Как вывести значение в поле или колонку формы без создания реквизита в 1С?

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

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

Попытка записать расчетное значение напрямую в элемент формы обычно приводит к ошибке платформы: «Поле объекта недоступно для записи». Разберем причины возникновения этой ситуации и по шагам рассмотрим корректные способы решения задачи.

Причина ошибки «Поле объекта недоступно для записи»

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

Когда разработчик пишет следующую конструкцию:

ЭтаФорма.Элементы.Остаток = Количество - Стр.Количество;

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

Способ 1. Вывод остатка в отдельное поле или надпись на форме

Если требуется отображать остаток под табличной частью в виде отдельной строки или поля ввода, недоступного для редактирования, рассмотрим два варианта реализации.

Вариант через реквизит формы (поле ввода):

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

ОстатокТовара = Количество - Стр.Количество;

Вариант через декорацию (текстовая надпись):

Если требуется вывести не поле ввода, а обычный текст, разберем работу с элементом вида Декорация — надпись:

  1. В дереве элементов формы нажмем «Добавить» и выберем тип элемента «Декорация — надпись», задав имя, например, НадписьОстаток.
  2. В программном коде значение выводится путем изменения свойства Заголовок элемента формы:

Элементы.НадписьОстаток.Заголовок = "Остаток: " + Формат(Количество - Стр.Количество, "ЧДЦ=2");

Способ 2. Добавление колонки остатка напрямую в строки таблицы

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

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

Теперь обращение к этой колонке в коде обработчиков выполняется через текущую строку таблицы:


Стр = Элементы.Товары.ТекущиеДанные;
Если Стр <> Неопределено Тогда
    Стр.Остаток = Количество - Стр.Количество;
КонецЕсли;

Оптимизация производительности и обработка событий

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

1. Корректные события для обновления данных

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


&НаКлиенте
Процедура ТоварыПриАктивизацииСтроки(Элемент)
    ТекущиеДанные = Элементы.Товары.ТекущиеДанные;
    Если ТекущиеДанные = Неопределено Тогда
        ОстатокТовара = 0;
        Возврат;
    КонецЕсли;
    
    // Расчет и обновление поля остатка
    ОстатокТовара = ПолучитьОстатокСервер(ТекущиеДанные.Номенклатура) - ТекущиеДанные.Количество;
КонецПроцедуры

2. Отказ от тяжелого метода РеквизитФормыВЗначение

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


&НаСервере
БезКонтекста
Функция ПолучитьОстатокНоменклатуры(Номенклатура, Склад, Организация, Дата)
    Возврат МТ_ОперативныйУчетВСкладах.МТ_ПолучитьОстаток(Номенклатура, Склад, Организация, Дата);
КонецФункции

3. Снижение частоты серверных вызовов

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

← На главную