При работе с конфигурацией 1С:Управление торговлей 11.4 у разработчиков часто возникает задача по дополнению стандартных печатных форм информацией, хранящейся в дополнительных реквизитах или сведениях документов. В этом руководстве мы подробно рассмотрим, как получить и вывести в печатную форму документа "Заказ клиента" значения дополнительных свойств (сведений), которые, как правило, хранятся отдельно от самого объекта документа.
Разберем конкретную ситуацию, когда требуется получить значение дополнительного свойства, например, "МетодОплаты" или "Сайт", для печатной формы "Заказа клиента". Мы выясним, как правильно модифицировать запрос, используемый для формирования печатной формы, чтобы включить эти данные, и почему прямая работа с объектом может быть неэффективной для массовой печати.
Прежде чем мы перейдем к решению, крайне важно четко понимать разницу между дополнительными реквизитами и дополнительными сведениями в 1С. Это ключевой момент, который влияет на способ их получения.
ДополнительныеРеквизиты.ДополнительныеСведения.В нашем случае, когда мы говорим о "дополнительных свойствах" и обращаемся к РегистрСведений.ДополнительныеСведения, мы имеем в виду именно дополнительные сведения.
В конфигурации 1С:УТ 11.4 данные для печатных форм документов, таких как "Заказ клиента", обычно формируются в модуле менеджера соответствующего документа. Для "Заказа клиента" это будет:
Внутри этого модуля вы найдете функцию, отвечающую за сбор данных для печатной формы, которая выглядит примерно так:
Функция ПолучитьДанныеДляПечатнойФормыЗаказаНаТоварыУслуги(МассивОбъектов, ПараметрыПечати) Экспорт
Если ПараметрыПечати <> Неопределено И ПараметрыПечати.Свойство("ОтображатьСкидки") Тогда
ОтображатьСкидки = ПараметрыПечати.ОтображатьСкидки;
Иначе
ОтображатьСкидки = (Константы.ОтображениеСкидокВПечатныхФормахДокументовПродажи.Получить()
<> Перечисления.ВариантыВыводаСкидокВПечатныхФормах.НеВыводитьСкидки);
КонецЕсли;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Документы.Ссылка КАК Ссылка,
| Документы.Номер КАК Номер,
| Документы.Дата КАК Дата,
| Документы.АдресДоставки КАК АдресДоставки,
| Документы.Организация КАК Организация,
| Документы.Организация КАК Исполнитель,
| Документы.ЖелаемаяДатаОтгрузки КАК ЖелаемаяДатаОтгрузки,
| Документы.ВремяДоставкиС КАК ВремяДоставкиС,
// ... другие поля документа
|ИЗ
| Документ.ЗаказКлиента КАК Документы
|ГДЕ
| Документы.Ссылка В(&МассивОбъектов)";
// ... остальной код
Именно в этот запрос нам предстоит внести изменения.
Для эффективного получения дополнительных сведений по одному или нескольким документам (что особенно важно при массовой печати) рекомендуется использовать механизм запросов с ЛЕВОЕ СОЕДИНЕНИЕ. Это позволяет избежать проблемы "N+1 запросов", когда для каждого объекта в цикле выполняется отдельный запрос к базе данных, что существенно замедляет работу.
Разберем шаги по модификации запроса:
Нам потребуется выбрать само значение свойства, а также для отладки можно вывести ссылку на объект и имя свойства. Добавим эти поля в начало или середину списка ВЫБРАТЬ вашего запроса:
"ВЫБРАТЬ
| Документы.Ссылка КАК Ссылка,
| Документы.Номер КАК Номер,
| Документы.Дата КАК Дата,
| // ... другие поля документа
| ДопСвойство1.Объект.Ссылка КАК ОбъектСсылка,
| ДопСвойство1.Свойство.Имя КАК СвойствоИмя,
| ДопСвойство1.Значение КАК Сайт,
| ДопСвойство2.Значение КАК МетодОплаты,
| ДопСвойство3.Значение КАК КомментарииПокупателя
// ...
Обратите внимание, что мы используем псевдонимы, такие как Сайт, МетодОплаты, КомментарииПокупателя, для удобства доступа к значениям в дальнейшем.
ЛЕВОЕ СОЕДИНЕНИЕ с РегистрСведений.ДополнительныеСведения.
Этот регистр содержит все дополнительные сведения для различных объектов. Нам нужно присоединить его к таблице документов Документ.ЗаказКлиента.
Добавьте следующие блоки после основной таблицы документа Документ.ЗаказКлиента КАК Документы:
|ИЗ
| Документ.ЗаказКлиента КАК Документы
|
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДополнительныеСведения КАК ДопСвойство1
| ПО Документы.Ссылка = ДопСвойство1.Объект
| И (ДопСвойство1.Свойство = &ПараметрСвойствоСайт)
|
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДополнительныеСведения КАК ДопСвойство2
| ПО Документы.Ссылка = ДопСвойство2.Объект
| И (ДопСвойство2.Свойство = &ПараметрСвойствоМетодОплаты)
|
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДополнительныеСведения КАК ДопСвойство3
| ПО Документы.Ссылка = ДопСвойство3.Объект
| И (ДопСвойство3.Свойство = &ПараметрСвойствоКомментарииПокупателя)
// ...
Важные моменты:
ЛЕВОЕ СОЕДИНЕНИЕ гарантирует, что даже если у документа нет заданного дополнительного свойства, он все равно будет включен в результат, а соответствующее поле со значением свойства будет NULL (или Неопределено в 1С).Документы.Ссылка = ДопСвойство1.Объект связывает запись регистра сведений с конкретным документом.ДопСвойство1.Свойство = &ПараметрСвойства фильтрует записи регистра по конкретному дополнительному свойству. Для каждого нужного свойства необходимо свое отдельное левое соединение и свой параметр.РегистрСведений.ДополнительныеСведения (без "Ы" на конце), в отличие от программного кода, где будет РегистрыСведений.ДополнительныеСведения (с "Ы").Теперь необходимо установить значения для параметров запроса &ПараметрСвойствоСайт, &ПараметрСвойствоМетодОплаты, &ПараметрСвойствоКомментарииПокупателя. Эти параметры должны содержать ссылки на сами объекты свойств, которые хранятся в плане видов характеристик.
После формирования текста запроса, но до его выполнения, добавьте строки для установки параметров:
// ... после Запрос.Текст = "..."
Запрос.УстановитьПараметр("МассивОбъектов", МассивОбъектов);
Запрос.УстановитьПараметр("ПараметрСвойствоСайт",
ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Сайт"));
Запрос.УстановитьПараметр("ПараметрСвойствоМетодОплаты",
ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("МетодОплаты"));
Запрос.УстановитьПараметр("ПараметрСвойствоКомментарииПокупателя",
ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Комментарии покупателя"));
// ... Запрос.Выполнить().Выгрузить() и т.д.
Важные моменты:
НайтиПоНаименованию() из плана видов характеристик ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.ПланыВидовХарактеристик (с "Ы" на конце).После выполнения запроса, вы получите табличную часть или массив со всеми данными для печатной формы, включая ваши дополнительные свойства. Например, если вы назвали поле Сайт, то в результате запроса оно будет доступно как РезультатЗапроса.Сайт.
Обычно эти данные передаются в другой модуль (например, модуль менеджера обработки ПечатьЗаказовНаТоварыУслуги) в параметре ДанныеДляПечати.
Давайте посмотрим, как будет выглядеть функция ПолучитьДанныеДляПечатнойФормыЗаказаНаТоварыУслуги с интегрированными дополнительными свойствами:
Функция ПолучитьДанныеДляПечатнойФормыЗаказаНаТоварыУслуги(МассивОбъектов, ПараметрыПечати) Экспорт
Если ПараметрыПечати <> Неопределено И ПараметрыПечати.Свойство("ОтображатьСкидки") Тогда
ОтображатьСкидки = ПараметрыПечати.ОтображатьСкидки;
Иначе
ОтображатьСкидки = (Константы.ОтображениеСкидокВПечатныхФормахДокументовПродажи.Получить()
<> Перечисления.ВариантыВыводаСкидокВПечатныхФормах.НеВыводитьСкидки);
КонецЕсли;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Документы.Ссылка КАК Ссылка,
| Документы.Номер КАК Номер,
| Документы.Дата КАК Дата,
| Документы.АдресДоставки КАК АдресДоставки,
| Документы.Организация КАК Организация,
| Документы.Организация КАК Исполнитель,
| Документы.ЖелаемаяДатаОтгрузки КАК ЖелаемаяДатаОтгрузки,
| Документы.ВремяДоставкиС КАК ВремяДоставкиС,
| Документы.ВремяДоставкиПо КАК ВремяДоставкиПо,
| ДопСвойствоСайт.Значение КАК Сайт,
| ДопСвойствоМетодОплаты.Значение КАК МетодОплаты,
| ДопСвойствоКомментарииПокупателя.Значение КАК КомментарииПокупателя
// ... другие поля из документа, если они есть
|ИЗ
| Документ.ЗаказКлиента КАК Документы
|
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДополнительныеСведения КАК ДопСвойствоСайт
| ПО Документы.Ссылка = ДопСвойствоСайт.Объект
| И (ДопСвойствоСайт.Свойство = &ПараметрСвойствоСайт)
|
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДополнительныеСведения КАК ДопСвойствоМетодОплаты
| ПО Документы.Ссылка = ДопСвойствоМетодОплаты.Объект
| И (ДопСвойствоМетодОплаты.Свойство = &ПараметрСвойствоМетодОплаты)
|
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДополнительныеСведения КАК ДопСвойствоКомментарииПокупателя
| ПО Документы.Ссылка = ДопСвойствоКомментарииПокупателя.Объект
| И (ДопСвойствоКомментарииПокупателя.Свойство = &ПараметрСвойствоКомментарииПокупателя)
// ... другие левые соединения для табличных частей документа
|ГДЕ
| Документы.Ссылка В(&МассивОбъектов)
// ... прочие условия
|УПОРЯДОЧИТЬ ПО
| Документы.МоментВремени";
Запрос.УстановитьПараметр("МассивОбъектов", МассивОбъектов);
Запрос.УстановитьПараметр("ПараметрСвойствоСайт",
ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Сайт"));
Запрос.УстановитьПараметр("ПараметрСвойствоМетодОплаты",
ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Метод оплаты")); // Пример с пробелом
Запрос.УстановитьПараметр("ПараметрСвойствоКомментарииПокупателя",
ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Комментарии покупателя"));
// ... остальной код функции
// Результат запроса, который будет использоваться для заполнения печатной формы
Возврат Запрос.Выполнить().Выгрузить();
КонецФункции
После того, как данные о дополнительных свойствах будут получены запросом и возвращены функцией ПолучитьДанныеДляПечатнойФормыЗаказаНаТоварыУслуги, они станут доступны в структуре, которая передается в процедуру заполнения табличного документа. Обычно это происходит в модуле менеджера обработки печати, например, в Обработки.ПечатьЗаказовНаТоварыУслуги.МодульМенеджера, в процедуре ЗаполнитьТабличныйДокументЗаказаНаТоварыУслуги(ТабличныйДокумент, ДанныеДляПечати, ОбъектыПечати, ИмяМакета).
В этой процедуре вы можете обратиться к полученным данным и разместить их в соответствующих областях макета:
В конфигураторе перейдите в "Обработки" -> "ПечатьЗаказовНаТоварыУслуги". Разверните ее и найдите нужный макет (например, "МакетЗаказаНаТоварыУслуги").
В нужной области макета (например, в "Шапке" или "Подвале") добавьте параметры, которые будут соответствовать названиям полей, полученных из запроса. Например, для свойства "Сайт" вы добавите параметр &Сайт.
В процедуре ЗаполнитьТабличныйДокументЗаказаНаТоварыУслуги найдите место, где происходит заполнение соответствующей области макета. Затем используйте метод УстановитьПараметр или прямой доступ к полям для передачи значения:
// Предполагаем, что ДанныеПечати - это строка результата запроса
// или элемент коллекции, содержащий поля запроса
// Например, если обрабатывается один документ:
ОбластьШапка.Параметры.Сайт = ДанныеПечати.Сайт;
ОбластьШапка.Параметры.МетодОплаты = ДанныеПечати.МетодОплаты;
ОбластьШапка.Параметры.КомментарииПокупателя = ДанныеПечати.КомментарииПокупателя;
// Если ДанныеДляПечати - это коллекция (например, ТаблицаЗначений)
// и мы в цикле по ней:
Для Каждого СтрокаДанных Из ДанныеДляПечати Цикл
// ...
ОбластьМакета.Параметры.Сайт = СтрокаДанных.Сайт;
// ...
ТабличныйДокумент.Вывести(ОбластьМакета);
КонецЦикла;
В Библиотеке стандартных подсистем (БСП) конфигурации 1С:УТ 11.4 существует общий модуль УправлениеСвойствами, который предоставляет функции для работы с дополнительными реквизитами и сведениями. Одна из таких функций - УправлениеСвойствами.ЗначениеСвойства(Объект, Свойство, КодЯзыка).
Её параметры:
Объект: Ссылка на объект (например, ДокументСсылка.ЗаказКлиента).Свойство: Ссылка на дополнительный реквизит/сведение (ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения) или его наименование (строка).КодЯзыка: Необязательный параметр для получения представления значения на указанном языке.Пример использования в коде:
// Где-то в коде обработки или модуля объекта:
СсылкаНаЗаказ = Документы.Ссылка; // Получаем ссылку на текущий заказ
ЗначениеСайт = УправлениеСвойствами.ЗначениеСвойства(СсылкаНаЗаказ, "Сайт");
ЗначениеМетодОплаты = УправлениеСвойствами.ЗначениеСвойства(СсылкаНаЗаказ, "Метод оплаты");
// Затем эти значения можно использовать для заполнения параметров макета
// ОбластьМакета.Параметры.Сайт = ЗначениеСайт;
Хотя этот метод удобен для получения значения одного свойства для одного объекта, он не является оптимальным для массовой печати. Если у вас в МассивОбъектов будет сто документов, и для каждого из них вы будете в цикле вызывать УправлениеСвойствами.ЗначениеСвойства(), это приведет к выполнению отдельного запроса к базе данных для каждого вызова функции, что значительно увеличит время формирования печатной формы. Поэтому для случаев, подобных печати, где необходимо агрегировать данные по множеству объектов, использование запроса с ЛЕВОЕ СОЕДИНЕНИЕ является более производительным и предпочтительным решением.
НайтиПоНаименованию(), полностью совпадает с наименованием, заданным для этого свойства в режиме 1С:Предприятие через "НСИ и администрирование – Общие настройки – Свойства – Дополнительные реквизиты и сведения". Регистр букв и пробелы имеют значение.
ЛЕВОЕ СОЕДИНЕНИЕ наиболее эффективен, когда вам нужно получить данные сразу для нескольких документов или когда эти данные нужны в большом объеме.
Следуя этим шагам и рекомендациям, вы сможете успешно вывести дополнительные свойства документа "Заказ клиента" в печатную форму в 1С:УТ 11.4.