【簡単エクセル/Excel VBA マクロ】異なるファイル間でのデータマッチング(照合・突合)第2版|アプリ事例 #010

アフィリエイト広告を利用しています。
QRコード
【QRコード】PC<-->スマホの切り替えにご利用ください
運営者・ポテ

いつもありがとうございます!

ノンプログラマー向けの「Excel VBA マクロ アプリ事例解説シリーズ」へようこそ。

本稿では、「異なるファイル間でのデータマッチング(照合・突合)第2版」を解説いたします。

Information
  • ノンプログラマー
    プログラミングを専門にしていない人たちのことです。
  • VBAとマクロの違い
    VBAは、Visusal Basic for Application の略で、プログラミング言語のことです。マクロは、VBAを使って作成される「機能」のことです。

前回、同じテーマの記事(以下、第1版と称します)をご紹介しました。

この記事も間違いではありませんが、変数名の付け方やコード全体の汎用性に、いくつか改善の余地がありました。

そこで今回は、第2版としてリライトしたものをお届けします。

前回の第1版と今回の第2版の主な違いは、下表の通りです。

項目第1版第2版
変数名の意味明確化fa_row_idx などの略語が多く、処理対象が不明瞭になりやすいbase_rowcheck_value など、対象の役割が明示され、可読性が向上
コメント逐語的で冗長な説明が多く、コードの流れが読みづらいコンパクトかつ構造的なコメントで、コード全体の見通しが良くなる
マジックナンバー排除列番号などを直接数値で指定しており、修正時にリスクが高いBASE_TARGET_COL のような定数化により、意図が明確になり、メンテナンス性が向上
可読性ネストや長い行が多く、視線の移動が多くなる折り返しやインデントにより、視線移動が少なく、処理のブロックが把握しやすい
拡張性ファイル名や列番号などがベタ書きされ、再利用や変更に弱いファイル名・列番号を定数として外出しすることで、設定変更が容易に
処理の汎用性処理内容が固定されており、他の照合処理に転用しづらい比較処理の構造が抽象化されており、今後の追加処理にも対応しやすい
Information
  • マジックナンバー
    コードの中に直接書かれた意味の分からない数字のこと。たとえば、13をそのまま使うと、何の列(または行)か分からなくなりやすく、修正ミスの原因になります。
  • 抽象化
    「抽象化」という言葉の日本語的な意味は、物ごとの細かな違いを取り除き、共通する本質や特徴だけを取り出して考えることです。
    プログラミングの文脈では、特定の処理やデータの「中身」に立ち入らず、共通の仕組みとして整理することを指します。たとえば「比較処理」だけを汎用化すれば、どんなデータにも再利用できるようになります。

本稿が、あなたのVBAマクロの価値をさらに高める一助となれば幸いです。VBAを活用して、自分自身や身近なコミュニティに合ったアプリケーションを作成し、仕事量は半分に、成果は2倍にしていきましょう!成果を増やす!是非ご覧ください。

VBAで「異なるファイル間(複数ファイル間)でのデータマッチング(照合・突合)」を行う方法(第2版

アプリケーションの仕様

以下のようなファイル・フォルダ構成です。

your_folder/
  ├── BaseFile.xlsx
  ├── CheckFile.xlsx
  └── データをマッチングする.xlsm

データをマッチングする.xlsm が、VBAコードを記述するマクロファイルです。

このファイルが BaseFile.xlsxCheckFile.xlsx を読み込み、両者のデータを照合します。

両者のデータの一致が見つかった場合は、その情報をデバッグ出力します。

なお、BaseFile.xlsxCheckFile.xlsxのシートの中身は、次のとおりです。

ExcelシートのA列に、上から順に「りんご」「バナナ」「さくらんぼ」「いちじく」「ぶどう」と入力されている。
BaseFile.xlsx
ExcelシートのA列に、上から順に「バナナ」「みかん」「ぶどう」「すいか」「もも」と入力されている。
CheckFile.xlsx

コードの実装

上述のアプリケーションを実現するコードと、その実行結果を示します。

Option Explicit


Sub MatchFileData()

    
    ' 変数宣言
    Dim base_fp         As String       ' Base File のパス
    Dim base_wb         As Workbook     ' Base Workbook
    Dim base_ws         As Worksheet    ' Base Worksheet
    Dim base_last_row   As Long         ' Base Worksheet の終端行
    Dim base_row        As Long         ' Base Worksheet の行ループ用変数
    Dim base_value      As Variant      ' Base Worksheet のイテレーター値
    
    Dim check_fp        As String       ' Check File のパス
    Dim check_wb        As Workbook     ' Check Workbook
    Dim check_ws        As Worksheet    ' Check Worksheet
    Dim check_last_row  As Long         ' Check Worksheet の終端行
    Dim check_row       As Long         ' Check Worksheet の行ループ用変数
    Dim check_value     As Variant      ' Check Worksheet のイテレーター値
       
    ' 定数設定 ↓ここを修正して使用してください↓
    Const BASE_FILE_NAME    As String = "BaseFile.xlsx"
    Const BASE_TARGET_COL   As Long = 1
    Const CHECK_FILE_NAME   As String = "CheckFile.xlsx"
    Const CHECK_TARGET_COL  As Long = 1


    ' Base File (基準ファイル)を開く
    base_fp = ThisWorkbook.Path & "\" & BASE_FILE_NAME
    Set base_wb = Workbooks.Open(base_fp)
    Set base_ws = base_wb.Worksheets(1)
    base_last_row = base_ws.Cells( _
        base_ws.Rows.Count, BASE_TARGET_COL _
    ).End(xlUp).Row
    
    ' Check File (チェック対象ファイル)を開く
    check_fp = ThisWorkbook.Path & "\" & CHECK_FILE_NAME
    Set check_wb = Workbooks.Open(check_fp)
    Set check_ws = check_wb.Worksheets(1)
    check_last_row = check_ws.Cells( _
        check_ws.Rows.Count, CHECK_TARGET_COL _
    ).End(xlUp).Row
    
        
    ' Base File の行をループ
    For base_row = 1 To base_last_row
        
        ' Base File の値を変数に代入
        base_value = base_ws.Cells(base_row, BASE_TARGET_COL)
            
        ' Check File の行をループ
        For check_row = 1 To check_last_row
            
            ' Check File の値を変数に代入
            check_value = check_ws.Cells(check_row, CHECK_TARGET_COL)
            
            ' Base File の値と Check File の値が一致したら
            If base_value = check_value Then
                
                ' ここに行いたい処理を書く
                Debug.Print check_row, check_value
            
            End If
        
        Next check_row
    
    Next base_row

    ' Cleanup
    base_wb.Close SaveChanges:=False
    check_wb.Close SaveChanges:=False


End Sub

このコードを実行すると、イミディエイトウィンドウに次の結果が返ります。

アプリケーション実行結果
nformation

イミディエイトウィンドウ
各種演算の結果や、処理の途中で変数に代入されている値を表示するなど、プログラムを検証するために使われるツールです。


運営者・ポテ

それでは、解説していきます!

Option Explicit

ここでは、Option Explicit を有効にしています。この設定を使うと、変数を使用する前に必ず宣言が必要になります。これにより、変数のタイプミスや未定義変数によるエラーを防ぎ、コードの安全性と信頼性を高めることができます。

    ' 変数宣言
    Dim base_fp         As String       ' Base File のパス
    Dim base_wb         As Workbook     ' Base Workbook
    Dim base_ws         As Worksheet    ' Base Worksheet
    Dim base_last_row   As Long         ' Base Worksheet の終端行
    Dim base_row        As Long         ' Base Worksheet の行ループ用変数
    Dim base_value      As Variant      ' Base Worksheet のイテレーター値
    
    Dim check_fp        As String       ' Check File のパス
    Dim check_wb        As Workbook     ' Check Workbook
    Dim check_ws        As Worksheet    ' Check Worksheet
    Dim check_last_row  As Long         ' Check Worksheet の終端行
    Dim check_row       As Long         ' Check Worksheet の行ループ用変数
    Dim check_value     As Variant      ' Check Worksheet のイテレーター値

ここでは、処理対象となる2つのファイルに対応する変数をあらかじめ宣言しています。

変数は Dim 変数名 As データ型 の構文で宣言します。これにより、各変数は As 以降で指定したデータ型の値を格納できるようになります。

ここでは、具体的には、それぞれのファイルに対して、ファイルパス、ブック、シート、最終行、ループ用の行番号、そして比較対象となるセルの値を格納する変数が用意されています。変数名には base_check_ の接頭辞を付けておくことで、どちらのファイルに属するものかが明確になり、コード全体の見通しが良くなります。

また、セルの値を格納する base_valuecheck_value の型に Variant を使用しているのは、文字列や数値など異なるデータ型を柔軟に扱うためです。こうした事前の変数定義は、マクロの読みやすさと保守性を高める上で重要な役割を果たします。

Information

イテレーター値
ループ処理の中で、現在の行や列に対応するセルの値を一時的に取り出して使う変数のことです。ここでは、1行ごとに値を読み込んで比較するため、base_valuecheck_value がそれにあたります。

なお、各データ型の意味は下表の通りです。

データ型種類意味
Workbookオブジェクト型ワークブック全体を表すデータ型です。ファイルを開いたり保存したりする処理に使います。
Worksheetオブジェクト型ワークシートを表すデータ型です。セルの読み書きなど、シート上の操作に使います。
String文字列型文字列を格納するデータ型です。ファイル名やパスなど、テキスト情報に使います。
Long数値型整数を格納するデータ型です。行番号や最終行の取得などに使います。
Variant汎用型どのような型のデータでも格納できるデータ型です。セルの値をそのまま受け取るときに使います。
    ' 定数設定 ↓ここを修正して使用してください↓
    Const BASE_FILE_NAME    As String = "BaseFile.xlsx"
    Const BASE_TARGET_COL   As Long = 1
    Const CHECK_FILE_NAME   As String = "CheckFile.xlsx"
    Const CHECK_TARGET_COL  As Long = 1

ここでは、ファイル名と列番号を定数として定義しています。

Const は、後から値を変更しない前提の固定値を定義するときに使います。このように定数としてまとめておくことで、ファイル名や対象列をあとから変更したい場合に、コード全体の修正箇所を最小限に抑えることができます

ここでは、BaseFile.xlsx の 1列目と、CheckFile.xlsx の 1列目を照合の対象とする設定になっています。別のファイル名や列番号に変更する場合は、この部分だけを書き換えれば対応できます。

この記事の読者の皆さんの環境に合わせて調整しやすいよう、コメントでその意図も明示しています。

    ' Base File (基準ファイル)を開く
    base_fp = ThisWorkbook.Path & "\" & BASE_FILE_NAME
    Set base_wb = Workbooks.Open(base_fp)
    Set base_ws = base_wb.Worksheets(1)
    base_last_row = base_ws.Cells( _
        base_ws.Rows.Count, BASE_TARGET_COL _
    ).End(xlUp).Row
    
    ' Check File (チェック対象ファイル)を開く
    check_fp = ThisWorkbook.Path & "\" & CHECK_FILE_NAME
    Set check_wb = Workbooks.Open(check_fp)
    Set check_ws = check_wb.Worksheets(1)
    check_last_row = check_ws.Cells( _
        check_ws.Rows.Count, CHECK_TARGET_COL _
    ).End(xlUp).Row

ここでは、基準ファイルとチェック対象ファイルを順に開き、それぞれの最終行を取得しています。

ファイルは、マクロファイル(ThisWorkbook)と同じフォルダ内にあるという前提で、パスを連結して開いています。Set を使ってワークブックとワークシートのオブジェクトを取得したあと、対象列の最終行を End(xlUp) を使って求めています。

なお、End(xlUp) は「下から上に向かって最初にデータが見つかるセル」を探すExcelの動作を利用した方法です。これにより、実際にデータが入力されている最下行を取得できます。

このようにして、各ファイルのデータ範囲の終端を正確に把握してから、照合処理に入る流れになっています。

    ' Base File の行をループ
    For base_row = 1 To base_last_row
        
        ' Base File の値を変数に代入
        base_value = base_ws.Cells(base_row, BASE_TARGET_COL)
            
        ' Check File の行をループ
        For check_row = 1 To check_last_row
            
            ' Check File の値を変数に代入
            check_value = check_ws.Cells(check_row, CHECK_TARGET_COL)
            
            ' Base File の値と Check File の値が一致したら
            If base_value = check_value Then
                
                ' ここに行いたい処理を書く
                Debug.Print check_row, check_value
            
            End If
        
        Next check_row
    
    Next base_row

ここでは、For...Next ステートメントを使用して2つのファイルのデータを総当たりで照合しています。

まず、BaseFile.xlsx の指定列を上から順にループし、各セルの値を base_value に代入します。次に、CheckFile.xlsx 側でも同様に、各行の値を check_value に取り出し、両者を比較します。

もし値が一致した場合には、処理ブロック内の Debug.Print により、行番号と値がイミディエイトウィンドウに出力されます。この部分には、目的に応じて任意の処理(書式変更、別シートへの出力など)を追加することができます。

なお、ここで使用しているループはいわゆる「総当たり」の比較であり、行数が多くなると処理時間が長くなる傾向があります。必要に応じて、配列を利用して処理を高速化することもできます。

    ' Cleanup
    base_wb.Close SaveChanges:=False
    check_wb.Close SaveChanges:=False

ここでは、開いたファイルを保存せずに閉じています。SaveChanges:=False は、保存をせずにファイルを閉じる設定を指します。今回の処理ではファイルに変更は加えていませんが、保存するのかしないのか、意思を持ったコードとするために指定しています。

運営者・ポテ

以上で、解説は終了です。ありがとうございました!

関連記事

本稿と関連の深い記事です。もしよろしければ、合わせてご活用ください。

VBAプログラミングスキルアップのための参考情報

ここでは参考図書を紹介いたしますが、これらに限らず自分に合うものを選ぶことが重要だと考えております。皆様の、より一層のご成功を心よりお祈りしております。

VBAプログラミングのスキルアップ

学習用としてもハンドブックとしても役立つ便利な書籍がこちらです。価格はやや高めですが、その内容は非常に充実しています。相応のスキルを身に付けるためには、こうしたしっかりとした書籍を一冊持っておくと良いでしょう。



入門書に関しては、どの書籍も大きな違いはありません。あまり迷うことに時間をかけるよりは、手頃なものを一冊選んでみると良いでしょう。VBAの入門書は数多く出版されていますので、興味がある方はぜひチェックしてみてください。

甲乙つけがたい場合、私はインプレス社の「いちばんやさしい」シリーズを選ぶことが多いです。

\チェックしてみよう/

\チェックしてみよう/

\チェックしてみよう/


VBAのプログラミング能力を客観的に証明したい場合には「VBAエキスパート試験」があります。この試験はVBAの知識を公式に認定するものです。VBAの総合的な能力獲得を目指す方に適しています。以下の公式テキストが販売されております。



プログラミングの一般教養

「独学プログラマー」というプログラミングの魅力を解説した書籍があります。これはVBAではなくPythonを題材としていますが、プログラミングの基本的な知識や思考法、仕事の進め方まで幅広く学べます。


こちらの記事でも紹介しております。もしよろしければご覧ください。

QRコード
【QRコード】PC<-->スマホの切り替えにご利用ください

相談無料】VBAアプリケーション作成のご相談を承ります

運営者・ポテ

いつもありがとうございます!

限られた時間をより良く使い、日本の生産性を高めたい──
この取り組みが、社会全体の課題を解決する一歩になると信じています。

みんなの実用学では、「時間はもっとも大切な資源」と考え、クライアント様の業務課題解決のお手伝いをさせていただいております。

その一環として、クラウドソーシングサービス「ランサーズ」を通じて、VBAやGAS(Google Apps Script)による業務支援アプリケーションの作成を行っています。

Information

ランサーズ
日本最大級のクラウドソーシングサービスで、企業や個人がフリーランスに仕事を依頼できるプラットフォームです。

ご相談は無料です。お気軽にお問い合わせください。


こちらの記事でも紹介しておりますので、もしよろしければ、ご覧ください。

おわりに

運営者・ポテ

ご覧いただきありがとうございました!

本稿では、「異なるファイル間でのデータマッチング(照合・突合)第2版」をお届けいたしました。

お問い合わせやご要望等ございましたら、「お問い合わせ/ご要望」またはコメントにて、ご連絡いただければ幸いでございます。

皆様の人生がより一層素晴らしいものになるよう、少しでもお役に立てれば幸いでございます。

なお、当サイトでは様々な情報を発信しております。もしよろしければ、トップページもご確認いただけると幸いでございます。

この記事を書いた人

運営者・ポテ
■人生を追求する凡人■日本一安全で、気の向くままに自分の時間を過ごせる、こだわりのキャンプ場を作るのが夢■光学・機械系エンジニア(歴20年、内マネジメント10年、特許数件権利化)/副業フリーランスエンジニア■読書・文学愛好■人生は時間そのもの。ひとりでも多くの人が「より良い人生にするために時間を使って欲しい」と願い、仕事のスキルの向上、余暇の充実、資産形成を研究。■VBAアプリ開発サービス提供中(業務委託 / VBA使用経験20年)■Python愛好(歴5年)■VBAエキスパート「Excel VBA スタンダード」(上級者向け資格)/ Python 3 エンジニア認定基礎(経済産業省「ITスキル標準(ITSS)」に掲載)

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です