• ベストアンサー

エクセルでマッチング

2つのエクセルファイルの内容をマッチングさせたいんですけど、 例えば、aaa.xlsとbbb.xlsというのがあって、 aaa.xlsのA列とbbb.xlsのA列にファイル名、 bbb.xlsのB列にパッケージ名が格納されていて、 aaa.xlsのA列の1行目から順に、bbb.xlsのA列と 同じファイル名が存在するかマッチングさせていき、 マッチした場合にマッチした行のパッケージ名を aaa.xlsのB列に表示させたいんですけど、 関数なりマクロなりを使ってなんとかならないでしょうか?

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

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

マクロは動いているという事でよろしいでしょうか? 前回の修正版です。(補足のように変更したつもりです) 確認してみてください。 Sub DataMatch()   Set ws1 = Workbooks("ステップアップ一覧.xls").Worksheets("Sheet1")   flg = 0   'OPENチェック   For Each wb In Workbooks     If (wb.Name = "SQLJ一覧.xls") Then       flg = 1       Exit For     End If   Next wb   If (flg = 0) Then 'OPENされていない場合はOPENする     Workbooks.Open Filename:="C:\管理台帳\SQLJ一覧.xls"     ws1.Activate 'ステップアップ一覧のシートをアクティブにする   End If      Set ws2 = Workbooks("SQLJ一覧.xls").Worksheets("Sheet1")      'マッチング処理   On Error Resume Next   For i = 3 To ws1.Cells(Rows.Count, 2).End(xlUp).Row 'ステップアップ一覧の3行目から終りの行まで     Err.Clear     no = ws2.Columns("B:B").Find(What:=ws1.Cells(i, 2)).Row 'SQLJ一覧のマッチング行     '上記式は、SQLJ一覧にマッチングデータがないとエラーになるので     'On error Resume Next によりエラーを回避     If (Err.Number = 0) Then 'SQLJ一覧にマッチングするデータがあった場合       ws1.Cells(i, 3) = ws2.Cells(no, 3) 'マッチング行の3列目をステップアップ一覧へコピー     End If   Next i   MsgBox "処理終了" End Sub まだ処理がおかしいようなら補足してください。 >ステップアップ一覧のB列3行とSQLJ一覧のB列3行から比較し 私のプログラムは、ステップアップ一覧のB列3行目とSQLJ一覧のB列全てとを比較し、値を持ってきています。 SQLJ一覧のB1、B2セルの値が、B3、B4・・・と同じ値で無ければ問題ありませんが、 同じ値がある場合には、そちらも補足してください。

mikmik_a
質問者

補足

マクロを動かしてみると、「インデックスが有効範囲にありません」というメッセージが出ました。 SQLJ一覧のB1は空白、B2は列名(SQLファイル名と書いてある)です。

その他の回答 (10)

回答No.11

