При формировании печатных форм и отчетов разработчики часто сталкиваются с задачей параллельного вывода двух списков, которые не имеют общих ключей связи в базе данных — например, начислений и удержаний сотрудника. Разберем подробнее, с какими ошибками можно столкнуться при решении этой задачи и какими способами можно реализовать вывод таких данных.
Разберем типичную ошибку, возникающую при попытке динамического заполнения произвольной ячейки табличного документа. Посмотрим на код, который приводит к сбою:
ОбластьСтрок = ТабДок.Область("R9C7:R9C9");
ОбластьСтрок.Параметр.УДЕРЖАНИЯ = "***"; // Ошибка: Значение не является значением объектного типа
Выясним причину этой ошибки. Объект ОбластьЯчеекТабличногоДокумента не имеет свойства Параметр в единственном числе. Коллекция параметров макета называется Параметры (во множественном числе), и обращаться к ней можно только тогда, когда область получена из макета методом ПолучитьОбласть(), а тип заполнения ячейки установлен в значение «Параметр».
Если мы обращаемся к произвольному диапазону ячеек по адресу (например, "R9C7:R9C9"), то для установки строкового значения необходимо напрямую использовать свойство Текст:
ОбластьСтрок = ТабДок.Область("R9C7:R9C9");
ОбластьСтрок.Текст = "Значение удержания";
Важное примечание: свойство Текст доступно для записи только в том случае, если ячейка не содержит установленного значения (свойство СодержитЗначение равно Ложь).
Рассмотрим, как скомпоновать два независимых списка в табличном документе программно. Для этого разделим макет на две области: левую (для начислений) и правую (для удержаний).
Алгоритм решения заключается в последовательном обходе двух таблиц с использованием метода Присоединить():
Вывести().Присоединить().Проанализируем пример реализации данного подхода:
МаксСтрок = Макс(ТаблицаНачислений.Количество(), ТаблицаУдержаний.Количество());
Для Индекс = 0 По МаксСтрок - 1 Цикл
// Заполняем начисления
ОбластьЛевая = Макет.ПолучитьОбласть("СтрокаНачисления");
Если Индекс < ТаблицаНачислений.Количество() Тогда
СтрокаНач = ТаблицаНачислений[Индекс];
ОбластьЛевая.Параметры.ВидРасчета = СтрокаНач.ВидРасчета;
ОбластьЛевая.Параметры.Сумма = СтрокаНач.Сумма;
Иначе
ОбластьЛевая.Параметры.ВидРасчета = "";
ОбластьЛевая.Параметры.Сумма = 0;
КонецЕсли;
ТабДок.Вывести(ОбластьЛевая);
// Присоединяем удержания справа
ОбластьПравая = Макет.ПолучитьОбласть("СтрокаУдержания");
Если Индекс < ТаблицаУдержаний.Количество() Тогда
СтрокаУдерж = ТаблицаУдержаний[Индекс];
ОбластьПравая.Параметры.ВидРасчета = СтрокаУдерж.ВидРасчета;
ОбластьПравая.Параметры.Сумма = СтрокаУдерж.Сумма;
Иначе
ОбластьПравая.Параметры.ВидРасчета = "";
ОбластьПравая.Параметры.Сумма = 0;
КонецЕсли;
ТабДок.Присоединить(ОбластьПравая);
КонецЦикла;
Если требуется получить готовый результат одним запросом без усложнения кода обхода табличного документа, проанализируем вариант связывания по автономному номеру строки.
Сформируем две временные таблицы с нумерацией строк и свяжем их через ПОЛНОЕ СОЕДИНЕНИЕ:
ВЫБРАТЬ
Начисления.ВидРасчета КАК ВидНачисления,
Начисления.Сумма КАК СуммаНачисления,
АВТОНОМЕРСТРОКИ() КАК НомерСтроки
ПОМЕСТИТЬ ВТ_Начисления
ИЗ
&ТаблицаНачислений КАК Начисления
;
ВЫБРАТЬ
Удержания.ВидРасчета КАК ВидУдержания,
Удержания.Сумма КАК СуммаУдержания,
АВТОНОМЕРСТРОКИ() КАК НомерСтроки
ПОМЕСТИТЬ ВТ_Удержания
ИЗ
&ТаблицаУдержаний КАК Удержания
;
ВЫБРАТЬ
ЕСТЬНУЛЛ(ВТ_Начисления.ВидНачисления, "") КАК ВидНачисления,
ЕСТЬНУЛЛ(ВТ_Начисления.СуммаНачисления, 0) КАК СуммаНачисления,
ЕСТЬНУЛЛ(ВТ_Удержания.ВидУдержания, "") КАК ВидУдержания,
ЕСТЬНУЛЛ(ВТ_Удержания.СуммаУдержания, 0) КАК СуммаУдержания
ИЗ
ВТ_Начисления КАК ВТ_Начисления
ПОЛНОЕ СОЕДИНЕНИЕ ВТ_Удержания КАК ВТ_Удержания
ПО ВТ_Начисления.НомерСтроки = ВТ_Удержания.НомерСтроки
В результате выборки получим единую таблицу, где на каждой строке расположены данные одного начисления и одного удержания, что позволяет вывести отчет простым обходом выборки.
В отчетах на базе СКД решение реализуется еще проще. Для этого выполним следующие шаги:
Каждый из описанных способов позволяет эффективно решить задачу параллельного вывода независимых списков и обеспечивает полный контроль над формированием итогового документа.