• ベストアンサー

VBAで別ブックからVLOOKUPで抽出

ブックBシート1A列の値にマッチする値をそれぞれの列にVLOOKUPでブックAシート1にある値から貼り付けたいのですがVBAコードが解る方宜しくお願いします。尚、データーが50行ぐらいあるのですが。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

#1です。漏れがありましたので、追加回答です。 #1のマクロでは、 ブックBの[年齢]列にだけ結果が返る、内容になっていましたが、 ブックBの[氏名]列と[年齢]列の2列に結果が返るように書くべきでしたので、 #1のマクロをすべて、下に示すものと差し換えてください。 うっかりしてました。すみません。 ついでに、一応、 > ■ブックAが開いている状況からマクロを実行する前提 だけど、 >  ▲開いていなくても動作するように書きました。 ブックAが開いて居ない場合は、ブックAが開いてから処理する、という意味です。 結果として残したいものが"固定値"ではなく"数式"であるならば、 考える必要もないことですが、、、。 シート上に数式を出力する方法、については、 固定値を出力する目的であったとしても、 現代的な Excel VBA としては、寧ろ一般的な方法で、 演算結果を確定するまでの時間が短い、という特長があり、 同じ様にExcelの関数(数式)を用いるWorksheetFunctionとは、 大きく性格が異なり、パフォーマンスにも違いがあります。 他の有力な方法としては、Excelの関数(数式)を用いずに、  VBAでメモリ上で演算した結果を返す方法や  Excel一般機能の[検索]=.Findメソッドを使う方法など も非常に有力な方法として考えられますが、 シート上で数式を演算させる方法は、 構文的に簡潔ですし、パフォーマンスも十分ですし、 今回は「VLOOKUPで」という指定でしたので、 このような方法を選択しています。 シート上で数式を演算させる方法、の難点、注意点としては、 文字列である"数式"を整形する時にミスし易いこと、が挙げられます。 よくあるのが、 1. 数式内で文字列値を指定する時の二重引用符の書き方。    "=""abc"""    "=IF(A1,1,"""")"     と書くべきものを誤って    "=ABC"    "=IF(A1,1,"")"    とか、 2. 数式内で外部シートを参照する時の書き方。    ='D:\フォルダ\[ブックA.xlsm]Sheet1'!$A$2、    ='Sheet1 (2)'!$A$2、    と書くべきものを誤って    =D:\フォルダ\[ブックA.xlsm]Sheet1!$A$2、    =Sheet1 (2)!$A$2、    とか、 今回は二重引用符は関係ありませんし、 シートへの参照方法も数式に使える形の記述を Excel側に問い合わせた結果を用いているので、 この点はミスが無いよう工夫しています。 セル範囲や引数の指定だけは確認の必要がありますけれど。 以下、差し替え、を、お願いします。 ' ' /// ブックB に記載するマクロ 2個 /// 改 Sub Re8984933w()   Dim sRefSrc As String ' ' ブックA On Error GoTo errH_ ' ブックA が開いていない場合のエラートラップ   ' ' 要確認★ブック名 "ブックA.xlsm" ? 拡張子を確認して正確に!★シート名 "Sheet1" ?   With Workbooks("ブックA.xlsm").Sheets("Sheet1") On Error GoTo 0 ' エラートラップ解除     ' ' 要確認★先頭列番地(3ヶ所) A ?★[年齢]列までの列数 .Resize(, 3) ?     sRefSrc = .Range("A2:A" & .Cells(Rows.Count, "A").End(xlUp).Row).Resize(, 3).Address(True, True, xlA1, True)   End With ' ' ブックB   With ThisWorkbook.Sheets("Sheet1") ' 要確認★ブックB:処理結果を反映させたいシート名 "Sheet1" ?     ' ' 要確認★先頭列番地(3ヶ所) A ?★[年齢]列までの相対列位置 .Offset(, 1) ?     With .Range("A2:A" & .Cells(Rows.Count, "A").End(xlUp).Row).Offset(, 1).Resize(, 2)       ' ' 要確認★ブックB:先頭列番地 A ?★ブックA:[年齢]列までの列数 ,3 ?       ' ' 要確認 ブックA:先頭列から見た★[氏名]列の列位置 ,2 ?★[年齢]列の列位置 ,3 ?       .Formula = Array( _             "=VLOOKUP(A2," & sRefSrc & ",2,0)", _             "=VLOOKUP(A2," & sRefSrc & ",3,0)" _             )       ' ' 数式の結果を値として残す場合は直下の行を イキ '      .Value = .Value     End With   End With Exit Sub errH_:   OpenBookA   Resume End Sub Private Sub OpenBookA()   ' ' 要指定★ブックAのフォルダパス 例示は「このブックのフォルダパス + \」 末尾の \ を忘れずに!   ' ' 要確認★ブックAのブック名 "ブックA.xlsm" ? 拡張子を確認して正確に!   Workbooks.Open ThisWorkbook.Path & "\ブックA.xlsm" End Sub ' ' ///

