Как установить значение по умолчанию для реквизита типа Справочник в обычной форме 1С?

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

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

Анализ проблемы и типичные ошибки новичков

Рассмотрим ситуацию, описанную автором темы. В документе есть реквизит НаименованиеГруза с типом данных СправочникСсылка.НаименованиеГруза. Автор пытается установить значение по умолчанию в процедуре ПриОткрытии формы документа следующими способами:


НаименованиеГруза = "Наименование";
НаименованиеГруза.Наименование = "Наименование";

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

  1. Попытка присвоить строку ссылке. Строка "Наименование" — это текстовый тип данных. Реквизит документа ожидает получить объект типа СправочникСсылка (уникальный идентификатор записи в базе данных). Платформа 1С строго типизирована, поэтому попытка записать строку в поле ссылки будет либо проигнорирована, либо вызовет ошибку несоответствия типов.
  2. Попытка изменить свойство ссылки. Конструкция НаименованиеГруза.Наименование = "Наименование" ошибочна, так как любая ссылка в 1С (объект типа СправочникСсылка) доступна только для чтения. Изменить ее свойства напрямую через точку невозможно. Для изменения данных элемента справочника требуется сначала получить сам объект через метод ПолучитьОбъект(), изменить его и записать в базу, что в данном контексте абсолютно нецелесообразно.

Также в ходе обсуждения было предложено использовать выборку данных из справочника:


Выборка = Справочники.ТвойСправочник.Выбрать();
Выборка.Следующий();
ТвойРеквизит = Выборка;

Этот код содержит грубую ошибку. Переменная Выборка возвращает объект типа СправочникВыборка, а не ссылку на элемент. Чтобы получить саму ссылку, необходимо обращаться к свойству Ссылка объекта выборки. Правильная строка должна выглядеть так: ТвойРеквизит = Выборка.Ссылка;.

Решение 1. Программная установка значения в модуле формы с проверкой на новый объект

Если нам необходимо заполнить реквизит непосредственно при открытии формы, мы можем сделать это в обработчике события ПередОткрытием или ПриОткрытии формы. Разберем по шагам, как написать этот код безопасно.

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

Рассмотрим правильный пример кода для обычной формы документа:


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

В этом примере метод ЭтоНовый() возвращает Истина только в том случае, если документ еще ни разу не сохранялся в базе данных. Метод ЗначениеЗаполнено() гарантирует, что мы не запишем пустую ссылку, если поиск по наименованию не увенчался успехом.

Почему поиск по наименованию — это плохая практика, и как сделать лучше

Автор темы решил проблему, используя метод НайтиПоНаименованию(). Несмотря на то что это рабочий вариант, в реальной промышленной разработке использовать жестко прописанные текстовые строки (хардкод) крайне не рекомендуется по следующим причинам:

Рассмотрим альтернативные, более надежные архитектурные решения:

Вариант А. Предопределенные элементы

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

НаименованиеГруза = Справочники.НаименованиеГруза.Песок;

Такой элемент невозможно случайно удалить или переименовать так, чтобы код перестал работать, поскольку связь осуществляется по уникальному имени предопределенного элемента.

Вариант Б. Использование констант или настроек пользователей

Если значение по умолчанию может периодически меняться решением руководства или зависит от конкретного пользователя, лучшим решением будет создание Константы (например, ОсновнойГруз) или использование регистра сведений для хранения персональных настроек.

Посмотрим на пример кода с использованием константы:


Если ЭтоНовый() Тогда
    // Получаем значение по умолчанию из константы
    НаименованиеГруза = Константы.ОсновнойГруз.Получить();
КонецЕсли;

Этот подход позволяет администратору или пользователю в любой момент изменить значение по умолчанию через пользовательский интерфейс без привлечения программиста для изменения программного кода.

Решение 2. Лучшая практика — перенос логики в модуль объекта (ОбработкаЗаполнения)

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

Проанализируем правильный подход: перенос бизнес-логики заполнения в Модуль объекта в специализированный обработчик ОбработкаЗаполнения.

Рассмотрим пример реализации в модуле объекта документа:


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

Этот метод универсален. Он гарантирует заполнение реквизита как при ручном создании документа пользователем, так и при программном создании с использованием метода ПолучитьФорму() или простом вызове метода объекта Заполнить().

Решение 3. Использование стандартных свойств метаданных (без программирования)

Если вы работаете на платформе «1С:Предприятие 8.2» и выше, для решения этой задачи зачастую вообще не требуется писать программный код. Платформа предоставляет мощные встроенные механизмы настройки свойств реквизитов непосредственно в конфигураторе.

Разберем по шагам, как настроить автоматическое заполнение через палитру свойств:

  1. Откройте конфигуратор и найдите ваш документ.
  2. Перейдите на вкладку «Данные» и откройте свойства нужного реквизита (в нашем случае НаименованиеГруза).
  3. В палитре свойств найдите раздел «Заполнение».
  4. В свойстве «Значение заполнения» выберите конкретный элемент справочника (это отлично работает, если в справочнике настроены предопределенные элементы). Теперь при создании нового документа платформа сама подставит это значение.
  5. Обратите внимание на свойство «Заполнять из данных заполнения». Если установить этот флаг в значение Истина, то при создании документа из формы списка, где установлен отбор по конкретному грузу, этот груз автоматически подставится в новый документ.

Что означает свойство «Быстрый выбор»?

Автор темы упомянул, что у его поля ввода установлено свойство «Быстрый выбор», и выразил опасение, что это мешает решению задачи. Проясним эту ситуацию.

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

Таким образом, наличие свойства «Быстрый выбор» никак не ограничивает программную работу с реквизитом. Вы можете смело использовать любые вышеописанные способы заполнения значения по умолчанию — платформа корректно отобразит предзаполненное значение в поле ввода на форме.

← На главную