При работе с обработкой «Загрузка данных из табличного документа» и написании произвольных алгоритмов на встроенном языке 1С разработчики часто сталкиваются с ошибками вида Проверка мутабельных значений на заполненность не поддерживается или Переменная не определена (Справочник). В этой статье мы подробно разберем причины возникновения этих ошибок и рассмотрим проверенные способы их решения.
Рассмотрев механизмы платформы 1С, выясним, почему возникает данное исключение при вычислении выражений в обработках загрузки.
Во встроенном языке 1С типы данных делятся на ссылочные и объектные (мутабельные):
СправочникОбъект, ДокументОбъект, ТаблицаЗначения). Они служат для создания и модификации записей.СправочникСсылка.НоменклатураПоставщиков). Они являются неизменяемыми значениями.В обработке загрузки данных в поле вычисления переменная Результат ожидает получить именно ссылку на элемент справочника. Если присвоить переменной Результат сам объект (типа СправочникОбъект), платформа при попытке записать его в реквизит или проверить на заполненность вызовет исключение мутабельности.
Проанализируем ошибочный фрагмент кода:
НоваяНоменклатура = Справочники.НоменклатураПоставщиков.СоздатьЭлемент();
НоваяНоменклатура.Наименование = ТекстыЯчеек[22];
НоваяНоменклатура.Записать();
// ОШИБКА: передается мутабельный объект СправочникОбъект
Результат = НоваяНоменклатура;
Для исправления ошибки необходимо явным образом получить ссылку созданного объекта через свойство Ссылка:
НоваяНоменклатура = Справочники.НоменклатураПоставщиков.СоздатьЭлемент();
НоваяНоменклатура.Наименование = ТекстыЯчеек[22];
НоваяНоменклатура.Записать();
// ПРАВИЛЬНО: передается ссылка СправочникСсылка
Результат = НоваяНоменклатура.Ссылка;
Схожее правило действует и при заполнении реквизитов подчинения. Например, реквизиту Владелец объекта справочника должно быть присвоено значение типа СправочникСсылка.
Методы поиска НайтиПоКоду() или НайтиПоНаименованию() у менеджера справочника всегда возвращают ссылочный тип. Поэтому результат поиска владельца можно присваивать напрямую:
Витта = Справочники.Партнеры.НайтиПоКоду("00-00000009");
НоваяНоменклатура.Владелец = Витта; // Витта уже является ссылкой
Разберем распространенную ошибку, когда при проверке пустой ссылки пытаются использовать синтаксис ЗНАЧЕНИЕ(Справочник.Имя.ПустаяСсылка). Конструкция ЗНАЧЕНИЕ(...) применяется исключительно в языке запросов и системе компоновки данных (СКД). При вызове в коде BSL она приводит к ошибке компиляции Переменная не определена (Справочник).
Рассмотрим 4 корректных способа проверки ссылок на пустоту во встроенном языке 1С:
Использование метода менеджерa справочника ПустаяСсылка():
Если НомПос = Справочники.НоменклатураПоставщиков.ПустаяСсылка() Тогда
// Ссылка пустая
КонецЕсли;
Использование метода самого ссылочного значения Пустая():
Если НомПос.Пустая() Тогда
// Ссылка пустая
КонецЕсли;
Использование глобальной функции ЗначениеЗаполнено():
Если Не ЗначениеЗаполнено(НомПос) Тогда
// Значение не заполнено или содержит пустую ссылку
КонецЕсли;
Использование системной функции ПредопределенноеЗначение():
Если НомПос = ПредопределенноеЗначение("Справочник.НоменклатураПоставщиков.ПустаяСсылка") Тогда
// Ссылка пустая
КонецЕсли;
Посмотрим на итоговый исправленный алгоритм поиска и создания элемента в обработке загрузки данных из табличного документа:
НомПос = Справочники.НоменклатураПоставщиков.НайтиПоНаименованию(ТекстыЯчеек[21]);
Если Не ЗначениеЗаполнено(НомПос) Тогда
Витта = Справочники.Партнеры.НайтиПоКоду("00-00000009");
НоваяНоменклатура = Справочники.НоменклатураПоставщиков.СоздатьЭлемент();
НоваяНоменклатура.Наименование = ТекстыЯчеек[22];
НоваяНоменклатура.Владелец = Витта;
НоваяНоменклатура.Записать();
Результат = НоваяНоменклатура.Ссылка;
Иначе
Результат = НомПос;
КонецЕсли;