среда, 23 декабря 2015 г.

ЧтениеXML и ЗаписьXML. [Шаблон проэктов]. В примере, показана работа с FTP-ресурсами.

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

В основном стоит задача, что-то выгрузить из системы в файл xml. Как пример привожу выгрузку справочника товары из конфигурации "Управление торговлей " (УТ 10)

ЗаписьXML:


Процедура ЗаписатьСтрокуВ_XML(Запись, СписокДляЗаписи);

    Для Каждого
СтрокаСписка ИЗ СписокДляЗаписи Цикл

       
ЗначениеХМЛ = СтрокаСписка.Значение;
       
ЗначениеХМЛ = СтрЗаменить(ЗначениеХМЛ, "&", "&");
       
ЗначениеХМЛ = СтрЗаменить(ЗначениеХМЛ, "<", "<");
       
ЗначениеХМЛ = СтрЗаменить(ЗначениеХМЛ, ">", ">");

       
Запись.ЗаписатьНачалоЭлемента(СтрокаСписка.Представление);
       
Запись.ЗаписатьТекст(ЗначениеХМЛ);
       
Запись.ЗаписатьКонецЭлемента();

    КонецЦикла;

   
СписокДляЗаписи.Очистить();

КонецПроцедуры

Процедура ВыгрузитьТоварыВКаталогНаДиске(Параметры, СтрокаТаблицыИнформации, ВыгруженоОбъектов,Успешно=Истина)

   
ИмяФайла    = ПолучитьИмяФайлаВыгрузкиВ_WMS("Nom"Параметры.КаталогВыгрузки);
   
ТекДанные   = ПолучитьТаблицуНоменклатуры(Параметры.СтруктураИзменений.Товары, Параметры);  //внешний запро, где получаем все поля выгрузки. Возвращаемый тип "ТаблицаЗначений"

   
Если ТекДанные.Количество() = 0 Тогда

       
ПодготовитьИтоговуюИнформациюПоВыгрузке(СтрокаТаблицыИнформации, ВыгруженоОбъектов); //служебная процедура, если данных нет информируем это в логе обмена

       
Возврат;
    КонецЕсли;

   
СписокДляЗаписиВ_XML = Новый СписокЗначений;

   
ЗаписьXML = Новый ЗаписьXML;
    Попытка
       
ЗаписьXML.ОткрытьФайл(ИмяФайла, "windows-1251");
       
ЗаписьXML.ЗаписатьОбъявлениеXML();
    Исключение

       
Успешно=Ложь;

       
мДеталиОшибки = ОписаниеОшибки();
       
ОбъявитьОшибкуXML(СтрокаТаблицыИнформации, "Выгрузка товаров - прервана!", мДеталиОшибки); //вызов процедуры-исключения

       
Возврат;
    КонецПопытки;

   
СсылкаНаФайл = Новый Файл(ИмяФайла);
   
ЗаписьXML.ЗаписатьНачалоЭлемента("NOMENKLATURA");

    Для Каждого
СтрокаВыборки Из ТекДанные Цикл

       
ВыгруженоОбъектов = ВыгруженоОбъектов+1;

       
ЗаписьXML.ЗаписатьНачалоЭлемента("NOM");
       
СписокДляЗаписиВ_XML.Добавить(Строка(СтрокаВыборки.Номенклатура.УникальныйИдентификатор()), "CODE");
       
СписокДляЗаписиВ_XML.Добавить(СтрокаВыборки.Наименование,                                   "NAME");
       
СписокДляЗаписиВ_XML.Добавить(СокрЛП(СтрокаВыборки.КодПроизводителя),                       "ARTK");
       
СписокДляЗаписиВ_XML.Добавить(СтрокаВыборки.Родитель,                                       "GROUP_NAME");
       
СписокДляЗаписиВ_XML.Добавить(СтрокаВыборки.ЕдиницаИзмерения,                               "UNIT_OP_NAME");
       
СписокДляЗаписиВ_XML.Добавить(СтрокаВыборки.ЕдиницаИзмерения,                               "UNIT_NAME");
       
СписокДляЗаписиВ_XML.Добавить(СтрокаВыборки.ЕдиницаИзмерения,                               "UNIT_CL_NAME");
       
ЗаписатьСтрокуВ_XML(ЗаписьXML, СписокДляЗаписиВ_XML);

       
//строим древовидную структуру
        // +PALLS_INFO
        //   +PALL
       
ЗаписьXML.ЗаписатьНачалоЭлемента("PALLS_INFO");
       
ЗаписьXML.ЗаписатьНачалоЭлемента("PALL");

       
СписокДляЗаписиВ_XML.Добавить(1,                                            "TYPE");
       
СписокДляЗаписиВ_XML.Добавить(Формат(5000, Параметры.ФорматКоличества),     "BLCK");
       
