【ExcelVBA】Excelのシートにデータ件数分のチェックボックスを追加してAccessのDBの値で制御するには

この記事では、Excelのシートにデータ件数分のチェックボックスを追加してAccessのDBの値で制御する方法についてご説明します。

【動画】Excelのシートにデータ件数分のチェックボックスを追加してDBの値で制御する実際の動き

本題に入る前に、まずは次の動画をご覧ください。


マクロがAccessのDBのテーブルデータを取得し、そのデータをシートに出力します。

また、テーブルデータの値を判定し、マクロが自動で生成したチェックボックスにチェックを付けていきます。

今回のサンプルでは、フィールド「フラグ」の値が1の場合はチェックを付け、0の場合はチェックを付けません。

マクロ作成の流れ

STEP.1
AccessのDBのテーブルデータを取得する
AccessのDBのテーブルデータを取得します。
STEP.2
STEP.1で取得したテーブルデータをシートに出力する
STEP.1で取得したテーブルデータをシートに出力します。
STEP.3
STEP.1で取得したテーブルデータの件数分チェックボックスをシートに生成する
STEP.1で取得したテーブルデータの件数分チェックボックスをシートに生成します。
STEP.4
STEP.1で取得したテーブルデータの値を判定し、値によってチェックボックスにチェックを付ける
STEP.1で取得したテーブルデータの値を判定し、値によってチェックボックスにチェックを付けます。
今回のサンプルでは、フィールド「フラグ」の値が1の場合はチェックを付け、0の場合はチェックを付けません。

Excelファイルの例

今回は次のExcelファイルを用意しました。

また、今回用意したAccessのDBのテーブルは下の通りです。

マクロを実行すると下の通りに出力されます。

マクロがAccessのDBにある「T_社員」テーブルのデータを取得してシート「data」の表に出力されています。

また、A列にチェックボックスをマクロが生成し、フィールド「フラグ」の値が1の場合はチェックボックスにチェックを付けています。0の場合はチェックを付けません。

コードの例

Option Explicit

