2011-02-07 6 views
4

Я следую коду, который я нашел на другом сайте. Вот основы моего кода:Таблицы запросов (QueryTables) в Excel 2010 с VBA с VBA, создающими множество соединений.

Dim SQL As String 
Dim connString As String 

connString = "ODBC;DSN=DB01;UID=;PWD=;Database=MyDatabase" 
SQL = "Select * from SomeTable" 

With Worksheets("Received").QueryTables.Add(Connection:=connString, Destination:=Worksheets("Received").Range("A5"), SQL:=SQL) 
.Refresh 

End With 

End Sub 

Проблема с делать это каждый раз, когда они попали кнопку, присвоенное это создает новое соединение и не всегда, кажется, уронить его. Я открываю таблицу после тестирования, и есть много версий соединения, перечисленных в разделе «Подключения». Подключение Connection1 Connection2

Я не могу найти способ закрыть или удалить соединения. Если я добавлю «.delete» после «.Refresh», я получаю ошибку 1004. Эта операция не может быть выполнена, поскольку данные обновляются в фоновом режиме.

Любые идеи о том, как закрыть или удалить соединение?

ответ

8

Вы можете спросить себя, почему вы каждый раз создаете QueryTable в своем коде. Есть основания для этого, но это обычно не обязательно.

QueryTables - это, скорее, объекты времени разработки. То есть вы создаете свой QueryTable один раз (через код или пользовательский интерфейс), а вы обновляете QueryTable для получения обновленных данных.

Если вам нужно изменить базовый оператор SQL, у вас есть некоторые параметры. Вы можете настроить параметры, которые запрашивают значение или получают его из ячейки. Другой вариант изменения SQL - это изменение кода в существующем QueryTable.

Sheet1.QueryTables(1).CommandText = "Select * FROM ...." 
Sheet1.QueryTables(1).Refresh 

Вы можете выбрать разные столбцы или даже разные таблицы, изменив CommandText. Если это другая база данных, вам понадобится новое соединение, но это довольно редко.

Я знаю, что это не отвечает на ваш вопрос напрямую, но я считаю, что определить, действительно ли вам нужно добавлять QueryTable каждый раз, является первым шагом.

Подробнее о параметрах см. В разделе http://www.dicks-clicks.com/excel/ExternalData6.htm Это для 2003 года, поэтому существует несколько несоответствий с более поздними версиями. Основы одинаковы, вам просто нужно узнать об объекте ListObject, если вы используете 2007 или более поздний.

1

Вы должны объявить соединение как отдельный объект, после чего вы можете закрыть его после завершения запроса базы данных.

У меня нет VBA IDE передо мной, поэтому извините меня, если есть какие-то неточности, но это должно указывать на вас в правильном направлении.

E.g.

Dim SQL As String 
Dim con As connection 

Set con = New connection 
con.ConnectionString = "ODBC;DSN=DB01;UID=;PWD=;Database=MyDatabase" 

Worksheets("Received").QueryTables.Add(Connection:=con, Destination:=Worksheets("Received").Range("A5"), SQL:=SQL).Refresh 

con.close 
set con = nothing 
+0

Когда я пытаюсь это сделать, строка Worksheets («Received») ... дает неверный вызов процедуры Run Time Error 5. Я также попытался изменить его из New Connection в New ADODB Connection и соответствующим образом использовать его. Нет кубиков. – DavidStein

+0

Ну, все, что я делал, это ответ отформатированного st0000, но это * - это ответ на ваш оригинальный вопрос о закрытии соединений. Я не работаю в Excel, поэтому я не могу помочь с чем-то другим. – RolandTumble

7

У меня была такая же проблема. Предыдущий ответ, хотя определенный шаг в правильном направлении - PITA.

Она тем не менее, позвольте мне уточнить мой поиск и победитель ...

http://msdn.microsoft.com/en-us/library/bb213491(v=office.12).aspx

т.е. для существующего объекта QueryTable просто сделать это:

.MaintainConnection = False 

Работы очень набухают ,После обновления данных больше нет файла блокировки доступа к БД.

1

Я обнаружил, что по умолчанию новые соединения, созданные таким образом, называются «Соединение». Я использую этот фрагмент кода для удаления соединения, но сохраняю listobject.

Application.DisplayAlerts = False 
ActiveWorkbook.Connections("Connection").Delete 
Application.DisplayAlerts = True 

Его можно легко изменить, чтобы удалить последнее добавленное соединение (или если вы отслеживаете соединения по их индексу).

Application.DisplayAlerts = False 
ActiveWorkbook.Connections(ActiveWorkbook.Connections.Count).Delete 
Application.DisplayAlerts = True 
0

Если вы хотите удалить, если сразу после обновления вы должны сделать обновление не в фоновом режиме (с помощью первого параметра -> Refresh False), так что у вас есть правильная последовательность действий

0

Попробуйте установить QueryTable .MaintainConnection для False ...

«Установите MaintainConnection на True, если соединение с указанным источником данных должно поддерживаться после обновления и пока рабочая книга не будет закрыта. Значение по умолчанию - True! для этого флажок пользовательского интерфейса (Read/write Boolean) "

0

Все еще релевантные годы спустя ... борьба с одной и той же проблемой, и это наиболее полезная тема там. Моя ситуация является вариантом выше, и я добавлю свое решение, когда найду его.

Я использую базу данных Access для своего источника данных и устанавливаю таблицу запросов на новом листе. Затем я добавляю еще два новых листа и пытаюсь установить таблицу запросов, используя одно и то же соединение для каждого из них, но в другую таблицу Access. Первая таблица запросов отлично работает, и я использую .QueryTables (1). Удалите и установите объект querytable в Nothing, чтобы отключить его.

Однако следующий лист не удается установить новую таблицу запросов с использованием того же соединения, которое не было закрыто. Я подозреваю (и добавлю решение ниже), что мне нужно удалить соединение перед удалением таблицы запросов. Код Rasmus выше выглядит как вероятное решение.

1

Вместо добавления другой таблицы запросов с помощью метода add вы можете просто обновить свойство CommandText соединения. Однако вы должны знать, что есть ошибка при обновлении свойства CommandText соединения ODBC. Если вы временно переключитесь на OLEDB-соединение, обновите свойство CommandText, а затем вернитесь к ODBC, он не создает новое соединение. Не спрашивайте меня, почему ... это просто работает для меня.

Создать новый модуль и вставьте следующий код:

Option Explicit 

Sub UpdateWorkbookConnection(WorkbookConnectionObject As WorkbookConnection, Optional ByVal CommandText As String = "", Optional ByVal ConnectionString As String = "") 

With WorkbookConnectionObject 
    If .Type = xlConnectionTypeODBC Then 
     If CommandText = "" Then CommandText = .ODBCConnection.CommandText 
     If ConnectionString = "" Then ConnectionString = .ODBCConnection.Connection 
     .ODBCConnection.Connection = Replace(.ODBCConnection.Connection, "ODBC;", "OLEDB;", 1, 1, vbTextCompare) 
    ElseIf .Type = xlConnectionTypeOLEDB Then 
     If CommandText = "" Then CommandText = .OLEDBConnection.CommandText 
     If ConnectionString = "" Then ConnectionString = .OLEDBConnection.Connection 
    Else 
     MsgBox "Invalid connection object sent to UpdateWorkbookConnection function!", vbCritical, "Update Error" 
     Exit Sub 
    End If 
    If StrComp(.OLEDBConnection.CommandText, CommandText, vbTextCompare) <> 0 Then 
     .OLEDBConnection.CommandText = CommandText 
    End If 
    If StrComp(.OLEDBConnection.Connection, ConnectionString, vbTextCompare) <> 0 Then 
     .OLEDBConnection.Connection = ConnectionString 
    End If 
    .Refresh 
End With 

End Sub 

Эта UpdateWorkbookConnection подпрограмма работает только по обновлению OLEDB или ODBC соединения. Соединение необязательно должно быть связано со сводной таблицей. Он также исправляет еще одну проблему и позволяет вам обновлять соединение, даже если на одном и том же соединении имеется несколько сводных таблиц.

Чтобы начать обновление только вызов функции с объектом связи и командных текстовых параметров, как это:

UpdateWorkbookConnection ActiveWorkbook.Connections("Connection"), "exec sp_MyAwesomeProcedure" 

При необходимости можно обновить строку подключения, а также.

Смежные вопросы