ACCESS VBA レコードを一括削除する方法(VBAコード公開)
ACCESSのテーブル操作では、毎回テーブルのレコードをすべて空にして、新しいレコードを追加しなおす、という処理を作ることがあります。
テーブルのレコードを一括削除するのは簡単に思えますが、VBAの通常の関数ではレコードの更新ができません。
テーブルを操作する際はADO(ActiveX Data Object)を使用する必要があります。
今回は、ADOを使ってVBAからテーブルのレコードを一括削除する方法をご紹介します。
こんにちは。
はこにわガジェット (@hakoniwagadget) です。
ACCESSを使った売上管理、顧客管理などのデータベース開発を行っています。
ACCESSは基本機能だけでも十分便利ですが、VBAを使うことで格段に使いやすいデータベースを作成可能です。
この記事ではACCESSでのVBAの使い方をご紹介していきます。
目次
VBAでレコードを削除する方法
まず、VBAでテーブルのレコードを削除する方法をまとめましょう。
基本的にVBAは、フォームを開けたり、クエリを実行したり、フィルターをかけたりはできますが、テーブルのレコード自体を直接操作することができません。
そのため、VBAからレコードを削除する場合は、以下の2つの方法のどちらかを選択することになります。
1.削除クエリを作成しておき、VBAで削除クエリを実行する
2.ADO(ActiveX Data Object)を使用してVBAからレコードを操作する
このうち、簡単なのは1.の方です。
それぞれ、詳しく見ていきましょう。
VBAで削除クエリを実行する
VBAでクエリを実行する際は、「DoCmd.OpenQuery」メソッドを使用します。
削除クエリの名称が「削除クエリ」だった場合、クエリの名称を”(ダブルクォーテーション)で囲って
DoCmd.OpenQuery "削除クエリ"
で実行できます。
なお、この際一つ注意点があります。
削除をクエリを含めたアクションクエリ(テーブルのデータを変更するクエリ)は、実行前に確認メッセージが表示されます。
例えば削除クエリならこんな感じですね。
手動でアクションクエリを実行した時であればメッセージに違和感はないのですが、VBAで自動処理をさせている中でこうしたメッセージが出ると、ユーザーはレコード削除を意図していない場合もあるため、「なんのことだろう?」と思ってしまいます。
そのため、VBAでアクションクエリを実行する際は、こうしたアラートメッセージが表示されないようにするのが一般的です。
DoCmd.SetWarningsメソッドを使って下記のように記述すれば、一時的にアラートメッセージが出ないようにできます。
'アラートメッセージを停止
DoCmd.SetWarnings False
'削除クエリを実行
DoCmd.OpenQuery "削除クエリ"
'アラートメッセージを再開
DoCmd.SetWarnings True
アラートメッセージを停止したら、その後再開させることを忘れないようにしましょう。
これで不要なメッセージが表示されなくなります。
もし、レコードの削除件数を表示したうえで確認メッセージなどを出したい場合は、MsgBox関数を使ってアラートメッセージを作成するとよいでしょう。
ADOを使用してレコードを削除する
なぜADOが必要なのか
もう一つの方法として、ADO(ActiveX Data Object)を使用してレコードを削除する方法があります。
先に説明した削除クエリの方法が簡単なので、これで十分なのではないか、と思われるかもしれません。
しかし、削除クエリの方法には一つの欠点があります。
それは、事前に削除クエリを作っておかなければいけない、ということです。
もちろん、削除クエリを作成すること自体は簡単ですし、それほど問題ではありません。
問題なのは、削除クエリで削除するレコードの抽出条件を、事前に決めておくことができないケースがあるということです。
例えば、フォームでのユーザーの入力値に応じてレコードを抽出して削除するケースや、VBA処理中に作成した一時テーブルのレコードを削除する場合などです。
ACCESSをある程度使いこなし、VBAでの自動処理を進めてくるといつかこうしたケースに遭遇します。
ここで便利なのがADOを使ったレコード削除なのです。
ADOとは
ADO(ActiveX Data Objects)とはマイクロソフトが提供する、データベースを操作するための様々オブジェクトの集合体です。
ADOを使うことでデータベースの操作が可能です。
ACCESSはもともとクエリ等のデータベースを操作する独自オブジェクトを用意していますが、ADOを使うことで条件分岐やループを含めたより柔軟なデータベースの追加、更新、削除が可能です。
ADOとよく似たものに、DAO(Data Access Object)があります。
ACCESSのデータベース接続に特化している点が特長で、ADO登場以前から使われています。
ただ、今後VBAプログラミングを行うならADOを使っておくほうが良いでしょう。
ADOとDAOはプログラミングの方法が若干異なりますので、混在すると複雑になります。
ADOの使用準備
ADOを使用するためにはACCESS側で、ADOの利用に必要なライブラリファイルを追加する必要があります。
といっても、操作は簡単です。
ACCESSを起動させたら、ALT + F11キーでVBE(Visual Basic Editor)を表示します。
VBEの画面で、ツールから参照設定を選択します。
参照設定の画面が表示されますので、Microsoft ActiveX Data Objects X.X Libraryを選択して、OKを押します。
X.Xの部分はバージョンです。できるだけ数字の大きいもの(新しいもの)を選択してください。
これで、事前準備は完了です。
ADOを使ったレコード削除処理
それではVBAで年月を追加するプログラムを書いていきましょう。
今回は以下のコードを作成しました。
TRN_売上というテーブルから、売上日が
Public Sub sakujo()
Dim cnn As ADODB.Connection
Dim rst1 As ADODB.Recordset
'変数にADOオブジェクトを代入
Set cnn = CurrentProject.Connection
Set rst1 = New ADODB.Recordset
rst1.CursorLocation = adUseClient
'レコードセットを取得
rst1.Open "TRN_売上サンプル", cnn, adOpenKeyset, adLockOptimistic
'売上日で抽出
rst1.Filter = "売上日 = " & #2/3/2020#
Do Until rst1.EOF
rst1.Delete
rst1.MoveNext
Loop
'終了処理
rst1.Close: Set rst1 = Nothing
cnn.Close: Set cnn = Nothing
End Sub
処理概要
今回のコードでは、 テーブル「TRN_売上サンプル」から売上日が2020年2月3日のレコードを抽出して、該当のレコードを削除しています。
ADOでは削除処理は1レコードずつになるので、削除処理を、ループで繰り返しています。
以下、細かく解説していきます。
ADOの基本構文
ADOを利用する場合は、ある程度決まった記述があります。
最初に、
Dim cnn As ADODB.Connection
Dim rst1 As ADODB.Recordset
で、ADO用のオブジェクト変数を定義します。
そのうえで、
Set cnn = CurrentProject.Connection
Set rst1 = New ADODB.Recordset
rst1.CursorLocation = adUseClient
で、ADOのオブジェクトに接続します。
cnnがプロジェクト全体、rst1がその中のレコードセット(テーブル)の一つを指すと考えてください。
この部分と、最後の終了処理である、
rst1.Close: Set rst1 = Nothing
cnn.Close: Set cnn = Nothing
は、毎回使用しますので、ADOを使用する際はまずはこの最初と最後を記述して、後から中身を埋めていくとよいでしょう。
レコードセットの取得
ADOのオブジェクトに接続したら、次はレコードセットを取得します。
定義したrst1にテーブルを代入するのです。
rst1.Open "TRN_売上サンプル", cnn, adOpenKeyset, adLockOptimistic
が該当部分になります。
今回はrst1というレコードセットオブジェクトに、テーブル「TRN_売上サンプル」を代入しました。
レコードセットの取得の際のパラメータは、以下の通りです。
基本は、adOpenKeyset, adLockOptimisticにしておけば問題はないです。
CursorType
adOpenForwardOnly | 前方スクロールカーソル。前方スクロールのみだが高速。検索を一度のみ実施する場合などに利用。 |
adOpenKeyset | キーセットカーソル。他のユーザーによる追加・削除は確認できない。 |
adOpenDynamic | 動的カーソル。レコードをすべての方向に移動することができる。他のユーザーによる追加・削除が確認できる。 |
adOpenStatic | 静的カーソル。レコードをすべての方向に移動することができる。他のユーザーによる追加・削除は確認できない。 |
LockType
adLockReadOnly | 読み取り専用 |
adLockPessimistic | レコード単位の排他的ロック |
adLockOptimistic | レコード単位の共有的ロック |
adLockBatchOptimistic | 共有的バッチ更新 |
adLockUnspecified | ロックタイプを指定しない |
該当レコードの抽出
今回は 2020年2月3日のレコードを削除したいので、Filterプロパティを使用してレコードを抽出します。
rst1.Filter = "売上日 = " & #2/3/2020#
日付を指定しているので、「”」ではなく「#」で囲うのを間違えないようにしてください。
ループでの削除処理
この後は、Do Until ~ Loopを使って、TRN_売上サンプルの最終レコードまで1レコードずつ削除していきます。
Do Until rst1.EOF
rst1.Delete
rst1.MoveNext
Loop
ADOを使ってレコードを削除する際は、上記の記述方法になります。
rst1.Deleteで削除し、rst1.mMoveNextで次のレコードへ移動します。
これをrst1.EOFつまり、対象としたTRN_売上サンプルテーブルの最終レコードまで繰り返すことですべてのレコードを削除できるというわけです。
ADOを使ったレコード削除方法は、クエリを使ったものより複雑な分、柔軟な対応ができるのが強みです。
通常はクエリでの削除をベースとしつつ、削除クエリで対応できない複雑な要件の際はADOの利用を検討しましょう。
以上、レコードを一括削除する方法をご紹介しました。
ACCESSを使いこなせば、業務の効率化や自動化が実現できます。
しかし、自分でACCESSを学ぶには時間がない、難しそうで不安、という方も多いでしょう。
そんな時は、ACCESS開発歴20年以上、過去に100以上のACCESSデータベースを開発してきた私(@hakoniwagadget)にお任せください。
ACCESSの新規開発、既存のACCESSの修正、ACCESSの操作レッスンなど様々なサービスをご提供しています。
ご興味のある方は下記のサービス一覧をご覧ください。
最後までお読みいただき、ありがとうございました。