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

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

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

В этой статье мы подробно разберем, почему возникает эта ошибка и как составить запрос так, чтобы документы всегда следовали в строгой хронологической последовательности, идентичной той, что мы видим в стандартных бухгалтерских отчетах (например, в «Карточке счета»).

Анализ проблемы: Почему сортировки по Периоду недостаточно

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

Поле Период в регистре бухгалтерии хранит дату и время с точностью до секунды. Если в течение одной секунды было проведено два и более документа (например, при групповом перепроведении или загрузке из внешней системы), то для СУБД эти записи имеют одинаковое значение сортировки. В результате порядок их выдачи становится неопределенным. Для бухгалтерского учета это критично: если «Поступление товаров и услуг» и «Списание с расчетного счета» имеют одно время, но в запросе оплата встанет раньше поступления, алгоритм расчета авансов отработает неверно, и мы получим развернутое сальдо на субсчетах.

Решение 1: Использование механизма АВТОУПОРЯДОЧИВАНИЕ

Самый простой и зачастую эффективный способ — использование зарезервированного слова АВТОУПОРЯДОЧИВАНИЕ в конце запроса. Рассмотрим, как изменится наш код:


Запрос.Текст = 
    "ВЫБРАТЬ
    |    ХозрасчетныйОбороты.Регистратор КАК Регистратор,
    |    ХозрасчетныйОбороты.Период КАК Период
    |ИЗ
    |    РегистрБухгалтерии.Хозрасчетный.Обороты(&ДатаНачала, &ДатаОкончания, Регистратор, , , , , ) КАК ХозрасчетныйОбороты
    |УПОРЯДОЧИТЬ ПО
    |    Регистратор
    |АВТОУПОРЯДОЧИВАНИЕ";

Как это работает: Когда мы указываем АВТОУПОРЯДОЧИВАНИЕ и выбираем поле типа ДокументСсылка (в данном случае Регистратор), платформа 1С не просто сортирует данные по ссылке. Она неявно добавляет в запрос дополнительные поля для сортировки:

  1. Дату документа (момент времени).
  2. Внутренний идентификатор ссылки (GUID), что гарантирует уникальность и стабильность порядка.

Важно помнить, что АВТОУПОРЯДОЧИВАНИЕ работает только в том случае, если в списке выборки или в условиях упорядочивания присутствует ссылка на объект (Регистратор). Однако у этого метода есть минус: он может работать медленнее на больших объемах данных, так как платформа генерирует более сложный SQL-запрос.

Решение 2: Явное упорядочивание по Периоду и Регистратору

Если нам нужно обеспечить максимальную производительность и предсказуемость, мы можем явно указать поля для сортировки. Для регистра бухгалтерии золотым стандартом является связка Период + Регистратор.

Проанализируем исправленный вариант запроса:


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

Почему это надежно? В СУБД ссылка (Регистратор) представлена уникальным идентификатором. Даже если периоды записей совпадают до секунды, идентификаторы документов всегда разные. Система выстроит их в порядке возрастания GUID. Хотя этот порядок может не совпадать с визуальным порядком в журнале документов (созданных «руками» в той же секунде), он будет строго детерминированным. Это значит, что при каждом запуске запроса вы будете получать один и тот же результат, что позволит корректно закрывать остатки при последовательной обработке.

Решение 3: Использование физической таблицы проводок

В некоторых случаях виртуальной таблицы Обороты бывает недостаточно. Например, если один и тот же документ делает несколько движений по одному счету и аналитике (допустим, разбиение по ставкам НДС или разным статьям затрат). Виртуальная таблица может «схлопнуть» эти движения, если не указана соответствующая периодичность.

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


Запрос.Текст = 
    "ВЫБРАТЬ
    |    Хозрасчетный.Регистратор КАК Регистратор,
    |    Хозрасчетный.Период КАК Период,
    |    Хозрасчетный.НомерСтроки КАК НомерСтроки
    |ИЗ
    |    РегистрБухгалтерии.Хозрасчетный КАК Хозрасчетный
    |ГДЕ
    |    Хозрасчетный.Счет В ИЕРАРХИИ(&МассивСчетов)
    |    И Хозрасчетный.Период МЕЖДУ &ДатаНачала И &ДатаОкончания
    |УПОРЯДОЧИТЬ ПО
    |    Период,
    |    Регистратор,
    |    НомерСтроки";

Разберем преимущества этого подхода:

Нюанс с «Моментом времени» в запросах

Часто в обсуждениях всплывает рекомендация использовать МоментВремени. Нужно понимать техническое ограничение: объект МоментВремени существует в объектной модели (в коде 1С:Предприятие), но его нет как поля в базе данных. В языке запросов вы не можете написать УПОРЯДОЧИТЬ ПО Регистратор.МоментВремени.

Когда вы используете УПОРЯДОЧИТЬ ПО Регистратор вместе с АВТОУПОРЯДОЧИВАНИЕ, система фактически эмулирует сортировку по моменту времени. Если же вы работаете с физической таблицей, то комбинация Период, Регистратор является наиболее близким аналогом Момента времени для целей упорядочивания документов.

Почему «разваливается» учет в Карточке счета?

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

Рекомендация: При перепроведении документов для восстановления взаиморасчетов (60, 62 счета) всегда используйте сортировку Период, Регистратор. Это гарантирует, что оплата, введенная позже поступления в той же секунде, будет обработана именно как оплата долга, а не как аванс (при условии, что ссылка на оплату была создана позже).

Подведем итоги

Для корректного упорядочивания документов в запросе к регистру бухгалтерии придерживаемся следующих правил:

  1. Избегайте сортировки только по полю Период.
  2. Всегда добавляйте Регистратор в список полей УПОРЯДОЧИТЬ ПО.
  3. Используйте АВТОУПОРЯДОЧИВАНИЕ, если вам нужна логика платформы по умолчанию.
  4. При необходимости учитывать порядок проводок внутри документа обращайтесь к физической таблице и полю НомерСтроки.
  5. Помните, что обращение к полям через точку от регистратора (например, Регистратор.Дата) в условиях упорядочивания может значительно замедлить выполнение запроса, так как вызовет дополнительное соединение (LEFT JOIN) с таблицей документа.

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

← На главную