Использование и отладка некоторых дополнительных обработок с назначением

04.05.26

Разработка - БСП (Библиотека стандартных подсистем)

Пример использования и отладки внешних обработок вида Заполнение объекта и Печатная форма.

Бесплатные

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Узнавайте о новых бесплатных решениях в нашей телеграм-группе Инфостарт БЕСПЛАТНО

Наименование Скачано Бесплатно
Пример внешней обработки Печатная форма
.epf 9,11Kb
20 Скачать бесплатно
Пример внешней обработки Заполнение объекта
.epf 15,89Kb
25 Скачать бесплатно

Вы можете заказать платную доработку или адаптацию этой разработки под вашу конфигурацию на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

Довольно часто приходится создавать дополнительные обработки, в то же время пытаясь вспомнить уже готовые и похожие, которые можно использовать в качестве шаблона. Поэтому было решено и покрепче обняться с БСП, и сочинить возможный паттерн по означенной теме.

Инфраструктура отладки реализована как в самой, открытой как внешняя, обработке в приближённом к аутентичному контексте (первый вариант), так и через перенаправление вызова команды дополнительной обработки на файл внешней (второй вариант).

Назначение обеих обработок — документ Заказ клиента конфигурации 1С:ERP.

I. Заполнение объекта

Для обработки вида "Заполнение объекта" добавим 4 команды:

  • ОткрытиеФормы (вызов из формы документа, из формы списка — будем инициировать отказ)
  • ВызовКлиентскогоМетода (вызов из формы документа, из формы списка — будем открывать форму документа-объекта назначения)
  • ВызовСерверногоМетода (вызов из формы документа и списка)
  • ЗаполнениеФормы (вызов из формы документа, в форме списка согласно "правилам БСП" команда отсутствует)

Клиентские команды будут заполнять табличную часть Товары из файла, серверные — записывать текущую дату в реквизит Комментарий.

Функция СведенияОВнешнейОбработке() Экспорт
	
	ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке(СтандартныеПодсистемыСервер.ВерсияБиблиотеки());
	
	МассивНазначений = Новый Массив;
	МассивНазначений.Добавить("Документ.ЗаказКлиента");
	
	ПараметрыРегистрации.Вставить("Вид", "ЗаполнениеОбъекта");
	
	ПараметрыРегистрации.Вставить("Назначение",		МассивНазначений);
	ПараметрыРегистрации.Вставить("Наименование",	"Пример внешней обработки Заполнение объекта");
	ПараметрыРегистрации.Вставить("Информация",		"Пример внешней обработки Заполнение объекта");
	ПараметрыРегистрации.Вставить("Версия",			"1.0");
	ПараметрыРегистрации.Вставить("БезопасныйРежим", Истина);
	
	Разрешение = РаботаВБезопасномРежиме.РазрешениеНаИспользованиеКаталогаВременныхФайлов(Истина, Истина);
	ПараметрыРегистрации.Разрешения.Добавить(Разрешение);
	
	НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
	НоваяКоманда.Представление = НСтр("ru = 'ОткрытиеФормы'");
	НоваяКоманда.Идентификатор = "ОткрытиеФормы";
	НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыОткрытиеФормы();
	НоваяКоманда.ПоказыватьОповещение = Ложь;
	
	НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
	НоваяКоманда.Представление = НСтр("ru = 'ВызовКлиентскогоМетода'");
	НоваяКоманда.Идентификатор = "ВызовКлиентскогоМетода";
	НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовКлиентскогоМетода();
	НоваяКоманда.ПоказыватьОповещение = Ложь;
	
	НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
	НоваяКоманда.Представление = НСтр("ru = 'ВызовСерверногоМетода'");
	НоваяКоманда.Идентификатор = "ВызовСерверногоМетода";
	НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовСерверногоМетода();
	НоваяКоманда.ПоказыватьОповещение = Ложь;
	
	НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
	НоваяКоманда.Представление = НСтр("ru = 'ЗаполнениеФормы'");
	НоваяКоманда.Идентификатор = "ЗаполнениеФормы";
	НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыЗаполнениеФормы();
	НоваяКоманда.ПоказыватьОповещение = Ложь;
	
	Возврат ПараметрыРегистрации;
	
КонецФункции

 

Добавим табличную часть Товары. Создадим форму.

 

 

При открытии / получении формы доп. обработки в форму передаются параметры. Создавать их в самой форме не обязательно, но полезно. Если объявить их ключевыми, они будут доступными и после создания формы.

1. Первый вариант отладки реализуем с помощью имитации выполнения команд во внешней обработке

В форме внешней обработки ключевые параметры формы доступны не будут, поэтому создадим реквизит формы ДополнительнаяОбработкаСсылка, который заполним при создании на сервере. Также добавим список идентификаторов команд.

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	Если Параметры.ИдентификаторКоманды = "ОткрытиеФормы" И Найти(Параметры.ИмяФормы, "ФормаСписка") > 0 Тогда
		ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Команда предназначена для формы документа");
		Отказ = Истина;
		Возврат;
	КонецЕсли;
	
	Элементы.ФормаИдентификаторКоманды.РежимВыбораИзСписка = Истина;
	Элементы.ФормаИдентификаторКоманды.СписокВыбора.Добавить("ОткрытиеФормы");
	Элементы.ФормаИдентификаторКоманды.СписокВыбора.Добавить("ВызовКлиентскогоМетода");
	Элементы.ФормаИдентификаторКоманды.СписокВыбора.Добавить("ВызовСерверногоМетода_ФормаОбъекта", "ВызовСерверногоМетода (форма объекта)");
	Элементы.ФормаИдентификаторКоманды.СписокВыбора.Добавить("ВызовСерверногоМетода_ФормаСписка", "ВызовСерверногоМетода (форма списка)");
	Элементы.ФормаИдентификаторКоманды.СписокВыбора.Добавить("ЗаполнениеФормы");
	ЭтотОбъект.ФормаИдентификаторКоманды = "ВызовКлиентскогоМетода";
	
	ЭтотОбъект.ДополнительнаяОбработкаСсылка = Справочники.ДополнительныеОтчетыИОбработки.НайтиПоРеквизиту("ИмяОбъекта", "ПримерВнешнейОбработки_ЗаполнениеОбъекта");
	
