フォーム上での検索処理は、MS-Access で日常的に行われる処理の一つです。
たとえば [氏名] 欄を「山田」で前方一致検索して、該当レコードがアクティブになったとします。
[氏名] 欄を見れば、「山田太郎」さんであることが分かります。
次に [都道府県] 欄を「東京都」で検索して、該当レコードがアクティブになったとします。
[都道府県] 欄を見れば、「東京都」であることが分かります。
では今度は、ちょっと長い [プロフィール] 欄を「水泳」で部分一致検索して、該当レコードがアクティブになったとします。
プロフィールの長さにもよりますが、たまたま「水泳」が先頭付近に有るのでない限り、「水泳」の箇所を探すのに少し手間取るかもしれませんね。
[プロフィール] ならまだいいですが、これが [論文] なんてフィールドだったら大変です。
メモ型フィールドに 5,000 字入っていたりした日には、「干し草の山から針を探す」ということわざの意味を体感する破目にもなりかねません。
こんなとき、Google のキャッシュや HTML ヘルプの検索でお馴染みの、検索語句の強調表示が出来るといいですね。
残念ながら、MS-Access の標準コントロールには検索語句の強調表示機能を持ったコントロールは存在しません。したがって、ActiveX コントロールを使用して自前で実装することになります。
※ Access 2007 からメモ型フィールドにリッチ テキスト書式(実体は HTML)が追加されたため、Access 2007 以降 (accdb) では組み込みコントロールだけで強調表示が可能になっています。筆者は Access 2007 を所有していないので、2007 用のサンプルを提供できません。このトピックはあくまで Access 2003 までのバージョンを前提としています。ご了承ください。2007 以降用の方法をお探しの方は、下記リンク先をご参照ください。
私が思いつく範囲では、次の 2 つの選択肢が有り得るでしょう。
それぞれ一長一短があります。
特徴を表にしてみましょう。
| 形式 | 直接編集 | 表現力 | 資料 | Access 2003 | |
|---|---|---|---|---|---|
| Rich TextBox | RTF | ○ | △ | 少 | 使用不可 |
| Web Browser | HTML | × | ○ | 多 | 使用可 |
以下では、この 2 つの手法について、それぞれ解説をしていきます。
ただし事前に断っておきますが、MS-Access の帳票形式フォームは実体が 1 つしか無いものを複数存在するように見せかけるために特殊な実装を行なっており、MS-Access の標準コントロールはそれに対応していますが、ActiveX コントロールは対応していないので、帳票形式フォームでは正常に動作しません。
あくまで単票形式フォーム上のみでの限定使用となります。
※ ここでは VBA の記述およびオートメーションの手法そのものについては解説しません。VBA 全般の知識はすでにあるものとして、説明されています。VBA およびオートメーションの基礎については、ヘルプあるいは市販の参考書籍をご覧ください。
※ Access 95 および Access 97 については、Office Developer Edition でない場合は環境に ActiveX コントロールが付属していない可能性が有るため、対象外としています。環境に ActiveX コントロールが存在する場合は、同じ方法論を使えるはずです。
Rich TextBox コントロールは、RTF(リッチテキスト形式)を表示するコントロールです。
分かりやすく言えば、Windows OS 付属のアクセサリであるワードパッドをそのまま埋め込めると考えればよいでしょう。
最大のメリットは、Rich TextBox コントロール上で直接テキストを編集できることです。そのため、通常のテキストボックスとほとんど変わらない操作性を維持できます。
一方デメリットとしては、表現力の貧弱さと RTF 仕様の古さ、分かりにくさを挙げることが出来ます。
RTF は HTML/XML が現在のように標準化する以前に Microsoft が提唱した古い規格で有るため、現在の HTML/XML が持つような多様な表現力を持ちません。また RTF はテキストを完全にエンコードするため、ソースを見てもそのままでは人間は読めません。
もっとも、ここで意図しているような語句の強調表示に必要な機能(下線、太字、文字色の変更など)は全て備えているので、よほど高度な処理を必要としない限り、表現力が問題になることは実際にはあまり無いでしょう。また Rich TextBox コントロールは VB 付属のコントロールとして昔から使用されてきた実績があり、各種メソッドやプロパティが充実しています。ソースを直接編集する必要も、通常はまず無いでしょう。
ただし MS-Access には一部を除いて ActiveX コントロールに関するヘルプが付属していないので、例によって資料不足というハンディキャップが付いて回ります。
この辺りについては、インターネット時代の強みを最大限に生かして、Web 上のリソースで補う必要が有ります。
さて、まずは ActiveX コントロールを配置するための単票形式フォームが必要です。
今回も MS-Access 付属のサンプル データベース NorthWind.mdb にご登場いただくことにしましょう。
[社員] フォームを少し改造して、検索用のテキストボックスとコマンドボタンを配置します。
今回はサンプルをダウンロードできるようにするため、ファイルサイズに影響する写真フィールドなどは削除しています。
続いて [挿入]-[ActiveX コントロール] から「Microsoft Rich TextBox Control, version 6.0」を選択して <OK> を押下します。
ここでは Rich TextBox コントロールの名前を「xRtb」と付けることにします。
次に、挿入した Rich TextBox コントロールをダブルクリックして、プロパティを表示させます。
環境によってはメニューが英語表記(英語版の ActiveX)かもしれませんが、項目に差が有るわけではありませんので、適宜読み替えてください。
ここで [描画スタイル] タブの [スクロール バー] から「rtfVertical」を選んでおきましょう。
こうしておかないと、テキストが長くて表示しきれない場合でも、スクロールバーが表示されません。
後は <適用> と <OK> を押下して、プロパティを閉じます。
今回の仕様としては、検索語句を入力して <検索> を押下すると、該当箇所が赤字・太字・下線付きの大サービスで表示される、ということにしておきましょうか。
ただし、あくまでカレントレコード内での検索です。
Rich TextBox コントロールはフィールドに連結することも可能ですが、連結すると RTF ソースの方が格納されてしまいます。
そこで、Rich TextBox コントロールは非連結のままにしておき、以下の 3 つの機能を実装することにします。
というわけで、以下が今回追加する全コードです。
Option Compare Database Option Explicit Const SOURCE_FIELD = "プロフィール" Const FIND_TEXTBOX = "txt検索" Const RICH_TEXTBOX = "xRtb" Dim DisableEvents As Boolean ' xRtb_Change イベント停止フラグ Private Sub Form_Open(Cancel As Integer) DisableEvents = True ' xRtb_Change イベント無効化 End Sub Private Sub Form_Load() DisableEvents = False ' xRtb_Change イベント有効化 End Sub Private Sub Form_Current() ' Rich TextBox コントロールにプロフィールを代入します。 DisableEvents = True ' xRtb_Change イベント無効化 Me(RICH_TEXTBOX) = Nz(Me(SOURCE_FIELD)) DisableEvents = False ' xRtb_Change イベント有効化 End Sub Private Sub cnd検索_Click() ' 検索を実行します。 If IsNull(Me(FIND_TEXTBOX)) Then MsgBox "検索語句を指定してください。", vbExclamation ElseIf FindInRTB(Me(RICH_TEXTBOX).Object, Me(FIND_TEXTBOX)) = 0 Then MsgBox "検索語句は見つかりませんでした。", vbInformation End If End Sub Private Sub xRtb_Change() ' [プロフィール] フィールドに、Rich TextBox のプレーンテキストを代入 If DisableEvents Then Exit Sub ' イベント停止フラグがオンの場合は終了 Me(SOURCE_FIELD) = Me(RICH_TEXTBOX).Object.Text End Sub ' リッチテキストボックス上で文字列検索します。 ' 引数の説明: ' rtb 必須。RichTextBox オブジェクトを渡します。 ' strFind 必須。検索語句を渡します。 ' IsMatchCase 省略可。検索時に大文字と小文字を区別する場合は True を、 ' 区別しない場合は False を渡します。 ' 戻り値: ' 存在した検索語句の数を返します。 Private Function FindInRTB(rtb As RichTextBox, _ strFind As String, _ Optional IsMatchCase As Boolean) As Integer ' 変数宣言部 Dim strText As String Dim intLenBFind As Integer Dim intOffset As Integer Dim intOffsetSJIS As Integer ' 変数を初期化 strText = rtb.Text rtb.Text = strText ' 前回の検索結果をクリア intLenBFind = LenB(StrConv(strFind, vbFromUnicode)) ' 例外処理 If (intLenBFind = 0 Or LenB(strText) = 0) Then GoTo ExitProcedure ' 検索 intOffset = rtb.Find(strFind, , , IsMatchCase * -4) Do Until intOffset = -1 rtb.SelUnderline = True ' 下線を引く rtb.SelColor = vbRed ' 文字色を赤に設定 rtb.SelBold = True ' 太字に設定 intOffsetSJIS = LenB(StrConv(Left$(strText, intOffset) _ , vbFromUnicode)) + intLenBFind intOffset = rtb.Find(strFind, intOffsetSJIS, , IsMatchCase * -4) FindInRTB = FindInRTB + 1 ' 戻り値をセット Loop ExitProcedure: Set rtb = Nothing End Function
このコードのポイントは 2 つ有ります。
1 つは Rich TextBox の Change イベントで、変更されたテキストを [プロフィール] フィールドへ代入する際に、フラグを参照して代入を行なうかどうか判定させている箇所です。
Change イベント自体は、フォームを開く際や、レコード移動時の初期化時にも発生しますが、そこで代入しても意味が無いので、フラグを立てて代入を停めています。
もう 1 つは、Rich TextBox の検索ルーチンにあります。
Find メソッドは、検索語句が見つからないと -1 を、検索語句が見つかるとそのオフセットを返します。
このオフセットは文字単位です。
次のループでは、前回の検索語句位置の最後から検索を再開します。
しかしFind メソッドが引数として取る検索開始位置および検索終了位置は ASCII 形式のバイト単位なのです。
この違いは、英語圏であればさほど問題にはならないでしょうが、日本語のような DBCS 使用圏では致命的な実装ミスにつながりかねません。
そのため、検索開始位置(あるいは検索終了位置)を特定するために、まずオフセット文字列を StrConv 関数でユニコードから ASCII コードに変換し、次に LenB 関数でバイト数を取得しています。
...というわけで、実行結果はこちら。
けっこういい感じじゃないですかね、コレは。
Web Browser コントロールは、HTML を表示するコントロールです。
分かりやすく言えば、Intrernet Explorer をそのまま埋め込んだものと考えればよいでしょう。
最大のメリットは、HTML/DHTML の持つ表現力の多様性と可能性、そして HTML 仕様の分かりやすさにあります。
一方デメリットとしては、直接テキストを編集できないという点を挙げることが出来ます。Web Browser コントロールは閲覧専用なので、もし編集したければ別のテキストボックスを用意して切り替える必要があります。
この辺は Rich TextBox と正反対ですね。
Web Browser コントロールもロクにヘルプが無いという意味では Rich TextBox コントロールと同じハンディキャップは有りますが、HTML や IE に関する Web リソースの多さは RTF の比では有りません。
情報が有り過ぎてどれから手を付けて良いか分からないという嬉しい悩みは有ったとしても、情報が見つからないということだけは無さそうです。
さて、とにもかくにも ActiveX コントロールを配置するための単票形式フォームが必要です。
Rich TextBox コントロールの場合と同様に、NorthWind.mdb の [社員] フォームを改造して、検索用のテキストボックスとコマンドボタンを配置します。
続いて [挿入]-[ActiveX コントロール] から「Microsoft Web Browser」を選択して <OK> を押下します。
ここでは Web Browser コントロールの名前を「xWb」と付けることにします。
今回の仕様としては、検索語句を入力して <検索> を押下すると、該当箇所が太字、背景色が黄色で表示される、ということにしておきましょうか。
今度もあくまでカレントレコード内での検索です。
相手が IE なので、HTML および DOM(Document Object Model)とあるていど格闘する覚悟は必要です。
もっともそんなに難しいことをやるつもりはない(できない?^ ^;)ので、別にビビる必要はありません。
というわけで、以下がフォームのクラスモジュール全コードです。
Option Compare Database Option Explicit Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Const SOURCE_FIELD = "プロフィール" Const FIND_TEXTBOX = "txt検索" Const WEB_BROWSER = "xWb" Private Sub Form_Load() Call InitWB(Me(WEB_BROWSER).Object) ' Web Browser を初期化 End Sub Private Sub Form_Current() ' Web Browser コントロールにプロフィールを代入します。 Call FindInWB(Me(WEB_BROWSER).Object, Nz(Me(SOURCE_FIELD))) End Sub Private Sub cnd検索_Click() ' 検索を実行します。 If IsNull(Me(FIND_TEXTBOX)) Then MsgBox "検索語句を指定してください。", vbExclamation ElseIf FindInWB(Me(WEB_BROWSER).Object, Nz(Me(SOURCE_FIELD)), _ Me(FIND_TEXTBOX)) = 0 Then MsgBox "検索語句は見つかりませんでした。", vbInformation End If End Sub ' Web Browser を初期化します。 Private Sub InitWB(wb As SHDocVw.WebBrowser) ' 定数宣言部 Const STYL_BODY = "BODY {margin:2;font-size:10pt;}" Const STYL_FIND = ".FIND {background-color:yellow;" _ & "font-weight:bolder;}" ' 空文書をロード wb.Navigate2 "about:blank" Do While wb.ReadyState <> READYSTATE_COMPLETE Sleep 100 ' 0.1 秒待機します。 DoEvents Loop ' テンプレートを出力 With wb.Document .writeln "<HTML><HEAD>" .writeln "<meta http-equiv='Content-Language' content='ja'>" .writeln "<meta http-equiv='Content-Type'" _ & " content='text/html; charset=shift_jis'>" .writeln "<STYLE MEDIA='ALL' TYPE='TEXT/CSS'>" .writeln STYL_BODY .writeln STYL_FIND .writeln "</STYLE></HEAD>" .writeln "<BODY></BODY></HTML>" End With End Sub ' Web ブラウザに検索結果を表示します。 ' 引数の説明: ' wb 必須。Web Browser オブジェクトを渡します。 ' source 必須。対象文字列を渡します。 ' find 省略可。検索語句を渡します。 ' compare 省略可。比較の方法を指定します。 ' 省略時は大文字と小文字を区別します。 ' 戻り値:存在した検索語句の数を返します。 Private Function FindInWB( _ wb As SHDocVw.WebBrowser, _ source As String, _ Optional find As String, _ Optional ByVal compare As VbCompareMethod = vbBinaryCompare) _ As Integer ' 変数宣言部 Dim strSource As String Dim strFind As String Dim strReplace As String Dim intCount As Integer ' 対象文字列が空文字列の場合 If (LenB(source) = 0) Then wb.Document.body.innerHtml = vbNullString ' 検索語句が空文字列の場合 ElseIf (LenB(find) = 0) Then wb.Document.body.innerHtml = EscapeStr(source) ' 検索語句が指定されている場合 Else intCount = UBound(Split(source, find, -1, compare)) ' 検索語句が見つからなかった場合 If (intCount = 0) Then wb.Document.body.innerHtml = EscapeStr(source) ' 検索語句が見つかった場合 Else strSource = EscapeStr(source) strFind = EscapeStr(find) strReplace = "<SPAN CLASS='FIND'>" & strFind & "</SPAN>" wb.Document.body.innerHtml _ = Replace(strSource, strFind, strReplace, 1, -1, compare) End If End If ' 戻り値をセットします。 FindInWB = intCount End Function ' 文字列を HTML ソース用に簡易エスケープします。 Private Function EscapeStr(source As String) As String Dim strTemp As String strTemp = Replace(source, "&", "&", 1, -1, vbBinaryCompare) strTemp = Replace(strTemp, "\", "¥", 1, -1, vbBinaryCompare) strTemp = Replace(strTemp, "<", "<", 1, -1, vbBinaryCompare) strTemp = Replace(strTemp, ">", ">", 1, -1, vbBinaryCompare) strTemp = Replace(strTemp, """", """, 1, -1, vbBinaryCompare) strTemp = Replace(strTemp, vbCrLf, "<BR>", 1, -1, vbBinaryCompare) EscapeStr = strTemp End Function
ポイントは、取り立てて無いですね。
Web Browser が空文書をロードするあいだの時間稼ぎに、Win32 API の Sleep 関数を使っていることくらいでしょうか。
後は、コードが幾ら長いとは言っても、結局やっていることは単なる文字列処理ですから。
...というわけで、実行結果はこちら。
これまた、けっこういい感じじゃないですか。
Web Browser コントロールにはホームページと同じ内容を表示させられるので、凝る気になれば、検索語句の先頭にアニメーション GIF を表示させてド派手に強調するなんてことも(あまり意味は有りませんが)出来てしまいますし、文章中の一部にハイパーリンクを張って、クリックしたらジャンプさせるなんてこともお手のモノです。
ただし原則として閲覧のみで編集は出来ません。
もし [プロフィール] を編集させたい場合は、連結テキストボックスを背後に重ねておいて、Web Browser コントロールがダブルクリックされたタイミングなどでフォーカスを移動するという感じでしょうか。
ただし編集後の内容を Web Browser コントロールに反映させる処理が必要になるでしょうから、実際にはもう少し手がかかります。
今回のサンプルでは、そこまでは実装していません。
Web Browser コントロールでは編集は出来ない、と言った舌の根も乾かないうちにこう言うのも何ですが、ある条件を満たすと Web Browser コントロール上で直接編集が出来ます。
どこまで一般的に認知されているのかは知りませんが、Internet Explorer 5.5 以降では MSHTML Editing という機能が追加されており、この機能をオンにするとブラウザ上でコンテンツの直接編集が可能になります。つまり IE がエディターに早変わりするというわけです。
これを利用すれば、Web Browser コントロール上での直接編集も もちろん可能です。
ただし利用環境に必ず IE 5.5 以降がインストールされていることが必須条件となります。
バージョンが 5.5 未満の方は、下記から最新版を入手してみてください。
ひょっとすると半信半疑の方もいらっしゃるかもしれませんから、まずは自分の手で簡単に Web Browser コントロールを編集可能にできるところを実際にご覧いただいた方が早いでしょう。
前章で使用した社員フォームを再度デザインビューで開いてください。
もちろんこの時点では、フォーム上でのテキスト編集はできません。
クラスモジュールを開き、InitWB サブプロシージャのコードを修正します。
とは言っても、たったの一箇所だけです。
以下に再掲して、追加箇所を太字にしておきます。
' Web Browser を初期化します。 Private Sub InitWB(wb As SHDocVw.WebBrowser) ' 定数宣言部 Const STYL_BODY = "BODY {margin:2;font-size:10pt;}" Const STYL_FIND = ".FIND {background-color:yellow;" _ & "font-weight:bolder;}" ' 空文書をロード wb.Navigate2 "about:blank" Do While wb.ReadyState <> READYSTATE_COMPLETE Sleep 100 ' 0.1 秒待機します。 DoEvents Loop ' テンプレートを出力 With wb.Document .writeln "<HTML><HEAD>" .writeln "<meta http-equiv='Content-Language' content='ja'>" .writeln "<meta http-equiv='Content-Type'" _ & "content='text/html; charset=shift_jis'>" .writeln "<STYLE MEDIA='ALL' TYPE='TEXT/CSS'>" .writeln STYL_BODY .writeln STYL_FIND .writeln "</STYLE></HEAD>" .writeln "<BODY contentEditable='true'></BODY></HTML>" End With End Sub
これだけです。
修正にはものの 10 秒もかからないでしょう。
社員フォームをフォームビューで開き直して、[プロフィール] 欄をクリックしてみてください。カーソルがビームポインタ(I 字型)に変わり、明らかに編集が出来るようになっていることを確認できるはずです。
もしコードの修正前と変化が無い場合は、IE のバージョンが 5.5 未満ということになります。
さて、これで Web Browser コントロール上での直接編集は可能になりましたが、編集後にレコードを移動したりフォームを閉じたりすると、現状では変更内容は失われてしまいます。
フィールドと連結していないので当然ですが、それでは MS-Access 的に困るので、変更が有った場合は内容をフィールドに書き戻すようにコードを修正してみましょう。
まずモジュールレベルで変更可能かどうかを判定するフラグ用の変数を宣言し、フォームのロード時に IE のバージョンを調べて変数をセットするようにします。
該当箇所のコードは下記の通りです。
Option Compare Database Option Explicit Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Const SOURCE_FIELD = "プロフィール" Const FIND_TEXTBOX = "txt検索" Const WEB_BROWSER = "xWb" Dim isAllowEdit As Boolean ' 編集可能フラグ Private Sub Form_Load() With Me(WEB_BROWSER) Call InitWB(.Object) ' Web Browser を初期化 ' IE5.5 以上の場合は、編集可能フラグを True にセットします。 isAllowEdit = (Val(Split( _ .Object.Document.window.clientInformation.appVersion, _ "MSIE")(1)) >= 5.5) End With End Sub
続いて、Web Browser コントロールの [フォーカス喪失時] イベントで、変更が有った場合にその内容をフィールドに書き戻すためのコードを追加します。
Private Sub xWb_Exit(Cancel As Integer) Dim strContent As String ' 編集不可の場合はプロシージャを終了します。 If (isAllowEdit = False) Then Exit Sub ' 内容が変更されている場合は、フィールドを更新します。 strContent = Me(WEB_BROWSER).Object.Document.body.innerText If StrComp(Nz(Me(SOURCE_FIELD)), strContent, vbBinaryCompare) Then _ Exit Sub Me(SOURCE_FIELD) = strContent RunCommand acCmdSaveRecord ' レコードを保存します。 End Sub
さて、早速テストしてみましょうか。
ご覧の通り、書き変え可能になっています。
# ヒトの趣味を勝手に変えてはいけませんね。(^ ^;)
繰り返しになりますが、Web Browser コントロールは IE とほとんど同じことが出来るので、DHTML を駆使したりすると MS-Access 単体では実現不可能な視覚効果をほんの数行のコードで得る事ができます。
しかもこの ActiveX コントロールは、特に何も考慮しなくても、ほぼ確実にどの環境にも存在します。
せっかくですから、大いに活用したいものです。
下記リンクからサンプル MDB をダウンロードできます。
ImprsWrd.lzh (Access 2000 形式 - 64kb)
lzh 形式で圧縮されており、解凍すると MDB ファイルが展開します。
解凍用のソフトが無い場合は、Vector 等のソフトウェアライブラリから入手する必要があります。
解凍後、MDB ファイルを実行中に次のようなエラーメッセージが表示されるかもしれません。
イベント名は「読み込み時」だったり「レコード移動時」だったりするかもしれません。
この場合は ActiveX コントロールを表示するために必要なライブラリへの参照設定に問題が発生している可能性があります。
Visual Basic Editor の [ツール]-[参照設定]-[参照可能なライブラリファイル] の中で、「Microsoft Internet Controls」と「Microsoft Rich Textbox Control 6.0 (SP3)」がオンになっていることを確認してください。
もしチェックが入っているライブラリ名の先頭に「参照不可」と表示されているものが有れば、チェックを外してください。
もし一覧の中に「Microsoft Internet Controls」と「Microsoft Rich Textbox Control 6.0 (SP3)」のライブラリが見当たらないか、あるいは参照不可の場合は、<参照> をクリックして対象ライブラリを直接指定してください。
| コントロール | ライブラリ | ファイル |
|---|---|---|
| Web Browser | Microsoft Internet Controls | shdocvw.dll |
| Rich Textbox | Microsoft Rich Textbox Control 6.0 (SP3) | richtx32.ocx |
パスは環境によって異なる可能性があるため、検索する必要があるかもしれません。
検索する際は、Windows エクスプローラのオプション設定で、隠しファイルや隠しフォルダを表示していること、拡張子を表示する設定になっていることを確認してください。また Windows XP では検索ウィンドウの詳細設定オプションの中で [隠しファイルと隠しフォルダの検索] がオンになっていないと素通りしてしまいます。ご注意ください。
今回必要な 2 つのライブラリのうち、shdocvw.dll で問題が起きる可能性は低いでしょう。
問題が起きるとしたら、richtx32.ocx です。
richtx32.ocx は Office Developer Edition や Visual Studio のような開発製品をインストールすると入ります。
もし環境に存在しない場合は、雑誌の付録 CD-ROM や VECTOR などのサイトから VB6.0 用ランタイムパッケージを入手後インストールしてください。
ランタイムは重すぎるという場合は、@ガッテンで OCX 群のみの軽量パッケージを配布しているので、利用するとよいでしょう。
ちなみにあちこちに richtx32.ocx のみを DL できるところも有るようですが、ライセンス的にどうなのかはよく分かりません。
今回は、検索結果を一時的に強調表示する方法を紹介しました。
元のフィールドは、あくまで単なるプレーンテキストです。
これをもし、強調表示の状態のまま保存したい場合は、RTF か HTML ソースをそのままメモ型フィールドに格納しておくことになります。
ある意味、Rich TextBox の場合はこちらの方がラクです。
Rich TextBox コントロールの [コントロールソース] プロパティにメモ型フィールドを指定しておけば、それだけで OK で、今回実装したような更新時処理(フィールドへの書き戻し処理)は不要になります。
一方、Web Browser コントロールはデータソースへ連結できないので、やはり更新時処理が必要になります。
興味のある方はトライしてみてください。
なお、実際には、検索結果を一時的に強調表示する方法としてこれ以外にも Microsoft Word を使用する方法がありますが、ここでは取り上げませんでした。
今回それを除外したのには、以下の 3 つの理由があります。
特に今回のようにレコードを移動しながら更新をかけていくような使い方をした場合には 1 が致命的で、レコード移動してから内容が更新されるまで 1、2 秒のタイムラグが発生してしまいます。
逆に言うと、あるていどの処理の重さは許容できて、Word オートメーションにも抵抗が無いようなケースでは、MS-Access から Word の持つ豊富な機能に自在にアクセスできるわけですから、選択肢として検討する余地は十分有るでしょう。
MS のオフィシャルな関連リソースおよび国内の有益なサイトです。海外の民間サイトは膨大に有るので追っていません。各自で検索してみてください。
MSHTML Editing
リッチテキストボックス コントロール
ウェブブラウザ コントロール
※ 公開終了のため、web archive へ