次の方法で共有

【VBA】複数行からの抽出について

Anonymous
2024-09-28T07:47:54+00:00

表A"検索対象_商品名"に記載されている商品名を、 表B"商品データ"に記載されている商品名から検索して、

該当行に記載されている情報を抽出したいです。

===============================================================

【表A:検索対象_商品名】

検索対象_商品名

スラックスA

ワイシャツ

ジャケット


【表B:商品データ】

発注番号 商品名 仕入れ先 金額  ・・・

HB-0001 スラックスA A社 1000 (★)

HB-0002 スラックスA B社 2000 (★)

HB-0003 スラックスA A社 1500 (★)

HB-0004 ワイシャツ A社 500  (★)

HB-0005 スラックスB A社 500

HB-0006 スラックスB A社 500

HB-0007 ジャケット C社 10000 (★)

HB-0008 ジャケット B社 15000 (★)


【表C:出力結果】

発注番号 商品名 仕入れ先 金額

(★)行が抽出されるイメージ

===============================================================

表Aは最大100行×1列程度、表Bは現状18万行×40列程度のデータ量があり、 検索キーとなる商品名は、表B内では重複しています。(表A内では重複なし)

・表Bを連想配列(Dictionary)化することを検討しましたが、Dictionary生成の処理中に、商品名をKEYとしてITEMを随時追加することが出来ませんでした。

・for文での繰り返し検索については、表B内に商品名が何個あるか把握できず、100行×18万の検索になり、処理時間がかかるため避けたいと考えています。

代替案・対策等ご存じの方、ご助力頂けますと幸いです。

開発者テクノロジ | Visual Basic for Applications

ロックされた質問。 この質問は、Microsoft サポート コミュニティから移行されました。 役に立つかどうかに投票することはできますが、コメントの追加、質問への返信やフォローはできません。

0 件のコメント コメントはありません

2 件の回答

並べ替え方法: 最も役に立つ
  1. motosan 3,230 評価のポイント
    2024-09-28T12:20:55+00:00

    棚田優生 さま

    Dictionary は重複したキーを登録できないため

    表Bのすべての商品名を 商品名をキーとした

    Dictionary に登録する ことはできません。

    発想を変えればどうでしょうか?

    (1) 表Aの方を Dictionary に登録する

    (2) 表Bの商品名が Dictionary に存在する行だけを抽出する。

    どうしても表Bのすべての商品名をDictionary に登録したい場合は

    Dictionaryのキーを商品名、アイテムを同じ商品名の行番号の配列として

    すでに登録済みの場合、配列に追加するようにすれば登録できます。

    配列の定義が難しいかもしれませんが

    ご参考になれば幸いです。

    追記)2024 9/29 18:18

    表B を Dictionary に格納する場合も、結局 18万回 Dictionaryに存在するかチェックすることになります。

    結局、表A から作成した Dictionary を使用した方が速いと思います。

    処理時間を短くするには、セルを1つずつ処理せずに2次元配列に変換して処理した方が効果的です。

    VBA 高速化 配列 などをキーワードにして検索すると例があります。

    例えば下記のようにすると18万回の検索もすぐに終わります。

    追記)2024 9/30 8:20

     質問の処理に近いように書き換えました。

     長いですが、参考になれば幸いです。

    ' 入力 <br><br>Dim shtA As Worksheet <br><br>Dim arrayA As Variant <br><br> <br><br>Dim dicA As Dictionary <br><br>Dim keyA As String <br><br> <br><br>Dim shtB As Worksheet <br><br>Dim arrayB As Variant <br><br>' 出力 <br><br>Dim shtC As Worksheet <br><br>Dim rangeC As Range <br><br>Dim arrayC As Variant <br><br>Dim cntC As Long ' 出力行数 <br><br> <br><br>Dim i As Long <br><br>Dim j As Long <br><br> <br><br>'Dictionary用 入力 <br><br>Set shtA = ThisWorkbook.Worksheets("表A") <br><br>' セル範囲から値を配列に読み込む <br><br>arrayA = shtA.Range("A2:A100").Value <br><br> <br><br>'Dictionaryの作成 <br><br>Set dicA = New Dictionary <br><br>For i = LBound(arrayA) To UBound(arrayA) <br><br> If arrayA(i, 1) = "" Then <br><br> Exit For <br><br> End If <br><br> keyA = arrayA(i, 1) <br><br> If Not dicA.Exists(keyA) Then <br><br> dicA.Add keyA, "" <br><br> End If <br><br>Next i <br><br> <br><br>'入力 <br><br>Set shtB = ThisWorkbook.Worksheets("表B") <br><br>' セル範囲から値を配列に読み込む <br><br>arrayB = shtB.Range("A2:D180000").Value <br><br> <br><br>'出力 <br><br>Set shtC = ThisWorkbook.Worksheets("表C") <br><br>'とりあえず最大行数の配列を作成 <br><br>' 後で実際の行数に縮小する <br><br>Set rangeC = shtC.Range("A2:D180000") <br><br>arrayC = rangeC.Value <br><br>cntC = 0 <br><br> <br><br>For i = LBound(arrayB, 1) To UBound(arrayB, 1) <br><br> keyA = arrayB(i, 2) <br><br> If keyA <> "" Then <br><br> If dicA.Exists(keyA) Then <br><br> cntC = cntC + 1 <br><br> For j = LBound(arrayB, 2) To UBound(arrayB, 2) <br><br> 'arrayC(cntC, j) = "b" & arrayB(i, j) <br><br> arrayC(cntC, j) = arrayB(i, j) <br><br> Next j <br><br> End If <br><br> End If <br><br>Next i <br><br> <br><br>' サイズを変更したセル範囲に書き戻す <br><br>rangeC.ClearContents <br><br>If cntC > 0 Then <br><br> rangeC.Resize(cntC).Value = arrayC <br><br>End If

    以上

    この回答は役に立ちましたか?

    0 件のコメント コメントはありません
  2. simo-k 85,415 評価のポイント ボランティア モデレーター
    2024-09-28T09:05:21+00:00

    VBA(マクロ)の公式サポート場所は、海外コミュニティとなっています。  有識者が集まっている所の方が、適切なアドバイスを受けやすいでしょう。・Stack Overflow(VBA)[VBA プログラミングに関する質問]Stack Overflow には、説明的なタイトル、完全で簡潔な問題ステートメント、問題を再現する 
      ための十分な詳細の要求などのガイドラインがあることに注意してください。 
      機能要求または過度に広範な質問は、トピック外と見なされます。 
      新しいユーザーの場合は、Stack Overflow ヘルプ センター にアクセスして詳細を確認して下さい。※ 閲覧者・回答者が多い公式サポートサイトをお勧めします。英語で質問を送信してください。所謂、くれくれ君には対応してくれないと思います。

    この回答は役に立ちましたか?

    0 件のコメント コメントはありません