КонецПроцедуры

 

Логика отладки такова, что необходимо выбрать идентификатор команды, объект назначения и выполнить команду ВыполнитьОбработку.

Обратим внимание, что при выборе команды ОткрытиеФормы на самом деле команда ВыполнитьОбработку блокируется (форма и так открыта), и становится доступной команда Перенести, а ВызовСерверногоМетода дублируется для формы объекта и формы списка.

1.1 Открытие формы

1.1.1 Доп. обработка

Команда доп. обработки открывает форму обработки, подчинённую форме документа. Пользователь нажимает кнопку ПрочитатьФайл, выбирает файл, заполняется табличная часть Товары, пользователь нажимает кнопку Перенести, товары переносятся в документ, заполняются необходимые реквизиты объекта и формы документа, форма обработки закрывается.

Контекст открытия формы доп. обработки из формы документа:

 

 

1.1.2 Внешняя обработка

Пользователь указывает объект назначения — существующий документ ЗаказКлиента. Пользователь нажимает кнопку ПрочитатьФайл, выбирает файл, заполняется табличная часть Товары, пользователь нажимает кнопку Перенести — открывается форма документа-объекта назначения, заполняются необходимые реквизиты объекта и формы документа, форма обработки не закрывается.

В модуле команды Перенести напишем:

&НаКлиенте
Процедура Перенести(Команда)
	
	Если Не ЗначениеЗаполнено(Параметры.ИдентификаторКоманды) Тогда
		ЕстьДокумент = (ЭтотОбъект.ФормаОбъектыНазначения.Количество() > 0 И ЗначениеЗаполнено(ЭтотОбъект.ФормаОбъектыНазначения[0].ОбъектНазначения));
		Если Не ЕстьДокумент Тогда
			ПоказатьПредупреждение(, "Не указан объект назначения");
			Возврат;
		КонецЕсли;
	КонецЕсли;
	
	Если ЭтотОбъект.ВладелецФормы <> Неопределено Тогда
		Форма = ЭтотОбъект.ВладелецФормы;
	Иначе
		Форма = ПолучитьФорму("Документ.ЗаказКлиента.Форма.ФормаДокумента", Новый Структура("Ключ", ЭтотОбъект.ФормаОбъектыНазначения[0].ОбъектНазначения));
		Форма.Открыть();
	КонецЕсли;
	
	ПеренестиТовары(Форма);
	
КонецПроцедуры

 

 

Содержимое файла:

 

1.2 Вызов клиентского метода

1.2.1 Доп. обработка

Команда доп. обработки создаёт форму обработки (открытия формы не происходит), подчинённую форме документа. Открывается диалог выбора файла, пользователь выбирает файл, товары переносятся в документ, заполняются необходимые реквизиты объекта и формы документа. 

Контекст вызова клиентского метода из формы документа:


 

Код обработки клиентского метода:

&НаКлиенте
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения) Экспорт
	
	Форма = ЭтотОбъект.ВладелецФормы;
	
	Если ИдентификаторКоманды = "ВызовКлиентскогоМетода" Тогда
		Если Найти(Форма.ИмяФормы, "ФормаСписка") > 0 Тогда
			Форма = ПолучитьФорму("Документ.ЗаказКлиента.Форма.ФормаДокумента", Новый Структура("Ключ", ОбъектыНазначения[0]));
			Форма.Открыть();
		КонецЕсли;
		Выполнить_ВызовКлиентскогоМетода(ИдентификаторКоманды, ОбъектыНазначения, Форма);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура Выполнить_ВызовКлиентскогоМетода(ИдентификаторКоманды, ОбъектыНазначения, Форма)
	
	Обработка_ВызовКлиентскогоМетода(ИдентификаторКоманды, ОбъектыНазначения, Форма);
	
КонецПроцедуры

&НаКлиенте
Процедура Обработка_ВызовКлиентскогоМетода(ИдентификаторКоманды, ОбъектыНазначения, Форма)
	
	ПрочитатьФайлНаКлиенте(Форма);
	
КонецПроцедуры

&НаКлиенте
Процедура ПрочитатьФайлНаКлиенте(Форма = Неопределено)
	
	Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
	Диалог.Фильтр = "Файлы Excel|*.xlsx;*.xls";
	Диалог.ПроверятьСуществованиеФайла = Истина;
	Диалог.МножественныйВыбор = Ложь;
	Оповещение = Новый ОписаниеОповещения("ПрочитатьФайлНаКлиенте_Завершение", ЭтотОбъект, Новый Структура("Форма", Форма));
	Диалог.Показать(Оповещение);
	
КонецПроцедуры

&НаКлиенте
Процедура ПрочитатьФайлНаКлиенте_Завершение(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт

	Если Не (ТипЗнч(ВыбранныеФайлы) = Тип("Массив") И ВыбранныеФайлы.Количество() > 0) Тогда
		Возврат;
	КонецЕсли;
	
	ПутьКФайлу = ВыбранныеФайлы[0];
	Файл = Новый Файл(ПутьКФайлу);
	ДвоичныеДанные = Новый ДвоичныеДанные(ПутьКФайлу);
	АдресВХ = ПоместитьВоВременноеХранилище(ДвоичныеДанные);
	ПрочитатьФайлНаСервере(АдресВХ, Файл.Расширение);
	
	Если Параметры.ИдентификаторКоманды = "ВызовКлиентскогоМетода" Или (Параметры.ИдентификаторКоманды = "" И ЭтотОбъект.ФормаИдентификаторКоманды = "ВызовКлиентскогоМетода") Тогда
		ПеренестиТовары(ДополнительныеПараметры.Форма);
	КонецЕсли;
	
КонецПроцедуры

 

1.2.2 Внешняя обработка

Пользователь указывает объект назначения — существующий документ ЗаказКлиента, нажимает кнопку ВыполнитьКоманду. Открывается форма документа. Открывается диалог выбора файла. Пользователь выбирает файл, товары переносятся в документ, заполняются необходимые реквизиты объекта и формы документа.

 

 

Код внешней обработки:

&НаКлиенте
Процедура ВыполнитьОбработку(Команда)
	
	ОчиститьСообщения();
	
	ЕстьДокумент = (ЭтотОбъект.ФормаОбъектыНазначения.Количество() > 0 И ЗначениеЗаполнено(ЭтотОбъект.ФормаОбъектыНазначения[0].ОбъектНазначения));
	Если ЭтотОбъект.ФормаИдентификаторКоманды <> "ЗаполнениеФормы" И Не ЕстьДокумент Тогда
		ПоказатьПредупреждение(, "Не указан объект назначения");
		Возврат;
	КонецЕсли;
	
	ОбъектыНазначения = Новый Массив();
	Для Каждого ДФЭК Из ЭтотОбъект.ФормаОбъектыНазначения Цикл
		ОбъектыНазначения.Добавить(ДФЭК.ОбъектНазначения);
	КонецЦикла;
	
	Форма = Неопределено;
	Если ЭтотОбъект.ФормаИдентификаторКоманды <> "ВызовСерверногоМетода_ФормаСписка" Тогда
		Если ЕстьДокумент Тогда
			Форма = ПолучитьФорму("Документ.ЗаказКлиента.Форма.ФормаДокумента", Новый Структура("Ключ", ЭтотОбъект.ФормаОбъектыНазначения[0].ОбъектНазначения));		
		Иначе     
			// Для типа команды ЗаполнениеФормы ссылка может быть пустая
			Форма = ПолучитьФорму("Документ.ЗаказКлиента.Форма.ФормаДокумента");
		КонецЕсли;
		Форма.Открыть();
	КонецЕсли;
	
	Если ЭтотОбъект.ФормаИдентификаторКоманды = "ВызовКлиентскогоМетода" Тогда
		Выполнить_ВызовКлиентскогоМетода(ЭтотОбъект.ФормаИдентификаторКоманды, ОбъектыНазначения, Форма);
	ИначеЕсли Найти(ЭтотОбъект.ФормаИдентификаторКоманды, "ВызовСерверногоМетода") > 0 Тогда
		Выполнить_ВызовСерверногоМетода(ЭтотОбъект.ФормаИдентификаторКоманды, ОбъектыНазначения, Форма);		
	ИначеЕсли ЭтотОбъект.ФормаИдентификаторКоманды = "ЗаполнениеФормы" Тогда
		// Параметр ОбъектыНазначения использован не будет
		Выполнить_ЗаполнениеФормы(ЭтотОбъект.ФормаИдентификаторКоманды, ОбъектыНазначения, Форма);
	КонецЕсли;
	
КонецПроцедуры

 

1.3 Вызов серверного метода

1.3.1 Доп. обработка

Команда доп. обработки получает объекты назначения и записывает текущую дату в комментарий.

Контекст вызова серверного метода из формы документа:

 

 

Контекст вызова серверного метода из формы списка:

 

 

Если команда вызвана из формы документа, то после её завершения будет вызван метод формы Прочитать.

 

 

Код обработки серверного метода:

Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения, ПараметрыКоманды) Экспорт

	Если ИдентификаторКоманды = "ВызовСерверногоМетода" Тогда
		Обработка_ВызовСерверногоМетода(ИдентификаторКоманды, ОбъектыНазначения, ПараметрыКоманды);
	ИначеЕсли ИдентификаторКоманды = "ЗаполнениеФормы" Тогда
		Обработка_ЗаполнениеФормы(ИдентификаторКоманды, ОбъектыНазначения, ПараметрыКоманды);
	КонецЕсли;
	
КонецПроцедуры

Процедура Обработка_ВызовСерверногоМетода(ИдентификаторКоманды, ОбъектыНазначения, ПараметрыКоманды) Экспорт
	
	Для Каждого ОбъектНазначения Из ОбъектыНазначения Цикл 
		Обт = ОбъектНазначения.ПолучитьОбъект();
		Обт.Комментарий = ТекущаяДата();
		Обт.Записать();
	КонецЦикла;
	
КонецПроцедуры

 

1.3.2 Внешняя обработка

Пользователь указывает объект назначения — существующий документ ЗаказКлиента. На выбор доступны 2 команды: вызов серверного метода из формы объекта и из формы списка. Нажимает кнопку ВыполнитьКоманду. Если используется команда из формы объекта, то будет открыта форма документа. Исполняется команда обработки. Если используется команда из формы объекта, то будет вызван метод формы Прочитать.

 

 

Код внешней обработки:

&НаКлиенте
Процедура ВыполнитьОбработку(Команда)
	
	ОчиститьСообщения();
	
	ЕстьДокумент = (ЭтотОбъект.ФормаОбъектыНазначения.Количество() > 0 И ЗначениеЗаполнено(ЭтотОбъект.ФормаОбъектыНазначения[0].ОбъектНазначения));
	Если ЭтотОбъект.ФормаИдентификаторКоманды <> "ЗаполнениеФормы" И Не ЕстьДокумент Тогда
		ПоказатьПредупреждение(, "Не указан объект назначения");
		Возврат;
	КонецЕсли;
	
	ОбъектыНазначения = Новый Массив();
	Для Каждого ДФЭК Из ЭтотОбъект.ФормаОбъектыНазначения Цикл
		ОбъектыНазначения.Добавить(ДФЭК.ОбъектНазначения);
	КонецЦикла;
	
	Форма = Неопределено;
	Если ЭтотОбъект.ФормаИдентификаторКоманды <> "ВызовСерверногоМетода_ФормаСписка" Тогда
		Если ЕстьДокумент Тогда
			Форма = ПолучитьФорму("Документ.ЗаказКлиента.Форма.ФормаДокумента", Новый Структура("Ключ", ЭтотОбъект.ФормаОбъектыНазначения[0].ОбъектНазначения));		
		Иначе     
			// Для типа команды ЗаполнениеФормы ссылка может быть пустая
			Форма = ПолучитьФорму("Документ.ЗаказКлиента.Форма.ФормаДокумента");
		КонецЕсли;
		Форма.Открыть();
	КонецЕсли;
	
	Если ЭтотОбъект.ФормаИдентификаторКоманды = "ВызовКлиентскогоМетода" Тогда
		Выполнить_ВызовКлиентскогоМетода(ЭтотОбъект.ФормаИдентификаторКоманды, ОбъектыНазначения, Форма);
	ИначеЕсли Найти(ЭтотОбъект.ФормаИдентификаторКоманды, "ВызовСерверногоМетода") > 0 Тогда
		Выполнить_ВызовСерверногоМетода(ЭтотОбъект.ФормаИдентификаторКоманды, ОбъектыНазначения, Форма);		
	ИначеЕсли ЭтотОбъект.ФормаИдентификаторКоманды = "ЗаполнениеФормы" Тогда
		// Параметр ОбъектыНазначения использован не будет
		Выполнить_ЗаполнениеФормы(ЭтотОбъект.ФормаИдентификаторКоманды, ОбъектыНазначения, Форма);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура Выполнить_ВызовСерверногоМетода(ИдентификаторКоманды, ОбъектыНазначения, Форма)
	
	Выполнить_ВызовСерверногоМетодаНаСервере(ИдентификаторКоманды, ОбъектыНазначения);
	
	ОповеститьОбИзменении(Тип("ДокументСсылка.ЗаказКлиента"));
	
	Если ИдентификаторКоманды = "ВызовСерверногоМетода_ФормаОбъекта" Тогда
		// В случае доп. обработки после вызова серверного метода вызывается ДополнительныеОтчетыИОбработкиКлиент.ОбновитьДанныеВФорме
		Форма.Прочитать();
	Иначе                                                                     
		ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Команда выполнена");
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Процедура Выполнить_ВызовСерверногоМетодаНаСервере(ИдентификаторКоманды, ОбъектыНазначения)

	ОбъектОбработки = РеквизитФормыВЗначение("Объект");
	
	ПараметрыКоманды = Новый Структура();
	ПараметрыКоманды.Вставить("ДополнительнаяОбработкаСсылка", ЭтотОбъект.ДополнительнаяОбработкаСсылка);
	ПараметрыКоманды.Вставить("ИдентификаторКоманды", ИдентификаторКоманды);
	Если ИдентификаторКоманды = "ВызовСерверногоМетода_ФормаОбъекта" Тогда
		ПараметрыКоманды.Вставить("ИмяФормы", "Документ.ЗаказКлиента.Форма.ФормаДокумента");
	КонецЕсли;
	ПараметрыКоманды.Вставить("ОбъектыНазначения", ОбъектыНазначения);
	ПараметрыКоманды.Вставить("РезультатВыполнения", Новый Структура());
	
	ОбъектОбработки.Обработка_ВызовСерверногоМетода(ИдентификаторКоманды, ОбъектыНазначения, ПараметрыКоманды);
	
КонецПроцедуры

 

1.4 Заполнение формы

1.4.1 Доп. обработка

Пользователь, находясь в форме документа, выполняет команду. Документ, в отличие от других команд, может быть не записан в инфобазу. Форма может быть модифицирована. Записывать объект не требуется.
Обратим внимание, что параметр ОбъектыНазначения = Неопределено, а в параметрах команды появляется ключ ЭтаФорма.

Контекст команды заполнения формы из формы объекта:

 

 

Код обработки заполнения формы:

Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения, ПараметрыКоманды) Экспорт

	Если ИдентификаторКоманды = "ВызовСерверногоМетода" Тогда
		Обработка_ВызовСерверногоМетода(ИдентификаторКоманды, ОбъектыНазначения, ПараметрыКоманды);
	ИначеЕсли ИдентификаторКоманды = "ЗаполнениеФормы" Тогда
		Обработка_ЗаполнениеФормы(ИдентификаторКоманды, ОбъектыНазначения, ПараметрыКоманды);
	КонецЕсли;
	
КонецПроцедуры

