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

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

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

Анализ проблемы: почему код «не заходит» в серверную процедуру?

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

Также важно проверить настройки отладки. Разберем этот момент подробнее: в конфигураторе через меню Отладка -> Подключение необходимо убедиться, что отладчик видит и клиентский сеанс (тонкий или веб-клиент), и серверный процесс. Если серверная отладка не включена в параметрах запуска службы 1С, точка останова в процедурах &НаСервере просто не сработает.

Правильное получение ссылки из динамического списка

Для того чтобы получить данные из левой таблицы (динамического списка), рассмотрим использование свойства ТекущиеДанные. Часто разработчики пытаются передать "Наименование" или "Номер" документа, однако для поиска данных в базе всегда следует использовать Ссылку. Это гарантирует уникальность и быстродействие запроса.

Посмотрим на пример кода на клиенте:


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

Различие между реквизитами формы и элементами формы

Проанализируем одну из самых критических ошибок, упомянутую в обсуждении. Попытка записать данные напрямую в ЭтаФорма.Элементы.ИмяКолонки = Значение является в корне неверной. В управляемом приложении действует строгая иерархия:

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

Рассмотрим, как нельзя делать (ошибка из сообщения №15):


// ОШИБОЧНЫЙ КОД
Для Каждого СтрокаТЧ Из Результат Цикл
    // Попытка обращения к визуальному элементу вместо данных
    ЭтаФорма.Элементы.МояТаблицаИмя = СтрокаТЧ.Имя; 
КонецЦикла;

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

Оптимизация заполнения таблицы: метод Загрузить()

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

Разберем пример реализации на сервере:


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

Использование ЗаполнитьЗначенияСвойств

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


&НаСервере
Процедура ЗаполнитьВЦикле(РезультатЗапроса)
    
    // Очищаем реквизит формы (коллекцию данных)
    НазначенныеОтветственные.Очистить();
    
    Выборка = РезультатЗапроса.Выбрать();
    
    Пока Выборка.Следующий() Цикл
        // Добавляем новую строку в ДАННЫЕ формы
        НоваяСтрока = НазначенныеОтветственные.Добавить();
        
        // Автоматически копируем данные из выборки в строку таблицы
        ЗаполнитьЗначенияСвойств(НоваяСтрока, Выборка);
    КонецЦикла;
    
КонецПроцедуры

Подведем итоги

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

← На главную