我们有一些旧的遗留应用程序是在2000年开发的,我们已经从访问2003年转移到2007年。当我尝试运行应用程序的模块时,它给了我一个错误:
"运行时错误3847.不再支持ODBCDirect。重写代码以使用ADO而不是DAO"。
它突出显示了Set WS = CreateWorkspace("NewWS", "", "", dbUseODBC)
行。由于我是Access的新手,我在此处发布此问题之前做过研究,但没有运气。我正在尝试重写代码以使用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
答案 0 :(得分:2)
首先,您真的不想将ADO引入围绕DAO构建和设计的应用程序中。更糟糕的是,ADO已经走出了大约15年的道路。事实上,SQL服务器正在放弃对ADO工作的oleDB的支持。 (所以不要去那里)。
请参阅此链接,了解有关SQL Server删除oleDB支持的信息:
该行业已从ADO转移,所有主要供应商都建议使用开放式数据库连接作为行业标准。 (这意味着ODBC)。
我会在Access中创建并保存pass-though查询。然后您可以将代码重写为:
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
所以创建一个pass-through查询。你可以在你使用JET-DIRECT的所有地方使用它。在访问2007中,删除了jet-direct支持,但使用简单的pass-through查询将足以满足要求,并且如上所示还可以节省编码和开发人员时间。如果你拥有的“左”表达式可以返回null,那么你可能需要将该表达式包装在nz()中以返回“”(空字符串)或适当的值。