Delphi word замена текста

Обновлено: 04.07.2024

Когда вы первый раз заходите с помощью соцсетей, мы получаем публичную информацию из вашей учетной записи, предоставляемой провайдером услуги соцсети в рамках ваших настроек конфиденциальности. Мы также автоматически получаем ваш e-mail адрес для создания вашей учетной записи на нашем веб сайте. Когда она будет создана, вы будете авторизованы под этой учетной записью. Когда вы первый раз заходите с помощью соцсетей, мы получаем публичную информацию из вашей учетной записи, предоставляемой провайдером услуги соцсети в рамках ваших настроек конфиденциальности. Мы также автоматически получаем ваш e-mail адрес для создания вашей учетной записи на нашем веб сайте. Когда она будет создана, вы будете авторизованы под этой учетной записью.

Спасибо, попробую сегодня. А для чего тебе вообще из программы в Word пересылку делать? Отчеты что ли там формируют? Просто для этого вроде более удобные способы есть. Хотя заказчикам все подряд нужно. :-)

Интересует формирование отчётов не через OLE в ворд, а через создание XML документа, который ворд откроет.

Меня тоже интересует :) Попробую чего-нибудь написать по тому поводу

Очень интересный подход, а я в дельфи так и не смог этого сделать

Здравствуйте. Подскажите, пожалуйста, как подавить диалоговое окно на сохранение документа? Пол дня уже не могу сделать.

Про которое окно идет речь? Если про то, что выскакивает, когда Вы пытаетесь закрыть Ворд из своей программы, то при создании объекта надо написать так:
var Word: OLEVariant
begin
[. ]//создаем объект
Word.DisplayAlerts:=wdAlertsNone
end;
DisplayAlerts может принимать одно из следующих значений:
wdAlertsAll -1
wdAlertsMessageBox -2
wdAlertsNone 0

Вот привожу листинг из макроса, для вставки таблицы, то ничего не понятно.

Спасибо, через компоннеты не помогло, а тут все так просто)

srg91,
[code]Word.Quit;
UnAssigned(Word)[/code]

В Delphi-приложении вроде бы никак. Или я просто не встречал программ, способных такое сделать.

Понял, спасибо.
Еще вопрос есть.
RichEdit и RxRichEdit как-то странно ссылки в тексте отображают.
В открываемом RTF ссылки нормальные:
например:

а когда открываю RTF в своей программке, ссылки имеют такой вид:

Почему так? И можно ли привести их в нормальный вид?

Подскажите пожалуйтса.
У меня в программе нужно открыть Word на определенной закладке.
Когда работал в Delphi 7 я это сделал с помощью Ole,
Перешел на 2010 и не могу это сделать. И вообще нет компонентов с Word.
Подскажите плиз!

to Vlad
слушай подсади нубу как в ворде через делфи вставить ТАБ
такая команда не работает, а точнее компилятор не пропускает, команду взял из макроса:

[code]
var
word_stud:Variant;
word_stud.Selection.TypeText Text:=vbTab;
[/code]
За ранее спасибо!


подскажите пожалуйста:
мне необходимо записать из поля edit информацию в word при том, чтобы word он не открывался.
спасибо

можно просто не показывать видимость документа:
w.visible:=false;

В один документ надо вставить с определенной позиции весь текст другого документа. Как это сделать? Пишет слишком длинная строка.

НЕ подскажете можно ли из дельфи вставить и редактировать формулы в Word Т.е. работа с редактором формул. Или это не реально?

Через OLE-контейнеры вроде бы можно было, но сам никогда над такими вещами не работал

Понятно. Спасибо за отклик. Придется тогда шаблон использовать. А хотелось конечно все программно сделать

Подскажите, как можно создать базу данных, состоящую из документов word в delphi?

преподаватель задал вот такую задачку)

Помогите, не могу создать путь чтобы открыть документ

Word.Documents.Open(D:\. . . \. . . docx:=FilePath, ReadOnly:=true) Что тут не так.

Серега, всё не так. Во-первых почему первый параметр задом наперед стоит? Во-вторых, почему в пути к файлу кодировка сбита?

нахожу в документе нужное слово с помощью метода FIND объекта SELECTION. Как теперь перед найденным словом перевести каретку (аналогично нажатию клавиши ENTER)?
И ещё, как после нахождения искомого слова выделить следующий за ним фрагмент текста?
Заранее благодраю!

Спасибо! Я только только начал заниматься вопросами автоматизации обработки документов и сразу же встретился с массой трудностей. В инете ничего конкретного. Я был бы вам признателен, если бы вы подсказали мне какой-нибудь ресурс или ссылку на источник, где более или менее освещен данный вопрос (к слову, известная многим книга В.Корнякова мне не очень помогла).

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

Поиск текста по документу и замена его на свой текст
Вот есть маркер в Вворде типа $FIO$-2е штуки. В одну надо записывать Фамилию Имя Отчество полностью.


Поиск и замена в MS Word
Dim Word As Object Word = CreateObject("Word.Application") .

Это функция ворда. Пофиг из чего ее вызывать.

