Microsoft Access 掲示板

SQL ServerからADOで取得したRecordsetの扱いについてご教示いただけないでしょうか。 / 2

2 コメント
views
4 フォロー
2

リンクテーブルから取得していた時のように連結フィールドへのデータ入力が
そのままがDBに反映されることはない?

Office VBA Reference: Bind a form to an ADO Recordset

・そのレコードセットが ADO を介して更新可能であること。

・そのレコードセットに一意なインデックス(テーブルの主キーなど)が含まれていること。

基本的には上記の条件を満たしているか否か次第。

SQL等は割愛します

なので、レコードセットを開く際にどのような SQL 文を実行しているかも
無関係ではありません。

従来のリンクテーブルで動作したしていたFilterを、
ADOで取得したフォームのレコードセットに適応しても画面に反映されない。

Me.Recordset.Filter = '内容'

ADO.Recordset オブジェクトと連結されたフォームにおいて、
そのフォームの Recordset プロパティを介して Filter プロパティを
設定するのは無効です。

リンクテーブルは遅いからADOを使えという知見が多く見られるため、
今回がんばって連結フォームの機能をADOで実現しようとしているが、
SQL Serverへのリンクテーブルを作成し、従来の様にレコードソースに
SQL文を入れる形でもよいのでしょうか?

そのテーブルやフォームの使用目的によるとしか。

想定されるユーザー数は現状では多くて20~30かと思います。増える可能性は大いにあります。

マルチユーザーアクセスを前提としているのであれば、少なくとも
SQL Server のテーブルに格納されている全てのレコードを、
編集目的のためにまるごと呼び出して表示するような処理は
極力避けた方がよいでしょう。
(トランザクションや排他ロックなどの制御を行なう必要があるなら
なおのこと)

Option Compare Database
Option Explicit

Private adoCn As ADODB.Connection
Private adoRs  As ADODB.Recordset

Private Const ServerName  As String = "ServerName"
Private Const UserName    As String = "UserName"
Private Const Password    As String = "PassWord"
Private Const CatalogName As String = "DatabaseName"
Private Const TableName As String = "TableName"

'フォームの[開く時]イベント
Private Sub Form_Open(Cancel As Integer)
On Error GoTo Err_Form_Open

    Me.Painting = False

    Set adoCn = New ADODB.Connection
    
    With adoCn
        'SQL Server Native Client をプロバイダーとする場合
        .ConnectionString = "Provider=SQLNCLI11;" & _
                            "Data Source=" & ServerName & ";" & _
                            "User Id=" & UserName & ";" & _
                            "Password=" & Password & ";" & _
                            "Initial Catalog=" & CatalogName & ";" & _
                            "DataTypeCompatibility=80"
        .CursorLocation = adUseClient
        .CommandTimeout = 1
        .Open
    End With
    
    Dim strSQL As String
    strSQL = "SELECT * FROM [dbo].[" & TableName & "] ORDER BY [ID];"
    
    Set adoRs = New ADODB.Recordset
    
    With adoRs
        Set .ActiveConnection = adoCn
        .Source = strSQL
        .CursorLocation = adUseClient
        .CursorType = adOpenKeyset
        .LockType = adLockOptimistic
        .Open
    End With
    
    Set Me.Recordset = adoRs
    
Exit_Form_Open:
    
    Me.Painting = True
    
    Exit Sub

Err_Form_Open:
    
    Dim ErrText As String
    ErrText = "実行時エラー " & Err.Number & ": " & Err.Description
    Debug.Print ErrText
    MsgBox ErrText, vbCritical, Me.Name & ".Form_Open"
    
    Call ReleaseObjects
    Cancel = True

End Sub

'フォームの[読み込み解除時]イベント
Private Sub Form_Unload(Cancel As Integer)
    
    Call ReleaseObjects

End Sub

'コマンドボタン[cmdExecFilter]の[クリック時]イベント
Private Sub cmdExecFilter_Click()

    '編集中のカレントレコードを保存する
    If Me.Dirty = True Then
        DoCmd.RunCommand acCmdSaveRecord
    End If
    
    Dim strCriteria As String
    
    '非連結テキストボックス[txtFilter]の値が
    '数値データに変換可能である場合
    If IsNumeric(Me![txtFilter].Value) Then
        'フィールド[ID]の値が、非連結テキストボックス[txtFilter]の値を
        '整数値に変換した結果と等しいレコードを抽出する条件式
        strCriteria = "[ID]=" & CLng(Me![txtFilter].Value)
    End If
    
    'フィルターを適用
    adoRs.Filter = strCriteria
    
    'レコードセットを再連結
    Me.Painting = False
    Set Me.Recordset = Nothing
    Set Me.Recordset = adoRs
    Me.Painting = True

End Sub

'コマンドボタン[cmdClose]の[クリック時]イベント
Private Sub cmdClose_Click()

    'このフォームを閉じる
    DoCmd.Close acForm, Me.Name, acSaveNo

End Sub

'オブジェクトの解放処理
Private Sub ReleaseObjects()
On Error Resume Next

    If Not adoRs Is Nothing Then
        If adoRs.State = adStateOpen Then
            adoRs.Close
        End If
        Set adoRs = Nothing
    End If
    
    If Not adoCn Is Nothing Then
        If adoCn.State = adStateOpen Then
            adoCn.Close
        End If
        Set adoCn = Nothing
    End If

End Sub

とりあえずの例としては、上記のようなコードが挙げられますが。

通報 ...