Реализация протестирована на 1С 8.3.12.1714 (x64).
WARNING
Данная статья не претендует на оригинальность и не является конечным решением. Подходы решения задач и примеры программного кода несут исключительно обучающий характер. |
Иногда возникает потребность дать пользователю самому редактировать макет печатной формы, в случае с табличным документом проблем реализации зачастую не возникает. Но совсем другая ситуация когда результатом печатной формы должен быть документ Microsoft Word.
Некоторое время назад Я искал возможность открыть документ MS Word для редактирования и забирать его обратно в базу поcле закрытия.
Это можно реализовать через: ДобавитьОбработчик Word.Quit, ВыходИзWord;
Предусмотрел возможность редактирования нескольких макетов. Предполагается что макеты хранятся в виде двоичных данных (где хранить решать Вам).
Итак, приступим:
- Для начала опишу таблицу макетов:
- Заполнить таблицу макетов для редактирования:
&НаСервере Процедура ЗаполнитьМакеты() мОбъект = РеквизитФормыВЗначение("Объект"); // получаем макеты для изменений Для Каждого СтрМакет Из мОбъект.Метаданные().Макеты Цикл Если Строка(СтрМакет.ТипМакета) <> "ДвоичныеДанные" Тогда Продолжить; КонецЕсли; Макет = Макеты.Добавить(); ЗаполнитьЗначенияСвойств(Макет, СтрМакет); Макет.ДвоичныеДанные = мОбъект.ПолучитьМакет(СтрМакет.Имя) КонецЦикла; КонецПроцедуры
В данном примере макеты хранятся во внешней обработке, но по факту их можно хранить где угодно.
-
Открытие макета 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" на экране пользователя и навесить обработчики на его закрытие.
-
После окончания редактирования, перед закрытием "Word.Application" сохранить его:
&НаКлиенте Процедура ПередЗакрытиемДокументаWord(Документ, Отмена) Экспорт Документ.Save(); КонецПроцедуры
-
Во время закрытия файла "Word.Application" загрузить его обратно в таблицу макетов:
&НаКлиенте Процедура ВыходИзWord() Экспорт Для Каждого СтрМакет Из Макеты Цикл Файл = Новый Файл(СтрМакет.ИмяВременногоФайла); Если НЕ Файл.Существует() Тогда Продолжить; КонецЕсли; ДвоичныеДанные = Новый ДвоичныеДанные(СтрМакет.ИмяВременногоФайла); // если макет был изменен Если СтрМакет.ДвоичныеДанные <> ДвоичныеДанные Тогда СтрМакет.Изменен = Истина; СтрМакет.ДвоичныеДанные = ДвоичныеДанные; СтрМакет.Ответственный = Пользователь; ЭтаФорма.Модифицированность = Истина; КонецЕсли; КонецЦикла; КонецПроцедуры
Этапы загрузки макета в базу:
- Прочитать все строки таблицы макетов;
- Получить те, которые были сохранены в файл;
- Получить двоичные данные из сохраненных файлов;
- Сравнить изменены ли данные;
- В случае изменения — записать новые данные в таблицу.
Описание применения:
Программный код или всю форму можно перенести во внешнюю печатную форму (обработку) и хранить измененные макеты в РегистрСведений.БезопасноеХранилищеДанных или Справочник.ДополнительныеОтчетыИОбработки.ХранилищеНастроек, где перед началом заполнения макета, проверять наличие его модификации в системе.
Модифицированный таким образом макет MS Word совместим со стандартной подсистемой печати и может быть использован в УправлениеПечатьюКлиент.ИнициализироватьМакетОфисногоДокумента(ДвоичыеДанные, "DOC");
Еще можно добавить, что в конфигурациях на основе БСП есть подсистема работы с файлами, функционал подсистемы позволяет настроить работу пользователей с шаблонами.
А таким образом можно все события в Ворде передавать в 1С?
(2) надо читать API COM WORD.Application. Может где-то и можно.
натолкните на идею, как редактирование таб док пользователем реализовать?
(2) Можно событие печати / отслеживать из 1с.
ДобавитьОбработчик Word.DocumentBeforePrint, ПередПечатьюДокумента;….
…Процедура ПередПечатьюДокумента(WDocument, Cancel)
Еще вопрос. что если документов подобным образом открытых у вас не 1 а несколько. Нужно как-то понять принадлежность дока к макету.
Другой вопрос что будет если word открыт, а форму которая ловит события пользователь закрыл. Как оградить пользователя от этого действия?!
Редактирование таб. пок. пользователем и так реализовано в всех типовых. В БП3 точно есть.