Как по нажатию кнопки открыть табличную часть документа в 1С 8.3

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

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

Начинающие разработчики часто пытаются решить эту задачу «в лоб», пытаясь передать путь к табличной части (ТЧ) непосредственно в метод ОткрытьФорму(). Давайте сразу проясним важный архитектурный момент: у табличной части документа нет собственной формы. Табличная часть — это лишь структура хранения данных в базе, не являющаяся самостоятельным интерфейсным объектом. Напрямую вызвать её как отдельное окно программно невозможно.

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

Сценарий 1. Использование стандартной формы выбора (Множественный подбор)

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

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

Шаг 1. Написание обработчика кнопки «Подбор»

Нам необходимо открыть форму выбора справочника Сотрудники. Чтобы окно не закрывалось сразу после клика на первого сотрудника, и пользователь мог выбрать сразу нескольких человек, мы настроим параметры формы.

Проанализируем следующий код на клиенте:


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

Шаг 2. Обработка выбранных данных в форме документа

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

Создадим обработчик события ОбработкаВыбора для таблицы на форме документа:


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

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

Сценарий 2. Создание произвольной формы подбора (Ввод сотрудника и зарплаты)

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

Шаг 1. Создание вспомогательной формы подбора в конфигураторе

Вы можете создать эту форму непосредственно внутри самого документа (как подчиненный объект «Форма») либо оформить её как форму внешней обработки, если планируете использовать её в разных местах конфигурации. Назовем её ФормаПодбора.

  1. Откройте редактор созданной формы и перейдите на вкладку «Реквизиты».
  2. Создайте новый реквизит формы с именем ТаблицаПодбора и типом данных ТаблицаЗначений.
  3. Внутри этого реквизита создайте две колонки:
    • Сотрудник (тип: СправочникСсылка.Сотрудники);
    • Зарплата (тип: Число, длина 15, точность 2).
  4. Перетащите мышкой реквизит ТаблицаПодбора в левую часть редактора — на рабочую область формы. Платформа автоматически сгенерирует элемент интерфейса «Таблица».
  5. На вкладке «Команды» добавьте новую команду формы с именем ПеренестиВДокумент и выведите её на форму в виде кнопки.

Шаг 2. Разработка кода во вспомогательной форме подбора

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

Пропишем следующий обработчик для нашей кнопки переноса данных:


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

Шаг 3. Вызов формы и обработка результата в документе

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

1. Код для кнопки «Подбор» на форме документа:


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

2. Процедура-обработчик результата в форме документа:

Обратите внимание на то, что данная процедура обязательно должна иметь ключевое слово Экспорт, иначе платформа не сможет вызвать её из другого контекста.


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

Выводы и рекомендации

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

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

← На главную