• ベストアンサー

Excel VBA で二つのシートを比較抽出

Excel VBA で二つのシートを比較して合致するレコードを別のシートに抽出する方法について 下記ホームページのコードを利用させていただきました。 https://okwave.jp/qa/q5917011.html ●fax2シート B列(検索順)  セル1 A    2 B    3 D    4 C ●fax3シート( 比較抽出結果)  セル1 A    2 B    3 C    4 D 比較抽出結果が検索順にするにはどのようにコードを記述すればよいか教えていただけますか。

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

  • ベストアンサー
  • kkkkkm
  • ベストアンサー率65% (1620/2459)
回答No.13

色(書式)のコピーは 変数宣言の後に Worksheets("Fax3").Cells.Clear を追加して 'セル幅自動調整 の前に Worksheets("Fax1").Range("A1").copy Worksheets("Fax3").Range("A1:Z1").PasteSpecial Paste:=xlPasteFormats Worksheets("Fax1").Range("A2").copy Worksheets("Fax3").Range(Cells(2, "A"), Cells(n - 1, "Z")).PasteSpecial Paste:=xlPasteFormats を追加してみてください。

Japan20121012
質問者

お礼

セルの色についてもできることが できました。 いろいろとご教示いただき有り難う ございました。 コードの記述内容については 今後の為に自分で調べていきます。

その他の回答 (12)

  • kkkkkm
  • ベストアンサー率65% (1620/2459)
回答No.12

> ●fax1シートのセルは塗るつぶしされています。 >  fax3シートに書き出す際に塗るつぶしも >  できないでしょうか。 全て同じ色で塗りつぶされているのでしょうか。 パターンが分かりません。状況によっては動作がかなり遅くなります。 > ●1行ごとにコードの説明を記載して >  いただけないでしょうか。 甘えすぎです。簡単な動作の説明は入れてあります。 そんなトリッキーな事はしていませんので、ご自身で調べてください。

  • kkkkkm
  • ベストアンサー率65% (1620/2459)
回答No.11

No10の追記です。 '重複して抽出された場合、fax3への出力が5000行を超える可能性がある場合はこちらで '可能性がない場合でもこちらでいけます。 'fax2のB列データがfax1のB列に重複しない(させない)場合はExit Forを有効にしてください。 Public Sub TestcopyTranspose() Dim mfax1 As Variant, mFax1Row As Long, mFax1Column As Long Dim mfax2 As Variant, mFax2Row As Long Dim mfax3 As Variant Dim i As Long, j As Long, k As Long, n As Long 'fax1データ範囲を配列変数に取り込み mfax1 = Worksheets("Fax1").Range("A1:Z5000").Value 'fax2データ範囲を配列変数に取り込み mfax2 = Worksheets("Fax2").Range("A1:B500").Value ReDim tmp(1 To UBound(mfax1), 1 To UBound(mfax1, 2)) ReDim mfax3(1 To UBound(mfax1, 2), 1 To 2) mFax1Column = UBound(mfax1, 2) mFax1Row = UBound(mfax1) mFax2Row = UBound(mfax2) '見出し For k = 1 To mFax1Column mfax3(k, 1) = mfax1(1, k) Next k '比較開始 Fa2の位置関係のまま取り出し n = 2 For i = 2 To mFax2Row For j = 2 To mFax1Row If mfax2(i, 2) = mfax1(j, 2) And mfax2(i, 2) <> "" Then For k = 1 To mFax1Column mfax3(k, n) = mfax1(j, k) Next k n = n + 1 ReDim Preserve mfax3(1 To UBound(mfax1, 2), 1 To n) 'Exit For 'fax2のB列データがfax1のB列に重複しない(させない)場合はこれをコメントから外して End If Next j Next i 'データ書き出し With Sheets("fax3") .Range("A1").Resize(UBound(mfax3, 2), UBound(mfax3)) = WorksheetFunction.Transpose(mfax3) End With Worksheets("Fax3").Activate '比較終了 'セル幅自動調整 Worksheets("fax3").Range("a:g").Columns.AutoFit Worksheets("fax3").Activate End Sub

  • kkkkkm
  • ベストアンサー率65% (1620/2459)
