- 締切済み
在庫管理 Excel VBA 検索
商品の在庫を管理しているシートがあります。この中から、特定の品名条件(5列分)を指定して特定の商品を管理している行を検索するには、どうしたらいいでしょうか?
- みんなの回答 (5)
- 専門家の回答
みんなの回答
- hige_082
- ベストアンサー率50% (379/747)
#3、#4です #4書き込み後に、#2さんへの補足を読んだもので #4はパスしてください #2さんの補足を踏まえると Lの付くデータを新規データ、Zの付くデータを表データと推測し説明します 今までは 最終行なら、行挿入 L品番とZ品番を比較し、L品番が大なら挿入、Z品番が大なら読込 L幅とZ幅を比較し、L幅が大なら挿入、Z幅が大なら読込 L巻長とZ巻長を比較し、L巻長が大なら挿入、Z巻長が大なら読込 L等級とZ等級を比較し、L等級が大なら挿入、Z等級が大なら読込 となっています それを 新規データと表データを比較し 品番、幅、巻長、等級がすべて等しいと読込 最終行、L品番がZ品番より大きい場合 或いは L品番がZ品番と同じで、以下、幅、巻長、等級をそれぞれ比較し 何れか一つでも新規データの方が大きければ 行挿入としてみました If Lhinban = Zhinban _ And Lhaba = Zhaba _ And Lmakichou = Zmakichou _ And Ltoukyuu = Ztoukyuu Then Call Z_MOVE ElseIf Zgyou > Zend_gyou _ Or Lhinban < Zhinban _ Or (Lhinban = Zhinban _ And Lhaba < Zhaba _ Or Lmakichou < Zmakichou _ Or Ltoukyuu < Ztoukyuu) Then Call Z_INSERT Else Call Z_ADD End If Loop Loop のように、提示された部分の条件の変更だけでも行けるのではと思います しかし、条件が5個あるとの事ですが、コードからは4個しか見当たりませんが、前半部分にあるのかな? こちらとしては、分かる範囲でのアドバイスしか出来ないので 解決のヒントになればと思います
- hige_082
- ベストアンサー率50% (379/747)
補足有難う御座います >コードの可読性をアップしたいのです。 そうでしたか、失礼しました コードを少し整理してみました 比較の順番が関係あるのであれば If Zgyou > Zend_gyou Then Call Z_INSERT ElseIf Lhinban > Zhinban Then Call Z_MOVE ElseIf Lhinban < Zhinban Then Call Z_INSERT ElseIf Lhaba > Zhaba Then Call Z_MOVE ElseIf Lhaba < Zhaba Then Call Z_INSERT ElseIf Lmakichou > Zmakichou Then Call Z_MOVE ElseIf Zmakichou < Zmakichou Then Call Z_INSERT ElseIf Ltoukyuu > Ztoukyuu Then Call Z_MOVE ElseIf Ltoukyuu < Ztoukyuu Then Call Z_INSERT Else Call Z_ADD End If Loop Loop 比較の順番が関係ないのであれば If Zgyou > Zend_gyou _ Or Lhinban < Zhinban _ Or Lhaba < Zhaba _ Or Zmakichou < Zmakichou _ Or Ltoukyuu < Ztoukyuu Then Call Z_INSERT ElseIf Lhinban > Zhinban _ Or Lhaba > Zhaba _ Or Lmakichou > Zmakichou _ Or Ltoukyuu > Ztoukyuu Then Call Z_MOVE Else Call Z_ADD End If Loop Loop こんな感じですが ただ、どうして比較式が不等号なのか? Findを使用するなら等号式を置き換えると思うのですが まあ、コードの前半部分がどうなっているか分からないので、何ともいえませんが
補足
hige_082さん、再びのご回答ありがとうございます。 よく、あのコードを読んで修正して下さいました。 >ただ、どうして比較式が不等号なのか? なぜなのでしょうか? どういう意味をもっているのか私にもわかりません。 ただ比較式は前半・後半あって( = )の場合はすり抜けて(完全一致) Call Z_ADD(在庫数計算)を呼び出します。 >Findを使用するなら等号式を置き換えると思うのですが そのつもりです。 >コードの前半部分がどうなっているか分からないので、何ともいえませんが 記述したコードの前は大した処理はしていません。入出庫ログシートが入っ ているブックをOpenしてソート処理を行っているだけです。 在庫管理シートの検索の方法がまずいのか、変なところに挿入してしまい、在 庫管理がうまくいかないのです。そこで集計方法を替えてみる事にしました。 1. 集計前に在庫管理シート、入出庫ログシート共に昇順でソートする。 2. 入出庫ログシートから1行読んで該当する品目を在庫管理シートで検索し、集計する。該当する品目が存在しなければ、末尾に挿入する。 3. 最後にもう一度在庫管理シートを昇順でソートする。 2の"該当する品目を在庫管理シートで検索"のときにFindを使用して検索 すれば的確に在庫データを更新できるのではないかと考えています。 それでも、不具合が出るのであればhige_082さんが示して下さった方法で検 索して見ようと思います。 ありがとうございました。
- hige_082
- ベストアンサー率50% (379/747)
>現在1500件ぐらいありますが処理速度もかなり問題です。 1500件ぐらいであれば、FINDでもFor・・Nextでも そんなに処理速度は変わらない気がします 現在使用している、コードを提示されては如何でしょう 簡単な修正で速度アップできるかもしれません
補足
hige_082さん、おはようございます。 ご回答ありがとうございます。 >現在使用している、コードを提示されては如何でしょう コードを提示しますが、理解に苦しまれると思います。私も未だによく理解できません。Findを使用したいのは処理速度をあげるためというより、コードの可 読性をアップしたいのです。 このコードの中のそれぞれのサブルーチンの内容は Z_INSERT ・・・ 在庫管理シートに行を追加する Z_MOVE ・・・ 在庫管理シートの行データを読み込む If Zgyou > Zend_gyou Then Call Z_INSERT Exit Do Else If Lhinban > Zhinban Then Call Z_MOVE Else If Lhinban < Zhinban Then Call Z_INSERT Exit Do Else If Lhaba > Zhaba Then Call Z_MOVE Else If Lhaba < Zhaba Then Call Z_INSERT Exit Do Else If Lmakichou > Zmakichou Then Call Z_MOVE Else If Zmakichou < Zmakichou Then Call Z_INSERT Exit Do Else If Ltoukyuu > Ztoukyuu Then Call Z_MOVE Else If Ltoukyuu < Ztoukyuu Then Call Z_INSERT Exit Do Else Call Z_ADD Exit Do End If End If End If End If End If End If End If End If End If Loop Loop
- fujillin
- ベストアンサー率61% (1594/2576)
5列分のテーブルに品名が並列してあって、そのなかから特定の品名を検索するのかと思いました。 どうやら1行で1品目ということですよね? まだ、5列分の検索の意味がわかりませんが、ひょっとして条件が5種類あって、(例えば幅200、等級A・・・)の5条件に合致する品名(行)を検索したいというようなことでしょうか? もしそうであれば、ループで1500行検索して、条件(and なのかorなのか不明ですが)に合致する行をリストアップすればよいのでは? (ループがネストすることはないと思いますが…?) 条件(対象列)は検索のたびに変わるのでしょうか? どうもよくわからないのでなんともいえませんが、単純にFindというわけでもなさそうですね。 なお、処理速度を上げる方法としては、とりあえず ・画面のアップデートを行わない ・データを配列に読み込んでシートへのアクセスを減らす などがあると思います。
補足
fujillinさん、おはようございます。 ご回答ありがとうございます。 >どうやら1行で1品目ということですよね? >まだ、5列分の検索の意味がわかりませんが、ひょっとして条件が5種類あっ >て、(例えば幅200、等級A・・・)の5条件に合致する品名(行)を検索したいという>ようなことでしょうか? その通りです。すみません、舌足らずで。 >もしそうであれば、ループで1500行検索して、条件(and なのかorなのか不明で>すが)に合致する行をリストアップすればよいのでは? >(ループがネストすることはないと思いますが…?) hige_082さんへの補足投稿に書きましたが、現在のコードが恐ろしくネストしているのです(私も未だによく理解できない)。 >条件(対象列)は検索のたびに変わるのでしょうか? 検索のたびに変わる事はありません。 この在庫管理シートの集計の方法は入出庫ログからデータを1行1行読んで集計し、在庫管理シートに存在しない品目が出てきた場合には新たに挿入します。 >どうもよくわからないのでなんともいえませんが、単純にFindというわけでもなさ>そうですね。 在庫管理シートの検索の方法がまずいのか、変なところに挿入してしまい、在庫管理がうまくいかないのです。そこで集計方法を替えてみる事にしました。 1. 集計前に在庫管理シート、入出庫ログシート共に昇順でソートする。 2. 入出庫ログシートから1行読んで該当する品目を在庫管理シートで検索し、集計する。該当する品目が存在しなければ、末尾に挿入する。 3. 最後にもう一度在庫管理シートを昇順でソートする。 2の"該当する品目を在庫管理シートで検索"のときにFindを使用して検索すれば的確に在庫データを更新できるのではないかと考えています。 >なお、処理速度を上げる方法としては、とりあえず > ・画面のアップデートを行わない ・・・ 1 > ・データを配列に読み込んでシートへのアクセスを減らす ・・・ 2 1の方法は取りあえずやっています。2の方法は在庫管理がうまくいった後、 取り入れようと思います。 Excel VBAもFindも殆んど初心者です。特にFindは今回初めて使用します。 どうかよろしく、アドバイス下さい。
- fujillin
- ベストアンサー率61% (1594/2576)
こんばんは。 >特定の品名条件(5列分)を指定 の意味がよくわかりませんが… 普通の検索という観点で答えれば、 Range.Find(What,・・・) で検索可能です。 Findメソッドについて調べてみてください。 もちろん、For・・Nextなどのループで検索するのもありです。 あるいは、ワークシート関数を用いて検索するという方法もあります。 「Visual Basic で使用できるワークシート関数一覧」などをキーにして調べてみてください。
お礼
fujillinさん、早いご回答ありがとうございます。 >特定の品名条件(5列分)を指定 の意味がよくわかりませんが… 在庫管理している商品の品名、幅、巻長、等級.........等です。 Range.Findについては、私も着目しプログラムを組み始めましたが、複数列の指定方法がわからずに、色々調べている内に、こちらにたどり着きました。 シートの構成はこうなっています。 A B C D F G H I 品名 幅 巻長 等級 ........繰越 入庫数 出庫数 在庫数 1 XXX 100 10000 A 100 1000 500 600 2 XXX 200 20000 A 200 2000 500 1700 3 XXX 300 30000 A 300 3000 500 2800 別シートの入出庫ログからこのシートの入庫数、出庫数の転記し 在庫数を管理していますが、このシートの作成者はFor・・Next を使って品名を検索していました。品名を代表するような品名コード のようなものはありません。For・・Nextで検索するとネストが多く、 プログラムの可読性に問題があります。現在1500件ぐらいありますが 処理速度もかなり問題です。 入出庫データを転記する時と新しい商品が増えた時に、行を挿入す る際、最適な行を検索する必要があります。Findメソッドを使って検 索してみようと思います。 そこで、Findメソッドで複数の列を指定して検索する方法をご教授下さい。
お礼
hige_082さん、こんばんは。他の仕事でお礼が遅くなり申し訳ありません。折角ご教示いただきましたが、やっぱり最初の方針通りFindを使用してコードを作成しました。複数列を検索条件にする事は結局わからずじまいで、結局もう1列増やして"品番"+"幅"+"巻長"+"等級"を1つのコードとしてセットしました。 >しかし、条件が5個あるとの事ですが、コードからは4個しか見当たりませんが 失礼しました。その通りです。検索条件にしなくてもいい列までカウントしてい ました。下記に検索部分のコードを記しておきます。 With SearchArea Set FoundCell = .Find( _ What:=StrkeyWord, _ LookIn:=xlValues, _ LookAt:=xlWhole, _ SearchDirection:=xlNext) End With If FoundCell Is Nothing Then 在庫管理シート行検索 = -1 GoTo End_Func End If Z_Gno = FoundCell.Row 色々とご教授いただきましてありがとうございました。