LoginSignup
42
61

More than 3 years have passed since last update.

【VBA】ADOを使用してExcel表をDB操作する方法のまとめ(範囲指定、書き込みなど)

Last updated at Posted at 2020-11-09

はじめに

この記事は、ADO(ActiveX Data Objects)を使用して、ExcelファイルSQL文で操作する方法のまとめです。
大半はよくある内容ですが、ワークシートの読み込みから、DBとしての更新処理まで、自身の備忘を兼ねて残しておきます。

なお、ADO(ActiveX Data Objects)とは「データベース操作のためのパッケージ(API)」のことです(詳しくはIT用語辞典 ADOを参照してください)。

<目次>
1. 基本的なサンプルコード
 1-1. シート全体をテーブルとして取得する場合
 1-2. シートの一部をテーブルとして取得する場合
2. 各コードの説明
 2-1. 外部ライブラリの機能を持ったオブジェクト変数(インスタンス)の作成
 2-2. ADO接続
 2-3. SQL文で抽出したデータをレコードセットで開く
 2-4. レコードセットの中身を確認する
3. ワークシートのデータを更新する方法
 3-1. ファイルを開いてレコードを書き込む(CopyFromRecordsetメソッド)
 3-2. ファイルを開かずにレコードを書き込む(Update、UpdateBatchメソッド)

1. 基本的なサンプルコード

1-1. シート全体をテーブルとして取得する場合

まず、基本として、ワークシート全体をテーブルとして取得してSQL文で操作する場合です。
次のようなExcel表をサンプルとして使用します。
2020-11-08 212220.png
この記事においては、「表を記載したファイル」と「VBAを記載するファイル」は別々にして、同じフォルダに保存しています。
参考までに、私の手元では、次のような構成としています。

用途 ファイル名 ディレクトリ(フルパス)
VBAを記録するファイル ADOTest.xlsm C:\VBA\ADOTest.xlsm
表を記載するファイル TestTable.xlsx C:\VBA\TestTable.xlsx

1-1-1. 参照設定をしない場合

最初に、参照設定をしない場合の例です。
つまり、VBAで事前の設定をしなくても書けるコードです。

サンプルコード1(参照設定をしない場合)
Sub Sample1()
    '外部ライブラリからインスタンスを作成(実行時バインディング)
    Dim cn As Object
    Dim rs As Object
    Set cn = CreateObject("ADODB.Connection")
    Set rs = CreateObject("ADODB.Recordset")

    'ADO接続
    cn.Provider = "Microsoft.ACE.OLEDB.12.0"
    cn.Properties("Extended Properties") = "Excel 12.0"
    cn.Open ThisWorkbook.Path & "\" & "TestTable.xlsx"

    'SQL文の実行
    rs.Open "SELECT * FROM [Sheet1$] ORDER BY 単価", cn

    '取得した内容(Recordset)の確認
    Do Until rs.EOF
        Debug.Print rs!品名 & ", " & rs!単価
        rs.MoveNext
    Loop

    'メモリの解放(無くとも構わない)
    rs.Close
    Set rs = Nothing
    cn.Close
    Set cn = Nothing
End Sub

Excel表の1行目部分を自動的にカラム名として読み取って、レコードセット(rs)に格納しています。
レコードの内容は、rs![カラム名]という形で取得することができます。
詳細は後述します。

<出力結果>

イミディエイト
みかん, 40
じゃがいも, 50
にんじん, 70
りんご, 150
キャベツ, 180
バナナ, 300
メロン, 1500

SQL文のORDER BY句で、単価の昇順に並べ替えがされています。

イミディエイト ウィンドウが表示されない場合は、VBAのメニュー「表示」から「イミディエイト ウィンドウ」を選択してください。

1-1-2. 参照設定をする場合