回答No.10

No6で頂いた補足より引き続き fax2のB列のデータがfax1のB列にあればfax1のその行のAからZまでのデータをfax3にfax2の順番で転記する とうことでいいのでしょうか、以下で試してみてください。 Public Sub Testcopy3() Dim mfax1 As Variant, mFax1Row As Long, mFax1Column As Long Dim mfax2 As Variant, mFax2Row As Long Dim mfax3 As Variant Dim i As Long, j As Long, k As Long, n As Long 'fax1データ範囲を配列変数に取り込み mfax1 = Worksheets("Fax1").Range("A1:Z5000").Value 'fax2データ範囲を配列変数に取り込み mfax2 = Worksheets("Fax2").Range("A1:B500").Value ReDim tmp(1 To UBound(mfax1), 1 To UBound(mfax1, 2)) ReDim mfax3(1 To UBound(mfax2), 1 To UBound(mfax1, 2)) mFax1Column = UBound(mfax1, 2) mFax1Row = UBound(mfax1) mFax2Row = UBound(mfax2) '見出し For k = 1 To mFax1Column mfax3(1, k) = mfax1(1, k) Next k '比較開始 Fa2の位置関係のまま取り出し n = 2 For i = 2 To mFax2Row For j = 2 To mFax1Row If mfax2(i, 2) = mfax1(j, 2) And mfax2(i, 2) <> "" Then For k = 1 To mFax1Column mfax3(n, k) = mfax1(j, k) Next k n = n + 1 Exit For 'fax2のB列データがfax1のB列に複数ある場合はこれをコメントに End If Next j Next i 'データ書き出し With Sheets("fax3") .Range("A1").Resize(UBound(mfax3), mFax1Column) = mfax3 End With Worksheets("Fax3").Activate '比較終了 'セル幅自動調整 Worksheets("fax3").Range("a:g").Columns.AutoFit Worksheets("fax3").Activate End Sub

Japan20121012
質問者

補足

速やかな回答有難う御座います。 意図していることが出来ました。 申し訳ありませんが、あと2つ要望が あります。 ●fax1シートのセルは塗るつぶしされています。  fax3シートに書き出す際に塗るつぶしも  できないでしょうか。 ●1行ごとにコードの説明を記載して  いただけないでしょうか。 勝手なお願いばかりで申し訳ありません。

  • HohoPapa
  • ベストアンサー率65% (454/691)
回答No.9

#3です。 もし、 抽出するときに重複を含めるのであれば、  SQL = SQL & "group BY [F1]" & vbCrLf ↑の行をコメントアウトしてください。

  • kkkkkm
  • ベストアンサー率65% (1620/2459)
回答No.8

No4を試す場合以下のように変更してください。 空白が無いとエラーになるのを忘れてました。 With Worksheets("Fax3") .Range(.Cells(1, "A"), .Cells(Rows.Count, "A").End(xlUp).Offset(1, 0)). _ SpecialCells(xlCellTypeBlanks).EntireRow.Delete End With のところを Dim mRange As Range With Worksheets("Fax3") Set mRange = .Range(.Cells(1, "A"), .Cells(Rows.Count, "A").End(xlUp)) If WorksheetFunction.CountBlank(mRange) > 0 Then mRange.SpecialCells(xlCellTypeBlanks).EntireRow.Delete End If End With Set mRange = Nothing

  • kkkkkm
  • ベストアンサー率65% (1620/2459)
回答No.7

No6の訂正です もとのコメントをそのままにしましたが、今回の場合は 'fax1範囲指定 'fax2範囲指定 は、それぞれ 'fax1データ範囲を配列変数に取り込み 'fax2エータ範囲を配列変数に取り込み が適切でした。

  • kkkkkm
  • ベストアンサー率65% (1620/2459)
