При разработке на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с задачей вывода произвольных данных в отдельное окно. Если для документов или справочников процедура заполнения формы через реквизит Объект интуитивно понятна, то работа с общими формами вызывает вопросы, так как у них отсутствует стандартный объект данных. В этой статье мы разберем, как правильно передавать данные в общую форму, как обрабатывать их на сервере и какие инструменты платформы сделают этот процесс наиболее эффективным.
Рассмотрим типичную ситуацию: нам необходимо при двойном клике по номенклатуре в списке открывать информационное окно. В этом окне должна отображаться сама номенклатура, список ее характеристик и актуальные цены. Поскольку это окно не является формой редактирования конкретного справочника, использование общей формы — идеальный вариант. Однако, в отличие от формы документа, мы не можем просто написать Форма.Объект.Наименование = "Значение", так как реквизита Объект в общей форме попросту нет.
Выясним причину этой сложности. Управляемая форма работает в рамках парадигмы разделения данных и представления. Общая форма — это «чистый лист», состав реквизитов которого определяет сам разработчик. Для того чтобы заполнить ее «извне», существует несколько проверенных способов. Давайте разберем их по шагам.
Это самый правильный и рекомендуемый методикой 1С способ. Вместо того чтобы «заталкивать» данные в уже созданную форму, мы передаем необходимые идентификаторы в момент открытия. Форма сама инициализирует себя, используя полученные данные.
Проанализируем процесс реализации. Сначала в общей форме необходимо создать реквизиты, которые мы хотим заполнить (например, НоменклатураСсылка и таблицу Цены). Далее выполним следующие действия:
1. Вызов открытия формы с передачей структуры параметров:
&НаКлиенте
Процедура СписокВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
// Формируем структуру параметров
ПараметрыОткрытия = Новый Структура;
ПараметрыОткрытия.Вставить("Номенклатура", ВыбраннаяСтрока);
// Открываем общую форму
ОткрытьФорму("ОбщаяФорма.ПоказЦенНоменклатуры", ПараметрыОткрытия);
КонецПроцедуры
2. Обработка параметров внутри общей формы на сервере:
В модуле общей формы мы используем стандартный обработчик ПриСозданииНаСервере. Здесь мы извлекаем переданную номенклатуру и заполняем таблицу цен запросом.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Проверяем наличие параметра
Если Параметры.Свойство("Номенклатура") Тогда
ОбъектНоменклатура = Параметры.Номенклатура;
// Заполняем реквизит формы для отображения в заголовке
РеквизитНоменклатура = ОбъектНоменклатура;
// Вызываем процедуру заполнения таблицы данных
ЗаполнитьТаблицуЦенНаСервере(ОбъектНоменклатура);
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура ЗаполнитьТаблицуЦенНаСервере(СсылкаНаНоменклатуру)
// Здесь пишем запрос к регистру сведений ЦеныНоменклатуры
// И загружаем результат в таблицу формы (ДанныеФормыКоллекция)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Цены.Характеристика КАК Характеристика,
| Цены.Цена КАК Цена
|ИЗ
| РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, Номенклатура = &Номенклатура) КАК Цены";
Запрос.УстановитьПараметр("Номенклатура", СсылкаНаНоменклатуру);
РезультатЗапроса = Запрос.Выполнить();
// Загружаем данные напрямую в реквизит формы типа Таблица
ТаблицаЦен.Загрузить(РезультатЗапроса.Выгрузить());
КонецПроцедуры
Если задача заключается только в просмотре данных, использование Динамического списка в общей форме — наиболее производительный вариант. Нам не нужно писать код для выполнения запроса и обхода строк.
Разберем, как это настроить:
ДинамическийСписок.ГДЕ Номенклатура = &ПараметрНоменклатура.Посмотрим на пример кода в модуле формы:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Параметры.Свойство("Номенклатура") Тогда
// Устанавливаем параметр динамического списка
ЗначениеПараметра = СписокЦен.Параметры.Найти("ПараметрНоменклатура");
Если ЗначениеПараметра <> Неопределено Тогда
СписокЦен.Параметры.УстановитьЗначениеПараметра("ПараметрНоменклатура", Параметры.Номенклатура);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Этот метод хорош тем, что платформа сама заботится об оптимизации выборки данных, сортировке и группировке, что значительно экономит ресурсы сервера при работе с большими объемами информации.
В некоторых случаях нам нужно заполнить форму данными, которые уже есть на клиенте, не выполняя повторных запросов к базе данных. Для этого мы можем получить объект формы, напрямую обратиться к её экспортируемым переменным или методам, а затем открыть её.
Рассмотрим пример:
&НаКлиенте
Процедура КомандаОткрытьИЗаполнить(Команда)
// Получаем экземпляр формы без открытия
Форма = ПолучитьФорму("ОбщаяФорма.МояИнформационнаяФорма");
// Прямое заполнение реквизитов формы (они должны быть созданы в редакторе формы)
Форма.ЗаголовокОкна = "Информация о ценах: " + Объект.Наименование;
Форма.РеквизитТекст = "Данные сформированы вручную";
// Если нужно вызвать процедуру в форме, она должна быть объявлена с ключевым словом Экспорт
// Форма.ПодготовитьДанные();
Форма.Открыть();
КонецПроцедуры
Важное замечание: Хотя этот метод кажется простым, он менее предпочтителен, так как нарушает инкапсуляцию логики формы. Старайтесь концентрировать логику заполнения внутри самой формы (в ПриСозданииНаСервере), передавая ей только минимально необходимые входные параметры.
Часто возникает вопрос: как заполнить таблицу в общей форме, если данные приходят не из запроса, а, например, из другой таблицы значений? Нужно помнить, что таблицы на форме имеют тип ДанныеФормыКоллекция. Для работы с ними на сервере мы используем метод ЗначениеВДанныеФормы или прямой перебор.
Посмотрим на пример преобразования Таблицы Значений в данные формы:
&НаСервере
Процедура ЗаполнитьИзВнешнейТаблицы(ВнешняяТЗ)
// ВнешняяТЗ - это объект типа ТаблицаЗначений
// ТаблицаНаФорме - реквизит формы типа Список (коллекция)
ЗначениеВДанныеФормы(ВнешняяТЗ, ТаблицаНаФорме);
КонецПроцедуры
Этот прием позволяет мгновенно отрисовать готовую таблицу в интерфейсе без циклов Для Каждого.
Чтобы ваша общая форма выглядела профессионально и была удобна пользователю, воспользуйтесь следующими советами:
ТолькоПросмотр = Истина, чтобы пользователь понимал: данные здесь только для ознакомления.ИспользоватьРазделениеДанных и настройте автоматическое сохранение положения окна.Подводя итог, можно сказать, что заполнение общей формы — это гибкий процесс, который строится на передаче параметров через Структуру и последующей обработке этих параметров на стороне сервера. Выбирайте метод с ПриСозданииНаСервере как основной, и используйте Динамические списки для быстрого отображения данных из регистров. Это обеспечит высокую скорость работы приложения и чистоту вашего кода.