次に、参照設定をする場合の例です。
参照設定をするには、VBAメニューの「ツール(T)」から「参照設定(R)」を開きます。
2020-11-08 122610.png
参照設定の画面で、次のようにMicrosoft ActiveX Data Object X.X LibraryをチェックしてOKボタンを押せば完了です(ここではバージョンは6.1を選択しています)。
2020-11-08 122928.png
この設定により、プログラムの実行前に、ActiveX Data Object (ADO)ライブラリを読み込むことになります。

記載するソースコードは、以下のとおりです。
前の例と異なるのは、最初の2行のインスタンス作成部分だけです。
細かい説明は後述します。

サンプルコード2(参照設定をする場合)
Sub Sample2()
    'インスタンスを作成(事前バインディングの場合)
    Dim cn As New ADODB.Connection
    Dim rs As New ADODB.Recordset

    'ADO接続
    cn.Provider = "Microsoft.ACE.OLEDB.12.0"
    cn.Properties("Extended Properties") = "Excel 12.0"
    cn.Open ThisWorkbook.Path & "\" & "TestTable.xlsx"

    'SQL文の実行
    rs.Open "SELECT * FROM [Sheet1$] ORDER BY 単価", cn

    '取得した内容(Recordset)の確認
    Do Until rs.EOF
        Debug.Print rs!品名 & ", " & rs!単価
        rs.MoveNext
    Loop

    'メモリの解放(無くとも構わない)
    rs.Close
    Set rs = Nothing
    cn.Close
    Set cn = Nothing
End Sub

(出力結果は同じなので省略)

1-2. シートの一部をテーブルとして取得する場合

次に、ワークシートの一部をテーブルとして取得してSQL文で操作する場合です。
次のようなExcel表をサンプルとして使用します。
2020-11-08 212508.png
このような場合は、赤枠の部分(B4からF11の間のデータ)をテーブルとして取得する必要があります。
コードを書くと次のとおりです。

サンプルコード3(ワークシートの範囲を指定する場合)
Sub Sample3()
    'インスタンスを作成(事前バインディングの場合)
    Dim cn As New ADODB.Connection
    Dim rs As New ADODB.Recordset

    'ADO接続
    cn.Provider = "Microsoft.ACE.OLEDB.12.0"
    cn.Properties("Extended Properties") = "Excel 12.0"
    cn.Open ThisWorkbook.Path & "\" & "TestTable.xlsx"

    'SQL文の実行(シートの範囲を指定してテーブルとする)
    rs.Open "SELECT * FROM [Sheet1$B4:F] WHERE 区分 = '果物' ORDER BY 単価 DESC", cn

    '取得した内容(Recordset)の確認
    Do Until rs.EOF
        Debug.Print rs!品名 & ", " & rs!単価
        rs.MoveNext
    Loop

    'メモリの解放(無くとも構わない)
    rs.Close: Set rs = Nothing
    cn.Close: Set cn = Nothing
End Sub

<出力結果>

イミディエイト
メロン, 1500
バナナ, 300
りんご, 150
みかん, 40

SQL文の絞り込み方法を変えているので、出力結果は変わりますが、正しくテーブルの範囲を指定できていることがわかります。

<ソースコードの変更部分>
ソースコードのうち、表の範囲を指定しているのは次の1行です。

テーブル範囲の指定部分
rs.Open "SELECT * FROM [Sheet1$B4:F] WHERE 区分 = '果物' ORDER BY 単価 DESC", cn

ページ全体を取得する場合は、テーブルを[Sheet1$]と指定していたのに対して、範囲を指定する場合は[Sheet1$B4:F]というように、$の後に、対象となるセルの範囲のヘッダー部分を指定しています。
この場合、表の下限は自動的に判定されます。

なお、[Sheet1$B4:F11]というように、表の下限まで指定することもできますが、レコードの追加時にエラーが出てしまうなど、汎用性が落ちます。

また、テーブルの上側及び左側が全て空白の場合は[Sheet1$]と指定しても、自動的にテーブルの範囲を取得してくれます(本例の場合は、B2セルに"●買物メモ"と入っているので自動取得はできません)。

2. 各コードの説明

以下、外部ライブラリとかインスタンスとか、慣れない人には分からない用語が出てきますが、言葉の意味は重要ではないので気にしなくても大丈夫です(簡単に説明は入れていきます)。
用語には、「Microsoft」の公式ページか、「エクセルの神髄」というサイト(かなり参考になるサイトです)のリンクを付けさせていただきます。

2-1. 外部ライブラリの機能を持ったオブジェクト変数(インスタンス)の作成

最初に、各サンプルコードの冒頭部分「外部ライブラリを利用したインスタンス生成」の部分についてです。
外部ライブラリを使用するということは、VBA自体の機能ではなくて、ActiveXという機能(外部ライブラリ)を使用することを意味します。
ここは、参照設定の有無で記載が分かれますので、順に見ていきます。

まずは、参照設定をしない場合の例です。

参照設定をしない場合
Dim cn As Object
Dim rs As Object
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")

ここでは、プログラムの実行時にCreateObject関数で外部ライブラリを呼び出して、その機能を有するオブジェクト変数(cnrs)を作成しています。
このようなライブラリの機能(実体)を持ったオブジェクト(変数)をインスタンスと呼んでいます。

次に、参照設定をした場合です。

参照設定をした場合
Dim cn As New ADODB.Connection
Dim rs As New ADODB.Recordset

プログラムの実行前にActiveX Data Object (ADO)ライブラリを読み込んでいるため、直接、ADODB.Connection型およびADODB.Recordset型のオブジェクト変数を宣言をすることができます。
オブジェクト変数の前にNewを付けることで、変数の宣言と同時にインスタンスを生成しています。

2-2. ADO接続

次に、以下の3行についてです。

Office2007以降の場合
cn.Provider = "Microsoft.ACE.OLEDB.12.0"
cn.Properties("Extended Properties") = "Excel 12.0"
cn.Open ThisWorkbook.Path & "\" & "TestTable.xlsx"

上記の3行で、対象ファイルとの接続を確立しています。
これにより、ADOによるデータベース操作が可能となります。
以下、順次、1行ずつ見ていきます。

2-2-1. プロバイダ(ドライバ)の指定

cn.Provider = "Microsoft.ACE.OLEDB.12.0"

まず、1行目のcn.Provider =の部分では、ADO接続に使用するプロバイダ(ドライバ)の呼び出しを行っています。
基本的には、Officeのバージョンに合わせて、次のように指定すれば大丈夫です。

指定文字列 内容
Microsoft.Jet.OLEDB.4.0 Office2003以前の場合
Microsoft.ACE.OLEDB.12.0 Office2007以降の場合

参考記事
Microsoft Access(.mdb、.accdb)のODBC、OLEDBドライバーに関するまとめ
ADOによるアクセスの仕組み

2-2-2. 拡張プロパティ(Extended Properties)の指定

cn.Properties("Extended Properties") = "Excel 12.0"

2行目のcn.Properties("Extended Properties") =の部分では、拡張プロパティ(Extended Properties)についての指定を行っています。
この拡張プロパティについては、実は、はっきり分からないことも多いのですが、「ADO.NET / 接続文字列の構文」など、いくつかのサイトを参考にさせていただきました。
基本的には「データベースでないもの(Excelやcsvファイル)をデータベースとして扱う場合の設定」を行うところとなります。

① ISAMバージョンの指定
ISAM(Indexed Sequential Access Method)とは、日本語で言えば「索引付き順次アクセス方式」となります。
次の例にならえば、問題はないようです。

指定文字列 内容
Excel 8.0 Office2003以前の場合
Excel 12.0 Office2007以降の場合
Text csvファイルの場合

② 1行目をカラム名(ヘッダー)として取得するか否かの指定
この指定をしない場合は、デフォルトでHDR=Yes(1行目をカラム名として取得する)となります。

指定文字列 内容
HDR=Yes 1行目をカラム名として取得する
HDR=No 1行目はカラム名として取得しない

③ IMEX(IMPORT EXPORT MODE)の設定
このIMEXは、サンプルコードのように特に指定しない例が多いです。
次のようなモードが用意されています。

指定文字列 内容
IMEX=0 エクスポートモード(書き込みモード)
IMEX=1 インポートモード(読み込みモード)
IMEX=2 リンクモード(書き込みと読み込み)

もし、データの読み込みだけに限るならばIMEX=1としている例も多く見られます。この読み込みモードでは、混在したデータはテキストとして読み込んでくれるとの解説もあります(しかし、実際は思うような挙動が得られなかったりしますので、難しいところです)。

なお、IMEX=0(書き込みモード)と設定した場合には、ファイルを開くことなく、AccessのようにDBとしての書き込みが可能になります(後述)。

○ 複数の項目を指定する方法
以上のから以外にも設定できる内容があるようですが、ここでは触れません(私が、あんまり分かっていません)。
複数の項目を指定する場合は、次のように;で繋げて記載することになります。

複数のExtendedPropertiesを設定する例
cn.Properties("Extended Properties").Value = "Excel 12.0;HDR=Yes;IMEX=1"

<参考サイト>
ADO.NET入門記-027 (Excelに接続してデータを取得・追加・更新)
OLEDB接続文字列内のIMEXとは何ですか?
What is the default value of IMEX in OLEDB?
关于Excel导入的HDR=YES; IMEX=1详解

2-2-3. ファイルを指定して接続を実行する

cn.Open ThisWorkbook.Path & "\" & "TestTable.xlsx"