Private Sub btn_exec_Click()

    Dim DbName      As String                   'データベース名
    Dim adoCON      As ADODB.Connection         'Connection用変数
    Dim adoRS       As ADODB.Recordset          'レコードセット用変数
    Dim sqlStr      As String                   'SQL文
    Dim cnt         As Long                     'カウンタ
    Dim obj         As Object                   'シェイプ・コントロール用変数
    Dim rng         As Range                    'Rangeオブジェクト格納用変数
    Dim cell        As Range                    'セル用変数
    Dim top         As Double                   'チェックボックスの上端位置を格納する変数
    Dim leftPos     As Double                   'チェックボックスの左端位置を格納する変数
    Dim cb          As CheckBox                 'チェックボックス用変数
    
    'データの先頭行位置
    Const bgnRPos   As Long = 4
    
    '取得元のテーブル名
    Const tblNM     As String = "T_社員"
        
    'カレントディレクトリのデータベースパスを取得
    DbName = ActiveWorkbook.Path & "\" & "0237.mdb"
    
    'シートをクリアする
    Worksheets("data").Range("A3:H1000").ClearContents
    
    With Worksheets("data")
    
        'シート「data」上のシェイプ・コントロールの数分だけループ
        For Each obj In .Shapes
        
            If InStr(obj.Name, "test_cbx") > 0 Then
            
                '「test_cbx」の文字列を含むコントロールの場合
            
                'コントロールを削除する
                obj.Delete
            
            End If
        
        Next obj
        
    End With
    
    'Connectionオブジェクトのインスタンスを生成する
    Set adoCON = CreateObject("ADODB.Connection")
    
    'データベース接続情報の取得
    adoCON.ConnectionString = "provider=Microsoft.ACE.OLEDB.12.0;" _
                            & "Data Source=" _
                            & DbName & ""
    
    'Accessに接続する
    adoCON.Open
 
    'Recordsetオブジェクトのインスタンスを生成する
    Set adoRS = CreateObject("ADODB.Recordset")
    
    'クライアントサイドカーソルに変更
    adoRS.CursorLocation = adUseClient
    
    '先ほど取得したデータベース接続情報が設定されているadoCONをActiveConnectionプロパティに設定し、
    'ConnectionオブジェクトとRecordsetオブジェクトを関連付ける
    '⇒Recordsetオブジェクトを開いたり操作するのに必要な設定
    adoRS.ActiveConnection = adoCON
    
    'カーソルを開く
    adoRS.Open tblNM, adoCON
        
    'Accessからテーブルデータを取得するSQL文を作成
    sqlStr = "SELECT "
    
    For cnt = 0 To adoRS.Fields.Count - 1
    
        Select Case True
    
            Case adoRS.Fields.Item(cnt).Name <> "フラグ"
            
                'フィールドが「フラグ」ではない場合
    
                '列名をSELECT文に使う
                sqlStr = sqlStr & adoRS.Fields.Item(cnt).Name & ","
                
                'フィールド名をシートに出力する
                Worksheets("data").Cells(bgnRPos - 1, cnt + 2).Value = adoRS.Fields.Item(cnt).Name
        
            Case Else
            
            End Select
        
    Next
    
    '末尾の「'」を削除
    sqlStr = left(sqlStr, Len(sqlStr) - 1)
    
    sqlStr = sqlStr & " FROM " & tblNM
    sqlStr = sqlStr & " ORDER BY 社員番号 ASC"
    
    'フィールド名が取得できたので一度レコードセットを閉じる
    adoRS.Close
    
    'SELECT文を実行して、Recordsetオブジェクトにデータをロード
    adoRS.Open sqlStr, adoCON
    
    'recordsetの値をシートのセルに出力する
    Worksheets("data").Range("B" & bgnRPos).CopyFromRecordset adoRS
        
    'フィールド名が取得できたので一度レコードセットを閉じる
    adoRS.Close
        
    'Accessから、チェックボックスの付与を行うのに必要な判断情報を取得するSQL文を作成
    sqlStr = "SELECT 社員番号, フラグ FROM " & tblNM
    sqlStr = sqlStr & " ORDER BY 社員番号 ASC"
        
    'SELECT文を実行して、Recordsetオブジェクトにデータをロード
    adoRS.Open sqlStr, adoCON
    
    'カウンタを初期化する
    cnt = 0
    
    'チェックボックスを設置するセルの範囲を取得する
    Set rng = Worksheets("data").Range("A" & bgnRPos & ":A" & CStr(bgnRPos + adoRS.RecordCount - 1))
    
    For Each cell In rng
        
        cnt = cnt + 1
        
        'チェックボックスの上端位置を取得する(セルの縦位置の中央に設置)
        '→(セルのHeightの中央値に設定し、さらに微調整分マイナスする)
        top = cell.top + (cell.Height / 2) - 9
        
        'チェックボックスの左端位置を取得する
        leftPos = cell.left
        
        'チェックボックスを生成して配置する
        Set cb = Worksheets("data").CheckBoxes.Add(leftPos, top, 0, 0)
        
        'チェックボックスのキャプションを空にする
        cb.Caption = ""
        
        'チェックボックスに名前を付ける(重複しないよう項番も付与する)
        cb.Name = "test_cbx" & cnt
        
        If adoRS.Fields("フラグ").Value = 1 Then
        
            '「フラグ」という名前のフィールドの値が1の場合
            
            ' チェックボックスにチェックを付ける
            cb.Value = xlOn
        
        End If
        
        ' 次のレコードに移動
        adoRS.MoveNext
        
        DoEvents
        
    Next cell
    
    'レコードセットを閉じる
    adoRS.Close
    
    '後処理
    Set adoCON = Nothing
    Set adoRS = Nothing
    Set obj = Nothing
    Set cb = Nothing

End Sub

注目すべきコード①

最初に見て頂きたいのは18行目です。

    'データの先頭行位置
    Const bgnRPos   As Long = 4

コードの説明

以上のコードは、取得したAccessのDBのテーブルデータをシートの何行目から出力するのかその開始行を取得するコードです。

今回は4を設定していますが、値が4の場合は4行目からデータが出力されます。

注目すべきコード②

次に見て頂きたいのは24行目です。

    'カレントディレクトリのデータベースパスを取得
    DbName = ActiveWorkbook.Path & "\" & "0237.mdb"

コードの説明

以上のコードは、データを取得するAccessのDBファイルのフルパスを取得するコードです。

注目すべきコード③

