Вставка изображения в документ Word

28 7

Предисловие

На одном из проектов я столкнулся с необходимостью вставлять изображения во вложенные в задачу документы. Причем документы могли быть различного формата, но изображение должно было всегда вставляться в правый верхний угол документа. Для решения поставленной задачи были разработаны две функции ISBL, которые использовали объекты Word.Application и Excel.Application соответственно. В функцию в качестве параметров попадали документы word и excel, вложенные в задачу, а так же документ-изображение, хранящийся в системе.  Со своей задачей функции справлялись, хоть и не обошлось без ошибок и костылей, связанных с взаимодействием ISBL и объектов word и excel. По завершении данного проекта появилась идея развить решение, учитывая все трудности и нюансы, возникшие в ходе разработки упомянутых функций. Также были изучены уже существующие решения:

Справочник

Главной идеей развития было создать специализированный справочник, который будет хранить изображения для вставки в документы, так как хранить большое количество изображений в системе в качестве отдельных файлов достаточно неудобно. Создание справочника также решало проблему перегруженности функции параметрами настройки, так как все параметры вставки изображения можно хранить в записи справочника. Постепенно был создан концепт справочника, который был дополнен еще одной идеей: обеспечить возможность работы с подложками (водяными знаками). Изображения в качестве подложки используются не часто, поэтому в справочник было решено добавить еще одно представление, для объектов Word Art. Также было принято решение ориентировать разработку только на документы Word. Если разработка окажется жизнеспособной, то ее функционал будет расширен и на документы Excel.

Концепт:

Результатом разработки стал справочник «Графические объекты для вставки в документ» с тремя представлениями:

  • Изображение для вставки в документ
  • Word Art для вставки в документ
  • Все графические объекты

Главное представление «AllGraphics» доступно только для просмотра всех имеющихся записей справочника без возможности менять их содержимое.

Представление «Picture» отображает только те записи, в которых хранятся изображения. Эти записи можно редактировать, меняя настройки изображения.

Также в карточке есть возможность просмотра того, как будет выглядеть вставленное изображение в документе (кнопка «Предпросмотр»). Чтобы выбрать документ для просмотра, необходимо заполнить константу «DIO_WordDocumentExample».  При нажатии на кнопку откроется локальная копия документа с уже внесенными изменениями.

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

Представление «WordArt» отображает только те записи, в которых хранятся надписи для объекта Word Art.

Аналогично с представлением «Picture» в карточке можно менять настройки для вставляемого объекта. Кнопка «Предпросмотр» открывает тот же документ, что и в представлении с изображением.

Функция

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

  • ИД документа
  • Номер версии документа
  • ИД записи справочника «Графические объекты для вставки в документ»

Получив ИД записи справочника, функция считывает значения всех реквизитов и вставляет изображение или Word Art с теми настройками, которые указаны в записи.

У функции также есть четвертый параметр «ShowDocument». Этот параметр имеет логический тип и необязателен для заполнения. Если установить значение этого параметра в «TRUE», то в указанный документ системы не внесутся изменения, а будет открыта копия документа, сохраненная во временной папке, с внесенными изменениями. В действии «Предпросмотр» справочника «Графические объекты для вставки в документ» выполняется данная функция со значением «TRUE».

Возникшие трудности

Во время разработки функции пришлось столкнуться с проблемами использования объекта Word.Application в ISBL. Основной проблемой стала невозможность передачи некоторых значений в свойства объектов. Изначально планировалось, что в разработанном справочнике будет возможность настройки обтекания объекта текстом. Но при передаче необходимого значения возникала ошибка интерпретации данных, которую не удалось обойти (ISBL не может присвоить значение с типом данных «single»). Также, по неизвестным причинам, свойство объекта «rotation», отвечающее за его поворот, не работает для изображений, не являющихся подложками.

Итог

Разработка выполнена в системе DIRECTUM 5.0.

В состав разработки входят:

  • Константа
  • Словари локализации
  • Справочник
  • Функция

DIO_InsertObject.zip (60,87 Кб)

_______________________________________________________________________________________________________________________

--------------------------------------------------16.05.2014--------------------------------------------------------------------------------------------------------

Дополненная версия разработки

Список изменений:

  • Поворот вставленного изображения работает для любых вариантов вставки.
  • Добавлена возможность настройки обтекания текстом.
  • В связи с новым функционалом были изменены представления справочника.
  • Поменялся принцип работы сценария.

Теперь обо всем подробнее.

Так как предыдущая версия разработки не позволяла реализовать часть функционала из-за ограниченной возможности передачи данных определенного типа (например «single») в ISBL, то было принято решение реализовать разработку средствами VBS. В результате была получена разработка, выполняющая все задуманные действия. Однако, прежде чем использовать модифицированное решение, советую ознакомиться с его особенностями.

Особенности решения

Функция, выполняющая основные действия, сохранила прежние параметры, однако же вычисления полностью изменились:

  1. Функция формирует VBS, в который передаются все необходимые значения.
  2. После запуска, VBS использует объект Word.Application для работы с документом.
  3. Далее происходит самое неприятное. Так как VBS никак не связан с ISBL, то после запуска скрипта, функция не прекращает свое действие. Для того чтобы дождаться отработки скрипта и уже только потом сохранить модифицированный документ в систему, было решено воспользоваться таймером (функция «Sleep()» в системе DIRECTUM). Значение ожидания равно двум секундам, затем, посредством возможностей объекта «Scripting.FileSystemObject», функция проверяет дату изменения модифицируемого документа и, если она прежняя, то снова уходит в ожидание. Лимит ожидания установлен на десять секунд, по истечению которых выводится ошибка.

Итог

Разработка выполнена в системе DIRECTUM 5.0.

В состав разработки входят:

  • Константа
  • Словари локализации
  • Справочник
  • Функция

DIO_InsertObject2.zip (59,90 Кб)

Денис Архипов

а если использовать в ISBL скрипты на VBS? в качестве еще одного костыля? или переписать всю логику на VBS, а из ISBL только вызвать нужный скрипт.
 

Евгений Вальков

Переписать всю логику на VBS действительно может стать решением. Мне тут дали ссылку на статью:

http://club.directum.ru/post/Postroenie-otchjotov-Reshenie-problemy-s-zavisaniem-processov-Excel.aspx

Можно будет опробовать. В случае успешной работы функции, добавлю ее обновленную версию.

Евгений Вальков

Опробовал способ в указанной статье. Вставка изображения работает, но чтобы извне добавить и запустить новую функцию, нужно настраивать соответствующие параметры безопасности ("Доверять доступ к объектной модели проектов VBA").

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

  1. Через ISBL создаем VBS
  2. Передаем в него необходимый код
  3. В VBS обращаемся к объекту Word.Application и отрабатываем переданный код
Евгений Вальков

Реализовал разработку посредством VBS. Подробности в статье.

Михаил Тарасов

Используя ScriptControl, думаю, можно будет не использовать циклические задержки для ожидания...

Кроме того, в него можно передавать значения, являющиеся Com объектами (наследники iObject, всякие там iList и т.д.)

Михаил Тарасов

Проверил с вызовом через ScriptControl, заменил ваш вызов на свой

scriptControl = CreateObject("ScriptControl")
scriptControl.Language = "vbscript"
 
scriptControl.AddCode(VBScriptText)

Всё работает. ISBL ждет, пока завершится VBS скрипт. Поэтому, костыль с проверкой даты изменения файла можно не использовать

Авторизуйтесь, чтобы написать комментарий