Процедура Обработка_ЗаполнениеФормы(ИдентификаторКоманды, ОбъектыНазначения, ПараметрыКоманды) Экспорт
	
	Если ПараметрыКоманды.Свойство("ЭтаФорма") Тогда
		// Доп. обработка
		Форма = ПараметрыКоманды.ЭтаФорма;
		ОбъектФормы = Форма.Объект;
	ИначеЕсли ПараметрыКоманды.Свойство("ОбъектФормы") Тогда
		// Внеш. обработка. Не можем передать форму на сервер, используем только объект формы.
		Форма = Неопределено;
		ОбъектФормы = ПараметрыКоманды.ОбъектФормы;
	Иначе
		Возврат;
	КонецЕсли;
	
	ОбъектФормы.Комментарий = ТекущаяДата();
	
	Если Форма <> Неопределено Тогда
		Форма.Модифицированность = Истина;
	КонецЕсли;
	
КонецПроцедуры

 

1.4.2 Внешняя обработка

Табличная часть ОбъектыНазначения может быть пустой, так как команда заполнения формы может быть вызвана для формы с пустой ссылкой. Пользователь нажимает кнопку ВыполнитьКоманду. Открывается форма существующего или нового документа. Исполняется команда заполнения формы. Вызывается метод формы Прочитать.

В данном случае форму документа на сервер мы передать не можем, поэтому передаём только объект формы.

Код внешней обработки:

&НаКлиенте
Процедура ВыполнитьОбработку(Команда)
	
	ОчиститьСообщения();
	
	ЕстьДокумент = (ЭтотОбъект.ФормаОбъектыНазначения.Количество() > 0 И ЗначениеЗаполнено(ЭтотОбъект.ФормаОбъектыНазначения[0].ОбъектНазначения));
	Если ЭтотОбъект.ФормаИдентификаторКоманды <> "ЗаполнениеФормы" И Не ЕстьДокумент Тогда
		ПоказатьПредупреждение(, "Не указан объект назначения");
		Возврат;
	КонецЕсли;
	
	ОбъектыНазначения = Новый Массив();
	Для Каждого ДФЭК Из ЭтотОбъект.ФормаОбъектыНазначения Цикл
		ОбъектыНазначения.Добавить(ДФЭК.ОбъектНазначения);
	КонецЦикла;
	
	Форма = Неопределено;
	Если ЭтотОбъект.ФормаИдентификаторКоманды <> "ВызовСерверногоМетода_ФормаСписка" Тогда
		Если ЕстьДокумент Тогда
			Форма = ПолучитьФорму("Документ.ЗаказКлиента.Форма.ФормаДокумента", Новый Структура("Ключ", ЭтотОбъект.ФормаОбъектыНазначения[0].ОбъектНазначения));		
		Иначе     
			// Для типа команды ЗаполнениеФормы ссылка может быть пустая
			Форма = ПолучитьФорму("Документ.ЗаказКлиента.Форма.ФормаДокумента");
		КонецЕсли;
		Форма.Открыть();
	КонецЕсли;
	
	Если ЭтотОбъект.ФормаИдентификаторКоманды = "ВызовКлиентскогоМетода" Тогда
		Выполнить_ВызовКлиентскогоМетода(ЭтотОбъект.ФормаИдентификаторКоманды, ОбъектыНазначения, Форма);
	ИначеЕсли Найти(ЭтотОбъект.ФормаИдентификаторКоманды, "ВызовСерверногоМетода") > 0 Тогда
		Выполнить_ВызовСерверногоМетода(ЭтотОбъект.ФормаИдентификаторКоманды, ОбъектыНазначения, Форма);		
	ИначеЕсли ЭтотОбъект.ФормаИдентификаторКоманды = "ЗаполнениеФормы" Тогда
		// Параметр ОбъектыНазначения использован не будет
		Выполнить_ЗаполнениеФормы(ЭтотОбъект.ФормаИдентификаторКоманды, ОбъектыНазначения, Форма);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура Выполнить_ЗаполнениеФормы(ИдентификаторКоманды, ОбъектыНазначения, Форма)
	
	ОбъектФормы = Форма.Объект;
	
	// Форму на сервер передать не можем. Используем только объект формы
	// Если нужна модификация формы, придётся писать код на клиенте после вызова серверной процедуры
	Выполнить_ЗаполнениеФормыНаСервере(ИдентификаторКоманды, ОбъектыНазначения, ОбъектФормы);
	
	// Так как объект формы модифицируется на сервере
	КопироватьДанныеФормы(ОбъектФормы, Форма.Объект);
	
	Форма.Модифицированность = Истина;
	
КонецПроцедуры

&НаСервере
Процедура Выполнить_ЗаполнениеФормыНаСервере(ИдентификаторКоманды, ОбъектыНазначения, ОбъектФормы)
	
	ОбъектОбработки = РеквизитФормыВЗначение("Объект");
	
	ПараметрыКоманды = Новый Структура();
	ПараметрыКоманды.Вставить("ДополнительнаяОбработкаСсылка", ЭтотОбъект.ДополнительнаяОбработкаСсылка);
	ПараметрыКоманды.Вставить("РезультатВыполнения", Новый Структура());
	// Форму на сервер передать не можем. Используем только объект формы.
	ПараметрыКоманды.Вставить("ОбъектФормы", ОбъектФормы);
	
	ОбъектОбработки.Обработка_ЗаполнениеФормы(ИдентификаторКоманды, ОбъектыНазначения, ПараметрыКоманды);
	
КонецПроцедуры

 

2. Второй вариант отладки реализуем с помощью подключения из доп. обработки внешней обработки из файла.

Примечание: существует небезызвестное расширение для отладки доп. обработок, но в данном случае мы будем использовать только возможности внешней обработки.

При вызове команды доп. обработки будет происходить подключение внешней обработки из файла, куда оный вызов и будет передан.

Важный момент: после загрузки обработки в справочник следует изменить имя внешней обработки (произвольно), чтобы не возникло проблем с отладкой. Разумеется, при повторной загрузке обработки в справочник, необходимо вернуть оригинальное имя.

 

 

Добавим ключевой параметр формы РежимОтладкиОбработки. В модуле внешней обработки напишем:

Функция ИспользуетсяОтладка() Экспорт
	
	Возврат Истина;
	
КонецФункции

Функция ПодключитьВнешнююОбработку(ПолучитьОбработку) Экспорт
	
	ПутьКФайлу = "/mnt/shared/ПримерВнешнейОбработки_ЗаполнениеОбъекта.epf";
	
	Если Не ЗначениеЗаполнено(ПутьКФайлу) Тогда
		Возврат Неопределено;
	КонецЕсли; 
	
	Файл = Новый Файл(ПутьКФайлу);
	Если Не Файл.Существует() Тогда
		Возврат Неопределено;
	КонецЕсли;
	
	ВнешнийОбъект = ВнешниеОбработки.Создать(ПутьКФайлу, Ложь, ОбщегоНазначения.ОписаниеЗащитыБезПредупреждений());
	
	ИмяОбработки = ВнешнийОбъект.Метаданные().Имя;
	
	Возврат ?(ПолучитьОбработку, ВнешнийОбъект, ИмяОбработки);
	
КонецФункции

 

Функция ИспользуетсяОтладка отвечает за то, будет ли использоваться отладка через подключение файла внешней обработки. При изменении возвращаемого значения следует перезагрузить обработку в справочник доп. обработок.

Добавим реквизит формы ИспользуетсяОтладка. В процедуре ПриСозданииНаСервере напишем:

	ОбъектОбработки = РеквизитФормыВЗначение("Объект");
	ЭтотОбъект.ИспользуетсяОтладка = ОбъектОбработки.ИспользуетсяОтладка();

 

Теперь нужно организовать передачу вызова для открытия формы, для процедуры ВыполнитьКоманду на клиенте и для процедуры ВыполнитьКоманду модуля объекта.

2.1 Открытие формы

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	
	Если ИспользуетсяОтладка_ПриОткрытии() Тогда
		Возврат;
	КонецЕсли;
	
	//...
	
КонецПроцедуры

&НаКлиенте
Функция ИспользуетсяОтладка_ПриОткрытии()
	
	Если ЭтотОбъект.ИспользуетсяОтладка И Не Параметры.РежимОтладкиОбработки Тогда
		
		ИмяОбработки = ПодключитьВнешнююОбработку();

		Если ИмяОбработки = Неопределено Тогда
			Возврат Ложь;
		КонецЕсли;
		
		ПараметрыФормы = Новый Структура();
		ПараметрыФормы.Вставить("ДополнительнаяОбработкаСсылка", Параметры.ДополнительнаяОбработкаСсылка);
		ПараметрыФормы.Вставить("ИдентификаторКоманды", Параметры.ИдентификаторКоманды);
		ПараметрыФормы.Вставить("ИмяФормы", Параметры.ИмяФормы);
		ПараметрыФормы.Вставить("ОбъектыНазначения", Параметры.ОбъектыНазначения);
		ПараметрыФормы.Вставить("РежимОтладкиОбработки", Истина);
		
		ОткрытьФорму("ВнешняяОбработка." + ИмяОбработки + ".Форма", ПараметрыФормы, ЭтотОбъект.ВладелецФормы);
		
		ЭтотОбъект.Закрыть();
		
		Возврат Истина;
		
	КонецЕсли;
	
    Возврат Ложь;
	
КонецФункции

 

Контекст отладки при открытии формы:

 

 

2.2 Выполнение команды на клиенте

&НаКлиенте
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения) Экспорт
	
	Если ИспользуетсяОтладка_ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения) Тогда
		Возврат;
	КонецЕсли;
	
	// ...
	
КонецПроцедуры

&НаКлиенте
Функция ИспользуетсяОтладка_ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения)
	
	Если ЭтотОбъект.ИспользуетсяОтладка И Не Параметры.РежимОтладкиОбработки Тогда
		
		ИмяОбработки = ПодключитьВнешнююОбработку();

		Если ИмяОбработки = Неопределено Тогда
			Возврат Ложь;
		КонецЕсли;
		
		ПараметрыФормы = Новый Структура();
		ПараметрыФормы.Вставить("ДополнительнаяОбработкаСсылка", Параметры.ДополнительнаяОбработкаСсылка);
		ПараметрыФормы.Вставить("ИдентификаторКоманды", ИдентификаторКоманды);
		ПараметрыФормы.Вставить("ИмяФормы", Параметры.ИмяФормы);
		ПараметрыФормы.Вставить("ОбъектыНазначения", ОбъектыНазначения);
		ПараметрыФормы.Вставить("РежимОтладкиОбработки", Истина);

		ФормаВнешнегоОбъекта = ПолучитьФорму("ВнешняяОбработка." + ИмяОбработки + ".Форма", ПараметрыФормы, ЭтотОбъект.ВладелецФормы);		
		ФормаВнешнегоОбъекта.ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения);
		
		Возврат Истина;
		
	КонецЕсли;
	
    Возврат Ложь;
	
КонецФункции

&НаСервере
Функция ПодключитьВнешнююОбработку()
	
	ОбъектОбработки = РеквизитФормыВЗначение("Объект");
	
	Возврат ОбъектОбработки.ПодключитьВнешнююОбработку(Ложь);
	
КонецФункции

 

Контекст отладки при вызове клиентского метода:

 

 