次に見て頂きたいのは29行目から45行目です。

    With Worksheets("data")
    
        'シート「data」上のシェイプ・コントロールの数分だけループ
        For Each obj In .Shapes
        
            If InStr(obj.Name, "test_cbx") > 0 Then
            
                '「test_cbx」の文字列を含むコントロールの場合
            
                'コントロールを削除する
                obj.Delete
            
            End If
        
        Next obj
        
    End With

コードの説明

以上のコードは、本マクロを1度実行して生成されたチェックボックスを削除する処理のコードです。

これから新たにチェックボックスを設置したいので、設置されたチェックボックスは削除しておきます。

コードの詳細

32行目のコードでは、シート「data」上のシェイプ・コントロールの数分だけ処理を繰り返すFor文を用意し、その中で「test_cbx」の文字列が含まれた名前のチェックボックスだけを削除します。

なお、今回のマクロで設置するチェックボックスには、「test_cbx」という文字列が含まれた名前を付けています。(147行目)

        'チェックボックスに名前を付ける(重複しないよう項番も付与する)
        cb.Name = "test_cbx" & cnt

「test_cbx」という文字列を含めることで、チェックボックスを削除するのに特定がしやすくなります。(他のコントロールは削除しないようにする)

削除するチェックボックスを特定するために、34行目でInStr関数を使ってコントロールに「test_cbx」の文字列が含まれているか判定します。

「test_cbx」の文字列が含まれている場合は、39行目でそのコントロールを削除します。

注目すべきコード④

次に見て頂きたいのは48行目から56行目です。

    'Recordsetオブジェクトのインスタンスを生成する
    Set adoCON = CreateObject("ADODB.Connection")
    
    'データベース接続情報の取得
    adoCON.ConnectionString = "provider=Microsoft.ACE.OLEDB.12.0;" _
                            & "Data Source=" _
                            & DbName & ""
    
    'Accessに接続する
    adoCON.Open

コードの説明

以上のコードは、マクロがAccessのDBに接続するための接続情報を取得して接続するコードです。

コードの詳細

48行目のコードでは、Connectionインスタンスを生成します。

このインスタンスがないとマクロがAccessのDBに接続することができないので必ず生成しておきます。

51行目から53行目で接続情報を取得し、56行目でOpenメソッドを実行してマクロがAccessのDBに接続します。

注目すべきコード⑤

次に見て頂きたいのは59行目から70行目です。

    'Recordsetオブジェクトのインスタンスを生成する
    Set adoRS = CreateObject("ADODB.Recordset")
    
    'クライアントサイドカーソルに変更
    adoRS.CursorLocation = adUseClient
    
    '先ほど取得したデータベース接続情報が設定されているadoCONをActiveConnectionプロパティに設定し、
    'ConnectionオブジェクトとRecordsetオブジェクトを関連付ける
    '⇒Recordsetオブジェクトを開いたり操作するのに必要な設定
    adoRS.ActiveConnection = adoCON
    
    'カーソルを開く
    adoRS.Open tblNM, adoCON

コードの説明

以上のコードは、Recordsetオブジェクトのインスタンスを生成し、マクロがAccessのDBに接続する処理のコードです。

コードの詳細

59行目のコードでは、Recordsetオブジェクトのインスタンスを生成します。

このインスタンスがないとマクロがAccessのDBのテーブルからデータを取得することができないので必ず生成しておきます。

Recordsetオブジェクトのインスタンスが生成されると、マクロが接続したAccessのDBのテーブルに対してSQLのSELECT文を実行することができます。

62行目でクライアントサイドカーソルに変更し、67行目でConnectionオブジェクトとRecordsetオブジェクトを関連付けます。

70行目でマクロがAccessのDBを開き、テーブルを参照します。

注目すべきコード⑥

次に見て頂きたいのは73行目から99行目です。

    'Accessからテーブルデータを取得するSQL文を作成
    sqlStr = "SELECT "
    
    For cnt = 0 To adoRS.Fields.Count - 1
    
        Select Case True
    
            Case adoRS.Fields.Item(cnt).Name <> "フラグ"
            
                'フィールドが「フラグ」ではない場合
    
                '列名をSELECT文に使う
                sqlStr = sqlStr & adoRS.Fields.Item(cnt).Name & ","
                
                'フィールド名をシートに出力する
                Worksheets("data").Cells(bgnRPos - 1, cnt + 2).Value = adoRS.Fields.Item(cnt).Name
        
            Case Else
            
            End Select
        
    Next
    
    '末尾の「'」を削除
    sqlStr = left(sqlStr, Len(sqlStr) - 1)
    
    sqlStr = sqlStr & " FROM " & tblNM
    sqlStr = sqlStr & " ORDER BY 社員番号 ASC"

コードの説明

以上のコードは、Accessからテーブルデータを取得するSQL文を作成する処理のコードです。

コードの詳細

73行目のコードは、SELECT文の「SELECT(句)」です。

75行目のコードは、参照するテーブルのフィールド数分処理を繰り返すForです。

84行目のコードで、参照するテーブルのフィールド名を取得してSELECT文を組み立てます。

なお、取得したフィールド名は「,」(カンマ)区切りでSELECT文を組み立てていきます。

87行目ではSELECT文の組み立ての処理とは関係ないですが、ここまででフィールド名が取得できたので、シートにフィールド名を出力します。

また、取得したフィールド名は「,」(カンマ)区切りでSELECT文を組み立てていきますが、最後のフィールド名にも後ろに「,」が付いているので、その「,」を除去します。(96行目)

98行目のコードではFROM句を、99行目のコードではORDER BY句をつなげてSELECT文を組み立てます。

以上でSELECT文を組み立てることができました。

注目すべきコード⑦

次に見て頂きたいのは102行目です。

    'フィールド名が取得できたので一度レコードセットを閉じる
    adoRS.Close

以上のコードは、Recordsetを閉じる処理のコードです。

ここまでで開いたRecordsetはフィールド名を取得するためであり、この先は組み立てたSELECT文を実行するのにまたRecordsetを開く必要があります。

ただしそのままSELECT文を実行するのにRecordsetを開こうとすると、すでにRecordsetが開かれているとエラーになってしまいます。

なのでここで1度Recordsetを閉じておきます。

注目すべきコード⑧

次に見て頂きたいのは105行目から108行目です。

    'SELECT文を実行して、Recordsetオブジェクトにデータをロード
    adoRS.Open sqlStr, adoCON
    
    'recordsetの値をシートのセルに出力する
    Worksheets("data").Range("B" & bgnRPos).CopyFromRecordset adoRS

コードの説明

以上のコードは、「注目すべきコード⑥」で組み立てたSELECT文を実行し、取得した値をシートのセルに出力する処理のコードです。

CopyFromRecordsetプロパティに、recordset用変数「adoRS」を指定することで、SELECT文で抽出したデータをExcelのシートのセルに出力することができます。

注目すべきコード⑨

次に見て頂きたいのは114行目から118行目です。

    'Accessから、チェックボックスの付与を行うのに必要な判断情報を取得するSQL文を作成
    sqlStr = "SELECT 社員番号, フラグ FROM " & tblNM
    sqlStr = sqlStr & " ORDER BY 社員番号 ASC"
        
    'SELECT文を実行して、Recordsetオブジェクトにデータをロード
    adoRS.Open sqlStr, adoCON

コードの説明

以上のコードは、フィールド「フラグ」の値を取得するSELECT文を組み立てて実行する処理のコードです。

フィールド「フラグ」の値は、チェックボックスにチェックを付けるかどうかを判定するのに使います。

チェックボックスにチェックを付けるかどうか判定しているコードは146行目で行ってます。

        If adoRS.Fields("フラグ").Value = 1 Then

注目すべきコード⑩

次に見て頂きたいのは124行目です。

    'チェックボックスを設置するセルの範囲を取得する
    Set rng = Worksheets("data").Range("A" & bgnRPos & ":A" & CStr(bgnRPos + adoRS.RecordCount - 1))

コードの説明

以上のコードは、チェックボックスを配置するセルの範囲を取得するコードです。

注目すべきコード⑪

次に見て頂きたいのは126行目です。

    For Each cell In rng

コードの説明

以上のコードは、「注目すべきコード⑩」で説明したチェックボックスを配置する範囲のセルを一つ一つ繰り返し取得するFor文のコードです。

セルを取得する目的はセルの上端位置と左端位置が欲しいためです。

上端位置と左端位置については詳しくは「注目すべきコード⑫」でご説明します。

注目すべきコード⑫