kuma0220
質問者

お礼

追加説明ありがとうございます。 列はWith .Range("A2:A" & .Cells(Rows.Count, "A").End(xlUp).Row).Offset(, 2) .Formula = "=VLOOKUP(A2," & sRefSrc & ",3,0)" .Value = .Value ' ☆ End Withを追加していったらなんとか出来ましたけど補足のコードのほうがよいですね。 助言も含めて本当にありがとうございました。

その他の回答 (2)

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.2

(通常のケース) VBAでエクセルシート関数を使うやり方はVBAを使うものには常識だろう。 Application.WorksheetFunction.VLookup・・ のように書く 同一シート内に「表引きするデータ」がある場合。 Sub test01() Set sh1 = ThisWorkbook.Sheets("Sheet1") rl = sh1.Range("A1000").End(xlUp).Row MsgBox rl For i = 2 To rl MsgBox sh1.Range("A" & i) With sh1 st = Application.WorksheetFunction.VLookup(sh1.Range("A" & i), sh1.Range("D2:E8"), 2, False) MsgBox st Range("B" & i) = st End With Next i End Sub ーー 2.(別シートにある場合)  「表引きするデータ」が同一ブックの別シートにある場合。コード略。 3.(別ブックにある場合)  「表引きするデータ」が別ブック(したがって別シート)にある場合。 4.(上記でエラーだ起こらない家庭の場合) 5.(上記でエラーが起こっても次行分の検索を続行) などかあり得て、順に少しずつむつかしくなる。 ーー 5.の線で 下記コード例。 ーーー 余り使い慣れないのでエラー処理で手こずったが、下記でどうだろう。 Sub test06() On Error Resume Next '--点数をセットするブック・シート Set wb1 = Workbooks("VLOOKUPVBA") Set sh1 = wb1.Sheets("Sheet1") '--点数を採ってくるブック・シート Set wb2 = Workbooks.Open("C:\Users\惇\Documents\点数例1.xlsx") Set sh2 = wb2.Sheets("Sheet1") '--点数をセットするシートのA列の最下行 rl = sh1.Range("A1000").End(xlUp).Row '--探索開始 For i = 2 To rl '点数を採ってくる氏名ごと繰り返し st = Application.WorksheetFunction.VLookup(sh1.Range("A" & i), sh2.Range("A2:B8"), 2, False) If Err Then sh1.Range("B" & i) = "なし" Err.Clear GoTo nt2 Else '点数をセットするブック・シートのセルに点数をセット sh1.Range("B" & i) = st MsgBox "探索= " & sh1.Range("A" & i) & " 点数= " & st End If nt2: Next i GoTo nt1 '--エラー処理削除可 error1: sh1.Range("B" & i) = "見つからず" wb2.Activate sh2.Select GoTo nt2 '-- nt1: End Sub 'http://excel-ubara.com/excelvba4/EXCEL207.html 'http://atamoco.boy.jp/vba/lang/error/on-error-resume-next.php ’-- テストデータ(元データ)は VLOOKUPVBAというブックのSheet1 A1:B8(1行目見出し行) 氏名 点数 吉田 45 池田 65 佐藤 54 福田 48 三木 56 野田 64 岡田 78 ーー 実行前 指定氏名のあるシート VLOOKUPVBAブックのSheet1 氏名 点数(点数を引く前でブランク) 野田 三木 佐藤 池下 池田 佐藤 木村 吉田 ーーー 実行後(点数が入った) 氏名 点数 野田 64 三木 56 佐藤 54 池下 なし 池田 65 佐藤 54 木村 なし 吉田 45 ーーー コード VLOOKUPVBAブックの標準モジュール Sub test06() On Error Resume Next '--点数をセットするブック・シート Set wb1 = Workbooks("VLOOKUPVBA") Set sh1 = wb1.Sheets("Sheet1") '--点数を採ってくるブック・シート を開く Set wb2 = Workbooks.Open("C:\Users\xxxx\Documents\点数例1.xlsx") Set sh2 = wb2.Sheets("Sheet1") '--点数をセットするシートのA列の最下行を探る rl = sh1.Range("A1000").End(xlUp).Row '--探索開始 For i = 2 To rl '点数を採ってくる氏名セルごと繰り返し st = Application.WorksheetFunction.VLookup(sh1.Range("A" & i), sh2.Range("A2:B8"), 2, False) If Err Then sh1.Range("B" & i) = "なし" Err.Clear ’ここで不案内で、手こずった GoTo nt2 Else '点数をセットするブック・シートのセルに点数をセット sh1.Range("B" & i) = st MsgBox "探索= " & sh1.Range("A" & i) & " 点数= " & st End If nt2: Next i GoTo nt1 '--エラー処理(不要、失敗例) error1: sh1.Range("B" & i) = "見つからず" wb2.Activate sh2.Select GoTo nt2 '-- nt1: End Sub 以下のサイトを参考にしてください 'http://excel-ubara.com/excelvba4/EXCEL207.html 'http://atamoco.boy.jp/vba/lang/error/on-error-resume-next.php ーー Googleででも通常のケースなどはたくさんコード例がある。 それぐらいやってから質問しているのかな。 そこでやってみてどこで行き詰まったか、書くこと。 私なら、文章で質問文に (1)引くデータが他ブックにあるときの参照VBAコード (2)見つからないエラーが起こった時の続行 になるかな。 >データーが50行ぐらいあるのですが。 これも書く必要ない。少数です、でよい。 ーー 普通の関数だけでも、式の複写を用いて、できると思う。 Googleででも、「エクセル 関数 他ブック参照」で検索すればたくさん記事がある。 そういう時に、質問者はなぜVBAでやるのか。

kuma0220
質問者

お礼

いろんな詳細説明ありがとうございます。

回答No.1

こんにちは。 問題解決の為に必要な情報が不足しているので、 こちらで想定した仮の条件で一例としてお応えします。 回答する側が迷うことなくすっきりした解決を提示出来るようにする為に 必要なポイントは以下。 ●マクロを書くのは「どの」ブック ? ●ブックAやブックBは開いている状態から処理するのか ?  「何が」開いていて「何が」閉じているのか ?  ▲閉じているブックがある場合は、   閉じているブックのフォルダパスが必要 ●「VLOOKUP」関数を使った数式を設定したい、のか、  「VLOOKUP」で得られるのと同じ結果になるようにVBAを組みたいのか ?  ▲結果として残したいのは"数式"なのか"固定値"なのか ? こちらで想定した仮の条件 ■マクロを書くのは  ブックB ■ブックAが開いている状況からマクロを実行する前提 だけど、  ▲開いていなくても動作するように書きました。 ■「VLOOKUP関数を使う例」という趣旨で書いています。  ▲"固定値"がお望みの場合は、☆の行の先頭 ' を一文字削除してください。 また、  シート名など、各種 名前について、  セル範囲の位置関係について、 変動する場合の指定(確認)箇所を★印でマークしていますので、 そちらで適宜修正を加えて、応用するようにしてください。 こちらで想定した仮の条件が、お望みと一致する確率は1/10未満と見ています。 必要なパーツを示すことはできていると思うので、 期待通りでなかった場合でも、まずは自分なりに応用することに努めてください。 その上で、どうしても解決できない場合は、上述のポイントを整理して、 補足欄に追加説明を書いてみて下さい。 迷わず着手できるだけの情報が揃えば、再レスするつもりです。 強調しておきますが、以下の例は、 ブックBにマクロを記載する場合、です。 ' ' /// ' ' /// ブックB に記載するマクロ 2個 /// Sub Re8984933w()   Dim sRefSrc As String    ' ' ブックA On Error GoTo errH_ ' ブックA が開いていない場合のエラートラップ   ' ' 要確認★ブック名 "ブックA.xlsm" ? 拡張子を確認して正確に!★シート名 "Sheet1" ?   With Workbooks("ブックA.xlsm").Sheets("Sheet1") On Error GoTo 0 ' エラートラップ解除     ' ' 要確認★先頭列番地(3ヶ所) A ?★[年齢]列までの列数 .Resize(, 3) ?     sRefSrc = .Range("A2:A" & .Cells(Rows.Count, "A").End(xlUp).Row).Resize(, 3).Address(True, True, xlA1, True)   End With ' ' ブックB   With ThisWorkbook.Sheets("Sheet1") ' 要確認★ブックB:処理結果を反映させたいシート名 "Sheet1" ?     ' ' 要確認★先頭列番地(3ヶ所) A ?★[年齢]列までの相対列位置 .Offset(, 2) ?     With .Range("A2:A" & .Cells(Rows.Count, "A").End(xlUp).Row).Offset(, 2)       ' ' 要確認★ブックB:先頭列番地 A ?★ブックA:[年齢]列までの列数 ,3 ?       .Formula = "=VLOOKUP(A2," & sRefSrc & ",3,0)"       ' ' 数式の結果を値として残す場合は直下の行を イキ '      .Value = .Value ' ☆     End With   End With Exit Sub errH_:   OpenBookA   Resume End Sub Private Sub OpenBookA()   ' ' 要指定★ブックAのフォルダパス 例示は「このブックのフォルダパス + \」 末尾の \ を忘れずに!   ' ' 要確認★ブックAのブック名 "ブックA.xlsm" ? 拡張子を確認して正確に!   Workbooks.Open ThisWorkbook.Path & "\ブックA.xlsm" End Sub ' ' ///