ЗаписатьСтрокуВ_XML(ЗаписьXML, СписокДляЗаписиВ_XML);

       
ЗаписьXML.ЗаписатьКонецЭлемента(); //PALL
       
ЗаписьXML.ЗаписатьКонецЭлемента(); //PALLS_INFO

       
ЗаписьXML.ЗаписатьНачалоЭлемента("UNITS_INFO");
       
ЗаписьXML.ЗаписатьНачалоЭлемента("UNIT");

       
СписокДляЗаписиВ_XML.Добавить("шт", "TYPE");
       
СписокДляЗаписиВ_XML.Добавить(1,    "CNT");
       
СписокДляЗаписиВ_XML.Добавить(1,    "EXPONENT");
       
ЗаписатьСтрокуВ_XML(ЗаписьXML, СписокДляЗаписиВ_XML);

       
ЗаписьXML.ЗаписатьКонецЭлемента(); //UNIT
       
ЗаписьXML.ЗаписатьКонецЭлемента(); //UNITS_INFO

       
ЗаписьXML.ЗаписатьКонецЭлемента(); //

   
КонецЦикла;

   
ЗаписьXML.ЗаписатьКонецЭлемента(); //
   
ЗаписьXML.Закрыть();

   
ОписаниеИнформацииОбмена = "Файл записан: "+ИмяФайла;
   
СтрокаТаблицыИнформации.Описание = ?(ПустаяСтрока(СтрокаТаблицыИнформации.Описание),"",СтрокаТаблицыИнформации.Описание+Символы.ПС)+ ОписаниеИнформацииОбмена;

   
//используется ФТП-соединение (для примера так-же)
   
ФайлFTP = ПолучитьКорневойКаталогFTP(Параметры.НастройкаFTPСоединения.FTPАдресОбмена) + "Nom/"+СсылкаНаФайл.Имя;
   
ФайлFTP = СтрЗаменить(ФайлFTP, "\", "/");

    Попытка
       
Параметры.ТекущееFTPСоединение.Записать(ИмяФайла, ФайлFTP);
    Исключение
       
ОписаниеИнформацииОбмена = "Ошибка перемещения на FTP-ресурс: "+ФайлFTP;
       
СтрокаТаблицыИнформации.Описание = ?(ПустаяСтрока(СтрокаТаблицыИнформации.Описание),"",СтрокаТаблицыИнформации.Описание+Символы.ПС)+ ОписаниеИнформацииОбмена+Символы.ПС+ОписаниеОшибки();
       
Успешно=Ложь;
       
ВыгруженоОбъектов = 0;
    КонецПопытки;

   
УдалитьФайлы(ИмяФайла);

    Если
Успешно Тогда

       
ОписаниеИнформацииОбмена = "Файл перемещен на FTP-ресурс: "+ФайлFTP;
       
СтрокаТаблицыИнформации.Описание = ?(ПустаяСтрока(СтрокаТаблицыИнформации.Описание),"",СтрокаТаблицыИнформации.Описание+Символы.ПС)+ ОписаниеИнформацииОбмена;

    КонецЕсли;

   
ПодготовитьИтоговуюИнформациюПоВыгрузке(СтрокаТаблицыИнформации, ВыгруженоОбъектов); //служебные процедуры для вывода в лог - информации по обмену

КонецПроцедуры

//ПРИМЕР РАБОТЫ С ФТП-обменом
// более широко в примере будет при загрузке применяться. Именно отчитка файла и помещение подтверждения

Функция ПолучитьКорневойКаталогFTP(FTPАдресОбмена)

   
КорневойКаталог = "";

   
//раскладываем строку адреса для получения Корневого каталога
    // например: ftp://opt2.unipol.ru/Erp-prof/homyak/Bitrix/
    // корневой каталог = Erp-prof/homyak/Bitrix/
   
ИндТочки = Найти(FTPАдресОбмена, ".");
    Для
Шаг = ИндТочки По СтрДлина(FTPАдресОбмена) Цикл

       
ТекСимв = Сред(FTPАдресОбмена, Шаг, 1);
        Если
ТекСимв = "/" Тогда
           
КорневойКаталог = Сред(FTPАдресОбмена, Шаг+1);
            Прервать;
        КонецЕсли;

    КонецЦикла;

    Если Не
ПустаяСтрока(КорневойКаталог) и Прав(КорневойКаталог, 1) <> "/" Тогда
       
КорневойКаталог = КорневойКаталог + "/"; //добавочный слэш
   
КонецЕсли;

    Возврат
КорневойКаталог;
КонецФункции

ЧтениеXML и пример обработки результата:


//Функция предназначена отчитать содержимое файлов XML и возвращает структурированный массив:
// ФайлFTP| ФайлЛокальный |Данные
//
Функция РазобратьФайлыXMLЧтение(Параметры, КаталогЧтенияFTP, СтрокаТаблицыИнформации, Успешно=Истина)

   
ЗагружаемыеФайлыXML = Новый Массив;
   
НайденныеФайлы = Параметры.ТекущееFTPСоединение.НайтиФайлы(КаталогЧтенияFTP, "*.xml");

    Если
НайденныеФайлы.Количество() = 0 Тогда

       
ОписаниеИнформацииОбмена = "Отсутствует пакет документов для импорта, каталог пуст: "+КаталогЧтенияFTP;
       
СтрокаТаблицыИнформации.Описание = ?(ПустаяСтрока(СтрокаТаблицыИнформации.Описание),"",СтрокаТаблицыИнформации.Описание+Символы.ПС)+ ОписаниеИнформацииОбмена;

        Возврат
ЗагружаемыеФайлыXML;
    КонецЕсли;

   
//Файл на ФТП найден. Для отчитки, необходимо его скопировать на локальный ресурс
   
Для Каждого ФайлFTP Из НайденныеФайлы Цикл //-} начало итерации по найденным файлам FTP-ресурса

       
ИмяФайла = Параметры.КаталогЗагрузки+"\"+ФайлFTP.Имя;
       
Параметры.ТекущееFTPСоединение.Получить(ФайлFTP.ПолноеИмя, ИмяФайла); //копируем файл с ФТП-ресурса на локальный
       
ФайлЛокальный = Новый Файл(ИмяФайла); //типизируем

       
ОписаниеИнформацииОбмена = "    -}Чтение содержимого файла: "+ФайлFTP.Имя;
       
СтрокаТаблицыИнформации.Описание = ?(ПустаяСтрока(СтрокаТаблицыИнформации.Описание),"",СтрокаТаблицыИнформации.Описание+Символы.ПС)+ ОписаниеИнформацииОбмена;

       
ЧтениеXML = Новый ЧтениеXML;
        Попытка
           
ЧтениеXML.ОткрытьФайл(ИмяФайла,,,"windows-1251");
        Исключение

           
Успешно = Ложь;
           
ДеталиОшибки = "Ошибка открытия файла! "+ОписаниеОшибки()+Символы.ПС;
           
СтрокаТаблицыИнформации.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Ошибка;
           
СтрокаТаблицыИнформации.Описание = ?(ПустаяСтрока(СтрокаТаблицыИнформации.Описание),"",СтрокаТаблицыИнформации.Описание+Символы.ПС)+ ДеталиОшибки;

           
ЧтениеXML.Закрыть();
           
ПереместитьФайлВКаталогОшибок(ФайлFTP, Параметры, СтрокаТаблицыИнформации); //процедура размещена по тексту ниже
           
УдалитьФайлы(ИмяФайла);

            Продолжить;
        КонецПопытки;

       
ЗагружаемыеДокументыXML = Новый Массив;
       
СтекУзлов               = Новый Массив;
       
ТекущийПуть             = "";

        Попытка

            Пока
ЧтениеXML.Прочитать() Цикл //-} начало Чтения XML

               
Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда

                   
ИмяУзла = ЧтениеXML.Имя;
                   
СтекУзлов.Добавить(ИмяУзла);
                   
ТекущийПуть = МассивВСтроку(СтекУзлов);

                    Если
ВРег(ИмяУзла) = "DOC_IN" или ВРег(ИмяУзла) = "DOC_OUT" Тогда // начало документа
                       
СтруктураДокументаXML   = Новый Структура("Номер, Дата, Контрагент, Склад, ДокументОснование, ВидДокумента, Комментарий, Состав");
                    ИначеЕсли
ВРег(ИмяУзла) = "CONTENT" Тогда
                       
СтруктураДокументаXML.Состав = Новый Массив;
                    ИначеЕсли
ВРег(ИмяУзла) = "CODE" Тогда // атрибуты товара (ид товара)
                       
СтрокаСостава               = Новый Структура("Номенклатура, Количество, КоличествоБрак, ТипКондиции, Качество, Характеристика");
                       
СтрокаСостава.Номенклатура  = ЧтениеXML.ПолучитьАтрибут("CODE_ID");
                    КонецЕсли;

                ИначеЕсли
ЧтениеXML.ТипУзла = ТипУзлаXML.Текст Тогда

                   
ЗнчXML = ЧтениеXML.Значение;
                    Если
ВРег(ИмяУзла) = "NUMBER" Тогда
                       
СтруктураДокументаXML.Номер = ЗнчXML;
                    ИначеЕсли
ВРег(ИмяУзла) = "ID_DOC" Тогда
                       
СтруктураДокументаXML.ДокументОснование = ЗнчXML;
                    ИначеЕсли
ВРег(ИмяУзла) = "CLIENT_DOC_NUM" Тогда
                       
СтруктураДокументаXML.ВидДокумента = ЗнчXML;
                    ИначеЕсли
ВРег(ИмяУзла) = "WAREHOUSE_N" Тогда
                       
СтруктураДокументаXML.Склад = Число(ЗнчXML);
                    ИначеЕсли
ВРег(ИмяУзла) = "PUT_ON_STORE_FD" или ТекущийПуть = "DOC\DOC_OUT\DATE" Тогда
                       
СтруктураДокументаXML.Дата = ПолучитьДатуИзСтроки(ЗнчXML);
                    ИначеЕсли
ВРег(ИмяУзла) = "DSC" Тогда
                       
СтруктураДокументаXML.Комментарий = СокрЛП(ЗнчXML);
                    ИначеЕсли
ВРег(ИмяУзла) = "CUSTOMER_ID" Тогда
                       
СтруктураДокументаXML.Контрагент = ЗнчXML;
                    ИначеЕсли
ВРег(ИмяУзла) = "CNT" Тогда
                       
СтрокаСостава.Количество = Число(ЗнчXML);
                    ИначеЕсли
ВРег(ИмяУзла) = "CNT_BRAK" Тогда
                       
СтрокаСостава.КоличествоБрак = Число(ЗнчXML);
                    ИначеЕсли
ВРег(ИмяУзла) = "ST_PART_N" Тогда
                       
СтрокаСостава.Характеристика = ЗнчXML;
                    ИначеЕсли
ВРег(ИмяУзла) = "NOM_TYP" Тогда
                       
СтрокаСостава.ТипКондиции = Число(ЗнчXML);  //принимает значения 1- новый, 3- брак
                   
ИначеЕсли (ВРег(ИмяУзла) = "SUB_NOM_TYP" или ВРег(ИмяУзла) = "NOM_COND_TYP" или ВРег(ИмяУзла) = "NOM_BRAK_TYP") и Число(ЗнчXML) } 0 Тогда
                       
