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