5

フォームの読み込み時にデータシート サブフォームでこのコードを実行していますが、エラー メッセージやコード ブレークは表示されません。私の debug.print は、Recordset rs が本来あるべき 2131 レコードで満たされていることを示していますが、私のフォームには #Name? という 1 つの行が表示されています。あらゆる分野で。私のコントロールのコントロール ソース プロパティは、上に挙げたフィールド名とほぼ確実に一致します。RS はフォーム レベル変数であり、フォームが閉じるまで閉じたり、何も設定したりしません。

私は何が間違っているのですか?

Set rs = New ADODB.Recordset
rs.Fields.Append "TimesUsed", adInteger
rs.Fields.Append "strWorkType", adVarWChar, 150
rs.Fields.Append "DateLastUsed", adDate
rs.Fields.Append "SelectedYN", adBoolean
Set rs.ActiveConnection = Nothing
rs.CursorLocation = adUseClient
rs.LockType = adLockBatchOptimistic
rs.Open

Dim sSQL As String
sSQL = "MyComplicated SQL Statement Ommitted from this SO Question"

Dim r As DAO.Recordset
Set r = CurrentDb.OpenRecordset(sSQL, dbOpenDynaset, dbSeeChanges)
If Not (r.EOF And r.BOF) Then
    r.MoveFirst
    Dim fld
    Do Until r.EOF = True
        rs.AddNew
        For Each fld In r.Fields
            rs(fld.Name) = r(fld.Name).value
        Next
        rs.Update
        r.MoveNext
    Loop
End If
r.Close
Set r = Nothing
Debug.Print rs.RecordCount '2131 records
Set Me.Recordset = rs

わかりましたので、MSDN サイトでこれを読みました。

レコードセットには、テーブルの主キーなど、一意にインデックス付けされた 1 つ以上のフィールドが含まれている必要があります。

(注: この情報は、この文脈では誤りのようです。)

4

3 に答える 3

7

メモリ内オブジェクトのみであるレコードセットに主キーを設定することは可能ですか?

はい、Append MethodadFldKeyColumnのとして使用します。詳細については、 FieldAttributeEnumについてお読みください。Attrib

SQL ステートメントから使用できる適切な一意のフィールド (またはフィールドの組み合わせ) が既にある場合は、それを使用します。そうでない場合は、長い整数フィールドを作成し、それを偽の主キー フィールドとして使用します。挿入する行ごとに値を増やします。

rs.Fields.Append "pkey", adInteger, , adFldKeyColumn

また、Danny Lesandrini による Database Journal の次の記事が役立つかどうかも確認してください:インメモリ ADO レコードセットの作成

于 2012-05-05T03:14:11.827 に答える
5

これを機能させる唯一の方法は、LockType adLockPessimistic または adLockOptimisic を使用することであることがわかりました。明らかな理由で adLockReadOnly が機能せず、レコードセットが完全に機能しているように見えても、何らかの理由で adLockBatchOptimistic がフォームにレコードを表示することを許可しません。

また、このタイプの切断された Recordset をフォームにバインドするために、主キーを定義する必要がないこともわかりました。フォームを介してレコードセットを編集または更新することはできませんが、私のテストでは、エラー 3270 が発生していたため、このタイプのフォーム/レコードセットを編集できないことがわかりました。 (欠落しているプロパティと関係があります)。それは本当にこの質問の範囲外です。

作業中のインメモリ レコードセットを作成するために必要な最小限のコードは次のとおりです。

Dim rs As ADODB.Recordset 'Form Level variable

Private Sub Form_Load()
    Set rs = New ADODB.Recordset
    rs.Fields.Append "ID", adInteger
    'Set rs.ActiveConnection = Nothing 'Not Required
    'rs.CursorType = adOpenKeyset 'Not Required
    'rs.CursorLocation = adUseClient 'Not Required
    rs.LockType = adLockPessimistic 'May also use adLockOptimistic
    rs.Open

    Dim i as Integer

    For i = 1 To 10
        rs.AddNew
        rs("ID").Value = i
        rs.Update
    Next i

    Set Me.Recordset = rs
End Sub

フォーム (私の場合はデータシート ビュー) をこのような切断されたレコードセットにバインドすることは、私の特定のニーズに適したシンプルなソリューションであると最初に思いました。しかし、私はいくつかの問題に遭遇しました。フォームが ADO​​ レコードセットにバインドされている場合、既定のフォームの並べ替えが機能していないように見えます。また、何らかの理由で、このレコードセットを編集可能/更新可能にすることができませんでした。これは、私のニーズの要件でした (基本的に、マルチチェック リストとして使用していました)。(空のテーブルであっても) テーブルからレコードセットを取得して切断すると、この問題を回避できます。レコードを追加/編集しようとしたときに表示される 3270 エラー メッセージから判断すると、テーブルは、上記のコードで設定に失敗したある種の構造またはプロパティを提供しているようです。そして、私は'

結論として、代わりに Access の「一時」テーブルを使用することに頼ると思います。これは、複雑さが軽減され、上に挙げた問題が発生しないためです。

于 2012-05-05T15:00:16.140 に答える
4

注: 上記の「インメモリ ADO レコードセットの作成」の例を使用して、新しいレコードを挿入するとともに、すべてを正しく機能させることができました。 次に、次をフォーム コードに変更します。 rstADO.Update 後の MoveFirst & rstADO.MoveLast

Option Compare Database
Dim rstADO As ADODB.Recordset
Dim lngRecordID As Long

Private Sub Form_BeforeInsert(Cancel As Integer)

    lngRecordID = lngRecordID + 1
    rstADO.AddNew
    rstADO("EmployeeID").value = lngRecordID
    rstADO.Update
    rstADO.MoveFirst
    rstADO.MoveLast

End Sub

Private Sub Form_Load()

    Dim fld As ADODB.Field

    Set rstADO = New ADODB.Recordset
    With rstADO
        .Fields.Append "EmployeeID", adInteger, , adFldKeyColumn
        .Fields.Append "FirstName", adVarChar, 10, adFldMayBeNull
        .Fields.Append "LastName", adVarChar, 20, adFldMayBeNull
        .Fields.Append "Email", adVarChar, 64, adFldMayBeNull
        .Fields.Append "Include", adInteger, , adFldMayBeNull
        .Fields.Append "Selected", adBoolean, , adFldMayBeNull

        .CursorType = adOpenKeyset
        .CursorLocation = adUseClient
        .LockType = adLockPessimistic
        .Open
    End With
    Set Me.Recordset = rstADO

End Sub

Private Sub Form_Unload(Cancel As Integer)

    Set rstADO = Nothing

End Sub
于 2012-07-26T06:37:31.130 に答える