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

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

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

Разберем типичные ошибки, возникающие при реализации этого сценария в среде управляемых форм 1С 8.3, а также рассмотрим корректные подходы к выборке данных и их передаче между контекстами.

Типичные ошибки при передаче данных между формами

Проанализируем основные архитектурные заблуждения, с которыми сталкиваются начинающие разработчики:

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

Способ 1. Обход строк таблицы и сбор отмеченных значений

Если в форме выбора используется таблица с колонками Пометка (тип Булево) и Счет, мы можем обойти строки коллекции и заполнить массив или список значений выбранными элементами.

Посмотрим на пример кода в модуле формы выбора при нажатии кнопки подтверждения:


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

Важный момент: для передачи параметров между контекстами и использования в запросах предпочтительнее использовать тип Массив, так как он легче сериализуется и потребляет меньше ресурсов по сравнению с объектом СписокЗначений. В параметрах запроса условие ГДЕ Счет В (&Счета) одинаково успешно принимает как список, так и массив.

Способ 2. Быстрый отбор через метод НайтиСтроки на сервере

Если выборка выполняется на сервере и таблица представлена полноценным объектом ТаблицаЗначений, перебирать все строки в цикле необязательно. Мы можем воспользоваться методом НайтиСтроки.

Разберем этот вариант:


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

Передача данных между формами через механизм оповещений

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

  1. В вызывающей форме (Форма 1) описываем клиентский обработчик события ОбработкаОповещения.
  2. В форме выбора (Форма 2) формируем массив счетов и вызываем метод Оповестить с уникальным именем события.
  3. При получении события Форма 1 принимает переданный параметр и отправляет его на сервер для выполнения расчетов.

Посмотрим на реализацию в вызывающей форме (Форма 1):


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

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

Выясним, как передать полученный массив счетов из модуля формы в модуль объекта (например, внешней обработки или отчета) для выполнения серверных алгоритмов.

Для этого в модуле формы вызываем серверную процедуру, которая получает объект через РеквизитФормыВЗначение и вызывает его экспортный метод.

Код в модуле формы (Форма 1):


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

Код в модуле объекта обработки:


Процедура РассчитатьДанныеПоСчетам(МассивСчетов) Экспорт
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   ХозрасчетныйОстатки.Счет КАК Счет,
        |   ХозрасчетныйОстатки.СуммаОстаток КАК СуммаОстаток
        |ИЗ
        |   РегистрБухгалтерии.Хозрасчетный.Остатки(, Счет В (&МассивСчетов), , ) КАК ХозрасчетныйОстатки";
        
    Запрос.УстановитьПараметр("МассивСчетов", МассивСчетов);
    
    РезультатЗапроса = Запрос.Выполнить();
    // Дальнейшая обработка выборки
    
КонецПроцедуры

Альтернативный вариант: возврат через ОписаниеОповещения

Более строгим и современным подходом в 1С 8.3 является использование описания оповещения при открытии формы выбора. В этом случае не требуется рассылать широковещательные оповещения через Оповестить, а результат передается напрямую в процедуру закрытия.

Разберем этот механизм по шагам:


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

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

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

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

← На главную