СтрокаСостава.Качество = Число(ЗнчXML); //соответствие качеств
                   
КонецЕсли;

                ИначеЕсли
ЧтениеXML.ТипУзла = ТипУзлаXML.КонецЭлемента Тогда

                    Если
ВРег(ЧтениеXML.Имя) = "CODE" Тогда
                       
СтруктураДокументаXML.Состав.Добавить(СтрокаСостава);

                    ИначеЕсли
ВРег(ЧтениеXML.Имя) = "DOC_IN" или  ВРег(ЧтениеXML.Имя) = "DOC_OUT" Тогда
                       
ЗагружаемыеДокументыXML.Добавить(СтруктураДокументаXML); //в том случае, когда в файле будет содержаться несколько документов
                   
КонецЕсли;

                   
СтекУзлов.Удалить(СтекУзлов.Количество()-1);
                   
ТекущийПуть = МассивВСтроку(СтекУзлов);

                КонецЕсли;

            КонецЦикла;
//{-Конец Чтения XML

           
ЧтениеXML.Закрыть();

           
ОписаниеИнформацииОбмена = "    {-Закончено чтение файла: "+ФайлFTP.ПолноеИмя;
           
СтрокаТаблицыИнформации.Описание = ?(ПустаяСтрока(СтрокаТаблицыИнформации.Описание),"",СтрокаТаблицыИнформации.Описание+Символы.ПС)+ ОписаниеИнформацииОбмена;

           
ЗагружаемыеФайлыXML.Добавить(Новый Структура("ФайлFTP, ФайлЛокальный, ДанныеXML", ФайлFTP, ФайлЛокальный, ЗагружаемыеДокументыXML));

        Исключение

           
Успешно= Ложь;
           
ЧтениеXML.Закрыть();
           
ОписаниеИнформацииОбмена = "        Сбой внутри файла в узле: " + ТекущийПуть + Символы.ПС + ОписаниеОшибки();
           
СтрокаТаблицыИнформации.Описание = ?(ПустаяСтрока(СтрокаТаблицыИнформации.Описание),"",СтрокаТаблицыИнформации.Описание+Символы.ПС)+ ОписаниеИнформацииОбмена;
           
СтрокаТаблицыИнформации.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Ошибка;

           
ПереместитьФайлВКаталогОшибок(ФайлFTP, Параметры, СтрокаТаблицыИнформации);
           
УдалитьФайлы(ФайлЛокальный.ПолноеИмя);

        КонецПопытки;

    КонецЦикла;
//{-Конец итерации найденных FTP-файлов

   
Возврат ЗагружаемыеФайлыXML;

КонецФункции