SQLJ一覧の相対パスには、できないと思います。(私の知識の中では) ステップアップ一覧と同じフォルダという事なら   If (flg = 0) Then 'OPENされていない場合はOPENする     FDir = thisworkbook.path 'ステップアップ一覧のパス取得     if ( right(FDir,1)<>"\") then '最終の[\]処理       FDir = FDir & "\"     End If     Workbooks.Open Filename:=FDir & "SQLJ一覧.xls"     ws1.Activate 'ステップアップ一覧のシートをアクティブにする   End If のように変更すれば、移動しても(あくまで、ステップアップ一覧と同じフォルダ) 使用できるかと思います。(テストしていませんので記述ミスがあるかもしれません) 別サーバにSQLJ一覧のみ移動する時には、絶対パスを修正するようにしないと できないと思います。(私の知識内では、無理と言う事で、断言できる訳ではありません) 移動するのも、エクスプローラなどのソフトを使うとEXCELで認識する事もできないですし・・・

mikmik_a
質問者

お礼

同フォルダ内だと、上記のやり方でうまくいきました。ファイルを別サーバに分けて動かすことはないので、これで十分です。本当にいろんなことを教えていただきありがとうございました。

回答No.10

>インデックスが有効範囲にありません 私の方でテストした時にはエラーがでませんので推測で回答します。 プログラムの中の 'マッチング処理 以下の部分ではOn Error Resume Nextでエラーが出てもメッセージが出ませんので、  考えられるのは、シート名が違うのが一番怪しいですね! 前回同様の2行の変更はしていただいたでしょうか?   Set ws1 = Workbooks("ステップアップ一覧.xls").Worksheets("Sheet1")   Set ws2 = Workbooks("SQLJ一覧.xls").Worksheets("Sheet1") 大文字、小文字、全角、半角を正確に入れてください。 次にマクロを書く時のために、両ブックのシート名を補足してください。 もし、きちんと書いてある場合には、 エラーの出ている行(黄色になっている行)を教えてください。 よく分からなければ、お手数ですが (1)[Alt]+[F11]でVisualBasicEditerに移り (2)Sub DataMacth...End Subのプログラムの中にカーソルを移し(行はどこでも構いません) (3)[F8]を押すと1行づつ実行していきます。(1行目が黄色くなると思います) (4)[F8]を何度か押して、エラーがでたらその場所を教えてください。 手間を取らせますが、すみません。

mikmik_a
質問者

お礼

すみません。シート名が間違ってました。シート名を訂正するとちゃんと動きました。あとは、メニューからマクロを実行させるには、ANo.#7のような感じでやればいいんですよね? このたびは、マクロを作っていただきありがとうございました。説明もわかりやすくて、本当に助かりました。また機会がありましたらよろしくお願いいたします。

mikmik_a
質問者

補足

今回のマクロは、SQLJ一覧のパスを絶対パスで指定しているのですが、もしこのファイルを別のサーバなどに移動させると、動かないですよね?相対パス指定はできるのでしょうか?

回答No.8

このプログラムで試してみてください。 1、[Alt]+[F11]を押す。VisialBasicEditerに変更されます。 2、左上にプロジェクトと書いてある中に、    VBAProject(ステップアップ一覧.XLS)      └Microsoft Excel Objects         ├Sheet1          ・・・         └ThisWorkbook   とあると思うので、ThisWorkBookをダブルクリック 3.以下のコードを貼り付ける   (シート名は[Sheet1]にしてありますので、違う場合は   Set ws2 = Workbooks("ステップアップ一覧.xls").Worksheets("Sheet1")   Set ws1 = Workbooks("SQLJ一覧.xls").Worksheets("Sheet1")   この2行のシート名を変更してください。 ***************************この下から***************************** Sub DataMatch()   Set ws2 = Workbooks("ステップアップ一覧.xls").Worksheets("Sheet1")   flg = 0   'OPENチェック   For Each wb In Workbooks     If (wb.Name = "SQLJ一覧.xls") Then       flg = 1       Exit For     End If   Next wb   If (flg = 0) Then 'OPENされていない場合はOPENする     Workbooks.Open Filename:="C:\管理台帳\SQLJ一覧.xls"   End If      Set ws1 = Workbooks("SQLJ一覧.xls").Worksheets("Sheet1")   ws1.Activate 'SQLJ一覧のシートをアクティブにする      'マッチング処理   On Error Resume Next   For i = 1 To ws1.Cells(Rows.Count, 1).End(xlUp).Row 'SQLJ一覧の1行目から終りの行まで     Err.Clear     no = ws2.Columns("A:A").Find(What:=ws1.Cells(i, 1)).Row 'ステップアップ一覧のマッチング行     '上記式は、ステップアップ一覧にマッチングデータがないとエラーになるので     'On error Resume Next によりエラーを回避     If (Err.Number = 0) Then 'ステップアップ一覧にマッチングするデータがあった場合       ws1.Cells(i, 2) = ws2.Cells(no, 2) 'マッチング行の2列目をSQLJ一覧へコピー     End If   Next i   MsgBox "処理終了" End Sub ***************************この上まで*************************** 4.[Alt]+[F11]を押す。Excelに戻ります。 5.とりあえず「ツール」→「マクロ」→「マクロ」から「ThisWorkbook.DataMatch」を選択して実行してみてください。 処理(数十秒)を終了したら、メッセージボックスを表示するようにしています。 メッセージボックスは表示されますか? メッセージがでなければ、マクロが動いていません。 メッセージがでて、何も処理がされなければ補足してください。

mikmik_a
質問者

補足

taisuke555さん、マクロを作っていただきありがとうございます。また、kazuhiko5681さん、いろいろ丁寧に教えていただきありがとうございます。 ただ、申し訳ないのですが、処理の説明が間違っているところがありました。マッチングは、ステップアップ一覧のB列とSQLJ一覧のB列を比較し、マッチすると、ステップアップ一覧のC列にSQLJ一覧のC列を対照行に表示するという風になります。比較方法は、ステップアップ一覧のB列3行とSQLJ一覧のB列3行から比較し、一致しなければSQLJ一覧の行をずらして比較していくといった形になり、1つのセルのマッチングが終わると、ステップアップ一覧の行を下に移動し、同じように最終行まで比較を続けるといった形になります。 お手数ですが、よろしくお願いいたします。

回答No.7

こんばんわ。 Sub Macro1() Dim myWbn1 As Workbook Dim myBook As String Dim myWsn1 As Worksheet Dim myWsn2 As Worksheet Dim i As Integer Dim j As Integer For Each myWbn1 In Workbooks If myWbn1.Name = "一覧表.xls" Then myBook = myWbn1.Name: Exit For End If Next If myBook = "" Then Workbooks.Open Filename:="C:\管理台帳\一覧表.xls" End If Set myWsn1 = Workbooks("一覧表.xls").Worksheets(1) Set myWsn2 = Workbooks("ステップアップ一覧.xls").Worksheets(1) For i = 2 To myWsn2.Cells(Rows.Count, 1).End(xlUp).Row For j = 1 To myWsn1.Cells(Rows.Count, 1).End(xlUp).Row If myWsn1.Cells(j, 1).Value = myWsn2.Cells(i, 1).Value Then myWsn1.Cells(j, 2).Value = myWsn2.Cells(i, 2).Value End If Next j Next i End Sub 上のコードで実行してみて下さい。もしこれでもエラーが出るようであれば、当方のほうでは正常に動作しておりますので、貴方様の方のパソコン側でチェックしない限り動くようにはならないかと思います。その時は下記のコードで実行してみて下さい。ただし、下記のコードを実行する時には、必ず2つのファイルを開いた後、マクロを実行して下さい。 Sub Macro1() Dim myWbn1 As Workbook Dim myBook As String Dim myWsn1 As Worksheet Dim myWsn2 As Worksheet Dim i As Integer Dim j As Integer Set myWsn1 = Workbooks("一覧表.xls").Worksheets(1) Set myWsn2 = Workbooks("ステップアップ一覧.xls").Worksheets(1) For i = 2 To myWsn2.Cells(Rows.Count, 1).End(xlUp).Row For j = 1 To myWsn1.Cells(Rows.Count, 1).End(xlUp).Row If myWsn1.Cells(j, 1).Value = myWsn2.Cells(i, 1).Value Then myWsn1.Cells(j, 2).Value = myWsn2.Cells(i, 2).Value End If Next j Next i End Sub マクロ実行ボタンをメニューバーへ貼り付ける方法 1.エクセル画面で、メニューバーにマウスポインターをあわせて右クリック後、出てきたプルダインメニューのユーザー設定をクリックする。 2.表示されたダイアロゴボックスのコマンドタブを選択し、分類と書かれている下の四角の中から新しいメニューを選択する。 3.コマンドの下にある新しいメニューの上にマウスポインタを合わせ、その上で左ボタンを押してメニューバーのヘルプの横までドラッグしメニューバーの上でボタンを離す。 4.選択したボタンの編集を押し、名前と書いてある横の四角の中に任意の名前を入力してマクロの登録ボタンを押す。 5.マクロの登録ダイアログボックスのマクロ名の下の四角い部分にMacro1と入力し、OKボタンを押してボックスを閉じ、閉じるボタンを押してユーザー設定ダイアログボックスを閉じる。 これで今作ったボタンにマクロが登録され、このボタンを押すとマクロが走ります。 もし、これでマクロが走らない時は、貴方様のパソコン側でチェックしなければ動かない原因がつかめません。ですから、シート状にコマンドボタンを配置して実行できるようにするのが一般的な使用方法だといえます。

mikmik_a
質問者

補足

遅れてすみません。 実行時にエラーは出ないのですが、なにも変化がありませんでした。

回答No.6

エクセルのバージョンとウインドウズのバージョンを教えて下さい。 それと、2つのブックが入っている場所のフルパス名も教えて下さい。 お手数をおかけいたします。よろしくお願いいたします。

mikmik_a
質問者

補足

エクセルはExcel2000でOSはWindows2000Professionalです。 パスは、C:\管理台帳の中に入ってます。 よろしくお願いします。

回答No.5

>'SQLJ一覧.xls'が見つかりません。というエラーが発生しました。 このエラーは、ブック名が違っている時に起きるエラーです。次の確認をお願いします。 ・SQLJ一覧.xlsを一覧表.xlsとブック名を変更する。 ・コードの中のSQLJ一覧.xlsと書かれている部分をすべて一覧表.xls二変更する。 これでマクロを実行してみて下さい。その結果を再度お知らせ下さい。 >できれば、シート上ではなく、メニュー上か、ファイルを開いた時にポップアップみたいな感じで出したいんですけど、可能でしょうか? 両方ともできます。どちらを説明すればよろしいのか教えて下さい。 お手数をおかけいたします。よろしくお願いいたします。

mikmik_a
質問者

補足

ファイル名を一覧表.xlsに変更しましたが、結果はさきほどと同じく、「見つかりません」といったエラーが発生しました。 起動ですが、メニュー上のボタンで起動できるようよろしくお願いいたします。

回答No.4

こんばんわ。サンプルマクロを組んでみました。つぎのように操作してみて下さい。 ・ステップアップ一覧.xlsを開き、ALT+F11キーを押してVBE画面を表示させ、画面左上のVBAProjectと書かれている下のSheet1をダブルクリックして表示された画面の右側の白い部分に下記のコードをコピー&ペーストする。 Private Sub CommandButton1_Click() Dim myWbn1 As Workbook Dim myBook As String Dim myWsn1 As Worksheet Dim myWsn2 As Worksheet Dim i As Integer Dim j As Integer For Each myWbn1 In Workbooks If myWbn1.Name = "SQLJ一覧.xls" Then myBook = myWbn1.Name: Exit For End If Next If myBook = "" Then Workbooks.Open Filename:="SQLJ一覧.xls" End If Set myWsn1 = Workbooks("SQLJ一覧.xls").Worksheets(1) Set myWsn2 = Workbooks("ステップアップ一覧.xls").Worksheets(1) For i = 2 To myWsn2.Cells(Rows.Count, 1).End(xlUp).Row For j = 1 To myWsn1.Cells(Rows.Count, 1).End(xlUp).Row If myWsn1.Cells(j, 1).Value = myWsn2.Cells(i, 1).Value Then myWsn1.Cells(j, 2).Value = myWsn2.Cells(i, 2).Value End If Next j Next i End Sub ALT+F11キーを押してエクセルの画面にもどる。 ・メニューバー上の表示→ツールバー→Visual Basicを順にクリックする。 ・表示されたツールバーの中のコントロールツールボックス(かなづちとスパナのマーク)をクリックし、出てきたプルダウンメニューからコマンドボタン(一番右の上から2番目)をクリックし、シートの貼り付けたいところにマウスポインターをあわせてクリックする。 ・デザインモード(一番左の一番上)をクリックしてへこんだ状態から普通の状態へ戻す。 コマンドボタンをクリックするとマクロが走り、貴方様のIお考えになっている動作が実現できると思います。 ご不明な点・不具合等がありましたら、ご遠慮なくお知らせ下さい。私のわかる範囲でご一緒に考えていきたいと思います。

mikmik_a
質問者

補足

おはようございます。 早速試してみましたが、実行すると、 「実行時エラー:1004  'SQLJ一覧.xls'が見つかりません。というエラーが発生しました。ディレクトリはステップアップ一覧と同フォルダ内にあります。 あと、実行時のボタンなんですが、できれば、シート上ではなく、メニュー上か、ファイルを開いた時にポップアップみたいな感じで出したいんですけど、可能でしょうか? よろしくお願いします。

回答No.3

こんばんわ。さっそく補足いただき有難うございます。VBAの知識が皆無ということですので、コピー&ペーストするだけできちんと動作するようにしたいと思いますので、次のことを教えて下さい。 ・aaa.xlsの正式なブック名とbbb.xlsの正式なブック名 正式なブック名とは、貴方様が現在つけられているブック名のことです。 お手数をおかけいたします。よろしくお願いいたします。

mikmik_a
質問者

補足

ファイル名はSQLJ一覧.xlsとステップアップ一覧.xlsです。 ステップアップ一覧がマクロの実行元で、ステップアップ一覧のファイル名の列と、SQLJ一覧.xlsのファイル名の列とをマッチングさせて、ファイル名が一致すると、SQLJ一覧.xlsのパッケージ名列にステップアップ一覧の一致した行のパッケージ名を表示するといった形にしようと思っています。 また、マクロの実行元には、実行ボタンを作りたいと思うのですが、もしよければそれも教えていただければありがたいです。

回答No.2

初めまして。サンプルマクロを組んでみました。参考にしてみて下さい。 もし操作方法等で解らないことがありましたらお知らせ下さい。詳しく説明させていただきます。 Sub test() Dim myWbn1 As Workbook Dim myBook As String Dim myWsn1 As Worksheet Dim myWsn2 As Worksheet Dim i As Integer Dim j As Integer For Each myWbn1 In Workbooks If myWbn1.Name = "bbb.xls" Then myBook = myWbn1.Name: Exit For End If Next If myBook = "" Then Workbooks.Open Filename:="bbb.xls" End If Set myWsn1 = Workbooks("aaa.xls").Worksheets(1) Set myWsn2 = Workbooks("bbb.xls").Worksheets(1) For i = 2 To myWsn2.Cells(Rows.Count, 1).End(xlUp).Row For j = 1 To myWsn1.Cells(Rows.Count, 1).End(xlUp).Row If myWsn1.Cells(j, 1).Value = myWsn2.Cells(i, 1).Value Then myWsn1.Cells(j, 2).Value = myWsn2.Cells(i, 2).Value End If Next j Next i End Sub

mikmik_a
質問者

補足

プログラムまで作って頂きありがとうございます。 ただ、私はマクロの知識は皆無なので、もしよければ 簡単な説明などしていただけたらありがたいです。 あと、使用方法なども教えてください。

  • ledm
  • ベストアンサー率21% (19/89)
回答No.1

VLOOKUPという関数があります。 ご希望どおり、2つのシートのデータをマッチングさせます。 例えば、aaa.xlsのA列のセルとbbb.xlsのA列をマッチングし、bbb.xlsのB列の値をaaa.xlsのB列に持ってきたいとします。 その場合は、まずA2のセルに、 =VLOOKUP(A1,[bbb.xls]Sheet1$A$1:$B$1000,2,0) という式になります。 式の項目の意味は、 A1 ・・・ マッチングのキー [bbb.xls]Sheet1$A$1:$B$1000 ・・・ 参照先の範囲 2 ・・・ マッチングした際に、上の参照先範囲の何列目のデータを持ってくるか 0 ・・・ 近似値ではなく、完全一致のみ です。 詳しくはヘルプや、関数の本に載っていますよ。 但し、件数が多いと再計算に時間がかかりますが・・・。