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

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

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

Шаг 1. Открытие формы выбора с параметрами

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

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


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

В данном фрагменте кода мы передаем структуру отбора, которая автоматически применится к динамическому списку открываемой формы. Параметр МножественныйВыбор позволяет пользователю выделять несколько строк через клавишу Ctrl или Shift.

Шаг 2. Перехват результата в обработчике выбора

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


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

Шаг 3. Заполнение таблицы значений на сервере

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

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


&НаСервере
Процедура ЗаполнитьТЗУслугНаСервере(МассивСсылок)
    
    // Проходим циклом по всем выбранным ссылкам
    Для Каждого СсылкаДокумента Из МассивСсылок Цикл
        
        // Получаем данные документа. 
        // Для оптимизации лучше использовать запрос, но в простом случае можно прочитать объект
        ДокументОбъект = СсылкаДокумента.ПолучитьОбъект();
        
        Для Каждого СтрокаУслуг Из ДокументОбъект.Услуги Цикл
            
            // Добавляем новую строку в нашу таблицу на форме (Объект.ТЗ_Услуги)
            НоваяСтрока = Объект.Услуги.Добавить();
            ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаУслуг);
            
            // Если требуется специфическая логика, прописываем ее явно
            НоваяСтрока.ДокументОснование = СсылкаДокумента;
            
        КонецЦикла;
        
    КонецЦикла;
    
КонецПроцедуры

Особенности работы с расширениями и именованием

Выясним причину, по которой у разработчиков часто возникают трудности при работе с формами выбора. Во-первых, если вы работаете в расширении конфигурации, убедитесь, что тип документа и его формы заимствованы правильно. В методе ОткрытьФорму следует указывать имя с учетом префикса, если форма создана непосредственно в расширении (например, "Документ.Расш1_Справка.ФормаВыбора").

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

Использование Описания Оповещения (Альтернативный вариант)

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


&НаКлиенте
Процедура КомандаОткрытьСВызовом(Команда)
    
    Оповещение = Новый ОписаниеОповещения("ЗавершитьВыборДокументов", ЭтаФорма);
    
    ПараметрыЗапуска = Новый Структура;
    ПараметрыЗапуска.Вставить("РежимВыбора", Истина);
    
    ОткрытьФорму("Документ.РеализацияТоваровУслуг.ФормаВыбора", ПараметрыЗапуска, , , , , Оповещение);
    
КонецПроцедуры

&НаКлиенте
Процедура ЗавершитьВыборДокументов(Результат, ДополнительныеПараметры) Экспорт
    Если Результат <> Неопределено Тогда
        // Обработка логики выбора
    КонецЕсли;
КонецПроцедуры

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

Итоги и рекомендации

Подведем итоги нашего анализа:

  1. Всегда проверяйте уникальность имен переменных при формировании структур параметров для ОткрытьФорму().
  2. Для реализации массового подбора используйте параметр МножественныйВыбор = Истина.
  3. Если необходимо, чтобы форма не закрывалась после каждого выбора (режим «подбора»), передавайте параметр ЗакрыватьПриВыборе = Ложь.
  4. Передачу данных из табличных частей выбранных документов выполняйте строго на сервере для минимизации клиент-серверных вызовов в цикле.
  5. При использовании расширений внимательно следите за полным путем к форме объекта.

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

← На главную