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

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

В процессе разработки на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда в табличную часть (ТЧ) документа на форме добавляются вспомогательные колонки. Эти колонки могут быть созданы вручную в редакторе формы или программно через метод ИзменитьРеквизиты(). Проблема возникает, когда мы пытаемся обратиться к этим данным из внешней обработки или из модуля объекта: система выдает ошибку «Поле объекта не обнаружено». Рассмотрим подробнее, почему это происходит и как правильно организовать работу с такими данными.

Разберем причину ошибки: Различие контекстов объекта и формы

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

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

Решение 1: Использование «Дополнительных свойств»

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

Рассмотрим по шагам, как реализовать этот механизм:

  1. В модуле формы, в процедуре ПередЗаписьюНаСервере, мы извлекаем значение из нашего «эфемерного» реквизита ТЧ.
  2. Помещаем это значение в структуру ДополнительныеСвойства текущего объекта.
  3. В модуле объекта (например, в ПриЗаписи) извлекаем это значение и используем его.

Пример кода для модуля формы:


&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
    // Допустим, у нас есть программная колонка "СлужебнаяИнформации" в ТЧ
    // Передаем данные из первой строки ТЧ на форме в объект
    Если Объект.Товары.Количество() > 0 Тогда
        ТекущийОбъект.ДополнительныеСвойства.Вставить("ВажноеЗначение", Элементы.Товары.ТекущиеДанные.СлужебнаяИнформация);
    КонецЕсли;
КонецПроцедуры

Решение 2: Перенос реквизита в метаданные (самый надежный способ)

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

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

Решение 3: Программный доступ через контекст формы

Посмотрим на ситуацию, когда нам все же нужно прочитать данные именно из открытой формы из другой обработки. Это возможно только в том случае, если у нас есть ссылка на экземпляр УправляемаяФорма. В 1С 8.3 мы можем обратиться к реквизиту формы напрямую через точку от объекта формы.

Рассмотрим пример, где мы получаем доступ к реквизиту формы:


// В контексте, где доступна переменная "ФормаДокумента"
ЗначениеКолонки = ФормаДокумента.Элементы.Товары.ТекущиеДанные.ИмяВашейКолонки;

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

Особенности работы с табличными частями (ТЧ)

Важно понимать нюанс с коллекциями. Когда вы добавляете колонку программно на форму, она попадает в коллекцию ДанныеФормыКоллекция. При этом коллекция ЭтотОбъект.ИмяТЧ в модуле объекта остается неизменной. Она содержит только те колонки, которые определены в дереве метаданных. Любые расчетные или временные колонки на форме будут полностью проигнорированы платформой при передаче объекта с клиента на сервер для записи в БД.

Альтернативные способы хранения (без изменения структуры документа)

Если вы не хотите «раздувать» структуру документа лишними полями, но данные сохранять нужно, проанализируем следующие варианты:

Резюме и рекомендации

Если вы столкнулись с ошибкой «Поле объекта не обнаружено» при попытке доступа к колонке ТЧ, выполните следующие действия:

  1. Проверьте место создания: Если поле создано только в «Элементах» или «Реквизитах» формы, оно недоступно через Объект или Ссылка.
  2. Оцените необходимость хранения: Если значение нужно сохранять — добавьте его в реквизиты ТЧ в конфигураторе.
  3. Используйте ДополнительныеСвойства: Для разовой передачи данных из формы в модуль объекта при записи это лучший инструмент.
  4. Разделяйте логику: Никогда не полагайтесь на данные формы в алгоритмах, которые должны работать автономно (в фоновых заданиях или внешних обработках).

Таким образом, понимание жизненного цикла формы и объекта позволяет избежать архитектурных ошибок и создавать стабильный код, который не ломается при обновлении или работе в фоновых режимах.

← На главную