Рассмотрим распространенную проблему, с которой часто сталкиваются разработчики в 1С: два документа выполняют движения в один и тот же подчиненный регистратору регистр сведений с абсолютно одинаковой датой и временем (например, 01.09.2017 00:00:00). При просмотре списка регистра записи второго документа оказываются выше или раньше записей первого документа, нарушая ожидаемую логику.
Разберем причины такого поведения платформы 1С и проанализируем проверенные способы решения этой задачи.
Выясним, почему порядок записей в рамках одной секунды кажется хаотичным:
Период, полю Регистратор (ссылка на документ) и полю НомерСтроки. Если период совпадает с точностью до секунды, платформа определяет физический порядок записей путем сравнения внутренних уникальных идентификаторов (GUID) ссылок регистраторов.СрезПоследних при наличии двух и более записей с одинаковым периодом также выбирает итоговую запись на основании внутренних ссылок регистраторов. Это может приводить к считыванию некорректных данных.Рассмотрим основные способы устранения этой проблемы.
Самое простое и распространенное решение — гарантировать, чтобы документы-регистраторы имели разное время. Разберем по шагам, как это можно реализовать:
Если документы создаются программно или проводятся последовательно, настроим логику так, чтобы при обнаружении уже существующего документа на это же время, дата нового документа сдвигалась вперед на 1 секунду.
Пример программного смещения времени перед записью документа:
КонецСекунды = КонецСекунды(Объект.Дата);
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| Ссылка
|ИЗ
| Документ.ПриходнаяНакладная
|ГДЕ
| Дата МЕЖДУ &НачалоСекунды И &КонецСекунды
| И Ссылка <> &Ссылка";
Запрос.УстановитьПараметр("НачалоСекунды", НачалоСекунды(Объект.Дата));
Запрос.УстановитьПараметр("КонецСекунды", КонецСекунды);
Запрос.УстановитьПараметр("Ссылка", Объект.Ссылка);
Результат = Запрос.Выполнить();
Если НЕ Результат.Пустой() Тогда
Объект.Дата = Объект.Дата + 1; // Сдвигаем время на 1 секунду вперед
КонецЕсли;
Если требования бизнеса строго запрещают изменять время документов и они должны быть проведены ровно в одну и ту же секунду, применим подход с добавлением порядка на уровне структуры регистра:
Приоритет, Индекс или НомерПоПорядку с типом Число.ОбработкаПроведения явно зафиксируем приоритетность записей для каждого типа документа или сценария.Проанализируем ситуацию с точки зрения пользователей базы. Обычным пользователям не обязательно давать прямой доступ к списку регистра сведений.
Если правильный порядок отображения критичен для работы, сформируем специализированный отчет или динамический список на основе запроса, где сортировка явно задается по моменту времени документа-регистратора и его дополнительным реквизитам (например, полю Ссылка.Дата и Ссылка.Номер):
ВЫБРАТЬ
Регистр.Период КАК Период,
Регистр.Регистратор КАК Регистратор,
Регистр.Значение КАК Значение
ИЗ
РегистрСведений.МойРегистр КАК Регистр
УПОРЯДОЧИТЬ ПО
Регистр.Период ВОЗР,
Регистр.Регистратор.Дата ВОЗР,
Регистр.Регистратор.Номер ВОЗР
Подведем итог: Нельзя рассчитывать на встроенную сортировку регистра сведений, если документы записаны в одну секунду. Для решения проблемы следует либо сдвигать время документов на секунду, либо добавлять в регистр измерение приоритета, либо использовать запросы с явным упорядочиванием.