![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как правидлно закрыть Excel?
ВиТ © (2004-09-25 20:12:00)Я работаю с Excel с помощью переменной типа вариант:
var xl:Variant;и т.д.
xl:=CreateOLEObject('Excel.Application');
Когда программа завершает работу необходимо закрыть Excel командой
xl.quit. Но если он не был запущен, то возникает ошибка!
Ка проверить, связана ли xl c Екселем? т.е. запушен ли он.
Пробовал
if xl.Active then xl.quit
не помогает. Т.к. сама проверка xl.Active вызывает ошибку.
try.. except тоже не помогло:(
Sergey_Masloff (2004-09-26 01:08:00) [1]Кстати
>Основную мысль понял, но неудобно же создавать еще одну >переменную.
ты еще не пробовал на C++ писать... Вот где ж... с интерфейсами. При каждом присваивании переменной изволь ей (интерфейсу) _AddRef() сделать и не забыть везде соотв. _Release()...
Sergey_Masloff (2004-09-26 01:02:00) [2]Ну тут уже тонкости. Unassigned это не значение а функция. А вариант которому что-то присвоено с возвращаемым ею результатом несравним.
Одним словом, используй VarIsEmpty(), VarIsNull() и так далее. То есть не if(app <> Unassigned) а if VarIsEmpty(app)
YurikGL (2004-09-26 00:51:00) [3]А главное, как на исходный вопрос то ответить? Ведь Unassigned при наличии открытых рабочих книг не осуществляет выход из екслеля... А каждый раз переменную создвать - тоже не очень удобно
YurikGL (2004-09-26 00:43:00) [4]
> Sergey_Masloff (26.09.04 00:41) [25]
Да
Sergey_Masloff (2004-09-26 00:41:00) [5]>Так все же, почему исключение то возникает?
Которое? При проверке на Unassigned?
YurikGL (2004-09-26 00:33:00) [6]
> Sergey_Masloff (26.09.04 00:29) [22]
Беру свои слова обратно, просто никогда не было надобности работать с екселем без рабочих книг :-)
Основную мысль понял, но неудобно же создавать еще одну переменную.
Я обычно так делаю... Запустил новый екслель через ексельаппликейшн или олеобджект сделал там отчет и unassigned от него. К книгам обращаюсь через activebook или коллекцию книг. И все. А закрывать ексель на выходе... Никогда такой потеребности не возникало.
Так все же, почему исключение то возникает?
Sergey_Masloff (2004-09-26 00:31:00) [7]Кстати все там ренджи и так далее - все вышеприведенное действует и для них. За подробностями - Дейл Роджерсон основы COM. Правда там нет ни слова про Excel и Delphi $-)
Sergey_Masloff (2004-09-26 00:29:00) [8]YurikGL © (26.09.04 00:20) [19]
>Извини, но видимо уже ты кое что не понимаешь
Извиняю но я все понимаю. Метод Add обращается за интерфейсом рабочей книги (а это уже другой интерфейс) и увеличивает счетчик ссылок твоего App до двух. Потом ты высвобождаешь ОДНУ из них. Если работаешь через варианты ты обязан объявить еще одну вариантную переменную, допустим, wrkbook : Variant и поработав также ее прибить.
YurikGL (2004-09-26 00:27:00) [9]
> 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:23:00) [10]Вобщем unassigned присвоить безопасно. В моем примере если эксель даже закроет юзер то никаких исключений не будет.
Кстати при выходе переменнойиз области видимости переменной nil присвоится сам - компилятор сгенерирует для этого соотв. код сам.
то есть
procedure TForm1.Button1Click(Sender: TObject);
var
xl : Variantl
begin
xl:=CreateOLEObject('Excel.Application');
xl.Visible := True;
end;
Эксель мигнет на экране (на медленном компьютере на быстром и не мигнет) и все.
YurikGL (2004-09-26 00:20:00) [11]
> 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:20:00) [12]>А если юзверь возьмёт и сам ексель закроет?
>Не получится ли вот так:
Получится-получится. Поэтому никакие флажки не нужны
одним словом
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.
Sergey_Masloff (2004-09-26 00:17:00) [13]YurikGL © (26.09.04 00:16) [16]
>Это кто тебе сказал????
Те кто писал справку по Delphi. А также авторы MSDN и др.
YurikGL (2004-09-26 00:16:00) [14]
> app:=Unassigned;
>
> также закроет ексел.
Это кто тебе сказал????
Опиши, что тебе нужно... ИМХО твою проблему можно по другому решить.
ВиТ (2004-09-26 00:14:00) [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:14:00) [16]
> Sergey_Masloff (26.09.04 00:11) [13]
Да, я использую технологию COM без ее понимания абсолютно, методом научного тыка... Но код [12] вызывает исключение. Вопрос: почему????????? Объект нештатно никто не грохает.
Sergey_Masloff (2004-09-26 00:11:00) [17]YurikGL © (26.09.04 00:04) [11]
>У меня вызывает...
Так не бывает. Вернее, бывает когда люди не читают справки и используют технологии без их понимания.
Вы создаете объект получая ссылку на интерфейс.
Потом грохаете объект делая ссылку инвалидной, причем грохаете объект нештатно, не сообщая системе COM о том что вы сделали.
После этого пытаетесь инвалидную ссылку использовать. Это если на пальцах.
YurikGL (2004-09-26 00:08:00) [18]
procedure TForm1.Button1Click(Sender: TObject);
var
App : Variant;
begin
try
app := CreateOleObject('Excel.Application');
App.Visible := True;
App.WorkBooks.Add;
try
if app<>Unassignedthen app.quit;
except
app.quit;
end;
finally
App:=Unassigned;
end;
end;
Жирным выделен кусок вызывающий исключение...
YurikGL (2004-09-26 00:04:00) [19]
> Sergey_Masloff (26.09.04 00:03) [10]
У меня вызывает...
Sergey_Masloff (2004-09-26 00:03:00) [20]app<>Unassigned
исключения не вызывает если app объявлена как Variant