При программной работе с документами в платформе 1С:Предприятие начинающие разработчики часто пытаются получить данные из элементов формы, используя метод ПолучитьФорму() и обращаясь к свойству ТекущиеДанные. Однако такой подход нередко приводит к ошибкам или возвращает Неопределено. Разберем по шагам, почему возникает эта проблема и как правильно обращаться к реквизитам документа и его табличным частям напрямую.
Проанализируем ситуацию, когда выполняется код создания формы программным способом:
ФормаОб = ПлатВх.ПолучитьФорму("ФормаДокумента");
Нстр = ФормаОб.ЭлементыФормы.РасшифровкаПлатежа.ТекущиеДанные.ДокументРасчетовСКонтрагентом;
При вызове метода ПолучитьФорму() создается новый экземпляр формы. Поскольку форма еще не была открыта пользователем интерактивно, контекст формы не загружен, а события (например, ПриОткрытии) еще не выполнялись. Соответственно, понятие «текущая строка» для табличного поля отсутствует, и свойство ТекущиеДанные принимает значение Неопределено. Обращение к реквизиту от Неопределено приводит к критической ошибке.
Важно: Если цель заключается в чтении или обработке учетных данных документа, не следует обращаться к элементам интерфейса. Вся бизнес-логика должна работать непосредственно с реквизитами самого документа (ссылки или объекта).
Рассмотрим, как правильно прочитать значение реквизита из табличной части документа без обращения к форме. Табличная часть объекта представляет собой коллекцию строк, к которым можно обращаться по индексу или с помощью цикла Для Каждого.
Если необходимо получить значение из конкретной строки (например, первой строки табличной части РасшифровкаПлатежа), используем следующий код:
ЗначениеРеквизита = ПлатВх.РасшифровкаПлатежа[0].ДокументРасчетовСКонтрагентом;
Для безопасного обращения рекомендуется предварительно проверить, содержит ли табличная часть хотя бы одну строку:
Если ПлатВх.РасшифровкаПлатежа.Количество() > 0 Тогда
ЗначениеРеквизита = ПлатВх.РасшифровкаПлатежа[0].ДокументРасчетовСКонтрагентом;
КонецЕсли;
Выясним причину еще одной частой ошибки. При попытке проверить, выбран ли документ в поле составного типа данных, разработчики вызывают метод Пустая():
Если ПлатВх.РасшифровкаПлатежа[0].ДокументРасчетовСКонтрагентом.Пустая() = Ложь Тогда
// Выполнение действий
КонецЕсли;
Если реквизит не заполнен, платформа возвращает ошибку: «Значение не является значением объектного типа (Пустая)».
Это происходит потому, что у реквизитов составного типа (которые могут хранить ссылки на разные типы документов или справочников) значение по умолчанию равно Неопределено, а не пустой ссылке конкретного типа. Метод Пустая() существует только у ссылочных типов данных, поэтому при вызове его от значения Неопределено возникает ошибка времени выполнения.
Для универсальной и безопасной проверки заполнености любых реквизитов (включая составные типы) в 1С предусмотрена глобальная функция ЗначениеЗаполнено().
Разберем итоговый правильный вариант условия с проверкой наличия строк и заполнености реквизита:
Если ПлатВх.РасшифровкаПлатежа.Количество() > 0 Тогда
ДокументРасчетов = ПлатВх.РасшифровкаПлатежа[0].ДокументРасчетовСКонтрагентом;
Если ЗначениеЗаполнено(ДокументРасчетов) Тогда
// Документ расчетов выбран, выполняем необходимую логику
НомерДокумента = ДокументРасчетов.Номер;
КонецЕсли;
КонецЕсли;
Функция ЗначениеЗаполнено() корректно обрабатывает значения Неопределено, Null, пустые ссылки любых типов, пустые строки и нулевые даты, что делает ее наиболее надежным инструментом при работе с данными в 1С.