Je développe une application dans Access 2007. Elle utilise un frontal .accdb se connectant à un backend SQL Server 2005. J'utilise des formulaires liés aux jeux d'enregistrements ADO lors de l'exécution. Par souci d'efficacité, les enregistrements contiennent généralement un seul enregistrement, et sont interrogés sur le serveur:Les formulaires liés aux jeux d'enregistrements ADO pouvant être mis à jour ne peuvent pas être mis à jour lorsque la source inclut un JOIN
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 (la chaîne containg la TSQL sur laquelle le recordset est basé) est assemblé par la routine d'appel, dans ce cas de l'événement Open du formulaire étant lié:
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
le jeu d'enregistrements renvoyé par setupformrecordset est entièrement actualisable, et sa propriété .Prend montre. Il peut être édité et mis à jour dans le code.
Le formulaire entier, cependant, est en lecture seule, même si ses propriétés .AllowEdits et .AllowAdditions sont toutes deux vraies. Même les champs du côté droit (le côté 'plusieurs') ne peuvent pas être édités.
La suppression de la clause INNER JOIN du TSQL (en limitant strSource à une table) rend le formulaire entièrement modifiable.
J'ai vérifié que le TSQL inclut des champs de clé primaire des deux tables, et chaque table inclut un champ d'horodatage pour la simultanéité.
J'ai essayé de modifier les propriétés .CursorType et .CursorLocation du jeu d'enregistrements en vain.
Qu'est-ce que je fais mal?
"Bien que la méthode Supports puisse renvoyer True pour une fonctionnalité donnée, elle ne garantit pas que le fournisseur peut rendre la fonctionnalité disponible dans toutes les circonstances La méthode Supports renvoie simplement si le fournisseur peut prendre en charge la fonctionnalité spécifiée. Par exemple, la méthode Supports peut indiquer qu'un objet Recordset prend en charge les mises à jour, même si le curseur est basé sur une jointure de table multiple - certaines colonnes ne peuvent pas être mises à jour. " - http://msdn.microsoft.com/en-us/library/ms676500%28VS.85%29.aspx – barrowc
Ce type de code: "If Not Nz (.RecordSource, vbNullString) = vbNullString Then "me fait mal à la tête Pourquoi pas" If Not IsNull (.RecordSource) "? Si .RecordSource ne peut pas être nul et est un ZLS lorsqu'il est vide, alors" Len (.RecordSource) = 0 " serait le bon test –