2016-12-30 48 views
0

我們得到了這是在2000年開發了一些舊的遺留應用程序,我們已經從接入移動2003至2007年當我試圖運行的應用程序的模塊,它給我的錯誤:如何將代碼從DAO重寫到ADO?

"Run-time error 3847. ODBCDirect is no longer supported. Rewrite the code to use ADO instead of 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

重寫ADO會有很多工作要做。或者,修改 - 仍然使用DAO - 在沒有ODBC WorkSpace的情況下工作。 – Gustav

+1

我會把整個東西移植到SQL Server免費版。我最近在Access上花費了大量的時間和精力。可怕。 –

+1

我已經重新格式化了您的問題以修復代碼塊,但您的問題本質上*太寬泛*。您可以在[Documentation.SO](http://stackoverflow.com/documentation/vba/3578/working-with-ado#t=201612301821243706514)中找到有關ADO的信息;一旦你被困在一個特定的問題上,你就會有一個*特定的問題,我們將能夠給你特定的答案。現在看起來你要求其他人爲你做「翻譯」工作,這不是Stack Overflow的目的。 –

回答

2

首先,您真的不想將ADO引入到圍繞DAO構建和設計的應用程序中。更糟的是,ADO現在已經走了15年了。實際上SQL服務器正在放棄對ADO工作的oleDB的支持。 (所以不要去那裏)。

請參閱有關SQL服務器刪除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中創建並保存傳遞查詢。您的代碼可以重寫爲:

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 

因此,創建一個傳遞查詢。你可以在你使用JET-DIRECT的所有地方使用它。在2007年的訪問中,jet-direct支持被放棄了,但使用簡單的傳遞查詢將綽綽有餘,而且上面的代碼顯示了節省編碼和開發人員時間的空間。如果你有的「left」表達式可以返回null,那麼你可能需要將該表達式包裝在nz()中以返回「」(空字符串)或適當的值。

+0

謝謝你的回覆。我正在研究在線傳遞查詢。所以,上面的「qrypass」是傳遞查詢,對吧?傳遞查詢的內容是什麼?它是存儲過程sp_insert嗎? – toofaced

+0

您可以在傳遞查詢中放置任何您想要的內容。所以只需用tblCustomers中的簡單選擇計數(*)來測試PT。 PT查詢可以從任何合法的t-sql語句開始。上面顯示您將「經常」將該PT查詢的.SQL文本屬性修改爲任何即時操作。因此,首先通過點擊它來運行PT查詢來運行它。一旦工作,上面的代碼將按照上面的動態改變.SQL屬性。這可以讓你在PT查詢中使用任何t-sql。這也意味着你不會在代碼中弄亂連接字符串,並且很適合替換jet-direct代碼。 –

+0

任何在上面qryPass是我用於PT查詢的名稱 - 它可以是任何你想要的名字。由於DAO記錄集代碼的其餘部分不需要重新編寫,並且可以像以前一樣工作,所以此方法是首選。因此,這種方法對現有的DAO記錄集代碼進行最少量的更改。 –