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

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

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

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

Анализ исходной проблемы и неверного подхода

Давайте проанализируем ситуацию автора. Задача — в форме списка справочника материалов вывести актуальное количество остатков по каждой позиции. Первоначальная идея заключалась в том, чтобы при открытии формы получить текущую строку и для неё рассчитать остаток, обратившись к серверной функции.

Вот пример кода, который приводил к ошибке:

Код в модуле формы списка:


&НаКлиенте
Процедура ПриОткрытии(Отказ)
    СтрокаТабличнойЧасти = Элементы.Список.ТекущиеДанные;
    // На следующей строке возникает ошибка
    СтрокаТабличнойЧасти.Количество = РаботаСоСправочниками.ОстатокПоМатериалам(ТекущаяДата(), СтрокаТабличнойЧасти.Наименование);
КонецПроцедуры

Код в общем модуле:


Функция ОстатокПоМатериалам(АктуальнаяДата, ЭлементНоменклатуры) Экспорт
    Отбор = Новый Структура("Номенклатура", ЭлементНоменклатуры);
    ЗначенияРесурсов = РегистрыНакопления.РегистрСклада.Остатки(АктуальнаяДата, Отбор);
    Возврат ЗначенияРесурсов.Количество;
КонецФункции

Ошибка {Форма.ФормаСписка.Форма(34)}: Значение не является значением объектного типа (Количество) возникает в строке СтрокаТабличнойЧасти.Количество = ....

В чем причина?

Причина кроется в строке СтрокаТабличнойЧасти = Элементы.Список.ТекущиеДанные;. Событие ПриОткрытии на клиенте срабатывает в самый момент инициализации и открытия формы. В этот момент пользователь еще не выбрал ни одной строки в списке, курсор нигде не стоит. Соответственно, свойство Элементы.Список.ТекущиеДанные возвращает Неопределено. Когда мы пытаемся обратиться к свойству у значения Неопределено (Неопределено.Количество), система и выдает закономерную ошибку.

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

Правильное решение: модификация запроса динамического списка

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

Рассмотрим по шагам, как это сделать.

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

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

  5. Добавьте таблицу остатков. В конструкторе запроса, в левой части, где отображаются таблицы базы данных, найдите ваш регистр накопления. Нам нужна его виртуальная таблица остатков. Например, РегистрНакопления.РегистрСклада.Остатки. Перетащите ее в правую часть, в область «Таблицы».
  6. Настройте связь. Перейдите на вкладку «Связи». Платформа, скорее всего, попытается создать связь автоматически, но ее нужно проверить. Нам нужно связать таблицу справочника с таблицей остатков. Связь должна быть типа «Левое соединение». Это важно, потому что так в список попадут даже те материалы, по которым еще не было движений и нет остатков.

    Условие связи будет выглядеть примерно так:

    СправочникМатериалыНоменклатура.Ссылка = РегистрСкладаОстатки.Номенклатура

  7. Выберите поля для вывода. На вкладке «Таблицы и поля» выберите все нужные поля из справочника (Ссылка, Код, Наименование) и поле с остатком из таблицы остатков (например, КоличествоОстаток).
  8. Обработайте значения NULL. Если по номенклатуре нет остатка, левое соединение вернет для поля остатка значение NULL. В форме это будет выглядеть как пустое поле. Чтобы вместо пустоты отображался 0, нужно использовать функцию языка запросов ЕСТЬNULL(). Перейдите на вкладку «Вычисляемые поля», создайте новое поле (например, «Остаток») и напишите для него выражение: ЕСТЬNULL(РегистрСкладаОстатки.КоличествоОстаток, 0)

    Теперь это поле «Остаток» можно использовать для вывода в список.

После всех этих действий текст вашего запроса будет выглядеть примерно так:


ВЫБРАТЬ
    СправочникМатериалыНоменклатура.Ссылка,
    СправочникМатериалыНоменклатура.Наименование,
    СправочникМатериалыНоменклатура.Код,
    ЕСТЬNULL(РегистрСкладаОстатки.КоличествоОстаток, 0) КАК Количество
ИЗ
    Справочник.МатериалыНоменклатура КАК СправочникМатериалыНоменклатура
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.РегистрСклада.Остатки КАК РегистрСкладаОстатки
        ПО СправочникМатериалыНоменклатура.Ссылка = РегистрСкладаОстатки.Номенклатура

Осталось только добавить новую колонку на форму, перетащив поле «Количество» из реквизита «Список» в дерево элементов формы.

Что делать, если колонка остатков все равно пустая?

Иногда даже после правильной настройки запроса колонка с остатками остается пустой. Давайте разберем возможные причины.

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

← На главную