3行目のcn.Openのところでは、データベースとして開くファイルのディレクトリ(ThisWorkbook.Path & "\" & "TestTable.xlsx")を指定して、接続処理の実行を行っています。
これは、同じフォルダ内のTestTable.xlsxという別のExcelファイルを指定している例です。

VBAを記載したファイル自体にあるワークシートを参照するならば、次のようにすれば参照できます。

VBA記載ファイル内のワークシートを参照する場合
cn.Open ActiveWorkbook.FullName

なお、次のように、「ディレクトリの指定」と「接続の実行」を分けて記載することもできます(迂遠ですが)。

ディレクトリの指定を個別に行う場合
cn.Properties("Data Source") = ThisWorkbook.Path & "\" & "TestTable.xlsx"
cn.Open

<注意>
"\"の部分は環境(フォント)によって、半角のまたはと2通りの表示がされます。
コピペすれば、VBAの画面上では"¥"と表示されるはずです。

2-2-4. ADO接続を1行で表記する方法

以上のように、本例では、3行に分けて記載しましたが、次のように1行にまとめて記載することも可能です(普通は適当な位置で折り返しを入れます)。

ADO接続を1行で記載する場合(自ファイル内のワークシートを参照の例)
cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ActiveWorkbook.FullName & ";Extended Properties=""Excel 12.0;HDR=No"""

2-3. SQL文で抽出したデータをレコードセットで開く

レコードセット(Recordset)は、レコード(行)とフィールド(列)から構成され、表のようなデータ構造をしています。
このRecordsetオブジェクトの「Openメソッド」を使用して、SQL文で抽出したデータやテーブルなどを開いて操作をすることができます。

サンプルコードでは、次のようにSQL文コネクションのみを指定していますが、その他にもパラメータ(引数)があります。

rs.Open "SELECT * FROM [Sheet1$] ORDER BY 単価", cn

このOpenメソッドの全てのパラメーターを含めた正式な構文を書くと次のようになります。

Openメソッドの構文
recordset.Open Source, ActiveConnection, CursorType, LockType, Options

Openメソッドのパラメーターを一覧にすると次のとおりです(ざっくりな説明です)。

パラメーター 日本語 説明
Source DBのソース SQLステートメント、テーブル名などを指定
ActiveConnection コネクション DBへの接続(コネクション)を指定
CursorType カーソルの種類 カーソルの移動や、他のユーザーの更新結果を反映するかを指定(adOpenForwardOnly、adOpenKeyset、adOpenDynamic、adOpenStatic)
LockType ロックの種類 編集中にレコードに適用されるロックの種類を指定(adLockBatchOptimistic、adLockOptimistic、adLockPessimistic、adLockReadOnly、adLockUnspecified)
Options オプション

パラメーターの詳細は、「3-2. ファイルを開かずにレコードを書き込む(Update、UpdateBatchメソッド)」で再度取り上げます。

2-4. レコードセットの中身を確認する

サンプルコードでは、次のループ処理でレコードを1行ずつ読み込んでいます。

Do Until rs.EOF
    Debug.Print rs!品名 & ", " & rs!単価
    rs.MoveNext
Loop

このコードでは、レコードが末尾まで行くと、rs.EOFがTrueになるので、それまでの間ループを繰り返します。
なお、EOFはEnd Of Fileのことです(また、BOFはBeginning Of Fileのことです)。

そして、現在カーソルがあるレコードのデータを抽出するには、rs![カラム名]という形で取得することができます。
そのほかの書き方としては、rs([カラム名])でも、同様にデータを取得できます(次のとおり)。

Debug.Print rs("品名") & ", " & rs("単価")

レコードを読み込んだ後、次のレコードには自動的に移らないので、rs.MoveNextというようにMoveNextメソッドを使用してカーソルを移動させています。

レコードセットの主なメソッドおよびプロパティは次のとおりです。

名称 内容
MoveFirstメソッド レコード位置を最初のレコードに移動
MoveLastメソッド レコード位置を最後のレコードに移動
MoveNextメソッド レコード位置を1レコード次に移動
MovePreviousメソッド レコード位置を1レコード前に移動
Updateメソッド レコードの更新を保存
UpdateBatchメソッド 保留中の更新を一括して保存
AddNewメソッド 新しいレコードを作成
Deleteメソッド レコードを削除
Findメソッド 指定した条件を満たす行を検索
BOFプロパティ レコードの位置が最初のレコードより前にあることを示す
EOFプロパティ レコードの位置が最後のレコードより後にあることを示す

3. ワークシートのデータを更新する方法

Excelファイルへのデータ更新は、普通に Excel VBA の手法で書き換えることができます。
ただ、ここではRecordsetを使用して、Excelファイル(DB)を更新する方法について書いておきます。

なお、更新方法には、「ファイルを開いてRecordsetのデータを貼り付ける単純な方法」と「ファイルを開かず一般的なDBのように更新する方法」がありますので、これらの例を、順を追って紹介させていただきます。

3-1. ファイルを開いてレコードを書き込む(CopyFromRecordsetメソッド)

まず、ファイルを開いてレコードを書き込む方法ですが、Excelを操作する上では、比較的に安定していて使いやすい手法だと思います。

サンプルコード4
Sub Sample4()
    'インスタンスを作成(事前バインディング)
    Dim cn As New ADODB.Connection
    Dim rs As New ADODB.Recordset

    Dim wb As Workbook
    Set wb = Workbooks.Open(ThisWorkbook.Path & "\" & "TestTable.xlsx")

    'ADO接続
    cn.Provider = "Microsoft.ACE.OLEDB.12.0"
    cn.Properties("Extended Properties") = "Excel 12.0"
    cn.Open ThisWorkbook.Path & "\" & "TestTable.xlsx"


    'SQL文の実行
    rs.Open "SELECT * FROM [Sheet1$] ORDER BY 単価", cn, adOpenKeyset

    'Recordsetのデータを貼り付ける
    wb.Sheets("Sheet1").Cells(2, 1).CopyFromRecordset rs

    'ファイルを保存して閉じる
    wb.Close savechanges:=True

    'メモリの解放(無くとも構わない)
    rs.Close: Set rs = Nothing
    cn.Close: Set cn = Nothing
End Sub

このコードを実行すると、単価の昇順でデータが並べ替えられます。

CopyFromRecordsetメソッドを使っているのは次の部分です。

wb.Sheets("Sheet1").Cells(2, 1).CopyFromRecordset rs

ワークシートのうち、セルを貼り付ける左上の起点を指定して(Cells(2, 1))、レコードセットの行数および列数分だけデータを貼り付けます。

3-2. ファイルを開かずにレコードを書き込む(Update、UpdateBatchメソッド)

次に、ファイルを開かずに、一般的なDBのようにデータを更新する方法です。

3-2-1. レコードセットと連動して更新を行う

ますは、RecordsetのUpdateメソッドを使用して、レコードを1行ずつ更新する方法です。

3-2-1-1. レコードを1行ずつ更新する

サンプルコード5(Recordsetと連動してデータ更新)
Sub Sample5()
    'インスタンスを作成(事前バインディング)
    Dim cn As New ADODB.Connection
    Dim rs As New ADODB.Recordset

    'ADO接続
    cn.Provider = "Microsoft.ACE.OLEDB.12.0"
    cn.Properties("Extended Properties") = "Excel 12.0;HDR=Yes;IMEX=0"
    cn.Open ThisWorkbook.Path & "\" & "TestTable.xlsx"

    'SQL文の実行
    rs.Open "SELECT * FROM [Sheet1$] WHERE 区分 = '野菜'", cn, adOpenStatic, adLockPessimistic

    'Recordsetの更新
    Do Until rs.EOF
        rs!単価 = Val(rs!単価) + 1
        rs.Update
        rs.MoveNext
    Loop

    'メモリの解放(無くとも構わない)
    rs.Close: Set rs = Nothing
    cn.Close: Set cn = Nothing
End Sub

これは、区分が野菜であるレコードについて、単価を1円だけ上げる例ですが、Recordsetを1行更新するたびに、Excelのワークシートも同時に更新されていきます。
これにより、一般的なDBと同じような形で操作することができます。

このコードで重要な点の一つは、ADO接続の拡張プロパティ(Extended Properties)の部分です(次のところ)。

cn.Properties("Extended Properties") = "Excel 12.0;HDR=Yes;IMEX=0"

IMEXのところがIMEX=0となっています。これによりExcelファイルは書き込みモード(エクスポートモード)になり、Recordsetから更新することが可能になります。

もう一つ重要なところは、RecordsetのOpenメソッドのところです。

rs.Open "SELECT * FROM [Sheet1$] WHERE 区分 = '野菜'", cn, adOpenStatic, adLockPessimistic

ここでは、カーソルタイプ(CursorTypeプロパティ)とロックタイプ(LockTypeプロパティ)を指定しています。

それぞれの種類を見てみると次のようになっています。

① カーソルタイプ(CursorType)

名称 日本語 内容
adOpenDynamic 動的カーソル 他のユーザーによる追加・変更・削除が反映される
adOpenKeyset キーセットカーソル 他のユーザーによる変更は反映されるが、追加・削除したレコードにはアクセスできない
adOpenStatic 静的カーソル 他のユーザーによる追加・変更・削除は反映されない
adOpenForwardOnly 順方向専用カーソル 他のユーザーによる追加・変更・削除は反映されない(パフォーマンス性は向上する)

Excelファイルへの複数ユーザーの同時アクセスを考慮する機会はあまりないと思いますが、カーソルタイプによりRecordsetで取得できるデータが変わってきます(本稿では、ほぼ考慮していません)。

② ロックタイプ(LockType)

名称 日本語
adLockBatchOptimistic バッチ更新用の共有的ロック
adLockOptimistic 共有的ロック
adLockPessimistic 排他的ロック
adLockReadOnly 読み取り専用
adLockUnspecified ロック指定なし

本例では、2番目のadLockOptimistic(共有ロック)と、3番目のadLockPessimistic(排他的ロック)であればデータの更新ができます。
1番目のadLockBatchOptimisticは、後述のバッチ更新で使用します。
なお、4番目のadLockReadOnly(読み取り専用)、5番目のadLockUnspecified(指定なし)は、データ更新する場合には基本的には使用しません。

このあたりの詳細は「ロック機構 - Windows 2000 - Development Guide for Business Applications」および「CursorTypeプロパティ」などの記事で分かりやすく解説されています。

最後にUpdateメソッドについてです。
Recordsetを更新するたびに、次のようにUpdateメソッドrs.Updateのところ)を使ってExcelのワークシートも更新していきます。

Do Until rs.EOF
    rs!単価 = Val(rs!単価) + 1
    rs.Update
    rs.MoveNext
Loop

3-2-1-2. レコードを追加する

レコードを追加する場合は、次のように記載します。
RecordsetのAddNewメソッドでレコードを追加して、Updateメソッドでデータの更新を行っています。

サンプルコード5_2(レコードを追加する)
Sub Sample5_2()
    'インスタンスを作成(事前バインディング)
    Dim cn As New ADODB.Connection
    Dim rs As New ADODB.Recordset

    'ADO接続
    cn.Provider = "Microsoft.ACE.OLEDB.12.0"
    cn.Properties("Extended Properties") = "Excel 12.0;HDR=Yes;IMEX=0"
    cn.Open ThisWorkbook.Path & "\" & "TestTable.xlsx"

    'SQL文の実行
    rs.Open "SELECT * FROM [Sheet1$A1:E]", cn, , adLockOptimistic

    rs.AddNew
    rs!品名 = "ピーマン"
    rs!区分 = "野菜"
    rs!単価 = 120
    rs!購入数 = 3
    rs!購入日 = #11/10/2020#
    rs.Update

    'メモリの解放(無くとも構わない)
    rs.Close: Set rs = Nothing
    cn.Close: Set cn = Nothing
End Sub

このコードを実行すると、次のように、末尾にレコードが追加されます。
2020-11-09 231125.png
枠線が無くて格好悪いですが、DBとして扱うなら最初から枠線を入れない方が無難かもしれません。

3-2-2. 一括してバッチ更新を行う

これは、もうコードの記載例のみです(申し訳ありません)。
次のようにすることで、バッチ更新をすることが可能です。

サンプルコード6(バッチ更新で一括処理)
Sub Sample6()
    'インスタンスを作成(事前バインディング)
    Dim cn As New ADODB.Connection
    Dim rs As New ADODB.Recordset

    'ADO接続
    cn.Provider = "Microsoft.ACE.OLEDB.12.0"
    cn.Properties("Extended Properties") = "Excel 12.0;HDR=Yes;IMEX=0"
    cn.Open ThisWorkbook.Path & "\" & "TestTable.xlsx"

    'SQL文の実行
    rs.CursorLocation = adUseClient
    rs.Open "SELECT * FROM [Sheet1$] WHERE 区分 = '野菜'", cn, adOpenStatic, adLockBatchOptimistic
    Set rs.ActiveConnection = Nothing 'コネクションを一旦切断する

    'Recordsetの更新
    Do Until rs.EOF
        rs!単価 = Val(rs!単価) + 2000
        rs.MoveNext
    Loop

    rs.ActiveConnection = cn 'コネクションに再接続する
    rs.UpdateBatch 'ここで一括更新する

    'メモリの解放(無くとも構わない)
    rs.Close: Set rs = Nothing
    cn.Close: Set cn = Nothing
End Sub

さいごに

ADOは、これまでも色々と使ってきたものの、いざ、記事にまとめようとすると結構分かっていないことがたくさんあり、勉強になりました。

今回の記事作成で参考にさせていただいたWEBサイトは、できるだけリンクを残しましたので、あわせてご覧頂くと理解がしやすいのではないかと思います。

42
61
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
42
61