Продолжение цикла статей посвященных работе с MS WORD.
Как и обещал, продолжаю рассказывать про элементы объекта document приложения Word. (Предыдущие статьи автора "Основы OLE Automation" и "Объектная модель MSWord. Основные понятия" прим. вед. раздела) В этой статье будет рассмотрены такие семейства как bookmarks, и fields. Все эти элементы в документе Word несут четко заданную цель. Однако, рассматривая Word как модель для управления, и как объект для получения и конечной обработки данных из Access такие объекты будут рассматриваться как кандидаты для передачи данных. Любой принцип передачи заключается в заполнении данными каких-то специфических свойств того или иного элемента и в отображении его на экране каким-либо образом. Т.н. реперные точки расстановки данных. В самом плохом случае пользователь должен иметь шаблон для подстановки. Я постараюсь научить обходиться без шаблона или, по крайней мере, создавать этот шаблон на лету. Последнее занимает больше времени, но не отнимает места на диске ненужными файлами, которые пользователь может случайно удалить, что приведет к неправильной работе всего приложения. Коллекция "Закладки" (bookmarks). Закладка — это элемент документа, которому присвоено уникальное имя. Это имя можно использовать для последующих ссылок. Закладки используются для быстрого перехода в определенное место документа, создания перекрестных ссылок, пометки диапазонов страниц для элементов предметного указателя и т.п. Закладки могут быть видимыми или скрытыми. Показать закладки можно в меню сервис выберите команду Параметры, а затем — вкладку Вид, там установите флажок Закладки. Закладки, соответствующие элементам, отображаются на экране в квадратных скобках ([…]), причем эти скобки не печатаются. Закладка, назначенная некоторой позиции, имеет I-образный вид. Одна "небольшая" неприятность закладок в том, что в режиме невидимости и при пустом значении их может удалить и сам создатель, даже не подозревая об этом. Навигация по закладкам очень проста, В меню вставка выберите команду закладки, а затем —выберите имя той закладки, которая вам нужна. Удобство перехода, и добавления делает закладку хорошим кандидатом для передачи данных в документ. Механизм передачи данных в этом случае таковой: пользователь имеет файл-шаблон, где в нужных местах расставлены закладки. Программа берет нужную часть данных, ищет закладку с определенным именем и заполняет закладку этими данными. Команда отобразить закладки (которые изначально могут быть скрыты) - отобразит всю информацию о переданных данных. Самые важные свойства закладок, которые будут использованы в примерах: Свойство/метод | Дополнительные указания | Возвращаемое значение | Комментарий | ShowHidden | Свойство (bookmarks) | Да/нет | Переключает режим отображения скрытых закладок. | Count | Свойство (bookmarks) | число | Возвращает количество закладок | Empty | Свойство | Да/нет | Возвращает да, если закладка пустая | Range | Свойство | Диапазон | Возвращает диапазон места размещения закладки | Name | Свойство | Имя | Имя закладки, четко характеризующее ее в документе | Add | метод(bookmarks) | закладка | Добавление новой закладки | Exist | метод(bookmarks) | Да/нет | Поиск закладки по имени. При наличии возвращает да | Delete | метод | | Удаляет выбранную закладку | Select | метод | диапазон | Выделяет нужную закладку в Активном документе | Эта табличка дает понять, что закладка достаточно простой объект, и, в принципе, все, что она может - это четко определять место расположения в документе. Заполнение закладки производится неявно, через свойство text свойства range. Получается, что в документ в определенный диапазон добавляется информация, и этот начало диапазона четко помечено и поименовано. Вот и все прелести закладок. Следующий пример позволит нам создать новый документ с 1 закладкой. Опять используется свойство range, для определения места вставки закладки, в данном случае этот диапазон совпадает с выделенным диапазоном, описанным в свойствах объекта select Public Sub word_new_dot() Dim word_obj As New word.Document 'описали переменную. стадия "раннего связывания" Err.Clear 'почистили ошибки On Error Resume Next 'сделали переход по ошибке на следующую строку Set word_obj = GetObject(, "word.document") 'попробовали просто вызвать ворд If Err = 429 Then Set word_obj = CreateObject("word.document") ElseIf Err <> 0 Then MsgBox "error" & Err ' если ворд не вызвался, однако 'режим вызова разрешен 'создали документ иначе сказали "ошибка" End If If Err <> 429 And Err <> 0 Then Exit Sub Else Err.Clear 'если была ошибка из за запрета вызова 'например данному пользователю запрещено запускать 'приложение ворд - то выход из процедуры 'иначе очистить ошибку и работать далее On Error GoTo 0 ''----------------------Блок проверки файла ------------ On Error Resume Next If Dir("c:
ew.doc", vbNormal) <> "" Then Kill "c:
ew.doc" 'Этот файл будет шаблоном 'для последующего переноса данных. Если шаблон есть тогда его удалим. If Err = 75 Then MsgBox "А кто то с этим файлом работает...." 'если файл занят другими пользователями Exit Sub ' остановим процедуру ElseIf Err <> 0 Then MsgBox Err ' при условии что призошла ошибка файловой системы Exit Sub ' тоже остановим процедуру End If ' я бы мог использовать структуру "case" но "if" немного быстрее On Error GoTo 0 With word_obj 'Что бы не писать далее много раз имя переменной. 'И работать будет немного быстрее .Application.Activedocument.Bookmarks.Add _ Range:=Selection.Range, Name:="Закладка" ' ** 'Мы программно добавили закладку 'в документ.ее не видно, но она есть. 'посмотреть то, что она есть можно в word меню вставка/закладки или 'выполнить команду программы для отображения закладок на экране : '.ActiveDocument.ActiveWindow.View.ShowBookmarks = True 'использование свойств вида активного окна .SaveAs FileName:="c:
ew.doc" ' записали наш новый файл с закладкой .Close SaveChanges:=wdDoNotSaveChanges 'закрыли ИМЕННО этот документ!!!!. ' Если бы мы не использовали 'раннее связывание,тогда пришлось бы описывать что такое wdDoNotSaveChanges 'или писать "SaveChanges:=0" 'Внимание!!! Если бы вместо Close использовалось 'word_obj.Application.Quit SaveChanges:=wdDoNotSaveChanges 'тогда бы мы закрыли все открытые документы без сохранения, что иногда бывает фатально 'именно поэтому надо четко представлять себе что происходит при использовании 'GetObject и CreateObject End With Set word_obj = Nothing End Sub
|
** - При создании объекта Word.Document автоматически запускается приложение Word. Но обращаться к свойствам, Word.application и уж тем более к его вложенным элементам можно задействовав свойство application элемента document. Аналог такого режима создания можно проследить в ADO, когда создается recordset без явного создания connection(соединения с источником данных), то соединение создается по умолчанию в неявном виде. Однако я сам все-таки предпочитаю явно открыть соединение. И точно так же предпочитаю явно открывать приложения. Предыдущий пример позволил создать документ, где расположена закладка. Для передачи нескольких частей данных - соответственно надо будет создать несколько закладок, при этом расставить их можно либо потом руками, либо меняя координаты точек вставки при добавлении закладки. Теперь после выполнения подпрограммы создания шаблона, можем вставить данные в закладку. Используется свойство text свойства range. Проверка количества закладок свойством count: Public Sub data_insert_in_word() Dim word_obj As New word.Application ' описали переменную. стадия "раннего связывания" Dim i As Integer Err.Clear ' почистили ошибки On Error Resume Next ' сделали переход по ошибке на следующую строку Set word_obj = GetObject(, "word.Application") ' попробовали просто вызвать приложение ворд If Err = 429 Then Set word_obj = CreateObject("word.Application") 'Если его нет запустим ElseIf Err <> 0 Then MsgBox "error" & Err ' ошибка End If If Err <> 429 And Err <> 0 Then Exit Sub Else Err.Clear ' если была ошибка, то выход из процедуры ' иначе очистить ошибку и работать далее On Error GoTo 0 If Dir("c:
ew.doc", vbNormal) = "" Then ' проверили а есть ли файл MsgBox "Куда дели файл шаблона?" ' если нет - выйдем Set word_obj = Nothing ' не забыв при этом явно освободить переменную Exit Sub End If With word_obj.Application ' опять же для простоты .Documents.Open FileName:="c:
ew.doc", Visible:=True ' открыли документ, 'видим его на панели приложений windows .Documents("c:
ew.doc").Activate 'на всякий случай, а то вдруг не тот документ активен If .Documents("c:
ew.doc").Bookmarks.Count < 1 Then ' проверили а есть ли закладки в файле MsgBox "Куда дели в шаблоне закладку????" ' если нет - выйдем .Documents("c:
ew.doc").Close SaveChanges:=wdDoNotSaveChanges 'закрыли Set word_obj = Nothing ' не забыв при этом явно освободить переменную Exit Sub End If For i = 1 To .Documents("c:
ew.doc").Bookmarks.Count ' пробежим по циклу(это если много закладок) If .Documents("c:
ew.doc").Bookmarks(i).Name = "Закладка" Then ' если это наша закладка .Documents("c:
ew.doc").Bookmarks("закладка").Range.Text = _ "Это было ранней весной или поздней осенью" 'нашли закладку в тексте, и вписали в тело закладки текст End If Next .Documents("c:
ew.doc").Close SaveChanges:=wdSaveChanges 'закрыли, записав изменения If .Documents.Count = 0 Then .Application.Quit SaveChanges:=wdDoNotSaveChanges 'А вот тут как раз проверили, если нет более документов - можем вообще закрыть приложение. End With Set word_obj = Nothing End Sub
|
Данный пример показал, как я в файле нашел нужное место и положил туда нужный текст. Теперь, создав достаточно большой шаблон, на несколько закладок - можно через аналогичную процедуру их заполнять данными. Коллекция закладок удобна, и по ней сделана навигация в Word. Что упрощает работу с ними. Коллекция (семейство) "полей"(fields) документа. Семейство объектов - полей документа, диапазона или области выделения. Поле в понятии Word - вычисляемый элемент, который вставлен в документ, поле содержит определенный код и может иметь несколько параметров документа. Обзор типов полей можно получить в диалоговом окне, выбрав в меню Word пункт вставка/поле. Поля используются для размещения в документе переменных данных и создания составных документов: конвертов, наклеек и т. п. Наиболее часто в документах встречаются поля PAGE, которое вставляется при добавлении номера страницы, и DATE, которое вставляется при выборе команды Дата и время в меню вставка с последующей установкой флажка обновлять автоматически. Поля вставляются автоматически при создании предметного указателя и оглавления с помощью команды Оглавление и указатели (меню Вставка). Кроме того, использование полей позволяет организовать автоматическое обновление сведений о документе (фамилию автора, имя файла и т. п.), выполнить вычисления, установить связи с другими документами и объектами, создать перекрестные ссылки и многое другое. Коды полей отображаются внутри фигурных скобок ( { } ). Для просмотра значений полей — например результатов вычислений — скройте коды полей: выберите команду Параметры в меню Сервис, а затем снимите флажок Коды полей на вкладке Вид. Можно провести следующую аналогию между полями Word и формулами Microsoft Excel: код поля соответствует формуле, а значение поля — результату этой формулы. Ограничивающие поле фигурные скобки ( { } ) нельзя вводить с клавиатуры. Поля вставляются при выполнении некоторых команд, например команды Дата и время (меню Вставка). Кроме того, можно нажать клавиши CTRL+F9, чтобы вставить пустые фигурные скобки, и ввести соответствующие инструкции между ними. Добавляя поля в главный документ, можно включать в составные документы дополнительные сведения и регулировать слияние документов в Word. Даже работать с закладками можно через поля (поле set).Именно элементы такого типа и использует Access для переноса данных в Word при слиянии данных. Причем очень уж толково он это делает, что бы этим не пользоваться. Основные свойства/методы полей, которые будут использованы в примерах: Много других свойств я не стал приводить, т.к. они похожи на свойство date - т.е. специфичны, и в каждом случае набор используемых свойств может быть разный. Свойство/метод | Дополнительные указания | Возвращаемое значение | Kомментарий | Add | метод(fields) | Поле | Добавление поля | Update | метод(fields/field) | Поле | Обновление содержимого поля (авто вычисление) | Unlink | метод(fields/field) | Текст/графика | Преобразование поля в часть текста, поле при этом перестает существовать | UpdateSource | метод(fields/field) | Поле | При связи нескольких документов - обновление источника | Delete | метод | | Удаляет указанное поле | Select | Метод | range | Выделяет поле. | doclick | метод | действие | В зависимости от поля выполняет определенное действие. (например, для поля MACROBUTTON запускает определенный макрос) | code | свойство | свойство | Самое главное в поле это его код. Код поля номер текущей страницы - PAGE и т.д. | showcodes | свойство | Да нет | Режим отображения кода поля/текст поля | data | свойство | дата | Специфическое свойство возвращающее (устанавливающее) заданную дату для определенных полей. Для других типов полей обращение к этому свойству вызывает ошибку | result | свойство | Результат выполнения | Возвращает результат выполнения действия поля. Для текстовых результатов используется свойство text свойства range | type | свойство | Описание типа | Общее свойство объектов приложения, возвращает тип объекта. | Next/previous | свойство | объект | Навигация по объектам, в данном случае, по полям | Перечислять типы полей не имеет смысла. Многие могут нести информацию о типе/дате/авторе/и много о чем еще. Некоторые поля выполняют какие то действия. Некоторые используют другие элементы документа (например, те же закладки и поля). Некоторые занимаются передачей данных. Именно к ним обратим пристальное внимание. Рассмотрим предлагаемый разработчиками office вариант передачи данных. В документе Word проставляются специфические поля, соответствующие местам вставки данных из документов. Диапазон документов источников огромен - это файлы Word, Access, Excel, Outlook и все источники, допустимые с использованием ODBC. Далее этот документ сохраняется как шаблон. При нажатии кнопки объединить создастся документ, куда, в расставленные поля будут переданы данные. Документ можно отправить сразу на печать, или по электронной почте. Либо как вложение (к сожалению как "*.doc") либо как письмо с данными в теле сообщения. Уникальное решение, предложенное разработчиками, к сожалению, не часто используется, и, к тому же, многими изобретается еще и еще раз. При открытии головного файла (шаблона) сразу же устанавливается подключение к источнику данных. Попробуйте хоть раз такой способ передачи данных, и, возможно, вам покажется, что что-то еще искать не имеет смысла. Поля, которые используются при этом механизме, это поля данных MERGEFIELD объекта MAILMERGE принадлежащего объекту Document. У MAILMERGE четко заданная задача - компоновка документа "на лету" используя базу данных, плюс практически мгновенная отправка документа по электронной почте (свойства MAILMERGE, такие как адрес, вложение и т.п. убыстряют компоновку электронного послания.). Важное свойство любого такого поля - описание источника данных. В таком описании можно задавать строку подключения, запрос на выборку данных, принцип связи с данными и много других важных параметров. Попробуем на примере немного разобраться, как в Word создается документ-шаблон, где находятся поля для последующей передачи данных. Источник данных. - tested.mdb, где есть Табличка - получатель Uin | Name_firm | Address | Fone | Fax | Email | Face | Ключевое поле | Название фирмы | Адрес фирмы | Телефон фирмы | Факс фирмы | Электронная почта | Контактное лицо | Подпрограмма создания шаблона: Public Sub word_field_dot() Dim word_obj As Object ' не стоит забывать что так тоже можно обьявлять переменную. '' ----------стандартный модуль открытия объекта -------- Err.Clear ' On Error Resume Next Set word_obj = GetObject(, "word.Application") If Err = 429 Then Set word_obj = CreateObject("word.Application") ElseIf Err <> 0 Then MsgBox "error" & Err End If If Err <> 429 And Err <> 0 Then Exit Sub Else Err.Clear On Error GoTo 0 '' ----------Ваяем далее -------- ''-----------Проверка свободного файла ----------------- On Error Resume Next If Dir("c:word_field.doc", vbNormal) <> "" Then Kill "c:word_field.doc" 'Этот файл будет шаблоном 'для последующего переноса данных. Если шаблон есть тогда его удалим. If Err = 75 Then MsgBox "А кто то с этим файлом работает...." 'если файл занят другими пользователями Exit Sub ' остановим процедуру ElseIf Err <> 0 Then MsgBox Err ' при условии что призошла ошибка файловой системы Exit Sub ' тоже остановим процедуру End If On Error GoTo 0 '' ----------Ваяем далее -------- With word_obj.Application .Documents.Add DocumentType:=wdNewBlankDocument ' Создали простой документ .ActiveDocument.MailMerge.MainDocumentType = wdFormLetters 'Задали тип документа 'типы бывают разные - формат для наклеек , конвертов и т.п. .ActiveDocument.MailMerge.OpenDataSource _ Name:="C:Мои документыстатьи ested.mdb", _ ReadOnly:=True, _ LinkToSource:=True, _ AddToRecentFiles:=False, _ Connection:="table Получатель" 'Команда открытия источника для слияния. 'Универсальность ворда в том. что он поддерживает множество источников. 'начиная с других файлов ворд, ексель, odbc источников и др. 'кроме параметра connection, есть еще параметр SQLStatement позволяющий вместо таблицы 'задавать запрос. и SQLStatement1 - 'Это если количество полей запроса > 255 тогда продолжение запроса пишется здесь .ActiveDocument.MailMerge.EditMainDocument 'запустили режим правки шаблонного документа. .ActiveDocument.MailMerge.Fields.Add Range:=Selection.Range, Name:="uin" 'влепили поле соответствующее полю uin в таблице .Selection.TypeParagraph ' добавили красную строку. Для красивости .ActiveDocument.MailMerge.Fields.Add Range:=Selection.Range, Name:="Name_firm" 'влепили поле соответствующее полю Название фирмы в таблице .Selection.TypeParagraph ' добавили красную строку. .ActiveDocument.MailMerge.Fields.Add Range:=Selection.Range, Name:="Address" 'влепили поле соответствующее полю адрес фирмы в таблице .Selection.TypeParagraph ' добавили красную строку. .ActiveDocument.MailMerge.Fields.Add Range:=Selection.Range, Name:="Fone" 'влепили поле соответствующее полю телефон фирмы в таблице .Selection.TypeParagraph ' добавили красную строку. .ActiveDocument.MailMerge.Fields.Add Range:=Selection.Range, Name:="Fax" 'влепили поле соответствующее полю факс фирмы в таблице .Selection.TypeParagraph ' добавили красную строку. .ActiveDocument.MailMerge.Fields.Add Range:=Selection.Range, Name:="email" 'влепили поле соответствующее полю электронная почта фирмы в таблице .Selection.TypeParagraph ' добавили красную строку. .ActiveDocument.MailMerge.Fields.Add Range:=Selection.Range, Name:="face" 'влепили поле соответствующее полю Контактное лицо фирмы в таблице .Selection.TypeParagraph ' добавили красную строку. .ActiveDocument.saveas "c:word_field.doc" 'сохранили шаблон .ActiveDocument.Close SaveChanges:=wdDoNotSaveChanges 'Закрыли документ If .Documents.Count = 0 Then .Application.Quit SaveChanges:=wdDoNotSaveChanges 'А вот тут как раз проверили, если нет более документов - можем вообще закрыть приложение. End With Set word_obj = Nothing End Sub
|
Проанализируем полученный шаблон. Итак, полученная процедура установила поля связи с данными на лист. Отмечу, что я описал используемую переменную как объект (т.е. фактически применил позднее связывание), однако использовал константы, которые в принципе использовать не могу. Тут все просто, подключенная библиотека элементов Word позволила мне такую шалость. Но в некоторых случаях это может "не пройти". Поэтому при позднем связывании константы все-таки лучше описывать явно. Опишу необходимые моменты, без которых невозможна была бы дальнейшая работа Первое важное действие, которое я выполнил, это объявил тип головного документа объекта MailMerge и запустил процедуру редактирования головного документа (editmaindocument), таким образом получив доступ к необходимым полям. Второе - Открыл источник данных (OpenDataSource). Параметров этого метода много. Но главные - файл источник, строка подключения. Третье - расставил поля. Для задания координат расстановки использовалось свойство range. В конкретном случае диапазон все-таки полей совпадал с диапазоном выделения. Добавляя параграфы, я просто отделял поля др., от друга. Имена полей должны совпадать с именами полей источника. Можно программно или вручную навести красоту - вставить текст, поясняющий, что и зачем, любой другой текст и т.д. Главное не задеть поля. В итоге получим документ шаблон, без данных. В готовый шаблон передать данные не составит особого труда. В этом может помочь следующая процедура Public Sub word_field_filled() Dim word_obj As Variant ' не стоит забывать что так тоже можно обьявлять переменную. '' ----------стандартный модуль открытия объекта -------- Err.Clear On Error Resume Next Set word_obj = GetObject(, "word.Application") If Err = 429 Then Set word_obj = CreateObject("word.Application") ElseIf Err <> 0 Then MsgBox "error" & Err End If If Err <> 429 And Err <> 0 Then Exit Sub Else Err.Clear On Error GoTo 0 '' ----------Ваяем далее -------- ''-----------Проверка файла-шаблона ----------------- If Dir("c:word_field.doc", vbNormal) = "" Then MsgBox "А куда дели шаблончик????" 'Если шаблона нет тогда Exit Sub ' остановим процедуру, но никто не мешает вам вместо выхода из процедуры ' Запустить подпрограмму создания шаблона. End If On Error GoTo 0 '' ----------Ваяем далее -------- With word_obj.Application ' нам лениво писать каждый раз word_obj.Application .Documents.Open "c:word_field.doc" ' шаблон открыли .ActiveDocument.MailMerge.DataSource.QueryString = _ "SELECT * FROM [Получатель] WHERE (([uin] = 1)) ORDER BY [uin]" 'напрямую строка запроса на отбор With .ActiveDocument.MailMerge ' работаем с обьектом MailMerge .Destination = wdSendToNewDocument ' Куда будут помещены данные на основе шаблона ' варианты - письмо, вложение, фаил. .MailAsAttachment = False ' у нас как раз не вложение .MailAddressFieldName = "" 'строка кому в электронном письме (если это письмо) .MailSubject = "" 'строка тема письма (если это письмо) .SuppressBlankLines = True 'Скрывать поле, если оно пустое With .DataSource 'работа с источником данных .FirstRecord = wdDefaultFirstRecord 'Ограничитель передаваемых данных .LastRecord = wdDefaultLastRecord 'т.о. можно передать все записи, или End With 'или скалибровать выборку данных .Execute Pause:=True ' команда мгновенного выполнения плюс вывод окна диалога при ошибках ' передачи данных. иначе все ошибки будут записаны в новый документ End With .Documents("c:word_field.doc").Close SaveChanges:=wdDoNotSaveChanges 'Закрыли шаблон End With Set word_obj = Nothing End Sub
|
Анализируя программный код, видим, что используется всего 1 метод - это метод execute. А все остальные команды это подготовка объекта mailmerge и его полей к передаче данных. Используя метод отбора как в строке запроса, так и ограничивая программно по записям (используя свойства .FirstRecord, .LastRecord )- можно компоновать последовательности документов на много записей и документы с данными всего одной записи. Из строки запроса видно, что я уменьшил возвращаемые данные до 1 строки максимум. А ограничениями ничего обрезать не стал, задав там параметры конечной и начальной записей "по умолчанию". Однако эти свойства помогают в word откалибровать запрос по количеству передаваемых записей. Их можно не использовать, если производится конкретный запрос с сортировкой, но если в качестве источника стоит целая таблица, а нужно не все записи передавать - то тут как раз понадобится способ ограничения количества записей. В данном примере при проверке на наличие файла-шаблона, стоит выход из подпрограммы в случае отсутствия файла, но никто не мешает вам запустить вместо этого подпрограмму создания шаблона. После выполнения процедуры мы получим файл с данными, где никаких полей нет, а вместо них стоят переданные данные. При этом файл-шаблон остался на первый взгляд неизмененным. Вообще-то мы поменяли параметры этого документа, однако, их восстановить не стоит большого труда закрыв документ без сохранения. Данный механизм передачи данных в Word проработан разработчиками. И их вариант представляется мне одним из самых оптимальных. Все остальные вариации поле/закладка просто легкая модификация уже существующего немного сложного механизма. И еще невозможно пока отойти от структуры шаблона, именно на основе которого формируется отчетный лист с данными, в данном случае, конечно. Вообще процесс передачи данных с задействованием полей документа многогранен, поэтому я не рассматриваю остальные варианты работы с полями. Информацию о других методах можно найти в интернете. Так в статье В.Сизова Формирование и регистрация стандартных документов Word с помощью Excel читателям предлагается использовать совсем другие поля. Что не меняет суть передачи данных, а только способ обращения к ним. Статью можно найти на русских страницах библиотеки Microsoft office extentions. Подведем итог всего, что тут написано. Приложение Word имеет большое количество полей, выполняющих множество функций, начиная с текстовых полей типа data и заканчивая полями передачи данных. Также, для удобной навигации и организации ссылок в приложении Word есть коллекция закладок. Обращаться и работать с ними можно также через поля. Навигацию по полям и закладкам документа легко осуществляется как программно, так и через встроенную навигационную систему. Создание нового документа и передача в него данных из Access с использованием закладок проще, чем с использованием полей, однако, при разработке четкого шаблона, способ передачи данных через поля оптимальнее. С уважением, MAKC.
Этот e-mail защищен от спам-ботов. Для его просмотра в вашем браузере должна быть включена поддержка Java-script
http://mytraffic.narod.ru Все приведенные модули проверены и работают. О найденных неточностях прошу сообщать на почтовый ящик. При написании этой статьи использовалась литература издательства BHV г. Санкт - Петербург. Серия "Мастер". Просмотров: 26021
Ваш коментарий будет первым | | |