В разработке на платформе 1С:Предприятие одной из самых частых задач является программное заполнение реквизитов документов или справочников. Начинающие разработчики часто сталкиваются с трудностями при работе с типом СправочникСсылка, путая ссылку на запись в базе данных с самим объектом. В данной статье мы подробно разберем, как правильно работать с ссылочными типами, как программно создавать подчиненные элементы и как избегать типичных ошибок, таких как нарушение уникальности или обращение к свойствам пустого значения.
Для начала проанализируем фундаментальное различие. Ссылка (СправочникСсылка) — это неизменяемый идентификатор записи в таблице базы данных. Через ссылку мы можем только читать данные (например, Ссылка.Наименование). Объект (СправочникОбъект) — это данные, загруженные в оперативную память для изменения. Только у объекта есть метод Записать().
Рассмотрим пример типичной ошибки, когда разработчик пытается изменить наименование напрямую через реквизит другого объекта:
// ОШИБОЧНЫЙ КОД
СТРВ.Характеристика.Наименование = "НеЗаполнено"; // Ошибка! Ссылка только для чтения.
Чтобы изменить данные, необходимо сначала получить объект из ссылки. Выясним, как это сделать правильно, учитывая возможные пустые значения.
Разберем ситуацию из практики: при подборе номенклатуры в таблицу характеристика может быть не указана. Наша задача — проверить, заполнена ли ссылка, и если нет — найти существующую техническую характеристику "НеЗаполнено" или создать её. Проанализируем правильный подход по шагам.
Шаг 1. Проверка заполнения ссылки
Для проверки того, выбрано ли значение в поле, мы используем функцию ЗначениеЗаполнено(). Использование сравнения с Неопределено или пустой строкой для ссылочных типов часто является некорректным.
Шаг 2. Поиск существующего элемента
Прежде чем создавать новый элемент, мы обязаны проверить, нет ли его уже в базе. В случае с справочником ХарактеристикиНоменклатуры, который почти всегда является подчиненным справочнику Номенклатура, поиск должен выполняться строго с учетом Владельца.
// Правильный поиск с учетом владельца
НайденнаяСсылка = Справочники.ХарактеристикиНоменклатуры.НайтиПоНаименованию("НеЗаполнено", Истина, стрО.Номенклатура);
Шаг 3. Создание нового элемента
Если поиск вернул пустую ссылку (НайденнаяСсылка.Пустая()), мы приступаем к созданию. Разберем по шагам процесс инициализации нового объекта:
СоздатьЭлемент().Владелец (для подчиненных справочников).Наименование и другие обязательные реквизиты.Записать(), чтобы сохранить данные в БД и получить ссылку.Рассмотрим пример кода, реализующего эту логику в цикле обхода таблицы:
Если ЗначениеЗаполнено(стрО.Характеристика) Тогда
СТРВ.Характеристика = стрО.Характеристика;
Иначе
// Пытаемся найти техническую характеристику у конкретной номенклатуры
ХарактеристикаСсылка = Справочники.ХарактеристикиНоменклатуры.НайтиПоНаименованию("НеЗаполнено", Истина, стрО.Номенклатура);
Если ХарактеристикаСсылка.Пустая() Тогда
// Если не нашли — создаем
НовыйОбъект = Справочники.ХарактеристикиНоменклатуры.СоздатьЭлемент();
НовыйОбъект.Владелец = стрО.Номенклатура; // Установка владельца критична!
НовыйОбъект.Наименование = "НеЗаполнено";
Попытка
НовыйОбъект.Записать();
ХарактеристикаСсылка = НовыйОбъект.Ссылка;
Исключение
Сообщить("Не удалось создать характеристику: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
СТРВ.Характеристика = ХарактеристикаСсылка;
КонецЕсли;
Эта ошибка возникает, когда вы пытаетесь вызвать метод (например, ПолучитьОбъект()) у переменной, которая содержит Неопределено, Null или пустую ссылку типа, отличного от ожидаемого. Рассмотрим ситуацию: если поле в таблице пустое, метод стрО.Характеристика.ПолучитьОбъект() вызовет исключение. Перед получением объекта всегда проверяйте ссылку на пустоту методом Пустая().
В современных конфигурациях 1С (таких как УТ 11, ERP 2.5) справочник характеристик имеет свои особенности. Часто в модуле объекта прописаны строгие проверки в обработчике ПередЗаписью. Выясним причину ошибки "Значение поля 'Рабочее наименование' не уникально".
Эта ошибка означает, что для данного Владельца (Номенклатуры) уже существует запись с таким же текстом в поле, которое система использует для контроля уникальности. Проанализируем, почему это происходит:
НайтиПоНаименованию(), и система не нашла существующий элемент, решив создать новый-дубль.КонтролироватьУникальностьРабочегоНаименованияНоменклатурыИХарактеристик.В некоторых случаях, если технически необходимо создать элемент в обход типовых проверок уникальности, разработчики используют дополнительные свойства объекта:
НовыйОбъект.ДополнительныеСвойства.Вставить("РабочееНаименованиеПроверено", Истина);
Однако, наиболее правильным решением будет корректная настройка поиска, чтобы программа "видела" уже созданные элементы и не пыталась записать их повторно.
Подводя итог нашему анализу, сформулируем основные правила работы с СправочникСсылка:
СправочникСсылка. Например, Объект.Склад = "Основной" — это грубая ошибка. Нужно найти ссылку: Объект.Склад = Справочники.Склады.НайтиПоНаименованию("Основной").ТаблицаЗначений всегда указывайте ОписаниеТипов, чтобы система понимала, какие данные там хранятся.Попытка ... Исключение, так как запись может быть заблокирована другим пользователем или прервана проверками в модуле объекта.Соблюдение этих правил позволит вам писать надежный код, который не будет "падать" при встрече с пустыми данными и не создаст в базе данных тысячи ненужных дублей.