При выгрузке данных из 1С в офисные документы MS Word через COM-объект Word.Application разработчики часто сталкиваются с ситуацией, когда вместо ожидаемой даты в шаблоне остается пустая строка или заменяемый параметр вовсе пропадет. Рассмотрим подробно, почему возникают такие ошибки в коде 1С, проанализируем частые причины сбоя при вызове функции Формат() и научимся правильно передавать реквизиты в макет Word.
Разберем ключевые проблемы, с которыми сталкиваются при формировании печатных форм через механизмы COM-взаимодействия:
Дата содержит значение по умолчанию (пустая дата вида 01.01.0001 0:00:00), то функция Формат(Шапка.Дата, "ДФ=dd.MM.yyyy") возвращает пустую строку "". При поиске и замене метки в Word подставляется пустой текст, из-за чего создается ощущение, что дата не выводится.РеквизитыДокумента = Шапка.Номер превращает структуру в обычную строку, после чего обращение к свойству РеквизитыДокумента.Дата приводит к ошибке выполнения.ЭтотОбъект.СсылкаНаОбъект внутри серверных функций или внешних обработок без проверки на заполненность реквизитов может возвращать пустые значения.Find.Execute ищет метки только в основной области текста (Content). Если тег даты расположен в таблице, надписи или колонтитуле, замена стандартным вызовом не произойдет.Проанализируем ситуацию из практики. Разработчик пытается извлечь номер и дату документа с помощью запроса и передать их в замену меток [Дата] и [Номер] в шаблоне Word.
Посмотрим на ошибочный фрагмент кода получения данных:
Функция ПолучитьРеквизитыДокумента()
РеквизитыДокумента = Новый Структура ("Номер","Дата");
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| ПриемНаРаботуВОрганизацию.Номер,
| ПриемНаРаботуВОрганизацию.Дата
|ИЗ
| Документ.ПриемНаРаботуВОрганизацию КАК ПриемНаРаботуВОрганизацию
|ГДЕ
| ПриемНаРаботуВОрганизацию.Ссылка = &ТекущийДокумент";
Запрос.УстановитьПараметр("ТекущийДокумент", СсылкаНаОбъект);
Шапка = Запрос.Выполнить().Выбрать();
Шапка.Следующий();
// Ошибка 1: Перезапись всей структуры значением Номера!
РеквизитыДокумента = Шапка.Номер;
// Ошибка 2: Попытка обратиться к свойству "Дата" у строки:
РеквизитыДокумента.Дата = Формат(Шапка.Дата,"ДФ=dd.MM.yyyy");
Возврат РеквизитыДокумента;
КонецФункции
В данном фрагменте строка РеквизитыДокумента = Шапка.Номер полностью уничтожает ранее созданную структуру РеквизитыДокумента. Последующая попытка присвоения РеквизитыДокумента.Дата вызывает сбой.
Кроме того, при проверке через отладчик значение поля Шапка.Дата или ЭтотОбъект.Дата может оказаться незаполненным: 01.01.0001 0:00:00. Если дата в документе-источнике не установлена, метод Формат() вернет пустую строку, и Word подставит пустое место на место текстового маркера.
Исправим ошибки в коде. Сформируем структуру реквизитов корректно, организуем проверку даты на заполненность и реализуем надежную замену в документе Word через COM.
Функция ПолучитьРеквизитыДокумента()
РеквизитыДокумента = Новый Структура("Номер, Дата, Организация");
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ПриемНаРаботу.Номер КАК Номер,
| ПриемНаРаботу.Дата КАК Дата,
| ПриемНаРаботу.Организация КАК Организация
|ИЗ
| Документ.ПриемНаРаботуВОрганизацию КАК ПриемНаРаботу
|ГДЕ
| ПриемНаРаботу.Ссылка = &ТекущийДокумент";
Запрос.УстановитьПараметр("ТекущийДокумент", СсылкаНаОбъект);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
РеквизитыДокумента.Номер = СокрЛП(Выборка.Номер);
// Проверяем заполненность даты перед форматированием
Если ЗначениеЗаполнено(Выборка.Дата) Тогда
РеквизитыДокумента.Дата = Формат(Выборка.Дата, "ДФ=dd.MM.yyyy");
Иначе
РеквизитыДокумента.Дата = "_____г.";
КонецЕсли;
РеквизитыДокумента.Организация = СокрЛП(Строка(Выборка.Организация));
КонецЕсли;
Возврат РеквизитыДокумента;
КонецФункции
Процедура ПечатьВWord() Экспорт
Данные = ПолучитьРеквизитыДокумента();
ПутьКМакету = МакетПолучить(); // Получаем путь к временному doc-файлу
Если Не ЗначениеЗаполнено(ПутьКМакету) Тогда
Возврат;
КонецЕсли;
Попытка
Word = Новый COMОбъект("Word.Application");
Исключение
Сообщить("Не удалось запустить MS Word. Проверьте установку программы.");
Возврат;
КонецПопытки;
NewDoc = Word.Documents.Add(ПутьКМакету);
// Выполняем замену меток в документе
Замена = NewDoc.Content.Find;
// Замена даты
Замена.Execute("[Дата]", , , , , , , , , Данные.Дата, 2);
// Замена номера
Замена.Execute("[Номер]", , , , , , , , , Данные.Номер, 2);
// Замена организации
Замена.Execute("[Организация]", , , , , , , , , Данные.Организация, 2);
Word.Visible = Истина;
// Удаляем временный файл макета
УдалитьФайлы(ПутьКМакету);
КонецПроцедуры
Помимо прямого поиска текста с помощью Find.Execute, существуют более надежные способы заполнения шаблонов MS Word из 1С:
NewDoc.Bookmarks("ДатаДокумента").Range.Text = Данные.Дата;
Этот подход предотвращает случайное удаление меток или сбой поиска из-за форматирования текста.DOCVARIABLE "ИмяПеременной". Из кода 1С значения присваиваются коллекции переменных:
NewDoc.Variables.Item("ДатаДокумента").Value = Данные.Дата;
NewDoc.Fields.Update(); // Обновление всех полей в документе
.docx представляет собой ZIP-архив с XML-структурой) либо использовать механизмы Библиотеки Стандартных Подсистем (БСП) для генерации офисных документов.