Как правильно программно добавить строку в таблицу на управляемой форме 1С?

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

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

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


Выясняем причину: почему возникает ошибка «Обращение к процедуре как к функции»?

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

НоваяСтрокаКом = Элементы.ТзНоменклатураДокумнетовДляПодбора.ДобавитьСтроку();

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

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

Разбираем по шагам: данные против интерфейса

Для успешного решения задачи нам необходимо четко разделять два понятия:

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


Правильное решение проблемы

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

НоваяСтрокаКом = ТзНоменклатураДокумнетовДляПодбора.Добавить();

Давайте проанализируем, почему этот вариант работает безошибочно:

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

Рассмотрим пример полноценного заполнения новой строки программным путем:


// Добавляем строку непосредственно в коллекцию данных формы
НоваяСтрокаКом = ТзНоменклатураДокумнетовДляПодбора.Добавить();

// Заполняем реквизиты добавленной строки
НоваяСтрокаКом.Номенклатура  = Справочники.Номенклатура.НайтиПоРеквизиту("Код", "000001");
НоваяСтрокаКом.Количество    = 10;
НоваяСтрокаКом.Цена          = 1500;
НоваяСтрокаКом.Сумма         = НоваяСтрокаКом.Количество * НоваяСтрокаКом.Цена;

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


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

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

А. Как визуально сфокусировать (выделить) добавленную строку?

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


// 1. Добавляем строку в данные
НоваяСтрокаКом = ТзНоменклатураДокумнетовДляПодбора.Добавить();

// 2. Получаем уникальный идентификатор этой строки в контексте формы
ИдентификаторСтроки = НоваяСтрокаКом.ПолучитьИдентификатор();

// 3. Устанавливаем фокус на эту строку в визуальном элементе управления
Элементы.ТзНоменклатураДокумнетовДляПодбора.ТекущаяСтрока = ИдентификаторСтроки;

Б. Как сразу открыть добавленную строку для редактирования?

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


// Добавляем строку и фокусируемся на ней
НоваяСтрокаКом = ТзНоменклатураДокумнетовДляПодбора.Добавить();
ИдентификаторСтроки = НоваяСтрокаКом.ПолучитьИдентификатор();
Элементы.ТзНоменклатураДокумнетовДляПодбора.ТекущаяСтрока = ИдентификаторСтроки;

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

// Принудительно открываем режим интерактивного редактирования ячейки
Элементы.ТзНоменклатураДокумнетовДляПодбора.ИзменитьСтроку();

В. Работа с контекстом выполнения (Клиент и Сервер)

Важно всегда контролировать, в каком контексте выполняется ваш программный код:


&НаСервере
Процедура ЗаполнитьТабличнуюЧастьНаСервере()
    // Добавление строки в табличную часть документа на сервере
    НоваяСтрока = Объект.Товары.Добавить();
    НоваяСтрока.Номенклатура = Справочники.Номенклатура.НайтиПоКоду("00012");
КонецПроцедуры

Резюме

При программной работе с таблицами в управляемых формах 1С всегда задавайте себе вопрос: я сейчас работаю с данными или с картинкой на экране?

Если вам нужно добавить строку, удалить ее, изменить количество или цену — работайте напрямую с реквизитом формы (ТзНоменклатураДокумнетовДляПодбора.Добавить()). Если же вам нужно выделить строку цветом, установить фокус ввода или скрыть какую-то колонку — используйте визуальный элемент из коллекции элементов формы (Элементы.ТзНоменклатураДокумнетовДляПодбора).

← На главную