Как исправить ошибку «Значение не является значением объектного типа (Значение)» в отчетах 1С на базе СКД?

Программист 1С v8.3 (Обычные формы) 1C:Бухгалтерия Бухгалтерский учет IT и автоматизация бизнеса
← На главную

При работе с внешними отчетами и обработками в среде «1С:Предприятие 8.3» разработчики и пользователи часто сталкиваются со следующей ошибкой: «{ВнешнийОтчет.ИмяОтчета.МодульОбъекта(НомерСтроки)}: Значение не является значением объектного типа (Значение)». Обычно эта ошибка возникает в момент открытия отчета или при попытке сформировать данные.

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

Почему возникает эта ошибка? Выясняем причину

Ошибка «Значение не является значением объектного типа» в языке 1С означает, что программа пытается обратиться к свойству или методу переменной, которая на самом деле не является сложным объектом (структурой, справочником, элементом параметров и т.д.), а содержит простейшее значение — чаще всего Неопределено или Null.

Рассмотрим фрагмент исходного кода из темы обсуждения:


Параметры = КомпоновщикНастроек.Настройки.ПараметрыДанных;
ОтборНачПериода = Параметры.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("НачПериода"));
ОтборНачПериода.Значение = НачПериода;
ОтборНачПериода.Использование = Истина;

Давайте проанализируем эту ситуацию по шагам:

  1. Программа обращается к коллекции параметров СКД через КомпоновщикНастроек.Настройки.ПараметрыДанных.
  2. Метод НайтиЗначениеПараметра() ищет в схеме компоновки данных параметр с уникальным именем "НачПериода".
  3. Если параметр с таким именем действительно создан в схеме компоновки (вкладка «Параметры» в конструкторе СКД), метод возвращает объект типа ЗначениеПараметраНастроекКомпоновкиДанных.
  4. Если же в схеме СКД параметра с именем "НачПериода" нет (например, разработчик забыл его добавить, переименовал в запросе или удалил), метод НайтиЗначениеПараметра() возвращает значение Неопределено.
  5. На следующей строке код пытается присвоить значение свойству: ОтборНачПериода.Значение = НачПериода;. Но так как переменная равна Неопределено, у нее нет свойства Значение. Платформа аварийно завершает работу и выдает ошибку.

Таким образом, корень проблемы кроется в рассинхронизации между программным кодом инициализации и структурой параметров в самой схеме компоновки данных (СКД).

Решение 1. Добавление недостающих параметров в схему СКД

Самый очевидный и правильный путь исправления — привести структуру схемы компоновки данных в соответствие с тем, что ожидает программный код модуля. Выполним настройку схемы СКД через Конфигуратор:

  1. Запустите «1С:Предприятие» в режиме Конфигуратор.
  2. Откройте ваш внешний отчет или обработку (меню Файл -> Открыть).
  3. В окне дерева объектов найдите и откройте основную схему компоновки данных (обычно она называется ОсновнаяСхемаКомпоновкиДанных).
  4. Перейдите на вкладку Параметры в верхней панели конструктора СКД.
  5. Проверьте наличие параметров, к которым обращается код: "НачПериода" и "КонПериода". Если их там нет, добавьте их, нажав кнопку Добавить (+).
  6. Для каждого нового параметра укажите:
    • Имя: точное имя без пробелов (например, НачПериода и КонПериода).
    • Тип данных: выберите Дата.
    • Доступные значения: при необходимости настройте ограничение.
    • Ограничение доступности: снимите галочку, если хотите, чтобы пользователь мог изменять эти даты на форме отчета напрямую.
  7. Сохраните изменения во внешнем отчете и перезапустите его в режиме «1С:Предприятие».

Решение 2. Написание безопасного кода («дуракоустойчивость»)

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

Перепишем исходную процедуру, сделав ее максимально безопасной и стабильной:


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

Благодаря такой проверке, даже если параметры будут случайно удалены из схемы СКД будущими разработчиками, отчет не упадет с критической ошибкой, а продолжит открываться и работать.

Решение 3. Использование лаконичного метода УстановитьЗначениеПараметра

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

Проанализируем пример изящного решения:


Процедура УстановитьПараметры Экспорт
    // Быстрая установка значений по умолчанию
    НачДата = НачалоМесяца(ТекущаяДата());
    КонДата = КонецМесяца(ТекущаяДата());
    
    // Установка параметров СКД напрямую
    КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("НачПериода", НачДата);
    КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("КонПериода", КонецДня(КонДата));
КонецПроцедуры

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

Решение 4. Устранение проблемы кэша и сохраненных настроек пользователя

Нередко возникает странная ситуация: один пользователь открывает отчет без проблем (например, на другом компьютере или под другой учетной записью), а у второго — падает описанная выше ошибка. Почему так происходит?

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

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

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

Решение 5. Работа с Пользовательскими настройками (User Settings)

Начиная с версии платформы 8.3, параметры СКД, выведенные на форму отчета, хранятся в специальной коллекции — КомпоновщикНастроек.ПользовательскиеНастройки. Если программист меняет параметры напрямую через КомпоновщикНастроек.Настройки.ПараметрыДанных, эти изменения могут попросту не примениться к элементам на форме, так как приоритет пользовательских настроек выше.

Рассмотрим, как правильно изменять параметры с учетом механизма пользовательских настроек:


// Ищем описание параметра в основных настройках СКД
ПараметрИскомый = КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти("НачПериода");

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

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

Решение 6. Правильное архитектурное место для инициализации параметров

В обсуждении на форуме код инициализации вызывается при открытии формы (процедура УстановитьПараметры). Но что произойдет, если отчет будет формироваться программно — например, регламентным заданием по расписанию, в фоновом задании на сервере или при автоматической рассылке отчетов?

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

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


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

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

← На главную