実務で使用されるリストでは、売上台帳と商品台帳が分離していることがあります。売上台帳には商品コードだけを記入し、該当する商品名は商品台帳から参照するような使い方です。こうした使い方は、Access などのリレーショナル データベースが本領を発揮しますが、Excel でも実現することは可能です。ただし、あくまでも「できる」という話で、VBA の深い知識が必要になったり、メンテナンスが困難になる場合もあります。数千件程度のリストなら問題ありませんが、本格的なデータベースを構築するのでしたら、Access などの使用を検討した方がいいでしょう。「餅は餅屋」です。ここでは、今まで使ってきたサンプルを 3 つのシートに分けて考えます。
最初の [売上データ] シートには、次のようなデータが入力されています。商品に関するデータは [商品コード] だけで、商品名はありません。
2 番目の [商品マスター] は次の通りです。
[売上データ] シートから「3月5日から3月11日の間に納品した」データだけを [抽出結果] シートに抽出します。そのとき、[商品マスター] シートで商品名を調べます。
Sub Sample05() Dim i As Long ''オートフィルタで抽出 With Worksheets("売上データ").Range("A1") .AutoFilter Field:=3, Criteria1:=">=3月5日", Operator:=xlAnd, Criteria2:="<=3月11日" .CurrentRegion.SpecialCells(xlVisible).Copy Worksheets("抽出結果").Range("A1") .AutoFilter End With With Worksheets("抽出結果") ''[抽出結果]シートに「商品名」フィールドを追加 .Columns("B:B").Insert Shift:=xlToRight .Range("B1") = "商品名" With .Range("A2") ''商品名の表引き Do While .Offset(i, 0) <> "" .Offset(i, 1) = WorksheetFunction.VLookup(.Offset(i, 0), _ Worksheets("商品マスター").Range("A1:B8"), 2) i = i + 1 Loop End With .Columns("A:D").EntireColumn.AutoFit End With End Sub
前半はオートフィルタによる抽出です。検索する条件の日付をユーザーから受け取るようにすると実用的ですね。
オートフィルタの結果を [抽出結果] シートに転記したら、[抽出結果] シートの B 列に空列を挿入します。ここが「商品名」フィールドです。
次にリレーショナル処理です。Excel のワークシート関数には、指定したキーをリスト内で検索して該当するデータを返す VLOOKUP 関数というスグレモノがあります。まさにリレーショナルな処理にぴったりですね。VLOOKUP関数の使い方に関しては、この関数はこう使え!の「VLOOKUP関数」を参照してください。
ここでは、Offset プロパティの使い方がポイントです。[抽出結果] シートのセル A2 が .Offset(0, 0) です。したがって、.Offset(1, 0) はセル A2 から 1 行下がったセル A3 を表します。最後に [抽出結果] シートを整形して完了です。
Sample05 では、1 度も「Select していない」点がポイントです。Select すると画面がちらつきますし、速度も著しく低下します。