Как правильно получить данные из виртуальной таблицы «ДвиженияССубконто» в 1С?

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

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

Проблема: Почему «размножаются» строки в запросе?

Рассмотрим ситуацию, описанную в теме: разработчик пытается соединить таблицу материалов документа ТребованиеНакладная.Материалы с таблицей ДвиженияССубконто. В качестве условия связи используется только Регистратор. Проанализируем, почему это приводит к некорректным данным. В одной табличной части документа может быть 10 строк с разной номенклатурой. Этот же документ в регистре бухгалтерии может сформировать 10 (или более) проводок. Если мы соединяем их только по полю Ссылка (в документе) и Регистратор (в регистре), СУБД сопоставит каждую строку документа с каждой строкой проводки. В итоге вместо 10 строк мы получим 100.

Важный момент: Чтобы получить корректную сумму по конкретной строке номенклатуры, необходимо связывать таблицы по всем измерениям и доступной аналитике (счет, субконто, подразделение).

Способ 1. Уточнение связей в запросе

Первое, что необходимо сделать — добавить в условие соединения ПО все поля, которые однозначно идентифицируют строку. Если мы говорим о списании материалов, то это будут: Счет, Номенклатура, Склад и, возможно, Характеристика.

Проанализируем правильный подход к связям:


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

Обратите внимание, что поля Субконто имеют составной тип данных. Поэтому для оптимизации и стабильности желательно использовать типизацию, о которой мы поговорим ниже.

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

Одна из самых распространенных ошибок начинающих разработчиков — накладывание условий в секции ГДЕ. Выясним причину, почему это плохо. Когда мы пишем условия в ГДЕ, платформа сначала выбирает все записи из базы, а затем фильтрует их. Если же мы передаем условия в параметры виртуальной таблицы (в скобках), фильтрация происходит на уровне СУБД, и в запрос попадает только нужный объем данных.

Рассмотрим, как правильно передать отбор по регистратору и счетам в параметры:


РегистрБухгалтерии.Хозрасчетный.ДвиженияССубконто(
    , 
    , 
    Регистратор = &Ссылка 
    И Активность = ИСТИНА 
    И СчетКт В (ВЫБРАТЬ Счет ИЗ ВТ_Документ)
)

Это значительно ускоряет выполнение запроса, особенно если в базе данных миллионы проводок.

Способ 3. Группировка данных перед соединением

Для исключения дублей и повышения производительности рекомендуется использовать временные таблицы. Разберем по шагам алгоритм оптимального запроса:

  1. Выбираем данные из документа, суммируем количество (если номенклатура дублируется в строках) и помещаем во временную таблицу ВТ_Документ.
  2. Обязательно индексируем временную таблицу по полям связи (Ссылка, Номенклатура, Склад).
  3. Выбираем данные из регистра бухгалтерии, также предварительно сгруппировав их по аналитике, чтобы на одну комбинацию «Номенклатура + Склад» приходилась одна сумма.
  4. Соединяем две подготовленные таблицы.

Пример группировки данных документа:


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

Технические нюансы: Работа с составными типами (Субконто)

Поля СубконтоДт1, СубконтоКт1 и так далее в виртуальной таблице ДвиженияССубконто имеют составной тип. Это означает, что СУБД приходится выполнять дополнительные проверки типов при каждом сравнении. Проанализируем, как это оптимизировать.

Если вы точно знаете, что на первом субконто счета всегда находится справочник Номенклатура, используйте функцию ВЫРАЗИТЬ. Это подскажет планировщику SQL-запроса, с какой конкретно таблицей нужно работать, и исключит лишние соединения.

Пример использования ВЫРАЗИТЬ в связях:


ПО ВТ_Документ.Номенклатура = ВЫРАЗИТЬ(ХозрасчетныйДвиженияССубконто.СубконтоКт1 КАК Справочник.Номенклатура)

Важно: Номера субконто (1, 2, 3) зависят от настроек плана счетов. Если на одном счете «Номенклатура» — это Субконто1, а на другом — Субконто2, ваш запрос должен это учитывать, иначе данные не сойдутся.

Резюме и рекомендации

Подводя итоги, сформулируем правила работы с ДвиженияССубконто:

Соблюдение этих правил позволит вам писать быстрые и надежные запросы, которые будут возвращать корректные суммы даже в самых сложных хозяйственных операциях.

← На главную