はじめに
この記事は、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表をサンプルとして使用します。
この記事においては、「表を記載したファイル」と「VBAを記載するファイル」は別々にして、同じフォルダに保存しています。
参考までに、私の手元では、次のような構成としています。
用途 | ファイル名 | ディレクトリ(フルパス) |
---|---|---|
VBAを記録するファイル | ADOTest.xlsm | C:\VBA\ADOTest.xlsm |
表を記載するファイル | TestTable.xlsx | C:\VBA\TestTable.xlsx |
1-1-1. 参照設定をしない場合
最初に、参照設定をしない場合の例です。
つまり、VBAで事前の設定をしなくても書けるコードです。
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)」を開きます。
参照設定の画面で、次のようにMicrosoft ActiveX Data Object X.X Library
をチェックしてOK
ボタンを押せば完了です(ここではバージョンは6.1
を選択しています)。
この設定により、プログラムの実行前に、ActiveX Data Object (ADO)
ライブラリを読み込むことになります。
記載するソースコードは、以下のとおりです。
前の例と異なるのは、最初の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表をサンプルとして使用します。
このような場合は、赤枠の部分(B4からF11の間のデータ)をテーブルとして取得する必要があります。
コードを書くと次のとおりです。
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関数で外部ライブラリを呼び出して、その機能を有するオブジェクト変数(cn
、rs
)を作成しています。
このようなライブラリの機能(実体)を持ったオブジェクト(変数)をインスタンスと呼んでいます。
次に、参照設定をした場合です。
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行についてです。
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としての書き込みが可能になります(後述)。
○ 複数の項目を指定する方法
以上の①から③以外にも設定できる内容があるようですが、ここでは触れません(私が、あんまり分かっていません)。
複数の項目を指定する場合は、次のように;
で繋げて記載することになります。
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を記載したファイル自体にあるワークシートを参照するならば、次のようにすれば参照できます。
cn.Open ActiveWorkbook.FullName
なお、次のように、「ディレクトリの指定」と「接続の実行」を分けて記載することもできます(迂遠ですが)。
cn.Properties("Data Source") = ThisWorkbook.Path & "\" & "TestTable.xlsx"
cn.Open
<注意>
""の部分は環境(フォント)によって、半角の\
または¥
と2通りの表示がされます。
コピペすれば、VBAの画面上では"¥"と表示されるはずです。
2-2-4. ADO接続を1行で表記する方法
以上のように、本例では、3行に分けて記載しましたが、次のように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メソッドの全てのパラメーターを含めた正式な構文を書くと次のようになります。
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を操作する上では、比較的に安定していて使いやすい手法だと思います。
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行ずつ更新する
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メソッド
でデータの更新を行っています。
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
このコードを実行すると、次のように、末尾にレコードが追加されます。
枠線が無くて格好悪いですが、DBとして扱うなら最初から枠線を入れない方が無難かもしれません。
3-2-2. 一括してバッチ更新を行う
これは、もうコードの記載例のみです(申し訳ありません)。
次のようにすることで、バッチ更新をすることが可能です。
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サイトは、できるだけリンクを残しましたので、あわせてご覧頂くと理解がしやすいのではないかと思います。