【问题标题】:Use alternate ODBC DSN if primary ODBC DSN does not exist如果主 ODBC DSN 不存在,则使用备用 ODBC DSN
【发布时间】:2020-05-19 16:47:27
【问题描述】:

我有多个用户使用以下两种 ODBC 系统 DSN 之一通过 Access 连接到 SQL Server:REPORT 和 REPORTS。除了名称之外,它们是相同的。我会定期更新或创建新的基于 Access 的工具,然后将其部署到共享网络驱动器。我目前必须维护每个工具的两个版本——一个使用 REPORT,另一个使用 REPORTS。我正在寻找一种方法来测试和重新链接表格:

  • 如果 REPORT 存在,请使用它并重新链接表。
  • 否则,如果 REPORTS 存在,请使用它并重新链接表。
  • 否则返回错误消息。

我有在 VBA 中使用无 DSN 连接的经验,如果无法测试已经存在的 ODBC 连接,这可能是一个可行的选择。理想情况下,我希望 IT 部门对 DSN 名称进行标准化,但历史如此之深,以至于我无法轻易确定谁使用了哪个 DSN。

【问题讨论】:

  • 您需要 VBA,您可以构建两个连接字符串,测试哪个可用,然后更新所有链接表的所有 .connect 属性。看到这个:stackoverflow.com/search?q=%5Bms-access%5D+refresh+linked+table
  • 我有在 VBA 中使用无 DSN 连接的经验——然后​​我会使用它。我发现这更简单(尤其是在您的情况下)。

标签: vba ms-access odbc dsn


【解决方案1】:

罗伯,

下面是一些代码,它首先返回有效的 DSN(通过尝试从列出的两个 DSN 中的每一个中导入一个测试表),然后循环访问数据库中的所有链接表以在需要时正确设置 DSN:

Function fGetODBCName() As String
    On Error GoTo E_Handle
    DoCmd.DeleteObject acTable, "dbo_tblTest"
    DoCmd.TransferDatabase acLink, "ODBC Database", "ODBC;DSN=REPORT;Trusted_Connection=Yes;DATABASE=TEST", acTable, "tblUser", "dbo_tblTest"
    If Not IsNull(DLookup("Name", "MSysObjects", "Name='dbo_tblTest'")) Then
        fGetODBCName = CurrentDb.TableDefs("dbo_tblTest").Connect
    Else
        DoCmd.TransferDatabase acLink, "ODBC Database", "ODBC;DSN=REPORTS;Trusted_Connection=Yes;DATABASE=TEST", acTable, "tblUser", "dbo_tblTest"
        If Not IsNull(DLookup("Name", "MSysObjects", "Name='dbo_tblTest'")) Then
            fGetODBCName = CurrentDb.TableDefs("dbo_tblTest").Connect
        End If
    End If
    DoCmd.DeleteObject acTable, "dbo_tblTest"
fExit:
    On Error Resume Next
    Exit Function
E_Handle:
    Select Case Err.Number
        Case 3146   '   DSN does not exist
            Resume Next
        Case 7874   '   dbo_tblTest does not exist so cannot delete it
            Resume Next
        Case Else
            MsgBox Err.Description & vbCrLf & vbCrLf & "fGetODBCName", vbOKOnly + vbCritical, "Error: " & Err.Number
    End Select
    Resume fExit
End Function

Sub sRelinkODBC()
    On Error GoTo E_Handle
    Dim db As DAO.Database
    Dim lngLoop1 As Long
    Dim lngCount As Long
    Dim strConnect As String
    Dim strLocal As String
    Dim strSource As String
    strConnect = fGetODBCName
    If Len(strConnect) > 0 Then
        Set db = DBEngine(0)(0)
        db.TableDefs.Refresh
        lngCount = db.TableDefs.Count - 1
        For lngLoop1 = lngCount To 0 Step -1
            If Len(db.TableDefs(lngLoop1).Connect) > 0 Then
                If db.TableDefs(lngLoop1).Connect <> strConnect Then '   only relink if needed
                    strLocal = db.TableDefs(lngLoop1).Name
                    strSource = db.TableDefs(lngLoop1).SourceTableName
                    DoCmd.DeleteObject acTable, strLocal
                    DoCmd.TransferDatabase acLink, "ODBC Database", strConnect, acTable, strSource, strLocal
                End If
            End If
        Next lngLoop1
        db.TableDefs.Refresh
    Else    '   not able to find a suitable DSN

    End If
sExit:
    On Error Resume Next
    Set db = Nothing
    Exit Sub
E_Handle:
    MsgBox Err.Description & vbCrLf & vbCrLf & "sRelinkODBC", vbOKOnly + vbCritical, "Error: " & Err.Number
    Resume sExit
End Sub

虽然这可行,但我强烈建议您与您的系统管理员交谈,让他们使用组策略向所有用户推出一个 DSN。

HTH

【讨论】:

    猜你喜欢
    • 2020-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多