この6月からAccessを始めて生産管理アプリの作成に挑戦しております。
現在、社内ファイルサーバーにあるAccessファイルをバックエンドとし、
リンクテーブルで接続しています。
利用者は当日の生産目標や実績が一覧になった帳票フォームを操作画面とし、
フォームのロード時にVBAで生成したSQL文をレコードソースにセットする連結フォームの形で実現していました。
今回SQL Serverへの移行のため、コードの見直しをしております。
現状では、ADO接続で取得したRecordsetをフォームにセットすることで、
リンクテーブル時と同様に当日の案件を表示することができるようになりました。
しかし、動作が異なる箇所が多く非常に悩んでおります。
まだまだSQLもVBAも始めたばかりで、分からないことだらけの中、
自分1人で検索しながら答えを出すことに行き詰まってまいりました。
皆様アドバイスをいただけないでしょうか。
ADOで取得したレコードセットをフォームにセットしても、
リンクテーブルから取得していた時のように連結フィールドへのデータ入力が
そのままがDBに反映されることはない?(スナップショットの様な動作?)
⇒ 入力されたフィールドに対して、更新ボタンやイベントでカレントレコードに対して更新クエリを作成し、
ADOでDBに投げる形で更新する、といった動作のイメージでしょうか?
パススルークエリも検証してみましたが、同様にスナップショットとして扱われるのでしょうか。レコードセット取得文の一部抜粋(SQL等は割愛します)
With adoRs .ActiveConnection = adoCn .Source = strSQL .LockType = adLockOptimistic .CursorType = adOpenKeyset .CursorLocation = adUseClient .Open End With Set adoRs.ActiveConnection = Nothing Set t_form.Recordset = adoRs
従来のリンクテーブルで動作したしていたFilterを、
ADOで取得したフォームのレコードセットに適応しても画面に反映されない。
例)Me.Recordset.Filter = '内容'
⇒ 取得したレコードから更に絞り込んで表示したい場合は、
改めてADOでSQLを投げてレコードセットを更新するべき?リンクテーブルは遅いからADOを使えという知見が多く見られるため、
今回がんばって連結フォームの機能をADOで実現しようとしているが、
SQL Serverへのリンクテーブルを作成し、従来の様にレコードソースにSQL文を入れる形でもよいのでしょうか?
リンクテーブルは、VBAからDSNレスでの作成ができました。
(想定されるユーザー数は現状では多くて20~30かと思います。増える可能性は大いにあります。)
以上となります。
どうぞよろしくお願い申し上げます。
なかなか、回答が付かないですね。
私自身は、SQL Serverでの経験がないので、適切な回答はできないので、
感想的な回答ですので、参考程度に。
そのようなソースのリンクがあれば紹介してもらえますか。
個人的には、リンクテーブルだから遅いのではなく、リンクテーブルと連結したフォームだと、常に更新可能なレコードセットとしてサーバーデータと常時接続された状態だから、遅いのだと思います。
ですので、ADOのレコードセットを開いて、フォームと連結させたら、結局、上記と同じ状態なので、速度的にはたいしてかわらないと推測しています。
もし、リンクテーブルと連結したフォームより、ADOのレコードセットと連結したフォームの方が速度的に有利であるという信頼できるソースがあるなら知りたいです。
下記によると要件さえ満たしいれば、更新可能になるようです。
ADO レコードセットにフォームを連結します | Microsoft Docs
フォームのそのようなプロパティはレコードソースで接続していることが前提のようで、Recordsetプロパティで連結した場合はほとんど使えないようです。RecordsetのFilterプロパティを使うか、SQLでレコードセットを再取得して、それと連結させるという処理が必要なようです。
ということで、あくまで、想像ですが、
連結フォームのような使い勝手は難しいと思います。
結局、速度改善したいなら、
パススルークエリで、必要なデータのみ取得して、これは閲覧のみ、更新する場合は、別に非連結フォームで更新したものを、更新クエリ、あるいは追加クエリでデータ更新することになるのではと思っています。
Office VBA Reference: Bind a form to an ADO Recordset
・そのレコードセットが ADO を介して更新可能であること。
・そのレコードセットに一意なインデックス(テーブルの主キーなど)が含まれていること。
基本的には上記の条件を満たしているか否か次第。
なので、レコードセットを開く際にどのような SQL 文を実行しているかも
無関係ではありません。
ADO.Recordset オブジェクトと連結されたフォームにおいて、
そのフォームの Recordset プロパティを介して Filter プロパティを
設定するのは無効です。
そのテーブルやフォームの使用目的によるとしか。
マルチユーザーアクセスを前提としているのであれば、少なくとも
SQL Server のテーブルに格納されている全てのレコードを、
編集目的のためにまるごと呼び出して表示するような処理は
極力避けた方がよいでしょう。
(トランザクションや排他ロックなどの制御を行なう必要があるなら
なおのこと)
とりあえずの例としては、上記のようなコードが挙げられますが。