powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft Office [игнор отключен] [закрыт для гостей] / Как отключить Excel от SQL-сервера после выполнения запроса
15 сообщений из 15, страница 1 из 1
Как отключить Excel от SQL-сервера после выполнения запроса
    #33678116
Яровенко
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
на SQL-сервере находятся данные (1С, но это не принципиально)
из книги Excel SQL-запросом я вытягиваю данные (в сводную таблицу или на лист). Как закрыть соединение с SQL-сервером, не закрывая книгу Excel? (эта книга должна постоянно висеть открытой у пользователя. Каждая выборка данных попадает на новый лист, поэтому закрывать книгу нельзя).

Пробовал (при формировании сводной таблицы):
1.MaintainConnection = False
- не помогает
2. MaintainConnection = True
PivotCache.Connection.Close
- не помогает
3. сохранить книгу Excel
- не помогает

Как я определяю, что соединение открыто? Пытаюсь открыть базу в однопользовательском режиме - не разрешает, закрываю книгу Excel - разрешает.
...
Рейтинг: 0 / 0
Как отключить Excel от SQL-сервера после выполнения запроса
    #33678256
Фотография big-duke
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну если в лоб и побыстрому то мона так
use master

CREATE procedure _Kill_Base_Connections @BaseName nvarchar(500) as

declare @ProcID int,@strSQL nvarchar(500)
declare kill_cursor Cursor for
select spid from master.dbo.[sysprocesses] where db_name(dbid) in (@BaseName)
open kill_cursor
FETCH NEXT FROM kill_cursor INTO @procid

WHILE @@FETCH_STATUS = 0
BEGIN
set @strSQL= 'Kill ' + cast(@ProcID as nvarchar(500))
exec sp_executesql @strSQL
FETCH NEXT FROM kill_cursor INTO @procid

END

CLOSE kill_cursor
DEALLOCATE kill_cursor

после этого ни один коннект не выживет

GO

...
Рейтинг: 0 / 0
Как отключить Excel от SQL-сервера после выполнения запроса
    #33678280
Ashton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Так не закрывает?

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
    Dim cnn As New ADODB.Connection 
    Dim rst As New ADODB.Recordset 

    cnn.Open "..."

    rstRecordset.Open "...", cnn

    Set PivotCache = ActiveWorkbook.PivotCaches.Add( _
      SourceType:=xlExternal)
    PivotCache.MaintainConnection = False

    Set PivotCache.Recordset = rstRecordset
    PivotCache.Refresh 

    rst.Close
    cnn.Close 

    Set rst = Nothing
    Set cnn = Nothing
...
Рейтинг: 0 / 0
Как отключить Excel от SQL-сервера после выполнения запроса
    #33678394
Яровенко
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ashton, а так еще не пробовал (с импользование ADODB.Recordset)
я пробовал так, как макрос записывается
сейчас начну экспериментировать
...
Рейтинг: 0 / 0
Как отключить Excel от SQL-сервера после выполнения запроса
    #33678406
Яровенко
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
а чтобы работать с объектом ADODB.Connection, какую библиотеку нужно к проекту подключить?
...
Рейтинг: 0 / 0
Как отключить Excel от SQL-сервера после выполнения запроса
    #33678512
Ashton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
"Microsoft ActiveX Data Objects".
...
Рейтинг: 0 / 0
Как отключить Excel от SQL-сервера после выполнения запроса
    #33678829
Яровенко
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
У меня выскакивает "Ошибка, определенная объектом" на этой строке:
Set PivotCache.Recordset = rstRecordset

Ashton, ты не мог бы бросить весь рабочий пример целиком? буду ОЧЕНЬ признателен
...
Рейтинг: 0 / 0
Как отключить Excel от SQL-сервера после выполнения запроса
    #33680903
Ashton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
Public Sub CreatePivotTable()
    Dim cnn As ADODB.Connection
    Dim rst As ADODB.Recordset
    Dim objPivotCache As PivotCache
    Dim objPivotTable As PivotTable
    
    Set cnn = New ADODB.Connection
    Set rst = New ADODB.Recordset
    
    cnn.Open "Provider=SQLOLEDB.1;Integrated Security=SSPI;" & _
      "Persist Security Info=False;" & _
      "Initial Catalog=Northwind;" & _
      "Data Source=(local)"
    
    rst.Open "SELECT TOP 10 * FROM Orders", cnn, _
      adOpenStatic, adLockReadOnly
    
    Set objPivotCache = ActiveWorkbook.PivotCaches.Add( _
      SourceType:=xlExternal)

    Set objPivotCache.Recordset = rst

    With objPivotCache
        .CreatePivotTable TableDestination:=Worksheets("Лист1").Range("A3"), _
          TableName:="tblOrders"
    End With

    With Worksheets("Лист1").PivotTables("tblOrders")
        .SmallGrid = False
        With .PivotFields("OrderID")
            .Orientation = xlRowField
            .Position =  1 
        End With
        With .PivotFields("OrderDate")
            .Orientation = xlColumnField
            .Position =  1 
        End With
        With .PivotFields("Freight")
            .Orientation = xlDataField
            .Position =  1 
        End With
    End With
    
    rst.Close
    cnn.Close
    
    Set rst = Nothing
    Set cnn = Nothing
End Sub

P.S. В справочной системе есть пример создания сводной таблицы с данными из внешнего источника с использованием ADO.
...
Рейтинг: 0 / 0
Как отключить Excel от SQL-сервера после выполнения запроса
    #33681211
Яровенко
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
спасибо большое, Ashton

пример абсолютно рабочий, когда код находится в Workbook, но когда я пытаюсь выполнить этот код в dll-ке на VB6(заменив, естественно, все соответствующите ActiveWorkbook на внутрнние переменные), то всё спотыкается на
Set glWorkBook.PivotCaches.Add(SourceType:=xlExternal).Recordset = rst

хотя все переменные определены и инициализированы. Видимо, OLE не безграничен.

PS а этот вариант действительно НЕ оставляет зависшее соединение, жаль, что его не получается использовать
...
Рейтинг: 0 / 0
Как отключить Excel от SQL-сервера после выполнения запроса
    #33683596
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так если у тебя код в dll, то и вытягивай данные в самой dll! Зачем ты это Экселю поручаешь? Весь код работы с БД оставь внутри dll, вытягиваешь рекродсет, копируешь его в Эксель на пустой лист, закрываешь соединение с базой. Потом строишь сводные таблицы на основе данных уже лежащих в книге.
...
Рейтинг: 0 / 0
Как отключить Excel от SQL-сервера после выполнения запроса
    #33683798
Яровенко
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Была такая мысль, но остановило вот что:
1. двойная работа - потеря скорости
2. бывают случаи, когда данные на лист не помещаются (например, слишком много уникальных пар Склад-Товар, больше 65536), а если сразу в сводную таблицу (склады горизонтально), то все прекрасно помещается.

А копировать данные на лист это CopyFromRecordset?
Эх, хотелось бы весь код в dll "заковырять" - от пытливых взоров.
...
Рейтинг: 0 / 0
Как отключить Excel от SQL-сервера после выполнения запроса
    #33683824
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Яровенко1. двойная работа - потеря скоростиВ нормальной системе - нет.
Яровенко2. бывают случаи, когда данные на лист не помещаются (например, слишком много уникальных пар Склад-Товар, больше 65536), а если сразу в сводную таблицу (склады горизонтально), то все прекрасно помещается.Кошмар какой! Тащить на клиента более сотни записей это уже неправильно. Лучше переложить задачу составления сводной таблицы на сервер. Он для этого специально предназначен собственно говоря :) Лучше усложни свой SQL запрос чтобы получать цифры как можно более готовые для показа юзеру.

ЯровенкоА копировать данные на лист это CopyFromRecordset?Если вытягиваешь данные макросом, то да. А если из dll то лучше использовать что-то вроде:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
procedure TfMain.cmdExportClick(Sender: TObject);
var oApp: TExcelApplication;
    oWB: _WorkBook;
    oWS: _WorkSheet;
    i, j, k: Integer;
    TabGrid: Variant;
begin
  try
    CoInitializeEx(nil, COINIT_APARTMENTTHREADED);
    oApp := TExcelApplication.Create(self);
    try
      oWB := oApp.Workbooks.Add(Null,  0 );
      oWS := oWB.Worksheets.Get_Item( 1 ) as _WorkSheet;
      for i:= 0  to memData.FieldCount- 1  do begin
        oWS.Cells.Item[ 1 , i+ 1 ].Value := memData.Fields[i].DisplayName;
        oWS.Cells.Item[ 1 , i+ 1 ].Font.Bold := true;
      end;
      TabGrid := VarArrayCreate([ 0 ,(memData.RecordCount- 1 ), 0 ,(memData.FieldCount- 1 )],VarOleStr);

      k := memData.RecNo;
      memData.First;
      i:= 0 ;
      while not memData.Eof do begin
        for j:= 0  to memData.FieldCount- 1  do begin
          if memData.Fields[j].IsNull then
            TabGrid[i, j] := memData.Fields[j].AsString
          else
            TabGrid[i, j] := memData.Fields[j].AsVariant;
        end;
        memData.Next;
        Inc(i);
      end;
      memData.RecNo := k;
      oWS.Range['A2',oWS.Cells.Item[memData.RecordCount+ 1 ,memData.FieldCount]].Value2 := TabGrid;
      
      TabGrid := Unassigned;
      oWS.UsedRange[ 0 ].Columns.AutoFit;
      oApp.Windows[ 1 ].SplitRow :=  1 ;
      oApp.Windows[ 1 ].FreezePanes := true;
    finally
      oApp.Visible[ 0 ] := true;
      oApp.Disconnect;
    end;
  finally
  	CoUnInitialize;
  end;
end;
...
Рейтинг: 0 / 0
Как отключить Excel от SQL-сервера после выполнения запроса
    #33684114
Яровенко
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
если я правильно понял, ты из рекордсета заполняешь массив, а массив присваеваешь диапазону. А зачем, ведь это двойная работа?
Set rstRecordset = New ADODB.Recordset
................................. заполнение рекордсета
Dim tempRanje As Range
Set tempRanje = glSheet.Range("A1")
tempRanje.CopyFromRecordset rstRecordset
...
Рейтинг: 0 / 0
Как отключить Excel от SQL-сервера после выполнения запроса
    #33684116
Яровенко
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
То, что я написал в предыдущем посте - прекрасно работает в dll-ке.
А вот конструкция
Set objPivotCache.Recordset = MyRecordset
работает ТОЛЬКО непосредственно в книге Excel, а в dll-ке выдает невразумительную ошибку "определенную объектом".

А так хочется заполнять сводную таблицу из dll. Помогите, Братья!
...
Рейтинг: 0 / 0
Как отключить Excel от SQL-сервера после выполнения запроса
    #33687097
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЯровенкоА вот конструкция
Set objPivotCache.Recordset = MyRecordset
работает ТОЛЬКО непосредственно в книге Excel, а в dll-ке выдает невразумительную ошибку "определенную объектом".Вот именно по этому, я и делаю двойную работу с промежуточным массивом :)
Реальный рекордсет у меня может быть каким угодно и приходить откуда угодно (хоть из ADO, хоть из ODBC, хоть самостоятельно рассчитаным). Но чтобы перекинуть данные в Эксель их надо привести в форму понятную Экселю. Вот для этого я и использую Variant-массив. Это не вопрос двойной работы, это вопрос приведения типов данных :)
Если перекидывать данные по одной ячейке за раз, то можно обойтись и без промежуточного массива, можно будет работать напрямую с резалтсетом, но тогда ты будешь делать ту же самую конвертацию непосредственно перед посылкой данных в Эксель.
...
Рейтинг: 0 / 0
15 сообщений из 15, страница 1 из 1
Форумы / Microsoft Office [игнор отключен] [закрыт для гостей] / Как отключить Excel от SQL-сервера после выполнения запроса
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]