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

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

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

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

Почему не стоит использовать модуль формы

Рассмотрим ситуацию, с которой сталкиваются многие начинающие разработчики. Попытка установить Наименование в обработчике формы ПередЗаписьюНаСервере или ПриЗаписиНаСервере часто приводит к тому, что поле либо остается пустым, либо Код элемента начинает «перескакивать» через один (например, вместо «001» сразу записывается «003»).

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

Решение 1: Использование модуля объекта (Рекомендуемый способ)

Наиболее правильным и универсальным методом является перенос логики в Модуль объекта справочника. Это гарантирует, что код будет работать всегда: и при записи из формы, и при программном создании элемента, и при загрузке данных. Разберем по шагам, как это реализовать.

Нам понадобится обработчик события ПередЗаписью. В этом обработчике мы проверим, является ли объект новым, принудительно сгенерируем код и присвоим его наименованию.

Рассмотрим пример кода:


Процедура ПередЗаписью(Отказ)
    
    // 1. Обязательная проверка на режим загрузки данных
    Если ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;

    // 2. Логика для новых элементов
    Если ЭтоНовый() Тогда
        // Принудительно получаем новый номер, если он еще не назначен
        Если НЕ ЗначениеЗаполнено(ЭтотОбъект.Код) Тогда
            ЭтотОбъект.УстановитьНовыйКод();
        КонецЕсли;
        
        // Устанавливаем наименование
        Наименование = ЭтотОбъект.Код;
    КонецЕсли;
    
    // 3. (Опционально) Обновление наименования при изменении кода вручную
    Если НЕ ЭтоНовый() И ЗначениеЗаполнено(ЭтотОбъект.Код) Тогда
        Если Наименование <> ЭтотОбъект.Код Тогда
            Наименование = ЭтотОбъект.Код;
        КонецЕсли;
    КонецЕсли;

КонецПроцедуры

Почему это работает: Метод УстановитьНовыйКод() вызывается внутри транзакции записи. Поскольку мы делаем это непосредственно в объекте, который готовится к записи, платформа учитывает этот вызов и не создает «дублей» при инкрементации счетчика в самой БД.

Решение 2: Подписка на событие

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

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

Решение 3: Изменение основного представления

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

Выясним, как это настроить:

  1. Откройте окно редактирования справочника в Конфигураторе.
  2. Перейдите на закладку Данные.
  3. Найдите поле Основное представление.
  4. Установите значение В виде кода.

После этой настройки везде, где выводится ссылка на элемент (в документах, отчетах, списках), система будет автоматически отображать Код, даже если поле Наименование пустое. Это самый «чистый» архитектурный способ, если дублирование данных в базе не является обязательным требованием.

Важные технические нюансы

При программной синхронизации кода и наименования следует учитывать еще несколько аспектов:

1. Длина полей: Всегда проверяйте длину реквизитов. Если в метаданных длина Кода составляет 12 символов, а длина Наименования — всего 10, то при попытке записи возникнет обрезка строки или ошибка. Убедитесь, что длина Наименования больше или равна длине Кода.

2. Числовые коды: Если в справочнике используется числовой код, то при обращении к ЭтотОбъект.Код вы получите число. При присваивании его в Наименование (которое всегда является строкой), 1С преобразует его автоматически, но может добавить пробелы-разделители групп разрядов (например, "1 250"). Чтобы этого избежать, используйте функцию Формат():

Наименование = Формат(ЭтотОбъект.Код, "ЧГ=0");

3. Обмен данными: Никогда не забывайте про проверку ОбменДанными.Загрузка. Если ваша база участвует в обмене (РИБ или синхронизация через универсальный формат), то при поступлении данных из другой базы код не должен пересчитываться или модифицироваться, иначе это приведет к расхождениям между узлами.

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

← На главную