I've created a table in a SQL Server 2017 database. Then I've created a form in MS Access 2019 that use an ADO Object as "record source". On the form, there is a Textbox with the controlsource property=Field. Then, when I open the form, everything works as expected (the content of Field shows up in the Textbox, I can move the cursor backwards and forwards and so on) except for one thing: It's not possible to change, add or delete records.
Create a table On SQL Server (use SSMS):
CREATE TABLE Table1 (Field INT PRIMARY KEY)
INSERT INTO Table1 (Field) VALUES (15)
INSERT INTO Table1 (Field) VALUES (12)
In Access Module:
#Const EarlyBinding = -1
#If EarlyBinding Then
' Irrelevant in this context
#Else
Global Const adUseClient As Long = 3
Global Const adLockBatchOptimistic As Long = 4
Global Const adOpenDynamic As Long = 2
#End If
In Access Form's VBA Code:
Private Sub Form_Load()
Dim sqldb as Object, adocom as Object, rs As Object
Set sqldb = CreateObject("ADODB.Connection")
Set adocom = CreateObject("ADODB.Command")
Set rs = CreateObject("ADODB.Recordset")
SQLDB.Open "Driver={SQL Server Native Client 11.0};Server=SQL;Database=Test;Trusted_Connection=yes;"
SQLDB.CursorLocation = adUseClient
rs.LockType = adLockBatchOptimistic
rs.CursorType = adOpenDynamic
adocom.CommandText = "SELECT Field FROM Table1"
set rs = adcom.execute
set Me.Recordset=rs
end sub
This problem is "boiled down" from a much more complex code. The query I pass to SQL Server takes several minutes to execute if I use DAO so the big point is to let SQL Server execute the query (takes < 1 sek).
So what do I have to do to make it possible to add, modify or delete a record?
DML commands like
adocom.execute ”UPDATE Table1 SET Field=25 WHERE Field=15”
works.
But well, the thing is, I want the Access Form to act in exactly the same way with an ADO recordset connected to a SQL Server as it would act if the recordset was handled by a DAO object connected to a backend .accdb-file. So it’s the recordset that should be updatable. The property rs.recordcount is -1 which indicates that the recordset is not updatable. If that property is something else but -1 after the adocom.execute line , then we’re home.