我们得到了一些旧的旧应用程序,该应用程序是在2000年开发的,我们已经从Access 2003到2007。当我尝试运行应用程序的模块时,它给了我一个错误:
"运行时错误3847.不再支持ODBCDirect。重写要使用ADO代替DAO的代码"。
,它突出显示到线Set WS = CreateWorkspace("NewWS", "", "", dbUseODBC)
。由于我真的很陌生,因此我在此处发布此问题之前进行了研究,但没有运气。我正在尝试重写代码以使用ADO而不是DAO。
以下是我的旧VBA代码:
Public Function GetID (ByRef SegmentItem As clsSegmentDefinitions) As Long
Dim qdf As QueryDef
Dim qdfNewID As QueryDef
Dim rs As Recordset
Dim rsNewID As Recordset
Dim NaturalDescription As String
Dim WS As Workspace
Dim con As Connection
Set WS = CreateWorkspace("NewWS", "", "", dbUseODBC)
WS.DefaultCursorDriver = dbUseODBCCursor
Set con = WS.OpenConnection("", , , SQLConnectString)
DoCmd.Hourglass False
DoCmd.OpenForm " frmQuickAdd_AddNatural ", , , , , acDialog, SegmentItem.AddValue
DoCmd.Hourglass True
If Form_frmQuickAdd_AddNatural.Tag Then
Set qdf = con.CreateQueryDef("", "{ ? = call sp_Insert(?, ?, ?) }")
qdf.Parameters.Refresh
qdf![@prmDescription] = Left(Form_frmQuickAdd_AddNatural.txtSegmentDescription, 34)
qdf![@prmCreateUser] = CurrentUser
qdf![@prmProjectID] = 0
qdf.Execute
Set qdfNewID = CodeDb.CreateQueryDef("")
qdfNewID.Connect = SQLConnectString
qdfNewID.ReturnsRecords = True
qdfNewID.SQL = "sp_GetNewSegmentID"
Set rsNewID = qdfNewID.OpenRecordset
If Not IsNull(rsNewID!MaxOfSegmentID) Then
GetID = rsNewID!MaxOfSegmentID
Else
GetID = 0
End If
Else
GetID = 0
End If
DoCmd.Close acForm, "frmQuickAdd_AddNatural"
End Function
我已经开始重写代码,但是我不知道是否完全是这样。
Dim cnn As New ADODB.Connection
Dim rst As New ADODB.Recordset
cnn.Open "Provider=mssql;Data Source=" & dbq & ";User Id=" & uid & ";Password=" & pwd
With rst
.Open "SELECT COUNT(*) FROM " & tbl, cnn, adOpenKeyset, adLockOptimistic
num = .Fields(0)
.Close
End With
cnn.Close
Set rst = Nothing
Set cnn = Nothing
首先,您真的不想将ADO引入围绕DAO构建和设计的应用程序。更糟糕的是,Ado已经出门了大约15年了。实际上,SQL Server正在放弃对ADO工作的OLEDB的支持。(所以不要去那里)。
请参阅有关SQL Server删除OLEDB支持的此链接:
http://blogs.msdn.com/b/sqlnativeclient/archive/Archive/2011/08/29/microsoft-is-aligning-with-with-odbc-for-native-native-native-relational-data-access.aspx
该行业已经离开了ADO,所有主要供应商都建议将开放数据库连接用作行业标准。(这意味着ODBC)。
我会创建并保存一个通过查询,但可以在访问中进行查询。然后,您的代码可以重新编写为:
Public Function GetID(ByRef SegmentItem As String) As Long
Dim strSQL As String
strSQL = "sp_Insert('" & _
Left(Form_frmQuickAdd_AddNatural.txtSegmentDescription, 34) & "'," & _
"'" & CurrentUser & "', 0)"
With CurrentDb.QueryDefs("qryPass")
.SQL = strSQL
.ReturnsRecords = False
.Execute
End If
With CurrentDb.QueryDefs("qryPass")
.SQL = "sp_GetNewSegmentID"
.ReturnsRecords = True
GetID = Nz(.OpenRecordset()("MaxOfSegmentID"),0)
End With
End Function
所以创建一个通过查询。而且,您可以在使用喷气式直接的所有地方使用它。在Access 2007中,删除了Jet-Direct支撑,但是使用简单的传递 - 尽管查询还不够,还足够了,也显示了节省编码和开发人员时间的保存桶。如果您拥有的"左"表达式可以返回null,则您可能需要将该表达式包装在NZ()中才能返回"(null String)或适当的值。