Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как правидлно закрыть Excel?


Страницы:   1 2

ВиТ ©   (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


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо