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