Как правильно заполнить и программно создать значение типа СправочникСсылка

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

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

Различие между ссылкой и объектом

Для начала проанализируем фундаментальное различие. Ссылка (СправочникСсылка) — это неизменяемый идентификатор записи в таблице базы данных. Через ссылку мы можем только читать данные (например, Ссылка.Наименование). Объект (СправочникОбъект) — это данные, загруженные в оперативную память для изменения. Только у объекта есть метод Записать().

Рассмотрим пример типичной ошибки, когда разработчик пытается изменить наименование напрямую через реквизит другого объекта:


// ОШИБОЧНЫЙ КОД
СТРВ.Характеристика.Наименование = "НеЗаполнено"; // Ошибка! Ссылка только для чтения.

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

Алгоритм работы: Поиск — Проверка — Создание

Разберем ситуацию из практики: при подборе номенклатуры в таблицу характеристика может быть не указана. Наша задача — проверить, заполнена ли ссылка, и если нет — найти существующую техническую характеристику "НеЗаполнено" или создать её. Проанализируем правильный подход по шагам.

Шаг 1. Проверка заполнения ссылки

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

Шаг 2. Поиск существующего элемента

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


// Правильный поиск с учетом владельца
НайденнаяСсылка = Справочники.ХарактеристикиНоменклатуры.НайтиПоНаименованию("НеЗаполнено", Истина, стрО.Номенклатура);

Шаг 3. Создание нового элемента

Если поиск вернул пустую ссылку (НайденнаяСсылка.Пустая()), мы приступаем к созданию. Разберем по шагам процесс инициализации нового объекта:

  1. Вызываем метод СоздатьЭлемент().
  2. Обязательно заполняем реквизит Владелец (для подчиненных справочников).
  3. Заполняем Наименование и другие обязательные реквизиты.
  4. Вызываем метод Записать(), чтобы сохранить данные в БД и получить ссылку.

Рассмотрим пример кода, реализующего эту логику в цикле обхода таблицы:


Если ЗначениеЗаполнено(стрО.Характеристика) Тогда
    СТРВ.Характеристика = стрО.Характеристика;
Иначе
    // Пытаемся найти техническую характеристику у конкретной номенклатуры
    ХарактеристикаСсылка = Справочники.ХарактеристикиНоменклатуры.НайтиПоНаименованию("НеЗаполнено", Истина, стрО.Номенклатура);
    
    Если ХарактеристикаСсылка.Пустая() Тогда
        // Если не нашли — создаем
        НовыйОбъект = Справочники.ХарактеристикиНоменклатуры.СоздатьЭлемент();
        НовыйОбъект.Владелец = стрО.Номенклатура; // Установка владельца критична!
        НовыйОбъект.Наименование = "НеЗаполнено";
        
        Попытка
            НовыйОбъект.Записать();
            ХарактеристикаСсылка = НовыйОбъект.Ссылка;
        Исключение
            Сообщить("Не удалось создать характеристику: " + ОписаниеОшибки());
        КонецПопытки;
    КонецЕсли;
    
    СТРВ.Характеристика = ХарактеристикаСсылка;
КонецЕсли;

Разбор ошибки: "Значение не является значением объектного типа"

Эта ошибка возникает, когда вы пытаетесь вызвать метод (например, ПолучитьОбъект()) у переменной, которая содержит Неопределено, Null или пустую ссылку типа, отличного от ожидаемого. Рассмотрим ситуацию: если поле в таблице пустое, метод стрО.Характеристика.ПолучитьОбъект() вызовет исключение. Перед получением объекта всегда проверяйте ссылку на пустоту методом Пустая().

Проблема уникальности и "Рабочего наименования"

В современных конфигурациях 1С (таких как УТ 11, ERP 2.5) справочник характеристик имеет свои особенности. Часто в модуле объекта прописаны строгие проверки в обработчике ПередЗаписью. Выясним причину ошибки "Значение поля 'Рабочее наименование' не уникально".

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

В некоторых случаях, если технически необходимо создать элемент в обход типовых проверок уникальности, разработчики используют дополнительные свойства объекта:


НовыйОбъект.ДополнительныеСвойства.Вставить("РабочееНаименованиеПроверено", Истина);

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

Рекомендации по заполнению ссылочных типов

Подводя итог нашему анализу, сформулируем основные правила работы с СправочникСсылка:

  1. Никогда не присваивайте строковые значения в реквизиты, имеющие тип СправочникСсылка. Например, Объект.Склад = "Основной" — это грубая ошибка. Нужно найти ссылку: Объект.Склад = Справочники.Склады.НайтиПоНаименованию("Основной").
  2. Используйте типизацию. При программном создании колонок в ТаблицаЗначений всегда указывайте ОписаниеТипов, чтобы система понимала, какие данные там хранятся.
  3. Обрабатывайте исключения. При программной записи объектов всегда используйте конструкцию Попытка ... Исключение, так как запись может быть заблокирована другим пользователем или прервана проверками в модуле объекта.
  4. Владелец — это важно. Для подчиненных справочников (Характеристики, Серии, ЕдиницыИзмерения) всегда указывайте владельца и при поиске, и при создании.

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

← На главную