回答No.6

No1もNo4も元のコードを再利用しましたが、遅い場合は以下で試してみてください。 No1もNo4もFax1のA列のデータをFax2のC列のデータから探しています。 (元のコードがそれっぽかったので) Public Sub Testcopy() Dim mfax1 As Variant, mFax1Row As Long, mFax1Columns As Long Dim mfax2 As Variant, mFax2Row As Long, mFax2Columns As Long Dim mfax3 As Variant, mFax3Row As Long Dim mtmp As Variant Dim i As Long, j As Long, k As Long 'fax1範囲指定 mfax1 = Worksheets("Fax1").Range("A1").CurrentRegion.Value 'fax2範囲指定 mfax2 = Worksheets("Fax2").Range("A1").CurrentRegion.Value ReDim tmp(1 To UBound(mfax2), 1 To UBound(mfax1, 2)) ReDim mfax3(1 To UBound(mfax2), 1 To UBound(mfax1, 2)) mFax1Columns = UBound(mfax1, 2) mFax2Columns = UBound(mfax2, 2) mFax1Row = UBound(mfax1) mFax2Row = UBound(mfax2) mFax3Row = mFax2Row '見出し For k = 1 To mFax1Columns tmp(1, k) = mfax1(1, k) Next k '比較開始 Fa2の位置関係のまま取り出し For i = 1 To mFax1Row For j = 1 To mFax2Row If mfax1(i, 1) = mfax2(j, 3) And mfax1(i, 1) <> "" Then For k = 1 To mFax1Columns tmp(j, k) = mfax1(i, k) Next k End If Next j Next i j = 1 '途中の空白データを省く For i = 1 To mFax3Row If tmp(i, 1) <> "" Then For k = 1 To mFax1Columns mfax3(j, k) = tmp(i, k) Next k j = j + 1 End If Next i 'データ書き出し With Sheets("fax3") .Range("A1").Resize(UBound(mfax3), mFax1Columns) = mfax3 End With Worksheets("Fax3").Activate '比較終了 'セル幅自動調整 Worksheets("fax3").Range("a:g").Columns.AutoFit Worksheets("fax3").Activate End Sub Worksheets("fax3").Range("a:g").Columns.AutoFit Worksheets("fax3").Activate End Sub

Japan20121012
質問者

補足

回答有難う御座います。 質問内容に足らない点がありましたので 補足致します。 ●fax1シート(検索対象データ)  ➢1行目は見出し(列A~Z)   2行目からはデータが記載  ➢検索対象はB列 2行目~5,000行目 ●fax2シート(検索を行おうとしているデータ)  ➢1行目は見出し(列A~B) ➢検索を行おうとしているデータは   B列 2行目~500行目になります。 ●fax3シート( 比較抽出結果)  ➢1行目はfax1シートと同じ見出し  ➢fax1シート B列の中にfax2シート B列と   同じデータがある場合はfax3シートに   書き出す。 殆ど知識がなくうまく質問が出来なくて 申し訳ありません。

  • SI299792
  • ベストアンサー率48% (715/1480)
回答No.5

前の怪盗に「かなり遅くなる」と書いてあったので、早くできる方法です。 10000 件1秒でできます。 コピー領域は、前質問と同じ、A~G列としました。 「セル1 A」と書いてあったのでヘッダー無し、1行目からいきなりデータとしました。 Option Explicit ' Sub Macro1()   Dim Dictionary As Object   Dim I As Worksheet   Dim RInp As Long   Dim ROut As Long   Dim Key As String '   Set Dictionary = CreateObject("Scripting.Dictionary")   Set I = Sheets("fax1") '   For RInp = 1 To I.Cells(Rows.Count, "B").End(xlUp).Row     Key = I.Cells(RInp, "B")     Dictionary(Key) = ""   Next RInp '   Set I = Sheets("fax2")   Sheets("fax3").Select   [A:G].ClearContents   Application.ScreenUpdating = False '   For RInp = 1 To I.Cells(Rows.Count, "B").End(xlUp).Row     Key = I.Cells(RInp, "B") '     If Dictionary.Exists(Key) Then       [A1:G1].Offset(ROut) = I.[A1:G1].Offset(RInp - 1).Value       ROut = ROut + 1     End If   Next RInp End Sub

  • kkkkkm
  • ベストアンサー率65% (1620/2459)
