12.10.2015

Выгрузка-загрузка данных из 1С 8.2 на sFTP


Итак, здравствуйте, сегодня у нас задача выгрузить что-нибудь на sFTP.
Для начала что же такое sFTP? sFTP - это как FTP, только защищенное. В версии 1С 8.3 проблемы работы с защищенным FTP вроде как бы и нет, потому что разработчики подсуетились и сделали типовое решение, так что если у вас версия предприятия 8.3, то дальше можете не читать. Лучше почитайте синтаксис-помощник. Однако ж, если нужно выгрузить данные из версий более старых, то добро пожаловать.


В интернетах есть примерно два решения проблемы: первое - это с помощью COM-соединения, второе - через внешнее приложение winSCP. Сразу скажу, что первое мне было лень читать. Да оно, наверное, более правильное, но второе, хоть и во втором случае логи пишутся в мутном виде самой winSCP, мне показалось более простым для реализации.
Для работы схемы нам понадобится:
  1. исполняемый файл winSCP.exe(я качал portable-версию, т.к. наш админ не сильно радуется когда на сервер ставятся левые программы) - https://winscp.net/eng/download.php
  2. консольное приложение winSCP.com - оно лежит в архиве, если скачать portable-версию.
  3. put.bat - bat-файл для запуска выгрузки(его напишем сами).
  4. put.ini - файл с настройками для подключения и выгрузки на sFTP-сервер(его тоже напишем сами).
  5. настройки для подключения к sftp: пароль, логин, адрес и порт подключения.
По идее, файлы winSCP.exe и winSCP.com не сильно изменяются, т.е. их конечно обновляют, но для нас это условно неизменные файлы, как и put.bat. Поэтому я поступил с ними следующим образом: создав обработку, поместил их в макеты в качестве двоичных данных. Таким образом, если выйдет глобальное обновление, то файлы можно легко изменить.
макеты с двоичными данными файлов
Чтобы потом получить файл обратно достаточно выполнить код:
лМакет = ЭтотОбъект.ПолучитьМакет(лИмяМакета);
лХранилище = Новый ХранилищеЗначения(лМакет);
лХранилище.Получить();
лМакет.Записать(лПолноеИмяСохраняемогоФайла);
Где лИмяМакета - это "WinSCPmsdos", "WinSCPexe" и "putbat". лПолноеИмяСохраняемогоФайла - это полный путь к месту откуда будет производится выгрузка, например, "C:\1\winSCP.exe". И если у пользователя, под которым запущена обработка достаточно прав на работу с каталогом, то в этом каталоге у нас будет практически все необходимое для выгрузки данных на sFTP.
Теперь рассмотрим поконкретнее что же такое put.bat и put.ini. В bat файл запишем следующую строку(если winscp.exe  и put.ini лежат в одной папке):
winscp.exe /console /script=put.ini
Мы запускаем winSCP под консолью, и выполняем скрипт записанный в файле put.ini.
В файл put.ini пишем следующее:
option echo on
option confirm off
open sftp://#логин:#пароль@#адрес:#порт -hostkey=#ключ
cd /#каталогНаsFTP1
put C:\1.xml
cd /#каталогНаsFTP2
put C:\2.xml
...
close
exit
option echo on - вывод лога на экран вкл, когда в консоли бегают строчки
option confirm off - автоматическое подтверждение действия по умолчанию выкл
open sftp://#логин:#пароль@#адрес:#порт -hostkey=#ключ - тут вроде все понятно, единственное что может вызвать вопрос это #ключ. Чтобы получить ключ нужно подключиться к серверу sFTP в графическом режиме через winSCP.exe и при первом запуске он создаст ключ, который можно скопировать и использовать в дальнейшем. 
cd /#каталогНаsFTP1 - устанавливаем текущим каталогом желаемую папку на sFTP
put C:\1.xml - кладем туда файл 1.xml
close и exit - закрываем и выходим из подключения.
В дальнейшем, когда сформировали файлы подключения, можно проверить их просто запустив put.bat, в случае удачной отработки в консоли будут видны проценты загрузки файла на сервер. Ну и конечно файлы должны появится на сервере, это можно проверить в графическом режиме.
Чтобы запустить выгрузку из 1с потребуется всего одна строчка:
ЗапуститьПриложение("C:\1\put.bat",,Истина);
Второй пустой параметр это текущий каталог, устанавливать его не обязательно. А третий параметр Истина - это ДожидатьсяЗавершения, его лучше поставить.

В случае, если надо загрузить файлы с sFTP, то алгоритм аналогичный. Вместо put.ini и put.bat создаем get.ini и get.bat.
В get.bat пишем:
winscp.exe /console /script=get.ini
В get.ini:
option echo on
option confirm off
open sftp://#логин:#пароль@#адрес:#порт -hostkey=#ключ
cd /#каталогНаsFTP1
get *.xml ""#КаталогДляФайловЗагрузки+*.xml""
...
close
exit
Тут все тоже самое, единственное, что метод get должен содержать каталог для загрузки в двойных кавычках, на вроде ""C:\1\*.xml"". Звездочка означает, что имя файла будет таким же как и на sFTP-сервере.
Проблемой может быть запуск bat-ников из сетевой папки, как было у меня. Если папка для обмена находится в сети, то выполнение, например, put.bat приведет к ошибке: "winscp.exe не является внутренней или внешней командой, исполняемой программой или пакетным файлом." Чтобы этого избежать перед winscp.exe  и put.ini ставим хитрую конструкцию "%~dp0", тогда put.bat будет выглядеть как-то так: 
%~dp0winscp.exe /console /script=%~dp0put.ini
Ну, собственно, вот и все. Проблема загрузки и выгрузки на sFTP переходит в проблему правильного формирования нескольких текстовых файлов и запуска bat-файла из 1С.
Большую часть информации по тому как подключаться к sFTP  посредством консольных команд я взял вот отсюда.

Комментариев нет:

Отправить комментарий