Как программно изменить дату запрета изменения в регистре сведений 1С?

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

В процессе сопровождения информационных баз на платформе 1С:Предприятие 8 часто возникает необходимость массово обновить настройки системы. Одной из таких задач является автоматическое изменение даты запрета редактирования данных, например, при наступлении нового календарного месяца. Однако начинающие разработчики часто сталкиваются с трудностями, пытаясь применить к регистрам те же методы, которые используются для справочников или документов.

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

Почему исходный подход был ошибочным?

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

Основные отличия, которые важно помнить:

  1. У регистра сведений нет уникальной ссылки (UUID) для каждой строки.
  2. Запись регистра идентифицируется комбинацией значений его измерений.
  3. К регистру нельзя обратиться через ПолучитьОбъект(), так как он не является объектом в терминах платформы.

Разберем, как реализовать задачу правильно, используя стандартные механизмы платформы.

Вариант 1. Использование Набора Записей (универсальный способ)

Этот метод наиболее эффективен, когда нужно изменить группу записей или очистить регистр целиком. Рассмотрим алгоритм работы по шагам.

Сначала мы создаем объект НаборЗаписей. Это своего рода временная таблица, которую мы считываем из базы в оперативную память, модифицируем и записываем обратно.


// Определим новую дату (начало текущего месяца)
ТекДата = ТекущаяДата();
ДатаЗапретаНовая = НачалоМесяца(ТекДата);

// Создаем объект набора записей
НаборЗаписей = РегистрыСведений.ДатыЗапретаИзменения.СоздатьНаборЗаписей();

// Если нужно изменить ВСЕ записи в регистре, фильтры не устанавливаем.
// Если нужно изменить только по конкретному пользователю, добавляем отбор:
// НаборЗаписей.Отбор.Пользователь.Установить(НужныйПользователь);

// Читаем текущие данные из базы в набор
НаборЗаписей.Прочитать();

// Обходим каждую запись в цикле
Для Каждого Запись Из НаборЗаписей Цикл
    // Вносим изменения в ресурс (ДатаЗапрета - обычно ресурс в типовых решениях)
    Запись.ДатаЗапрета = ДатаЗапретаНовая;
КонецЦикла;

// Записываем измененный набор обратно в базу данных
// Важно: метод Записать() без параметров перезаписывает данные по установленному отбору
НаборЗаписей.Записать();

Проанализируем ситуацию с отборами. Как верно подмечено в обсуждении, отборы в наборах записей можно устанавливать только по измерениям. Если ДатаЗапрета является ресурсом, вы не сможете установить по ней отбор напрямую через НаборЗаписей.Отбор. В этом случае сначала выполняется чтение всех записей, удовлетворяющих измерениям, а затем фильтрация или изменение происходит уже в цикле Для Каждого.

Вариант 2. Использование Менеджера Записи (для точечных изменений)

Если вам нужно изменить одну конкретную запись (например, для конкретного пользователя и конкретного раздела), удобнее использовать МенеджерЗаписи. Он работает аналогично объекту, позволяя прочитать одну строку по ключу (комбинации измерений).


Менеджер = РегистрыСведений.ДатыЗапретаИзменения.СоздатьМенеджерЗаписи();

// Заполняем ключевые поля (измерения), чтобы система нашла конкретную запись
Менеджер.Пользователь = ВыбранныйПользователь;
Менеджер.Раздел = Справочники.РазделыДатЗапрета.ПустаяСсылка(); // Если разделение не используется

// Пытаемся прочитать запись
Менеджер.Прочитать();

// Если запись существует, меняем дату. Если нет - она будет создана при записи.
Менеджер.ДатаЗапрета = ДатаЗапретаНовая;
Менеджер.Записать();

Особенности работы в современных конфигурациях (БСП)

Если вы работаете в 1С:ERP, 1С:Управление торговлей 11 или 1С:Бухгалтерия 3.0, напрямую записывать данные в регистр ДатыЗапретаИзменения крайне не рекомендуется. В этих конфигурациях используется подсистема «Даты запрета изменения», которая включает в себя механизмы кэширования и проверки прав.

Рассмотрим, почему прямая запись может не сработать:

  1. Кэш параметров сеанса: Проверка даты запрета часто происходит не прямым запросом к регистру, а через обращение к параметрам сеанса или функциональным опциям. Если вы просто измените запись в регистре, пользователь, уже работающий в системе, может не заметить изменений до перезапуска сеанса.
  2. Сложная иерархия: В БСП дата запрета может устанавливаться для всей базы, для раздела или для конкретного объекта (организации, склада).

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


// Используем экспортную процедуру программного интерфейса БСП
// Параметры: Раздел, Объект (Пользователь), ДатаЗапрета
ДатыЗапретаИзменения.УстановитьДатуЗапрета(ПланыВидовХарактеришек.РазделыДатЗапретаИзменения.ДебиторскаяЗадолженность, , ДатаЗапретаНовая);

// После программного изменения в некоторых случаях требуется обновить кэш
ДатыЗапретаИзмененияСлужебный.ОбновитьДатыЗапретаИзменения();

Производительность и блокировки

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

В таких случаях рекомендуется использовать Запрос для получения только тех измерений, которые требуют корректировки, а затем изменять записи порциями или через менеджер записи в транзакции.

Резюме

Для успешного изменения дат в регистре:

  1. Забудьте про ПолучитьОбъект() — используйте НаборЗаписей или МенеджерЗаписи.
  2. Помните, что Отбор работает только по измерениям.
  3. Если конфигурация типовая — всегда проверяйте наличие готовых процедур в модуле ДатыЗапретаИзменения.
  4. Не забывайте про обновление параметров сеанса, чтобы изменения вступили в силу немедленно.
← На главную