回答No.4

fax2シートで見つかった順番ではなくfax2シートにある元の順番通りでしたら以下で試してみてください。 Dim FoundCell As Range Dim i As Long For i = 1 To fax1Table.Rows.Count Set FoundCell = fax2Table.Columns(3).Find(fax1Table(i, 1).Value, , xlValues, xlWhole) If Not FoundCell Is Nothing Then fax1Table(i, 1).Resize(1, 3).copy dst.Offset(FoundCell.Row - 1) End If Next i With Worksheets("Fax3") .Range(.Cells(1, "A"), .Cells(Rows.Count, "A").End(xlUp).Offset(1, 0)). _ SpecialCells(xlCellTypeBlanks).EntireRow.Delete End With また No1の fax1Table.Offset(i - 1).copy dst は fax1Table(i, 1).Resize(1, 3).copy dst の間違いでした。

  • HohoPapa
  • ベストアンサー率65% (454/691)
回答No.3

求めている内容を私が理解しているか疑問はありますが、 以下でいかがでしょうか Option Explicit Sub MyPicup()  Dim SQL As String  Dim cn As Object  Dim rs As Object  Dim PicData As String  Dim Rowcnt As Long    '抽出条件を組み立て  With ThisWorkbook.Sheets("fax1")   Rowcnt = 1   PicData = "'" & .Cells(1, 1).Value & "'" & vbCrLf   Do    If .Cells(Rowcnt, 1).Value = "" Then Exit Do    PicData = PicData & "," & "'" & .Cells(Rowcnt, 1).Value & "'" & vbCrLf    Rowcnt = Rowcnt + 1   Loop  End With  'SQL全文を組み立て  SQL = "SELECT F1" & vbCrLf  SQL = SQL & "FROM [" & "fax2" & "$C1:C50000]" & vbCrLf  SQL = SQL & "WHERE F1 IN(" & PicData & ")" & vbCrLf  SQL = SQL & "group BY [F1]" & vbCrLf  'DB定義とSQLを実行  Set cn = CreateObject("ADODB.Connection")  Set rs = CreateObject("ADODB.Recordset")  cn.Provider = "Microsoft.ACE.OLEDB.12.0"  cn.Properties("Extended Properties") = "Excel 12.0;HDR=No;IMEX=1"  cn.Open ThisWorkbook.Path & "\" & ThisWorkbook.Name  rs.Open SQL, cn    '出力先をクリアーして結果セットを出力  With ThisWorkbook.Sheets("fax3")   .Cells.ClearContents   .Cells(1, 1).CopyFromRecordset rs  End With  '後処理  rs.Close  Set rs = Nothing  cn.Close  Set cn = Nothing End Sub