Процедура
ЗагрузитьПриходныеДокументыПоСкладуИзФайла(Параметры, СтрокаТаблицыИнформации, ЗагруженоОбъектов, Успешно=Истина)

   
КаталогЧтения = ПолучитьКорневойКаталогFTP(Параметры.НастройкаFTPСоединения.FTPАдресОбмена) + "Notify_in/";
   
ЗагружаемыеФайлыXML = РазобратьФайлыXMLЧтение(Параметры, КаталогЧтения, СтрокаТаблицыИнформации, Успешно);

   
//Структура массива ЗагружаемыеФайлыXML:
    //ФайлFTP, ФайлЛокальный, ДанныеXML(Массив)
    //  Где, ДанныеXML(Массив)  = Новый Структура("Номер, Дата, Контрагент, Склад, ДокументОснование, ВидДокумента, Комментарий, Состав(Массив)")
    //  Где, Состав(Массив)     = Новый Структура("Номенклатура, Количество, КоличествоБрак, ТипКондиции, Качество, Характеристика")

    //расчетные переменные
   
ВидыОпераций = Новый Соответствие;
   
ВидыОпераций.Вставить("Поступление товаров и услуг",    Перечисления.ВидыОперацийПриходныйОрдер.ОтПоставщика);
   
ВидыОпераций.Вставить("Возврат товаров от покупателя"Перечисления.ВидыОперацийПриходныйОрдер.ОтПокупателя);
   
ВидыОпераций.Вставить("Перемещение товаров",            Перечисления.ВидыОперацийПриходныйОрдер.Перемещение);

    Для Каждого
ЭлементСтруктуры Из ЗагружаемыеФайлыXML Цикл //-}Начало итерации по содержимому файлов XML

       
ОписаниеИнформацииОбмена = "    -}Обработка файла: "+ЭлементСтруктуры.ФайлFTP.Имя;
       
СтрокаТаблицыИнформации.Описание = ?(ПустаяСтрока(СтрокаТаблицыИнформации.Описание),"",СтрокаТаблицыИнформации.Описание+Символы.ПС)+ ОписаниеИнформацииОбмена;
       
ЕстьОшибкиКонтента = Ложь;

        Для Каждого
ДокументXML Из ЭлементСтруктуры.ДанныеXML Цикл //-}Начало итерации по документам которые необходимо создать

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

            КонецЕсли;

            Если
ЕстьОшибкиКонтента Тогда
                Прервать;
//это мало вероятно поскольку в одном файле один документ, но если система WMS отдаст множество и в каком-то из документов будет ошибка
                            //то ошибочным считается файл целиком
           
КонецЕсли;

           
ВидОперацииДокумента = ВидыОпераций.Получить(ДокументXML.ВидДокумента);
            Если
ВидОперацииДокумента = Неопределено Тогда

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

            КонецЕсли;

           
//создание документа
           
ДокументОбъект = Документы.ПриходныйОрдерНаТовары.СоздатьДокумент();
           
ДокументОбъект.Дата         = ДокументXML.Дата;
           
ДокументОбъект.ВидОперации  = ВидОперацииДокумента;
           
ДокументОбъект.Организация  = Параметры.Организация;
           
ДокументОбъект.Склад        = Параметры.КодыСкладов.Получить(ДокументXML.Склад);
           
ДокументОбъект.Комментарий  = ДокументXML.Комментарий;//"#Загружен автоматически - "+ТекущаяДата()+" из WMS-системы по файлу: "+ЭлементСтруктуры.ФайлFTP.ПолноеИмя;

           
Если ЗначениеЗаполнено(ДокументXML.Контрагент) Тогда //расчетные поля по ИД "Контрагент"

               
Попытка
                   
ДокументОбъект.Контрагент = Справочники.Контрагенты.ПолучитьСсылку(Новый УникальныйИдентификатор(ДокументXML.Контрагент));
                Исключение
                   
//в случае Ид указан не GUID это исключение. Нам необходимо собрать информацию о проблемных блоках.
               
КонецПопытки;

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

            КонецЕсли;

            Если
ЗначениеЗаполнено(ДокументXML.ДокументОснование) и ВидОперацииДокумента = Перечисления.ВидыОперацийПриходныйОрдер.Перемещение Тогда //расчетные поля по ИД "ДокументПеремещения"

               
Попытка
                   
ДокументОбъект.ДокументПеремещения = Документы.ПеремещениеТоваров.ПолучитьСсылку(Новый УникальныйИдентификатор(ДокументXML.ДокументОснование));
                Исключение
                   
//в случае Ид указан не GUID это исключение. Нам необходимо собрать информацию о проблемных блоках.
               
КонецПопытки;

                Если Не
ЗначениеЗаполнено(ДокументОбъект.ДокументПеремещения) или ДокументОбъект.ДокументПеремещения.ПолучитьОбъект() = Неопределено Тогда

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

                КонецЕсли;

            КонецЕсли;

           
