Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.10.10;
Скачать: CL | DM;

Вниз

Как правидлно закрыть Excel?   Найти похожие ветки 

 
ВиТ ©   (2004-09-25 20:12) [0]

Я работаю с Excel с помощью переменной типа вариант:
var xl:Variant;
xl:=CreateOLEObject("Excel.Application");
и т.д.
Когда программа завершает работу необходимо закрыть Excel командой
xl.quit. Но если он не был запущен, то возникает ошибка!
Ка проверить, связана ли xl c Екселем?  т.е. запушен ли он.
Пробовал
if xl.Active then xl.quit
не помогает. Т.к. сама проверка xl.Active вызывает ошибку.
try.. except тоже не помогло:(


 
YurikGL ©   (2004-09-25 23:21) [1]


> try.. except тоже не помогло:(

Код в студию!!!

> Ка проверить, связана ли xl c Екселем?  т.е. запушен ли
> он.


Запущен ексель или нет проверяется поиском окна

У меня сработал следующий код
app:variant

try
if app<>Unassigned then app.quit;
except
 app.quit;
end;

Кстати, если app не связана с екслелем, то исключения не возникает, а если связана, то возникает. Почему - не знаю.


 
ВиТ ©   (2004-09-25 23:43) [2]

У меня всё равно не работает:(

try
if app<>Unassigned then app.quit;
except
app.quit;
end;

и в результате:
---------------------------
Debugger Exception Notification
---------------------------
Проект mm.exe вызвал исключение класса EVariantInvalidOpError с сообщением "Invalid variant operation". Процесс остановлен. Используйте Шаг или Запуск для продолжения.
---------------------------
OK   Help  
---------------------------


 
YurikGL ©   (2004-09-25 23:49) [3]


> ВиТ ©   (25.09.04 23:43) [2]

Дык это ж когда из делфи запускаешь EVariantInvalidOpError вываливается, а когда прогу не из делфи запускаешь, все будет OK


 
Sergey_Masloff   (2004-09-25 23:53) [4]

Зачем использовать quit?


 
Sergey_Masloff   (2004-09-25 23:55) [5]


try
if app<>Unassigned then app.quit;
except
app.quit;
end;

Это называется пробуем наступить на грабли. Если получили по лбу то наступаем снова.


 
YurikGL ©   (2004-09-25 23:57) [6]


> Sergey_Masloff   (25.09.04 23:55) [5]

:-) Код конечно извращенный, но с ходу ничего другого не придумал...:-( Зато работает...

А если по уму, то проще сделать флажок типа запускался или нет вообще ексель во время текущего сеанса и перед выходом его проверять


 
Sergey_Masloff   (2004-09-25 23:59) [7]

Господин ВиТ © если вы используете функцию CreateOLEObject для присвоения указателя на интерфейс варианту то дайте себе труд ознакомиться с разделом справки по этой функции. Там 3 абзаца всего.


 
YurikGL ©   (2004-09-26 00:00) [8]


> Sergey_Masloff   (25.09.04 23:55) [5]

Кстати, если app не связана с екслелем, то  исключение вызывает не app.quit а app<>Unassigned так что сравнение не корректно.

Если только наступили на одни грабли, потом на другие :-)


 
Sergey_Masloff   (2004-09-26 00:01) [9]

YurikGL ©   (25.09.04 23:57) [6]
Извини, тоже в хелп и в тот же раздел. Потому что как мне кажется налицо полное непонимание вопроса работы с серверами автоматизации через вариантные переменные. Или я ничего не понимаю...


 
Sergey_Masloff   (2004-09-26 00:03) [10]

app<>Unassigned
исключения не вызывает если app объявлена как Variant


 
YurikGL ©   (2004-09-26 00:04) [11]


> Sergey_Masloff   (26.09.04 00:03) [10]

У меня вызывает...


 
YurikGL ©   (2004-09-26 00:08) [12]

procedure TForm1.Button1Click(Sender: TObject);
var
  App : Variant;
begin
try
 app := CreateOleObject("Excel.Application");
 App.Visible := True;
 App.WorkBooks.Add;
 try
 if app<>Unassigned then app.quit;
 except
   app.quit;
 end;

finally
 App:=Unassigned;
end;
end;


Жирным выделен кусок вызывающий исключение...


 
Sergey_Masloff   (2004-09-26 00:11) [13]

YurikGL ©   (26.09.04 00:04) [11]
>У меня вызывает...
Так не бывает. Вернее, бывает когда люди не читают справки и используют технологии без их понимания.

Вы создаете объект получая ссылку на интерфейс.
Потом грохаете объект делая ссылку инвалидной, причем грохаете объект нештатно, не сообщая системе COM о том что вы сделали.
После этого пытаетесь инвалидную ссылку использовать. Это если на пальцах.


 
YurikGL ©   (2004-09-26 00:14) [14]


> Sergey_Masloff   (26.09.04 00:11) [13]

Да, я использую технологию COM без ее понимания абсолютно, методом научного тыка... Но код [12] вызывает исключение. Вопрос: почему????????? Объект нештатно никто не грохает.


 
ВиТ ©   (2004-09-26 00:14) [15]


> Господин ВиТ © если вы используете функцию CreateOLEObject
> для присвоения указателя на интерфейс варианту то дайте
> себе труд ознакомиться с разделом справки по этой функции.
> Там 3 абзаца всего.

Если я правильно понял:
you can release the interface by assigning the Unassigned constant to that Variant
то

app:=Unassigned;

также закроет ексел. Причём даже не возникает предыдущей ошибки,
когда из делфей запускаешь.


> А если по уму, то проще сделать флажок типа запускался или
> нет вообще ексель во время текущего сеанса и перед выходом
> его проверять

А если юзверь возьмёт и сам ексель закроет?
Не получится ли вот так:

if ExcelOpened then
try
if app<>Unassigned then app.quit;
except
app.quit;
end;

;)


 
YurikGL ©   (2004-09-26 00:16) [16]


> app:=Unassigned;
>
> также закроет ексел.

Это кто тебе сказал????

Опиши, что тебе нужно... ИМХО твою проблему можно по другому решить.


 
Sergey_Masloff   (2004-09-26 00:17) [17]

YurikGL ©   (26.09.04 00:16) [16]
>Это кто тебе сказал????
Те кто писал справку по Delphi. А также авторы MSDN и др.


 
Sergey_Masloff   (2004-09-26 00:20) [18]

>А если юзверь возьмёт и сам ексель закроет?
>Не получится ли вот так:
Получится-получится. Поэтому никакие флажки не нужны

одним словом

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

type
 TForm1 = class(TForm)
   Button1: TButton;
   Button2: TButton;
   procedure Button1Click(Sender: TObject);
   procedure Button2Click(Sender: TObject);
 private
   xl:Variant;
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation
uses ComObj;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);

begin
 xl:=CreateOLEObject("Excel.Application");
 xl.Visible := True;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 xl := Unassigned;
end;

end.


 
YurikGL ©   (2004-09-26 00:20) [19]


> Sergey_Masloff   (26.09.04 00:17) [17]

Извини, но видимо уже ты кое что не понимаешь

try
 app := CreateOleObject("Excel.Application");
 App.Visible := True;
 App.WorkBooks.Add;

finally
 App:=Unassigned;
end;


Просто запустит ексель...

Освободится переменная связанная с екслем,ссылка на него... Но сам ексель останется. Его никто не закрывал.


 
Sergey_Masloff   (2004-09-26 00:23) [20]

Вобщем unassigned присвоить безопасно. В моем примере если эксель даже закроет юзер то никаких исключений не будет.

Кстати при выходе переменнойиз области видимости переменной nil присвоится сам - компилятор сгенерирует для этого соотв. код сам.

то есть

procedure TForm1.Button1Click(Sender: TObject);
var
 xl : Variantl
begin
xl:=CreateOLEObject("Excel.Application");
xl.Visible := True;
end;

Эксель мигнет на экране (на медленном компьютере на быстром и не мигнет) и все.


 
YurikGL ©   (2004-09-26 00:27) [21]


> procedure TForm1.Button1Click(Sender: TObject);
> var
>  xl : Variantl
> begin
> xl:=CreateOLEObject("Excel.Application");
> xl.Visible := True;
> end;


Да, однако если

 app := CreateOleObject("Excel.Application");
 App.Visible := True;
 App:=Unassigned;

То ексель выйдет, но если
 app := CreateOleObject("Excel.Application");
 App.Visible := True;
 App.WorkBooks.Add;
 App:=Unassigned;

То уже не получится.


 
Sergey_Masloff   (2004-09-26 00:29) [22]

YurikGL ©   (26.09.04 00:20) [19]
>Извини, но видимо уже ты кое что не понимаешь
Извиняю но я все понимаю. Метод Add обращается за интерфейсом рабочей книги (а это уже другой интерфейс) и увеличивает счетчик ссылок твоего App до двух. Потом ты высвобождаешь ОДНУ из них. Если работаешь через варианты ты обязан объявить еще одну вариантную переменную, допустим, wrkbook : Variant и поработав также ее прибить.


 
Sergey_Masloff   (2004-09-26 00:31) [23]

Кстати все там ренджи и так далее - все вышеприведенное действует и для них. За подробностями - Дейл Роджерсон основы COM. Правда там нет ни слова про Excel и Delphi $-)


 
YurikGL ©   (2004-09-26 00:33) [24]


> Sergey_Masloff   (26.09.04 00:29) [22]

Беру свои слова обратно, просто никогда не было надобности работать с екселем без рабочих книг :-)

Основную мысль понял, но неудобно же создавать еще одну переменную.

Я обычно так делаю... Запустил новый екслель через ексельаппликейшн или олеобджект сделал там отчет и unassigned от него. К книгам обращаюсь через activebook или коллекцию книг. И все. А закрывать ексель на выходе... Никогда такой потеребности не возникало.
Так все же, почему исключение то возникает?


 
Sergey_Masloff   (2004-09-26 00:41) [25]

>Так все же, почему исключение то возникает?
Которое? При проверке на Unassigned?


 
YurikGL ©   (2004-09-26 00:43) [26]


> Sergey_Masloff   (26.09.04 00:41) [25]

Да


 
YurikGL ©   (2004-09-26 00:51) [27]

А главное, как на исходный вопрос то ответить? Ведь Unassigned при наличии открытых рабочих книг не осуществляет выход из екслеля... А каждый раз переменную создвать - тоже не очень удобно


 
Sergey_Masloff   (2004-09-26 01:02) [28]

Ну тут уже тонкости. Unassigned это не значение а функция. А вариант которому что-то присвоено с возвращаемым ею результатом несравним.
 Одним словом, используй VarIsEmpty(), VarIsNull() и так далее. То есть не if(app <> Unassigned) а if VarIsEmpty(app)


 
Sergey_Masloff   (2004-09-26 01:08) [29]

Кстати
>Основную мысль понял, но неудобно же создавать еще одну >переменную.
ты еще не пробовал на C++ писать... Вот где ж... с интерфейсами. При каждом присваивании переменной изволь ей (интерфейсу) _AddRef() сделать и не забыть везде соотв. _Release()...



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

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

Наверх




Память: 0.54 MB
Время: 0.023 c
4-1094282632
Интель
2004-09-04 11:23
2004.10.10
Убить explorer.exe без восстановления


1-1095780562
B-boy Dimo-N
2004-09-21 19:29
2004.10.10
детская проблема с компилированием DLL


11-1081335922
nsvi
2004-04-07 15:05
2004.10.10
StatusBar


6-1091184051
Гость
2004-07-30 14:40
2004.10.10
WEBBROWSEr1


1-1095888698
Константинов
2004-09-23 01:31
2004.10.10
Подскажите, как правильно работать со свойствами-массивами