関連するQ&A

  • EXCEL(2枚のSheetの比較・抽出)

    iwao32と申します。 EXCELについてまた教えてください。(まだまだど素人で、基本的な質問で申し訳ありません。) 以下の例で示します。 Sheet1                        Sheet2 A列     B列     C列           A列 1       10      a            2 2       20      b            4 3       30      c            5 4       40      d 5       50      e という2枚のSheetがあるとき、Sheet1のA列とSheet2のA列を比較して、Sheet1の中で、Sheet2のA列にあるものだけ、Sheet3に、 Sheet3 A列     B列     C列 2       20      b 4       40      d 5       50      e というものを作りたいのですが、やり方をお教えください。 よろしくお願いいたします。

  • Excel VBA で二つのシートを比較して合致するレコードを別のシー

    Excel VBA で二つのシートを比較して合致するレコードを別のシートに抽出する方法 全然詳しくはありません。 やりたいこととしては、fax1,fax2,fax3のシートがありまして、 fax1:a列にfax_id fax2:fax1同様に、c列にfax_id のようなExcelのデータがあります。 ここから、fax1のシートのidを一つ一つ読み込みながら、fax2のidと比較して、合致したらfax3シートにコピーするようなプログラムを作りたいです。 やり方はいろいろあるみたいなのですが、どうしても下記の記述をベースに作ってみたいのですが、単純にfax1からfax3にコピーするのはわかるのですが、ここから先がよくわかりません。 基本的なことで申し訳ないのですが、どなたかご教授いただけませんでしょうか。 よろしくお願いいたします。 Public Sub copy() Dim tempRange As Range Dim fax1Table As Range Dim fax2Table As Range Dim dst As Range 'fax1範囲指定 Worksheets("Fax1").Activate Set fax1Table = Range("a1").CurrentRegion Set fax1Table = fax1Table.Offset(1) Set fax1Table = fax1Table.Resize(fax1Table.Rows.Count - 1) 'fax2範囲指定 Worksheets("Fax2").Activate Set fax2Table = Range("a1").CurrentRegion Set fax2Table = fax2Table.Offset(1) Set fax2Table = fax2Table.Resize(fax2Table.Rows.Count - 1) '比較開始 Worksheets("fax1").Activate '見出しコピー Set dst = Worksheets("fax3").Range("a1") Range("a1:g1").Copy dst 'レコード抽出 For Each tempRange In fax1Table.Rows Set dst = dst.Offset(1) tempRange.Copy dst Next '比較終了 'セル幅自動調整 Worksheets("fax3").Range("a:g").Columns.AutoFit Worksheets("fax3").Activate End Sub

  • VBAを使った、Excelでのシート間データ抽出

    はじめまして。みなさまどうか教えてください。 Sheet1にはA列に250行程、コードが存在します。 Sheet2にはA列(コード)からI列まで、そして1000行程データが存在します。 Sheet1にあるコードは重複はなく、Sheet2のコード内に必ず同じコードがあります。 Sheet2にも重複コードはありません。 そこでSheet1のコードを使い、Sheet2を検索し、同一コードのデータ(A列からI列の行すべて)を全て(250件分)、Sheet1のコード記載順(A1、A2、A3・・・・)で、Sheet3に抽出したいのです。 どうか、よろしくお願いします。

  • エクセルで別シートに抽出

    エクセルで同じBOOKに以下のようなシートがあります。 【sheet1】 A B C D E… 5 7 8 9 3… 3 3 6 5 6… 【sheet2】 A B C D E… 2 7 8 5 3… 6 3 9 5 7… 【sheet3】 A B C D E… 1 8 5 7 6… 1 3 8 5 7… こんなシートがsheet1~sheet50まであり、これを 【sheet51】に A A A  5 2 1 3 6 1 【sheet52】に B B B 7 7 8 3 3 3 のようになるだけ簡単に抽出したいのですが… どなたか、よろしくお願いします。

  • エクセルのセル抽出でチェックシート

    複数ブックの同じシートの特定セルの内容を抽出し、1つのチェックシート用のエクセルに貼り付けたいのですが、可能でしょうか。 複数ブックは1つのフォルダの中に入れます。特定セルは複数のシートにまたがっています。 Book1 Sheet1:A5, B10, D20/Sheet3:C1, H4/Sheet5:F7 Book2 Sheet1:A5, B10, D20/Sheet3:C1, H4/Sheet5:F7 Book3 Sheet1:A5, B10, D20/Sheet3:C1, H4/Sheet5:F7  ・  ・

  • エクセル 別シートから一覧を抽出したい

    部品一覧表を作成しているのですが、2シートあり 1入力シート・2部品コードシートとあります。 部品コードシートにはB列に部品番号・C列部品名・D列部品番号・E列部品名と2行ずつ使い番号・品名がB~Wまで47行分入力されています。 B1:C47、D1:E47…と2列47行にはそれぞれ【A】、【B】、…とセルの名前の定義をつけました。現在【H】までありますが、今後増える可能性があります。 入力シートに、セルの名前を指定したときに部品コードのシートから 一覧を抽出したいのですが、どの関数を使えばよいのかわかりません。 入力シート                 |部品コードシート G   H                  | A Bコード C部品名  Dコード E部品名 4式入力用にあけています。     |1 1800  ユニットA   1501 電源A 5コード 部品名             |2 1801  ユニットB   1502 電源B 6                       |3 G4に関数を入れてG6~G52まで部品コードのシートA1~A47を一気に表示 させたいのです。部品コードシートの行数が変わることはありません。 マクロを使わないと、関数では難しいでしょうか?

  • エクセルでの複数シートの比較

    【シート1】 A B C D 1 A社 B社 C社 D社 2 50 30 20 80 3 あ い う え 4 aa bb cc dd 【シート2】 A B C D 1 A社 B社 C社 D社 2 50 30 20 80 3 あ い う こ 4 aa bbb cc dd こういった風に、基本的に同じデータ構造で作られたデータがあった時に 2つのシートで、入力されてるデータが違うかをチェックしたい時、 (ここではD3とB4のセルのデータが書き換わってる) どういった風なやり方が考えられますか? 方法としては、関数、マクロ、VBA等あると思いますが、 当方初心者に毛のはえた程度のレベルですので、 関数ぐらいしか分かりません(-_-;) ●同一ブック内にあるシートの比較 ●別ブック内にあるシートの比較   の2種類が知りたいです。 ○ここではD3とB4のセルの内容が違うということが分かればいいのです。  (D3・・・【シート1】え、【シート2】こ)←ここまで分かると必要はないです。 よろしくお願い致します。

  • EXCELでの行の抽出

    sheet1に   A    B    C    D 1 日付 金額  備考  コード 2 01  1000 あいう    1 3 10  2000 えおか    3 4 20  3000 きくけ    4 5 30  4000 こさし    1 . . . という感じで元データ(100行ほど)が入っています。 これを元にしてsheet2に   A    B    C    D 1  1 2 日付 金額  備考  コード 3 01  1000 あいう    1 4 30  4000 こさし    1 . . . というふうに表示したいのです。 sheet2のセルA1に入っているコードと一致するコードが入っているsheet1の行を抽出してsheet2に行の隙間なく表示させたいのです。 こんなことはできるのでしょうか? メニューからコマンドを選択して・・・という方法ではなく、計算式かマクロで実現したいのです。 エクセル2000、Win98です。よろしくお願いします。

  • エクセルでシート間の比較をしたいのですが。。。

    Excel2000を使用しています。 2つのシート間で同一データの有無の比較がしたいのです。 仮に比較したいものをシートA・Bとします。 それぞれ項目として、大字・小字・地番があり、それが同じ時に同一データと判断します。 件数にすると4000~5000件ぐらいあり、関数でやってみたのですが、うまくいきません。 比較で結果としては、下記の3パターンがあります。 1)AとBに有る。 2)Aに有って、Bに無い。 3)Bに有って、Aに無い。 希望としては、新たなシートに 2)と 3)のデータのみ抽出して、そのデータが 2)なのか 3)なのかわかるようにしたいのです。宜しくお願いします。

  • エクセル 2つのシートの抽出

    シート1 コード|地域|住所 0001|青森A|青森県青森市○丁目○-○ 0002|青森D|青森県青森市×丁目×-× 0003|岩手B|岩手県岩手市○丁目○-○ 0004|岩手D|岩手県岩手市×丁目×-×         シート2   コード|(住所を抽出したい) 0003| 0001|  シート1は一覧表で、シート2は今回の対象だとします。 シート2のコードとシート1のコードが一致したら、 シート2のB列にシート1の住所を抽出したいのですが、どのような方法があるのでしょうか?教えて下さい。