Реализация интерактивного редактирования макета Microsoft WORD из 1С для пользователя


Пользователь сам сможет редактировать макет Microsoft Word и в последствии использовать его для печати документа, справочника и т.д.
Реализация протестирована на 1С 8.3.12.1714 (x64).

WARNING

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

 

Иногда возникает потребность дать пользователю самому редактировать макет печатной формы, в случае с табличным документом проблем реализации зачастую не возникает. Но совсем другая ситуация когда результатом печатной формы должен быть документ Microsoft Word.

Некоторое время назад Я искал возможность открыть документ MS Word для редактирования и забирать его обратно в базу поcле закрытия.

Это можно реализовать через: ДобавитьОбработчик Word.Quit, ВыходИзWord;

Предусмотрел возможность редактирования нескольких макетов. Предполагается что макеты хранятся в виде двоичных данных (где хранить решать Вам).

Итак, приступим:

  1. Для начала опишу таблицу макетов:
  2. Заполнить таблицу макетов для редактирования: 
    &НаСервере
    Процедура ЗаполнитьМакеты()
    
    мОбъект = РеквизитФормыВЗначение("Объект");
    
    // получаем макеты для изменений
    Для Каждого СтрМакет Из мОбъект.Метаданные().Макеты Цикл
    Если Строка(СтрМакет.ТипМакета) <> "ДвоичныеДанные" Тогда
    Продолжить;
    КонецЕсли;
    Макет = Макеты.Добавить();
    ЗаполнитьЗначенияСвойств(Макет, СтрМакет);
    Макет.ДвоичныеДанные = мОбъект.ПолучитьМакет(СтрМакет.Имя)
    КонецЦикла;
    
    КонецПроцедуры
    

    В данном примере макеты хранятся во внешней обработке, но по факту их можно хранить где угодно.

  3. Открытие макета MS Word для изменения: 

    &НаКлиенте
    Функция МакетWordОткрытьДляИзменения(СтрМакет)
    
    СтрМакет.ИмяВременногоФайла = ПолучитьИмяВременногоФайла("doc");
    ДвоичныеДанные = СтрМакет.ДвоичныеДанные;
    ДвоичныеДанные.Записать(СтрМакет.ИмяВременногоФайла);
    Word = Новый COMОбъект("Word.Application");
    Word.Documents.Open(СтрМакет.ИмяВременногоФайла);
    Word.Visible = Истина;
    
    ДобавитьОбработчик Word.DocumentBeforeClose, ПередЗакрытиемДокументаWord;
    ДобавитьОбработчик Word.Quit, ВыходИзWord;
    
    КонецФункции
    
    &НаКлиенте
    Процедура МакетыВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    МакетWordОткрытьДляИзменения(Элемент.ТекущиеДанные);
    
    КонецПроцедуры
    

    Здесь все просто:

    • Сохранить макет в файл;
    • Открыть макет в новом COMОбъект("Word.Application");
    • Отобразить "Word.Application" на экране пользователя и навесить обработчики на его закрытие. 

     

  4. После окончания редактирования, перед закрытием "Word.Application" сохранить его: 

    &НаКлиенте
    Процедура ПередЗакрытиемДокументаWord(Документ, Отмена) Экспорт
    
    Документ.Save();
    
    КонецПроцедуры
    

     

  5. Во время закрытия файла "Word.Application" загрузить его обратно в таблицу макетов: 

    &НаКлиенте
    Процедура ВыходИзWord() Экспорт
    
    Для Каждого СтрМакет Из Макеты Цикл
    Файл = Новый Файл(СтрМакет.ИмяВременногоФайла);
    Если НЕ Файл.Существует() Тогда
    Продолжить;
    КонецЕсли;
    ДвоичныеДанные = Новый ДвоичныеДанные(СтрМакет.ИмяВременногоФайла);
    // если макет был изменен
    Если СтрМакет.ДвоичныеДанные <> ДвоичныеДанные Тогда
    СтрМакет.Изменен = Истина;
    СтрМакет.ДвоичныеДанные = ДвоичныеДанные;
    СтрМакет.Ответственный = Пользователь;
    ЭтаФорма.Модифицированность = Истина;
    КонецЕсли;
    
    КонецЦикла;
    
    КонецПроцедуры
    

    Этапы загрузки макета в базу:

    • Прочитать все строки таблицы макетов;
    • Получить те, которые были сохранены в файл;
    • Получить двоичные данные из сохраненных файлов;
    • Сравнить изменены ли данные;
    • В случае изменения — записать новые данные в таблицу.

Описание применения:

Программный код или всю форму можно перенести во внешнюю печатную форму (обработку) и хранить измененные макеты в РегистрСведений.БезопасноеХранилищеДанных или Справочник.ДополнительныеОтчетыИОбработки.ХранилищеНастроек, где перед началом заполнения макета, проверять наличие его модификации в системе.

Модифицированный таким образом макет MS Word совместим со стандартной подсистемой печати и может быть использован в УправлениеПечатьюКлиент.ИнициализироватьМакетОфисногоДокумента(ДвоичыеДанные, "DOC");

6 Comments

  1. duhh

    Еще можно добавить, что в конфигурациях на основе БСП есть подсистема работы с файлами, функционал подсистемы позволяет настроить работу пользователей с шаблонами.

    Reply
  2. script

    А таким образом можно все события в Ворде передавать в 1С?

    ДобавитьОбработчик Word.DocumentBeforeClose, ПередЗакрытиемДокументаWord;
    ДобавитьОбработчик Word.Quit, ВыходИзWord;
    Reply
  3. Eret1k

    (2) надо читать API COM WORD.Application. Может где-то и можно.

    Reply
  4. jaroslav.h
    Иногда возникает потребность дать пользователю самому редактировать макет печатной формы, в случае с табличным документом проблем реализации зачастую не возникает.

    натолкните на идею, как редактирование таб док пользователем реализовать?

    Reply
  5. it@contlog.ru

    (2) Можно событие печати / отслеживать из 1с.

    ДобавитьОбработчик Word.DocumentBeforePrint, ПередПечатьюДокумента;….

    …Процедура ПередПечатьюДокумента(WDocument, Cancel)

    Еще вопрос. что если документов подобным образом открытых у вас не 1 а несколько. Нужно как-то понять принадлежность дока к макету.

    Другой вопрос что будет если word открыт, а форму которая ловит события пользователь закрыл. Как оградить пользователя от этого действия?!

    Reply
  6. script

    Редактирование таб. пок. пользователем и так реализовано в всех типовых. В БП3 точно есть.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *