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

Вниз

Как правидлно закрыть 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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.52 MB
Время: 0.036 c
4-1094544612
SS
2004-09-07 12:10
2004.10.10
Работа с процессами


4-1093780326
Endi
2004-08-29 15:52
2004.10.10
Task Scheduler


14-1095669349
BiN
2004-09-20 12:35
2004.10.10
Вечная жизнь


1-1096258220
r9000
2004-09-27 08:10
2004.10.10
Работа с dll


1-1096286363
TActionManager
2004-09-27 15:59
2004.10.10
Как создать свой пункт меню первого уровня





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский