В процессе сопровождения информационных баз на платформе 1С:Предприятие 8 часто возникает необходимость массово обновить настройки системы. Одной из таких задач является автоматическое изменение даты запрета редактирования данных, например, при наступлении нового календарного месяца. Однако начинающие разработчики часто сталкиваются с трудностями, пытаясь применить к регистрам те же методы, которые используются для справочников или документов.
В этой статье мы подробно разберем, почему нельзя использовать метод ПолучитьОбъект() для регистров, как правильно работать с наборами записей и какие нюансы следует учитывать, если ваша конфигурация построена на базе «Библиотеки стандартных подсистем» (БСП).
Проанализируем типичную ошибку. В исходном запросе автор пытался получить ссылку на запись регистра и вызвать метод ПолучитьОбъект(). В системе 1С:Предприятие существует четкое разделение между объектными сущностями (справочники, документы, планы видов характеристик) и необъектными (регистры сведений, накопления, расчета).
Основные отличия, которые важно помнить:
ПолучитьОбъект(), так как он не является объектом в терминах платформы.Разберем, как реализовать задачу правильно, используя стандартные механизмы платформы.
Этот метод наиболее эффективен, когда нужно изменить группу записей или очистить регистр целиком. Рассмотрим алгоритм работы по шагам.
Сначала мы создаем объект НаборЗаписей. Это своего рода временная таблица, которую мы считываем из базы в оперативную память, модифицируем и записываем обратно.
// Определим новую дату (начало текущего месяца)
ТекДата = ТекущаяДата();
ДатаЗапретаНовая = НачалоМесяца(ТекДата);
// Создаем объект набора записей
НаборЗаписей = РегистрыСведений.ДатыЗапретаИзменения.СоздатьНаборЗаписей();
// Если нужно изменить ВСЕ записи в регистре, фильтры не устанавливаем.
// Если нужно изменить только по конкретному пользователю, добавляем отбор:
// НаборЗаписей.Отбор.Пользователь.Установить(НужныйПользователь);
// Читаем текущие данные из базы в набор
НаборЗаписей.Прочитать();
// Обходим каждую запись в цикле
Для Каждого Запись Из НаборЗаписей Цикл
// Вносим изменения в ресурс (ДатаЗапрета - обычно ресурс в типовых решениях)
Запись.ДатаЗапрета = ДатаЗапретаНовая;
КонецЦикла;
// Записываем измененный набор обратно в базу данных
// Важно: метод Записать() без параметров перезаписывает данные по установленному отбору
НаборЗаписей.Записать();
Проанализируем ситуацию с отборами. Как верно подмечено в обсуждении, отборы в наборах записей можно устанавливать только по измерениям. Если ДатаЗапрета является ресурсом, вы не сможете установить по ней отбор напрямую через НаборЗаписей.Отбор. В этом случае сначала выполняется чтение всех записей, удовлетворяющих измерениям, а затем фильтрация или изменение происходит уже в цикле Для Каждого.
Если вам нужно изменить одну конкретную запись (например, для конкретного пользователя и конкретного раздела), удобнее использовать МенеджерЗаписи. Он работает аналогично объекту, позволяя прочитать одну строку по ключу (комбинации измерений).
Менеджер = РегистрыСведений.ДатыЗапретаИзменения.СоздатьМенеджерЗаписи();
// Заполняем ключевые поля (измерения), чтобы система нашла конкретную запись
Менеджер.Пользователь = ВыбранныйПользователь;
Менеджер.Раздел = Справочники.РазделыДатЗапрета.ПустаяСсылка(); // Если разделение не используется
// Пытаемся прочитать запись
Менеджер.Прочитать();
// Если запись существует, меняем дату. Если нет - она будет создана при записи.
Менеджер.ДатаЗапрета = ДатаЗапретаНовая;
Менеджер.Записать();
Если вы работаете в 1С:ERP, 1С:Управление торговлей 11 или 1С:Бухгалтерия 3.0, напрямую записывать данные в регистр ДатыЗапретаИзменения крайне не рекомендуется. В этих конфигурациях используется подсистема «Даты запрета изменения», которая включает в себя механизмы кэширования и проверки прав.
Рассмотрим, почему прямая запись может не сработать:
Для корректной работы следует использовать программный интерфейс (API), предоставляемый разработчиками БСП. Посмотрим на пример кода, который делает ту же задачу правильно:
// Используем экспортную процедуру программного интерфейса БСП
// Параметры: Раздел, Объект (Пользователь), ДатаЗапрета
ДатыЗапретаИзменения.УстановитьДатуЗапрета(ПланыВидовХарактеришек.РазделыДатЗапретаИзменения.ДебиторскаяЗадолженность, , ДатаЗапретаНовая);
// После программного изменения в некоторых случаях требуется обновить кэш
ДатыЗапретаИзмененияСлужебный.ОбновитьДатыЗапретаИзменения();
Проанализируем ситуацию, когда записей в регистре очень много (например, тысячи пользователей с индивидуальными настройками). Метод НаборЗаписей.Прочитать() без установленных отборов прочитает все записи регистра. Это может привести к:
В таких случаях рекомендуется использовать Запрос для получения только тех измерений, которые требуют корректировки, а затем изменять записи порциями или через менеджер записи в транзакции.
Для успешного изменения дат в регистре:
ПолучитьОбъект() — используйте НаборЗаписей или МенеджерЗаписи.Отбор работает только по измерениям.ДатыЗапретаИзменения.