Delphi word разрыв страницы
Данная статья написана на базе реальной программы "Автоматизация производства" - автоматической генерации сопровождающей документации при разработке печатных плат на программных продуктах "P-CAD 2000/2001".
- Перечень элементов
- Спецификация
- Ведомость комплектации
На каждом предприятии, будь то малый бизнес и огромный завод, немалую роль играет составление документации и отчётов. Почти всегда этим занимается специально выделенный человек. Так заведено уже давно, но теперь всё чаще появляются инициативные руководители, стремящиеся свести эти горы однотипной рутинной работы с человека на машину. Для этого и используют программы автоматизации производства. Эти программы автоматически генерируют требуемую документацию. Зачастую это сводится к работе с базами данных и библиотеками. Есть много программ делающих это. Но типов таковой документации столь много, что современные программные монстры, такие как пользовательская программа (MS ACCESS) или программируемый монстр (ORACLE) не в состоянии обеспечить даже половины нужд. Ведь у каждого предприятия своя с годами сложившаяся традиция заполнения документации или свой "Норма контроль" с заданными обязательными параметрами. Универсальной программы такого сорта нет и быть не может. Поскольку специфика работы предприятия может быть как гибкой в области документации (коммерческий ларёк), так и строго установленной на мировом уровне (банк или производственная сфера). Для решения этих проблем используют нестандартные отчёты. Отчёты сделанные специально под требования, наложенные на их оформления. Вы только представьте, ту работу, которую сотрудник выполнял несколько месяцев, программа сделает за пару минут. И это вполне реально. Данная статья представляет собой набор советов и примеров, которые помогут разработчику разобраться в столь оставленной без внимания теме, как автоматизация производства. Поскольку документации по этой теме практически нет, то данная статья поможет резко уменьшить время разработки таких программ с месяцев до недель. Но хотя по предлагаемой информации уже были созданы описанные выше программы, этой информации может всё равно оказаться недостаточно. В конце статьи вы найдёте координаты связи для пополнения содержательной части статьи и вопросов. Иллюстрирующие примеры мы приводим на языке Delphi 32 (версии 5 и выше). Выбор был остановлен на Делфи в виду её простоты и наглядности, но все идеи и реализации, изложенные в статье, легко переносятся на любой другой обьектно ориентированный язык программирования высокого уровня.
Нестандартные отчёты - кто и зачем этим занимается
На вопрос "зачем" мы, думаю, дали уже достаточно аргументации. Но всё-таки это не всё, остановимся на ещё неописанных проблемах.
Первый вопрос, который нам обычно задают - это где я смогу это использовать кроме как на предприятии, сфера применимости данной тематики довольно широка, рассмотрим некоторые вопросы и варианты их решения по средствам работы с Ворд и созданием отчётов:
- Удобство интерфейса. Вы можете предоставлять пользователю информацию прямо через WORD, где он сможет либо распечатать её, либо внести необходимые корректировки или сохранить себе копию. Согласитесь, чтобы реализовать это как-либо иначе уйдёт слишком много времени, а интерфейс WORD интуитивен, знаком и понятен, так что ряд проблем просто отпадает.
- Вы можете пользоваться любыми средствами, какими располагает Ворд. В том числе проигрывать видео и аудио записи, выдавать изображения, кроме того, становятся доступны любые возможности конвертации файлов (Например, можно не используя тегов через Ворд создать документ HTML)
- Реальностью становится программа, анализирующая документы формата WORD на диске и создание библиотеки вида название документа = имя файла, причём всю информацию можно напрямую собирать из WORD документов.
- Можно реализовывать локальные операции, допустим, все файлы WORD перевести в DOSовские TXT файлы. И многое, многое другое.
А на счёт кто же этим занимается? Эта информация может быть полезна руководителям. Любой WINDOWS программист с высшим или средне специальным образованием, знакомый с ЯВУ и ООП. Такого вида программистов часто называют прикладными. Срок изготовления в среднем 2-3 месяца с учётом бета тестирования.
Основы работы с OLE
На программном уровне работа с WORD заключается в использовании OLE. Основная структура взаимодействия такова: Существует программа СЕРВЕР, которая считается главной и именно она выполняет все операции, в нашем случае сервером является программа WORD. Из этих слов уже ясно, что если WORD не установлен на компьютере, то есть сервер отсутствует, то ничего выполнено быть не может. Просто некому будет выполнять. Это, по сути, наиболее распространенный вопрос среди программистов среднего класса. Вторая взаимодействующая программа - это программа КЛИЕНТ, все, что она делает - это связывается с сервером и просит его выполнить необходимые операции, сама по себе она ничего не может. В результате такого взаимодействия и решается поставленная задача. Теперь рассмотрим реализацию:
Эта процедура связывает переменную MsWord с Ole, в результате чего подгружается сам WORD, далее мы делаем его пока невидимым и проверяем версию, пояснения процедуры проверки версии будут позже.
Главный класс, в котором описаны основные переменные и процедуры необходимые для корректной работы с WORD.
Следует помнить и совершать все необходимые проверки совместимости сразу, чтобы избежать некорректной работы впоследствии. В случае отсутствия Ворд или несоответствия версии необходимо сразу предупредить об этом пользователя для принятия необходимых мер.
Ошибки при вызове WORD
Для начала опишем процедуру загрузки в WORD DOC файла, делается это так:
Можно к уже открытому добавить ещё один, так чтобы в итоге из двух получить один.
A вот и процедура, которая наиболее часто используется в приложениях такого типа!
- Если установить Ворд и попытаться сразу связаться с ним через Ole, то ничего не получится, дело в том, что при первом запуске WORD программа предлагает напечатать тестовую страницу, при этом, никак не сообщив об этом Ole клиенту. Из-за чего в работе вашей программы может происходить сбой. И исправлению эта ошибка не подлежит, данная неприятность - дело рук компании MICROSOFT создавшей WORD и пока она эту проблему решать не собирается, как видно из WORD XP.
- Ещё может быть ситуация, когда открываемый WORD файл уже занят другим приложением, или копией вашего, тогда ворд предлагает использовать режим только для чтения, а по освобождению ресурса предлагает переход в возможность редактирования. Это тоже влияет на работу клиентской программы, поскольку требует от пользователя согласия на изменение режимов.
- Файл, который вы открываете, просто не существует. Эту проблему вам придётся решать средствами языка разработки. WORD подобные сервисы не предоставляет.
- На используемой машине не хватает памяти. Ответ на этот вопрос смотрите в пункте 3.
Создание отчётов в WORD (различные подходы)
- Это стандартный подход. Клиент делает запрос, сервер выполняет, клиент делает следующий запрос и так далее, пока задача не будет решена.
- Можно использовать встроенный в WORD язык VBA, написать необходимые макросы на Visual Basic Script и внедрить их в текущий документ, тогда останется только вызывать их и всё. За счёт этого можно реально выиграть во времени, но волею случая этот метод в основном используется в компьютерных вирусах, за счёт чего относится к вирусным технологиям и из-за этого некоторые антивирусы могут определять вашу программу как инфицированную WORD вирусом. Поэтому данный метод так и не получил распространения среди Ole программ.
- Третий метод - самый важный, а заключается он в сочетании первых двух, таким образом, демонстрируя взаимное дополнение подходов.
Для воплощения любого из 3-х подходов необходимы ещё дополнительные действия. Если требуется записывать/читать с определённой позиции в тексте или необходимо работать с таблицей, то надо расставить закладки в нужных позициях документа. Это лучше всего сделать в шаблонном документе вручную. Потом надо будет найти эти закладки в тексте и перейти к ним. Для начала, напишем процедуру поиска закладки и перехода к ней.
Теперь закладку мы нашли запишем в то место что-нибудь
Великолепно, кроме простой записи, мы получили, и доступ к конфигурации текста и можем писать текст с атрибутами жирный , курсив , зачёркнутый , подчёркнутый , указывать размер шрифта и даже отслеживать центровку, поверите мне - этого более чем достаточно для реализации программ любой степени сложности!
Теперь напишем процедуру перехода к следующей ячейке таблицы, считаем, что на первую мы перешли по закладке!
Таким же образом запускаются макросы WORD, только вместо NextCell надо вставить имя макроса который хотим запустить. Важно не забывать, что через Ole можно вызывать только "свободные макросы" то есть без параметров. (VIRUS TECHNOLOGIES NOT FOR GAME)
А вот ещё процедура. Она позволяет пропускать нужное число ячеек таблицы с учётом, что позиционирования на закладке ещё возможно не было.
- NewList - переменная булевского типа, отвечающая за начало нового листа и новой таблицы на нём.
- a1 - закладка на первую ячейку таблицы.
Есть ещё команда по работе с закладками. Это удаление.
Данная команда удаляет первую закладку. Это очень удобно для многостраничного документа. Ведь каждая страница содержит одинаковые закладки, поэтому, прежде чем загрузить новую страницу необходимо удалить старые закладки, иначе закладки не загрузятся.
Полезная процедура для всех типов подходов к ole программированию. Она пересчитывает сантиметры в пиксели.
Предварительная настройка страницы WORD
Одной из самых распространенных проблем работы с Ole WORD - различные настройки конфигурации у разных версий WORD и на разных машинах, Вследствие чего иногда документ воспроизводится некорректно. Эту проблему можно решить, задав параметры конфигурации страницы вручную. Среди таких настроек отдельно можно выделить возможности корректировки отступов справа, слева, сверху и снизу, а также ряд других параметров.
Как вы видите, ряд настроек закомментирован, и это не случайность. Поскольку каждое обращение к серверу занимает время, то слишком объемное конфигурирование системы может привести к тому, что пользователь подумает, что программа, должно быть, зависла и перезагрузится, не дав выполнить всё конфигурирование целиком. Поэтому я советую ввести эту возможность как полезную утилиту программы, типа: Full Correction
Вообще-то всего описанного выше вполне достаточно для работы, но есть такое понятие, как "подвязать бантики и шнурочки" и именно это мы и сделаем.
Репутация: нет
Всего: нет
Такая проблема, помогите;))
Открываю делфёй вордовский документ: каждую страницу надо записать в отдельный вордовский документ. Когда я говорю, каждую страницу, я имею в виду текст до разрыва страницы, он может быть и на пять страниц, и на 5 строчек.
Как это сделать?
В принципе проблема у меня:
1. как найти разрыв страницы;
2. как "взять" весь текст между разрывами (подозреваю, что можно через characters);
Кто-нибудь, подскажите что-нибудь
Репутация: нет
Всего: 50
1. Делай поиск спец символа "разрыв страницы" - "^m"
2. Выделяешь все от разрыва страницы до начала документа, вырезаешь, вставляешь в новый документ
3. goto 1
Репутация: нет
Всего: нет
Кстати, заодно спрошу: откуда вы все берёте эти спецсимволы? Где-то есть такой док?
Репутация: 15
Всего: 108
"Кто владеет информацией, тот владеет миром"
Уинстон Черчилль
Репутация: нет
Всего: нет
А как мне это всё выделить, я что-то не могу сообразить??
Вот так вот я наверное найду разрыв страницы:
. и после этого курсор стоит перед разрывом, да?
Как мне теперь выделить??
Репутация: 15
Всего: 108
это выделит весь текст, а не искомый.
в третьих, если эта страница вставлена, не через команду -> вставка -> разрыв -> новую страницу, то этого символа в тексте не найдёшь.
Уинстон Черчилль
Репутация: нет
Всего: 50
Делаешь соответствующий макрос и его код переносишь в Delphi (естественно с синтаксисом)
Репутация: 15
Всего: 108
упс. у меня не находило. но оказалось, что это был глюк самого ворда. как я этот глюк убрал. всё стало находить без проблем.
"Кто владеет информацией, тот владеет миром"
Уинстон Черчилль
Репутация: нет
Всего: нет
Ага, начинаю понимать.
. только HomeKey ругается, говорит: "Неверный параметр"!!
Почему?
И, вот ещё какой вопрос, у меня
- это TWordApplication, в нём открыто два документа, объект Selection - это курсор в том документе, который на данный момент является активным, так?
Репутация: нет
Всего: 50
Опечатка
p2:=wdExtend;
Точно не знаю, но я всегда активизурую нужный мне документ (doc.Activate) потом Selection указывает на него.
Репутация: нет
Всего: нет
Ой-ой-ой
Прошу прощения за оплошность.
Репутация: 15
Всего: 108
это выделение. Если ничего не выделено, то оно находится в позиции курсора. А так это может быть картинка, кусок текста и т.д. и т. п.
"Кто владеет информацией, тот владеет миром"
Уинстон Черчилль
1. Публиковать ссылки на вскрытые компоненты
2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Rrader, Girder.
[ Время генерации скрипта: 0.1635 ] [ Использовано запросов: 21 ] [ GZIP включён ]
Поместив на форму компонет WordApplication, видим, что свойств и методов у него совсем мало. В первую очередь следует задать свойство ConnectKind. Оно может принимать значения:
* ckRunningOrNew Подключение к уже запущенному серверу Word, при его отсутствии сервер запускается.
* ckNewInstance Приложение обязательно запустит для своих целей собственный экземпляр сервера.
* ckRunningInstance Приложение подключается только к работающему экземпляру сервера. При его отсутствии возникает ошибка.
* ckRemote Соединение с сервером на удаленном компьютере.
Обычно вполне устраивает значение по умолчанию ckRunningOrNew. Это значит, что ваше приложение будет работать с уже выполняющимся на компьютере экземпляром Word'а, а если такового нет, запустит. Второй вариант ckNewInstance означает, что обязательно запустится еще один экземпляр Word'а, независимо от того, открыт Word или нет. Если установить значение ckRunningInstance, наше приложение будет работать только с уже запущенным Word, а если его не имеется, возникнет исключение EOleSysError. Для работы с Word на удаленном компьютере выбираем ckRemote, при этом в свойстве RemoteMachineName не забываем указать сетевое имя нужной машины.
try
WordApplication1.Connect;
except
Application.MessageBox('Приложение будет закрыто', 'Ошибка соединения', 0);
Application.Terminate;
end;
При желании можно было бы проверять возникновение конкретно данного исключения (потребуется руками подключить модуль comobj), но это вряд ли существенно. Главное, удачно прошло соединение или нет. Для отсоединения от Word'а используем метод
Свойства AutoConnect и AutoQuit, установленные в True, позволяют производить соединение с Word и отсоединение от него автоматически. То есть при запуске вашей программы автоматически вызыватся метод Connect, а при выходе из нее - Disconnect и Quit. Однако постоянно держать соединение с Word обычно не требуется, потому по умолчанию эти свойства установлены в False.
Имеющееся у сервера Word свойство Visible определяет, будет ли виден MS Word во время нашей работы с ним. Может принимать значения True и False - соотвественно видимый и нет. Обычно работа с документами производится в невидимом режиме, а потом показывают на экране уже готовый результат. Но на этапе отладки удобнее видеть своими глазами, что делает программа. Впрочем, иногда из политических соображений можно оставить сервер видимым - когда сам собой открывается Word и начинает печататься документ, на непросвещенные умы это производит большое впечатление:))
Свойство Version дает возможность узнать версию установленного на машине Word'а. Например:
Если в метке '9.0', на компьютере Word 2000. Для XP и 97, честно говоря, не помню, но это несложно проверить. Можно сделать ему StrToFloat(), если меньше 9 - Word 97, если больше - Word XP.
Другое важное свойство сервера Word - коллекция Documents. Позволяет открыть документ или создать новый, обеспечивает доступ к уже открытым документам. Открытие документа (предварительно описываем переменную FileName типа OleVariant и присваиваем ей строку с именем файла):
WordApplication1.Connect;
WordApplication1.Documents.Open(FileName,
EmptyParam, EmptyParam, EmptyParam,
EmptyParam, EmptyParam, EmptyParam,
EmptyParam, EmptyParam, EmptyParam,
EmptyParam, EmptyParam);
WordDocument1.ConnectTo(WordApplication1.ActiveDocument);
Обратите внимание на количество параметров - "пустышек". Их число не совпадает с тем, что обычно приводится в книжках. Объясняется это тем, что "книжная" функция предназначена для MS Word 97, а такая запись для Word 2000 и Word XP. По моим наблюдениям, основная разница при работе с разными версиями Word заключается именно в открытии документа (или создании нового).
Создание нового документа выглядит проще:
WordApplication1.Connect;
WordApplication1.Documents.Add(EmptyParam, EmptyParam, EmptyParam, EmptyParam);
WordDocument1.ConnectTo(WordApplication1.ActiveDocument);
Здесь также ставим на пару "пустышек" больше - по тем же самым причинам. Если вы хотите создать новый документ на основании своего шаблона, вместо первого параметра ставите переменную типа OleVariant, которой предварительно присваиваете строку с путем к dot - файлу. При открытии документа несколько забежали вперед, про подсоединение компонента WordDocument еще поговорим в дальнейшем.
Когда у нас есть несколько открытых документов, можем переключаться между ними, но не прямо, а через "активное" окно Word'а:
var
vid: OleVariant;
begin
vid := 2;
WordApplication1.Windows.Item(vid).Activate;
WordDocument1.ConnectTo(WordApplication1.ActiveDocument);
При этом следует помнить, что переменная vid может принимать значения от 1 до WordApplication1.Documents.Count. Далее можем работать с указанным документом. Нумерация документов происходит в порядке их открытия. Формально мы могли бы записать
Но оно не работает. Вообще, разных глюков встретится много, уж не знаю, кого тут винить - Borland или Microsoft.
Чтобы Word не тратил время понапрасну, полезно сразу отключить проверку правописания и грамматики:
Соответственно, присвоив True, можем снова включить.
Ну и для того, чтобы выгрузить Word, вызываем метод Quit:
Для работы с документами предназначен компонент WordDocument. Свойств и методов у него снова не густо, свойства его схожи со свойствами WordApplication, о которых уже говорили. Как правило, свойства вообще и не трогают. Основное, что нам пока надо - соединение с нужным документом. Для этого служит метод ConnectTo. Если открыт только один документ, нет ничего проще - соединяемся с "активным" документом, пример см. выше в открытии документа. Если же документов открыто несколько, начинаются сложности. Формально можем записать, к примеру:
var
vid: OleVariant;
begin
vid := 2;
WordDocument1.ConnectTo(WordApplication1.Documents.Item(vid));
На практике это срабатывает почему-то только в первый раз. Если вставляем строку в документ ? 2, при первом вызове она вставится именно туда. При последующих, какой бы номер документа не был указан, строка попадает в первый документ. Потому при необходимости я использую тот переход по "номеру окна", который приводился в предыдущем разделе, а вообще стараюсь открывать только по одному документу за раз.
Для сохранения документа используем метод Save:
Метод Save с параметром позволяет сохранить документ под другим именем:
var
filename: OleVariant;
begin
filename := 'd:\test.doc';
WordDocument1.Save(filename);
Если хотим записать документ не только под другим именем, но и в другом формате, используем Save с двумя параметрами:
где переменная FileFormat типа OleVariant может принимать значения:
$00000000 - wdFormatDocument - Документ Word
$00000004 - wdFormatDOSText - Простой текст
$00000006 - wdFormatRTF - Файл RTF
Это самые насущные константы, а полный список можно найти в заголовочном файле, введя в строку поиска "Format".
Можно для сохранения использовать и метод Close. Для него указаваем, сохранить ли изменения при закрытии документа:
var
vschange: OleVariant;
begin
vschange := wdSaveChanges;
WordDocument1.Close(vschange);
Константа сохранения изменений может принимать значения
wdSaveChanges - $FFFFFFFF
wdDoNotSaveChanges - $00000000
wdPromptToSaveChanges - $FFFFFFFE
Первое значение сохраняет изменения, второе дает возможность выйти без сохранения изменений. Последняя константа вызывает при выходе стандартный диалог сохранения изменений.
Метод Close можем вызвать и без параметров:
Но если в документ вносились какие-то изменения, будет выдан стандартный запрос на их сохранение. Если Word невидим, запроса также не видим, и такие документы могут висеть в фоновом режиме вплоть до выключения компьютера, когда и получим все вопросы. Самое интересное, что при работе через стандартные компоненты Word не отображается в списке активных приложений, потому на его закрытие и своевременное сохранение документов надо обращать внимание.
Часто перед работой с Word'ом возникает необходимость проверить, нет ли на машине открытых документов, сохранить их и закрыть во избежание порчи:
var
i, doccount: Integer;
begin
doccount := WordApplication1.Documents.Count;
for i := 1 to doccount do
begin
WordDocument1.ConnectTo(WordApplication1.ActiveDocument);
WordDocument1.Save;
WordDocument1.Close;
end;
Такой код сохраняет и закрывает все открытые на машине документы. Записав вместо последних двух строк цикла метод Close с параметрами, можем выйти из документов без сохранения. То есть последовательное подключение к активному документу просто перебирает их. Что интересно, переключаться между документами для работы таким способом не выходит.
Здесь речь пойдет о установках страницы - полях, разрывах страниц и печати текста в несколько колонок. Также можем программно переключать "размер бумаги" - альбомный или портрет. Но с последним надо соблюдать осторожность, дальше будет сказано, почему.
Размер бумаги и поля
Сначала о том, как определить или изменить установленный в Word размер бумаги:
Это мы изменили совершенно произвольно высоту и ширину страницы. Числа, которые присваиваем соответствующим свойствам, типа Single. Таким же образов можем и прочитать установленные в Word параметры страницы.
Теперь о полях. Изменение (чтение) ширины полей страницы:
WordDocument1.PageSetup.TopMargin:=100;
WordDocument1.PageSetup.BottomMargin:=90;
WordDocument1.PageSetup.LeftMargin:=90;
WordDcoument1.PageSetup.RightMargin:=50;
Числа, которые присваиваем ширине полей, опять-таки типа Single.
Кроме того, можем пользоваться большим набором "предопределенных" форматов бумаги. По умолчанию это обычно "а4", но можем выбрать и что-нибудь другое.
Если есть желание вывести текст в несколько колонок, поступим так:
var
a, b, vwidth, vspace, vesp: OleVariant;
begin
vwidth := 210;
vspace := 10;
vesp := wdLineSpaceSingle;
WordDocument1.PageSetup.TextColumns.Add(vwidth, vspace, vesp);
Здесь мы добавили еще один столбец. Если начнем заносить в документ текст, он будет аккуратно распределяться в две колонки. Таким образом создаем столько колонок, сколько нужно. Первый параметр - ширина столбца, второй - расстояние между столбцами, третий - отступ между строчками. Может иметь значения:
wdLineSpaceSingle - $00000000
wdLineSpace1pt5 - $00000001
wdLineSpaceDouble - $00000002
Читайте также: