Access 2007でアプリケーションを開発しています。SQL Server 2005バックエンドに接続する.accdbフロントエンドを使用します。実行時にADOレコードセットにバインドされたフォームを使用します。効率のために、レコードセットは、通常、1つのレコードのみが含まれており、サーバー上で照会されます。ソースにJOINが含まれている場合、更新可能なADOレコードセットにバインドされたフォームは更新できません。
Public Sub SetUpFormRecordset(cn As ADODB.Connection, rstIn As ADODB.Recordset, rstSource As String)
Dim cmd As ADODB.Command
Dim I As Long
Set cmd = New ADODB.Command
cn.Errors.Clear
' Recordsets based on command object Execute method are Read Only!
With cmd
Set .ActiveConnection = cn
.CommandType = adCmdText
.CommandText = rstSource
End With
With rstIn
.CursorType = adOpenKeyset
.LockType = adLockPessimistic 'Check the locktype after opening; optimistic locking is worthless on a bound
End With ' form, and ADO might open optimistically without firing an error!
rstIn.Open cmd, , adOpenKeyset, adLockPessimistic 'This should run the query on the server and return an updatable recordset
With cn
If .Errors.Count <> 0 Then
For Each errADO In .Errors
Call HandleADOErrors(.Errors(I))
I = I + 1
Next errADO
End If
End With
End Sub
rstSource(レコードセットがベースとなっているTSQLをcontaing文字列)を呼び出しルーチンによって組み立てられ、
Private Sub Form_Open(Cancel As Integer)
Dim rst As ADODB.Recordset
Dim strSource As String, DefaultSource as String
Dim lngID As Long
lngID = Forms!MyParent.CurrentID
strSource = "SELECT TOP (100) PERCENT dbo.Customers.CustomerID, dbo.Customers.LegacyID, dbo.Customers.Active, dbo.Customers.TypeID, dbo.Customers.Category, " & _
"dbo.Customers.Source, dbo.Customers.CustomerName, dbo.Customers.CustAddrID, dbo.Customers.Email, dbo.Customers.TaxExempt, dbo.Customers.SalesTaxCode, " & _
"dbo.Customers.SalesTax2Code, dbo.Customers.CreditLimit, dbo.Customers.CreationDate, dbo.Customers.FirstOrder, dbo.Customers.LastOrder, " & _
"dbo.Customers.nOrders, dbo.Customers.Concurrency, dbo.Customers.LegacyLN, dbo.Addresses.AddrType, dbo.Addresses.AddrLine1, dbo.Addresses.AddrLine2, " & _
"dbo.Addresses.City, dbo.Addresses.State, dbo.Addresses.Country, dbo.Addresses.PostalCode, dbo.Addresses.PhoneLandline, dbo.Addresses.Concurrency " & _
"FROM dbo.Customers INNER JOIN " & _
"dbo.Addresses ON dbo.Customers.CustAddrID = dbo.Addresses.AddrID "
strSource = strSource & "WHERE dbo.Customers.CustomerID= " & lngID
With Me 'Default is Set up for editing one record
If Not Nz(.RecordSource, vbNullString) = vbNullString Then
If .Dirty Then .Dirty = False 'Save any changes on the form
.RecordSource = vbNullString
End If
If rst Is Nothing Then 'Might not be first time through
DefaultSource = .RecordSource
Else
rst.Close
Set rst = Nothing
End If
End With
Set rst = New ADODB.Recordset
Call setupformrecordset(dbconn, rst, strSource) 'dbconn is a global variable
With Me
Set .Recordset = rst
End With
End Sub
setupformrecordsetから返されるレコードセットが完全に更新可能であり、その.Supportsプロパティは、これを示していますフォームのOpenイベントから、この場合に束縛されます。これはコードで編集して更新することができます。
しかし、フォーム全体が.AllowEditsと.AllowAdditionsの両方のプロパティがtrueであっても、読み取り専用です。右手側(「多く」側)のフィールドでさえ、編集することはできません。
INNER JOIN句をTSQLから削除すると(strSourceを1つのテーブルに制限する)、フォームは完全に編集可能になります。
私は、TSQLに両方のテーブルのプライマリキーフィールドが含まれていることを確認しました。各テーブルには同時実行のタイムスタンプフィールドが含まれています。
レコードセットの.CursorTypeと.CursorLocationプロパティを無駄に変更しようとしました。
私は間違っていますか?
"Supportsメソッドは、特定の機能に対してTrueを返すことがありますが、プロバイダがすべての状況でこの機能を利用できるようにすることはできません。たとえば、Supportsメソッドは、カーソルが複数のテーブル結合に基づいていても、更新可能ではない列があっても、Recordsetオブジェクトが更新をサポートしていることを示している可能性があります。 - http://msdn.microsoft.com/en-us/library/ms676500%28VS.85%29.aspx – barrowc
この種のコード: "If Not Nz(。RecordSource、vbNullString)= vbNullStringそれから "私の頭が痛いのですが、なぜ" Not IsNull(.RecordSource) "なのでしょうか?.RecordSourceを空にすることはできませんし、空の場合はZLSです" Len(.RecordSource)= 0 " –