Главный "скилл" - это умение писать свой код, а не переписывать откуда бы то ни было. Открываем документ MS Word, в котором необходимо выполнить сию операцию, открываем вкладку "РАЗРАБОТЧИК" (если она не включена, в интернете куча инфы как её сделать видимой). На данной вкладке выбираем "Запись макроса", вводим (или запоминаем) имя макроса, и выполняем то, что хотим видеть в итоге. Останавливаем запись макроса. Нажимаем кнопку "Макросы", в списке ищем записанный макрос и нажимаем кнопку "Изменить". Вуаля, перед нами код макроса для MS Word, правда написанный на Visual Basic. НО. Там чётко видна объектная модель выполняемых операций.
Пример - был открыт произвольный документ, в котором сочетанием клавиш "CTRL+H" введён текст для поиска и текст для замены, выполнена замена найденного текста.
Код выглядит так:
Далее создаём проект и используя OLE-объектную модель MS Word выполняем сие творение.
Справку по объектной модели MS Word можно найти на официальном сайте. но нигде прям не нашёл какого то решения или примера Обычно так говорят те, кто даже не пытался что-то найти. А если бы пытались, только на этом форуме нашли бы, как минимум, это или это

А можно узнать, почему? Та причина, что Вы озвучили выше, это извините, просто ерунда. Какая разница, сколько закладок будет, ведь их будет ровно столько же, сколько и строк для замены. Главное - систематизировать их.
Вот пример: есть такой вот шаблон со следующим набором закладок:

в моем случае во все закладки, которые имеют префикс z1 будет вставлена дата из DateTimePicker, в закладки с префиксом z2 - текст из Edit1 и в закладки с префиксом z3 - текст из Edit2
В итоге, после выполнения следующего кода

получается вот такой документ


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

В предыдущей заметке "Поиск и замена текста в документе MS Word из Delphi" я рассказывал, как дорабатывал старый модуль, который генерирует клиентам компании письма в формате MS Word с помощью поиска и замены текста. Сдав модуль заказчикам, я в свободное от работы время, переделал его. Вместо поиска и замены использовал поля с переменными (DocVariable).
В шаблон письма с помощью макроса добавил переменные

Sub AddFields()
ThisDocument.Variables.Add "FIO", "FIO"
ThisDocument.Variables.Add "ADDRESS", "ADDRESS"
.
End Sub

Var
wa: WordApplication;
ovDotName, ovFileName: OleVariant;
i: Integer;
q: TSDQuery;
.
begin
.
wa := CreateComObject(CLASS_WordApplication) as _Application;
ovDotName := 'какой то шаблон.dot';
wa.Documents.Add(ovDotName, EmptyParam, EmptyParam, EmptyParam);

For i := 0 to q.FieldCount-1 do
MSWordSetVariable(q.Fields[i].FieldName, q.Fields[i].AsString);
.
ovFileName := 'письмо любимому клиенту.doc';
wa.ActiveDocument.SaveAs(ovFileName, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam);
.

procedure MSWordSetVariable(ovVariable: OleVariant; const sValue: String);
begin
If sValue = ''
then wa.ActiveDocument.Variables.Item(ovVariable).Value := ' '
else wa.ActiveDocument.Variables.Item(ovVariable).Value := sValue
end; Если переменной MS Word присвоить пустую строчку, то в поле выводится текст 'Ошибка! Переменная документа не указана.', поэтому вместо пустого значения я присваиваю ей пробел (так же делает и сам MS Word). Это связано со странной работой MS Word с коллекцией переменных. Если переменной присвоить пустую строку, то количество переменных в коллекции (Variables.Count) уменьшается на единицу, а попытка удалить переменную (Variables.Item(ovVariable).Delete) дает ошибку 'Объект был удален', т.е. присвоение пустой строки равносильно удалению. При этом после удаления переменной из коллекции переменных, присвоение ей непустого значения выполняется успешно и количество переменных в коллекции увеличивается на единицу, т.е. присвоение непустого значения равносильно вызову метода добавления переменной в коллекцию переменных.
Продемонстрирую вышесказанное примером кода, по которому видно как изменяется количество переменных (iCount): iCount := wa.ActiveDocument.Variables.Count; // iCount = 3
wa.ActiveDocument.Variables.Item(ovVariable).Value := '';
iCount := wa.ActiveDocument.Variables.Count; // iCount = 2
wa.ActiveDocument.Variables.Item(ovVariable).Value := 'не пусто';
iCount := wa.ActiveDocument.Variables.Count; // iCount = 3
wa.ActiveDocument.Variables.Item(ovVariable).Delete;
iCount := wa.ActiveDocument.Variables.Count; // iCount = 2
wa.ActiveDocument.Variables.Item(ovVariable).Value := 'не пусто';
iCount := wa.ActiveDocument.Variables.Count; // iCount = 3
wa.ActiveDocument.Variables.Item(ovVariable).Value := '';
iCount := wa.ActiveDocument.Variables.Count; // iCount = 2
wa.ActiveDocument.Variables.Item(ovVariable).Delete; // ошибка 'Объект был удален'

