Конференция "Corba" » Программа глючит при открытии Excel-документа с пред.просмотром.. [D6, D7, WinXP]
 
  • VoznikVopros (17.04.09 23:34) [0]
    Как открыть Excel-документ с предварительным просмотром БЕЗ глюков в программе?..

    Вот пример:
    procedure TForm1.Button1Click(Sender: TObject);
    var
    VExcel:Variant;
    begin
    //Открываем Excel-файл шаблона
    try
     //проверяем, нет ли запущенного Excel
     VExcel := GetActiveOleObject('Excel.Application');
    except
     //если нет, то запускаем
     on EOLESysError do
      VExcel := CreateOleObject('Excel.Application');
    end;
    VExcel.DisplayAlerts:=False;
    VExcel.Visible := True;
    //Открываем Excel на полный экран
    VExcel.WindowState := -4137;
    VExcel.WorkBooks.Open('C:\Документ.xls');

    VExcel.ActiveSheet.PrintOut(1,1,1,1); //Пред. просмотр
    end;


    В результате, если закоментировать строку " VExcel.ActiveSheet.PrintOut(1,1,1,1);", то после открытия Excel-окна в программу можно вернуться нормально (т.е. открыть форму с кнопкой).
    Если же выполнить данную строку, то когда появится окно Excel с предварительным просмотром - то программа будет глючить до тех пор, пока не закроется предварительный просмотр...

    Подскажите - как избавиться от этой ошибки? Спасибо!
  • Сергей М. © (19.04.09 11:35) [1]

    > программа будет глючить


    Дай догадаюсь - пограмма открывает окно, в котором написано "Я, программа, буду глючить" ?)
  • VoznikVopros (19.04.09 13:12) [2]
    Догадки неправильны=)

    Иными словами - программа становится не активной, в ней не видны контролы, невозможно нажать на них и тд и тп!
  • Сергей М. © (19.04.09 13:35) [3]
    Это не "глюки", а вполне нормальное поведение.

    Выноси работу с Excel в доп.поток.
  • VoznikVopros (19.04.09 13:41) [4]

    > Сергей М. ©   (19.04.09 13:35) [3]
    > Это не "глюки", а вполне нормальное поведение.Выноси работу
    > с Excel в доп.поток.

    Тоже про это думал... только как реализовать работу с Excel через доп.поток?..
  • Сергей М. © (19.04.09 14:00) [5]
    Точно так же как и "через" основной.
  • VoznikVopros (19.04.09 14:37) [6]

    > Сергей М. ©   (19.04.09 14:00) [5]
    > Точно так же как и "через" основной.

    Т.е. создать дополнительный VExcel2 типа Variant, в него загрузить документ и пустить на пред.просмотр?.. Смысла не вижу... ИМХО.. Или как?
  • Сергей М. © (19.04.09 14:51) [7]

    > Или как?


    Именно так.
  • Сергей М. © (19.04.09 15:06) [8]

    > Или как?


    Именно так.
  • VoznikVopros (19.04.09 17:54) [9]

    > Сергей М. ©   (19.04.09 15:06) [8]
    > > Или как?Именно так.

    Так а в чём смысл всё-таки создания двух VExcel? Если создать второй поток, то код будет таким же самым как и по нажатию кнопки... Т.е.:

    procedure TForm1.Button1Click(Sender: TObject);
    var
    VExcel:Variant;
    VExcel2:Variant;
    begin
    //Открываем Excel-файл шаблона
    try
    //проверяем, нет ли запущенного Excel
    VExcel := GetActiveOleObject('Excel.Application');
    VExcel2 := GetActiveOleObject('Excel.Application');
    except
    //если нет, то запускаем
    on EOLESysError do
    begin
     VExcel := CreateOleObject('Excel.Application');
     VExcel2 := CreateOleObject('Excel.Application');
    end;
    end;
    VExcel.DisplayAlerts:=False;
    VExcel2.DisplayAlerts:=False;
    VExcel.Visible := True;
    VExcel2.Visible := True;
    //Открываем Excel на полный экран
    VExcel.WindowState := -4137;
    VExcel2.WindowState := -4137;
    VExcel.WorkBooks.Open('C:\Документ.xls');//???
    VExcel2.WorkBooks.Open('C:\Документ.xls');//???

    VExcel.ActiveSheet.PrintOut(1,1,1,1); //Пред. просмотр    //???
    VExcel2.ActiveSheet.PrintOut(1,1,1,1); //Пред. просмотр   //???
    end;



    Т.е. так? Если нет, то как? Всё равно не понятно - почему при таком случае программа глючить не будет?..

    Может есть возможность "отсоединения" handl'a Excel от программы?..
  • Сергей М. © (19.04.09 18:07) [10]

    > в чём смысл всё-таки создания двух VExcel?


    Я про "два" ничего не говорил. Это тебе второй зачем-то понадобился)

    Речь идет о том, как вызвать к выполнению некую подпрограмму, блокирующую исполнение вызывающего ее кодового потока вплоть до момента завершение этой подпрограммы, и при этом дать возможность программе обновлять содержимое своих окон и реагировать на события пользовательского ввода.


    > код будет таким же самым как и по нажатию кнопки


    Почти таким.
    Перед первым обращением к Excel-объекту (как и к любому другому OLE-объекту) следует выполнить CoInitialize(nil), а по завершению работы вызвать CoUninitialize.


    > почему при таком случае программа глючить не будет?


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


    > есть возможность "отсоединения" handl'a Excel от программы?


    Нет.
  • VoznikVopros (20.04.09 01:41) [11]

    > Почти таким.Перед первым обращением к Excel-объекту (как
    > и к любому другому OLE-объекту) следует выполнить CoInitialize(nil),
    >  а по завершению работы вызвать CoUninitialize.

    То есть:
    procedure TForm1.Button1Click(Sender: TObject);
    var
    VExcel:Variant;
    begin
    //Открываем Excel-файл шаблона
    try
    //проверяем, нет ли запущенного Excel
    VExcel := GetActiveOleObject('Excel.Application');
    except
    //если нет, то запускаем
    on EOLESysError do
     VExcel := CreateOleObject('Excel.Application');
    end;

    CoInitialize(nil); //Ошибка!

    VExcel.DisplayAlerts:=False;
    VExcel.Visible := True;
    //Открываем Excel на полный экран
    VExcel.WindowState := -4137;
    VExcel.WorkBooks.Open('C:\Документ.xls');

    VExcel.ActiveSheet.PrintOut(1,1,1,1); //Пред. просмотр

    CoUninitialize;//Ошибка!
    end;



    При компиляции с данными методами возникает ошибка - они не находятся...
  • Сергей М. © (20.04.09 08:37) [12]
    uses ComObj;
    ..
    CoInitialize(nil);
    try
    .. здесь и ТОЛЬКО здесь осуществлять любые обращения к Excel !!!! ...
    finally
     CoUninitialize;
    end;

  • VoznikVopros (20.04.09 11:48) [13]

    > uses ComObj;..
    > CoInitialize(nil);
    > try
    > .. здесь и ТОЛЬКО здесь осуществлять любые обращения к Excel !!!! ...
    > finally  
    >  CoUninitialize;
    > end;

    Нету метода CoInitialize в ComObj... Из похожих есть только CoInitializeEx(pvReserved:Pointer; coInit:Integer)
    А аналога CoUninitialize нету..

    Если бы работало, то код бы выглядел бы так?

    uses ComObj,...;
    ...
    procedure TForm1.Button1Click(Sender: TObject);
    var
    VExcel:Variant;
    begin
    //Открываем Excel-файл шаблона
    try
    //проверяем, нет ли запущенного Excel
    VExcel := GetActiveOleObject('Excel.Application');
    except
    //если нет, то запускаем
     on EOLESysError do
      VExcel := CreateOleObject('Excel.Application');
    end;

    CoInitialize(nil); //Ошибка!

    try
     VExcel.DisplayAlerts:=False;
     VExcel.Visible := True;
     //Открываем Excel на полный экран
     VExcel.WindowState := -4137;
     VExcel.WorkBooks.Open('C:\Документ.xls');

     VExcel.ActiveSheet.PrintOut(1,1,1,1); //Пред. просмотр
    finally
     CoUninitialize;//Ошибка!
    end;
    end;



    Если написать "ComObj." - то в списке методов нужных не будет..
  • Сергей М. © (20.04.09 11:59) [14]

    > Нету метода CoInitialize в ComObj


    Пардон, в
    ActiveX

    это определено.


    > код бы выглядел бы так?


    Ну где же так ?

    Ф-ции GetActiveOleObject и CreateOleObject имеют прямое отношение к OLE-механизму, который ты еще не инициализировал (инициализация у тебя следует ниже)
  • VoznikVopros (20.04.09 13:55) [15]
    Да, с ActiveX скомпилировалось, но проблема не решена..

    Вот скрин - демонстрация глюка:
    http://www.pixshock.net/pic_b/10b6a6c0a75f6a1966587a86dc9c9566.jpg

    Вверху - исходное состояние программы после запуска

    Ниже - после открытия экселя с пред.просмотром, т.е. форма не реагирует ни на что...
  • Сергей М. © (20.04.09 14:03) [16]

    > VoznikVopros   (20.04.09 13:55) [15]



    > демонстрация глюка


    Сказка про белого бычка)

    см. [3]
  • VoznikVopros (20.04.09 14:55) [17]
    И сново по кругу? :-D

    CoInitialize(nil);
    CoUninitialize;
    Эти две строки и есть типа выноса в доп.поток?.. Приведи пример двух-поточной обработки...
  • Сергей М. © (20.04.09 15:06) [18]

    > Эти две строки и есть типа выноса в доп.поток?


    Эти две строки есть не "типа выноса".

    По поводу собственно выноса читай справку к классу TThread до полного увеселения, в частности и в 1-ю очередь - к его методу Execute, в теле при работе с OLE-подсистемой требуется соблюдение требований, на которых я заострил твое внимание в [12]
 
Конференция "Corba" » Программа глючит при открытии Excel-документа с пред.просмотром.. [D6, D7, WinXP]
Есть новые Нет новых   [134427   +35][b:0][p:0.003]