При разработке дополнительных отчетов и обработок в среде 1С на базе Библиотеки стандартных подсистем (БСП) программисты часто сталкиваются с необходимостью передать контекст текущего документа во вновь открываемую форму внешней обработки. Например, это требуется при создании загрузчиков спецификаций из Excel (XLS), когда пользователю нужно сначала открыть форму обработки, выбрать файл, а затем заполнить табличную часть текущего документа.
В этой статье мы подробно разберем, как правильно зарегистрировать такую обработку в системе, исправить частые ошибки совместимости версий БСП и получить ссылку на исходный документ внутри формы обработки.
В старых версиях БСП для вывода всплывающих окон использовался метод СтандартныеПодсистемыКлиентСервер.ВывестиОповещение(). Если вы скопировали код регистрации из устаревшего примера, система выдаст ошибку, так как в современных версиях библиотеки этот метод был упразднен.
Для исправления этой ситуации проанализируем контекст вызова. Нам необходимо заменить устаревший метод на штатный механизм платформы 1С:
ПоказатьОповещениеПользователя(
"Успешно",
ПолучитьНавигационнуюСсылка(Объект.Ссылка),
"Данные успешно загружены в документ!"
);
ОбщегоНазначения.СообщитьПользователю("Обработка данных завершена успешно.");
Рекомендуется просто закомментировать или удалить вызовы устаревшего метода ВывестиОповещение из серверных процедур заполнения.
Для того чтобы документ «знал» о существовании нашей обработки, мы должны объявить её в модуле объекта обработки в экспортной функции СведенияОВнешнейОбработке(). Разберем правильный вариант заполнения параметров регистрации для сценария с открытием формы.
Важно использовать тип команды ТипКомандыОткрытиеФормы(). Это укажет БСП, что вместо фонового выполнения кода на сервере нужно открыть основную форму нашей обработки.
Рассмотрим пример кода регистрации в модуле объекта внешней обработки:
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.1");
ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиЗаполнениеОбъекта();
// Указываем документы, к которым подключается обработка
ПараметрыРегистрации.Назначение.Добавить("Документ.ЗаказНаПеремещение");
// Добавляем команду для открытия формы
НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
НоваяКоманда.Представление = "Заполнить из XLS (открытие формы)";
НоваяКоманда.Идентификатор = "ЗаполнитьЗаказФорма";
НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыОткрытиеФормы();
НоваяКоманда.ПоказыватьОповещение = Истина;
Возврат ПараметрыРегистрации;
КонецФункции
Для назначаемых (контекстных) обработок БСП автоматически передает в открываемую форму параметры запуска. Главный из них — массив ссылок на объекты, из которых была вызвана обработка.
Выясним, как подготовить форму обработки к приему этих данных:
ОбъектыНазначения.Произвольный (поскольку БСП передает туда значение типа Массив, которого нет в стандартном списке типов параметров формы).Если вы не создадите этот параметр вручную, в некоторых версиях платформы и конфигураций при попытке открыть форму может возникнуть ошибка обращения к несуществующему параметру.
Теперь, когда БСП передает ссылку на исходный документ в параметрах формы, мы можем легко прочитать её при инициализации формы обработки на сервере.
Для этого в модуле формы нашей внешней обработки перейдем к обработчику события ПриСозданииНаСервере. Проанализируем пример кода:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Проверяем, передан ли параметр со ссылками на объекты назначения
Если Параметры.Свойство("ОбъектыНазначения") И ТипЗнч(Параметры.ОбъектыНазначения) = Тип("Массив") Тогда
Если Параметры.ОбъектыНазначения.Количество() > 0 Тогда
// Извлекаем первую ссылку из массива (обычно обработка вызывается из одного документа)
СсылкаНаДокумент = Параметры.ОбъектыНазначения[0];
// Записываем ссылку в реквизит формы для дальнейшего использования в других процедурах
Объект.ДокументСсылка = СсылкаНаДокумент;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Обратите внимание: в коде выше предполагается, что у вас создан реквизит обработки ДокументСсылка с типом, соответствующим вашему документу (например, ДокументСсылка.ЗаказНаПеремещение) или общего типа ДокументСсылка.
Если ваша внешняя обработка используется для заполнения табличной части документа (например, импорт строк номенклатуры из Excel), крайне не рекомендуется записывать документ в базу данных принудительно прямо из кода обработки. Пользователь должен иметь возможность увидеть результат заполнения на экране, проверить его и самостоятельно решить — сохранить документ или закрыть его без изменений.
Посмотрим, как организовать интерактивный перенос данных в форму-владелец. При открытии обработки через БСП формой-владельцем автоматически назначается форма исходного документа. Мы можем обратиться к ней через свойство ВладелецФормы на клиенте:
&НаКлиенте
Процедура ИмпортироватьДанныеВДокумент()
// Проверяем доступность формы-владельца
Если ВладелецФормы = Неопределено Тогда
Предупреждение("Не найдена форма документа для заполнения!");
Возврат;
КонецЕсли;
// Получаем объект формы-владельца (документа)
ДанныеФормыДокумента = ВладелецФормы.Объект;
// Пример заполнения табличной части "Товары" в документе-владельце
Для Каждого СтрокаИзТаблицыЭкселя Из Объект.ТаблицаИмпортированныхТоваров Цикл
НоваяСтрока = ДанныеФормыДокумента.Товары.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаИзТаблицыЭкселя);
КонецДляКаждого;
// Обязательно устанавливаем флаг модифицированности формы документа,
// чтобы звезда модификации появилась на заголовке окна и программа предложила сохранить изменения
ВладелецФормы.Модифицированность = Истина;
// Закрываем форму нашей вспомогательной обработки
Закрыть();
КонецПроцедуры
Используя этот подход, мы получаем максимально удобный и безопасный для пользователя сценарий: открывается форма обработки, загружаются данные из внешнего файла, а по нажатию кнопки «Перенести» данные мгновенно отображаются в форме документа без лишней и преждевременной записи в СУБД.