- ベストアンサー
エクセルVBAの文字列の部分一致について
在庫管理のため、バーコードハンディターミナルで収集したCSV形式のログデータを、別のエクセルファイルに転記するマクロを組もうとしています。 ログファイルには、以下のようにバーコードのコード番号に対して在庫数が入力してあります。 AAA01,10 AAA02,15 BBB01,5 BBB02,7 AAA01とAAA02は同じ種類なので、在庫数は転記先のエクセルファイルの同じセル内に数値を加算します。 この時、同じ文字列(ここではAAAまたBBB)が含まれるコードの在庫数をコピーするマクロはどのようにしたらよいのでしょうか?
- みんなの回答 (8)
- 専門家の回答
質問者が選んだベストアンサー
とりあえず If Cells(i, 1).Value = ("AAA") Then の部分を If InStr(Cells(i, 1).Value, "AAA") > 0 Then にすれば、AAAを含むものが対象となるはずです。
その他の回答 (7)
- imogasi
- ベストアンサー率27% (4737/17069)
通常質問に出る表現や、私が使う表現と、質問の言葉と違うようなので、質問の内容が良く伝わりません。もう少し勉強をしてからこういうシステムに取り組むのが適当かと。 >在庫管理のため、バーコードハンディターミナルで収集した 本質的ではない。書くと邪魔。 >CSV形式のログデータ 他のデータ収集システムがCSVデータ形式で作ってくれていて存在するのですね。 >別のエクセルファイルに転記する 「別」に決まっている。「転記」するとは「読み込む」ことでしょう。 既にエクセルのシートに読み込むところまでできましたか。 >ログファイルには、 できたとして、CSVファイルを読み込んだ、エクセルのシートは、既にできていますか。 できているなら、後はエクセルのシートの話をしてください。来歴のログファイルの話をする必要はありません。エクセルVBAの話のようですから。 > シートの列・行構成を明確に記してください。ここから質問を始めても良いぐらい。カンマは入れず A列(商品記号?) B列(在庫数) AAA01 10 AAA02 15 BBB01 5 BBB02 7 >転記先のエクセルファイルの同じセル内に数値を加算します。 別シートに同一種類商品は合算した計数を、種類別に出したいのでは ーーー 普通はAAA,BBB,CCC・・別合計を出したいという質問が多い。(昨日も載った) 本質問では、あるルールに基づいて集計したいらしい。 そのルールとは。質問の説明が明確でない。 (1)AAAは文字列ですか。桁数は一定ですか。 01は数字文字列で すか・桁数は一定ですか (2)AAAの位置は浮動しますか。先頭文字から始まりますか。 (3)AAA1とあったりAAA01とあって、両者が同じとかは、ないでしょうね。 >コピーする この表現は的波連れでは。 合算する。加算する。まとめるという表現が適当では。 ーーー aaa12 1 bbb2 2 aaa23 3 cc1 4 aaa341 5 aaaa12 1 10 10は =SUMIF(A1:A6,"aaa*",B1:B6) という関数で出ます。 こういうのは使えませんか。 ぎりぎり関数でもできそうな、問題のように思いましたhが。 ーー VBAでは >文字列の部分一致 は(1)Instr関数 2)ワイルドカード (3)その他 を使う、がありそうです。
Set R = .Find(GetGoodsName(Goods), LookIn:=xlValues) 当然に、品番で探さないと意味ありません。
一度も Excel は操作したことのない門外漢です。 そこで、ヘルプを手掛かりに質問者の要求に応えるであろうVBAコードに挑戦。 まあ、初挑戦ですから<決めうち>とはほど遠いでしょう。 <q_of_inventry.txt> AAA01,10 AAA02,15 BBB01,5 BBB02,7 <Excel> AAA____1 BBB____1 このような在庫表が存在するとします。 次のVBAの実行結果は、次のようです。 AAA___26 BBB___13 Option Explicit Private Sub CommandButton1_Click() Dim I As Integer Dim N As Integer Dim Datas() As String Dim Goods As String Dim Quantity As Long Dim R As Range With Worksheets(1).Range("a1:a500") Datas() = FileReadArray("C:\Temp\q_of_inventory.txt") N = UBound(Datas()) - 1 For I = 0 To N Goods = CutStr(Datas(I), ",", 1) Quantity = CutStr(Datas(I), ",", 2) Set R = .Find(Goods, LookIn:=xlValues) If Not R Is Nothing Then Range(R.Address).Offset(0, 1) = Quantity Else MsgBox "[" & Goods & "] に対応する品番は、既存の在庫表に見つかりませんでした" End If Next I End With End Sub Public Function GetGoodsName(ByVal Goods As String) As String Dim NewGoods As String NewGoods = Replace(Goods, "0", "") NewGoods = Replace(NewGoods, "1", "") NewGoods = Replace(NewGoods, "2", "") NewGoods = Replace(NewGoods, "3", "") NewGoods = Replace(NewGoods, "4", "") NewGoods = Replace(NewGoods, "5", "") NewGoods = Replace(NewGoods, "6", "") NewGoods = Replace(NewGoods, "7", "") NewGoods = Replace(NewGoods, "8", "") NewGoods = Replace(NewGoods, "9", "") GetGoodsName = NewGoods End Function .Find しか、ヘルプから見つけることが出来なかったということです。 FileReadArray()、CutStr()は、必要ならば補足します。
- Wendy02
- ベストアンサー率57% (3570/6232)
こんにちは。 補足を読みましたが、私の書いた内容が、ほとんど意味が通じていないようですね。 同じ内容を繰り返されても、話が進みません。それに、そのお書きになったマクロは、あまり役に立ちません。 ・そのコード番号には規則がありますか? ・データを集計するための、元のリストはありますか? もし、こちらの話が理解できないようでしたら、それは、CSV をインポートした後に、[並べ替え]してしまって、それで、COUNTIFやSUMIF などの関数を使って、数を抽出したほうが早いようです。
補足
>・そのコード番号には規則がありますか? 最初の3文字(AAA):薬品の種類 4文字目から5文字目(01):個体番号 という規則があります。つまり同じ種類の薬品が5本あれば"AAA05"のようになります。 >・データを集計するための、元のリストはありますか? 元リストはあります。
- Wendy02
- ベストアンサー率57% (3570/6232)
こんにちは。 現状の情報だけでは、VBAのコードを提供しても、キメウチの内容になって、無駄なコードの提供をしてしまうような気がします。もう少し、詳しく、自分で実際にどのようにしたら良いか組み立てたほうがよいと思います。具体的には、他の方がおっしゃるように、コードの比較の問題です。 AAA01 AAA02 BBB01 BBB02 文字-3個と、数字-2個というような、きちんとした規則があるなら、VBAで行うには、Dictionary オブジェクトという外部のオブジェクトを使うか、もしくは、1次元の配列で、ワークシートのMatch 関数を使うか、というような予測を立てています。 しかし、商品リストが予めあったほうが、楽ではないかと思います。その場合は、商品リストに当てはめていくような方法になるのだと思います。いずれにしても、これらのコードは、CSVファイル自体をインポートするわけではありません。そのコードを読んで、数量と思われる場所を読んでカウントします。
補足
在庫管理では、1000個程度の薬品に個別にバーコードを割り当てており、中には同じ種類のものが含まれています。個体を区別するために同じ種類でもそれぞれにコードを割り当てていますが、数量としては同じ種類のものの合計が欲しいのです。 ログデータとしては1000個程度のデータ(コード番号と数量)が順不同で羅列されますので、その中から同じ種類を表す"AAA"の部分が含まれる薬品の数量をコピーして別のエクセルファイルの特定のセルに加算することを考えています。 以下は現在作成途中のマクロの一部分ですが、これではコード番号が"AAA"の場合しか値をコピーしてくれません。これを「"AAA"を含むもの」として指定する方法をご教示下さい。 With LOGDATA Dim i As Integer For i = 1 To 1000 If Cells(i, 1).Value = ("AAA") Then Cells(i, 2).Copy ThisWorkbook.Worksheets(1).Range("H5").PasteSpecial Paste:=xlValues, Operation:=xlAdd End If
- shinkun0114
- ベストアンサー率44% (1553/3474)
具体的に何をしようとしているのかはわかりかねるのですが、 ある文字列の中に、別の文字列が含まれるかを判定する関数として、 VBAにはInstr関数があります。 http://officetanaka.net/excel/vba/tips/tips33.htm ご参考まで。
- pamsd
- ベストアンサー率18% (39/209)
>AAA01とAAA02は同じ種類なので、在庫数は転記先のエクセルファイルの同じセル内に数値を加算します。 AAA01とAAA02は 違うものです。 これが 同じならば 別のセルに AAA01とAAA02が同じものであるというしるしをつけたらいいでしょう。 そして そのしるしで集計すればいいですね。 たとえば 頭3文字をしるしとするならば そのセルには =LEFT(A1,3) などという感じで入れればいいのです。 また 0AAA1 AAA01 01AAA なども同じと見なす場合は、ちょっと難しいですね。 VBAとかを使ったらいいと思います。
お礼
シンプルにご回答頂きありがとうございます。 おかげざまで解決しました。