AccessVBA(ADO or DAO)でSQLを書いてレコードを抽出・フィールドを取り出す

AccessVBA(ADO or DAO)でSQLを書いてレコードを抽出・フィールドを取り出す

Accessってテーブルとフォームが連結しているので、VBAなしでも結構いけるんだなと思っていたんですが、ちょっと複雑なことをしたいとか、存在チェックとか、やっぱりやりたいよなーと思ったのでメモ。


DAOとADOの違いについて

160819-1

ざっくり言うと、どちらも「データベースへ接続する手段」なんですが、DAOはAccessのデータベースのみに特化していて、ADOはAccessをはじめ、SQLServerやOracleなど、他のデータベースでも幅広く使える接続手段、という感じです。

一時はDAOは古い手段とされて「これから作るならADO!」という風潮だったそうなのですが、Access2007からDAOの参照先が新しくなり、そのライブラリが既定で参照されるようになったという流れがあり、今はそんなに廃れていない印象です。

「既定で参照しとくから気軽に使ってね!」という解釈をすると、ローカルで自分自身のデータベースを操作するならDAOを使って、外部のデータベースを使いたいときはADOを使う、という感じでいいんじゃないのかなー、と思います。DAOはAccess特化なのでADOよりちょっと速いとか。

でも、速いと言ってもPCのスペックもどんどん上がっている現在、そんなに気にすることもないのかと。ちょっと触った感じ、レコード読込だけならあんまり感じませんが、追加や更新の書き方に結構クセがあるので、既にADOの書き方に慣れちゃってると、ちょっと戸惑う…。あえて使い分けなくてもADOで統一しちゃうという考え方もあるかもしれません。

一応、個人的なテンプレとしてDAOとADOのレコード読込の書き方をまとめてみました。

コード

DAOでの書き方

2007より前のバージョンでは参照設定の「Microsoft DAO *.* Object Library」にチェックをつけなきゃいけなかったのですが、2007より「Microsoft Office *.* Access Database Engine Object Library」と新しくなり、既定でチェックがついているので、Access2007以降であれば、特に何もしなくても下記のコードを書けば動きます。

Sub sample()
  Dim daoDB As DAO.Database 'データベースオブジェクト
  Dim daoRs As DAO.Recordset 'レコードセットオブジェクト
  Dim strSQL As String 'SQL文用文字列
  
  Set daoDB = CurrentDb '現在のデータベースをセット
  strSQL = "SELECT * FROM テーブル名 WHERE 条件;" 'SQL文作成
  Set daoRs = daoDB.OpenRecordset(strSQL) 'レコード抽出

  If daoRs.BOF = True And daoRs.EOF = True Then '存在チェック
    MsgBox "レコードが存在しません。" 'メッセージ
    GoTo Finally '後処理へジャンプ
  End If
  
  Do Until daoRs.EOF '抽出したレコードが終了するまで処理を繰り返す
    Debug.Print daoRs!フィールド名 'フィールドを取り出す
    daoRs.MoveNext '次のレコードに移動する
  Loop
  
Finally: '後処理
  '閉じる
  daoRs.Close
  daoDB.Close
  'オブジェクトの破棄
  Set daoRs = Nothing
  Set daoDB = Nothing
End Sub

2~4行で宣言、6~8行でレコード抽出、10~13行で存在チェック、15~18行が処理部分、20行以降が後処理となっています。

レコードが存在しなかったら12行目から20行目へジャンプして後処理しちゃいます。

16行目はサンプル的にイミディエイトウィンドウにフィールドを取り出すようにしていますので、ここをいろいろ変えてもらえれば。イミディエイトウィンドウが出ていない場合はツールバーの「表示」から出せます。

24~26行目の Nothing の処理はなくても良いみたいですね。なんとなく Set~Nothing はセットのような気がして一応書いてみたのですが。

ADOでの書き方

ADOは既定で参照設定がされていないので、「Microsoft ActiveX Data Objects *.* Library」という項目にチェックを入れてから利用します。

ADOを使う場合、参照設定を省略することもできます。

Sub sample()
  Dim adoCn As ADODB.Connection 'ADOコネクションオブジェクト
  Dim adoRs As ADODB.Recordset 'ADOレコードセットオブジェクト
  Dim strSQL As String 'SQL文
 
  Set adoCn = CurrentProject.Connection '現在のデータベースへ接続
  Set adoRs = New ADODB.Recordset  'ADOレコードセットのインスタンス作成
  strSQL = "SELECT * FROM テーブル名 WHERE 条件;" 'SQL文作成
  adoRs.Open strSQL, adoCn 'レコード抽出
  
  If adoRs.BOF = True And adoRs.EOF = True Then '存在チェック
    MsgBox "レコードが存在しません。" 'メッセージ
    GoTo Finally '後処理へジャンプ
  End If
  
  Do Until adoRs.EOF '抽出したレコードが終了するまで処理を繰り返す
    Debug.Print adoRs!フィールド名 'フィールドを取り出す
    adoRs.MoveNext '次のレコードに移動する
  Loop
  
Finally: '後処理
  '閉じる
  adoRs.Close
  adoCn.Close
  'オブジェクトの破棄
  Set adoRs = Nothing
  Set adoCn = Nothing
End Sub

こちらは、2~4行で宣言、6~9行でレコード抽出、11~14行で存在チェック、16~19行が処理部分、21行以降が後処理となっています。ちょっと書き方が違うだけで、接続しちゃえば扱い方はだいたい一緒なので、解説は上記をご覧ください。

以上です! 自分メモですがどなたかのお役に立てたら幸いです。

参考

ありがとうございました!

公開日:2016/08/19
更新日:2016/09/08

書籍を執筆しています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

コメントは承認制ですので、反映までしばらくお待ち下さい。(稀にスパムの誤判定にて届かないこともあるようですので、必要な際はお問い合わせからお願い致します。)

YouTubeでQ&Aコンテンツを企画しています

運営しているYouTubeチャンネルで、ご相談やご質問を募集しています。動画のコメントやお問い合わせページからお気軽にご相談をお寄せください。