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

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

Работа с динамическими интерфейсами в 1С — это мощный инструмент, который позволяет адаптировать форму под конкретные задачи пользователя «на лету». Однако программисты часто сталкиваются с трудностями при попытке программно добавить ТаблицуЗначений на форму и наполнить её данными. В этой статье мы подробно разберем, как правильно реализовать этот механизм, проанализируем типичные ошибки «Поле объекта не обнаружено» и выясним, почему метод ЗначениеВРеквизитФормы может выдавать исключение — для этих целей пригодится консоль разработчика для управляемых форм 1С.

Постановка задачи и архитектурный подход

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

Для решения задачи мы пройдем через три обязательных этапа:

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

Этап 1: Программное создание реквизитов формы

Рассмотрим ситуацию, когда в процедуре ПриСозданииНаСервере нам нужно объявить структуру будущей таблицы. Важно понимать, что просто создать объект Новая ТаблицаЗначений в коде недостаточно — форма «не знает» о его существовании как о части своих данных.

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


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // 1. Описываем массив добавляемых реквизитов
    МассивДобавляемыхРеквизитов = Новый Массив;
    
    // Добавляем саму таблицу. "ТЗ_Данные" — это внутреннее имя реквизита на форме
    МассивДобавляемыхРеквизитов.Добавить(Новый РеквизитФормы("ТЗ_Данные", Новый ОписаниеТипов("ТаблицаЗначений"), , "Список товаров"));
    
    // Добавляем колонки для этой таблицы. 
    // Обратите внимание на путь к данным: "ИмяТаблицы.ИмяКолонки"
    МассивДобавляемыхРеквизитов.Добавить(Новый РеквизитФормы("Код", Новый ОписаниеТипов("Строка"), "ТЗ_Данные"));
    МассивДобавляемыхРеквизитов.Добавить(Новый РеквизитФормы("Номенклатура", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"), "ТЗ_Данные"));
    МассивДобавляемыхРеквизитов.Добавить(Новый РеквизитФормы("Цена", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2)), "ТЗ_Данные"));
    
    // Применяем изменения на форме
    ЭтаФорма.ИзменитьРеквизиты(МассивДобавляемыхРеквизитов);
    
КонецПроцедуры

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

Этап 2: Создание визуальных элементов

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


&НаСервере
Процедура СоздатьВизуальныеЭлементы()
    
    // Добавляем саму таблицу на форму
    ТаблицаФормы = Элементы.Добавить("ТЗ_Вид", Тип("ТаблицаФормы"), ЭтаФорма);
    ТаблицаФормы.ПутьКДанным = "ТЗ_Данные"; // Связываем с созданным ранее реквизитом
    
    // Добавляем колонку "Код"
    НоваяКолонка = Элементы.Добавить("ТЗ_Код", Тип("ПолеФормы"), ТаблицаФормы);
    НоваяКолонка.Вид = ВидПоляФормы.ПолеВвода;
    НоваяКолонка.ПутьКДанным = "ТЗ_Данные.Код";
    НоваяКолонка.Заголовок = "Код товара";
    
    // Добавляем колонку "Номенклатура"
    НоваяКолонка = Элементы.Добавить("ТЗ_Номенклатура", Тип("ПолеФормы"), ТаблицаФормы);
    НоваяКолонка.Вид = ВидПоляФормы.ПолеВвода;
    НоваяКолонка.ПутьКДанным = "ТЗ_Данные.Номенклатура";
    НоваяКолонка.Заголовок = "Товар";

КонецПроцедуры

Этап 3: Заполнение таблицы данными из запроса

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

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


&НаСервере
Процедура пнПриИзмененииНаСервере()
    
    Если Объект.пн.Пустая() Тогда
        Возврат;
    КонецЕсли;

    // Рекомендуемый способ: Работаем сразу через реквизит формы
    // Преобразуем реквизит формы в объект ТаблицаЗначений
    ТаблицаОбъект = РеквизитФормыВЗначение("ТЗ_Данные");
    ТаблицаОбъект.Очистить();
    
    // Подготовим запрос
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   ПриходнаяНакладнаяЗапасы.Номенклатура КАК Номенклатура,
        |   ПриходнаяНакладнаяЗапасы.Номенклатура.Код КАК Код,
        |   ПриходнаяНакладнаяЗапасы.Цена КАК Цена
        |ИЗ
        |   Документ.ПриходнаяНакладная.Запасы КАК ПриходнаяНакладнаяЗапасы
        |ГДЕ
        |   ПриходнаяНакладнаяЗапасы.Ссылка = &Ссылка";
    
    Запрос.УстановитьПараметр("Ссылка", Объект.пн);
    
    // Выгружаем результат напрямую в таблицу
    ТаблицаОбъект = Запрос.Выполнить().Выгрузить();
    
    // Важно! Имена колонок в запросе (псевдонимы) ДОЛЖНЫ совпадать 
    // с именами реквизитов, добавленных в Этапе 1.
    
    // Возвращаем данные на форму
    ЗначениеВРеквизитФормы(ТаблицаОбъект, "ТЗ_Данные");
    
КонецПроцедуры

Разбор типичных ошибок

Проанализируем ситуацию из сообщения автора, где возникла ошибка «Недопустимое значение параметра (параметр номер '2')» при вызове ЗначениеВРеквизитФормы(ТДп, "Тп").

Причина 1: Неверное имя реквизита. Во втором параметре метода ЗначениеВРеквизитФормы нужно указывать строковое имя реквизита, который был добавлен через ИзменитьРеквизиты. Если вы назвали его "ТЗ_Данные", а пытаетесь записать в "Тп", система закономерно выдаст ошибку, так как реквизита "Тп" не существует в контексте формы.

Причина 2: Несоответствие типов. Если в локальной таблице значений ТДп колонка «Цена» имеет тип Число, а в реквизите формы она была объявлена как Строка, метод конвертации данных завершится ошибкой. Всегда следите за строгим соответствием типов данных.

Причина 3: Использование пустой таблицы. Ошибка Поле объекта не обнаружено (Код) при выполнении кода Строка.Код = ... означает, что в объекте ТаблицаЗначений, к которому вы обращаетесь, нет колонки с таким именем. Если вы создаете таблицу через Новый ТаблицаЗначений, вы обязаны явно прописать все колонки через ТЗ.Колонки.Добавить("Код").

Рекомендации по оптимизации

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

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

← На главную