こんにちは。ひらのです。
Excel VBA で一時DB⇔ADOを使用する方法のご紹介、第二弾です。
今回はDB(ADO)に登録したデータの更新方法についてご紹介します。
■前提知識
- 簡単なExcel VBAコードを読めること
■お題(要件)
- 任意のフォーマットの文字列を解釈したい(SELECT, INSERT)
- 特定のデータを更新したい(UPDATE) ★この記事ではコレを紹介します
- 特定のデータを削除したい(DELETE)
■特定のデータを更新したい(UPDATE)
前回の Excel VBA で一時DBを使用する ― INSERTとSELECT では、
下記データをADOに登録しました。
[2014/10/01 7:40:58.303] SND command=ACK ID=110405 messageId=002 data=
[2014/10/01 7:40:58.579] RCV command=DATA ID=110405 messageId=501 data=14B4 88B7 D54B A0D2 9A6A 3935
この記事ではADOに登録した内容にて、
特定のcommandとIDを持つレコードを更新したいと思います。
ここで早速問題が。
ADOではSQL文のWHERE句のように、
複数のカラムを選択条件に指定することができません!
なので、今回は選択(SELECT)時専用のカラムを用意する必要があります。
Public Sub OpenDb() Set adoRecordset = New ADODB.Recordset Call adoRecordset.Fields.Append("timestamp", ADODB.adDouble) Call adoRecordset.Fields.Append("direction", ADODB.adVarChar, 3) Call adoRecordset.Fields.Append("command", ADODB.adVarChar, 4) Call adoRecordset.Fields.Append("id", ADODB.adInteger) Call adoRecordset.Fields.Append("message_id", ADODB.adVarChar, 3) Call adoRecordset.Fields.Append("data", ADODB.adVarChar, 256) Call adoRecordset.Fields.Append("key", ADODB.adVarChar, 256) adoRecordset.OpenEnd Sub
Public Sub Insert( _ ByVal timestamp As Double, _ ByVal direction As String, _ ByVal command As String, _ ByVal id As Long, _ ByVal messageId As String, _ ByVal data As String) Call adoRecordset.AddNew '新しいレコードを登録 adoRecordset.Fields("timestamp") = timestamp adoRecordset.Fields("direction") = direction adoRecordset.Fields("command") = command adoRecordset.Fields("id") = id adoRecordset.Fields("message_id") = messageId adoRecordset.Fields("data") = data adoRecordset.Fields("key") = command & id Call adoRecordset.Update '新しいレコードの内容を更新End Sub
それぞれ9行目と17行目で、選択時専用のカラムを用意して
command と id をくっつけた値を登録してあげています。
□ 特定のデータを探して更新
前回作成した標準モジュールMyDBに、下記関数を追加します。
Public Sub UpdateWithSelectedData(ByVal command As String, ByVal data As String) If 0 = adoRecordset.RecordCount Then '登録レコード数が 0 なら何もしない Exit Sub End If Dim criteria As String criteria = "command = '" & command & "'" '"command = 'hogehoge'" になる adoRecordset.MoveFirst Call adoRecordset.Find(criteria, 0, adSearchForward) '現在のレコードも含めて検索 Do While Not adoRecordset.EOF adoRecordset.Fields("data") = data adoRecordset.Update 'レコードの内容を更新 Call adoRecordset.Find(criteria, 1, adSearchForward) '現在のレコードを含めないで検索 LoopEnd Sub
先頭から検索するため、9行目でカレントレコードを先頭に変更します。
続いて、ADOの Find() メソッドに検索条件を指定して、
該当するレコードをカレントレコードにセットします(10行目)。
最後まで検索しきるまで Find() を繰り返すことで、該当する全レコードを検索できます(15行目)。
ポイントは Find() の第2引数。
最初(10行目)はカレントレコードも検索対象にしたいので、
SkipRecords(検索開始オフセット位置)に 0 を指定します。
次からはカレントレコードを含めないで検索させたいので、
SkipRecordsに 1 を指定して、カレントレコードの次から検索させます。
なお、Find() には検索開始位置も指定できます(Start)。
これを使うと、上記とは異なった実装になります。
レコード内容の更新はレコード登録と同じやり方です。
カレントレコードのカラムの値を変更して、Update() でデータを更新します(13行目)。
「特定のデータを更新したい(UPDATE)」はここまでです。
次の記事では特定のデータを削除(DELETE)する方法をご紹介します(^^)/~