На написание данного материала меня натолкнул вопрос Антона Максунова заданный им на форуме Как можно вставлять в шаблон логотип компании? Процитирую сам вопрос:
Есть задача - надо переписку между нашими компаниями перевести в рамки шаблонов в Directum. У всех компаний разный логотип и он обязательно должен быть в письмах. В связи с этим несколько вопросов:
Если это слишком сложный путь, то может кто подскажет другое решение?
Немного поразмыслив, я подумал, а почему бы не реализовать какой-нибудь готовый вспомогательный механизм, который позволит при разработке шаблонов документов использовать возможности объектной модели Word, при этом избавит от необходимости изучения нюансов взаимодействия Directum и Word. Как говориться, дело было вечером, делать было нечего и в результате родилось что-то наподобие технического решения, которое будет описано ниже.
Само решение состоит из следующих компонент:
RITWordTemplate - справочник шаблонов документов Word;
RITOrgLogo - справочник логотипов "Наших организаций";
RITGenerateEDocFromWordTemplate(EDocument: Вариантный; VersionNumber: Целое число; WTCode: Строка) - функция заполнения полей в документе Word, где
EDocument - объект типа IEDocument, документ, в котором мы хотим заполнить поля;
VersionNumber - версия электронного документа, в которой необходимо заполнить поля;
WTCode - код записи справочника RITWordTemplate, в котором содержатся имена полей и их вычисления.
RITGetWordTemplateFieldValue(EDocID: Целое число; CalculateText: Строка) - функция вычисления значения поля документа, где
EDocID - ИД документа, для которого выполняется вычисление значения полей;
CalculateText - текст вычисления значения поля.
RITTestCreateEDocFromWordTemplate - сценарий примера использования данного решения.
Справочник RITWordTemplate выглядит так:
Карточка записи справочника RITWordTemplate:
Назначение реквизитов карточки понятно из их заголовков.
По кнопке Шаблон можно открыть для просмотра или изменения шаблон документа, указанный в реквизите "Шаблон электронного документа":
По кнопке Просмотр можно посмотреть результат заполнения полей шаблона:
В табличной части записи справочника RITWordTemplate задаются имена полей шаблона и вычисления для этих полей на языке ISBL. Результат вычисления необходимо вернуть в строковой переменной Result. В вычислениях доступна предопределенная переменная EDocument, с помощью которой можно обращаться к реквизитам карточки документа. Для полей, в которые нужно будет вставить картинку, необходимо установить реквизит "Картинка" в значение "Да". Для таких полей результат вычисления должен возвращать путь до картинки (другого способа вставки картинки в документ я не нашел). Путь может быть как локальный, так и сетевой (у пользователя должен быть доступ к сетевой папке, где хранятся картинки, на чтение). Поля, для которых не задано вычисление, пропускаются (для примера, поле [Тема] на скриншотах). Если результат вычисления будет пустая строка, то такие поля тоже заполняться не будут.
Для поля [Должность подписанта] вычисление выглядит так:
Для поля [Логотип] вычисление выглядит так:
Пример использования:
TypeKode = "ПЭА"
KindCode = "Г000043"
TemplateCode = "Д000066"
EDocument = EDocuments.CreateNewFromTemplate(TypeKode; KindCode; TemplateCode)
EDocument.ISBEDocName = "Документ из тестового шаблона"
EDocument.Save()
RITGenerateEDocFromWordTemplate(EDocument;;"Д000005")
EDocument.Open(True; -1)
Бонусом к решению добавлен справочник логотипов организаций RITOrgLogo:
Карточка записи справочника RITOrgLogo:
С помощью этого справочника можно хранить логотипы наших организаций и потом их использовать в вычислениях на ISBL или вставлять в шаблоны документов.
В итоге мы получили:
Разработка велась в версии DIRECTUM 4.6.1. В 4.7 тоже проверял, все работает. Ниже прилагаю архив с самой разработкой. Структура архива:
-------------------------------------------------------------------------------------------
Решение обновилось до версии 2.0
Список изменений:
1. Карточка записи справочника RITWordTemplate теперь выглядит так:
2. При выборе Вида электронного документа в реквизите Тип карточки доступны для выбора типы карточек только для данного вида электронного документа. Если доступен только один вид карточки, то он подставляется автоматически.
3. При выборе Вида электронного документа в реквизите Шаблон электронного документа доступны для выбора шаблоны только для данного вида электронного документа. Если доступен только один шаблон, то он подставляется автоматически.
4. Добавился реквизит Запоминать реквизиты. Если реквизит установлен в значение "Да", то будут запоминаться значения реквизитов, которые указываются при заполнении карточки, что избавляет от постоянного заполнения карточки документа при тестировании шаблона. Для каждой записи справочника RITWordTemplate запоминается свой набор значений реквизитов. Т.к. значения реквизитов хранятся в окружении, они будут храниться, пока не будет закрыт справочник RITWordTemplate.
5. Добавился реквизит Удалять временные документы. Если реквизит установлен в значение "Да", то при каждом просмотре шаблона (по кнопке Просмотр) будет удаляться временный документ, созданный при предыдущем просмотре. Если вам мешает то, что перед следующим просмотром, предыдущий временный документ, созданный из шаблона, надо закрыть (иначе его не получится удалить), то установите реквизит в значение "Нет". В этом случае вы можете потом после отладки шаблона удалить все временные документы, созданные во время отладки шаблона, по кнопке Эл.документы.
6. Добавилась кнопка Эл.документы. По этой кнопке отображается список всех временных документов, которые создавались во время тестирования шаблона. Вы можете их после отладки удалить или произвести с ними какие-либо другие действия.
7. Добавилась функция RITGenerateEDocFromWordTemplateFieldsList(EDocument: Вариантный; VersionNumber: Целое число; FieldsList: Вариантный) - функция заполнения полей в документе Word, где
EDocument - объект типа IEDocument, документ, в котором мы хотим заполнить поля;
VersionNumber - версия электронного документа, в котором необходимо заполнить поля;
FieldsList - список полей и их значений типа IList, которые необходимо заполнить в документе. В списке значений в
Name заносится имя поля, в Value массив вида (Значение_поля; Признак_картинки).
Данную функцию удобно использовать, когда значения полей вычисляются динамически (например, в ходе выполнения типового маршрута) и вы не можете их расчитать заранее в справочнике RITWordTemplate. Пример использования данной функции:
RECORDS_DOES_NOT_EXIST = 0
FIRST_WORKER_INDEX = 0
if Job.ExecutionResult.Code = 1
// Получим ИД документа из параметров задачи
DocID = ТМПолучитьПараметрЗадачи('ИДПНК')
EDoc = EDocuments.GetObjectByID(DocID)
// Добавим подпись руководителя и дату подписания
Performer = Job.Info.Performer
WorkerCodeList = GetEmployeesByUserID(Performer.ID)
if WorkerCodeList.Count > RECORDS_DOES_NOT_EXIST
WorkerCode = WorkerCodeList.Values(FIRST_WORKER_INDEX)
Worker = References.РАБ.GetObjectByCode(WorkerCode)
FieldsList = CreateList()
if Assigned(Worker.Requisites('Текст').AsString)
FileName = Worker.SYSREQ_NAME & '.' & Worker.Requisites('Текст').Extension
Path = GetTempFolder()
FileName = Path & FileName
Worker.Requisites('Текст').SaveToFile(FileName)
FieldsList.Add('[Подпись2]'; ArrayOf(FileName; YES_VALUE))
endif
FieldsList.Add('[Дата2]'; ArrayOf(ToDay(); NO_VALUE))
RITGenerateEDocFromWordTemplateFieldsList(EDoc; ; FieldsList)
FieldsList = nil
endif
endif
8. Исправлено много мелких ошибок, выявленных в ходе тестирования решения.
Разработка тестировалась в версиях DIRECTUM 4.6.0, 4.6.1, 4.7.0.
WordTemplate_ver2.zip (100,63 Кб)
P.S. данный механизм удобно использовать при разработке и тестировании шаблонов и с использованием стандартной интеграции DIRECTUM с MS Office. По крайней мере вы будете избавлены от необходимости выполнять действия по созданию шаблона и заполнению реквизитов карточки документа при тестировании шаблона. Сейчас все гораздо проще:
1. Нажал кнопку "Шаблон" - поправил шаблон и сохранил его.
2. Нажал кнопку "Просмотр" - посмотрел результат.
Замечательный пример, когда материал рождается по результатам обсуждения. Всем участникам сообщества предлагаю делать так же!
Не хватает тяму понять что и куда, новый реквизит добавить не могу =) Если честно даже не понял причину ошибки http://savepic.org/1964769.jpg
А шаблон точно вордовский? Вичисления для поля [Лого] есть? В сам шаблон поле [Лого] добавлено? И если добавлено то как?
Я такую ошибку повторить не смог, даже с чистым документом без полей. И еще, у вас действительно есть Вид документа "Документы произвольной формы"? Если есть, то у него указан тип карточки и доступные шаблоны?
А Word вообще установлен на том компьютере, на котором проверяете? :)
Еще хотелось бы взглянуть на сам шаблон.
Сейчас взял готовый шаблон "шаблон для тестирования", готовую вашу запись в шаблонах, ошибка осталась.
В списке процессов ворд не болтается?
Болтается, я параллельно шаблоны уже делаю )
Убил несколько висящих процессов, запустил. Опять ошибка и висящий процесс.
В командной строке выполнить: dcomcnfg
В открывшемся окне выбрать Службы компонентов -> Компьютеры -> Мой компьютер-> правой кнопкой мышки -> свойства -> Закладка "Свойства по умолчанию" -> Проверить что стоит галочка "Разрешить использование DCOM на этом компьютере"; Закладка "Безопасность COM" -> Раздел "Права доступа" -> кнопка "Изменить настройки по умолчанию" -> Добавьте себя и поставьте обе галки; Раздел "Разрешения на запуск и активацию" -> кнопка "Изменить настройки по умолчанию" -> Добавьте себя и поставьте все 4 галки
И если еще есть антивирус, то его можно попробовать временно отключить, чтобы убедиться что это не он мешает.
Все галки стояли как надобно, шаблон открывается как и прежде, а просмотр выдает ту же ошибку.
А офис какой стоит? Я тестировал на 2003 и 2007. Еще я забыл в функции RITGenerateEDocFromWordTemplate в конце добавить WordApp = nil
Офис 2007. Исправление внес, ошибка та же ) Еще, кстати, ворд пишет "неверно указана единица измерения"
Это он в какой момент пишет?
Ошибка ворда и через секунду ошибка директума. Её из под ошибки директума не видно вот и забыл сказать.
Попробуй создать файл TestWord.vbs с таким содержимым:
и запусти его. Должен появиться файл
C:\testdoc.doc
"неверно указана единица измерения"
документ с содержанием "тестовый документ, количество полей = 0"
зависший процесс ворда.
А в в панели управления - язык и региональные стандарты - Языковые стандарты и форматы стоит "Русский"? Там же расположение стоит Россия? По кнопке настройка разделитель целой и дробной части стоит запятая или точка (должна быть запятая)?
И еще гугл выдал:
Исправление ошибки "Неверно указана единица измерения" в Microsoft Word 2007
Если в Microsoft Word при изменении межстрочного интервала возникает ошибка "Неверно указана единица измерения", то нужно скачать и установить исправленную библиотеку WWINTL.DLL (http://spisok-literaturi.ru/filez/WWINTL.RAR)
Так же устраненяется некорректное отображение настроек.
Установка: файл WWINTL.DLL(с заменой) скопировать в *:\Program Files\Microsoft Office\Office12\1049.
Проблему с Word-ом решили. Если у кого-то такая же проблема "неверно указана единица измерения" (ошибка никак не связана с разработкой и присутствует в самом "криво" русифицированном офисе 2007), то вам поможет это:
Т.к. данным решением пришлось воспользоваться на одном из проектов, оно было значительно доработано и протестировано. Список изменений и саму разработку добавил в материал.
Здравствуйте. Очень полезной оказалась Ваша разработка. Подскажите, пожалуйста, почему может быть такая ошибка?
http://imglink.ru/show-image.php?id=16981606b48e430c2ac82d4566c157eb
Попробуйте перезапустить сервер сеансов.
Спасибо. Решение нашла, изменив немного код в функции "RITGenerateEDocFromWordTemplate".А именно строчку 37 поправила на: WTRecord = References.ReferenceFactory('RITWordTemplate').GetObjectByCode(WTCode).
Теперь у меня по функции "RITGenerateEDocFromWordTemplateFieldsList" возник вопрос. Для понимания ее работы упростила пример сценария до:
EDoc = EDocuments.GetObjectByID(136932) // документ, созданный на основе шаблона
FieldsList = CreateList()
FieldsList.Add('[дата]'; ArrayOf(ToDay(); NO_VALUE))
RITGenerateEDocFromWordTemplateFieldsList(EDoc; ; FieldsList)
FieldsList = nil
всё проходит без ошибок, но с файлом ничего не происходит. Подскажите, пожалуйста, что я делаю не так? Может нужно брать файл самого шаблона?
работаю в 4.7.
Достаточно было просто перезапустить сервер сеансов. Это особенность версии 4.7, после каждого приема новой разработки необходимо перезапускать сервер сеансов, чтобы изменения "подхватились".
В документе должно присутствовать поле [дата]. Нужно либо добавить его в этот документ вручную (открыть документ в MS Word и вставить поле через соответствующее меню), либо создать документ на основе шаблона, имеющего поле [дата] и уже потом вызывать данную функцию, чтобы она заполнила это поле передаваемым значением в нужном месте документа.
В документе всё есть. Не выходит. ((
Можете мне прислать этот документ, я на него взгляну?
Также интересует версия установленного MS Word.
Т.к. при извлечении значения параметра из списка FieldsList используется метод IndexOfName объекта IList, то имя параметра '[дата]' в списке полей FieldsList, передаваемом функции RITGenerateEDocFromWordTemplateFieldsList, и в документе должны совпадать с точностью до регистра. Т.е. '[Дата]' и '[дата]' - это два разных параметра.
Чтобы было понятно о чем речь, приведу пример небольшого сценария для тестирования работы с методом IndexOfName объекта IList:
TestList = CreateList()
TestList.Add("ИмяПараметра"; "1")
TestList.Add("имяпараметра"; "2")
Index = TestList.IndexOfName("имяпараметра")
if Index > -1
ShowMessage(TestList.Values(Index))
else
ShowMessage("Параметра с таким именем не существует")
endif
TestList = nil
Результат работы сценария:
А поля после сохранения обновляются, если внести исправления в карточку документа?
Такой цели во время разработки не преследовалось и подразумевалось только однократное заполнение полей документа при его создании, но если в событии сохранения карточки программно вызвать эту прикладную функцию заполнения полей документа со списком полей и их новыми значениями, то они обновятся.
Только в текущей реализации привязка идет к содержимому поля и если оно уже изменялось, то в качестве имени поля надо будет передать его текущее значение. Если при многократном обновлении полей необходима привязка к имени поля, то разработку необходимо будет доработать. Например, получать имя поля в функциях заполнения полей из свойства Code (а не Result, как в текущей разработке) объекта Field объектной модели MS Word.
добрый день,при импорте разработки (генерация реквизитов),появляется ошибка
Причина кроется скорее всего тут: "Разработка тестировалась в версиях DIRECTUM 4.6.0, 4.6.1, 4.7.0."
Попробуйте вот это решение: Заполнение полей шаблонов документов средствами Word, в том числе и из табличной части. оно посвежее будет.
Заполнение полей шаблонов документов средствами Word, в том числе и из табличной части.
При импорте пакета разработки,при заполнении справочника выходит сообщение "Class TSBReferenceRecordCardForm not found",такая же ошибка появляется при просмотре формы
Авторизуйтесь, чтобы написать комментарий