ExcelVBAマクロ Excelマクロからaccdb(mdb)を操作するクラスを拡張する(データ操作)

プログラミング

前回記事にてExcelVBAマクロからaccdb(mdb)の操作をまとめた操作クラスを作成しました。

今回はこのaccdb(mdb)操作クラスにデータ操作(追加・変更・削除)とデータの参照を追加して一通りの操作が出来るように拡張していくのでその方法について紹介していきます。

データ操作(追加・変更・削除)とデータの参照について

データベースにてデータの操作とは追加・変更・削除の事を指します。

これにデータの参照を加えた4つの操作を機能に折り込もうと思います。

これらはすべてSQL文経由で実行します。

ADOではSQL文の実行方法として以下の2種類が存在します。

  • ADODB.RecordSet.Open()
  • ADODB.Connection.Execute()

違いとしては「Open()」では実行結果を取得でき、「Execute()」では実行結果を取得できません。(厳密には両方ともADODB.RecordSetが戻るのですが「Execute()」では内部で「Close()」されているため中身の取得ができません)

このため、データの参照には実行結果が必要になるため「Open()」を使い、データの参照以外の操作(追加・変更・削除)は実行結果が不要なため、「Execute()」を使う事を想定した実装をしていきます。

データ操作(追加・変更・削除)とデータの参照を実装する

それでは実際にデータ操作(追加・変更・削除)とデータの参照を行う機能を追加していきます。

データの参照

クラスモジュールへデータの参照を行うプロシージャを追加します。

クラスモジュールのデータの参照

後述しますがRecordSetを複製するプロシージャ「cloneRecordSet()」も追加します。

クラスモジュールのRecordSetを複製する

内容を順番に見ていきましょう。

SQL文は外部から渡してもらう仕様で実装しています。

こうする事でいろいろなSQL文対応可能になります。(制限を付けたデータ参照のプロシージャを作りたい場合はまずはこのプロシージャを作り、このプロシージャをラップするプロシージャなりクラスを作る事をお勧めします)

操作前処理と操作後処理はいつも通りなので説明を省略します。

データの参照では「Open()」にて渡したSQL文の結果を受け取り、呼び出し元へRecordSetを戻します。

ただし、「Open()」の結果をそのまま戻してしまうとRecordSetおよびデータベースを閉じたタイミングで戻したRecordSetまで閉じてしまうので複製したRecordSetを戻すようにしています。

ここで問題が発生しました。

ADODB.RecordSetには「Clone()」が準備されており、Microsoftのドキュメントにも「元の レコードセット を閉じると、コピーが閉じられることはなく、コピーを終了しても、元のコピーまたは他のコピーを閉じることはできません。」と書かれています。

Clone メソッド (ADO) - ActiveX Data Objects (ADO)
Clone メソッド (ADO)
MicrosoftのCloneメソッド(ADO)のドキュメント(切り抜き)

これは使えると思い実装してみたのですが結果のRecordSetは元のRecordSetおよびデータベースを閉じたタイミングで閉じてしまう事が発覚したので使用を止め、同等の機能を持つ複製用プロシージャ「cloneRecordSet()」を別途作りました。

ADODB.RecordSetには「Clone()」が準備されているのですがこれの結果のRecordSetは元のRecordSetおよびデータベースを閉じたタイミングで閉じてしまう事が発覚したので使用を止め、同等の機能を持つ複製用プロシージャ「cloneRecordSet()」を別途作りました。

これによりプロシージャ「selectData()」から呼び出し元へ戻っても結果のRecordSetのデータを使う事ができるようになりました。

ちなみに手作りしたRecordSetの複製用プロシージャ「cloneRecordSet()」はパラメータのRecordSetのFieldsとValuesを新規作成したRecordSetへ順番に設定していくだけの物です。(ADOCB.RecordSetの「Clone()」が正しく使えるようになった場合にはこの代替えは廃止する予定です)

データ操作(追加・変更・削除)

クラスモジュールへデータ操作(追加・変更・削除)を行うプロシージャを追加します。

クラスモジュールのデータ操作(追加・変更・削除)

内容を順番に見ていきましょう。

と言ってもかなり小さいプロシージャです。

操作前処理と操作後処理をいつも通りで説明を省略します。

データの操作は受け取ったSQL文をそのまま投げるだけです。

データ情報の取得

データ操作の結果を確認するためにデータ情報を取得するプロシージャも追加します。

クラスモジュールのデータデータ情報の取得

データの操作を追加するときはこのプロシージャを作る予定が無かったのですが実際にデータ操作(追加・変更・削除)を実行後に正しく動作しているか確認が必要になったので追加しました。

内容を順番に見ていきましょう。

ここでは今まで出てきていた操作前処理と操作後処理は出てきません。

その理由はデータの取得にデータを参照するプロシージャ「selectData()」を使っているのでこの中で操作前処理と操作後処理を行っているためこのプロシージャには不要となります。

データを取得してからはフィールド情報とデータをDebug.Printにてイミディエイトウィンドウに出力しています。

フィールドはRecordSet.Fieldsの数分処理し、データ(値)はRecordSetの最後(EOF)まで処理しているためすべてのデータを出力できるようになっています。

使用済みのRecordSetは閉じて開放しておきます。(癖付けしておけばメモリ内に残骸が残らず堅牢なプログラムになります)

追加したプロシージャを使う方法

これでクラスモジュールへのプロシージャ追加が終わりました。

実際に使う方法については前回のテスト用プロシージャにデータ操作を行う処理を追加して確認してみます。

追加したプロシージャを使う方法

フィールドの追加を行ったところでデータを追加してみます。

「INSERT」のSQL文を作成し、「ctrlData()」を呼び出す事でデータを追加しています。

データが追加されたかどうか確認のために「showDataInfo()」を呼び出しています。

「deleteColumn()」後にもデータの確認をしていますがフィールドを削除してもフィールド以外のデータが残っているか確認のために追加しています。

まとめ

これでデータベースへの基本的な操作全般を行うクラスモジュールを作る事ができました。

次回は先送りにしていたエラー処理を追加していこうと思います。

コメント

タイトルとURLをコピーしました