СтрокиБрак = Новый Массив;
           
ТабличнаяЧастьТовары = ДокументОбъект.Товары;
            Для каждого
ЭлементСтрокиСостава Из ДокументXML.Состав Цикл //-} Начало итерации по загружаемым строкам

               
СтрокаТабличнойЧасти = ТабличнаяЧастьТовары.Добавить();

                Попытка
                   
СтрокаТабличнойЧасти.Номенклатура = Справочники.Номенклатура.ПолучитьСсылку(Новый УникальныйИдентификатор(ЭлементСтрокиСостава.Номенклатура));
                Исключение
                   
//в случае Ид указан не GUID это исключение. Нам необходимо собрать информацию о проблемных блоках.
               
КонецПопытки;

                Если Не
ЗначениеЗаполнено(СтрокаТабличнойЧасти.Номенклатура) или СтрокаТабличнойЧасти.Номенклатура.ПолучитьОбъект() = Неопределено Тогда

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

                КонецЕсли;

               
//внешние обработчики
               
ОбработкаТабличныхЧастей.ПриИзмененииНоменклатурыТабЧасти(СтрокаТабличнойЧасти, ДокументОбъект);
               
ОбработкаТабличныхЧастей.ЗаполнитьЕдиницуТабЧасти(СтрокаТабличнойЧасти, ДокументОбъект);

               
СтрокаТабличнойЧасти.Склад      = Параметры.КодыСкладов.Получить(ДокументXML.Склад);
               
СтрокаТабличнойЧасти.Количество = Макс(ЭлементСтрокиСостава.Количество, ЭлементСтрокиСостава.КоличествоБрак);

                Если
ЗначениеЗаполнено(ЭлементСтрокиСостава.Характеристика) Тогда

                   
СтрокаТабличнойЧасти.ХарактеристикаНоменклатуры = Справочники.ХарактеристикиНоменклатуры.НайтиПоНаименованию(ЭлементСтрокиСостава.Характеристика, Истина, ,СтрокаТабличнойЧасти.Номенклатура);

                    Если Не
ЗначениеЗаполнено(СтрокаТабличнойЧасти.ХарактеристикаНоменклатуры) Тогда

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

                    КонецЕсли;

                КонецЕсли;

               
//заполним массив строк браком
               
Если ЗначениеЗаполнено(ЭлементСтрокиСостава.КоличествоБрак) Тогда

                   
СтрокаТабличнойЧасти.Качество = Справочники.Качество.Новый; //приходуем в таком случае всегда новый

                   
СтрокиБрак.Добавить(Новый Структура("Номенклатура, Количество, ХарактеристикаНоменклатуры, КачествоНовое",
                                           
СтрокаТабличнойЧасти.Номенклатура,
                                           
ЭлементСтрокиСостава.КоличествоБрак,
                                           
СтрокаТабличнойЧасти.ХарактеристикаНоменклатуры,
                                           
Параметры.КодыКачеств.Получить(ЭлементСтрокиСостава.Качество)));
                Иначе
                   
СтрокаТабличнойЧасти.Качество = Параметры.КодыКачеств.Получить(ЭлементСтрокиСостава.Качество); //проставляем только в случае не бракованого товара
               
КонецЕсли;

            КонецЦикла;
//{- Конец итерации по загружаемым строкам

           
Если Не ЕстьОшибкиКонтента Тогда //когда ошибок в файле нет, записываем и проводим документ

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

               
ДокументОбъект.ЗаполнитьТабличныеЧастиПередПроведениемУпр(); //" имитация кнопки формы Заполнить и провести (только без проведения)"
               
ДокументОбъект.Записать(); //еще раз запишем

               
ЗагруженоОбъектов = ЗагруженоОбъектов + 1;
               
СсылкаНаДокумент = ДокументОбъект.Ссылка;

               
ОписаниеИнформацииОбмена = "        Создан документ: "+СсылкаНаДокумент;
               
СтрокаТаблицыИнформации.Описание = ?(ПустаяСтрока(СтрокаТаблицыИнформации.Описание),"",СтрокаТаблицыИнформации.Описание+Символы.ПС)+ ОписаниеИнформацииОбмена;

               
//зафиксируем ключ поиска в регистре сведений
               
ЗарегистрироватьЗагружаемыйОбъект(СсылкаНаДокумент, ДокументXML.Номер);

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

               
КонецПопытки;

            Иначе
//удалеям файлы и переносим в каталог ошибок

               
ПереместитьФайлВКаталогОшибок(ЭлементСтруктуры.ФайлFTP, Параметры, СтрокаТаблицыИнформации);
               
УдалитьФайлы(ЭлементСтруктуры.ФайлЛокальный.ПолноеИмя);
                Продолжить;

            КонецЕсли;

           
//------------------------------------------------------------------
            //Создаем документ корректировки качества товара при наявности брака
           
Если СтрокиБрак.Количество() } 0 Тогда

               
ДокументОбъект = Документы.КорректировкаКачестваТоваров.СоздатьДокумент();
               
ДокументОбъект.Дата         = ДокументXML.Дата;
               
ДокументОбъект.Организация  = Параметры.Организация;
               
ДокументОбъект.Склад        = Параметры.КодыСкладов.Получить(ДокументXML.Склад);
               
ДокументОбъект.Комментарий  = "#Загружен автоматически - "+ТекущаяДата()+" из WMS-системы по файлу: "+ЭлементСтруктуры.ФайлFTP.ПолноеИмя;

               
ТабличнаяЧастьТовары = ДокументОбъект.Товары;
                Для каждого
ЭлементСтрокиСостава Из СтрокиБрак Цикл //-} Начало итерации по строкам брак

                   
СтрокаТабличнойЧасти = ТабличнаяЧастьТовары.Добавить();

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

                КонецЦикла;
//{- Конец итерации по строкам брак

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

               
КонецПопытки;

               
ОписаниеИнформацииОбмена = "        Создан документ: "+ДокументОбъект.Ссылка;
               
СтрокаТаблицыИнформации.Описание = ?(ПустаяСтрока(СтрокаТаблицыИнформации.Описание),"",СтрокаТаблицыИнформации.Описание+Символы.ПС)+ ОписаниеИнформацииОбмена;

            КонецЕсли;

        КонецЦикла;
//{-Конец итерации по создаваемым документам

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

       
ОписаниеИнформацииОбмена = "    {-Закончена обработка файла: "+ЭлементСтруктуры.ФайлFTP.ПолноеИмя;
       
СтрокаТаблицыИнформации.Описание = ?(ПустаяСтрока(СтрокаТаблицыИнформации.Описание),"",СтрокаТаблицыИнформации.Описание+Символы.ПС)+ ОписаниеИнформацииОбмена;

    КонецЦикла;
//{-Конец итерации найденных FTP-файлов

   
ПодготовитьИтоговуюИнформациюПоЗагрузке(СтрокаТаблицыИнформации, ЗагруженоОбъектов);

КонецПроцедуры

Процедура
ПереместитьФайлВКаталогОшибок(ФайлFTP, Параметры, СтрокаТаблицыИнформации)

   
ПредставлениеГод    = Формат(ТекущаяДата(),"ДФ=yyyy");
   
ПредставлениеМесяц  = Формат(ТекущаяДата(),"ДФ=MM");
   
ПредставлениеДень   = Формат(ТекущаяДата(),"ДФ=dd");
   
КаталогОшибок       = ФайлFTP.Путь+"error/"+ПредставлениеГод+"/"+ПредставлениеМесяц+"/"+ПредставлениеДень+"/";

   
КаталогFTP = ФайлFTP.Путь+"error";
   
МассивКаталога = Параметры.ТекущееFTPСоединение.НайтиФайлы(КаталогFTP);
    Если
МассивКаталога.Количество() = 0 Тогда
       
Параметры.ТекущееFTPСоединение.СоздатьКаталог(КаталогFTP);
    КонецЕсли;

   
КаталогFTP = ФайлFTP.Путь+"error/"+ПредставлениеГод;
   
МассивКаталога = Параметры.ТекущееFTPСоединение.НайтиФайлы(КаталогFTP);
    Если
МассивКаталога.Количество() = 0 Тогда
       
Параметры.ТекущееFTPСоединение.СоздатьКаталог(КаталогFTP);
    КонецЕсли;

   
КаталогFTP = ФайлFTP.Путь+"error/"+ПредставлениеГод+"/"+ПредставлениеМесяц;
   
МассивКаталога = Параметры.ТекущееFTPСоединение.НайтиФайлы(КаталогFTP);
    Если
МассивКаталога.Количество() = 0 Тогда
       
Параметры.ТекущееFTPСоединение.СоздатьКаталог(КаталогFTP);
    КонецЕсли;

   
КаталогFTP = ФайлFTP.Путь+"error/"+ПредставлениеГод+"/"+ПредставлениеМесяц+"/"+ПредставлениеДень;
   
МассивКаталога = Параметры.ТекущееFTPСоединение.НайтиФайлы(КаталогFTP);
    Если
МассивКаталога.Количество() = 0 Тогда
       
Параметры.ТекущееFTPСоединение.СоздатьКаталог(КаталогFTP);
    КонецЕсли;

   
//Параметры.ТекущееFTPСоединение.УстановитьТекущийКаталог(ФайлFTP.Путь);
   
