Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vba 如果主ODBC DSN不存在,请使用备用ODBC DSN_Vba_Ms Access_Odbc_Dsn - Fatal编程技术网

Vba 如果主ODBC DSN不存在,请使用备用ODBC DSN

Vba 如果主ODBC DSN不存在,请使用备用ODBC DSN,vba,ms-access,odbc,dsn,Vba,Ms Access,Odbc,Dsn,我有多个用户使用两个ODBC系统DSN之一通过Access连接到SQL Server:REPORT和REPORTS。除了名字外,他们都是一样的。我定期更新或创建新的基于访问的工具,然后将这些工具部署到共享网络驱动器。我目前必须维护每个工具的两个版本——一个使用报表,另一个使用报表。我正在寻找一种测试和重新链接表的方法: 如果报告存在,请使用它并重新链接表 否则,如果存在报告,请使用它并重新链接表 否则返回错误消息 我有在VBA中使用无DSN连接的经验,如果没有方法测试已经存在的ODBC连接,

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

  • 如果报告存在,请使用它并重新链接表
  • 否则,如果存在报告,请使用它并重新链接表
  • 否则返回错误消息
我有在VBA中使用无DSN连接的经验,如果没有方法测试已经存在的ODBC连接,这可能是一个可行的选择。理想情况下,我会将其标准化为DSN名称,但历史如此之深,我无法轻易确定谁使用了哪个DSN。

Rob

下面是一些代码,这些代码首先返回有效的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
函数fGetODBCName()作为字符串
错误转到E_句柄
DoCmd.DeleteObject可执行,“dbo\u tblTest”
DoCmd.TransferDatabase acLink,“ODBC数据库”,“ODBC;DSN=REPORT;Trusted_Connection=Yes;Database=TEST”,可执行,“tblUser”,“dbo_tblTest”
如果不为null(DLookup(“Name”、“MSysObjects”、“Name='dbo\u tblTest')),则
fGetODBCName=CurrentDb.TableDefs(“dbo_tblTest”).Connect
其他的
DoCmd.TransferDatabase acLink,“ODBC数据库”,“ODBC;DSN=报告;可信连接=是;数据库=测试”,可执行,“tblUser”,“dbo\u tblTest”
如果不为null(DLookup(“Name”、“MSysObjects”、“Name='dbo\u tblTest')),则
fGetODBCName=CurrentDb.TableDefs(“dbo_tblTest”).Connect
如果结束
如果结束
DoCmd.DeleteObject可执行,“dbo\u tblTest”
脱欧:
出错时继续下一步
退出功能
E_手柄:
选择案例错误编号
案例3146的DSN不存在
下一步继续
案例7874“dbo_tblTest不存在,因此无法删除它
下一步继续
其他情况
MsgBox错误描述&vbCrLf&vbCrLf&“fGetODBCName”,vbOKOnly+vbCritical,“错误:”&错误编号
结束选择
恢复脱欧
端函数
Sub-sRelinkODBC()
错误转到E_句柄
Dim数据库作为DAO.Database
暗LNGLOP1与长LNGLOP1相同
暗计数等于长
作为字符串的Dim strConnect
作为字符串的Dim strLocal
作为字符串的Dim strSource
strConnect=fGetODBCName
如果Len(strConnect)>0,则
设置db=DBEngine(0)(0)
db.TableDefs.Refresh
lngCount=db.TableDefs.Count-1
对于LNGLOP1=lngCount到0步骤-1
如果Len(db.TableDefs(lngLoop1.Connect)>0,则
如果db.TableDefs(LNGLOP1).Connect strConnect,则“仅在需要时重新链接”
strLocal=db.TableDefs(LNGLOP1).Name
strSource=db.TableDefs(lngLoop1).SourceTableName
DoCmd.DeleteObject可执行,strLocal
DoCmd.TransferDatabase acLink,“ODBC数据库”,strConnect,acTable,strSource,strLocal
如果结束
如果结束
下一个LNGLOP1
db.TableDefs.Refresh
否则无法找到合适的DSN
如果结束
性别:
出错时继续下一步
Set db=Nothing
出口接头
E_手柄:
MsgBox错误说明&vbCrLf&vbCrLf&“sRelinkODBC”,vbOKOnly+vbCritical,“错误:”&错误编号
恢复性生活
端接头
虽然这样做有效,但我强烈建议您与您的系统管理员沟通,让他们使用组策略向所有用户推出单个DSN


HTH

您需要VBA。为此,您可以构建两个连接字符串,测试哪一个可用,然后更新所有链接表的所有
.connect
属性。看这个:我有在VBA中使用DSN较少连接的经验——然后我会使用它。我觉得这要简单得多(尤其是在你的情况下)。