前回はこちら
先週書いたコードはこんな感じでした。
'④-1.DB接続
'④-2.レコードセットオブジェクト生成
'④-3.クエリ実行&データ取得
'④-4.レコードセットの配列化
'④-5.配列データをコンボボックスのリストに反映
'④-6.DB切断
これを、DBからデータ取るプロシージャごとに実行する作りになってました。
1~6の流れの中で処理ごとに異なる内容というのは、
- 2でRecordsetのOpenに使うクエリ内容
- 4と5のプロシージャ個別処理
ぐらいなんですよね。
同じコードがあちこちにいっぱい書いてあるな、と感じたので共通化しました。
まずは元プロシージャ。
2のクエリを変数に格納した後、クエリ結果のレコードセットを返す関数へ渡すように。
strSQL = "SELECT catID,catName FROM category where parentID is null"
Set adoRs = getCursor(strSQL)
で、呼び出し先の関数が新たに作成したというか纏めなおした処理。
Private Function getCursor(ByVal strSQL As String) As Object
Dim objCon As Object
Dim adoRs As Object
'①DB接続
Set objCon = connectDB()'②レコードセットオブジェクト生成
Set adoRs = CreateObject("ADODB.Recordset")
adoRs.CursorLocation = 3 ' adUseClient クライアントサイド
'③クエリ実行&データ取得&後処理
adoRs.Open strSQL, objCon
adoRs.activeconnection = Nothing '※今回のポイント
'④DB切断
Call disconnectDB(objCon)
'⑤レコードセットを呼び出し元に返却
Set getCursor = adoRs
End Function
①、②、④は元の処理と同じ事をやってます。
⑤は、関数なので戻り値を設定してます。
③の一行目も元の処理と同じですが、ポイントが二行目。
activeconnection = Nothing
これが、この関数内でDBを切断する為に必要となります。
なんで関数内で切断が必要かというと、接続オブジェクトを呼び出し元で持ち回ししないといけないから。
接続オブジェクトを持ちまわす理由は、普通に閉じちゃうとレコードセットも操作できなくなるから。
(DBに繋いで見てるデータを参照する変数なので、切断したら見えなくなってしまう)
という事で、接続を閉じてもレコードセットを操作できるように値渡しの変数みたいに、値のコピーとして変数を定義できないか調べてました。
それで見つけたのが、切断してもレコードセットのデータ内容を保持する為のオプション。
よくわからずおまじないとして記述してた下のコードとも関わるようです。
CursorLocation = 3 ' adUseClient クライアントサイド
これで、DBオープン→クエリ実行して結果取得→それを保持したままDBクローズ、を実装出来ました。
DBオープンクローズを完全に分離したので、各プロシージャ内ではDB接続オブジェクトの変数も必要なくなりました。
お陰で結構スッキリした感じに!