Параметры.ТекущееFTPСоединение.Переместить(ФайлFTP.ПолноеИмя, КаталогОшибок+ФайлFTP.Имя);

    Если
ЗначениеЗаполнено(СтрокаТаблицыИнформации.Описание) Тогда

       
ОписаниеОшибок = Новый ТекстовыйДокумент;
       
ОписаниеОшибок.ДобавитьСтроку(СтрокаТаблицыИнформации.Описание);
       
ОписаниеОшибок.Записать(Параметры.КаталогЗагрузки+"\"+ФайлFTP.ИмяБезРасширения+".err");

       
Параметры.ТекущееFTPСоединение.Записать(Параметры.КаталогЗагрузки+"\"+ФайлFTP.ИмяБезРасширения+".err", КаталогОшибок+ФайлFTP.ИмяБезРасширения+".err");
       
УдалитьФайлы(Параметры.КаталогЗагрузки+"\"+ФайлFTP.ИмяБезРасширения+".err");

    КонецЕсли;

   
ДеталиОшибки = "    {-Файл перемещен в каталог ошибок: "+КаталогОшибок+ФайлFTP.Имя;
   
СтрокаТаблицыИнформации.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Ошибка;
   
СтрокаТаблицыИнформации.Описание = ?(ПустаяСтрока(СтрокаТаблицыИнформации.Описание),"",СтрокаТаблицыИнформации.Описание+Символы.ПС)+ ДеталиОшибки;

КонецПроцедуры

Процедура
ПереместитьФайлВКаталогУспешнойЗагрузки(ФайлFTP, Параметры, СтрокаТаблицыИнформации)

   
ПредставлениеГод    = Формат(ТекущаяДата(),"ДФ=yyyy");
   
ПредставлениеМесяц  = Формат(ТекущаяДата(),"ДФ=MM");
   
ПредставлениеДень   = Формат(ТекущаяДата(),"ДФ=dd");
   
КаталогЗагрузки     = ФайлFTP.Путь+"loaded/"+ПредставлениеГод+"/"+ПредставлениеМесяц+"/"+ПредставлениеДень+"/";

   
КаталогFTP = ФайлFTP.Путь+"loaded";
   
МассивКаталога = Параметры.ТекущееFTPСоединение.НайтиФайлы(КаталогFTP);
    Если
МассивКаталога.Количество() = 0 Тогда
       
Параметры.ТекущееFTPСоединение.СоздатьКаталог(КаталогFTP);
    КонецЕсли;

   
КаталогFTP = ФайлFTP.Путь+"loaded/"+ПредставлениеГод;
   
МассивКаталога = Параметры.ТекущееFTPСоединение.НайтиФайлы(КаталогFTP);
    Если
МассивКаталога.Количество() = 0 Тогда
       
Параметры.ТекущееFTPСоединение.СоздатьКаталог(КаталогFTP);
    КонецЕсли;

   
КаталогFTP = ФайлFTP.Путь+"loaded/"+ПредставлениеГод+"/"+ПредставлениеМесяц;
   
МассивКаталога = Параметры.ТекущееFTPСоединение.НайтиФайлы(КаталогFTP);
    Если
МассивКаталога.Количество() = 0 Тогда
       
Параметры.ТекущееFTPСоединение.СоздатьКаталог(КаталогFTP);
    КонецЕсли;

   
КаталогFTP = ФайлFTP.Путь+"loaded/"+ПредставлениеГод+"/"+ПредставлениеМесяц+"/"+ПредставлениеДень;
   
МассивКаталога = Параметры.ТекущееFTPСоединение.НайтиФайлы(КаталогFTP);
    Если
МассивКаталога.Количество() = 0 Тогда
       
Параметры.ТекущееFTPСоединение.СоздатьКаталог(КаталогFTP);
    КонецЕсли;

   
//Параметры.ТекущееFTPСоединение.УстановитьТекущийКаталог(ФайлFTP.Путь);
   
Параметры.ТекущееFTPСоединение.Переместить(ФайлFTP.ПолноеИмя, КаталогЗагрузки+ФайлFTP.Имя);

   
ОписаниеУспешнойИнформации = "  {-Файл перемещен в каталог успешной загрузки: "+КаталогЗагрузки+ФайлFTP.Имя;
   
СтрокаТаблицыИнформации.Описание = ?(ПустаяСтрока(СтрокаТаблицыИнформации.Описание),"",СтрокаТаблицыИнформации.Описание+Символы.ПС)+ ОписаниеУспешнойИнформации;

КонецПроцедуры

Функция
МассивВСтроку(МассивЗначений)

   
Результат = "";
    Для Каждого
Значение Из МассивЗначений Цикл

       
Результат = ?(ПустаяСтрока(Результат), Значение, Результат+"\"+Значение);

    КонецЦикла;

    Возврат
Результат;

КонецФункции


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

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