При разработке отчетов по бухгалтерскому учету (например, аналогов оборотно-сальдовой ведомости или актов сверки) часто возникает необходимость присоединить к остаткам и оборотам регистра данные из документов или справочников. Начинающие разработчики сталкиваются с ситуацией, когда при попытке установить связь по полю Субконто1 с реквизитом типа СправочникСсылка.Контрагенты результат связи оказывается пустым или происходит искажение сумм. Разберем причинно-следственные связи этой проблемы и рассмотрим правильные способы решения как в обычных запросах, так и в системе компоновки данных (СКД).
Поле Субконто в регистре бухгалтерии имеет составной тип данных (Характеристика.ВидыСубконтоХозрасчетные). Когда в условии связи пишется конструкция вида:
ПО ХозрасчетныйОстаткиИОбороты.Субконто1.Ссылка = ВТ_АктыСверки.Контрагент.Ссылка
СУБД вынуждена выполнять неявные соединения со всеми таблицами, входящими в составной тип. Из-за отсутствия явного указания конкретного типа ссылочных данных СУБД может некорректно сопоставить значения или возвращать NULL. Кроме того, использование обращения через .Ссылка создаёт ненужные соединения и снижает производительность.
Рассмотрим, как правильно установить связь между таблицами в едином запросе. Для устранения неопределенности составного типа необходимо применить функцию ВЫРАЗИТЬ к полю Субконто1.
Пример корректного соединения таблиц в запросе:
ВЫБРАТЬ
ХозрасчетныйОстаткиИОбороты.Счет КАК Счет,
ХозрасчетныйОстаткиИОбороты.Субконто1 КАК Контрагент,
ХозрасчетныйОстаткиИОбороты.Субконто2 КАК Договор,
ХозрасчетныйОстаткиИОбороты.СуммаКонечныйОстатокДт КАК ОстатокДт,
ВТ_АктыСверки.СверкаСогласована КАК СверкаСогласована
ИЗ
РегистрБухгалтерии.Хозрасчетный.ОстаткиИОбороты(
&НачалоПериода,
&КонецПериода,
,
,
Счет В ИЕРАРХИИ (&Счет),
&МассивСубконто,
) КАК ХозрасчетныйОстаткиИОбороты
ЛЕВОЕ СОЕДИНЕНИЕ ВТ_АктыСверки КАК ВТ_АктыСверки
ПО (ВЫРАЗИТЬ(ХозрасчетныйОстаткиИОбороты.Субконто1 КАК Справочник.Контрагенты)) = ВТ_АктыСверки.Контрагент
Проанализируем частую ошибку, когда условия по счетам и видам субконто накладываются в секции ГДЕ, а не в параметрах виртуальной таблицы. Фильтрация в секции ГДЕ заставляет СУБД сначала рассчитать итоги по всем счетам регистра, а затем отсекать лишнее. Для максимальной производительности отборы необходимо передавать напрямую в параметры виртуальной таблицы ОстаткиИОбороты:
Счет.ВидыСубконто.ВидСубконто = &ВидСубконто передаем в параметр УсловиеСчета или Субконто массив нужных видов субконто.Счет В ИЕРАРХИИ (&Счет) помещаем в пятый параметр виртуальной таблицы УсловиеСчета.Рассмотрим пример формирования массива субконто в коде 1С:
МассивСубконто = Новый Массив;
МассивСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты);
МассивСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Договоры);
Запрос.УстановитьПараметр("МассивСубконто", МассивСубконто);
Запрос.УстановитьПараметр("Счет", ПланыСчетов.Хозрасчетный.РасчетыСПоставщикамиИПодрядчиками);
При левом соединении виртуальной таблицы регистра с таблицей документов нужно быть внимательными. Если один контрагент фигурирует в нескольких документах "Акт сверки взаиморасчетов", происходит связь «один ко многим», из-за чего суммы оборотов и остатков регистра удваиваются или кратно увеличиваются.
Чтобы избежать этой проблемы, данные во временной таблице ВТ_АктыСверки должны быть предварительно сгруппированы до одной строки на каждого контрагента (и договор, если требуется):
ВЫБРАТЬ
АктСверки.Контрагент КАК Контрагент,
МАКСИМУМ(АктСверки.СверкаСогласована) КАК СверкаСогласована,
СУММА(АктСверки.Расхождение) КАК Расхождение
ПОМЕСТИТЬ ВТ_АктыСверки
ИЗ
Документ.АктСверкиВзаиморасчетов КАК АктСверки
ГДЕ
АктСверки.Проведен = ИСТИНА
СГРУППИРОВАТЬ ПО
АктСверки.Контрагент;
Посмотрим на ситуацию, когда запрос отлично работает в Консоли запросов, но при переносе в СКД данные присоединенной таблицы перестают выводиться или запрос подменяется. Процессор компоновки данных автоматически оптимизирует и перестраивает SQL-запрос под текущие настройки пользователя.
Если возникла подобная проблема, разберем порядок действий:
НаборДанных_Бухгалтерия (выбирает остатки и обороты);НаборДанных_АктыСверки (выбирает сгруппированные сведения по актам сверки).НаборДанных_Бухгалтерия (поле Субконто1) связывается с приемником НаборДанных_АктыСверки (поле Контрагент). Это решение работает на уровне платформы, не искажает бухитоги и корректно сопоставляет типы данных.