【问题标题】:Refresh QueryTable throwing "General ODBC error" - VBA Excel 2011 for Mac刷新 QueryTable 引发“常规 ODBC 错误” - VBA Excel 2011 for Mac
【发布时间】:2020-07-02 15:40:55
【问题描述】:

编辑:发现新错误?

我可能刚刚发现为什么我的脚本不再起作用了。最近有一个办公室更新,似乎他们已经实现了微软查询,摆脱了我根据需要安装和配置的 ODBC 管理器。现在实际的问题可能是这个 microsoft 查询没有 UNICODE 库,我不知道我可以把它们放在哪里,以便 microsoft 查询可以读取/获取它们。或者更确切地说,我不知道如何为 microsoft 查询提供 UNICODE 库的路径,因为在管理器中无法更改它,或者可能有但我只是没有找到它?除此之外,除非我直接从 excel 工作簿打开它,否则我无法打开 microsoft 查询管理器。

原始问题

这段代码工作了一段时间。现在使用完全相同的代码,我得到一个运行时错误。 Here我已经在这种情况下寻求帮助并让它发挥作用。

代码如下:

Sub ConnectSQL()

    Dim connstring As String
    Dim sLogin As String
    Dim qt As QueryTable

    sLogin = "Uid=*;Pwd=*;"
    sqlstringFirma = "select * from gi_kunden.tbl_Firma"
    sqlstringPerson = "select * from gi_kunden.tbl_Person"
    connstring = "ODBC;DSN=KundeDB;" & sLogin

    ActiveWorkbook.Sheets("Firma").Select
    ActiveSheet.Range("A1:T2000").Clear

    For Each qt In ActiveSheet.QueryTables
        qt.Delete
    Next qt

    With ActiveSheet.QueryTables.Add(Connection:=connstring, Destination:=Range("A1"), Sql:=sqlstringFirma)
        .BackgroundQuery = False
        .RefreshStyle = xlOverwriteCells
        .Refresh '"General ODBC error" hereeee
    End With

    ActiveWorkbook.Sheets("Person").Select
    ActiveSheet.Range("A1:T2000").Clear

    For Each qt In ActiveSheet.QueryTables
        qt.Delete
    Next qt

    With ActiveSheet.QueryTables.Add(Connection:=connstring, Destination:=Range("A1"), Sql:=sqlstringPerson)
        .BackgroundQuery = False
        .RefreshStyle = xlOverwriteCells
        .Refresh 'And hereee again
    End With


    Call Replace
    ActiveWorkbook.Sheets("Firma").Select

End Sub

我确实在这里使用了 .Select 两次,我知道我应该更改它。

我在 Mac 上使用 Excel 2011,因此请注意,并非所有在 Windows 上工作的东西都能正常工作。

* 编辑 *

首先:即使我激活了所有的对象库,这仍然不起作用。

其次,当我打开对象浏览器时,我才意识到一些事情:

  1. “ODBCConnection”是一个声明的类(“Excel 的类 ODBCConnection 成员”)。但是当我在对象浏览器中单击 Excel 时,“ODBCConnection”无处可寻。如果我输入代码“Excel.ODBCConnection.Refresh”,则会引发错误“找不到方法或数据成员”,仅突出显示“ODBCConnection”一词。当我仅使用 ODBCConnection.Refresh 时显示相同的错误(根据对象浏览器,刷新是 ODBCConnection 的一种方法)。

  2. 我对“QueryTable(1).Refresh”有完全相同的问题,它会引发错误:“变量未定义”,即使它已在对象浏览器中列出并声明(“类 QueryTable 成员Excel”)。

我相信与此相关的所有事情都会出现此类错误。

编辑

这会在 ActiveWorkbook.RefreshAll 行上引发相同的“常规 ODBC 错误”:

Dim strConn As String
Dim strLoginData As String
Dim QT As QueryTable

Dim strFirmSQL As String
Dim strPersSQL As String

strConn = "ODBC;DSN=KundeDB;" & strLoginData
strLoginData = "Uid=*myUid*;Pwd=*myPwd*"

strFirmSQL = "Select * From gi_kunden.tbl_firma"
strPersSQL = "Select * From gi_kunden.tbl_person"

Dim WSFirm As Worksheet
Set WSFirm = ActiveWorkbook.Sheets("Firma")

WSFirm.Range("A1:T1000").Clear

For Each QT In WSFirm.QueryTables
    QT.Delete
Next QT

With WSFirm.QueryTables.Add(strConn, WSFirm.Range("A1"), strFirmSQL)
    .SaveData = True
    .BackgroundQuery = True
    '.Refresh
End With


Dim WSPers As Worksheet
Set WSPers = ActiveWorkbook.Sheets("Person")

