Недавно попалось задание – организовать двухсторонний обмен данными с неким FTP сервером. В обмен должны попадать изменяемые с последней выгрузки документы. Обмен должен выполняться как вручную, так и автоматически по заданному расписанию. По возможности, требовалось обойтись без изменения типовой конфигурации.
После выполнения этого задания появилось следующее – а теперь организовать выгрузку данных, относящихся к другому складу на иной FTP-сервер.
Поделюсь некоторыми идеями в решении данной задачи.
Так как требовалось фиксировать изменения данных, попадающих в выгрузку, то использование планов обмена (конечно, в режиме «не РИБ») показалось очевидным. Благо, что, начиная с релиза 8.3.13, платформа позволяет создавать новые планы обмена в расширениях. Хочется отметить, что с планы обмена в расширениях вполне работоспособны и их использование в разработке практически ничем не отличается от планов обмена стандартной конфигурации. Наверное, единственным отличием является определение состава плана обмена. В состав планов обмена расширения могут включаться только объекты, созданные и заимствованные в текущем расширении.
Не будем подробно останавливаться на настройке состава и признаков авторегистрации изменений. В любом случае при начальной отладке я бы посоветовал не отключать авторегистрацию изменений для всех объектов, входящих в состав плана обмена (ПО).
Для ПО можно создавать реквизиты и табличные части. В реквизитах и табличных частях удобно размещать, например, параметры доступа к внешним серверам - точкам обмена и прочие настройки обмена. Дополнительно для хранения настроек можно создать регистра сведений, где ведущим изменением установить созданный ПО.
В пользовательском режиме следует создать узлы обмена для каждой из точек обмена. Если подсистемы в расширении не настраивались, то настроить ПО можно через «Все функции» («Все действия» в ранних релизах платформы).
При открытии формы в списке нового ПО будет присутствовать единственный узел, отмеченный зеленой точкой. Этот узел является предопределенным и отвечает за текущую ИБ. Для организации обмена с новыми точками обмена следует добавлять узлы в список, а не переименовывать существующий, считая, что таким образом заработает регистрация изменений для дополнительных точек. Да, об этом много написано, но отдельные пользователи и администраторы пытаются это сделать.
Правильная настройка узлов представлена на рисунке:
Предопределенный узел переименовывается во что-то, выделяющее его среди других узлов. Так как часто придется программно обращаться к узлам обмена по коду, следует ответственно отнестись к их назначению. Рекомендуется запретить изменение кода пользователями.
Программную реализацию обмена удобно выполнять через внешнюю обработку. По стандартам БСП для подключения обработки к современным типовым конфигурациям необходимо выполнить стандартные подготовительные действия.
В модуле объекта разместить (скопировать из общего модуля, взять из шаблона) следующие функции и процедуры:
//ПОДГОТОВКА РЕГИСТРАЦИИ ОБРАБОТКИ
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = Новый Структура;
ПараметрыРегистрации.Вставить("Вид", "ДополнительнаяОбработка"); //Варианты: "ДополнительнаяОбработка", "ДополнительныйОтчет", "ЗаполнениеОбъекта", "Отчет", "ПечатнаяФорма", "СозданиеСвязанныхОбъектов"
ПараметрыРегистрации.Вставить("Наименование", "Выгрузка на FTP");
ПараметрыРегистрации.Вставить("Версия", "1.0"); //"1.0"
ПараметрыРегистрации.Вставить("БезопасныйРежим", Ложь); //Варианты: Истина, Ложь
ПараметрыРегистрации.Вставить("Информация", "");
ПараметрыРегистрации.Вставить("ВерсияБСП", "2.2.5.29");// не ниже какой версии БСП подерживается обработка
ТаблицаКоманд = ПолучитьТаблицуКоманд();
ДобавитьКоманду(ТаблицаКоманд,
"Обмен на FTP тест",
"ОбменFTP1",
"ВызовСерверногоМетода", //Использование. Варианты: "ОткрытиеФормы", "ВызовКлиентскогоМетода", "ВызовСерверногоМетода"
Ложь,//Показывать оповещение. Варианты Истина, Ложь
"");//Модификатор
ПараметрыРегистрации.Вставить("Команды", ТаблицаКоманд);
Возврат ПараметрыРегистрации;
КонецФункции
Функция ПолучитьТаблицуКоманд()
Команды = Новый ТаблицаЗначений;
Команды.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));
Команды.Колонки.Добавить("Идентификатор", Новый ОписаниеТипов("Строка"));
Команды.Колонки.Добавить("Использование", Новый ОписаниеТипов("Строка"));
Команды.Колонки.Добавить("ПоказыватьОповещение", Новый ОписаниеТипов("Булево"));
Команды.Колонки.Добавить("Модификатор", Новый ОписаниеТипов("Строка"));
Возврат Команды;
КонецФункции
Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование, ПоказыватьОповещение = Ложь, Модификатор = "")
НоваяКоманда = ТаблицаКоманд.Добавить();
НоваяКоманда.Представление = Представление;
НоваяКоманда.Идентификатор = Идентификатор;
НоваяКоманда.Использование = Использование;
НоваяКоманда.ПоказыватьОповещение = ПоказыватьОповещение;
НоваяКоманда.Модификатор = Модификатор;
КонецПроцедуры
В зависимости от подхода функция ПолучитьТаблицуКоманд() и процедура ДобавитьКоманду() могут отсутствовать, а их код размещаться в основной функции СведенияОВнешнейОбработке().
Основные моменты, требующие изменения общего шаблона:
ПараметрыРегистрации.Вставить("Вид", "ДополнительнаяОбработка")
Указываем, что создается именно дополнительная обработка.
ДобавитьКоманду(ТаблицаКоманд,
"Обмен на FTP тест",
"ОбменFTP1",
"ВызовСерверногоМетода",
Ложь
"");
Здесь важно указать название команды (будущего регламентного задания), ее идентификатор и признак ВызовСерверногоМетода – указывающего на то, что код функционала обмена будет размещен в самом модуле обмена и исполняться на сервере.
Для организации обмена, работы с файлами следует отключить безопасный режим в советующем параметре.
Код исполнения размещается в процедуре
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ПараметрыВыполненияКоманды) Экспорт
Допустим, для обмена была разработана и размещена в модуле процедура ВыполнитьОбмен, входным параметром которой является ссылка на узел обмена.
В этом случае необходимо организовать выборку всех узлов текущего плана обмена, исключая предопределенный. Можно так же исключить помеченные на удаление узлы.
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ПараметрыВыполненияКоманды) Экспорт
Выборка = ПланыОбмена. Тест_ПланОбмена1.Выбрать();
Пока Выборка.Следующий() Цикл
Если Выборка.Ссылка = ПланыОбмена. Тест_ПланОбмена1.ЭтотУзел() Тогда
Продолжить;
КонецЕсли;
ВыполнитьОбмен(Выборка.Ссылка);
КонецЦикла;
КонецПроцедуры
Обработка готова к подключению.
Подключение осуществляется в пользовательском режиме. Раздел НСИ и администрирование\ Печатные формы, отчеты и обработки. Гиперссылка дополнительные отчеты и обработки доступна только при включенной соответствующей функциональной опции.
При добавлении созданной обработке в табличной части на форме отобразится созданная команда. Из данной формы можно выполнить команду или, что важно, настроить расписание регламентного исполнения.
Приведенный выше пример позволяет организовать регламентный или принудительный обмен одновременно со всеми узлами ПО. А как поступить, если требуется с узлами 1 и 2 обмениваться раздельно в разное время?
Самый простой способ: убрать из процедуры выборку и сократить всю процедуру ВыполнитьКоманду до одной строки
ВыполнитьОбмен(ПланыОбмена. Тест_ПланОбмена1.НайтиПоКоду("КодУзла"));
Далее следует «размножить» данные обработки по количеству узлов и все подключить в качестве внешних, для каждой из которых настроить расписание.
Очевидно, что данный подход не очень продуктивный. Можно рассмотреть более органичное решение.
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = Новый Структура;
ПараметрыРегистрации.Вставить("Вид", "ДополнительнаяОбработка"); //Варианты: "ДополнительнаяОбработка", "ДополнительныйОтчет", "ЗаполнениеОбъекта", "Отчет", "ПечатнаяФорма", "СозданиеСвязанныхОбъектов"
ПараметрыРегистрации.Вставить("Наименование", "Выгрузка на FTP");
ПараметрыРегистрации.Вставить("Версия", "1.0"); //"1.0"
ПараметрыРегистрации.Вставить("БезопасныйРежим", Ложь); //Варианты: Истина, Ложь
ПараметрыРегистрации.Вставить("Информация", "");
ПараметрыРегистрации.Вставить("ВерсияБСП", "2.2.5.29");// не ниже какой версии БСП подерживается обработка
ТаблицаКоманд = ПолучитьТаблицуКоманд();
Выборка = ПланыОбмена. Тест_ПланОбмена1.Выбрать();
Пока Выборка.Следующий() Цикл
Если Выборка.Ссылка = ПланыОбмена. Тест_ПланОбмена1.ЭтотУзел() Тогда
Продолжить;
КонецЕсли;
ДобавитьКоманду(ТаблицаКоманд,
"Обмен: "+Выборка.Наименование,
Выборка.Код,
"ВызовСерверногоМетода", //Использование. Варианты: "ОткрытиеФормы", "ВызовКлиентскогоМетода", "ВызовСерверногоМетода"
Ложь,//Показывать оповещение. Варианты Истина, Ложь
"");//Модификатор
КонецЦикла;
ПараметрыРегистрации.Вставить("Команды", ТаблицаКоманд);
Возврат ПараметрыРегистрации;
КонецФункции
Здесь процедура Добавить команду вызывается внутри цикла обхода выборки для каждого узла, кроме предопределенного. Наименование команды теперь будет содержать наименование узла, а идентификатор (ранее мы его не использовали) код узла.
Процедура ВыполнитьКоманду(...) теперь будет выглядеть следующим образом:
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ПараметрыВыполненияКоманды) Экспорт
ВыполнитьОбмен(ПланыОбмена.Тест.НайтиПоКоду(ИдентификаторКоманды));
КонецПроцедуры
При подключении обработки обнаруживаем таблицу команд, заполненную по данным имеющихся узлов. Каждую команду можно отдельно выполнить вручную и задать отдельное расписание.
При обновлении ПО – добавлении/изменении/удалении узлов ПО необходимо просто обновить обработку в справочнике.