Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2015.09.10;
Скачать: 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 вся ветка

Текущий архив: 2015.09.10;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.077 c
15-1415987381
Rouse_
2014-11-14 20:49
2015.09.10
Пара слов о кэшировании данных при чтении и смартпойнтерах


15-1417642205
Юрий
2014-12-04 00:30
2015.09.10
С днем рождения ! 4 декабря 2014 четверг


2-1392391651
dehkanin
2014-02-14 19:27
2015.09.10
Почему выплывает исключение?


15-1420010989
brother
2014-12-31 10:29
2015.09.10
С наступающим!


15-1421076624
Azize
2015-01-12 18:30
2015.09.10
Создание Word файла в Delphi