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