So I'm trying to do something a bit out of the norm. I've built a class to work with DAO and establish a connection to a SQL Server without using the local DB.
I create a database in memory and set with an OpenDatabase command that points directly to a SQL server. Then I have an "OpenRecordset" method on my class which returns a recordset.
When I set the combobox.recordset = db.OpenRecordset, data shows up in the combobox, but when a user selects something from the combobox it acts as if it just had a .requery run on it and whatever the user selected is now unselected.
If I use an ADO recordset this behavior does not happen.
Here is the DAO class I've built:
Code:
'---------------------------------------------------------------------------------------
' Module : GTSDAO
' Author : Steve Bishop
' Date : 3/13/2014
' Purpose : DAO connection that interacts with the SQL server directly
'---------------------------------------------------------------------------------------
Option Compare Database
Option Explicit
Public ODBC As String
Private p_Server As String
Private p_Database As String
Private p_Trusted As Boolean
Private p_UserID As String
Private p_Password As String
Public SQL As String
Private settings As New settings
Public db As DAO.database
Public Property Let Server(value As String)
p_Server = value
UpdateODBC
End Property
Public Property Let database(value As String)
p_Database = value
UpdateODBC
End Property
Public Property Let Trusted(value As Boolean)
p_Trusted = value
UpdateODBC
End Property
Public Property Let UserID(value As String)
p_UserID = value
UpdateODBC
End Property
Public Property Let Password(value As String)
p_Password = value
UpdateODBC
End Property
Public Property Get Server() As String
Server = p_Server
End Property
Public Property Get database() As String
database = p_Database
End Property
Public Property Get Trusted() As Boolean
Trusted = p_Trusted
End Property
Public Property Get UserID() As String
UserID = p_UserID
End Property
Public Property Get Password() As String
Password = p_Password
End Property
'---------------------------------------------------------------------------------------
' Procedure : DLookup
' Author : Steve Bishop
' Date : 3/13/2014
' Purpose : Lookup a value from a specific field on a table
'---------------------------------------------------------------------------------------
'
Public Function DLookup(Field As String, Table As String, Optional Criteria As String) As Variant
Dim rs As Recordset
Dim sSQL As String
sSQL = "SELECT " & Field & " FROM " & Table & IIf(Criteria = "", "", " WHERE " & Criteria)
Set rs = db.OpenRecordset(sSQL, 4, 64)
If rs.EOF Then
DLookup = Nothing
Else
rs.MoveFirst
DLookup = rs.Fields(0).value
End If
End Function
'---------------------------------------------------------------------------------------
' Procedure : DSum
' Author : Steve Bishop
' Date : 3/13/2014
' Purpose : Perform a sum on a particular field of a table
'---------------------------------------------------------------------------------------
'
Public Function DSum(Field As String, Table As String, Optional Criteria As String) As Variant
Dim rs As Recordset
Dim sSQL As String
sSQL = "SELECT sum(" & Field & ") as FieldSum FROM " & Table & IIf(Criteria = "", "", " WHERE " & Criteria)
Set rs = db.OpenRecordset(sSQL, 4, 64)
If rs.EOF Then
DSum = Nothing
Else
rs.MoveFirst
DSum = rs.Fields(0).value
End If
End Function
'---------------------------------------------------------------------------------------
' Procedure : DCount
' Author : Steve Bishop
' Date : 3/13/2014
' Purpose : Perform a count on a specific field in a table
'---------------------------------------------------------------------------------------
'
Public Function DCount(Field As String, Table As String, Optional Criteria As String) As Variant
Dim rs As Recordset
Dim sSQL As String
sSQL = "SELECT count(" & Field & ") as FieldCount FROM " & Table & IIf(Criteria = "", "", " WHERE " & Criteria)
Set rs = db.OpenRecordset(sSQL, 4, 64)
If rs.EOF Then
DCount = Nothing
Else
rs.MoveFirst
DCount = rs.Fields(0).value
End If
End Function
'---------------------------------------------------------------------------------------
' Procedure : OpenRecordset
' Author : Steve Bishop
' Date : 3/13/2014
' Purpose : Opens a recordset for a query from the SQL server
'---------------------------------------------------------------------------------------
'
Public Function OpenRecordset(SQL As String) As Recordset
Dim rs As Recordset
Set rs = db.OpenRecordset(SQL, dbOpenDynaset, dbSeeChanges)
Set OpenRecordset = rs
End Function
'---------------------------------------------------------------------------------------
' Procedure : Execute
' Author : Steve Bishop
' Date : 3/13/2014
' Purpose : Execute a SQL command on the SQL server
'---------------------------------------------------------------------------------------
'
Public Function Execute(Optional SQL As String)
If Nz(SQL, "") <> "" Then
Me.SQL = SQL
End If
db.Execute Me.SQL, dbSQLPassThrough
End Function
'---------------------------------------------------------------------------------------
' Procedure : class_initialize
' Author : Steve Bishop
' Date : 3/13/2014
' Purpose : Class constructor to set the default settings
'---------------------------------------------------------------------------------------
'
Private Sub class_initialize()
p_Server = settings.ViewSetting("SQLServer")
p_Database = settings.ViewSetting("SQLDatabase")
p_Trusted = CBool(settings.ViewSetting("WinAuth"))
p_UserID = settings.ViewSetting("SQLUserID")
p_Password = settings.ViewSetting("SQLPassword")
UpdateODBC
End Sub
Private Sub Class_Terminate()
Set db = Nothing
End Sub
'---------------------------------------------------------------------------------------
' Procedure : UpdateODBC
' Author : Steve Bishop
' Date : 3/13/2014
' Purpose : Sets the ODBC connection string and then connects to the database
'---------------------------------------------------------------------------------------
'
Private Sub UpdateODBC()
If Me.Trusted Then
ODBC = "ODBC;DRIVER=SQL Server;SERVER=" & Me.Server & ";DATABASE=" & Me.database & ";Trusted_Connection=Yes"
Else
ODBC = "ODBC;DRIVER=SQL Server;SERVER=" & Me.Server & ";DATABASE=" & Me.database & ";UID=" & Me.UserID & ";PWD=" & Me.Password
End If
Set db = OpenDatabase(Me.database, dbDriverComplete, True, Me.ODBC)
End Sub
I just perform a Set comboboxName.recordset = db.OpenRecordset(SQL) to bind my recordset to the combobox.
Is there something I'm missing with my recordset or is a combobox just never going to get along with a DAO database using an opendatabase function that points to SQL server?