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