Как связать Субконто со справочником в запросах 1С и СКД?

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия Бухгалтерский учет IT и автоматизация бизнеса
← На главную

При разработке отчетов по бухгалтерскому учету (например, аналогов оборотно-сальдовой ведомости или актов сверки) часто возникает необходимость присоединить к остаткам и оборотам регистра данные из документов или справочников. Начинающие разработчики сталкиваются с ситуацией, когда при попытке установить связь по полю Субконто1 с реквизитом типа СправочникСсылка.Контрагенты результат связи оказывается пустым или происходит искажение сумм. Разберем причинно-следственные связи этой проблемы и рассмотрим правильные способы решения как в обычных запросах, так и в системе компоновки данных (СКД).

Выясним причину: почему не работает прямая связь по Субконто

Поле Субконто в регистре бухгалтерии имеет составной тип данных (Характеристика.ВидыСубконтоХозрасчетные). Когда в условии связи пишется конструкция вида:


ПО ХозрасчетныйОстаткиИОбороты.Субконто1.Ссылка = ВТ_АктыСверки.Контрагент.Ссылка

СУБД вынуждена выполнять неявные соединения со всеми таблицами, входящими в составной тип. Из-за отсутствия явного указания конкретного типа ссылочных данных СУБД может некорректно сопоставить значения или возвращать NULL. Кроме того, использование обращения через .Ссылка создаёт ненужные соединения и снижает производительность.

Способ 1. Явное приведение типов с помощью ВЫРАЗИТЬ

Рассмотрим, как правильно установить связь между таблицами в едином запросе. Для устранения неопределенности составного типа необходимо применить функцию ВЫРАЗИТЬ к полю Субконто1.

Пример корректного соединения таблиц в запросе:


ВЫБРАТЬ
	ХозрасчетныйОстаткиИОбороты.Счет КАК Счет,
	ХозрасчетныйОстаткиИОбороты.Субконто1 КАК Контрагент,
	ХозрасчетныйОстаткиИОбороты.Субконто2 КАК Договор,
	ХозрасчетныйОстаткиИОбороты.СуммаКонечныйОстатокДт КАК ОстатокДт,
	ВТ_АктыСверки.СверкаСогласована КАК СверкаСогласована
ИЗ
	РегистрБухгалтерии.Хозрасчетный.ОстаткиИОбороты(
		&НачалоПериода,
		&КонецПериода,
		,
		,
		Счет В ИЕРАРХИИ (&Счет),
		&МассивСубконто,
		) КАК ХозрасчетныйОстаткиИОбороты
		ЛЕВОЕ СОЕДИНЕНИЕ ВТ_АктыСверки КАК ВТ_АктыСверки
		ПО (ВЫРАЗИТЬ(ХозрасчетныйОстаткиИОбороты.Субконто1 КАК Справочник.Контрагенты)) = ВТ_АктыСверки.Контрагент

Способ 2. Оптимизация параметров виртуальной таблицы

Проанализируем частую ошибку, когда условия по счетам и видам субконто накладываются в секции ГДЕ, а не в параметрах виртуальной таблицы. Фильтрация в секции ГДЕ заставляет СУБД сначала рассчитать итоги по всем счетам регистра, а затем отсекать лишнее. Для максимальной производительности отборы необходимо передавать напрямую в параметры виртуальной таблицы ОстаткиИОбороты:

  1. Отбор по видам субконто: Вместо условия Счет.ВидыСубконто.ВидСубконто = &ВидСубконто передаем в параметр УсловиеСчета или Субконто массив нужных видов субконто.
  2. Иерархический отбор по счету: Условие Счет В ИЕРАРХИИ (&Счет) помещаем в пятый параметр виртуальной таблицы УсловиеСчета.

Рассмотрим пример формирования массива субконто в коде 1С:


МассивСубконто = Новый Массив;
МассивСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты);
МассивСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Договоры);

Запрос.УстановитьПараметр("МассивСубконто", МассивСубконто);
Запрос.УстановитьПараметр("Счет", ПланыСчетов.Хозрасчетный.РасчетыСПоставщикамиИПодрядчиками);

Способ 3. Предотвращение удваивания итогов (двухэтапная обработка)

При левом соединении виртуальной таблицы регистра с таблицей документов нужно быть внимательными. Если один контрагент фигурирует в нескольких документах "Акт сверки взаиморасчетов", происходит связь «один ко многим», из-за чего суммы оборотов и остатков регистра удваиваются или кратно увеличиваются.

Чтобы избежать этой проблемы, данные во временной таблице ВТ_АктыСверки должны быть предварительно сгруппированы до одной строки на каждого контрагента (и договор, если требуется):


ВЫБРАТЬ
	АктСверки.Контрагент КАК Контрагент,
	МАКСИМУМ(АктСверки.СверкаСогласована) КАК СверкаСогласована,
	СУММА(АктСверки.Расхождение) КАК Расхождение
ПОМЕСТИТЬ ВТ_АктыСверки
ИЗ
	Документ.АктСверкиВзаиморасчетов КАК АктСверки
ГДЕ
	АктСверки.Проведен = ИСТИНА
СГРУППИРОВАТЬ ПО
	АктСверки.Контрагент;

Особенности работы с СКД (Схема компоновки данных)

Посмотрим на ситуацию, когда запрос отлично работает в Консоли запросов, но при переносе в СКД данные присоединенной таблицы перестают выводиться или запрос подменяется. Процессор компоновки данных автоматически оптимизирует и перестраивает SQL-запрос под текущие настройки пользователя.

Если возникла подобная проблема, разберем порядок действий:

  1. Проверить выбранные поля: Если поля из левого соединения не включены в структуру отчета (в выбранные поля группировок или детальных записей), СКД может полностью вырезать соединение из итогового запроса.
  2. Использовать связи наборов данных: Вместо объединения таблиц внутри одного текста запроса рекомендуется разделить логику на два набора данных:
    • НаборДанных_Бухгалтерия (выбирает остатки и обороты);
    • НаборДанных_АктыСверки (выбирает сгруппированные сведения по актам сверки).
    Затем на вкладке Связи наборов данных настраивается связь: источник НаборДанных_Бухгалтерия (поле Субконто1) связывается с приемником НаборДанных_АктыСверки (поле Контрагент). Это решение работает на уровне платформы, не искажает бухитоги и корректно сопоставляет типы данных.
  3. Отключить автозаполнение (при необходимости): На вкладке «Наборы данных» можно снять флаг «Автозаполнение» и явно прописать ролевую адресацию полей и параметры, чтобы компоновщик не модифицировал исходный запрос.
← На главную