Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2015.09.10;
Скачать: [xml.tar.bz2];

Вниз

Получить все открытые документы 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.048 c
15-1417807101
KilkennyCat
2014-12-05 22:18
2015.09.10
Где Северный полюс?


2-1394436419
alexdn
2014-03-10 11:26
2015.09.10
Закрытие формы


15-1419887710
Кто б сомневался
2014-12-30 00:15
2015.09.10
Кто-нить использует Test Mode в Win 7?


11-1217501243
KOLBOSS
2008-07-31 14:47
2015.09.10
EnumAllKeys


2-1396806177
Drowsy
2014-04-06 21:42
2015.09.10
В DBGridEh есть колонка навигации (самая левая) .





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский