Вниз
Скачать: CL | DM;

Получить все открытые документы Excel   Найти похожие ветки 

← →
Дмитрий С ©   (2014-12-04 18:30) [0]

Подскажите, пожалуйста, как получить список всех открытых документов Excel с возможностью что-нибудь в них "поделать"?

Помню когда-то делал такое для PowerPoint-а: нажимаешь кнопку в приложении - открывается список открытых презентаций (всех, а не только открытых моим приложением) - пользователь выбирает один из них - в него добавляется слайд. К сожалению, исходник не сохранился.

Вот примерно то же самое нужно сделать для Excel.


← →
Dimka Maslov ©   (2014-12-04 18:58) [1]

Получаем объект Excel.Application и вперёд, что хочешь делай.

function ConnectApplication(ProgID: String; var V: Variant): Boolean;
var
 Clsid: TCLSID;
 unk: IUnknown;
 dis: IDispatch;
begin
 Result := False;
 try
   if ( CLSIDFromProgID(PWideChar(ProgID), Clsid) <> S_OK ) then Exit;
   if ( GetActiveObject(Clsid, nil, unk) <> S_OK ) then Exit;
   if ( unk.QueryInterface(IDispatch, dis) <> S_OK ) then Exit;
   V := dis;
 except
   Exit;
 end;
 Result := True;
end;


← →
junglecat ©   (2014-12-04 19:04) [2]

в голову пришел тупой вариант:
перебрать все главные окна процесса excel.exe (класс XLMAIN вроде как), выдрать из заголовка регэкспом *.xls* имена файлов, сохранить в список, потом через ADO подключиться к выбранному


← →
Дмитрий С ©   (2014-12-04 19:20) [3]


> Dimka Maslov ©   (04.12.14 18:58) [1]
>

Так это я получу один какой-то инстанс, а если их несколько открыто?


> junglecat ©   (04.12.14 19:04) [2]
>

Вообще не вариант:)


← →
Dimka Maslov ©   (2014-12-04 19:25) [4]


> Так это я получу один какой-то инстанс, а если их несколько
> открыто?


Я не пробовал. Но у ExcelApplication есть свойство Documents может оно отражает все документы во всех активных инстанциях.


← →
junglecat ©   (2014-12-04 19:44) [5]

кстати, да. по крайней мере, у экселя 2010 один процесс на все доки. так что активинстанс вполне может содержать их все


← →
Дмитрий С ©   (2014-12-04 20:01) [6]


> у экселя 2010 один процесс на все доки.

Не обязательно. Какое-нибудь приложение может "назапускать" своих.


← →
Дмитрий С ©   (2014-12-04 20:02) [7]

Нашел и доработал способ в сети:

function AccessibleObjectFromWindow(
 Ahwnd: HWND;
 dwObjectID: DWORD;
 const riid: TGUID;
 var ppvObject: pointer
 ): DWORD;
 stdcall; external "OLEACC.DLL" name "AccessibleObjectFromWindow";

procedure TMainForm.SpeedButton1Click(Sender: TObject);
var
 I: Integer;
 SL: TStringList;
 H, H1, H2: THandle;
 ObjD: IDispatch;
 Obj: OleVariant;
begin
 SL := TStringList.Create;
 try
   H := FindWindowEx(0, 0, "XLMAIN", nil);
   while H <> 0 do
   begin
     H1 := FindWindowEx(H, 0, "XLDESK", nil);
     while H1 <> 0 do
     begin
       H2 := FindWindowEx(H1, 0, "EXCEL7", nil);
       while H2 <> 0 do
       begin
         if AccessibleObjectFromWindow(H2, $FFFFFFF0, IDispatch, Pointer(ObjD)) = 0 then
         begin
           Obj := ObjD;
           for I := 1 to Obj.Application.Workbooks.Count do
             SL.Add(Obj.Application.Workbooks[I].FullName);
         end;
         H2 := FindWindowEx(H1, H2, "EXCEL7", nil);
       end;
       H1 := FindWindowEx(H, H1, "XLDESK", nil);
     end;
     H := FindWindowEx(0, H, "XLMAIN", nil);
   end;
   Application.MessageBox(PChar(SL.Text), "", 0);
 finally
   SL.Free;
 end;
end;


Немного извращенный, но времени копаться нету:(


← →
Ega23 ©   (2014-12-04 20:11) [8]

У тебя может быть туча скрытых процессов.
xl:=CreateOleObject("Excel.Application");
for i := 1 to xl.workbooks.Count do
 wb:=xl.workbooks[i];


← →
Дмитрий С ©   (2014-12-05 01:19) [9]


> Ega23 ©   (04.12.14 20:11) [8]

Скрытые как раз не особо нужны.

Твой код не вернет ничего.


← →
Ega23 ©   (2014-12-05 08:37) [10]


> Твой код не вернет ничего.
>


М.б., на работе гляну.


← →
Ega23 ©   (2014-12-05 10:40) [11]

Так, ну перебора открытых у меня нету, только добавление своей. См. примеры, их в гугле полно.
Если будешь использовать делфёвые __Application и _Workbook, то индексация с нуля до Count-1.
Если на вариантах - то там не помню, по-идиотски как-то сделано, то с нуля, то с единицы. Проверять надо.


← →
junglecat ©   (2014-12-05 11:27) [12]

> [7] Дмитрий С ©   (04.12.14 20:02)

а зачем циклы для окон класса XLDESK и EXCEL7?


← →
Дмитрий С ©   (2014-12-05 15:50) [13]


> junglecat ©   (05.12.14 11:27) [12]

Не было времени изучать вопрос. Хуже от этого не будет точно.


← →
Дмитрий С ©   (2014-12-05 15:56) [14]

Кто-нибудь сталкивался с проблемой:
- Если Excel свернут, то данные на листе не обновляются. Причем если поскролить - то все проявляется. Т.е., грубо говоря, ексель отображет значения из какого-то кеша.



Страницы: 1 вся ветка

Скачать: CL | DM;



Память: 0.48 MB
Время: 0.036 c
15-1412228540
alexdn
2014-10-02 09:42
2015.09.10
Что с ВКонтакте?


15-1413896047
Ellisium
2014-10-21 16:54
2015.09.10
ado при execsql не выдает ошибку?


15-1412754599
ProstoTak
2014-10-08 11:49
2015.09.10
Программа CamFind - это нечто


15-1414791002
Юрий
2014-11-01 01:30
2015.09.10
С днем рождения ! 1 ноября 2014 суббота


15-1422221404
Юрий
2015-01-26 00:30
2015.09.10
С днем рождения ! 26 января 2015 понедельник




   Наверх