Delphi olecontainer excel одновременная работа
Видимо любители экономить килобайты оперативной памяти могут меня закидать помидорами или ещё чем по-хуже, но все-таки я скажу, что интеграция приложений (мегабайты оперативы) — это большой плюс нынешней разработки приложений.
Как ни крути, а время DOS и килобайтов оперативной памяти прошло. Вряд ли кто-то всерьез сейчас задумывается над тем куда это с винчестера пропал мегабайт? Да и использование в своих приложениях функциональности программ, которых ты не писал, но которые выполняют что-то лучше — это всё-таки больший прогресс, нежели корпеть год-два над программой, а потом узнать, что время-то прошло.
Введение
Итак, цель сегодняшней статьи — поделиться с Вами опытом работы с Microsoft Excel в приложениях, написанных на Delphi.
Вспомнился сейчас один случай. Когда я только начинал работать по своей специальности, пригласили меня написать программу-расчётник для экологов нашего нефтезавода. В принципе ничего серьёзного — программа считает выброс от нагревательной печи и выдает табличку результатов, которую необходимо распечатать и уложить в толстую папку с отчётами. Естественно, что в области разработки подобных приложения я далеко не пионер, поэтому дали взглянуть на аналог будущей программы, который работал ещё под DOS и печатались отчёты на дико скрипящем матричном принтере с 12-ю иголками. Ну посмотрел, элементарная таблица, расчёт немного запутан, но жить можно — начал по-тихоньку писать. И попалась мне тогда на глаза статейка про работу с Excel в Delphi. Вот я и решил попробовать выдавать отчёт не только на форму приложения, а ещё и скидывать весь ход расчёта с формулами и прочим делом в Excel…Надо сказать более сильно детской радости начальника отдела я не видел до сих пор :). Люди, всю жизнь проработавшие в DOS увидели как тот же самый расчёт может выглядеть в современных условиях. Вот теперь при определении технических заданий на каждую новую программу, обязательно присутствует пункт, гласящий, что программа должна передавать данные либо в MS Word либо в MS Excel.Соответственно и цена на разработку возрастает, иногда значительно.
Отсюда можно сделать простой и однозначный вывод — заказчики готовы пожертвовать лишними деньгами только для того, чтобы всё в программе было красиво. Excel может дать вашему приложению ту самую красоту и удобство.
Ну, а для того, чтобы каждый раз не утруждать себя выполнением однотипных операций, я разработал небольшой модуль для работы с Excel. Этот же модуль я в настоящее время дорабатываю под ещё одну задачу, но об этом после. Сегодня основы основ работы с Excel в Delphi.
1. Как проверить установлен ли Excel на компьютере пользователя?
Создаем новый модуль (unit) и подключаем в uses следующие модули:
Далее при раннем связывании идёт:
ExcelApp.ConnectTo( (OLEContExcel.OleObjectInterface as ExcelWorkbook).Application );
И всё работает, но при позднем связывании на этапе выполнения (оно и понятно) происходит ошибка:
Class EOleError with messages "Method "ConnectTo" not supported by. бла-бла"
ВотЪ! ):
clickmaker © ( 2004-09-24 14:40 ) [3]
> [2] П7 (24.09.04 14:33)
Открой delphi\ocx\servers\excel97.pas да посмотри реализацию этого connectto. Может, натолкнет на какие мысли
KSergey © ( 2004-09-24 14:54 ) [4]
На сколько я понимаю, ExcelApp.ConnectTo есть эквивалент GetActiveOleObject, либо (в случае отсутствия запущенного экземпляра) - CreateOleObject
← →П7 ( 2004-09-24 15:05 ) [5]
> clickmaker © (24.09.04 14:40) [3]
Открыл, посмотрел, ничего там такого интересного нету. Он передаёт полученный Application параметром в ConnectEvents. Этого метода так же нет. Ничего не понимаю. ):
> KSergey © (24.09.04 14:54) [4]
GetActiveOleObject возвращает ошибку, мол "не найден указанный источник объекта". Делаю так, может не правильно?
// бал-бал из предыдущего листинга
Excel.Run; // после этой строчки пишу
// тут возникает описанная ошибка
ExcelApp := GetActiveOleObject( "Excel.Application" );
GetActiveOleObject подключается к уже запущенному экземпляру; если его нет - понятно ошибка; стандартный ход на это
try
FWordApp := GetActiveOleObject ("Word.Application");
except
FWordApp := CreateOLEObject ("Word.Application");
end;
А вообще-то, я что-то потерялся: что получить-то надо?
← →Polevi © ( 2004-09-24 16:28 ) [8]
для листа вот так
procedure TForm1.FormCreate(Sender: TObject);
begin
OleContainer1.CreateObject("Excel.Sheet",false);
OleContainer1.AutoActivate := aaManual;
OleContainer1.DoVerb(ovShow);
end;
П7 ( 2004-09-24 16:45 ) [9]
> KSergey © (24.09.04 16:18) [7]
Не, теряться не нужно. У меня не получается показать созданный поздним связыванием ExcelApplication в OLE-контейнере. Вот и всё. Если я обычнм образом его создаю, то вместо того, чтобы появиться в ОЛЕ-контейнере, он открывает отдельное окно Excel"я и работает с ним. Оно и понятно, ведь на OLE-контейнер ничего не указывает.
В процессе извращений обнаружилась странная вещь. Если при созщдании, поздним связыванием, ExcelApplication"а поставить ему Visible в FALSE, то это Ёксель Аппликейшен начинает работать с уже открытым и показанным в OLE-контейнере экземпляром. Пока пользуюсь этим, но мне кажется, что это как-то не правильно.
В этой программе обращение к Excel происходит, в двух местах. При добавлении нового шаблона формы в программу и при вычислениях.
Разберём как происходит добавление формы в программу:
AssignFile ( DatFile , Main . ProgDir + '\dat\ ' + ChangeFileExt ( ExtractFileName ( OpenDialog1 . FileName ) , '.dat' ) ) ; //*
if ( Main . XLApp . WorkBooks [ 1 ] . WorkSheets [ k1 ] . Cells [ k3 , k2 ] . Style . Name = 'sum' ) then
if ( Main . XLApp . WorkBooks [ 1 ] . WorkSheets [ k1 ] . Cells [ k3 , k2 ] . Style . Name = 'set' ) then
if ( Main . XLApp . WorkBooks [ 1 ] . WorkSheets [ k1 ] . Cells [ k3 , k2 ] . Style . Name = 'mean' ) then
Main . XLApp . WorkBooks [ 1 ] . SaveAs ( Main . ProgDir + '\forms\ ' + ExtractFileName ( OpenDialog1 . FileName ) ) ; //*
IniFile . WriteString ( 'ListForms' , IntToStr ( length + 1 ) , ChangeFileExt ( ExtractFileName ( OpenDialog1 . FileName ) , '' ) ) ;
*Плагин отображающий код не правильно отображает символы \’ поэтому между этими символами я поставил пробел в действительности этот пробел не нужен
Добавление формы происходит при нажатии кнопки. После этого должен открыться экселевский файл, в котором проверяются все заполненые ячейки на наличие ячеек со стилями sum, mean и set. Позиции данных ячеек записываются в файл, для дальнейшего использования.
Рассмотрим код по подробнее:
в этой роцедуре мы будем пользоваться переменной XLApp типа — variant.
Объявленной в классе TMain — unit Statistic_U;
Так же мы объявляем Файл данных. Тип данных будет integer
Что бы начать работать с OLE объектами надо для начала создать Com объект:
Синтаксис этой функции следующий: function CreateOleObject(const ClassName: string): IDispatch;
Тоесть в функции мы указываем имя класса ClassNam в виде string а на выходе функции мы получаем ID данного объекта.
Дальше мы может открыть файл Excel который мы выбрали в самом начале нашей процедруры:
Данную операцию мы проделываем используя метод Open Рабочей книги:
Данный метод имеет следующий ситнтаксис: .Open(FileName, UpdateLinks, ReadOnly, Format, Password, WriteResPassword, IgnoreReadOnlyRecommended, Origin, Delimiter, Editable, Notify, Converter, AddToMru, Local, CorruptLoad)
FileName — имя файла который надо открыть.
UpdateLinks — этот параметр указывает как поступить с ссылками на другие файлы, по умолчанию при открытии пользователю будет задаваться вопрос.
ReadOnly — если указано, как true. То файл будет открыт только для чтения.
Format — если открывается текстовый документ, то в этом параметре можно указать символ разделитель, иначе используется символ разделитель по умолчанию.
Password — если книга защищена от просмотра, то здесь можно указать пароль в виде строки(type String), по умолчанию пользователю будет задан вопрос.
WriteResPassword — Если в файле стоит пароль на запись, а нам надо изменить данные, то здесь можно указать пароль в виде строки. По умолчанию пользователю будет задан вопрос.
Origin — Если открывается текстовый файл, то здесь можно указать место его создания есть три варианта : xlMacintosh, xlWindows, or xlMSDOS. По умолчанию будет использоваться текущая операционная система. Этот параметр помогает правильно определить конец строки.
Delimiter — Здесь можно указать символ разделитель для вкладок. При этом если внести строку то будет использоваться первый символ.
Editable — Данная настройка не работае для версий Microsoft Excel 5.0 и выше. Она определяла состояние видимости документа после открытия.
Notify — если необходимо открыть файл на чтение, но это не возможно то при указании этого значения в true файл добавится в список уведомлений, и когда это станет возможным пользователю отобразится уведомление. При значении false файл не сможет открыться.
Converter — с помощью данного аргумента можно использовать файлы конвертеры.
AddToMru — если значение указано как true книга добавится в список недавно открывавшихся, по умолчанию стотит false.
Local — при использовании значения true сохраняет файлы с языковыми настройками Microsoft Excel (включая параметры панели управления). При указании значения false— сохранение файлов с языковыми настройками Visual Basic. По умалчанию используется сохранение файлов с языковыми настройками Visual Basic.
CorruptLoad — принимает три значения xlNormalLoad (0) рабочая книга открывается «Нормально» , xlRepairFile (1) рабочая книга открывается в режиме восстановления, xlExtractData (2) рабочая книга открывается в режиме извлечения данных.
Дальше мы открываем файл с данными для записи в файл получаемых значений, но так как статья об OLE объектах мы не будем подробно описывать:
Компонент delphi OleContainer это компонент, обеспечивающий внедрение и связывание. Сразу вас предупреждаю, что применение этого компонента далеко не лучший способ использования OLE. В частности, нередко возникают определенные проблемы с этим компонентов в современных версиях Delphi. Лучше работать с серверами автоматизации OLE, о которых будет сказа в следующих статьях. Но для понимания сути использования этого компонента рассмотрю пример его применения на создания простого приложения.
Разместите на форме контейнер OleContainer, компонент главного меню MainMenu, и диалог OpenDialog. Контейнер должен занимать всю площадь формы, поэтому свойство Align делаем равным alClient. Пример этого приложения приведен на рисунке 1.
В MainMenu введите меню файл и в нем разделы открыть, активировать и деактивировать.
Теперь необходимо прописать обработчики событий для нашего меню.
Открыть
procedure TForm1 . N2Click ( Sender : TObject ) ;
begin
if OpenDialog1 . Execute then
OleContainer1 . CreateObjectFromFile ( OpenDialog1 . FileName , false ) ;
end ;
Активировать
procedure TForm1 . N4Click ( Sender : TObject ) ;
begin
if OleContainer1 . State < ; > ; osEmpty then
OleContainer1 . DoVerb ( ovShow ) ;
end ;
Деактивировать
procedure TForm1 . N5Click ( Sender : TObject ) ;
begin
if OleContainer1 . State < ; > ; osEmpty then
OleContainer1 . Close ;
end ;
Меню открыть вызывает метод InsertObjectDialog осуществляющий обращение к стандартному окну Windows Insert Object (вставка объекта), в котором пользователь может указать тип вставляемого объекта, инициализирует объект OLE и загружает его в контейнер OleContainerl. Меню активировать, вызывает Метод DoVerb обеспечивающий немедленное открытие программы, связанной со вставленным документом(запускает в нашем приложение OLE-сервер необходимый для редактирования файла). Типичными OLE-серверами являются такие системные утилиты, как Notepad, Paint и текстовый процессор Word, табличный процессор Excel и др. Меню деактивировать деактивирует OLE-сервер.
После запуска нашего приложения нажимаем файл и открыть, выбираем необходимый файл в моем случае я выбрал файл Word. Наше приложение открывает Word файл но его нельзя редактировать (рис. 2).
После нажатия активировать в меню файл в нашем приложении открывается MS Word после чего доступны все его функции (рис.3)
Продолжаем изучать Delphi
MediaPlayer Компонент delphi MediaPlayer обеспечивает воспроизведение звуковых файлов различных форматов (WAV, M.
PaintBox Компонент delphi PaintBox это область рисования. Компонент визуальный и используется для создания на.
Timer Компонент Delphi Timer генерирует последовательность событий timer, этот компонент является не визуа.
OleContainer Компонент delphi OleContainer это компонент, обеспечивающий внедрение и связывание. Сразу вас предуп.
Освоение принципов использования технологии OLE в среде Delphi.
Изучение свойств объекта OleContainer.
Получение практических навыков работы объектно-ориентированного программирования.
Вопросы для коллоквиума.
1. Что представляет собой технология OLE.
2. Укажите назначение компонента компонент OleContainer.
3. Перечислите свойства компонента OleContainer.
4. Укажите назначение OLE Контейнера.
Порядок выполнения работы.
- Создайте новый проект.
- Бросьте на форму компонент OleContainer с закладки System палитры компонентов. Теперь дважды щёлкните внутри окна компонента (или щёлкните правой кнопкой и в появившемся меню выберите пункт Insert Object). Перед вами откроется следующее окно:
- В этом окне, в списке «Тип объекта» найдите строку «Рисунок PaintBrush». Выделите эту строку. Если поставить галочку «В виде значка», то на форме вы потом увидите только значок объекта, а по двойному щелчку будет запускаться выбранное приложение (PaintBrush). Если галочки нет, то приложение встраивается прямо в окно.
- Запустите программу и дважды щёлкнуть внутри компонента OLEContainer. Компонент будет взят в рамочку и вы сможете рисовать в нём как в самом PaintBrush.
- Таким способом мы встроили стороннее приложение в свою программу.
- Для добавления меню в ваше приложение бросьте на форму компонент MainMenu. Туда не надо добавлять никаких пунктов, достаточно просто его бросить. Если у формы есть главное меню, то OLE компонент будет автоматически встраиваться в него.
- Запустите программу и убедитесь, что меню появляется.
- Теперь измените свойство Align у компонента OleContainer1 на alClient, чтобы растянуть его по всей форме. Запустите программу и посмотрите на результат. Теперь ваше приложение превратилось в полноценный PaintBrush. Единственное, что отличает его – заголовок окна и иконка Delphi.
- Создайте в нашем главном меню два пункта Файл и Правка. У обоих пунктов добавьте подпункты Выход и Копировать.
- Теперь запустите программу и посмотрите на результат. Когда вы пытаешься активизировать OLE объект, то меню Файл остаётся ваше, а аналогичное из программы PaintBrush исчезает. К тому же у вас должно получиться два пункта Правка. Пункты меню, у которых в свойстве GroupIndex стоит чётное значение (0, 2, 4 …) – остаются неизменными. Пункты меню, у которых GroupIndex нечётное – заменяются аналогичными из OLE объекта. Попробуйте поставить у пункта Правка в свойстве GroupIndex значение 1 и запустите программу. Теперь при активизации OLE объекта пункт меню «Правка» будет заменён аналогичным из объекта.
- Изменим наш пример. Добавьте на форму одну панель TToolBar(вкладка Win32) и бросьте на неё набор кнопок:
- Вставить из файла
- Сразу же изменим одно его свойство – дважды щёлкните по свойству EdgeBorders и измените свойство ebTop на false. Это заставит исчезнуть оборочку сверху панели.
- Измените свойство AutoSize на true, чтобы панель принимала размеры соответствующие кнопкам.
- Теперь создадим кнопки на панели. Для этого щёлкните по ней правой кнопкой мыши и выберите из появившегося меню пункт New Button. Пункт New Separator этого же меню создаёт разделитель между кнопками. Если вам нужно будет удалить кнопку или разделитель, то просто выделите его и нажмите кнопку Del (на клавиатуре ).
Таким образом создайте все кнопки вместе с разделителями. У вас должно получиться нечто похожее на рисунок:- Теперь необходимо сделать так, чтобы кнопки что-то отображали. Но для начала выделите саму панель и изменить свойство Flat на true, чтобы кнопки на панели выглядели более изящно (плоско).
- Теперь бросьте на форму компонент TImageList(вкладка Win32) и добавьте в него картинки.
- Выделите панель и в свойстве Images укажите созданный набор картинок. На кнопках сразу же отобразятся картинки в той последовательности, в которой вы их добавили. Если вы хотите изменить картинку на какой-нибудь кнопке, то надо выделить её и изменить свойство ImageIndex.
- Теперь для каждой кнопки в свойстве Caption напишите осмысленный текст (по умолчанию там стоит текст ToolButton плюс порядковый номер кнопки). Желательно, чтобы текст соответствовал изображению на картинке.
- Если хотите, чтобы панель отображала на кнопках не только картинки, но и указанный в свойствах Caption текст установите true в свойстве ShowCaptions у панели инструментов. (Если ещё установить свойство List у панели инструментов, то текст будет отображаться справа от картинки)
- У вас должна получится форма приблизительно такого вида:
procedure TForm1.ToolButton1Click(Sender: TObject);
- Теперь, после нажатия этой кнопки, программа будет отображать уже знакомое вам окно, с помощью которого можно будет сменить OLE объект на другой.
- По нажатию второй кнопки (свойства объекта) пишем следующий код:
procedure TForm1.ToolButton2Click(Sender: TObject);
Этим кодом мы будем отображать окно свойств объекта.
- По нажатию кнопки «Вставить из файла» пишем следующий код:
procedure TForm1.ToolButton4Click(Sender: TObject);
if OpenDialog1.Execute then
- Так как в для открытия файла требуется компонент OpenDialog, бросьте его на форму.Как только пользователь выбирает файл, создается объект на основе выбранного файла. Попробуйте запустить приложение и открыть bmp, doc или xls файл. Как только вы нажмёте кнопку «Открыть», так сразу перед вами появиться соответствующий выбранному файлу OLE объект. Если вы выберете doc файл, то запуститься Word.
- По нажатию кнопки «Открыть объект» пишем следующий код:
procedure TForm1.ToolButton4Click(Sender: TObject);
Здесь мы открываем объект из указанного файла. В качестве имени файла используем ‘ole.dat’.
- По нажатию кнопки сохранить мы пишем следующее:
procedure TForm1.ToolButton4Click(Sender: TObject);
Здесь мы сохраняем объект в тот же файл ‘ole.dat’. Файл созданный OLE объектом не совместим с форматом самой программы объекта. Это значит, что ole.dat – это не bmp картинка, хотя и bmp – это родной формат для программы PaintBrush. Так что вы не сможете открыть файл ole.dat с помощью PaintBrush.
procedure TForm1.ToolButton11Click(Sender: TObject);
Здесь мы закрываем запущенный OLE объект. Если пользователь дважды щёлкнул по контейнеру, то OLE объект запускается и закрыть его можно с помощью этой кнопки.
Читайте также: