Delphi olecontainer excel одновременная работа

Обновлено: 07.07.2024

В этой программе обращение к Excel происходит, в двух местах. При добавлении нового шаблона формы в программу и при вычислениях.

Разберём как происходит добавление формы в программу:

procedure TFOptions . Button3Click ( Sender : TObject ) ; //Предварительная обработка шаблона Main . XLApp . WorkBooks . Open ( OpenDialog1 . FileName ) ; AssignFile ( DatFile , Main . ProgDir + '\dat\ ' + ChangeFileExt ( ExtractFileName ( OpenDialog1 . FileName ) , '.dat' ) ) ; //* for k1 := 1 to Main . XLApp . Workbooks [ 1 ] . WorkSheets . Count do for k2 := 1 to Main . XLApp . WorkBooks [ 1 ] . WorkSheets [ k1 ] . UsedRange . Columns . Count do for k3 := 1 to Main . XLApp . WorkBooks [ 1 ] . WorkSheets [ k1 ] . UsedRange . Rows . Count do 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 := TIniFile . Create ( Main . ProgDir + '\Statistic.ini' ) ; length := IniFile . ReadInteger ( 'ListForms' , 'length' , length ) ; IniFile . WriteInteger ( 'ListForms' , 'length' , length + 1 ) ; IniFile . WriteString ( 'ListForms' , IntToStr ( length + 1 ) , ChangeFileExt ( ExtractFileName ( OpenDialog1 . FileName ) , '' ) ) ;

Добавление формы происходит при нажатии кнопки. После этого должен открыться экселевский файл, в котором проверяются все заполненые ячейки на наличие ячеек со стилями sum, mean и set. Позиции данных ячеек записываются в файл, для дальнейшего использования.

Рассмотрим код по подробнее:

Так же мы объявляем Файл данных. Тип данных будет integer

Что бы начать работать с OLE объектами надо для начала создать Com объект:

Синтаксис этой функции следующий: function CreateOleObject(const ClassName: string): IDispatch;

Тоесть в функции мы указываем имя класса ClassNam в виде string а на выходе функции мы получаем ID данного объекта.

Дальше мы может открыть файл Excel который мы выбрали в самом начале нашей процедруры:

Данную операцию мы проделываем используя метод Open Рабочей книги:

Main . XLApp . WorkBooks . Open ( OpenDialog1 . FileName ) ;

Данный метод имеет следующий ситнтаксис: .Open(FileName, UpdateLinks, ReadOnly, Format, Password, WriteResPassword, IgnoreReadOnlyRecommended, Origin, Delimiter, Editable, Notify, Converter, AddToMru, Local, CorruptLoad)

Дальше мы открываем файл с данными для записи в файл получаемых значений, но так как статья об OLE объектах мы не будем подробно описывать:

Фантастика. Мало того, что это именно то, что спрашивает автор
и что ему действительно нужно, так это единственно-возможный
адекватный вариант - Close всё равно так или иначе не обойти,
что с Save/Changed, что без. Но не видишь, так не видишь.

Posted via ActualForum NNTP Server 1.5

Добрый день, спасибо, что помогаете! Всё сделано через OLE-контейнер.

вод код создания контейнера:

А, ну так это проще, чем чистый COM, кодить меньше.
Досконально не проверял, но должно работать:

Можно было бы ещё через IOleClientSite.OnShowWindow,
но во-первых, это несколько длиннее выйдет, во-вторых,
это идеологически неправильный путь решения задачи.

Если чего не получится - скажи.

Posted via ActualForum NNTP Server 1.5

Как я и писал смысл всего этого в автоматическом сохранении изменённого документа в БД. Т.е. после отлова события закрытия документа я должен его покласть в БД. Я стал использовать как Вы писали тут: procedure TForm1.OnClose;

вот код сохранения в БД изменённого документа.

получается что идёт процесс закрытия документа Excel и он недоступен. немогу понять что делать. Теперь есть вариант отлова закрытия документа, но пропал вариант сохранения документа в БД.

Что сейчас делать - ну либо исправлять приведённый код,
в частности, на момент его работы лист/документ/сервер
может быть недоступен (не знаю, надо разбираться), либо
попробовать сохранять содержимое уже OleContainer-а
(я уже показывал на форуме с готовым кодом, поищите) -
для xlsx-версий может и не будет работать, но для xls
будет работать точно. Отдельно отмечу, что файл тут,
по идее, лишний и нежелательный.

