编辑:发现新错误?
我可能刚刚发现为什么我的剧本不再适用了。最近有一个办公室更新,似乎他们已经实现了微软查询,摆脱了我安装和配置为我需要的ODBC管理器。现在实际的问题可能是这个微软查询没有UNICODE库,我不知道我可以把它们放在哪里,以便微软查询可以读取/获取它们。或者更确切地说,我不知道如何让微软查询到UNICODE库的路径,因为在管理器中没有可能改变它,或者可能有,我只是没有找到它?除此之外,我无法打开microsoft查询管理器,除非我直接从excel工作簿中打开它。
原始问题
此代码已有一段时间了。现在使用完全相同的代码我得到运行时错误。 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
我确实使用过。在这里选择两次,我知道我应该改变它。
我在Mac上使用Excel 2011,因此请注意,并非所有可在Windows上运行的内容都能正常工作。
*编辑*
首先:即使我激活了所有对象库,这仍然无效。
其次,我在打开对象浏览器时意识到了一些事情:
" ODBCConnection"是一个声明的类("类的ODBCConnection成员的Excel")。但是当我在对象浏览器中点击Excel" ODBCConnection"无处可寻。如果我输入代码" Excel.ODBCConnection.Refresh"它会抛出错误"方法或数据成员未找到"突出显示单词" ODBCConnection"。当我只使用ODBCConnection.Refresh(根据对象浏览器刷新是ODBCConnection的方法)时,会显示相同的错误。
我对" QueryTable(1).Refresh"有完全相同的问题,这就是抛出错误:"变量未定义"即使它已在对象浏览器中列出并声明(" Excel的Class QueryTable成员")。
我相信我会为与此相关的所有事情得到这些错误。
修改
这会抛出相同的"常规ODBC错误"在线ActiveWorkbook.RefreshAll:
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
答案 0 :(得分:5)
我无法解决您的问题,但我可以帮您调试。
第一个问题是:该错误消息是什么意思?它是否告诉您,您在数据上运行的查询或命令出现错误,或者是否阻止您连接到数据库?
实际上可以编写信息性错误消息,并且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环境中无效:但您完全有可能:
如果连接有效,则可能是您在数据库中运行的查询或命令是问题的根源 - 以及错误消息I'在你的问题中看到的确指向了那个方向 - 所以我们需要深入研究一下。
不幸的是,我无法知道我使用的工具是否适用于您:这是开发人员和#39;调试代码,你需要修改它才能使它工作。
它如此繁琐的原因是实施QueryTable的Office团队做出了一些有趣的决定:'连接'和'记录集' QueryTable公开的属性不是全功能的对象 - 我认为它们是允许QueryTable使用对象称为' connection'和'记录集'来自各种不同的提供者,并公开一组共同的属性和方法。它是跨平台可用性的一个很好的决定,但这意味着需要询问这些对象的开发人员不能依赖于运行时存在的任何给定方法 - 所以这是针对反编译代码的'调试'仅限模式。
您还需要在IDE中注册Microsoft DAO和ADO引用:后期绑定' 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: https://msdn.microsoft.com/en-us/library/office/ff835313.aspx
Debug.Print "Query: " & .CommandText
Debug.Print "Database request type: " & .CommandType ' XlCmdType documented here: https://msdn.microsoft.com/en-us/library/office/ff197456.aspx
.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,可能会产生误导:&#39;缺少参数&#39;可能意味着字段名称或函数名称未知。这也可能意味着you can't run that SQL outside an MS-Access user session。
如果无效,请返回ConnectionTest代码并针对conADO连接对象运行命令文本:
conADO.Execute strCommandText
......并再次询问错误集合。
对于我可以对这个问题采取的调试工具来说,这几乎是很好的:希望另一个&#39; Stacker可以提出其他方法。