Группа: Пользователи
Сообщений: 51
Спасибо сказали: 0 раз
Рейтинг: 0
Добрый день. Подскажите пожалуйста как решить мою проблему. Есть сайт на OpenCart, есть подключенный к нему модуль OpenCart Exchange 1C . Модуль на сайте настроен. Обмен с сайтом настроен. Всё выгружается, НО, есть одно но. На сайт выгружается цена в долларах. А нужно чтобы выгружалась в грн. Для примера показываю на картинке что конкретно я имею ввиду:
Каким образом настроить так, чтобы выгружалась нужная цена? Я облазил уже весь модуль "Обмена с сайтом".
Группа: Пользователи
Сообщений: 51
Спасибо сказали: 0 раз
Рейтинг: 0
Он слишком большой. Меня админы будут бить если я его добавлю)))) Один раз уже предупреждали. А функции раскрывающегося списка я здесь не нашёл. Как быть? кинуть весь модуль?
Группа: Основатель
Сообщений: 13982
Из: Киев
Спасибо сказали: 4549 раз
Рейтинг: 3678.1
Цитата(r1p88@mail.ru @ 10.11.14, 13:40)
Он слишком большой. Меня админы будут бить если я его добавлю)))) Один раз уже предупреждали.
r1p88@mail.ru, я боюсь, что выложенный полностью модуль вряд ли чем поможет.
Цитата(r1p88@mail.ru @ 10.11.14, 13:40)
А функции раскрывающегося списка я здесь не нашёл. Как быть? кинуть весь модуль?
Когда пишете ответ слева под смайликами есть блок "Теги", в котором присутствует "Спрятать". Если оно всё влезет в "Спрятать" - размещайте. Но повторюсь, что по моему лично мнению 100 000 строк кода в виде текста на форуме делу врядли помогут.
Группа: Пользователи
Сообщений: 51
Спасибо сказали: 0 раз
Рейтинг: 0
Цитата(Vofka @ 10.11.14, 15:21)
r1p88@mail.ru, я боюсь, что выложенный полностью модуль вряд ли чем поможет.
Я тогда выложу часть кода, который был вставлен в стандартный модуль обмена с сайтом и если нужно выложить ещё какую нибудь часть когда, напишите какую выложу. Код, который был вставлен:
// Передаем значение валюты выбраной цены в переменную - ТекТипЦены ТекТипЦены = ПостроительЗапроса.Отбор.ТипЦен.Значение.ВалютаЦены.Ссылка;
//Мой код для конвертации цены номенклатуры, в валюту цены, выбранной в отборе Если ТекТипЦены <> Неопределено Тогда
Если СтрокаЦены.Валюта <> ТекТипЦены Тогда НовЦена = Ценообразование.ПересчитатьЦенуПриИзмененииВалюты(СтрокаЦены.Цена,СтрокаЦены.Валюта,ТекТипЦены); СтрокаЦены.Цена = НовЦена; СтрокаЦены.Валюта = ТекТипЦены; КонецЕсли;
КонецЕсли; //Конец кода
С этим добавленным кодом выдаёт ошибку "Поле обьекта ВалютаЦены не найдено". В настройках модуля обмена в отборе я указал поле "ТипЦен-Валюта Цены по умолчанию" и значение поставил ГРН. Если не использовать этот кусок кода, а использовать стандартный модуль обмена с сайтом, то происходит, то что я писал в первом сообщении.
СтрокаСообщенияПользователю = ""; Успешно = ПроцедурыОбменаССайтом.HTTPВыполнитьАвторизациюДляСоединения(Соединение, СтруктураПараметровСайта, ОтветСервера, СтрокаСообщенияПользователю, ТипСоединения); Если Не ПустаяСтрока(СтрокаСообщенияПользователю) Тогда СообщитьОбОшибкеОбмена(СтрокаСообщенияПользователю, Ложь); КонецЕсли;
ОтобразитьСостояние("Загрузка данных с сервера...");
ИнформацияДляПользователя = ""; ОтветСервера = ПроцедурыОбменаССайтом.HTTPПолучитьДанныеССервера(Соединение, АдресДляРаботы + ПараметрЗапросаHTTP_ПолучитьДанные, ЗаголовкиЗапросов, ИнформацияДляПользователя); Если Не ПустаяСтрока(ИнформацияДляПользователя) Тогда СообщитьПользователю(ИнформацияДляПользователя, Ложь); КонецЕсли;
Если ОтветСервера = Неопределено Тогда СообщитьОбОшибкеОбмена("Не удалось загрузить данные с сервера.", Ложь); Возврат Ложь; КонецЕсли;
СтрокаCML = "";
Если Лев(ОтветСервера, 2) = "PK" Тогда СтрокаCML = РаспаковатьZIPАрхив(ОтветСервера); Иначе Если Лев(ОтветСервера, 5) = "<?xml" Тогда СтрокаCML = ОтветСервера; КонецЕсли; КонецЕсли;
Если НЕ ЗначениеЗаполнено(СтрокаCML) Тогда СообщитьОбОшибкеОбмена("Не удалось прочитать данные, загруженные с сервера.", Ложь); Возврат Ложь; КонецЕсли;
ДеревоДокументов = РазобратьCML(СтрокаCML);
Если ДеревоДокументов = Неопределено Тогда СообщитьОбОшибкеОбмена("Не удалось разобрать данные, загруженные с сервера.", Ложь); Возврат Ложь; КонецЕсли;
Успешно = ОбработатьДокументы(ДеревоДокументов, КоличествоОбработанныхДокументов);
Если НЕ Успешно Тогда СообщитьОбОшибкеОбмена("Не удалось обработать документы, загруженные с сервера.", Ложь); Возврат Ложь; КонецЕсли;
ИнформацияДляПользователя = ""; ПроцедурыОбменаССайтом.HTTPПолучитьДанныеССервера(Соединение, АдресДляРаботы + ПараметрЗапросаHTTP_УспешноеЗавершениеИмпорта, ЗаголовкиЗапросов, ИнформацияДляПользователя); Если Не ПустаяСтрока(ИнформацияДляПользователя) Тогда СообщитьПользователю(ИнформацияДляПользователя, Ложь); КонецЕсли;
СтрокаСообщенияПользователю = ""; Успешно = ПроцедурыОбменаССайтом.HTTPВыполнитьАвторизациюДляСоединения(Соединение, СтруктураПараметровСайта, ОтветСервера, СтрокаСообщенияПользователю, ТипСоединения); Если Не ПустаяСтрока(СтрокаСообщенияПользователю) Тогда СообщитьОбОшибкеОбмена(СтрокаСообщенияПользователю, Истина); КонецЕсли;
Если СтрЧислоСтрок(ОтветСервера) <> 2 тогда СообщитьОбОшибкеОбмена("Не удалось прочитать ответ сервера. Параметры обмена не получены.", Истина); Возврат Ложь; КонецЕсли;
Если ZIPФайлыРазрешены Тогда ОтобразитьСостояние("Подготовка ZIP-архива..."); СписокФайловДляОтправки = ПодготовитьZIPАрхивы(СписокФайловДляОтправки, КаталогОбмена); КонецЕсли;
Если ОграничениеРазмераФрагментаФайлаОбмена > 0 Тогда СписокФайловДляОтправки = РазделитьФайлыНаФрагменты(СписокФайловДляОтправки, ОграничениеРазмераФрагментаФайлаОбмена); КонецЕсли;
Если ZIPФайлыРазрешены Тогда Попытка УдалитьФайлы(ТекФайл.Значение); Исключение КонецПопытки; КонецЕсли;
Если ОтветСервера = Неопределено Тогда СообщитьОбОшибкеОбмена("Не удалось получить ответ сервера. Файл не отправлен (" + ТекФайл.Значение + ").", Истина); Возврат Ложь; КонецЕсли;
Если СостояниеОбмена = ОтветСервера_АварийноеЗавершениеТекущейОперации Тогда
СообщитьОбОшибкеОбмена("Произошла ошибка на стороне сервера. Файл не отправлен (" + ТекФайл.Значение + ").", Истина); СообщитьРасширенноеОписаниеОтветаСервера(ОтветСервера); Возврат Ложь;
ИначеЕсли СостояниеОбмена = ОтветСервера_УспешноеЗавершениеТекущейОперации Тогда
Если СтрЧислоСтрок(ОтветСервера) > 1 Тогда СообщитьПользователю("Получен расширенный статус успешного завершения сеанса", Истина, СтатусСообщения.Информация); СообщитьРасширенноеОписаниеОтветаСервера(ОтветСервера); КонецЕсли;
Иначе
СообщитьОбОшибкеОбмена("Произошла ошибка на стороне сервера. Не получен статус завершения операции. Файл не отправлен (" + ТекФайл.Значение + ").", Истина); СообщитьРасширенноеОписаниеОтветаСервера(ОтветСервера); Возврат Ложь;
КонецЕсли;
КонецЦикла;
ИмпортУспешноЗавершен = Ложь;
Если ОжидатьЗавершенияИмпортаФайловСервером Тогда
Для Каждого ТекФайл Из МассивИсходныхCMLФайлов Цикл
Успешно = Ложь; СообщитьОбОшибкеОбмена("Не удалось получить текущее состояние процесса обмена. Данные обмена отправлены, но не загружены.", Истина);
ИначеЕсли СтрЧислоСтрок(ОтветСервера) = 0 Тогда Успешно = Ложь; СообщитьОбОшибкеОбмена("Не удалось прочитать данные о текущем состоянии процесса обмена. Данные обмена отправлены, но не загружены.", Истина); Иначе
СостояниеОбмена = НРег(СтрПолучитьСтроку(ОтветСервера,1)); Если СостояниеОбмена = ОтветСервера_АварийноеЗавершениеТекущейОперации Тогда Успешно = Ложь; СообщитьОбОшибкеОбмена("Произошла ошибка на стороне сервера.", Истина); СообщитьРасширенноеОписаниеОтветаСервера(ОтветСервера); ИначеЕсли СостояниеОбмена = ОтветСервера_УспешноеЗавершениеТекущейОперации Тогда ИмпортУспешноЗавершен = Истина; ИначеЕсли СостояниеОбмена = ОтветСервера_ВыполнениеТекущейОперации Тогда ТекущееСостояние = ТекущееСостояние + СтрПолучитьСтроку(ОтветСервера, 2); ИмпортПродолжается = Истина; Иначе Успешно = Ложь; СообщитьОбОшибкеОбмена("Произошла ошибка на стороне сервера. Получен неизвестный статус импорта.", Истина); СообщитьРасширенноеОписаниеОтветаСервера(ОтветСервера); КонецЕсли;
КонецЕсли;
КонецЦикла; //Импорт
Если НЕ ИмпортУспешноЗавершен Тогда Прервать; КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат Успешно;
КонецФункции
Функция HTTPОтправитьФайлНаСервер(ПолноеИмяФайла, Соединение, ПараметрыЗапроса="", Заголовки="")
Попытка Соединение.ОтправитьДляОбработки(ПолноеИмяФайла, СокрЛП(ПараметрыЗапроса), ИмяФайлаОтвета, СокрЛП(Заголовки)); Исключение СообщитьОбИсключительнойОшибке(Истина, ОписаниеОшибки()); КонецПопытки;
ФайлОтвета = Новый Файл(ИмяФайлаОтвета);
Если ФайлОтвета.Существует() Тогда
ТекстОтвета = Новый ТекстовыйДокумент(); ТекстОтвета.Прочитать(ИмяФайлаОтвета); Если ТекстОтвета.КоличествоСтрок()>0 Тогда ОтветСервера = ТекстОтвета.ПолучитьТекст(); Иначе СообщитьПользователю("Отправка файла на сервер: Получен пустой ответ сервера.", Истина); КонецЕсли;
Иначе СообщитьПользователю("Отправка файла на сервер: Ответ сервера не получен.", Истина); КонецЕсли;
Попытка УдалитьФайлы(КаталогВременныхФайлов(), ИмяФайлаОтвета); Исключение КонецПопытки;
Для Каждого Элемент Из СписокЗначений Цикл Если Элемент.Представление = КонецЭлементаCML Тогда ОбъектCML.ЗаписатьКонецЭлемента(); ИначеЕсли Элемент.Представление = НачалоЭлементаCML Тогда ОбъектCML.ЗаписатьНачалоЭлемента(Элемент.Значение); ИначеЕсли Элемент.Представление = "" Тогда ОбъектCML.ЗаписатьТекст(Элемент.Значение); ИначеЕсли Найти(Элемент.Представление, ПрефиксУзлаCML) > 0 Тогда ИмяУзла = СтрЗаменить(Элемент.Представление, ПрефиксУзлаCML, ""); ЗаписатьТекстовойУзел(ОбъектCML, ИмяУзла, Элемент.Значение); ИначеЕсли Найти(Элемент.Представление, ПрефиксАтрибутаCML) > 0 Тогда ИмяАтрибута = СтрЗаменить(Элемент.Представление, ПрефиксАтрибутаCML, ""); ОбъектCML.ЗаписатьАтрибут(ИмяАтрибута, Элемент.Значение); КонецЕсли; КонецЦикла;
Для Каждого СтрокаХарактеристикаСвойство Из Товар.Строки Цикл ДобавитьНачалоЭлементаCML(СписокЗначенийCML, "ХарактеристикаТовара"); ДобавитьУзелCML(СписокЗначенийCML, "Наименование", ФорматНаименованияДляCML(СтрокаХарактеристикаСвойство.ХарактеристикаСвойство)); ДобавитьУзелCML(СписокЗначенийCML, "Значение" , СтрокаХарактеристикаСвойство.ХарактеристикаЗначениеСвойства); ДобавитьКонецЭлементаCML(СписокЗначенийCML); КонецЦикла;
// картинки нет вообще ДобавитьНачалоЭлементаCML(СписокЗначенийCML, "Картинка"); ДобавитьКонецЭлементаCML(СписокЗначенийCML);
КонецЕсли;
КонецЕсли;
СписокЗначенийСвойств = Новый СписокЗначений; Для Каждого СтрокаХарактеристикаСвойство Из Товар.Строки Цикл Для Каждого СтрокаСвойствоНоменклатуры Из СтрокаХарактеристикаСвойство.Строки Цикл Если ЗначениеЗаполнено(СтрокаСвойствоНоменклатуры.СвойствоНоменклатуры) И СписокЗначенийСвойств.НайтиПоЗначению(СтрокаСвойствоНоменклатуры.СвойствоНоменклатуры) = Неопределено Тогда
Если СписокЗначенийСвойств.Количество() > 0 Тогда ДобавитьНачалоЭлементаCML(СписокЗначенийCML, "ЗначенияСвойств"); Для Каждого ЗначениеСвойства Из СписокЗначенийСвойств Цикл
СтатусУдаления = ""; Если Товар.НоменклатураСсылка.ПометкаУдаления ИЛИ Товар.ХарактеристикаСсылка.ПометкаУдаления Тогда СтатусУдаления = "Удален"; КонецЕсли;
ТаблицаЦен = Новый ТаблицаЗначений; ТаблицаЦен.Колонки.Добавить("ТипЦен"); ТаблицаЦен.Колонки.Добавить("Валюта"); ТаблицаЦен.Колонки.Добавить("Цена"); ТаблицаЦен.Колонки.Добавить("ЕдиницаИзмеренияЦены");
Для Каждого СтрокаСвойствоХарактеристики Из Товар.Строки Цикл Для Каждого СтрокаСвойствоНоменклатуры Из СтрокаСвойствоХарактеристики.Строки Цикл Для Каждого СтрокаТипаЦен Из СтрокаСвойствоНоменклатуры.Строки Цикл Если НЕ СтрокаТипаЦен.ТипЦен = NULL Тогда НовСтрока = ТаблицаЦен.Добавить(); ЗаполнитьЗначенияСвойств(НовСтрока, СтрокаТипаЦен); КонецЕсли; КонецЦикла;
// Забираем из первой ветки, // а дальше цены дублируются
Если СтрокаДерева.Строки.Количество() > 0 Тогда ВыгрузитьГруппыРекурсивно(ОбъектCML, СтрокаДерева.Строки); КонецЕсли; ОбъектCML.ЗаписатьКонецЭлемента();
КонецЦикла;
Если НужноВыгружатьГруппы Тогда ОбъектCML.ЗаписатьКонецЭлемента(); КонецЕсли;
Если ТЧУслуги Тогда ИдТовара = СформироватьИдентификаторТовара(СтрокаТЧ.Номенклатура); Иначе ИдТовара = СформироватьИдентификаторТовара(СтрокаТЧ.Номенклатура, СтрокаТЧ.ХарактеристикаНоменклатуры); КонецЕсли;
Запрос.УстановитьПараметр("Объект", СтрокаТЧ.ХарактеристикаНоменклатуры); РезультатЗапроса = Запрос.Выполнить(); Если НЕ РезультатЗапроса.Пустой() Тогда
Функция СформироватьИдентификаторТовара(Номенклатура, Характеристика = Неопределено)
Если Характеристика = Неопределено ИЛИ Характеристика = ПустаяХарактеристикаСсылка Тогда Возврат Строка(Номенклатура.УникальныйИдентификатор()); Иначе Возврат Строка(Номенклатура.УникальныйИдентификатор()) + "#" + Строка(Характеристика.УникальныйИдентификатор()); КонецЕсли;
КонецФункции
Функция ВыгрузитьКартинку(Номенклатура, КаталогНаДиске)
СтруктураРезультата = Новый Структура; СтруктураРезультата.Вставить("Адрес", ""); СтруктураРезультата.Вставить("Размер", "0");
Картинка = Номенклатура.ОсновноеИзображение.Хранилище.Получить(); Если ТипЗнч(Картинка) <> Тип("Картинка") Тогда Возврат СтруктураРезультата; КонецЕсли;
ФорматКартинкиОбъекта = Картинка.Формат(); Если ФорматКартинкиОбъекта = ФорматКартинки.НеизвестныйФормат Тогда ФорматКартинкиРазрешен = Ложь; Иначе Если НЕ (ФорматКартинкиОбъекта = ФорматКартинки.GIF ИЛИ ФорматКартинкиОбъекта = ФорматКартинки.JPEG ИЛИ ФорматКартинкиОбъекта = ФорматКартинки.PNG) Тогда Попытка ФорматКартинкиОбъекта = Картинка.Преобразовать(ФорматКартинки.JPEG); Исключение СообщитьОбИсключительнойОшибке(Истина, "Не удалось преобразовать формат картинки. Номенклатура: " + Номенклатура + ". Преобразование из " + Строка(ФорматКартинкиОбъекта) + " в JPEG"); Возврат СтруктураРезультата; КонецПопытки; КонецЕсли; РасширениеФайлаКартинки = Строка(ФорматКартинкиОбъекта); КонецЕсли;
#Иначе // СЕРВЕР
// На сервере проверка формата файла по сигнатуре файла: // JPEG: FF D8 xx xx xx xx 4A 46 49 46 00 // GIF: 47 49 46 // PNG: 89 50 4e 47 0d 0a 1a 0a // // -1 - значит байт игнорируется. // Код должен быть не более 127(dec) для совместимости Unicode-ASCII
МаксДлинаСигнатуры = 0; Для каждого Сигнатура Из РазрешенныеСигнатуры Цикл ДлинаСигнатуры = Сигнатура.Значение.Количество(); Если МаксДлинаСигнатуры < ДлинаСигнатуры Тогда МаксДлинаСигнатуры = ДлинаСигнатуры; КонецЕсли; КонецЦикла;
ИмяВремФайла = ПолучитьИмяВременногоФайла(); Попытка Картинка.Записать(ИмяВремФайла); Исключение СообщитьОбИсключительнойОшибке(Истина, "Не удалось записать файл " + ИмяВремФайла + " для определения формата картинки. Номенклатура: " + Номенклатура); Возврат СтруктураРезультата; КонецПопытки;
ТекстФайлКартинки = Новый ЧтениеТекста; Попытка ТекстФайлКартинки.Открыть(ИмяВремФайла,,,Символы.ПС); Исключение СообщитьОбИсключительнойОшибке(Истина, "Не удалось прочитать файл " + ИмяВремФайла + " для определения формата картинки. Номенклатура: " + Номенклатура); Возврат СтруктураРезультата; КонецПопытки;
Если ТекстКартинки = "" Тогда СообщитьПользователю("Не удалось получить сигнатуру файла картинки. Номенклатура: " + Номенклатура, Истина, СтатусСообщения.Информация); Возврат СтруктураРезультата; КонецЕсли;
ФорматКартинкиРазрешен = Ложь;
Для каждого Сигнатура Из РазрешенныеСигнатуры Цикл
Для Сч = 1 По ДлинаСигнатуры Цикл ТекБайтСигнатуры = Сигнатура.Значение[Сч - 1]; Если ТекБайтСигнатуры = -1 Тогда Продолжить; КонецЕсли; ТекБайтФайла = КодСимвола(ТекстКартинки, Сч); Если НЕ ТекБайтСигнатуры = ТекБайтФайла Тогда СигнатураРаспознана = Ложь; Прервать; КонецЕсли; КонецЦикла;
Если СигнатураРаспознана Тогда ФорматКартинкиРазрешен = Истина; РасширениеФайлаКартинки = Сигнатура.Ключ; Прервать; КонецЕсли;
КонецЦикла;
#КонецЕсли
Если НЕ ФорматКартинкиРазрешен Тогда СообщитьПользователю("Формат основного изображения неизвестен или запрещен. Номенклатура: " + Номенклатура, Истина, СтатусСообщения.Информация); Возврат СтруктураРезультата; КонецЕсли;
ДобавитьНовоеЗначениеРеквизита(ОбъектCML, "Номер по 1С", Док.Номер); ДобавитьНовоеЗначениеРеквизита(ОбъектCML, "Дата по 1С", ФорматДатыДляCML(Док.Дата)); ДобавитьНовоеЗначениеРеквизита(ОбъектCML, "ПометкаУдаления", Док.ПометкаУдаления); ДобавитьНовоеЗначениеРеквизита(ОбъектCML, "Проведен", Док.Проведен);
Если СтрокаТД.Оплачен ИЛИ СтрокаТД.Отгружен Тогда
Если СтрокаТД.Оплачен Тогда ДобавитьНовоеЗначениеРеквизита(ОбъектCML, "Номер оплаты по 1С", СтрокаТД.НомерОплаты); ДобавитьНовоеЗначениеРеквизита(ОбъектCML, "Дата оплаты по 1С", ФорматДатыДляCML(СтрокаТД.ДатаОплаты, Истина, Истина)); КонецЕсли;
Если СтрокаТД.Отгружен Тогда ДобавитьНовоеЗначениеРеквизита(ОбъектCML, "Номер отгрузки по 1С", СтрокаТД.НомерОтгрузки); ДобавитьНовоеЗначениеРеквизита(ОбъектCML, "Дата отгрузки по 1С", ФорматДатыДляCML(СтрокаТД.ДатаОтгрузки, Истина, Истина)); КонецЕсли;
Если ВернутьДату И ВернутьВремя Тогда Результат = ДатаСтрока + "T" + ВремяСтрока; ИначеЕсли ВернутьДату И (НЕ ВернутьВремя) Тогда Результат = ДатаСтрока; ИначеЕсли (НЕ ВернутьДату) И ВернутьВремя Тогда Результат = ВремяСтрока; КонецЕсли;
Возврат Результат;
КонецФункции
//////////////////////////////////////////////////////////////////////////////// // СЕРВИСНЫЕ ПРОЦЕДУРЫ И ФУНКЦИИ
//////////////////////////////////////////////////////////////////////////////// // ПРОЦЕДУРЫ УПРАВЛЕНИЯ ВЫГРУЗКОЙ ДАННЫХ Процедура ВыгрузитьДанные() Экспорт
СообщитьПользователю("Выгрузка товаров не произведена.", Истина); Возврат Истина;
КонецЕсли;
HTTPОбменАдресСкрипта = НачалоАдресаСкрипта;
Если ПустаяСтрока(КаталогВыгрузки) Тогда КаталогВыгрузки = КаталогВременныхФайлов(); Иначе ПоследнийСимвол = Сред(КаталогВыгрузки, СтрДлина(КаталогВыгрузки), 1); Если ПоследнийСимвол <> "\" Тогда КаталогВыгрузки = КаталогВыгрузки + "\"; КонецЕсли; КонецЕсли;
ВыбранныеСвойства = ТабСвойств.ВыгрузитьКолонку("СвойствоНоменклатуры"); ЭлементNULL = ВыбранныеСвойства.Найти(NULL); Если ЭлементNULL <> Неопределено Тогда ВыбранныеСвойства.Удалить(ЭлементNULL); КонецЕсли;
ТабСвойств = Неопределено;
// требуетя неизменный UUID каталога для проекта. // По организации взять UUID не можем, поскольку не ограничиваем // выгрузку рамками одной организации, выгружаем по предприятию в целом. // Поэтому, чтобы нигде не хранить UUID, получаем его из валюты // регламентированного учета, считая ее самой "стабильной" единицей // данных в рамках ИБ.
Если КоличествоОбработанныхДокументовНаЗагрузке + КоличествоОбработанныхДокументовНаВыгрузке > 0 Тогда СообщитьПользователю("Обмен заказами успешно завершен", Истина); КонецЕсли;
Иначе СообщитьПользователю("Обмен заказами завершен с ошибками!!!", Истина); КонецЕсли;
Возврат Успешно;
КонецФункции
Функция ВыгрузитьЗаказыНаСайт(СтруктураИзменений, СтруктураПараметровСайта, КоличествоОбработанныхДокументовНаВыгрузке)
Успешно = ОбработатьДокументы(ДеревоДокументов, КоличествоОбработанныхДокументов); Если НЕ Успешно Тогда СообщитьОбОшибкеОбмена("Не удалось обработать документы, загруженные из файла.", Ложь); КонецЕсли;
ФайлCMLНаДиске = Новый ТекстовыйДокумент; ФайлCMLНаДиске.УстановитьТекст(ОбъектCMLСтрока);
Попытка ФайлCMLНаДиске.Записать(ПолноеИмяФайлаОбмена); Исключение СообщитьОбИсключительнойОшибке(Истина, "Не удалось записать CML файл на диск."); Возврат Ложь; КонецПопытки;
Если ВыгружатьНаСайт Тогда Возврат ЕстьСайт И ЕстьОрганизация И ЕстьПараметрыИдентификации И ЕстьЕдиницаИзмерения; Иначе Возврат ЕстьФайлЗагрузки; КонецЕсли;
КонецФункции
//////////////////////////////////////////////////////////////////////////////// // ВСПОМОГАТЕЛЬНЫЕ ПРОЦЕДУРЫ И ФУНКЦИИ ОБРАБОТКИ ФАЙЛОВ
Если РаспакованныеФайлы.Количество() = 1 Тогда СтрокаИзФайла = Новый ТекстовыйДокумент; СтрокаИзФайла.Прочитать(РаспакованныеФайлы[0].ПолноеИмя); СтрокаСодержимого = СтрокаИзФайла.ПолучитьТекст(); КонецЕсли;
Попытка УдалитьФайлы(ИмяФайла); УдалитьФайлы(ИмяКаталога); Исключение КонецПопытки;
Возврат СтрокаСодержимого;
КонецФункции
Функция РазделитьФайлыНаФрагменты(СписокФайлов, ОграничениеРазмераФрагмента)
НовыйСписокФайлов = Новый СписокЗначений; Для Каждого ТекФайл Из СписокФайлов цикл
ФайлНаДиске = Новый Файл(ТекФайл.Значение); Если ФайлНаДиске.Размер() > ОграничениеРазмераФрагмента Тогда МассивФрагментов = РазделитьФайл(ФайлНаДиске.ПолноеИмя, ОграничениеРазмераФрагмента); Для Каждого НовыйФайл Из МассивФрагментов Цикл НовыйСписокФайлов.Добавить(НовыйФайл, ТекФайл.Представление); КонецЦикла; УдалитьФайлы(ФайлНаДиске.ПолноеИмя); Иначе НовыйСписокФайлов.Добавить(ТекФайл.Значение, ТекФайл.Представление); КонецЕсли;
КонецЦикла; Возврат НовыйСписокФайлов;
КонецФункции
Функция ПодготовитьZIPАрхивы(СписокФайлов, КаталогОбмена)
ПолноеИмяФайлаАрхива = ПолучитьИмяВременногоФайла("zip"); ЗаписьАрхива = Новый ЗаписьZipФайла(ПолноеИмяФайлаАрхива);
КоличествоЭлементов = СтрЧислоСтрок(ПромТекст); Для Счетчик = 1 По КоличествоЭлементов Цикл ИмяФайла = СтрПолучитьСтроку(ПромТекст, Счетчик); КонецЦикла;
Возврат ИмяФайла;
КонецФункции
Функция ПодготовитьИмяФайлаДляСервера(ФайлОбъект, КаталогОбмена)
ПолноеИмяФайлаДляСервера = "";
Если Найти(ФайлОбъект.Имя, ".xml") > 0 Тогда ПолноеИмяФайлаДляСервера = ФайлОбъект.Имя; Иначе //у картинки надо оставить 2 папки и развернуть слэши ПолноеИмяФайлаДляСервера = ФайлОбъект.ПолноеИмя; ПутьДляУдаления = КаталогОбмена + "\"; ПолноеИмяФайлаДляСервера = СтрЗаменить(ПолноеИмяФайлаДляСервера, ПутьДляУдаления, ""); ПолноеИмяФайлаДляСервера = СтрЗаменить(ПолноеИмяФайлаДляСервера, "\", "/"); КонецЕсли;
ФайлыВПодкаталоге = НайтиФайлы(КаталогОбмена + "\" + Подкаталог, Маска); Для Каждого ТекФайл Из ФайлыВПодкаталоге Цикл
Если ТекФайл.ЭтоКаталог() Тогда
ФайлыВДобавочномПодкаталоге = НайтиФайлы(ТекФайл.ПолноеИмя, Маска); Для Каждого ТекФайлВПодкаталоге Из ФайлыВДобавочномПодкаталоге Цикл
Если НЕ ТекФайлВПодкаталоге.ЭтоКаталог() Тогда ВсеФайлыДляВыгрузки.Добавить(ТекФайлВПодкаталоге); КонецЕсли;
КонецЦикла;
Иначе ВсеФайлыДляВыгрузки.Добавить(ТекФайл); КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецЕсли;
Для Каждого ТекФайл Из ВсеФайлыДляВыгрузки цикл
Если НЕ ТекФайл.ЭтоКаталог() Тогда ПолноеИмяФайлаДляСервера = ПодготовитьИмяФайлаДляСервера(ТекФайл, КаталогОбмена); СписокФайлов.Добавить(ТекФайл.ПолноеИмя, ПолноеИмяФайлаДляСервера); КонецЕсли;
КонецЦикла;
Возврат СписокФайлов;
КонецФункции
//////////////////////////////////////////////////////////////////////////////// // ПРОЦЕДУРЫ И ФУНКЦИИ ОПИСАНИЯ И ВЫВОДА ОШИБОК И СООБЩЕНИЙ
Функция ПолучитьСтруктуруИнформацииДляИстории()
СтруктураДляИстории = Новый Структура("ДатаПоследнейЗагрузки,ДатаПоследнейВыгрузки,ДатаНачалаПоследнейЗагрузки, |ДатаНачалаПоследнейВыгрузки,РезультатПоследнейЗагрузки,РезультатПоследнейВыгрузки, |КомментарийКЗагрузкеДанных,КомментарийКВыгрузкеДанных");
Процедура СообщитьПользователю(ТекстСообщения, ИнформацияОВыгрузке, Статус = Неопределено)
Если ИнформацияОВыгрузке Тогда ДобавитьТекстКСообщениюДляПользователя(мСтруктураИнформацииИсторииОбмена.КомментарийКВыгрузкеДанных, ТекстСообщения); Иначе ДобавитьТекстКСообщениюДляПользователя(мСтруктураИнформацииИсторииОбмена.КомментарийКЗагрузкеДанных, ТекстСообщения); КонецЕсли;
#Если Клиент Тогда Если Статус = Неопределено Тогда Статус = СтатусСообщения.Обычное; КонецЕсли; Сообщить(ТекстСообщения, Статус); #КонецЕсли
КонецПроцедуры
// Процедура выводит текст ответа сервера, если в нем имеется // расширенное описание ошибки (строки, начиная со 2-й) // // Параметры: // ОтветСервера - строка, текст ответа сервера // Процедура СообщитьРасширенноеОписаниеОтветаСервера(ОтветСервера)
ТекстСообщения = "Ответ сервера:" + Символы.ПС;
Если СтрЧислоСтрок(ОтветСервера) > 1 Тогда Для ТекСтрока = 2 по СтрЧислоСтрок(ОтветСервера) Цикл ТекстСообщения = ТекстСообщения + СтрПолучитьСтроку(ОтветСервера, ТекСтрока) + Символы.ПС; КонецЦикла; КонецЕсли;
// Процедура выводит текст сообщения об ошибке обмена // и текст "Обмен не выполнен." // // Параметры: // ТекстСообщения - строка, текст сообщения // Процедура СообщитьОбОшибкеОбмена(ТекстСообщения, ИнформацияОВыгрузке)
Если НЕ Строка(РасширеннаяИнформацияОбОшибке.Причина) = "ИнформацияОбОшибке" Тогда ТекстСообщения = ТекстСообщения + ". По причине: " + РасширеннаяИнформацияОбОшибке.Причина; КонецЕсли;
//ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.МестоРаботы.Организация.Контрагент" Тогда //ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.МестоРаботы" Тогда
ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.ЮридическийАдрес" Тогда
ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.РасчетныеСчета.РасчетныйСчет" Тогда ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.РасчетныеСчета.РасчетныйСчет.БанкКорреспондент.Банк" Тогда ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.РасчетныеСчета.РасчетныйСчет.БанкКорреспондент.Банк.Адрес" Тогда ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.РасчетныеСчета.РасчетныйСчет.БанкКорреспондент.Банк.Адрес.АдресноеПоле" Тогда ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.РасчетныеСчета.РасчетныйСчет.Банк" Тогда ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.РасчетныеСчета.РасчетныйСчет.Банк.Адрес" Тогда ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.РасчетныеСчета.РасчетныйСчет.Банк.Адрес.АдресноеПоле" Тогда
ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.Адрес" Тогда
//ИначеЕсли ИмяЭлемента = "Документ.Налоги.Налог" Тогда //ИначеЕсли ИмяЭлемента = "Документ.Скидки.Скидка" Тогда //ИначеЕсли ИмяЭлемента = "Документ.ДопРасходы.ДопРасход" Тогда
ИначеЕсли ИмяЭлемента = "Документ.Товары.Товар" Тогда
ИначеЕсли ИмяЭлемента = "Документ.Товары.Товар.БазоваяЕдиница" Тогда
Пока ОбъектCML.ПрочитатьАтрибут() Цикл Если ОбъектCML.Имя = "Код" Тогда КодБазовойЕдиницы = ОбъектCML.Значение; ТекущаяСтрокаТоваровУслуг.ТоварУслугаБазоваяЕдиницаКод = КодБазовойЕдиницы; Прервать; КонецЕсли; КонецЦикла
ИначеЕсли ИмяЭлемента = "Документ.Товары.Товар.ЗначенияРеквизитов.ЗначениеРеквизита" Тогда
ТекущаяСтрокаТоваровУслуг.Строки.Добавить();
ИначеЕсли ИмяЭлемента = "Документ.Товары.Товар.Скидки.Скидка" Тогда
ТекущаяСтрокаТоваровУслуг.Строки.Добавить();
ИначеЕсли ИмяЭлемента = "Документ.ЗначенияРеквизитов.ЗначениеРеквизита" Тогда
ИначеЕсли ИмяЭлемента = "Документ.ХозОперация" Тогда
Если НЕ ЗначениеЭлемента = "Заказ товара" Тогда СообщитьОбОшибкеОбмена("Ошибка в значении узла <Документ>.<ХозОперация> документа CML (" + ЗначениеЭлемента + ").", Ложь); Успешно = Ложь; КонецЕсли;
ИначеЕсли ИмяЭлемента = "Документ.Валюта" Тогда
ТекущийДокумент.ВалютаДокумента = ОбработатьВалютуCML(ЗначениеЭлемента); Если НЕ ЗначениеЗаполнено(ТекущийДокумент.ВалютаДокумента) Тогда СообщитьОбОшибкеОбмена("Ошибка в значении узла <Документ>.<Валюта> документа CML (" + ЗначениеЭлемента + ").", Ложь); Успешно = Ложь; КонецЕсли;
ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.ПолноеНаименование" ИЛИ ИмяЭлемента = "Документ.Контрагенты.Контрагент.ОфициальноеНаименование" Тогда
Если ИмяЭлемента = "Документ.Контрагенты.Контрагент.ПолноеНаименование" Тогда ТекущаяСтрокаДерева.СтруктураДанныхКонтрагента.Вставить("ЮрФизЛицо", Перечисления.ЮрФизЛицо.ФизЛицо); Иначе ТекущаяСтрокаДерева.СтруктураДанныхКонтрагента.Вставить("ЮрФизЛицо", Перечисления.ЮрФизЛицо.ЮрЛицо); КонецЕсли;
//ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.Обращение" Тогда //Не обрабатываем //ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.Фамилия" Тогда //Не обрабатываем, это полное наименование //ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.Имя" Тогда //Не обрабатываем, это полное наименование //ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.Отчество" Тогда //Не обрабатываем, это полное наименование
ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.ДатаРождения" Тогда
ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.УдостоверениеЛичности.ВидДокумента" ИЛИ ИмяЭлемента = "Документ.Контрагенты.Контрагент.УдостоверениеЛичности.Серия" ИЛИ ИмяЭлемента = "Документ.Контрагенты.Контрагент.УдостоверениеЛичности.Номер" ИЛИ ИмяЭлемента = "Документ.Контрагенты.Контрагент.УдостоверениеЛичности.ДатаВыдачи" ИЛИ ИмяЭлемента = "Документ.Контрагенты.Контрагент.УдостоверениеЛичности.КемВыдан" Тогда
ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.АдресРегистрации.Представление" ИЛИ ИмяЭлемента = "Документ.Контрагенты.Контрагент.АдресРегистрации.Комментарий" Тогда
ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.АдресРегистрации.АдресноеПоле.Тип" ИЛИ ИмяЭлемента = "Документ.Контрагенты.Контрагент.АдресРегистрации.АдресноеПоле.Значение" Тогда
//ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.МестоРаботы.Организация.Контрагент.Ид" Тогда //ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.МестоРаботы.Организация.Контрагент.Наименование" Тогда //ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.МестоРаботы.Должность" Тогда
ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.ЮридическийАдрес.Представление" ИЛИ ИмяЭлемента = "Документ.Контрагенты.Контрагент.ЮридическийАдрес.Комментарий" Тогда
ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.ЮридическийАдрес.АдресноеПоле.Тип" ИЛИ ИмяЭлемента = "Документ.Контрагенты.Контрагент.ЮридическийАдрес.АдресноеПоле.Значение" Тогда
//ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.РасчетныеСчета.РасчетныйСчет.НомерСчета" Тогда //ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.РасчетныеСчета.РасчетныйСчет.Комментарий" Тогда // //ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.РасчетныеСчета.РасчетныйСчет.БанкКорреспондент.Банк.СчетКорреспондентский" Тогда //ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.РасчетныеСчета.РасчетныйСчет.БанкКорреспондент.Банк.Наименование" Тогда //ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.РасчетныеСчета.РасчетныйСчет.БанкКорреспондент.Банк.БИК" Тогда //ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.РасчетныеСчета.РасчетныйСчет.БанкКорреспондент.Банк.SWIFT" Тогда // //ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.РасчетныеСчета.РасчетныйСчет.БанкКорреспондент.Банк.Адрес.Представление" Тогда //ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.РасчетныеСчета.РасчетныйСчет.БанкКорреспондент.Банк.Адрес.Комментарий" Тогда //ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.РасчетныеСчета.РасчетныйСчет.БанкКорреспондент.Банк.Адрес.АдресноеПоле.Тип" Тогда //ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.РасчетныеСчета.РасчетныйСчет.БанкКорреспондент.Банк.Адрес.АдресноеПоле.Значение" Тогда // //ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.РасчетныеСчета.РасчетныйСчет.Банк.СчетКорреспондентский" Тогда //ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.РасчетныеСчета.РасчетныйСчет.Банк.Наименование" Тогда //ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.РасчетныеСчета.РасчетныйСчет.Банк.БИК" Тогда //ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.РасчетныеСчета.РасчетныйСчет.Банк.SWIFT" Тогда // //ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.РасчетныеСчета.РасчетныйСчет.Банк.Адрес.Представление" Тогда //ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.РасчетныеСчета.РасчетныйСчет.Банк.Адрес.Комментарий" Тогда //ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.РасчетныеСчета.РасчетныйСчет.Банк.Адрес.АдресноеПоле.Тип" Тогда //ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.РасчетныеСчета.РасчетныйСчет.Банк.Адрес.АдресноеПоле.Значение" Тогда
ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.Адрес.Представление" ИЛИ ИмяЭлемента = "Документ.Контрагенты.Контрагент.Адрес.Комментарий" Тогда
ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.Адрес.АдресноеПоле.Тип" ИЛИ ИмяЭлемента = "Документ.Контрагенты.Контрагент.Адрес.АдресноеПоле.Значение" Тогда
ИначеЕсли ИмяЭлемента = "Документ.Контрагенты.Контрагент.Контакты.Контакт.Тип" ИЛИ ИмяЭлемента = "Документ.Контрагенты.Контрагент.Контакты.Контакт.Значение" ИЛИ ИмяЭлемента = "Документ.Контрагенты.Контрагент.Контакты.Контакт.Комментарий" Тогда
//ИначеЕсли ИмяЭлемента = "Документ.Налоги.Налог.Наименование" Тогда // Не обрабатываем, это может быть только НДС ИначеЕсли ИмяЭлемента = "Документ.Налоги.Налог.УчтеноВСумме" Тогда
ТекущийДокумент.СуммаВключаетНДС = Ложь; Если ЗначениеЭлемента = БулевоЗначениеCML_Истина Тогда ТекущийДокумент.СуммаВключаетНДС = Истина; КонецЕсли;
ИначеЕсли ИмяЭлемента = "Документ.Налоги.Налог.Ставка" Тогда
//ИначеЕсли ИмяЭлемента = "Документ.Скидки.Скидка.Наименование" Тогда // Не обрабатываем, т.к. есть у товара ИначеЕсли ИмяЭлемента = "Документ.Скидки.Скидка.Сумма" Тогда
ИначеЕсли ИмяЭлемента = "Документ.Скидки.Скидка.УчтеноВСумме" Тогда
ТекущаяСтрокаДерева.СкидкаВСумме = Ложь; Если ЗначениеЭлемента = БулевоЗначениеCML_Истина Тогда ТекущаяСтрокаДерева.СкидкаВСумме = Истина; КонецЕсли;
ИначеЕсли ИмяЭлемента = "Документ.Товары.Товар.Ид" ИЛИ ИмяЭлемента = "Документ.Товары.Товар.БазоваяЕдиница" ИЛИ ИмяЭлемента = "Документ.Товары.Товар.Наименование" Тогда
ИначеЕсли ИмяЭлемента = "Документ.Товары.Товар.ЦенаЗаЕдиницу" ИЛИ ИмяЭлемента = "Документ.Товары.Товар.Сумма" ИЛИ ИмяЭлемента = "Документ.Товары.Товар.Количество" Тогда
//ИначеЕсли ИмяЭлемента = "Документ.ДопРасходы.ДопРасход.УчтеноВСумме" Тогда // Не обрабатываем //ИначеЕсли ИмяЭлемента = "Документ.Товары.Товар.Скидки.Скидка.Наименование" Тогда // Не обрабатываем
ИначеЕсли ИмяЭлемента = "Документ.Товары.Товар.ЗначенияРеквизитов.ЗначениеРеквизита.Наименование" ИЛИ ИмяЭлемента = "Документ.Товары.Товар.ЗначенияРеквизитов.ЗначениеРеквизита.Значение" Тогда
ИначеЕсли ИмяЭлемента = "Документ.Товары.Товар.Скидки.Скидка.УчтеноВСумме" Тогда
ТекущаяСтрокаСкидок.СкидкаВСумме = Ложь; Если ЗначениеЭлемента = БулевоЗначениеCML_Истина Тогда ТекущаяСтрокаСкидок.СкидкаВСумме = Истина; КонецЕсли;
ИначеЕсли ИмяЭлемента = "Документ.ЗначенияРеквизитов.ЗначениеРеквизита.Наименование" ИЛИ ИмяЭлемента = "Документ.ЗначенияРеквизитов.ЗначениеРеквизита.Значение" Тогда
Попытка ОбъектCML.УстановитьСтроку(СтрокаCML); Исключение СообщитьОбИсключительнойОшибке(Ложь); Возврат Неопределено; КонецПопытки;
ПоследовательностьЭлементов = "";
ДеревоДокументов = Новый ДеревоЗначений;
ДеревоДокументов.Колонки.Добавить("ДокументОбъект"); ДеревоДокументов.Колонки.Добавить("НомерВходящий"); ДеревоДокументов.Колонки.Добавить("РанееЗагруженныйДокументСсылка", Новый ОписаниеТипов("ДокументСсылка.ЗаказПокупателя")); ДеревоДокументов.Колонки.Добавить("ЕстьСсылкиНаРанееЗагруженныйДокумент", Новый ОписаниеТипов("Булево")); ДеревоДокументов.Колонки.Добавить("СтруктураДанныхКонтрагента"); ДеревоДокументов.Колонки.Добавить("СтавкаНДС");
ПоследовательностьЭлементов = ДобавитьЭлементКПоследовательности(ПоследовательностьЭлементов, ИмяУзла); Успешно = ОбработатьНачалоЭлемента(ОбъектCML, ПоследовательностьЭлементов, ДеревоДокументов); Если НЕ Успешно Тогда СообщитьПользователю("Не удалось обработать начало элемента (" + ПоследовательностьЭлементов + ").", Ложь); Прервать; КонецЕсли;
ИначеЕсли ТипУзла = ТипУзлаXML.КонецЭлемента Тогда
ЗначениеЭлемента = ОбъектCML.Значение; Успешно = ОбработатьЗначениеЭлемента(ПоследовательностьЭлементов, ЗначениеЭлемента, ДеревоДокументов); Если НЕ Успешно Тогда СообщитьПользователю("Не удалось обработать значение элемента (" + ПоследовательностьЭлементов + ") = (" + ЗначениеЭлемента + ").", Ложь); Прервать; КонецЕсли;
КонецЕсли;
КонецЦикла;
ОбъектCML.Закрыть();
Если НЕ Успешно Тогда ДеревоДокументов = Неопределено; КонецЕсли;
Возврат ДеревоДокументов;
КонецФункции
Функция ДобавитьЭлементКПоследовательности(Знач ПоследовательностьЭлементов, Знач ИмяУзла)
ИсключатьИзПоследовательности = Новый Массив; ИсключатьИзПоследовательности.Добавить("КоммерческаяИнформация");
Если ИсключатьИзПоследовательности.Найти(ИмяУзла) = Неопределено Тогда
Если НЕ ПоследовательностьЭлементов = "" Тогда ПоследовательностьЭлементов = ПоследовательностьЭлементов + "."; КонецЕсли; ПоследовательностьЭлементов = ПоследовательностьЭлементов + ИмяУзла;
КонецЕсли;
Возврат ПоследовательностьЭлементов;
КонецФункции
Функция УдалитьПоследнийЭлементИзПоследовательности(Знач ПоследовательностьЭлементов);
ИмяПоследнегоЭлемента = ""; Если КоличествоЭлементов > 0 Тогда ИмяПоследнегоЭлемента = СтрПолучитьСтроку(ПромСтрока, КоличествоЭлементов); КонецЕсли;
Возврат ИмяПоследнегоЭлемента;
КонецФункции
Функция ОбработатьДокументы(ДеревоДокументов, КоличествоОбработанныхДокументов)
Успешно = Истина; КоличествоОбработанныхДокументов = 0;
СтруктураСтатистики = Новый Структура; СтруктураСтатистики.Вставить("Создано" , 0); СтруктураСтатистики.Вставить("Обновлено", 0); СтруктураСтатистики.Вставить("Пропущено", 0); СтруктураСтатистики.Вставить("ОплаченСписок", Новый Массив); СтруктураСтатистики.Вставить("ДоставкаРазрешенаСписок", Новый Массив); СтруктураСтатистики.Вставить("ФинальныйСтатусСписок", Новый Массив);
ОтобразитьСостояние("Поиск ранее загруженных документов...");
Успешно = ИдентифицироватьКонтрагентов(ДеревоДокументов);
Если НЕ Успешно Тогда ОтменитьТранзакцию(); СообщитьПользователю("Не удалось найти/создать контрагента.", Ложь); Возврат Ложь; КонецЕсли;
Успешно = ИдентифицироватьНоменклатуру(ДеревоДокументов); Если НЕ Успешно Тогда ОтменитьТранзакцию(); СообщитьПользователю("Не удалось найти/создать номенклатуру.", Ложь); Возврат Ложь; КонецЕсли;
МассивДокументовДляПроведения = Новый Массив(); Успешно = СоздатьОбновитьДокументы(ДеревоДокументов, СтруктураСтатистики, МассивДокументовДляПроведения, мМассивЗагруженныхДокументов); Если НЕ Успешно Тогда СообщитьПользователю("Не удалось создать/обновить документы.", Ложь); Возврат Ложь; КонецЕсли;
МассивОтклоненныхДокументов = Новый Массив(); Успешно = ЗаписатьСвойстваДокументов(ДеревоДокументов, СтруктураСтатистики, МассивОтклоненныхДокументов); Если НЕ Успешно Тогда СообщитьПользователю("Не удалось записать свойства документов.", Ложь); Возврат Ложь; КонецЕсли;
// если документы нужно проводить, то попытаемся их провести РежимПроведения = ?(ПроводитьДокументыОперативно, РежимПроведенияДокумента.Оперативный, РежимПроведенияДокумента.Неоперативный); Для Каждого ДокументПроведения Из МассивДокументовДляПроведения Цикл
Если МассивОтклоненныхДокументов.Найти(ДокументПроведения.Ссылка) <> Неопределено Тогда Продолжить; КонецЕсли;
ТекстСообщения = "Успешно получено и обработано документов: " + Строка(КоличествоОбработанныхДокументов);
ТекстСообщения = ТекстСообщения + Символы.ПС + "Список обработанных документов: "; Для Каждого СтрокаДД Из ДеревоДокументов.Строки Цикл ТекстСообщения = ТекстСообщения + Символы.ПС + Отступ + СтрокаДД.ДокументОбъект.Ссылка; КонецЦикла;
ТекстСообщения = ТекстСообщения + Символы.ПС + "В том числе:"; Если СтруктураСтатистики.Создано <> 0 Тогда ТекстСообщения = ТекстСообщения + Символы.ПС + Отступ + "создано новых: " + СтруктураСтатистики.Создано; КонецЕсли;
Если СтруктураСтатистики.Обновлено <> 0 Тогда ТекстСообщения = ТекстСообщения + Символы.ПС + Отступ + "обновлено: " + СтруктураСтатистики.Обновлено; КонецЕсли;
Если СтруктураСтатистики.Пропущено <> 0 Тогда ТекстСообщения = ТекстСообщения + Символы.ПС + Отступ + "пропущено: " + СтруктураСтатистики.Пропущено; КонецЕсли;
Если СтруктураСтатистики.ОплаченСписок.Количество() > 0 Тогда ТекстСообщения = ТекстСообщения + Символы.ПС + "Получено оплаченных документов: " + СтруктураСтатистики.ОплаченСписок.Количество(); Для Каждого Док Из СтруктураСтатистики.ОплаченСписок Цикл ТекстСообщения = ТекстСообщения + Символы.ПС + Отступ + Док; КонецЦикла; КонецЕсли;
Если СтруктураСтатистики.ДоставкаРазрешенаСписок.Количество() > 0 Тогда ТекстСообщения = ТекстСообщения + Символы.ПС + "Получено документов с разрешенной доставкой: " + СтруктураСтатистики.ДоставкаРазрешенаСписок.Количество(); Для Каждого Док Из СтруктураСтатистики.ДоставкаРазрешенаСписок Цикл ТекстСообщения = ТекстСообщения + Символы.ПС + Отступ + Док; КонецЦикла; КонецЕсли;
Если СтруктураСтатистики.ФинальныйСтатусСписок.Количество() > 0 Тогда ТекстСообщения = ТекстСообщения + Символы.ПС + "Получено документов в финальном статусе: " + СтруктураСтатистики.ФинальныйСтатусСписок.Количество(); Для Каждого Док Из СтруктураСтатистики.ФинальныйСтатусСписок Цикл ТекстСообщения = ТекстСообщения + Символы.ПС + Отступ + Док; КонецЦикла; КонецЕсли;
Функция ОбработатьДатуВремяCML(ДатаВремяСтрока, НачальнаяДата = Неопределено)
ДатаВремя = Неопределено;
Если ЗначениеЗаполнено(НачальнаяДата) Тогда Время = СтрЗаменить(ДатаВремяСтрока, ":", ""); ДатаВремя = Дата(Формат(НачальнаяДата, "ДФ=yyyyMMdd") + Время); Иначе ДатаВремя = Дата(СтрЗаменить(ДатаВремяСтрока, "-", "") + "000000"); КонецЕсли;
Возврат ДатаВремя; КонецФункции
Функция ОбработатьВалютуCML(КодВалютыСтрока) Валюта = Справочники.Валюты.НайтиПоНаименованию(КодВалютыСтрока); Возврат Валюта; КонецФункции
Функция СоздатьОбновитьДокументы(ДеревоДокументов, СтруктураСтатистики, МассивДокументовДляПроведения, МассивЗагруженныхДокументов)
Успешно = Истина;
Для Каждого Док Из ДеревоДокументов.Строки Цикл
// если на документ есть ссылки, то он вообще пропускается и не загружается Если Док.ЕстьСсылкиНаРанееЗагруженныйДокумент Тогда СтруктураСтатистики.Пропущено = СтруктураСтатистики.Пропущено + 1; Продолжить; КонецЕсли;
Если ЗначениеЗаполнено(Док.РанееЗагруженныйДокументСсылка) Тогда СтруктураСтатистики.Обновлено = СтруктураСтатистики.Обновлено + 1; Иначе СтруктураСтатистики.Создано = СтруктураСтатистики.Создано + 1; КонецЕсли;
ОбъектПринадлежитКатегории = (ТоварУслугаСвойство.СвойствоЗначение = БулевоЗначениеCML_Истина) ИЛИ (ТоварУслугаСвойство.СвойствоЗначение = БулевоЗначениеCML_Да);
Успешно = УстановитьКатегориюДокумента(СтрокаДД.ДокументОбъект.Ссылка, КатегорияСсылка, ОбъектПринадлежитКатегории);
Если НЕ Успешно Тогда
СообщитьПользователю("Не удалось установить категорию документа - " + Строка(КатегорияСсылка), Ложь); Прервать;
КонецЕсли;
Если ОбъектПринадлежитКатегории Тогда
Если КатегорияСсылка = Справочники.КатегорииОбъектов.СостояниеЗаказаНаWEBСайтеОплачен Тогда СтруктураСтатистики.ОплаченСписок.Добавить(СтрокаДД.ДокументОбъект.Ссылка); ИначеЕсли КатегорияСсылка = Справочники.КатегорииОбъектов.СостояниеЗаказаНаWEBСайтеДоставкаРазрешена Тогда СтруктураСтатистики.ДоставкаРазрешенаСписок.Добавить(СтрокаДД.ДокументОбъект.Ссылка); ИначеЕсли КатегорияСсылка = Справочники.КатегорииОбъектов.СостояниеЗаказаНаWEBСайтеЗавершен Тогда СтруктураСтатистики.ФинальныйСтатусСписок.Добавить(СтрокаДД.ДокументОбъект.Ссылка); ИначеЕсли КатегорияСсылка = Справочники.КатегорииОбъектов.СостояниеЗаказаНаWEBСайтеОтменен Тогда МассивОтклоненныхДокументов.Добавить(СтрокаДД.ДокументОбъект.Ссылка); КонецЕСли;
Попытка Запись.Записать(); Исключение Успешно = Ложь; СообщитьОбИсключительнойОшибке(Ложь, "Не удалось записать значение свойства " + ЗначениеСвойства); КонецПопытки;
Возврат Успешно;
КонецФункции
Функция ИдентифицироватьКонтрагентов(ДеревоДокументов)
Успешно = Истина;
Для Каждого СтрокаДД Из ДеревоДокументов.Строки Цикл
Если СтрокаДД.ЕстьСсылкиНаРанееЗагруженныйДокумент Тогда Продолжить; КонецЕсли;
Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1 | Контрагенты.Ссылка Как Контрагент |ИЗ | Справочник.Контрагенты КАК Контрагенты |ГДЕ |";
НуженПоискПоИнн = (СпособИдентификацииКонтрагентов = "ИНН") И ЗначениеЗаполнено(ИНН);
Если НуженПоискПоИнн Тогда Запрос.Текст = Запрос.Текст + " Контрагенты.КодПоЕДРПОУ = &ИНН "; Иначе Запрос.Текст = Запрос.Текст + " Контрагенты.Наименование = &Наименование "; КонецЕсли;
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда КонтрагентСсылка = Выборка.Контрагент; Иначе КонтрагентСсылка = СоздатьКонтрагента(СтрокаДД.СтруктураДанныхКонтрагента); КонецЕсли;
// нужны только договоры с покупателем и все мСтруктураПараметровДляПолученияДоговора.СписокДопустимыхВидовДоговоров.Очистить(); мСтруктураПараметровДляПолученияДоговора.СписокДопустимыхВидовДоговоров.Добавить(Перечисления.ВидыДоговоровКонтрагентов.СПокупателем);
СписокДопустимыхВидовВзаиморасчетов = Новый СписокЗначений(); СписокДопустимыхВидовВзаиморасчетов.Добавить(Перечисления.ВедениеВзаиморасчетовПоДоговорам.ПоЗаказам); мСтруктураПараметровДляПолученияДоговора.Вставить("СписокДопустимыхВидовВзаиморасчетов", СписокДопустимыхВидовВзаиморасчетов);
Попытка НайденныйДоговорОбъект.Записать(); Исключение СообщитьОбИсключительнойОшибке(Ложь, ОписаниеОшибки(), "Не удалось записать договор контрагента."); Возврат Неопределено; КонецПопытки;
Возврат НайденныйДоговорОбъект.Ссылка;
КонецФункции
Функция ПроверитьОсновнойДоговорКонтрагента(КонтрагентСсылка, ДокОбъект)
Успешно = Истина;
Если ЗначениеЗаполнено(КонтрагентСсылка.ОсновнойДоговорКонтрагента) Тогда Возврат Успешно; КонецЕсли;
Если Не ЗначениеЗаполнено(ДокОбъект.Организация) Тогда
СообщитьПользователю("Не удалось определить основной договор контрагента (не найдена организация).", Ложь); Возврат Ложь;
КонецЕсли;
// ищем договр по контрагенту, организации и валюте Запрос = Новый Запрос(); Запрос.Текст = "ВЫБРАТЬ | ДоговорыКонтрагентов.Ссылка КАК Ссылка, | ДоговорыКонтрагентов.ВалютаВзаиморасчетов КАК ВалютаВзаиморасчетов |ИЗ | Справочник.ДоговорыКонтрагентов КАК ДоговорыКонтрагентов |ГДЕ | ДоговорыКонтрагентов.Организация = &Организация | И ДоговорыКонтрагентов.ВидВзаиморасчетов = Значение(Перечисление.ВедениеВзаиморасчетовПоДоговорам.ПоЗаказам) | И ДоговорыКонтрагентов.ВидДоговора = Значение(Перечисление.ВидыДоговоровКонтрагентов.СПокупателем)";
Функция ИдентифицироватьНоменклатуру(ДеревоДокументов)
Успешно = Истина;
Успешно = ИнициализироватьВидыНоменкалтуры();
Если НЕ Успешно Тогда Возврат Ложь; КонецЕсли;
Для Каждого СтрокаДД Из ДеревоДокументов.Строки Цикл
Если СтрокаДД.ЕстьСсылкиНаРанееЗагруженныйДокумент Тогда Продолжить; КонецЕсли;
ОтобразитьСостояние("Идентификация товаров в документе: " + СтрокаДД.ДокументОбъект);
Для Каждого ТоварУслугаСвойство Из СтрокаДД.Строки Цикл
Если ЗначениеЗаполнено(ТоварУслугаСвойство.СвойствоНаименование) Тогда Продолжить; КонецЕсли;
ТипНоменклатурыCML = "";
Для Каждого ПодчиненнаяСтрокаТовараУслуги Из ТоварУслугаСвойство.Строки Цикл
Если ЗначениеЗаполнено(ПодчиненнаяСтрокаТовараУслуги.ЗначениеРеквизитаНаименование) И ПодчиненнаяСтрокаТовараУслуги.ЗначениеРеквизитаНаименование = ЗначениеCML_ТипНоменклатуры Тогда
Если СтрокаДД.ДокументОбъект.Товары.Количество() > 0 Тогда РаспределитьСуммуПоКолонке(СтрокаДД.ДокументОбъект, СтрокаДД.ДокументОбъект.Товары, "Товары", -СуммаСкидки); Иначе РаспределитьСуммуПоКолонке(СтрокаДД.ДокументОбъект, СтрокаДД.ДокументОбъект.Услуги, "Услуги", -СуммаСкидки); КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат Успешно;
КонецФункции
Функция РассчитатьСуммуСУчетомСкидок(СтрокаТовара);
ПозицияРазделителя = Найти(Ид, "#"); Если ПозицияРазделителя > 0 Тогда ИдНоменклатуры = Лев(Ид, ПозицияРазделителя - 1); Иначе ИдНоменклатуры = Ид; КонецЕсли;
Возврат ИдНоменклатуры;
КонецФункции
Функция ПолучитьИдХарактеристики(Знач Ид)
ПозицияРазделителя = Найти(Ид, "#"); Если ПозицияРазделителя > 0 Тогда ИдХарактеристики = Прав(Ид, СтрДлина(Ид) - ПозицияРазделителя); Иначе ИдХарактеристики = ""; КонецЕсли;
Возврат ИдХарактеристики;
КонецФункции
Функция ВыполнитьПоискНоменклатурыХарактеристикиПоСсылкам(СтрокаТовара, Номенклатура, ХарактеристикаНоменклатуры)
Если НЕ ЗначениеЗаполнено(СтрокаТовара.ТоварУслугаИд) Тогда Возврат Ложь; КонецЕсли;
Попытка
ИдНоменклатуры = ПолучитьИдНоменклатуры(СтрокаТовара.ТоварУслугаИд); Номенклатура = Справочники.Номенклатура.ПолучитьСсылку(Новый УникальныйИдентификатор(ИдНоменклатуры)); Если Номенклатура = Справочники.Номенклатура.ПустаяСсылка() Тогда Возврат Ложь; КонецЕсли;
Если Номенклатура.ПолучитьОбъект() = Неопределено Тогда // Объект не найден СообщитьПользователю("Номенклатура не найдена по уникальному идентификатору: " + ИдНоменклатуры, Ложь); Возврат Ложь; КонецЕсли;
Если НЕ Номенклатура.ВестиУчетПоХарактеристикам Тогда Возврат Истина; КонецЕсли;
ИдХарактеристики = ПолучитьИдХарактеристики(СтрокаТовара.ТоварУслугаИд); Если ПустаяСтрока(ИдХарактеристики) Тогда Возврат Истина; КонецЕсли;
Если ХарактеристикаНоменклатуры = ПустаяХарактеристикаСсылка Тогда Возврат Истина; КонецЕсли;
Если ХарактеристикаНоменклатуры.ПолучитьОбъект() = Неопределено Тогда СообщитьПользователю("Объект <ХарактеристикаНоменклатуры> не найден: " + Строка(ИдХарактеристики) + ". Будет создан новый объект.", Ложь);
Возврат Ложь;
КонецЕсли;
Исключение
Возврат Ложь;
КонецПопытки;
Возврат Истина;
КонецФункции
Функция НайтиНоменклатуруПоНаименованиюИВиду(НаименованиеНоменклатуры, ВидНоменклатуры)
// поиск номенклатуры по наименованию и виду Запрос = Новый Запрос;
Если ЗначениеЗаполнено(СтрокаТовара.ТоварУслугаБазоваяЕдиницаКод) Тогда ЕдиницаПоКлассификатору = Справочники.КлассификаторЕдиницИзмерения.НайтиПоКоду(СтрокаТовара.ТоварУслугаБазоваяЕдиницаКод); КонецЕсли;
Если НЕ ЗначениеЗаполнено(ЕдиницаПоКлассификатору) И ЗначениеЗаполнено(СтрокаТовара.ТоварУслугаБазоваяЕдиница) Тогда
Номенклатура.Записать(); Если ВыгружатьТолькоИзменения Тогда ПланыОбмена.УдалитьРегистрациюИзменений(УзелОбменаТоварами, Номенклатура.Ссылка); КонецЕсли;
// контактные лица ТаблицаКонтактныхЛиц = СтруктураДанныхКонтрагента.ТаблицаКонтактныхЛиц; ТаблицаКонтактныхЛиц.Свернуть("Наименование"); Для Каждого СтрокаКЛ Из ТаблицаКонтактныхЛиц Цикл
КонтактноеЛицоКонтрагента = Справочники.КонтактныеЛицаКонтрагентов.НайтиПоНаименованию(СтрокаКЛ.Наименование, Истина, , КонтрагентСсылка); Если ЗначениеЗаполнено(КонтактноеЛицоКонтрагента) Тогда Продолжить; КонецЕсли;
Элемент = Справочники.КонтактныеЛицаКонтрагентов.СоздатьЭлемент(); Элемент.Владелец = КонтрагентСсылка; Элемент.Наименование = СтрокаКЛ.Наименование; Элемент.Записать();
КонецЦикла;
//свойства
КонецПроцедуры
//////////////////////////////////////////////////////////////////////////////// // ПРОЦЕДУРЫ АНАЛИЗА ИЗМЕНЕНИЙ ДАННЫХ
Если ИнформацияОТоварах Тогда СтруктураВозврата.НомерСообщенияТовары = ЗаписьСообщения.НомерСообщения; Иначе СтруктураВозврата.НомерСообщенияЗаказы = ЗаписьСообщения.НомерСообщения; КонецЕсли;
// Получение Изменений #Если Клиент Тогда ОтобразитьСостояние("Выбор изменений ..."); Счетчик = 0; #КонецЕсли
СтруктураВозврата = Новый Структура("Товары,Заказы,Картинки,НомерСообщенияТовары,НомерСообщенияЗаказы", Новый Массив(), Новый Массив(), Новый Массив());
Если ОбменТоварами Тогда ЗаполнитьСтруктуруИзмененийДляУзла(УзелОбменаТоварами, СтруктураВозврата, Истина); КонецЕсли;
Если ОбменЗаказами Тогда ЗаполнитьСтруктуруИзмененийДляУзла(УзелОбменаЗаказами, СтруктураВозврата, Ложь); КонецЕсли;
Возврат СтруктураВозврата;
КонецФункции
//////////////////////////////////////////////////////////////////////////////// // ОПЕРАТОРЫ ОСНОВНОЙ ПРОГРАММЫ
Если в долларах, то укажите явно Гривну. Ну и проверте.
Запустил отладчик, поставил точку останова, пошагово прошёл тот кусок кода и в Переменную "НовЦена" ничего не передаётся. Значение пусто, тип Неопределенно.
когда на стороне сайта делается парсинг хмл-файла, там валюта ищется по строке "EUR" либо "ГРН". А если искать надо по международному названию гривны? "UAH" Для начала попробуйте в справочнике международное название гривны поменять. Возможно еще ошибка в верхнем/нижнем регистре.
Если не поможет, можно методом исключения действовать. Если не нужна цена в долларах, а только в гривнах, то выгружать цену только в гривне. Тогда проще будет.
В общем хочется или нет, а парсинг все равно надо будет разбирать.
Группа: Пользователи
Сообщений: 51
Спасибо сказали: 0 раз
Рейтинг: 0
Цитата(Acid @ 11.11.14, 12:35)
когда на стороне сайта делается парсинг хмл-файла, там валюта ищется по строке "EUR" либо "ГРН". А если искать надо по международному названию гривны? "UAH" Для начала попробуйте в справочнике международное название гривны поменять. Возможно еще ошибка в верхнем/нижнем регистре.
Если не поможет, можно методом исключения действовать. Если не нужна цена в долларах, а только в гривнах, то выгружать цену только в гривне. Тогда проще будет.
В общем хочется или нет, а парсинг все равно надо будет разбирать.
Вот есть код формы элемента справочника номенклатура. ПринтСкрин я вылаживал в самом начале. Так вот колонка "Цена в ГРН" считается вот так:
Если ТекущаяСтраница=13 Тогда Запрос = Новый Запрос(" |ВЫБРАТЬ | Цены.ТипЦен КАК ТипЦен, | Цены.Цена КАК Цена, | Цены.СпособРасчетаЦены КАК СпособРасчетаЦены, | Цены.Валюта КАК Валюта, | Цены.ЦенаГРН КАК кЦенаГРН, | Цены.ЕдиницаИзмерения КАК ЕдиницаИзмерения, | Цены.ПроцентСкидкиНаценки КАК ПроцентСкидкиНаценки |ИЗ | РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Дата, ТипЦен В (&ТипыЦен) | И Номенклатура = &Номенклатура И ХарактеристикаНоменклатуры = ЗНАЧЕНИЕ(Справочник.ХарактеристикиНоменклатуры.ПустаяСсылка) | ) КАК Цены |");
ТЗ = Запрос.Выполнить().Выгрузить(); Для каждого Выборка из ТЗ Цикл СтрокаЦен = ЦеныНоменклатуры.Найти(Выборка.ТипЦен, "ТипЦен"); ВГРН = Константы.ВалютаРегламентированногоУчета.Получить(); Если Выборка.Валюта<>ВГРН Тогда
1С Предприятие 8.3, 1С Предприятие 8.2, 1С Предприятие 8.1, 1С Предприятие 8.0, 1С Предприятие 7.7, Литература 1С, Общие вопросы по администрированию 1С, Методическая поддержка 1С - всё в одном месте: на Украинском 1С форуме!