Posted via ActualForum NNTP Server 1.5

Код, да, далёк от идеала, и что тут обижаться… с контейнером связался впервые. Мало кто знает, как он вообще работает. Я пытался найти вариант, кок можно Excel документ из контейнера покласть сразу в БД без выгрузки его во временный файл, но всё безуспешно… задавал вопрос на форуме на эту тему, единственный ответ который получил, сохранять через COMObj во временный файл. Вообще пару человек писали, что только через временный файл это сделать и можно, других вариантов нет. На других форумах находил примерно аналогичные топики, которые так и оставались без ответа…

Что касается ошибки "Interface not supported", согласен, он к Вашему коду ни какого отношения не имеет. Это появилось как следствие того, что при перехвате события о закрытии документа Excel, документ находиться в каком-то промежуточном состоянии он и не открыт и не закрыт и любые попытки обратиться к COMObj контейнера сводиться именно к этой ошибке (Interface not supported).

«Про то, что Вы зачем-то сохраняете только один лист, а не
весь документ я молчу, так и быть.»))) Заменить на строчку сохранения всего документа проблем нет… дело в том что сохранение листа занимает примерно на 15-20 кило меньше… возможно я не прав в том, что хочу уменьшить объём хранимых данных и не наткнутся на подводный камень))))

Posted via ActualForum NNTP Server 1.5

Спасибо за топик! Нашёл ещё с утра… но там описание про то как Вы демонстрируете загрузку документа Excel из БД в контейнер, а не процесс сохранения документа из контейнера обратно в БД без временного файла. Может есть другой топик? (но я больше ничего подобного не нашёл).

У контейнера есть метод сохранения в «стрим» , но я так понимаю он в свой собственный формат сохраняет содержимое контейнера… и как тут обойтись без временного файла?

Posted via ActualForum NNTP Server 1.5

Posted via ActualForum NNTP Server 1.5

Пробовал разными способами, несколько раз переписывал код… не получается… конечно многого я ещё недопонимаю. Без Вашей помощи не справлюсь!

Вот что у меня получилось на данный момент (ессно код нерабочий, слетает на StgOpenStorageOnILockBytes, пишет что "1% уже существует."):

Всем добрый вечер. Если кто в курсе – подскажите. При работе программы создаю в ней вторую форму, открываю в ней Olecontainer с встроенным пустым файлом Word. Цель – лень заполнять ручками (набивать) данные. Их же можно скачать из уже готового другого файла и вставить (есть необходимость вставить заполненную таблицу и потом уже раскидать значения из ее ячеек там, где надо). Вторая форма создается – все хорошо. В файл в Olecontainere таблица вставляется – все хорошо. Но при сохранении файла из Ole - сохраняется пустой исходник.

Проблема: Документ 11 остается такой же, как и был документ 1. Все изменения исчезают. Если в файле 1 изначально есть текст – он и переходи в файл 11. То есть процесс открытия файла, считывания, закрытия и сохранения как бы работает. Заранее спасибо. __________________
Помощь в написании контрольных, курсовых и дипломных работ здесь


Работа с OleContainer и FileListBox
Парни такая проблема пишу дипломную , Завис на работе ФайллистБокса и Олеконтайнера . Вывожу.

Работа с Excel и OleContainer
Доброго всем времени суток, помогите сделать вот что: у меня на форме есть 2 кнопки и OleContainer.

Olecontainer
Как убрать меню в word при отображении в olecontainer delphi.

OleContainer
Здравствуйте. Нарисовал курсором линию на OleContainer. Сделал прог.что-бы опознала точки линии на.

вводите данные в программу и сами делайте документ Word
и не нужно этого геморроя и оле-контейнеров Жалко терять время на нудную и неэффективную работу - заново набирать руками уже набранные таблицы. не надо набирать. надо только те данные, которые вводить, ввести в уже готовые шаблоны
но для этого не нужно открывать Word Во-первых, что бы найти готовую таблицу, из которой я должен взять информацию - Word открыть уже нужно. В идеале я бы выделил таблицу прямо в документе, скопировал бы ее в буфер и уже из него брал бы по кусочкам. Но я пока не нашел такой возможности. Кинуть таблицу в буфер можно, а вот выдрать из нее значения ячеек и скопировать каждое в нужном направлении (каждое в свой Edit, например). Только примерно. Например - состав компьютера - системный блок, монитор, клавиатура, мышь и принтер. Состав меняется редко, и комп, собранный 2-3 года назад при переучете набирать заново. А так скопировал - и готово. у вас в коде происходит странное
сначала вы создаете один объект

какая вообще связь между vWord и oleobj1 .

1. я создаю объект Word ( vWord := CreateOleObject('Word.Application'). Без этого никак.
2. Объявляю в Oleconteiner присоединение файла Word; То же вроде все правильно.
3. Присоединяю к Ole (открываю в окне Ole) конкретный файл Word (у меня файл "1.docx"). Файл открывается. Вижу контрольную надпись "Файл-источник", которая была в файле изначально;
4. Вношу изменения в файл. Вставляю таблицу, текст, вношу правки - все работает, как в обычном Wordе. Даже если в подготовительных операциях (№№ 1-3) я что-то делал не так - неважно, все работает.
5. Пытаюсь после выхода документа Word из Ole закрыть файл с изменениями. Что и не получается.

Я пробовал разные варианты - пытался и сначала выйти из Ole, затем сохранить файл Word, закрыть Word, закрыть Oleconteiner. И сначала сохранить документ в Word, потом выйти из Ole, закрытьWord, закрыть Ole.
В самом лучшем случае файл сохраняется с другим названием (становится 11.docx). Но изменения, внесенные прямо в Ole (п.4), в файле не сохраняются.
Я бы пошел по другому пути - открыть файл Word, выделить в нем таблицу (скопировать ее в буфер обмена), и пытаться уже из него копировать нужную информацию по-ячейкам. Текст и картинки так обрабатывать можно - масса примеров с объяснениями. Как вытащить информацию из ячейки таблицы - пока не нашел.

Добавлено через 3 минуты
Только что увидел одну свою глупость. Я Olecontainer обозвал Oleobj. Из-за этого есть непонятки. Хотя на работу не влияет.

тебе в посте №8 уже указали на причины: ты создаешь ДВЕ переменных. изменения проводишь в одной, а сохраняешь файл из другой. какие еще вопросы? ты уже создал объект vWord - вот и работай в нем, на кой еще oleobj1?

Добавлено через 56 секунд
а если ты изменения проводишь в oleobj1, так и СОХРАНЯЙ тоже oleobj1

Компонент delphi OleContainer это компонент, обеспечивающий внедрение и связывание. Сразу вас предупреждаю, что применение этого компонента далеко не лучший способ использования OLE. В частности, нередко возникают определенные проблемы с этим компонентов в современных версиях Delphi. Лучше работать с серверами автоматизации OLE, о которых будет сказа в следующих статьях. Но для понимания сути использования этого компонента рассмотрю пример его применения на создания простого приложения.

Разместите на форме контейнер OleContainer, компонент главного меню MainMenu, и диалог OpenDialog. Контейнер должен занимать всю площадь формы, поэтому свойство Align делаем равным alClient. Пример этого приложения приведен на рисунке 1.

Пример компонента OleContainer

В MainMenu введите меню файл и в нем разделы открыть, активировать и деактивировать.
Теперь необходимо прописать обработчики событий для нашего меню.

Открыть

Активировать

Деактивировать

Меню открыть вызывает метод InsertObjectDialog осуществляющий обращение к стандартному окну Windows Insert Object (вставка объекта), в котором пользователь может указать тип вставляемого объекта, инициализирует объект OLE и загружает его в контейнер OleContainerl. Меню активировать, вызывает Метод DoVerb обеспечивающий немедленное открытие программы, связанной со вставленным документом(запускает в нашем приложение OLE-сервер необходимый для редактирования файла). Типичными OLE-серверами являются такие системные утилиты, как Notepad, Paint и текстовый процессор Word, табличный процессор Excel и др. Меню деактивировать деактивирует OLE-сервер.

После запуска нашего приложения нажимаем файл и открыть, выбираем необходимый файл в моем случае я выбрал файл Word. Наше приложение открывает Word файл но его нельзя редактировать (рис. 2).

Отрытый файл Word в компонент OleContainer

После нажатия активировать в меню файл в нашем приложении открывается MS Word после чего доступны все его функции (рис.3)

Читайте также: