Как сделать на базе 1с.77 обмен по ftp
Рассмотрим пример на базе конфигурации Штрих-М кассир 1.хх:
- Настройка FTP
Во первых для того чтобы сделать обмен по FTP, необходима компонента которая способна работать по данному протоколу, мы используем “DialMail.dll”.
В процедуре “ПриНачалеРаботыСистемы” определим следующее, каталог в который будут сохраняться файлы и отправляться на FTP сервер:
КаталогFTP= КаталогИБ()+"FTP";
Время когда была произведена последняя отправка на FTP сервер:
Константа.УдачноеВремяОтправки = ТекущееВремя();
Константа.РаботаПоИнтервалу_2 = 0;
Инициализация компоненты DialMail:
Если ЗагрузитьВнешнююКомпоненту(КаталогИБ() + "DialMail.dll")=0 Тогда
Сообщить("Не удалось обнаружить компоненту DialMail.dll!");
КонецЕсли;
Попытка
FTP = СоздатьОбъект("AddIn.FTP");
FTP.ИмяЛогФайла = КаталогИБ() + "dialmail_ftp.log";
FTP.ВестиЛогФайл = 1;
FTP.ВестиТехническийЛогФайл = 1;
FTP.NewRFC = 0;
Сообщить(FTP.ВерсияОбъектаСтр);
Исключение
Сообщить("Не удалось создать объект из компоненты DialMail.dll!");
КонецПопытки;
- Настройка FTP
Во первых для того чтобы сделать обмен по FTP, нужно сделать настройки
Для обработки «Настройка» создадим вкладку «РаботаСFTP»
Добавим реквизиты:
- ОбменПоFTP(флаг использовать обмен по FTP или нет),
- ИмяСервераФТП(Имя сервера FTP для связи),
- ИмяПользователяФТП(Имя пользователя FTP для связи),
- ПарольПользователяФТП (Пароль пользователя FTP для связи),
- ПортФТП (Порт FTP для связи),
- ПассивныйРежимФТП (Пассивный или нет режим FTP для связи, через перечисление),
- Интервал1ФТП(Период через который будут отправляться файлы)
- Интервал2ФТП(Период через который система будет проверять связь в случае ее отстутствия).
В модуле обработки создадим процедуру “ВыборFTP”, заполнение полей вкладки из констант
Процедура ВыборFTP()
//Обмен данными по ФТП
ИмяСервераФТП = Константа.ИмяСервераФТП;
ИмяПользователяФТП = Константа.ИмяПользователяФТП;
ПарольПользователяФТП = Константа.ПарольПользователяФТП;
ПортФТП = Константа.ПортФТП;
ПассивныйРежимФТП = Константа.ПассивныйРежимФТП;
Интервал1ФТП = Константа.Интервал1ФТП;
Интервал2ФТП = Константа.Интервал2ФТП;
ОбменПоFTP = Константа.ОбменПоFTP;
Если ПортФТП < 1 Тогда
ПортФТП = 21;
КонецЕсли;
КонецПроцедуры
В процедуре “ПриВыбореЗакладки” дополним следующим кодом, для отображения вкладки и заполнения параметров вкладки:
ИначеЕсли ЗначениеЗакладки=11 Тогда
Форма.ИспользоватьСлой("РаботаСFTP",1);
ВыборFTP();
В конце модуля добавим код чтобы вкладка была в списке вкладок:
Форма.Закладки.ДобавитьЗначение(11,"Настройка FTP");
И конечно же для запоминания изменений по параметрам FTP в процедуру “Выполнить” добавим код:
Константа.ИмяСервераФТП = СокрЛП(ИмяСервераФТП);
Константа.ИмяПользователяФТП = СокрЛП(ИмяПользователяФТП);
Константа.ПарольПользователяФТП = ПарольПользователяФТП;
Константа.ПортФТП = ПортФТП;
Константа.ПассивныйРежимФТП = ПассивныйРежимФТП;
Константа.Интервал1ФТП = Интервал1ФТП;
Константа.Интервал2ФТП = Интервал2ФТП;
Константа.ОбменПоFTP = ОбменПоFTP;
- Режим обмена FTP
Определим периодический обмен в процедуре “Таймер”, добавив код
Если (Константа.ОбменПоFTP>0) И (Константа.РаботаПоИнтервалу_2 >0) Тогда
Если ПрошелИнтервал1()=1 Тогда
Для й=1 по 3 Цикл
FTPThreads[й] = "";
ИДПотока[й] = 0;
СостояниеПотока[й] = "";
КонецЦикла;
//Поиск не отправленных Файлов
ФС.УстТекКаталог(КаталогFTP);
ИмяФайла = ФС.НайтиПервыйФайл("*.*");
Пока 1=1 Цикл
ИмяФайла = ФС.НайтиСледующийФайл();
Если ПустаяСтрока(ИмяФайла)=1 Тогда
Прервать;
КонецЕсли;
Если (ИмяФайла=".") или (ИмяФайла="..") Тогда
Продолжить;
КонецЕсли;
//-2- Отправить по FTP
Если (ПодключитьсяКFTP()>0) Тогда
Если ВыгрузитьНаFTP(КаталогFTP+"\"+ИмяФайла,ИмяФайла)=0 Тогда
//включение интервала 2
Константа.РаботаПоИнтервалу_2 = 1;
Прервать;
Иначе
Константа.УдачноеВремяОтправки = ТекущееВремя();
Константа.РаботаПоИнтервалу_2 = 0;
//Переименовать!
ИмяКуда = СтрЗаменить(КаталогFTP+"\"+ИмяФайла,"PROD","OTPR");
ФС.ПереименоватьФайл(КаталогFTP+"\"+ИмяФайла,ИмяКуда,1);
КонецЕсли;
КонецЕсли;
КонецЦикла;
ОтключитьсяОтFTP();
Константа.УдачноеВремяОтправки = ТекущееВремя();
КонецЕсли;
КонецЕсли;
Первая строчка определяет, подключена ли работа с компонентой обмена по FTP и включена ли работа по интервалу 2(период проверки связи при его отсутствии), следующая функция «ПрошелИнтервал1()» возвращает 1 в случае если прошел период со времени последней удачной отправки данных на FTP, 0 в случае неудачи, код функции ниже:
Функция ПрошелИнтервал1()
ТекВрем = ТекущееВремя();
//проверка времени!
Если Константа.РаботаПоИнтервалу_2>0 Тогда
Дельта = Константа.Интервал2ФТП;
Иначе
Дельта = Константа.Интервал1ФТП;
КонецЕсли;
ПрошВремя = Константа.УдачноеВремяОтправки;
СекТекущие = РасчетСекундПоВремени(ТекВрем);
СекПоследние = РасчетСекундПоВремени(ПрошВремя);
РазницаСекунд = СекТекущие-СекПоследние;
Если (РазницаСекунд<0) Тогда
РазницаСекунд=-РазницаСекунд;
КонецЕсли;
Если (РазницаСекунд>=Дельта) Тогда //*60
Возврат 1;
КонецЕсли;
Возврат 0;
КонецФункции
Далее устанавливаем каталог FTP, и смотрим есть ли не отправленные файлы, если есть, то подключаемся при помощи функции «ПодключитьсяКFTP»
Функция ПодключитьсяКFTP()
ОтключитьсяОтFTP();
Подключено = 0;
FTP.ИспользоватьПрокси = 0;
FTP.ВремяДоРазрыва = 10000;
FTPПассивныйРежим=0;
Если FTP.Подключиться( СокрЛП(Константа.ИмяСервераФТП),
Константа.ПортФТП,
СокрЛП(Константа.ИмяПользователяФТП),
СокрЛП(Константа.ПарольПользователяФТП),FTPПассивныйРежим)=0 тогда
Сообщить("Не смогли подключиться к FTP-серверу");
Иначе
Подключено = 1;
КонецЕсли;
Возврат Подключено;
КонецФункции
После удачно подключения, выгрузим файл на FTP с помощью функции «ВыгрузитьнаFTP»:
Функция ВыгрузитьНаFTP(ОтправляемыйФайл,ВыбрФайл)
Если FTP.ОтправитьФайл(ОтправляемыйФайл,ВыбрФайл)=0 тогда
Предупреждение("Ошибка!!! Файл не отправлен!");
Возврат 0;
КонецЕсли;
Возврат 1;
НомерНезанятого = СоздатьСоединениеДляПотока();
ТекКаталог="/";
Если НомерНезанятого = 0 Тогда
Возврат 0;
КонецЕсли;
Если FTPThreads[НомерНезанятого].ОтправитьФайлы(ОтправляемыйФайл, // Файл(ы), расположенный на ftp
?(СокрЛП(ТекКаталог)="/","",СокрЛП(ТекКаталог)), // Каталог на диске, куда будет записываться файл
0, // 1 - докачка разрешена, 0 - переписываем, даже если найдем с таким же именем
0, // 1 - удаляем после удачного принятия, 0 - не удаляем
1, // 1 - посылаем команду Отключиться() после получения, 0 - оставляем сединение с FTP
1 // 1 - выполняем в потоке, 0 - без потока
)<> -100 Тогда
Предупреждение("Произошла непредвиденная ошибка!");
FTPThreads[НомерНезанятого] = "";
Возврат 0;
КонецЕсли;
ИДПотока[НомерНезанятого] = FTPThreads[НомерНезанятого].ИДПотока();
СостояниеПотока[НомерНезанятого] = "ОТПРАВКА";
Сообщить("Номер потока = "+ИДПотока[НомерНезанятого]);
Возврат 1;
КонецФункции
Описание функции «СоздатьСоединениеДляПотока»:
Функция СоздатьСоединениеДляПотока()
НомерНезанятого = 0;
Для й = 1 по 3 Цикл
Если ТипЗначенияСтр(FTPThreads[й])="Строка" Тогда
НомерНезанятого = й;
Прервать;
Иначе
Если FTPThreads[й].ВПотоке()=0 Тогда
FTPThreads[й] = "";
НомерНезанятого = й;
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если НомерНезанятого = 0 Тогда
Предупреждение("Все потоки заняты");
Возврат 0;
КонецЕсли;
FTPThreads[НомерНезанятого] = СоздатьОбъект("AddIn.FTP");
FTPThreads[НомерНезанятого].ИмяЛогФайла = КаталогИБ()+"dialmail_ftp"+СокрЛП(НомерНезанятого)+".log";
FTPThreads[НомерНезанятого].ВестиЛогФайл = 1;
FTPThreads[НомерНезанятого].ВестиТехническийЛогФайл = 1;
FTPThreads[НомерНезанятого].ВремяДоРазрыва = 100000; // Timeout
FTPThreads[НомерНезанятого].ВремяМеждуСобытиями=1000; FTPThreads[НомерНезанятого].ИспользоватьПрокси=0;
FTPПассивныйРежим = 0;
Если FTPThreads[НомерНезанятого].Подключиться(СокрЛП(Константа.ИмяСервераФТП),
Константа.ПортФТП,
СокрЛП(Константа.ИмяПользователяФТП),
СокрЛП(Константа.ПарольПользователяФТП),FTPПассивныйРежим)=0 тогда
Сообщить("Не; смогли подключиться к FTP-серверу");
Возврат 0;
КонецЕсли;
Возврат НомерНезанятого;
КонецФункции
Затем отключимся от FTP:
Процедура ОтключитьсяОтFTP()
FTP.Отключиться();
КонецПроцедуры
Теперь опишем обмен файлов в рабочем режиме. Создадим процедуру, которая будет выгружать чек после каждого закрытия чека «ВыгрузитьОтчетПоЧеку»:
Процедура ВыгрузитьОтчетПоЧеку(ТекЧек) Экспорт
Для й=1 по 3 Цикл
FTPThreads[й] = "";
ИДПотока[й] = 0;
СостояниеПотока[й] = "";
КонецЦикла;
//ИмяПК.PROD.№ЧЕКА.ДАТА
ИмяЧека = ИмяКомпьютера()+"_"+"PROD_"+"№"+НомерЧека+"_"+СтрЗаменить(Строка(ТекущаяДата()),".","_");
ИмяТекстовогоФайла = КаталогFTP+"\"+ИмяЧека;
////Пошел процесс формирования
//Информация в файле: время чека, общая сумма чека, код товара, количество товара по коду, цена
//-1-Создали файл
Анализатор=СоздатьОбъект("AddIn.XMLParser");
ФайлXML=Анализатор.СоздатьДокумент();
ВыгрузкаXML = Анализатор.СоздатьДокумент();
Шапка = ВыгрузкаXML.СоздатьПодчиненныйЭлемент("Chek");
//Дата
ствол = Шапка.СоздатьПодчиненныйЭлемент("Data");
ствол.Значение = Строка(ТекущаяДата());
//Общая сумма
ствол = Шапка.СоздатьПодчиненныйЭлемент("Summ");
ствол.Значение = ТекЧек.Итог("Сумма");
//Перебор!
Тело = Шапка.СоздатьПодчиненныйЭлемент("ChekStr");
инд=0;
ТекЧек.ВыбратьСтроки();
Пока ТекЧек.ПолучитьСтроку() = 1 Цикл
инд = инд +1;
Состояние ("Обработано "+инд+" элементов.");
ЗаполнитьДанныеПо__(Тело,ТекЧек);
КонецЦикла;
ВыгрузкаXML.Записать(ИмяТекстовогоФайла);
//-1-2
Если ПрошелИнтервал1()=1 Тогда
//Поиск не отправленных Файлов
ФС.УстТекКаталог(КаталогFTP);
ИмяФайла = ФС.НайтиПервыйФайл("*.*");
Пока 1=1 Цикл
ИмяФайла = ФС.НайтиСледующийФайл();
Если ПустаяСтрока(ИмяФайла)=1 Тогда
Прервать;
КонецЕсли;
Если (ИмяФайла=".") или (ИмяФайла="..") Тогда
Продолжить;
КонецЕсли;
//-2- Отправить по FTP
Если ПодключитьсяКFTP()=0 Тогда
//включение интервала 2
Константа.РаботаПоИнтервалу_2 = 1;
Прервать;
Иначе
Если ВыгрузитьНаFTP(КаталогFTP+"\"+ИмяФайла,ИмяФайла)=0 Тогда
//включение интервала 2
Константа.РаботаПоИнтервалу_2 = 1;
Прервать;
Иначе
Константа.УдачноеВремяОтправки = ТекущееВремя();
Константа.РаботаПоИнтервалу_2 = 0;
//Переименовать!
ИмяКуда = СтрЗаменить(КаталогFTP+"\"+ИмяФайла,"PROD","OTPR");
ФС.ПереименоватьФайл(КаталогFTP+"\"+ИмяФайла,ИмяКуда,1);
КонецЕсли;
КонецЕсли;
КонецЦикла;
ОтключитьсяОтFTP();
КонецЕсли;
КонецПроцедуры
Процедуру «ВыгрузитьОтчетПоЧеку» можно вызвать во функции «Выгрузка отчета» при следующих параметрах:
Если Константа.СпособОбменаДанными=2 Тогда
Смещение=0,
Синхронизация=1
Данные по чеку можно получить через
Если ФормаРегистрации<>0 Тогда
_Чек = ФормаРегистрации.Чек
Функция, которая создает xml-тело файл по данным чека «ЗаполнитьДанныеПо__»:
Функция ЗаполнитьДанныеПо__(Элемент,Эл)
ствол = Элемент.СоздатьПодчиненныйЭлемент("stroka");
//Код товара
Code = ствол.СоздатьПодчиненныйЭлемент("Code");
Code.Значение = Эл.Товар.Код;
//Кол
Quantity = ствол.СоздатьПодчиненныйЭлемент("Quantity");
Quantity.Значение =Эл.Количество;
//цена
Price = ствол.СоздатьПодчиненныйЭлемент("Price");
Price.Значение = Эл.Цена;
Возврат Элемент;
КонецФункции
В глобальном модуле сделаем следующие переменные
Перем КаталогFTP Экспорт;
Перем FTP Экспорт;
Перем FTPThreads[3];
Перем СостояниеПотока[3];
Перем ИДПотока[3];
Система готова.