Как работает группировка Документ в запросах 1С 7.7 и как получить остатки на момент проведения

Программист 1С v7.7 Управленческий учет IT и автоматизация бизнеса
← На главную

При построении отчетов по регистрам остатков в платформе 1С:Предприятие 7.7 разработчики часто сталкиваются с ситуацией, когда добавление строки Группировка Документ; в текст запроса не приводит к желаемому результату: выборка либо вообще не попадает в эту группировку, либо возвращает нулевые остатки. Разберем механику работы регистра остатков, выясним причины такого поведения и рассмотрим правильные варианты получения остатков и оборотов в разрезе документов-регистраторов.

Принцип хранения данных в регистрах остатков 1С 7.7

Для понимания логики работы запроса важно разделять физические таблицы, с которыми работает платформа:

  1. Таблица итогов (остатков). В ней хранятся рассчитанные остатки ресурсов только в разрезе измерений регистра на конец каждого месяца (точки актуальности). В этой таблице нет поля документа-регистратора.
  2. Таблица движений. В ней хранятся конкретные записи прихода и расхода с указанием даты, времени, регистратора и строки документа, а также значений измерений и ресурсов на момент совершения операции.

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

Почему запрос не попадает в группировку Документ

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

  1. Отсутствие функций оборотов в запросе. Если в тексте запроса используются исключительно функции остатков (НачОст, КонОст) и не используются функции оборотов (Приход, Расход), оптимизатор запросов 1С 7.7 обращается только к таблице итогов. Так как в таблице итогов информации о документах нет, платформенный генератор запроса полностью игнорирует группировку Документ. Чтобы запрос обратился к таблице движений, необходимо обязательно описать функции Приход и/или Расход.
  2. Не указан период или нет движений. Если период не задан явной конструкцией Период с ... по ...;, либо за указанный интервал по заданным условиям не было совершено ни одного проведения документов, в группировку выборка также не войдет.
  3. Нарушение иерархии группировок. Предопределенная группировка Документ (как и СтрокаДокумента) обязана располагаться на самом нижнем уровне дерева группировок — строго после всех измерений и периодических группировок (например, День или Месяц).

Разница между Группировка Документ и Группировка ТекДок

В коде конфигураций можно встретить два различных подхода к группировке по регистратору. Рассмотрим их отличия:

  1. Предопределенная Группировка Документ;. Платформа сортирует записи строго по хронологии на временной оси (дата, время, позиция документа). При обходе такой группировки механизм запросов автоматически рассчитывает значения функций НачОст (остаток непосредственно до документа) и КонОст (остаток с учетом движений текущего документа).
  2. Пользовательская переменная ТекДок = Регистр...ТекущийДокумент; Группировка ТекДок;. В этом случае документ обрабатывается как обычное ссылочное значение. Сортировка происходит по виду документа и внутреннему идентификатору, а не по хронологической шкале. В результате хронологическая последовательность нарушается, и получение промежуточных остатков НачОст/КонОст внутри такой группировки работать корректно не будет.

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


ТекстЗапроса = "
|Период с ВыбНачПериода по ВыбКонПериода;
|Товар = Регистр.ОстаткиТМЦ.Товар;
|Склад = Регистр.ОстаткиТМЦ.Склад;
|Кол = Регистр.ОстаткиТМЦ.Количество;
|Функция Нач = НачОст(Кол);
|Функция Прих = Приход(Кол);
|Функция Расх = Расход(Кол);
|Функция Кон = КонОст(Кол);
|Группировка Товар без групп;
|Группировка Документ;
|";

Альтернативные способы получения остатков и движений без запроса

Если требуется получить остатки на момент конкретного документа или прочитать его движения в модуле проведения, строить общий запрос не обязательно. Рассмотрим встроенные объектные механизмы платформы 1С 7.7.

1. Использование временного расчета регистров:

Для получения актуального остатка на позицию конкретного документа используем методы ВременныйРасчет и РассчитатьРегистрыНа (до документа) или РассчитатьРегистрыПо (включая движения документа):


Рег = СоздатьОбъект("Регистр.ОстаткиТМЦ");
Рег.ВременныйРасчет(1);
// Рассчитываем остатки строго на момент ДО проведения документа:
РассчитатьРегистрыНа(ВыбДокумент.ПолучитьПозицию());

ОстатокТовара = Рег.СводныйОстаток(ВыбТовар, ВыбСклад, "Количество");
Сообщить("Остаток до проведения: " + ОстатокТовара);

2. Выборка движений конкретного документа:

Если задача заключается исключительно в том, чтобы узнать, какие именно движения и по каким партиям/измерениям сформировал выбранный документ, используем метод ВыбратьДвиженияДокумента:


Рег = СоздатьОбъект("Регистр.ПартииНаличие");
Рег.ВыбратьДвиженияДокумента(ВыбДокумент);
Пока Рег.ПолучитьДвижение() = 1 Цикл
    Если Рег.Приход = 1 Тогда
        Сообщить("Приход по партии " + Рег.Партия + ": " + Рег.Количество);
    Иначе
        Сообщить("Расход по партии " + Рег.Партия + ": " + Рег.Количество);
    КонецЕсли;
КонецЦикла;

Таким образом, для получения детальной картины движения ТМЦ в отчетах необходимо сочетать функции остатков и оборотов с хронологической конструкцией Группировка Документ;, а для точечных алгоритмических проверок в коде — применять механизмы прямого временного расчета регистров.

← На главную