2.3 Выполнение команды на сервере

Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения, ПараметрыКоманды) Экспорт
	
	Если ИспользуетсяОтладка_ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения, ПараметрыКоманды) Тогда
		Возврат;
	КонецЕсли;

	Если ИдентификаторКоманды = "ВызовСерверногоМетода" Тогда
		Обработка_ВызовСерверногоМетода(ИдентификаторКоманды, ОбъектыНазначения, ПараметрыКоманды);
	ИначеЕсли ИдентификаторКоманды = "ЗаполнениеФормы" Тогда
		Обработка_ЗаполнениеФормы(ИдентификаторКоманды, ОбъектыНазначения, ПараметрыКоманды);
	КонецЕсли;
	
КонецПроцедуры

Функция ИспользуетсяОтладка_ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения, ПараметрыКоманды)
	
	Если ИспользуетсяОтладка() И Не ПараметрыКоманды.Свойство("РежимОтладкиОбработки") Тогда
		
		ВнешнийОбъект = ПодключитьВнешнююОбработку(Истина);

		Если ВнешнийОбъект = Неопределено Тогда
			Возврат Ложь;
		КонецЕсли;

		ПараметрыКоманды.Вставить("РежимОтладкиОбработки", Истина);
		ВнешнийОбъект.ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения, ПараметрыКоманды);
		
		Возврат Истина;
		
	КонецЕсли;
	
    Возврат Ложь;
	
КонецФункции

 

Контекст отладки при вызове серверного метода:

 

 

II. Печатная форма

Сведения о внешней обработке:

Функция СведенияОВнешнейОбработке() Экспорт
	
	ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке(СтандартныеПодсистемыСервер.ВерсияБиблиотеки());
	
	ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиПечатнаяФорма();
	
	МассивНазначений = Новый Массив();
	МассивНазначений.Добавить("Документ.ЗаказКлиента");
	ПараметрыРегистрации.Вставить("Назначение", МассивНазначений);	
	ПараметрыРегистрации.Наименование 	= "впф Счет на оплату";
	ПараметрыРегистрации.Информация 	= "впф Счет на оплату";
	ПараметрыРегистрации.Вставить("БезопасныйРежим", Истина);
	
	Разрешение = РаботаВБезопасномРежиме.РазрешениеНаИспользованиеКаталогаВременныхФайлов(Истина, Истина);
	ПараметрыРегистрации.Разрешения.Добавить(Разрешение);
	
	НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
	НоваяКоманда.Представление = НСтр("ru = 'впф Счет на оплату'");
	НоваяКоманда.Идентификатор = "впфСчетНаОплату";
	НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовСерверногоМетода();
	НоваяКоманда.ПоказыватьОповещение = Ложь;
	
	Возврат ПараметрыРегистрации;
	
КонецФункции

 

Создадим форму:

 

 

Код модуля формы:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	Элементы.ФормаИдентификаторКоманды.РежимВыбораИзСписка = Истина;             
	Элементы.ФормаИдентификаторКоманды.СписокВыбора.Добавить("впфСчетНаОплату");
	ЭтотОбъект.ФормаИдентификаторКоманды = "впфСчетНаОплату";
	
КонецПроцедуры

&НаКлиенте
Процедура ВыполнитьОбработку(Команда)
	
	ПараметрыОткрытия = Новый Структура("КоллекцияПечатныхФорм,ОбъектыПечати,ДополнительныеПараметры",,, Новый Структура());
	ВыполнитьОбработкуНаСервере(ЭтотОбъект.ФормаИдентификаторКоманды, ПараметрыОткрытия);
	УправлениеПечатьюКлиент.ПечатьДокументов(ПараметрыОткрытия.КоллекцияПечатныхФорм, ПараметрыОткрытия.ОбъектыПечати, ПараметрыОткрытия.ДополнительныеПараметры);
	
КонецПроцедуры

&НаСервере
Процедура ВыполнитьОбработкуНаСервере(ИдентификаторКоманды, ПараметрыОткрытия)
	
	МассивОбъектов = Новый Массив();
	Для Каждого ДФЭК Из ЭтотОбъект.ФормаОбъектыНазначения Цикл
		МассивОбъектов.Добавить(ДФЭК.ОбъектНазначения);
	КонецЦикла;
	
	КоллекцияПечатныхФорм = УправлениеПечатью.ПодготовитьКоллекциюПечатныхФорм(ИдентификаторКоманды);
	ОбъектыПечати = Новый СписокЗначений();
	ПараметрыВывода = УправлениеПечатью.ПодготовитьСтруктуруПараметровВывода();
	ПараметрыВывода.Вставить("ДополнительнаяОбработкаСсылка", ЭтотОбъект.ДополнительнаяОбработкаСсылка);
	
	РеквизитФормыВЗначение("Объект").Печать(
		МассивОбъектов,
		КоллекцияПечатныхФорм,
		ОбъектыПечати,
		ПараметрыВывода);
		
	ПараметрыОткрытия.КоллекцияПечатныхФорм = ОбщегоНазначения.ТаблицаЗначенийВМассив(КоллекцияПечатныхФорм);
	ПараметрыОткрытия.ОбъектыПечати = ОбъектыПечати;
		
КонецПроцедуры

 

Код модуля объекта:

Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
	
	Если ИспользуетсяОтладка_ВыполнитьКоманду(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Тогда
		Возврат;
	КонецЕсли;
	
	ПараметрыПечати = Новый Структура("ДополнитьКомплектВнешнимиПечатнымиФормами", Ложь);
	
	Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "впфСчетНаОплату") Тогда
		СтруктураТипов = ОбщегоНазначенияУТ.СоответствиеМассивовПоТипамОбъектов(МассивОбъектов);
		УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
			КоллекцияПечатныхФорм,
			"впфСчетНаОплату",
			"впф Счет на оплату",
			СформироватьПечатнуюФормуСчетНаОплату(СтруктураТипов, ОбъектыПечати, ПараметрыПечати));
	КонецЕсли;
		
	ФормированиеПечатныхФорм.ЗаполнитьПараметрыОтправки(ПараметрыВывода.ПараметрыОтправки, МассивОбъектов, КоллекцияПечатныхФорм);
	
