У меня есть проблема, которая, на мой взгляд, не так уж и редка, но, похоже, подобная ситуация едва освещена в моем онлайн-поиске. Это выглядит так: у нас есть два сервера Postgresql (назовем их A и B), созданные на одном и том же ПК-сервере, с точки зрения конфигурации, единственная разница между A и B - это номер порта, A слушает порт 5432 ( по умолчанию), когда B прослушивает порт 5434. Запросы, выполняемые на любом из серверов, выполняются успешно для различных сценариев (создание таблиц, несколько соединений, CTE и т. д.), а также при успешном добавлении обоих серверов в ODBC без каких-либо проблем с подключением, и когда один использует приложение Excel Data>GetData>From Other Sources>From ODBC
, тогда мы можем успешно извлечь данные из БД и загрузить их в лист Excel без каких-либо проблем для любого сервера. Затем, когда я тестирую новый сервер в VBA, возникают проблемы.
Public Sub Refresh()
Dim dataConn As New ADODB.Connection
Dim strSQL As String
Dim strCON As String
Dim strCmd As New ADODB.Command
Dim loadTable As QueryTable
Dim qt As QueryTable
Sheet3.AutoFilterMode = False
For Each qt In Sheet3.QueryTables
qt.Delete
Next
strCON = "Server=IP address;" & _
"DSN=PostgreSQL35W2;" & _
"UID=user name;" & _
"PWD=user password;" & _
"Database=dbA;" & _
"Port=5432;" & _
"CommandTimeout=12"
dataConn.ConnectionString = strCON
dataConn.Open
Sheet3.Range("A3:AA300000").Cells.ClearContents
strSQL = "Select * from tableA"
strCmd.ActiveConnection = dataConn
strCmd.CommandType = adCmdText
strCmd.CommandText = strSQL
strCmd.CommandTimeout = 0
Set loadTable = Sheet3.QueryTables.Add(Connection:=strCmd.Execute, Destination:=Sheet3.Range("A3"))
With loadTable
.BackgroundQuery = False
.AdjustColumnWidth = False
.Refresh
End With
Set strCmd = Nothing
dataConn.Close
Set dataConn = Nothing
ОДНАКО, если бы я только что сделал несколько очень простых изменений для порта, имени пользователя и т. Д., Появилась бы пресловутая ошибка 1004 времени выполнения VBA «Ошибка приложения или объекта», а стрелка отладки указала на * 1005. * (код выглядит так):
Public Sub Refresh()
Dim dataConn As New ADODB.Connection
Dim strSQL As String
Dim strCON As String
Dim strCmd As New ADODB.Command
Dim loadTable As QueryTable
Dim qt As QueryTable
Sheet3.AutoFilterMode = False
For Each qt In Sheet3.QueryTables
qt.Delete
Next
strCON = "Server=IP address;" & _
"DSN=PostgreSQL35W2;" & _
"UID=user name;" & _
"PWD=user password;" & _
"Database=dbB;" & _
"Port=5434;" & _
"CommandTimeout=12"
dataConn.ConnectionString = strCON
dataConn.Open
Sheet3.Range("A3:AA300000").Cells.ClearContents
strSQL = "Select * from tableB"
strCmd.ActiveConnection = dataConn
strCmd.CommandType = adCmdText
strCmd.CommandText = strSQL
strCmd.CommandTimeout = 0
Set loadTable = Sheet3.QueryTables.Add(Connection:=strCmd.Execute, Destination:=Sheet3.Range("A3"))
With loadTable
.BackgroundQuery = False
.AdjustColumnWidth = False
.Refresh
End With
Set strCmd = Nothing
dataConn.Close
Set dataConn = Nothing
Я на 100% уверен, что подключение к серверу B с портом 5434 прошло успешно, потому что, если я изменил строку sql на "Select * from tableC"
, в сообщении об ошибке будет отображаться "tableC does not exist"
, которое истинно и будет возвращено только так когда VBA успешно соединяется с БД. Итак, проблема сузилась до loadTable
части, и я ничего не понимаю по этой причине.
На самом деле, позже, когда я переключился на другой способ загрузки данных, все работает нормально для сервера B, но этот успех только сделает вышеуказанную ошибку более загадочной, поэтому любые мысли приветствуются, спасибо:
Public Sub refresh_cf2()
Dim dataConn As New ADODB.Connection
Dim strSQL As String
Dim strCON As String
Dim strCmd As New ADODB.Command
Dim loadTable As QueryTable
Dim qt As QueryTable
Dim rst As ADODB.recordSet
Dim connstring As String
Dim sqlstring As String
Sheet3.AutoFilterMode = False
For Each qt In Sheet3.QueryTables
qt.Delete
Next
Sheet3.Range("A1:NTM300000").Cells.Clear
sqlstring = "Select * from tableB "
connstring = _
"ODBC;DSN=PostgreSQL35W2;UID=user name;PWD=user password;Database=dbB;Port=5434"
With ActiveSheet.QueryTables.Add(Connection:=connstring, _
Destination:=Range("A1"), SQL:=sqlstring)
.Refresh
End With
End Sub
Вот одна ссылка, которую я нашел из здесь , но похоже, что нет определенного ответа на этот пост.