Как исправить ошибку «Проверка мутабельных значений на заполненность не поддерживается» в 1С?

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

При написании или доработке программного кода на платформе 1С:Предприятие разработчики нередко сталкиваются с исключением: «Ошибка при вызове метода контекста (ЗначениеЗаполнено): Проверка мутабельных значений на заполненность не поддерживается». Давайте подробно разберем, почему возникает данное исключение, какие типы данных платформа считает мутабельными и как правильно переписать проверку в зависимости от решаемой прикладной задачи.

Проанализируем типовую ситуацию из практики. В коде общего модуля выполняется условие:


Если ЗначениеЗаполнено(ОперацияЗБ) Тогда
    // Выполнение алгоритма
КонецЕсли;

Если в переменную ОперацияЗБ вместо ссылки передается сам прикладной объект (например, ДокументОбъект или СправочникОбъект), платформа немедленно прерывает выполнение с указанной ошибкой. Выясним причину такого поведения системы.

Почему возникает ошибка: концепция мутабельности в 1С

Функция ЗначениеЗаполнено() предназначена исключительно для работы с неизменяемыми (иммутабельными) типами и примитивными значениями. К ним относятся:

  1. Примитивные типы: Число, Строка, Дата, Булево, УникальныйИдентификатор.
  2. Специальные значения: Неопределено, Null.
  3. Ссылочные типы метаданных: ДокументСсылка.*, СправочникСсылка.*, ПеречислениеСсылка.*, ПланВидовХарактеристикСсылка.* и другие.

Мутабельными (изменяемыми) называются типы данных, внутреннее состояние которых может динамически модифицироваться в процессе работы программы. Платформа 1С принципиально не может однозначно определить критерий «заполненности» сложного составного объекта, поскольку в нем могут присутствовать десятки реквизитов и табличных частей. К мутабельным типам относятся:

  1. Объекты прикладных данных: ДокументОбъект.*, СправочникОбъект.*, ПланВидовХарактеристикОбъект.*, ОбработкаОбъект.* и т. д.
  2. Универсальные коллекции: Массив, Структура, Соответствие, ТаблицаЗначений, ДеревоЗначений, СписокЗначений.

Попытка передать любой из перечисленных выше типов напрямую в метод ЗначениеЗаполнено() всегда вызывает исключение. Рассмотрим рабочие способы исправления ошибки.

Вариант 1. Проверка инициализации переменной

Если в алгоритме требуется лишь убедиться, что переменная содержит переданный объект, а не является пустым значением Неопределено или Null, заменим вызов функции на прямое сравнение:


Если ОперацияЗБ <> Неопределено И ОперацияЗБ <> Null Тогда
    // Объект передан в переменную и доступен для работы
КонецЕсли;

Вариант 2. Проверка заполненности ссылки объекта

Если в переменной находится прикладной объект данных (например, ДокументОбъект), мы можем проверить его реквизит Ссылка. Сама ссылка является иммутабельным значением, поэтому метод ЗначениеЗаполнено() отработает корректно:


Если ОперацияЗБ <> Неопределено И ЗначениеЗаполнено(ОперацияЗБ.Ссылка) Тогда
    // Ссылка объекта не является пустой
КонецЕсли;

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

Вариант 3. Проверка факта существования объекта в базе данных

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


Если ОперацияЗБ <> Неопределено Тогда
    Если Не ОперацияЗБ.ЭтоНовый() Тогда
        // Документ уже существует и сохранен в базе данных
    КонецЕсли;
КонецЕсли;

Вариант 4. Универсальная проверка для полиморфных параметров

Разберем ситуацию, когда в одну и ту же процедуру из разных мест конфигурации может приходить как ссылка (ДокументСсылка), так и сам объект (ДокументОбъект), либо значение Неопределено. В таком случае напишем универсальную проверку через свойство Ссылка или анализ типа:


Если ОперацияЗБ <> Неопределено И ОперацияЗБ <> Null Тогда
    СсылкаДляПроверки = Неопределено;
    
    // Проверяем, передана ссылка или объект
    Если ОбщегоНазначенияКлиентСервер.ЭтоСсылка(ТипЗнч(ОперацияЗБ)) Тогда
        СсылкаДляПроверки = ОперацияЗБ;
    ИначеЕсли ОбщегоНазначенияКлиентСервер.ЕстьРеквизитИлиСвойствоОбъекта(ОперацияЗБ, "Ссылка") Тогда
        СсылкаДляПроверки = ОперацияЗБ.Ссылка;
    КонецЕсли;
    
    Если ЗначениеЗаполнено(СсылкаДляПроверки) Тогда
        // Обработка данных
    КонецЕсли;
КонецЕсли;

Если функции БСП недоступны, проверим тип стандартными средствами платформы:


ТипЗначения = ТипЗнч(ОперацияЗБ);

Если Документы.ТипВсеСсылки().СодержитТип(ТипЗначения) Тогда
    Заполнено = ЗначениеЗаполнено(ОперацияЗБ);
ИначеЕсли ОперацияЗБ <> Неопределено И ОперацияЗБ <> Null Тогда
    Заполнено = ЗначениеЗаполнено(ОперацияЗБ.Ссылка);
Иначе
    Заполнено = Ложь;
КонецЕсли;

Вариант 5. Проверка коллекций значений

Если в переменную ошибочно передается универсальная коллекция (например, Массив, ТаблицаЗначений, Структура), проверку на заполненность выполняем через метод Количество():


// Для массивов, таблиц значений и списков
Если ПеременнаяКоллекция <> Неопределено И ПеременнаяКоллекция.Количество() > 0 Тогда
    // В коллекции есть элементы
КонецЕсли;

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

← На главную