КонецПроцедуры

// ...

#Область Отладка

Функция ИспользуетсяОтладка_ВыполнитьКоманду(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода)
	
	Если ИспользуетсяОтладка() И Не ПараметрыВывода.Свойство("РежимОтладкиОбработки") Тогда
		
		ВнешнийОбъект = ПодключитьВнешнююОбработку(Истина);

		Если ВнешнийОбъект = Неопределено Тогда
			Возврат Ложь;
		КонецЕсли;

		ПараметрыВывода.Вставить("РежимОтладкиОбработки", Истина);
		ВнешнийОбъект.Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода);
		
		Возврат Истина;
		
	КонецЕсли;
	
    Возврат Ложь;
	
КонецФункции

Функция ИспользуетсяОтладка() Экспорт
	
	Возврат Истина;
	
КонецФункции

Функция ПодключитьВнешнююОбработку(ПолучитьОбработку) Экспорт
	
	ПутьКФайлу = "/mnt/shared/ПримерВнешнейОбработки_ПечатнаяФорма.epf";
	
	Если Не ЗначениеЗаполнено(ПутьКФайлу) Тогда
		Возврат Неопределено;
	КонецЕсли; 
	
	Файл = Новый Файл(ПутьКФайлу);
	Если Не Файл.Существует() Тогда
		Возврат Неопределено;
	КонецЕсли; 
	
	ВнешнийОбъект = ВнешниеОбработки.Создать(ПутьКФайлу, Ложь, ОбщегоНазначения.ОписаниеЗащитыБезПредупреждений());
	
	ИмяОбработки = ВнешнийОбъект.Метаданные().Имя;
	
	Возврат ?(ПолучитьОбработку, ВнешнийОбъект, ИмяОбработки);
	
КонецФункции

#КонецОбласти

 

Протестировано на платформе 8.3.27.2074, на конфигурациях 1С:ERP Управление предприятием 2 (2.5.22.176), Бухгалтерия предприятия 3.0 (3.0.196.1) (механизм подключения и отладки). БП — в клиент-серверном режиме на разных машинах: сервер 1с на linux на виртуальной машине с общей папкой.

P.S. При тестировании были случаи, когда слетала отладка (даже в событии ПриСозданииНаСервере при открытии внешней обработки). Приходилось перезапускать 1С.

Проверено на следующих конфигурациях и релизах:

  • 1С:ERP Управление предприятием 2, релизы 2.5.22.176

Вступайте в нашу телеграмм-группу Инфостарт

См. также

БСП (Библиотека стандартных подсистем) Программист Платные (руб)

Синтакс-помощник БСП - cправочник по библиотекам стандартных подсистем и электронных документов. В состав справочника входит описание экспортных процедур и функций, размещенных в областях кода ПрограммныйИнтерфейс БСП и БЭД.

3254 руб.

21.11.2024    13052    46    24    

52

БСП (Библиотека стандартных подсистем) Универсальные функции Программист 1С 8.3 1С:Библиотека стандартных подсистем Бесплатно (free)

Когда появляется необходимость сделать подключаемую внешнюю обработку, будь это печатная форма или отчет - нам всегда приходится прописывать сведения о внешней обработке для подключения их в соответствующий справочник. И это занимает некоторое время, что не очень удобно. Как для себя, так и для вас - я подготовил ряд примеров использования этой функции, можете выбрать один из них, чтобы в дальнейшем использовать их в шаблонах текста. Комментарии по дополнению и исправлению статьи - приветствуются.

06.02.2026    9787    manul1c    6    

24

Рефакторинг и качество кода БСП (Библиотека стандартных подсистем) Механизмы платформы 1С Программист 1С:Предприятие 8 1С:Библиотека стандартных подсистем Бесплатно (free)

Использование Библиотеки стандартных подсистем позволяет разработчикам 1С значительно ускорить процесс создания решений за счет готового универсального кода, поддерживаемого и обновляемого официальным вендором. В статье рассказывается про роль и применение «Библиотеки стандартных подсистем» (БСП), примеры интеграции и подключения подсистем.

23.09.2025    12873    AlexeyPROSTO_1C    1    

18

БСП (Библиотека стандартных подсистем) Программист 1С:Предприятие 8 1С:Библиотека стандартных подсистем Бесплатно (free)

Уже заезженная тема с выводом в Word макетов при помощи БСП, но некоторые коллеги все равно спрашивают. Поэтому размещаю тут материал, как это сделать за три простых шага. Решение, которым я успешно пользуюсь в случаях, когда не нужна универсальность подключаемых внешних печатных форм.

16.09.2025    6366    _seerco2002    0    

35

Нейросети БСП (Библиотека стандартных подсистем) Инструментарий разработчика Программист 1С:Предприятие 8 1С:Библиотека стандартных подсистем Бесплатно (free)

Telegram-бот для разработчиков 1С, работающих с БСП. Если не знаете нужный под задачу метод или не помните название, то опишите боту задачу и получите список подходящих экспортных методов из общих модулей БСП.

02.09.2025    7500    krasnov322    25    

44

Анализ учета БСП (Библиотека стандартных подсистем) 1С:Предприятие 8 1С:Библиотека стандартных подсистем Бесплатно (free)

Расширение для конфигураций на базе БСП 3.х. Позволяет создавать новые отчеты путем соединения или объединения других отчетов.

22.05.2025    5866    246    seperblunt    9    

31
Для отправки сообщения требуется регистрация/авторизация