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