如何将代码从DAO重写为ADO?

时间:2016-12-30 17:26:17

标签: vba ms-access ado dao

我们有一些旧的遗留应用程序是在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

1 个答案:

答案 0 :(得分:2)

首先,您真的不想将ADO引入围绕DAO构建和设计的应用程序中。更糟糕的是,ADO已经走出了大约15年的道路。事实上,SQL服务器正在放弃对ADO工作的oleDB的支持。 (所以不要去那里)。

请参阅此链接,了解有关SQL Server删除oleDB支持的信息:

http://blogs.msdn.com/b/sqlnativeclient/archive/2011/08/29/microsoft-is-aligning-with-odbc-for-native-relational-data-access.aspx

该行业已从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()中以返回“”(空字符串)或适当的值。