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