次に見て頂きたいのは132行目から135行目です。

        'チェックボックスの上端位置を取得する(セルの縦位置の中央に設置)
        '→(セルのHeightの中央値に設定し、さらに微調整分マイナスする)
        top = cell.top + (cell.Height / 2) - 9
        
        'チェックボックスの左端位置を取得する
        leftPos = cell.left

コードの説明

以上のコードは、セルの上端位置と左端位置を取得し、その位置からチェックボックスを設置するチェックボックスの上端位置と左端位置を決めます。

今回のサンプルでは、チェックボックスの上端位置は、配置するセルの上端から真ん中に設定しています。

また、チェックボックスの左端位置は、配置するセルの左端位置と同じにしています。

注目すべきコード⑬

次に見て頂きたいのは138行目です。

        'チェックボックスを生成して配置する
        Set cb = Worksheets("data").CheckBoxes.Add(left, top, 0, 0)

以上のコードは、セルにフォームコントロールのチェックボックスを配置している処理のコードです。

CheckBoxes.Addメソッドに左端位置、上端位置、横幅、縦幅の4つの値を引数に設置して実行することでセルにフォームコントロールのチェックボックスが配置されます。

今回のサンプルでは横幅、縦幅には0を設定しています(チェックボックスの□だけが欲しいので(チェックボックスの文言部分は使わない))

注目すべきコード⑭

次に見て頂きたいのは141行目から144行目です。

        'チェックボックスのキャプションを空にする
        cb.Caption = ""
        
        'チェックボックスに名前を付ける(重複しないよう項番も付与する)
        cb.Name = "cbx" & cnt

コードの説明

以上のコードは、配置されたチェックボックスのキャプションと名前の設定を行っている処理のコードです。

コードの詳細

141行目では、チェックボックスのキャプションを空にしています。

チェックボックスが配置された直後は、デフォルトでキャプションが設定されており表示されます。

今回のサンプルでは□だけの表示にしたいのでキャプションは何も設定しないようCaptionプロパティにブランクを設定しています。

144行目では、チェックボックスに名前を付けています。

今回のサンプルでは複数設置しているので、フォームコントロールのチェックボックスの名前が重複しないよう「test_cbx」という名前にカウンタの値をつなげて名前を一意にしています。

注目すべきコード⑮

次に見て頂きたいのは146行目から153行目です。

        If adoRS.Fields("フラグ").Value = 1 Then
        
            '「フラグ」という名前のフィールドの値が1の場合
            
            ' チェックボックスにチェックを付ける
            cb.Value = xlOn
        
        End If

コードの説明

以上のコードは、フィールド「フラグ」の値を判定し、合致する場合はチェックボックスにチェックを付ける処理のコードです。

フィールド「フラグ」の値が1の場合はチェックボックスにチェックを付けます。

フィールド「フラグ」の値が1出ない場合はチェックボックスにはチェックを付けません。

コードの詳細

146行目のコードでは、フィールド「フラグ」の値が1かどうか判定し、1の場合は151行目でチェックボックスにチェックを付けます。

フィールド「フラグ」の値が1以外の場合は何もしません。

動作確認

今回は以下のExcelファイルを用意しました。

また、今回用意したAccessのDBのテーブルは下の通りです。

マクロ実行後

マクロを実行すると下の通りに出力されます。

マクロがAccessのDBにある「T_社員」テーブルのデータを取得してシート「data」の表に出力されました。

また、A列にチェックボックスをマクロが生成し、フィールド「フラグ」の値が1の場合はチェックボックスにチェックを付けられました。

0の場合はチェックが付いていません。

最後に

この記事では、Excelのシートにデータ件数分のチェックボックスを追加してAccessのDBの値で制御する方法についてご説明しました。

AccessのDBのテーブルにあるデータを表示させたい場合、そしてAccessのDBのテーブルにあるフィールドの値によってシート上のテキストボックスにチェックを付けるか付けないか制御して表示させたい場合は本記事を参考にしてみてくださいね。

プログラミングのスキルを習得するなら

プログラミングのスキルを習得したい、今のスキルをもっと高めたい、そう考えているなら「プログラミングスクール」がおすすめです。

プログラミングのスキルの基礎を身につけるなら「TechAcademy」で1週間の無料体験があるので、これで「プログラミングの基礎」を学ぶのにおすすめですよ。

→ TechAcademyの「1週間 無料体験」はこちら