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

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

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

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

Разберем основную ошибку: почему не работает «Объект»?

Рассмотрим стандартную ситуацию: разработчик создает обработчик события ПриСозданииНаСервере и пытается обратиться к данным через Объект.ИмяРеквизита. Программа выдает ошибку: «Переменная не определена — Объект». Выясним причину этого поведения.

В управляемых формах справочников или документов основным реквизитом формы по умолчанию является Объект (тип ДанныеФормыСтруктура). Однако в форме записи регистра сведений основным реквизитом выступает Запись (тип ДанныеФормыСтруктура). Поэтому для доступа к полям регистра в коде формы необходимо использовать именно это ключевое слово.


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    // Неправильно:
    // Объект.ДатаЗагрузки = ТекущаяДата(); 

    // Правильно:
    Запись.ДатаЗагрузки = ТекущаяДатаСеанса();
КонецПроцедуры

Как определить, что создается именно новая запись?

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

Для регистров сведений проверка Параметры.Ключ.Пустая() часто приводит к ошибке «Метод объекта не обнаружен». Вместо этого следует использовать свойство ИсходныйКлючЗаписи. Это свойство хранит информацию о том, была ли запись прочитана из базы данных или она существует только в памяти формы.

Посмотрим на корректный пример кода:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Проверяем, является ли запись новой
    Если Запись.ИсходныйКлючЗаписи.Пустой() Тогда
        
        // Устанавливаем значения по умолчанию
        Запись.ДатаЗагрузки = ТекущаяДатаСеанса();
        
        // Если нужно заполнить что-то из параметров открытия
        Если Параметры.Свойство("ИмяПользователя") Тогда
            Запись.Ответственный = Параметры.ИмяПользователя;
        КонецЕсли;
        
    КонецЕсли;
    
    // Ограничиваем возможность редактирования поля пользователем, если это необходимо
    Элементы.ДатаЗагрузки.ТолькоПросмотр = Истина;
    
КонецПроцедуры

Нюансы использования системного времени: ТекущаяДата() или ТекущаяДатаСеанса()?

Проанализируем важный технический момент. В коде часто используют функцию ТекущаяДата(). В клиент-серверном варианте работы эта функция возвращает время сервера. Если сервер находится в Москве, а пользователь во Владивостоке, время записи может сбить пользователя с толку.

Рекомендуется всегда использовать ТекущаяДатаСеанса(). Она учитывает часовой пояс, установленный для конкретного пользователя в настройках, что гарантирует корректность ведения логов и фиксацию времени операций.

Альтернативный и более правильный метод: ОбработкаЗаполнения

Хотя инициализация в ПриСозданииНаСервере работает, идеологически более правильным считается использование события ОбработкаЗаполнения. Рассмотрим преимущества этого подхода:

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

Для реализации этого метода нужно открыть Модуль менеджера регистра сведений и добавить процедуру:


Процедура ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка)
    
    // Проверяем тип данных заполнения, если нужно
    Если ТипЗнч(ДанныеЗаполнения) = Тип("Структура") Тогда
        ЗаполнитьЗначенияСвойств(ЭтотОбъект, ДанныеЗаполнения);
    КонецЕсли;
    
    // Устанавливаем дату, если она еще не заполнена
    Если Не ЗначениеЗаполнено(ДатаЗагрузки) Тогда
        ДатаЗагрузки = ТекущаяДатаСеанса();
    КонецЕсли;
    
КонецПроцедуры

Учет копирования записей

Зачастую пользователи создают новые записи не с «нуля», а нажатием кнопки «Скопировать» (F9). В этом случае ИсходныйКлючЗаписи.Пустой() также вернет Истина, но поля будут заполнены данными из образца. Если вы хотите, чтобы в скопированной записи дата загрузки всегда обновлялась на текущую, вам нужно принудительно перезаписывать её в ПриСозданииНаСервере, проверяя параметр Параметры.ЗначениеКопирования.

Управление доступностью полей

Выясним, как лучше запретить пользователю менять автоматически установленное значение. В исходном обсуждении предлагалось использовать Элементы.ДатаЗагрузки.Доступность = Ложь. Однако это делает поле «серым» и трудночитаемым.

Лучшая практика: Использовать свойство ТолькоПросмотр = Истина. Это позволит пользователю видеть значение и даже копировать его, но не даст случайно изменить важную системную информацию.

Подводя итог, при работе с формой записи регистра сведений всегда помните: работаем с реквизитом Запись, проверяем новизну через ИсходныйКлючЗаписи.Пустой() и отдаем предпочтение ТекущаяДатаСеанса() для фиксации времени.

← На главную