Разработка внешних печатных форм (ВПФ) формата Microsoft Word (DOCX) с применением библиотеки стандартных подсистем (БСП) — частая задача при автоматизации документооборота. При выводе контактных данных (в частности, адресов контрагентов или организаций) разработчики нередко сталкиваются с ошибками выполнения запросов и системными исключениями механизма печати, такими как «Не задано значение параметра» и «Не определен список получаемых файлов».
Разберем по шагам причины возникновения этих сбоев, выясним, почему в готовый документ может не попадать адрес, и рассмотрим правильную реализацию выборки данных и заполнения шаблона.
Проанализируем первую ошибку, с которой сталкивается разработчик: Не задано значение параметра "Контрагент". Она возникает, когда вызов метода Выполнить() происходит до того, как в объекте Запрос инициализированы все параметры, объявленные в его тексте.
Посмотрим на ошибочный фрагмент кода:
// ОШИБКА: Запрос выполняется и сразу выгружается до заполнения параметров "Контрагент" и "ВидКИ"
Возврат ОбщегоНазначения.ТаблицаЗначенийВМассив(Запрос.Выполнить().Выгрузить());
СсылкаНаКонтрагента = Справочники.Контрагенты.НайтиПоРеквизиту("ИНН", 1111111111);
Запрос.УстановитьПараметр("Контрагент", СсылкаНаКонтрагента);
Запрос.УстановитьПараметр("ВидКИ", Справочники.ВидыКонтактнойИнформации.ЮрАдресКонтрагента);
Код, расположенный после оператора Возврат, является недостижимым. В результате платформа пытается выполнить запрос, содержащий параметры &Контрагент и &ВидКИ, значения которых еще не были переданы в коллекцию Запрос.Параметры.
Все параметры запроса обязательно должны быть установлены строго до вызова метода Запрос.Выполнить().
После механического переноса параметров наверх нередко возникает следующая ошибка: Не определен список получаемых файлов. Данное исключение генерируется клиентской частью подсистемы УправлениеПечатью БСП в тех случаях, когда соответствие ОфисныеДокументы возвращается пустым (количество элементов равно нулю).
Выясним причину, почему результирующая выборка оказывается пустой:
ИНН справочника Контрагенты имеет тип Строка. Если выполнить поиск Справочники.Контрагенты.НайтиПоРеквизиту("ИНН", 1435262677), передав число вместо строки, метод не найдет элемент и вернет пустую ссылку.СтроковыеФункцииКлиентСервер.ВставитьПараметрыВСтроку по шаблону Заказ покупателя №[Номер] от [Дата] в структуре параметров должно присутствовать поле Номер, которое часто забывают выбрать в тексте запроса.Если запрос выполняется без ошибок, но поле адреса в файле Word остается пустым, рассмотрим типичные источники проблемы:
{v8 ИмяПараметра}. Если при наборе шаблона в Word параметр форматировался по частям (менялся шрифт, исправлялись опечатки), редактор разбивает строку на разные XML-узлы. Для БСП параметр перестает существовать. Решение: удалить параметр из макета и набрать его заново с клавиатуры единым слитным текстом без смены стилей внутри фигурных скобок.ЮрАдресКонтрагента. Однако если контрагент является физическим лицом или самозанятым, юридический адрес у него отсутствует. В таких случаях данные заносятся в виды АдресПоПропискеКонтрагента или ФактАдресКонтрагента. При жестком отборе только по юридическому адресу левое соединение возвращает значение NULL.Справочник.Организации.КонтактнаяИнформация, а не к контактной информации контрагентов.Объединим выборку реквизитов документа и контактной информации в один запрос с помощью левого соединения. Связывать таблицы следует напрямую по ссылке на контрагента из самого документа, без искусственного поиска по ИНН.
Посмотрим на правильную реализацию функции получения данных:
Функция ПолучитьДанныеДляПечати(МассивОбъектов)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| &ДатаПечати КАК ДатаПечати,
| Поступление.Ссылка КАК Ссылка,
| Поступление.Номер КАК Номер,
| Поступление.Дата КАК Дата,
| Поступление.Организация КАК Заказчик,
| Поступление.Организация.ИНН КАК ЗаказчикИНН,
| Поступление.Организация.ОГРН КАК ЗаказчикОГРН,
| Поступление.Контрагент КАК Самозанятый,
| Поступление.Контрагент.ИНН КАК ИННСамозанятого,
| ВЫБОР
| КОГДА КонтрагентыКИ.Представление ЕСТЬ NULL ТОГДА """"
| ИНАЧЕ КонтрагентыКИ.Представление
| КОНЕЦ КАК АдресСамозанятого
|ИЗ
| Документ.ПоступлениеТоваровУслуг КАК Поступление
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты.КонтактнаяИнформация КАК КонтрагентыКИ
| ПО Поступление.Контрагент = КонтрагентыКИ.Ссылка
| И КонтрагентыКИ.Тип = ЗНАЧЕНИЕ(Перечисление.ТипыКонтактнойИнформации.Адрес)
| И (КонтрагентыКИ.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.ЮрАдресКонтрагента)
| ИЛИ КонтрагентыКИ.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.АдресПоПропискеКонтрагента)
| ИЛИ КонтрагентыКИ.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.ФактАдресКонтрагента))
|ГДЕ
| Поступление.Ссылка В(&МассивДоговоров)";
Запрос.УстановитьПараметр("ДатаПечати", ТекущаяДатаСеанса());
Запрос.УстановитьПараметр("МассивДоговоров", МассивОбъектов);
ТаблицаДанных = Запрос.Выполнить().Выгрузить();
Возврат ОбщегоНазначения.ТаблицаЗначенийВМассив(ТаблицаДанных);
КонецФункции
Для гарантированного получения контактной информации с учетом всех настроек конфигурации рекомендуется использовать типовой программный интерфейс БСП — общий модуль УправлениеКонтактнойИнформацией.
Разберем пример, как получить представление адреса контрагента программно при обходе строк выборки:
// Получение адреса через экспортную функцию БСП
ВидАдреса = Справочники.ВидыКонтактнойИнформации.ЮрАдресКонтрагента;
ПредставлениеАдреса = УправлениеКонтактнойИнформацией.КонтактнаяИнформацияОбъекта(
ДанныеПечати.Самозанятый,
ВидАдреса,
ТекущаяДатаСеанса(),
Истина
);
// Если юридический адрес не заполнен (например, для физлица), проверяем фактический
Если ПустаяСтрока(ПредставлениеАдреса) Тогда
ВидАдреса = Справочники.ВидыКонтактнойИнформации.ФактАдресКонтрагента;
ПредставлениеАдреса = УправлениеКонтактнойИнформацией.КонтактнаяИнформацияОбъекта(
ДанныеПечати.Самозанятый,
ВидАдреса,
ТекущаяДатаСеанса(),
Истина
);
КонецЕсли;
ДанныеПечати.Вставить("АдресСамозанятого", ПредставлениеАдреса);
Такой подход делает код устойчивым к изменениям структуры хранения контактной информации в будущих релизах конфигурации и исключает ошибки связывания таблиц в сложных запросах.