For Each QT In WSPers.QueryTables
    QT.Delete
Next QT

With WSPers.QueryTables.Add(strConn, WSPers.Range("A1"), strPersSQL)
    .SaveData = True
    .BackgroundQuery = True
    '.Refresh
End With

ActiveWorkbook.RefreshAll 'FAILS here

Call Replace

WSFirm.Activate

【问题讨论】:

  • 我们曾经遇到过类似的问题,我能够通过声明驱动程序来纠正其中的大部分问题(Teradata 通常让我最痛苦)。我也开始避免使用 DSN,因为我有一些用户喜欢将他们的连接命名为完全不同的名称。此外,如果存在访问问题,刷新将失败。
  • 这可能有帮助也可能没有帮助,但我注意到 strConn = "ODBC;DSN=KundeDB;" & strLoginData 出现在 strLoginData 被赋值之前。连接字符串看起来不包含登录凭据。只是我的两分钱!
  • 你是对的......我更正了它,但我仍然在 .refresh 行中得到一般的 odbc 错误...... :(

标签: excel vba macos


【解决方案1】:

我不能解决你的问题,但我可以帮你调试。

第一个问题是:那个错误信息是什么意思?它是在告诉您在数据上运行的查询或命令有错误,还是有什么阻止您连接到数据库?

实际上可以编写信息丰富的错误消息,并且无论在 Redmond 实现查询表的任何被误导的天才选择都不通过数据库服务器和连接库发出的详细错误信息。

幸运的是,我们自己完成了其中的一些工作。

QueryTable 对象有一个连接属性——它是一个字符串,不是一个功能齐全的连接对象,但您可以更详细地检查它并针对 ADODB 连接对象进行测试。试试这个函数来测试连接字符串,看看有没有有用的信息:


Public Sub ConnectionTest(ConnectionString As String)
' Late-binding: requires less effort, but he correct aproach is ' to create a reference to 'Microsoft ActiveX Data Objects' -
'Dim conADO As ADODB.Connection 'Set conADO = New ADODB.Connection
Dim conADO As Object Set conADO = CreateObject("ADODB.Connection")
Dim i As Integer
conADO.ConnectionTimeout = 30 conADO.ConnectionString = ConnectionString
On Error Resume Next
conADO.Open
If conADO.State = 1 Then Debug.Print "Connection string is valid" Else Debug.Print "Connection failed:"

For i = 0 To conADO.Errors.Count With conADO.Errors(i) Debug.Print "ADODB connection returned error " & .Number & " (native error '" & .NativeError & "') from '" & .Source & "': " & .Description End With Next i

End If
Debug.Print "Connection String: " Debug.Print vbTab & Replace(.Connection, ";", ";" & vbCrLf & vbTab) Debug.Print

Set conADO = Nothing

End Sub

...并将其插入到您的代码中:


Dim objQueryTable As Excel.QueryTable
Dim strConnect as String
set objQueryTable = ActiveSheet.QueryTables.Add(Connection:=connstring, Destination:=Range("A1"), Sql:=sqlstringFirma)
With objQueryTable strConnect = .Connection .BackgroundQuery = False .RefreshStyle = xlOverwriteCells .Refresh ' "General ODBC error" hereeee End With
ConnectionTest strConnect ' view the output in the debug window/immediate pane

如果您在其中看到错误,可能只是我的 ADODB 连接实现在您的 Mac Office 环境中不起作用:但您完全有可能遇到以下任何一种情况:

  1. 创建了一个连接,看到它工作,并消除了 您的连接字符串或 DSN 是 问题...
  2. ...或者在连接参数中发现错误,您可以 修复。

如果连接正常,则可能是您在数据库中运行的查询或命令是问题的根源 - 我在您的问题中看到的错误消息确实指向了这个方向 - 所以我们需要深入研究再深一点。

很遗憾,我无法知道我使用的工具是否适合您:这是开发人员的调试代码,您需要对其进行修改才能使其正常工作。

之所以如此繁琐,是因为实现 QueryTable 的 Office 团队做出了一些有趣的决定:QueryTable 公开的“连接”和“记录集”属性并不是功能齐全的对象——我认为它们是接口允许 QueryTable 使用来自各种不同提供者的称为“连接”和“记录集”的对象,并公开一组通用属性和方法。对于跨平台可用性来说,这是一个很好的决定,但这意味着需要询问这些对象的开发人员不能依赖运行时存在的任何给定方法 - 所以这仅适用于“调试”模式下的反编译代码.

您还需要在 IDE 中注册 Microsoft DAO 和 ADO 引用:当您需要能够在“Locals”窗口中查看这些对象时,使用“CreateObject”进行后期绑定是错误的工具:


Public Sub ConnectionDetails(objQueryTable As Excel.QueryTable)
Dim rstADO As ADODB.Recordset Dim conADO As ADODB.Connection
Dim rstDAO As DAO.Recordset Dim conDAO As DAO.Connection
Dim i As Integer

Set objQueryTable = Sheet1.ListObjects(1).QueryTable
With objQueryTable

Debug.Print "Connection String: " Debug.Print vbTab & Replace(.Connection, ";", ";" & vbCrLf & vbTab) Debug.Print

Debug.Print "Query Type: " & .QueryType ' Documented here: @987654321@ Debug.Print "Query: " & .CommandText Debug.Print "Database request type: " & .CommandType ' XlCmdType documented here: @987654322@

.MaintainConnection = True
On Error Resume Next If TypeOf .Recordset Is DAO.Recordset Then

On Error Resume Next Set rstDAO = .Recordset

rstDAO.OpenRecordset For i = 0 To DAO.Errors.Count With DAO.Errors(i) Debug.Print "DAO Recordset '" & Left(rstDAO.Name, 24) & "' returned error " & .Number & " from '" & .Source & "': " & .Description End With Next i

Set conADO = DAO.DBEngine.OpenConnection(.Connection) For i = 0 To DAO.Errors.Count With DAO.Errors(i) Debug.Print "DAO Connection '" & Left(conDAO.Name, 24) & "' returned error " & .Number & " from '" & .Source & "': " & .Description End With Next i

ElseIf TypeOf .Recordset Is ADODB.Recordset Then

On Error Resume Next Set rstADO = .Recordset

If rstADO.State <> 0 Then rstADO.Close rstADO.Open Set conADO = rstADO.ActiveConnection For i = 0 To conADO.Errors.Count With conADO.Errors(i) Debug.Print "ADODB Recordset '" & Left(rstADO.Source, 24) & "' connection returned error " & .Number & " (native error '" & .NativeError & "') from '" & .Source & "': " & .Description End With Next i
ElseIf Err.Number <> 0 Then

Debug.Print Err.Source & " Error " & Err.Number & ":" & Err.Description

Else

Debug.Print "recordset type is: '" & TypeName(.Recordset) & "': for further information, place a breakpoint in the code and use the 'Locals' window."

End If
End With
End Sub
代码做什么——或试图做什么——非常简单:它询问数据库并检索详细的错误消息。

他们可能会告诉您存在语法错误或 SQL 中缺少参数 - 如果数据库是 MS-Access,这可能会产生误导:“缺少参数”可能意味着字段名称或函数名称未知。这也可能意味着you can't run that SQL outside an MS-Access user session

如果无法正常工作,请返回 ConnectionTest 代码并针对 conADO 连接对象运行命令文本: conADO.Execute strCommandText ...并再次询问错误集合。

我可以用来解决这个问题的调试工具差不多就是这些了:希望另一个 'Stacker 可以建议其他方法。

【讨论】:

  • 在测试您的代码之前,请提供更多信息:不支持 ADODB。如果您点击我原始帖子中的“此处”链接,那么您可以看到我在此代码似乎工作之前已经尝试过的内容。我已经发现有很多关于连接到数据库的问题,其中命令 .Refresh 失败,但我无法找到解决这个问题的方法,这也适用于我。我不明白的是,此代码之前有效。我输入了一行代码(甚至在删除它之后),它在 .refresh 命令行上声明了错误“General ODBC error”。
  • 此外,命令 .Recordset 和 ODBC.Connection 在 mac 上的 excel 2011 中是未知的(至少我收到一条错误消息说......)。我的对象库可能有问题吗?
  • 顺便说一句:非常感谢您帮助我...遗憾的是,您编写的第一个代码由于 adodb 引发了 active-x 错误...我将其换成 odbc 并重试
  • 试试ConnectionTest() 代码示例:QueryTable 对象可能不支持 ADODB,但 ADO 库可能在 Mac 上实现 - 这意味着您可以使用 ADODB 测试连接,甚至可以运行查询...
  • ...如果 ADODB 在 Mac 上根本无法运行,您的下一个途径是 Excel 的“数据”菜单:单击“连接”并使用 DSN 文件从头开始创建连接。您应该在对话中的某处看到“测试连接”功能,因此您至少可以排除一个错误来源。我强烈建议您在表上构建查询,作为表而不是“SELECT”查询,因为这样可以更好地利用索引,并允许您排除 SQL 解析层中的错误。 ...至于它为什么停止工作,我采取宿命论的方法:另一个补丁,另一个锁定,必须是星期二。
猜你喜欢
  • 2016-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多