kuma0220
質問者

お礼

有難うございます。非常に助かりました。

関連するQ&A

  • [EXCEL2007]VBAからの別ブック参照VLOOKUPについて

    初めまして。 EXCEL2007で、VBAからFORMULA式を使って別ブックを参照するVLOOKUPを埋め込もうとしています。 このとき、対象となる別ブックのシートに、検索値に合致する情報がないと、「シートの選択」ダイアログが出てしまうのですが、これを出さずに、式を生かしたまま「#N/A」扱いにする(=ワークシート上でVLOOKUPに失敗したときと同じ結果とする)方法はないでしょうか? いろいろ試したのですが解決策が見つかりませんでした。 実装コードはつぎのような形になってます。 Sheet1.Formula = "=VLOOKUP(B2,'[Book2.xls]Sheet1!$B1:$C255,2,FALSE)" Book2のSheet1のB1:C255に、検索キー[B2]の値があるとき、C列の値を取ろうとしています。 このとき、検索に失敗すると、コード実行中に「シートの選択」ダイアログが出てしまうので、これを回避したいのが質問の主題です。 Application.DisplayAlerts = FALSE でもダメでした。 なにか良いアイデアがありましたらご教唆願います。

  • エクセル、VBA、抽出複数検索について

    エクセル、VBA、VLOOKUP、MATCH関数等について出来る方法があれば教えてください。 インチごとに分けてあるシートがあり、(在庫表です) これを参照して、別ブックへVLOOKUP等を使って、サンプルデータのシート4のように表示させたいのですが、 何か方法を使って出来ることは可能でしょうか? 問題点が複数あります 1、VLOOKUPの範囲について、B列が結合されていて、C列は複数行あるため、商品名が入ってきません。 C列については、何千件とデータがあるため、結合することは不可能です。 一致している条件としては商品コードが必ずあり、商品名には「/」が入っております。 =CONCATENATEとVLOOKUPは一緒に使うことは可能ですか? もしくはINDEX関数やIF、SUMPRODUCT等を使うのでしょうか? シート4のような形に出来る方法があれば、教えてほしいです。 VBAは詳しくはないのですが、VBAで出来るのであれば、教えてほしいです。 在庫表はとても作り方が悪いのですが、これを作り直すと言うことは、不可能です。 グループ会社で使っているため、なんとかこの在庫表を使いたいです。 VBAでA列をA5からA100にコードのみ入れた場合、B列に商品名が入るようにVBAで作ることは可能でしょうか? もしくは、検索条件を2つ使って、一つは商品コード完全一致+あいまい検索で【/】で商品名を入れることは可能でしょうか? 関数は調べたのですが、関数では難しいのかなと思います。 宜しくお願い致します。

  • Excel VLOOKUPをVBAでやりたいのですが、分からなくて困っ

    Excel VLOOKUPをVBAでやりたいのですが、分からなくて困ってます。 Sheet1のC列2行目行こうにSheet2のI列のデータを取得し (A列にデーターが入っている分、(時と場合により表示数が違う為)) なおかつ Sheet1のD列2行目以降にB-Cの差し引きをおこなう 以上のことをSheet1をアクティブにした時VBAでおこなうには、? 教えて下さい。宜しくお願い致します。

  • VLOOKUP関数をVBAで書くには

    EXCEL VBAの初心者です VLOOKUP関数をVBAで書きたいのですが、よくわかりません すいませんがどなたかご教授、願えないでしょうか? sheet1     sheet2 A    B  A    B      名称 CD    名称 CD 滋賀県 25     滋賀県  25 京都府 26     大阪府 27 大阪府 27 兵庫県 28     兵庫県 28 sheet2のA列をキーにsheet1のA列と照合して sheet2のB列にsheet1で一致した行のB列をコピーする VLOOKUP関数を使うと、sheet2のB2は =IF($A2="","",VLOOKUP($A2,Sheet1!$A$2:$B$5,2,0)) としたら、25を得ることができました VBAでする場合、どのように書けばいいのでしょうか? よろしくお願いします

  • エクセルで別ブックを検索するマクロ、VBA

    エクセルで以下の処理を行えるマクロを作成したいです。 当方、マクロについてほとんど知識がありません。 恐縮ですが、教えていただけると嬉しいです。 ・主にしたいこと  [検索]ブックで一致するコードを探して、  [結果]ブックの対応するコードの行にそれぞれの項目を返したい。 ●ブック1 [検索]  シートが12個あります(それぞれ、1、2、3…12というシート名=1~12月分)  ↓各シートの内容    A    B    C    D 1  氏名  数値  コード  内容 2  abc   111  SS1234 あいうえお 3  bcd   123  SS3456 かきくけこ ・ ・ ・ といった感じです。 12個のシートの中身はそれぞれ似たようなものですが、 「コード」や「内容」などは少しずつ違います。 ●ブック2 [結果]  ↓シートの内容    A    B    C    D 1  氏名  コード  内容  数値 2      SS3456 3      SS1234 ・ ・ ・ といった感じです。 (注)検索用ブックとは列の並びが異なっています。 ここでやりたいことの詳細ですが、 ・[結果]ブックの「コード」(B列)にコードを入力すると、  [検索]ブックで一致するコードを検索し、  A列「氏名」、C列「内容」、D列「数値」に、[検索]シートの内容を  自動的に表示させたい。  (ただし[結果]ブックに入力した「コード」は、[検索]ブックの1~12のうち、   どのシートにあるかわからない) ・入力したコードが見つからない場合は何も表示しない。 ということです。 最初VLOOKUP、MATCH等の関数で表示することを考えましたが、 シートが複数にまたがっているのと、 列の並び方が[検索][結果]ブックで違うのでわかりませんでした。 長くなってしまい申し訳ありませんが、どうかおしえてください。 よろしくお願いします。

  • VLOOKUP関数と同じことをVBAでおこなうには

     初めまして、当方VBAの素人です。よろしくお願いします。  同じような質問で、このようなVBAを見つけました。 Sub Macro1() For n = 2 To 5 '処理するSheet2の行数範囲 a = Sheets("Sheet2").Cells(n, 1) 'aにA列の値を代入 For m = 2 To 5 '検索するSheet1の行数範囲 If Sheets("Sheet1").Cells(m, 1) = a Then 'Sheet2のA列の値とSheet1のA列が一致した場合 v = Sheets("Sheet1").Cells(m, 2) 'vにB列の値を代入 Sheets("Sheet2").Cells(n, 2).Value = v 'Sheet2のB列に値を入力 Exit For '値が見つかったのでForを終了 End If Next Next End Sub このVBAではSheet2での検索、入力が列になるのですが、列でなく、行でできないでしょうか。できればSheet1のB列の値をSheet2の1行で検索、Sheet2の2行に入力されるだけではなく、Sheet1のC列の値をSheet3の1行で検索、Sheet3の2行に入力されるようにしたいと思います。  解る方、よろしくお願いします。

  • エクセル2つのブック列の比較 VBAや関数について

    Aと言うブックとBと言うブックがあるとして、 Aのブックは共有ファイルではなく、Zサーバー上にあるエクセルファイルです。 Aのブックに色々な人が行の挿入、商品名の書き換え等をしていて、いつ挿入されたのかが分からないため、VBAや関数を使って調べたいのですが、 Aのブックは10シートあり、サイズ別で行も並べられているため、新しい情報を特定するのが困難です。 BのブックはAと同じシート名を作り、必要箇所だけコピーしているデータです。(オリジナルブック) やりたいことは、Aのブックから探してBのブックに追加されていない情報、一致していない情報があれば、色を付けてわかりやすくするか、Bのブックの新しいシートに結果を出すようなことがしたいのですが、可能でしょうか? AのブックはA列-IC列まであるのですが、必要な部分は全シートB列(商品コード)とE列(商品名)のみです。 Bのブックには同じシート名にして、A列に商品コード、B列に商品名としております。 AのブックのB列、E列を参照して、BのブックのA列、B列になければ、結果を表示したいです。 もし出来る方法があれば、教えてほしいです。 今はシートごとに左右比較して、見ていってるのですが、10シートの中に、行数は2000行くらいあるため、それで半日おわってしまいます。 もし分かるかた、マクロを組める方がいれば教えて頂きたいです。宜しくお願い致します。

  • エクセルVBA VLOOKUPについて

    エクセル VBA初心者です。 関数でのVLOOKUPをVBAで作りたいのですが、上手くいきません。 あらかじめ、Sheet2の1から300行までに A列  / B列 商品名 / 商品コード が入力されています。(名前の定義=商品コード) Sheet1にユーザーフォームを利用して、データを書き込んだ後、 B列に商品名が書き込まれると、 A列に商品コードが表示されるようにしたいと考えています。 A列に =IF(B2="","",VLOOKUP(B2,商品コード,2,FALSE)) と入力していたのですが、 VBAでIfを使って出来ないかと考えてみたのですが、 上手くいきませんでした。 Private Sub Worksheet_Change(ByVal Target As Range) Dim sRow As Long Dim sColumn As Long sRow = ActiveCell.Row sColumn = ActiveCell.Column If Cells(sRow, 2).Value = True Then Cells(sRow, 1).Value = WorksheetFunction.VLookup(Cells(sRow2).Value, Worksheets("Sheet2").Range("A1:B300"), 2, False) ElseIf Cells(sRow, 2).Value = " " Then Cells(sRow, 1).Value = " " End If End Sub ご教授いただけないでしょうか? エクセル2003 WindowsXP

  • VBA2010,B3の値が変わったら、A3に

    VBA2010で,B列の値が変わったら、A列の同じ行に前日の日付を入力するには、マクロコードをどのように書けばよいですか?B列データ入力範囲はB3~B65536 尚、B3~B65536にはVLOOKUPで、他のブックから値を参照しています。 最後にA列の同じ日付セルを結合し、I列、P列、W列の同じ行に結合したセルをペーストたいのです。 宜しくお願い致します。

  • エクセルVBAで行うVLOOKUPについて

    エクセル2000を使用しています。 いまいろいろVBAを使用してますが、わからないことがあります。 シート1に入力データ、シート2に参照のデータ USERFORM を使用し たとえばテキストBOX1にコードAと入れるとテキストBOX2に東京支店と表示し確認をできるようにしたいのです。東京支店は、シート2の参照データから引用してきます。 BOX1にAと入れてエンターを押した時点でVLOOKUPを実施させたいのですがいまいちわかりません。 シート2は A列にコード A,B,C,D,.... B列に東京支店、千葉支店... よろしくお願いいたします

専門家に質問してみよう