Вот такая логика у индусов, писавших этот кусок MS Word.

После присвоения значений всем переменным, осталось только дать команду полям обновиться новыми значениями переменных. Для этого в VBA у коллекции объектов полей (Fields) есть метод Update:

А для того, чтобы избежать дальнейшего обновления полей, избавимся от их связи с переменными:

У каждого структурного элемента документа (заметки, колонтитула, сноски и т.д.) своя коллекция объектов полей, поэтому, если документ, как у меня, состоит из разных структурных элементов, то методы Update и Unlink необходимо вызвать для каждого из этих элементов. Для этого перебираем все элементы коллекции StoryRanges.

procedure MSWordUpdateStoryRanges;
Var
StoryRanges: Word2000.StoryRanges;
StoryRange: Word2000.Range;
iStoryIndex: integer;
Begin
StoryRanges := wa.ActiveDocument.StoryRanges;
For iStoryIndex := wdMainTextStory to wdFirstPageFooterStory do
Try
StoryRange := StoryRanges.Item(iStoryIndex);
If StoryRange <> nil then
begin
StoryRange.Fields.Update;
StoryRange.Fields.Unlink;

While (StoryRange.NextStoryRange <> nil) do
begin
StoryRange := StoryRange.NextStoryRange;
StoryRange.Fields.Update;
StoryRange.Fields.Unlink;
end;
end;
Except
StoryRange := nil;
End;
End;

Т.к. в моем шаблоне есть только основной текст и одна заметка, то вместо процедуры, которая перебирает все элементы коллекции StoryRanges, я сделал процедуру, которая работает только с одним ее элементом: procedure MSWordUpdateStoryRange(const iStoryIndex: integer);
Var
StoryRange: Word2000.Range;
begin
Try
StoryRange := wa.ActiveDocument.StoryRanges.Item(iStoryIndex);
If StoryRange <> nil then
begin
StoryRange.Fields.Update;
StoryRange.Fields.Unlink;
end;
Except
End;
end;

И вызываю ее перед сохранением документа.

Все бы ничего, но часть текста передаваемого из программы в MS Word необходимо было выводить жирным шрифтом. А это через переменные не сделать :( В подобном случае "поиск и замену текста" можно заменить на "переход к закладке и вывод текста". Например, в шаблон вставляем закладку с именем 'писать текст сюда', а в программе пишем:

Var
ovBookmarkName, ovWhat: OLEVariant;
begin
ovWhat := wdGoToBookmark;
ovBookmarkName := 'писать текст сюда';
Try
If wa.Selection.GoTo_(ovWhat, EmptyParam, EmptyParam, ovBookmarkName) <> nil then
begin
wa.Selection.TypeText('просто текст ');
wa.Selection.Font.Bold := 1;
wa.Selection.TypeText('жирный текст');
wa.Selection.Font.Bold := 0;
wa.Selection.TypeText(' просто текст');
end;
Except
End;

Вот и все :)
Раннее связывание и использование полей/закладок дало существенный рост скорости генерации писем. Если на 500-х различных документах этого было почти не заметно, то при генерации 15 000 документов, прирост скорости составил 30% (специально проверил несколько раз на одних и тех же исходных данных).

Приведенным ниже кодом, ищу и заменяю текст в документе word:

Всё хорошо ищет и заменяет.

НО! моя функция игнорирует надписи, или если хотите - автофигуры. Т.к. пока я дилетант во взаимодействии word'a и delphi, подскажите как можно решить эту проблему.

И чтобы сразу выкинуть мусор и хлам из темы просьба не писать "умным":
- погугли, там полно примеров;
- запиши макрос в word и посмотри;
- не могу понять что ты хочешь;

реализовал" идею с макросами.
но опять НО.

для ясности сначала:

вот такой функцией создаю макрос - поиска и замены в word.
описать поэтапно что делает функция не могу, так как нашел данный код во всемирной паутине, содрал, немного изменил под себя.
В двух словах:
1. описываем макрос;
2. создаем кнопку макроса;
3. нажимаем на нее;
4. ищем заменяем;
5. удаляем кнопку и макрос;
как то так.

знаю что пункты 2, 3, 4 лишние, но во избежании еще большей путаницы, оставил все как есть.

теперь ПРОБЛЕМА.
после запуска программки и соответствующих действий, выдает ошибку

Method 'VBProject' not supported by automation object.

как это переводится я знаю (кстати если заменить слово object на abject, интересный перевод получается)))
но что это значит и как его приготовить я не понимаю.

может я что то ни так изменил.
не могли бы Вы пояснение выдать.

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

наверное фраза: "Т.к. пока я дилетант во взаимодействии word'a и delphi", сказала что я все знаю.

если вы решили отнести себя к числу "умных" или это каким то образом задело вас, значит так оно и есть.

простите, что делаю такие поспешные выводы не зная вас, но сами. так сказать.

посему если не знаешь ответа, то лучше обзавестись тряпочкой, в которую обычно молчат.

говорить вам больше ничего не буду, т.к. сказал все. И вы мне ничего не отвечайте, "чтобы сразу выкинуть мусор и хлам из темы".

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