Excelのデータを検索し、その結果に基づいてAccessのテーブルを更新する

2023年3月4日

Accessを使用している場合、Excelで保持しているデータを利用して、Accessのテーブルを更新させるケースが出てきます。全てのテーブルを更新する場合は、データ全体を置き換えることで問題を解決できますが、一部のみを更新する場合は、VBAを使用してプログラムを作成する必要があります。このため、今回はAccess側からExcelのデータを検索し、その結果に基づいてAccessのテーブルを更新するアプリケーションを紹介します。

サンプルアプリの説明

社員一覧テーブルの勤務地について、参照先Excelシートのデータに基づいて更新をかけます。
下記の例では社員No「001」、「005」、「013」の社員勤務地を参照先Excelシートのデータに基づいて、それぞれ「福井県」→「名古屋」、「東京都」→「名古屋」、「東京都」→「名古屋」に置き換えます。

サンプルアプリの作成方法

・「作成」メニューから「標準モジュール」を選択します。

・ VBE(Visual Basic Editor)と呼ばれるエディターが開きますので、
  パソコンにインストールされているライブラリをVBAから使えるように参照設定を行います。

・ 下記赤枠のライブラリにレ点マークを付けて利用できるようにします。

・ 下記赤枠の箇所に下のサンプルアプリのコードを記述します。

記述できたらコード内にカーソルを置いて、緑色の「▶」ボタンをクリックします。
メニュー画面を作成してボタンから実行したい場合は こちらの記事 をご覧ください。

・ コードが実行され参照先Excelファイルの選択が求められますので、
  選択して「開く」ボタンを押すとテーブルが更新されます。

サンプルコードの解説

処理の大まかな流れは以下の通りです。詳細につきましてはサンプルアプリのコードに書かれているコメントをご覧ください。

 Accessの社員一覧テーブルを開く
    ↓
 読み込み先Excelファイルを選択する
    ↓
 テーブルのレコードを1行ずつ読み込み、検索キーとなる社員Noをキーに
 参照先Excelシートのデータを検索して、該当するデータがあったら
 勤務地フィールドを更新する
    ↓
 社員一覧テーブルを閉じて、オブジェクトをクリアする
    ↓
 参照先のExcelを保存せずに閉じる
    ↓
 処理完了メッセージを表示する

サンプルアプリのコード   ACCESSのプログラミング概要

Sub ImportExcelData()

    'Accessオブジェクトを作成
    Dim acApp As Object
    Set acApp = CreateObject("Access.Application")
    
    'Accessデータベースを開く
    acApp.OpenCurrentDatabase Application.CurrentProject.FullName
    
    'Accessの社員一覧テーブルを開く
    Dim acTable As Object
    Set acTable = acApp.CurrentDb.OpenRecordset("社員一覧")

    'ワークブックオブジェクト変数の定義
    Dim wb As Workbook 
    '読込み先ファイルのパスを格納する変数を定義
    Dim fn As String
    
    '読み込み先Excelファイルを選択するためのダイアログを表示させます。
    Dim dlg As FileDialog
    Set dlg = Application.FileDialog(msoFileDialogFilePicker)
    dlg.Filters.Clear
    dlg.Filters.Add "Excel ファイル", "*.xlsx"
    dlg.Title = "検索先Excel ファイルを選択して下さい。"
    If dlg.Show = -1 Then
      fn = dlg.SelectedItems(1)
    End If
    
    ' ファイル選択でキャンセルを選択した場合の処理
    If fn = "" Then
       MsgBox "キャンセルしました。"
       Exit Sub
    End If

    '参照先Excelファイルをwb変数に設定します。
    Set wb = Workbooks.Open(FileName:=fn, UpdateLinks:=0)
    '(UpdateLinks:=0 にすると、リンクを更新せずに開きます。)
    
    '参照先Excelファイルのシート名(Sheet1)をws変数に設定
    Dim ws As Worksheet
    Set ws = wb.Sheets("Sheet1")
    
    'カウント変数の定義
    Dim i As Long
    'テーブルのレコード数分をループ
    For i = 1 To acTable.recordCount
    
        'レコードから検索キーを取得
        Dim searchValue As String
        searchValue = acTable("社員No").Value
        
        'Excelから該当する行のデータを検索
        Dim foundRow As Range
        Set foundRow = ws.Range("A:A").Find(searchValue) ' 検索範囲や条件に応じて変更
        
        '検索の結果Excel上に該当するデータが見つかったらデータを取得してAccessのテーブルに書き込む
        If Not foundRow Is Nothing Then
        
            'Excel上の該当するデータを取得
            Dim rowData As Variant
            rowData = foundRow.EntireRow.Value
                        
            'Excelの5列目のデータをAccessの"勤務地フィールド"に書き込む
            acTable.Edit
            acTable("勤務地").Value = rowData(1, 5)
            
            '社員一覧テーブルを更新
            acTable.Update
        End If
        
        '次のレコードに移動
        acTable.MoveNext
          
        'ステータスバーに処理件数を表示
        SysCmd acSysCmdSetStatus, "処理件数: " & i - 1
        
    Next i
    
    '社員一覧テーブルを閉じて、オブジェクトをクリアする
    acTable.Close
    Set acTable = Nothing
        
    '参照先のExcelを保存せずに閉じる
    wb.Close saveChanges:=False
    
    'ステータスバーをクリアする
    SysCmd acSysCmdClearStatus
        
    '完了メッセージを表示する
    MsgBox "処理が完了しました。" & vbCrLf & "処理件数は" & i - 1 & "件です。", vbOKOnly + vbInformation, "処理完了"
    
End Sub

今回の処理とは逆にExcelのデータをAccessのテーブルのデータに基づいて更新する方法は以下のリンク先をご覧ください。
  https://scodebank.com/?p=1140