Почему движения документов в регистре сведений 1С с одинаковой датой отображаются в неверном порядке и как это исправить

Программист IT и автоматизация бизнеса
← На главную

Рассмотрим распространенную проблему, с которой часто сталкиваются разработчики в 1С: два документа выполняют движения в один и тот же подчиненный регистратору регистр сведений с абсолютно одинаковой датой и временем (например, 01.09.2017 00:00:00). При просмотре списка регистра записи второго документа оказываются выше или раньше записей первого документа, нарушая ожидаемую логику.

Разберем причины такого поведения платформы 1С и проанализируем проверенные способы решения этой задачи.

Технические причины и ограничения платформы

Выясним, почему порядок записей в рамках одной секунды кажется хаотичным:

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

Рассмотрим основные способы устранения этой проблемы.

Способ 1. Автоматическое смещение времени документа на секунду

Самое простое и распространенное решение — гарантировать, чтобы документы-регистраторы имели разное время. Разберем по шагам, как это можно реализовать:

Если документы создаются программно или проводятся последовательно, настроим логику так, чтобы при обнаружении уже существующего документа на это же время, дата нового документа сдвигалась вперед на 1 секунду.

Пример программного смещения времени перед записью документа:


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

Запрос.УстановитьПараметр("НачалоСекунды", НачалоСекунды(Объект.Дата));
Запрос.УстановитьПараметр("КонецСекунды", КонецСекунды);
Запрос.УстановитьПараметр("Ссылка", Объект.Ссылка);

Результат = Запрос.Выполнить();
Если НЕ Результат.Пустой() Тогда
    Объект.Дата = Объект.Дата + 1; // Сдвигаем время на 1 секунду вперед
КонецЕсли;

Способ 2. Добавление служебного измерения для сортировки

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

  1. Добавим в регистр сведений дополнительное измерение, например Приоритет, Индекс или НомерПоПорядку с типом Число.
  2. При формировании движений в процедуре ОбработкаПроведения явно зафиксируем приоритетность записей для каждого типа документа или сценария.
  3. При получении данных из регистра будем учитывать это новое измерение в сортировке запросов.

Способ 3. Вывод данных через отчеты и срез с явной сортировкой

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

Если правильный порядок отображения критичен для работы, сформируем специализированный отчет или динамический список на основе запроса, где сортировка явно задается по моменту времени документа-регистратора и его дополнительным реквизитам (например, полю Ссылка.Дата и Ссылка.Номер):


ВЫБРАТЬ
	Регистр.Период КАК Период,
	Регистр.Регистратор КАК Регистратор,
	Регистр.Значение КАК Значение
ИЗ
	РегистрСведений.МойРегистр КАК Регистр
УПОРЯДОЧИТЬ ПО
	Регистр.Период ВОЗР,
	Регистр.Регистратор.Дата ВОЗР,
	Регистр.Регистратор.Номер ВОЗР

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

← На главную