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

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

Как я определяю, что соединение открыто? Пытаюсь открыть базу в однопользовательском режиме - не разрешает, закрываю книгу Excel - разрешает.
...
Рейтинг: 0 / 0
20.04.2006, 10:06:33
    #33678256
big-duke
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как отключить Excel от SQL-сервера после выполнения запроса
Ну если в лоб и побыстрому то мона так
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
20.04.2006, 10:13:54
    #33678280
Ashton
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как отключить Excel от SQL-сервера после выполнения запроса
Так не закрывает?

Код: 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
20.04.2006, 10:42:20
    #33678394
Яровенко
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как отключить Excel от SQL-сервера после выполнения запроса
Ashton, а так еще не пробовал (с импользование ADODB.Recordset)
я пробовал так, как макрос записывается
сейчас начну экспериментировать
...
Рейтинг: 0 / 0
20.04.2006, 10:45:28
    #33678406
Яровенко
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как отключить Excel от SQL-сервера после выполнения запроса
а чтобы работать с объектом ADODB.Connection, какую библиотеку нужно к проекту подключить?
...
Рейтинг: 0 / 0
20.04.2006, 11:06:22
    #33678512
Ashton
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как отключить Excel от SQL-сервера после выполнения запроса
"Microsoft ActiveX Data Objects".
...
Рейтинг: 0 / 0
20.04.2006, 12:11:43
    #33678829
Яровенко
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как отключить Excel от SQL-сервера после выполнения запроса
У меня выскакивает "Ошибка, определенная объектом" на этой строке:
Set PivotCache.Recordset = rstRecordset

Ashton, ты не мог бы бросить весь рабочий пример целиком? буду ОЧЕНЬ признателен
...
Рейтинг: 0 / 0
20.04.2006, 23:40:33
    #33680903
Ashton
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как отключить Excel от SQL-сервера после выполнения запроса
Код: 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
21.04.2006, 09:25:16
    #33681211
Яровенко
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как отключить Excel от SQL-сервера после выполнения запроса
спасибо большое, Ashton

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

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

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

А копировать данные на лист это CopyFromRecordset?
Эх, хотелось бы весь код в dll "заковырять" - от пытливых взоров.
...
Рейтинг: 0 / 0
21.04.2006, 20:09:35
    #33683824
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как отключить Excel от SQL-сервера после выполнения запроса
Яровенко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
22.04.2006, 09:21:48
    #33684114
Яровенко
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как отключить Excel от SQL-сервера после выполнения запроса
если я правильно понял, ты из рекордсета заполняешь массив, а массив присваеваешь диапазону. А зачем, ведь это двойная работа?
Set rstRecordset = New ADODB.Recordset
................................. заполнение рекордсета
Dim tempRanje As Range
Set tempRanje = glSheet.Range("A1")
tempRanje.CopyFromRecordset rstRecordset
...
Рейтинг: 0 / 0
22.04.2006, 09:29:23
    #33684116
Яровенко
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как отключить Excel от SQL-сервера после выполнения запроса
То, что я написал в предыдущем посте - прекрасно работает в dll-ке.
А вот конструкция
Set objPivotCache.Recordset = MyRecordset
работает ТОЛЬКО непосредственно в книге Excel, а в dll-ке выдает невразумительную ошибку "определенную объектом".

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


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