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