Форум: "Основная";
Текущий архив: 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