Публикации

БСП
Разработки

Грабли при работе с макетом в СКД

Показана особенность при работе с макетом в конструкторе СКД, которая может легко загубить результаты вашей работы
На скринах показано как можно легко испортить Макет из-за своеобразной логики работы конструктора СКД Читать дальше
SDV 27 5

Загрузка в 1с из CSV. Обработка-шаблон для импорта из csv

4 buketoff 17 3
&НаКлиенте
Процедура ЗагрузитьCSV(Команда)  // выполняется при нажатии на кнопку
	ДиалогФыбораФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие); //!!!!!!!!!!!!
ДиалогФыбораФайла.Фильтр="csv файл с разделтелями (*.csv)|*.csv|";

ДиалогФыбораФайла.Заголовок = "Выберите файл";
ДиалогФыбораФайла.ИндексФильтра = 0;
описаниеОповещения = Новый ОписаниеОповещения("ГрузимИзФайла", ЭтотОбъект);
    
    ДиалогФыбораФайла.Показать(описаниеОповещения);	

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



&НаКлиенте
Процедура ГрузимИзФайла(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт // вызываем диалог выбора файла
    
    Если ВыбранныеФайлы <> Неопределено И ВыбранныеФайлы.Количество() > 0 Тогда
      //  Сообщить("Файл выбран!");
//работаем с файлом
    Имяфайла=ВыбранныеФайлы[0];		
// Пишем в реестр
    сообщить(имяФайла); // вызываем дальнейшую процедуру обработки
	Путь=имяФайла; // для сохранения xml понадобится
// читаем файл	
ЗагружаемыйФайл = Новый ТекстовыйДокумент; 
ЗагружаемыйФайл.Прочитать(ИмяФайла);

Если лист="лист1" тогда
	обработатьCSV1(ЗагружаемыйФайл);
	конецЕсли;

    Иначе
        Сообщить("Файл не выбран!");
    КонецЕсли;
    

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

// процедуру обработатьCSV1(файл) - можно сделать на клиенте
&наСервере   
процедура обработатьCSV1(файл)
	для номерстроки=2 по файл.КоличествоСтрок() цикл // первую строку пропускаем т.к. там название полей
	строка=файл.получитьСтроку(номерСтроки);
	массив=РазложитьСтрокуВМассивПодстрок(строка,";"); // строка csv - файла, преобразованная в массив, дальше с этими данными можно делать что угодно 

		конецЦикла;
	конецПроцедуры
	
	// процедуру РазложитьСтрокуВМассивПодстрок - можно сделать на клиенте, если процедура "обработатьCSV1" тоже имеет директиву &наКлиенте
	&наСервере
	Функция РазложитьСтрокуВМассивПодстрок(Знач Стр, Разделитель = ",") Экспорт
   
   МассивСтрок = Новый Массив();
   Если Разделитель = " " Тогда
       Стр = СокрЛП(Стр);
       Пока 1=1 Цикл
           Поз = Найти(Стр,Разделитель);
           Если Поз=0 Тогда
               МассивСтрок.Добавить(Стр);
               Возврат МассивСтрок;
           КонецЕсли;
           МассивСтрок.Добавить(Лев(Стр,Поз-1));
           Стр = СокрЛ(Сред(Стр,Поз));
       КонецЦикла;
   Иначе
       ДлинаРазделителя = СтрДлина(Разделитель);
       Пока 1=1 Цикл
           Поз = Найти(Стр,Разделитель);
           Если Поз=0 Тогда
               МассивСтрок.Добавить(Стр);
               Возврат МассивСтрок;
           КонецЕсли;
           МассивСтрок.Добавить(Лев(Стр,Поз-1));
           Стр = Сред(Стр,Поз+ДлинаРазделителя);
       КонецЦикла;
   КонецЕсли;
   
КонецФункции // глРазложить

TurboConf - расширение Конфигуратора 1С Промо

TurboConf повышает эффективность работы в Конфигураторе 1С и помогает автоматизировать рутинные задачи.
1 bolsun

Использование Синонима отчета/обработки при выполнении кода &НаКлиенте

Для использования синонима отчета/обработки при исполнении на клиенте для подобной универсальной подстановки в разные места - можно завести реквизит формы СинонимОтчета (тип Строка), заполнять его в ПриСозданииНаСервере() этой формы и потом обращаться к нему Форма.СинонимОтчета.
buketoff 17 3
//***********************************************************************
&НаКлиенте
Процедура СохранитьВExcel(Команда)
    
    ИмяФайла = Форма.СинонимОтчета + " (" + 
    Строка(Формат(ТекущаяДата(),"ДФ=""дд-ММ-гггг""")) + ")" 
    +".xlsx";
    
    //.....

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

&НаКлиентеНаСервереБезКонтекста
Процедура ОбновитьТекстЗаголовка(Форма)
    
    Отчет = Форма.Отчет;
    
    ЗаголовокОтчета = НСтр("ru = '" + Форма.СинонимОтчета + "'") + БухгалтерскиеОтчетыКлиентСервер.ПолучитьПредставлениеПериода(Отчет.НачалоПериода, Отчет.КонецПериода);

    Если ЗначениеЗаполнено(Отчет.Организация) И Форма.ИспользуетсяНесколькоОрганизаций Тогда
        ЗаголовокОтчета = ЗаголовокОтчета + " " + БухгалтерскиеОтчетыВызовСервераПовтИсп.ПолучитьТекстОрганизация(Отчет.Организация, Отчет.ВключатьОбособленныеПодразделения);
    КонецЕсли;
    
    Форма.Заголовок = ЗаголовокОтчета;

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

//***********************************************************************
&НаСервере
Функция ВернутьСинонимОтчета()
    
    ОтчетОбъект = РеквизитФормыВЗначение("Отчет");
    
    Возврат ОтчетОбъект.Метаданные().Синоним + " " + ОтчетОбъект.Метаданные().Комментарий;
    //Возврат ОтчетОбъект.Метаданные().Синоним;
    
КонецФункции
//***********************************************************************

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    ЭтаФорма.СинонимОтчета = ВернутьСинонимОтчета();

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

Универсальные функции для регистрации внешних обработок. Для внешней обработки (*.epf)

2 buketoff 17 3
/////////////////////////////////////////////////////////////////////////
// РЕГИСТРАЦИЯ ВНЕШНЕЙ ОБРАБОТКИ

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

    // Добавим команду в таблицу
    ДобавитьКоманду(ТаблицаКоманд, Синоним, "1" , "ОткрытиеФормы", Истина, );
        
       // Сохраним таблицу команд в параметры регистрации обработки
    РегистрационныеДанные.Вставить("Команды", ТаблицаКоманд);

    Возврат РегистрационныеДанные;

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

Функция ПолучитьТаблицуКоманд()
    
    // Создадим пустую таблицу команд и колонки в ней
    Команды = Новый ТаблицаЗначений;

    // Как будет выглядеть описание печатной формы для пользователя
    Команды.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка")); 

    // Имя нашего макета, что бы могли отличить вызванную команду в обработке печати
    Команды.Колонки.Добавить("Идентификатор", Новый ОписаниеТипов("Строка"));

    // Тут задается, как должна вызваться команда обработки
    // Возможные варианты:
    // - ОткрытиеФормы - в этом случае в колонке идентификатор должно быть указано имя формы, которое должна будет открыть система
    // - ВызовКлиентскогоМетода - вызвать клиентскую экспортную процедуру из модуля формы обработки
    // - ВызовСерверногоМетода - вызвать серверную экспортную процедуру из модуля объекта обработки
    Команды.Колонки.Добавить("Использование", Новый ОписаниеТипов("Строка"));

    // Следующий параметр указывает, необходимо ли показывать оповещение при начале и завершению работы обработки. Не имеет смысла при открытии формы
    Команды.Колонки.Добавить("ПоказыватьОповещение", Новый ОписаниеТипов("Булево"));

    // Для печатной формы должен содержать строку ПечатьMXL 
    Команды.Колонки.Добавить("Модификатор", Новый ОписаниеТипов("Строка"));
    Возврат Команды;
   
КонецФункции

Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование = "ОткрытиеФормы", ПоказыватьОповещение = Ложь, Модификатор)
    
    // Добавляем команду в таблицу команд по переданному описанию.
    // Параметры и их значения можно посмотреть в функции ПолучитьТаблицуКоманд
    НоваяКоманда = ТаблицаКоманд.Добавить();
    НоваяКоманда.Представление = Представление;
    НоваяКоманда.Идентификатор = Идентификатор;
    НоваяКоманда.Использование = Использование;
    НоваяКоманда.ПоказыватьОповещение = ПоказыватьОповещение;
    НоваяКоманда.Модификатор = Модификатор;

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

Универсальные функции для регистрации внешних отчетов. Для внешнего отчета (*.erf)

1 buketoff 17 3
Функция СведенияОВнешнейОбработке() Экспорт
    
    ИмяОтчета = ЭтотОбъект.Метаданные().Имя; 
    Синоним = ЭтотОбъект.Метаданные().Синоним; 
    Синоним = ?(ЗначениеЗаполнено(Синоним),Синоним, ИмяОтчета);         
    РегистрационныеДанные = Новый Структура;
    РегистрационныеДанные.Вставить("Вид","ДополнительныйОтчет"); //может быть – ПечатнаяФорма, ЗаполнениеОбъекта (для вн.обработки), ДополнительныйОтчет, СозданиеСвязанныхОбъектов… 
    РегистрационныеДанные.Вставить("Наименование", Синоним); //имя под которым обработка будет зарегестрирована в справочнике внешних обработок
    РегистрационныеДанные.Вставить("Версия", "1.0");
    РегистрационныеДанные.Вставить("БезопасныйРежим", Ложь);
    РегистрационныеДанные.Вставить("Информация", "Отчет "+Синоним); //так будет выглядеть описание вн.отчета для пользователя
    
    ТаблицаКоманд = ПолучитьТаблицуКоманд();
    
    // Добавим команду в таблицу
    ДобавитьКоманду(ТаблицаКоманд, Синоним, "СформироватьОтчет" , "ОткрытиеФормы", Истина, );
        
    // Сохраним таблицу команд в параметры регистрации обработки
    РегистрационныеДанные.Вставить("Команды", ТаблицаКоманд);
    
    Возврат РегистрационныеДанные;
                                       
КонецФункции

Функция ПолучитьТаблицуКоманд()
    
    // Создадим пустую таблицу команд и колонки в ней
    Команды = Новый ТаблицаЗначений;

    // Как будет выглядеть описание печатной формы для пользователя
    Команды.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка")); 

    // Имя нашего макета, что бы могли отличить вызванную команду в обработке печати
    Команды.Колонки.Добавить("Идентификатор", Новый ОписаниеТипов("Строка"));

    // Тут задается, как должна вызваться команда обработки
    // Возможные варианты:
    // - ОткрытиеФормы - в этом случае в колонке идентификатор должно быть указано имя формы, которое должна будет открыть система
    // - ВызовКлиентскогоМетода - вызвать клиентскую экспортную процедуру из модуля формы обработки
    // - ВызовСерверногоМетода - вызвать серверную экспортную процедуру из модуля объекта обработки
    Команды.Колонки.Добавить("Использование", Новый ОписаниеТипов("Строка"));

    // Следующий параметр указывает, необходимо ли показывать оповещение при начале и завершению работы обработки. Не имеет смысла при открытии формы
    Команды.Колонки.Добавить("ПоказыватьОповещение", Новый ОписаниеТипов("Булево"));

    // Для печатной формы должен содержать строку ПечатьMXL 
    Команды.Колонки.Добавить("Модификатор", Новый ОписаниеТипов("Строка"));
    Возврат Команды;
   
КонецФункции

Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование = "ОткрытиеФормы", ПоказыватьОповещение = Ложь, Модификатор = "ПечатьMXL")
    
    // Добавляем команду в таблицу команд по переданному описанию.
    // Параметры и их значения можно посмотреть в функции ПолучитьТаблицуКоманд
    НоваяКоманда = ТаблицаКоманд.Добавить();
    НоваяКоманда.Представление = Представление;
    НоваяКоманда.Идентификатор = Идентификатор;
    НоваяКоманда.Использование = Использование;
    НоваяКоманда.ПоказыватьОповещение = ПоказыватьОповещение;
    НоваяКоманда.Модификатор = Модификатор;

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

Сведения о внешней обработке - Печать

Сведения о внешней печатной формы для использования совместно с БСП
2 reborn85 17 3
#Область ОсновныеНастройкиДляПодключенияПечать
Функция ВернутьСтруктуруПараметров()
	
	Структура = Новый Структура();
	Структура.Вставить("Документ","Документ.АктОРасхожденияхПриПоступленииТоваров");
	Структура.Вставить("Представление",ЭтотОбъект.Метаданные().Представление());
	Структура.Вставить("Наименование",ЭтотОбъект.Метаданные().Синоним);
	Структура.Вставить("Идентификатор",ЭтотОбъект.Метаданные().Имя);
	Структура.Вставить("Версия","1.0.0.0");
	Возврат Структура;	
	
КонецФункции 


Функция	СведенияОВнешнейОбработке() ЭКСПОРТ
	
	Структура = ВернутьСтруктуруПараметров();
	Версия = СтандартныеПодсистемыСервер.ВерсияБиблиотеки();
	Сведения = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке(Версия);
	Сведения.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиПечатнаяФорма();
	Сведения.Версия = Структура.Версия;
	
	МассивНазначений = Новый Массив();
	МассивНазначений.Добавить(Структура.Документ);
	Сведения.Назначение = МассивНазначений;
	Сведения.Наименование = Структура.Наименование;
	
	стр = Сведения.Команды.Добавить();
	стр.Представление = Структура.Представление;
	стр.Идентификатор = Структура.Идентификатор;
	стр.Модификатор	  = "ПечатьMXL";
	стр.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовСерверногоМетода();	
	Возврат Сведения;
	
КонецФункции

Функция Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) ЭКСПОРТ
	
	Структура = ВернутьСтруктуруПараметров();
	
	Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, Структура.Идентификатор) Тогда
		УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(КоллекцияПечатныхФорм, Структура.Идентификатор, Структура.Представление, СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати));
	КонецЕсли;
	
КонецФункции

Функция СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати)
	
	ТабличныйДокумент = Новый ТабличныйДокумент;
	
	
	Возврат ТабличныйДокумент;
	
КонецФункции
#КонецОбласти

Объединить заголовки табличного документа

Нужно использовать функцию после формирования табличного документа
reborn85 17 3
Функция ОбработатьЗаголовки(ТабДок)
    ВысотаФ = ТабДок.ФиксацияСверху;
    ШиринаФ = ТабДок.ФиксацияСлева;
    ШиринаТаблицы = ТабДок.ШиринаТаблицы;
    МассивМассивовОбъединяемыхОбластей = Новый Массив;
    МассивОбъединяемыхОбластей = Новый Массив;
    НачальнаяКолонка = ШиринаФ + 1;
    КонечнаяКолонка = ШиринаТаблицы;
    МассивОбъединяемыхОбластей.Добавить(Новый Структура("НачальнаяКолонка, КонечнаяКолонка", НачальнаяКолонка, КонечнаяКолонка));
    МассивМассивовОбъединяемыхОбластей.Добавить(МассивОбъединяемыхОбластей);    
    Строка = 1;
    Пока Строка <= ВысотаФ Цикл
        Если Строка = МассивМассивовОбъединяемыхОбластей.Количество() Тогда
            Для Каждого ОбъединяемаяОбласть Из МассивМассивовОбъединяемыхОбластей[Строка-1] Цикл
                НачальнаяКолонка = ОбъединяемаяОбласть.НачальнаяКолонка;            
                КонечнаяКолонка = ОбъединяемаяОбласть.КонечнаяКолонка;
                Колонка = НачальнаяКолонка;
                Пока Колонка <= КонечнаяКолонка Цикл
                    Если НЕ ОбъединятьЯчейки(ТабДок, Строка, Колонка) ИЛИ Колонка = КонечнаяКолонка Тогда
                        Если Колонка <> НачальнаяКолонка Тогда
                            МассивОбъединяемыхОбластей.Добавить(Новый Структура("НачальнаяКолонка, КонечнаяКолонка", НачальнаяКолонка, Колонка));
                        КонецЕсли;
                        НачальнаяКолонка = Колонка + 1;
                    КонецЕсли;    
                    Колонка = Колонка + 1;
                КонецЦикла;
            КонецЦикла;
            Если МассивОбъединяемыхОбластей.Количество() = 0 И ОбъединяемаяОбласть.НачальнаяКолонка = ШиринаФ + 1 И ОбъединяемаяОбласть.КонечнаяКолонка = ШиринаТаблицы Тогда
                МассивОбъединяемыхОбластей.Добавить(Новый Структура("НачальнаяКолонка, КонечнаяКолонка", ОбъединяемаяОбласть.НачальнаяКолонка, ОбъединяемаяОбласть.КонечнаяКолонка));
            КонецЕсли;    
            МассивМассивовОбъединяемыхОбластей.Добавить(МассивОбъединяемыхОбластей);
            МассивОбъединяемыхОбластей = Новый Массив;
        КонецЕсли;
        Строка = Строка + 1;
    КонецЦикла;
    Строка = 1;
    Пока Строка < МассивМассивовОбъединяемыхОбластей.Количество() Цикл
        Для Каждого ОбъединяемаяОбласть Из МассивМассивовОбъединяемыхОбластей[Строка] Цикл
            ТекстЗаголовка = ТабДок.Область(Строка, ОбъединяемаяОбласть.НачальнаяКолонка).Текст;
            ОбъединяемаяОбласть = ТабДок.Область(Строка, ОбъединяемаяОбласть.НачальнаяКолонка, Строка, ОбъединяемаяОбласть.КонечнаяКолонка);
            ОбъединяемаяОбласть.Объединить();
            ОбъединяемаяОбласть.ГоризонтальноеПоложение = ГоризонтальноеПоложение.Центр;
            ОбъединяемаяОбласть.Текст = ТекстЗаголовка;        
        КонецЦикла;
        Строка = Строка + 1;
    КонецЦикла;
    Возврат ТабДок;
КонецФункции

Функция ОбъединятьЯчейки(ТабДок, Строка, НачальнаяКолонка)
    Ячейка = ТабДок.Область(Строка, НачальнаяКолонка);
    ЯчейкаСлед = ТабДок.Область(Строка, НачальнаяКолонка+1);
    Если ПустаяСтрока(Ячейка.Текст) Тогда
        Возврат ложь
    ИначеЕсли
        Ячейка.Текст = ЯчейкаСлед.Текст
            И Ячейка.Верх = Ячейка.Низ И ЯчейкаСлед.Верх = ЯчейкаСлед.Низ Тогда
        Возврат Истина;
    Иначе
        Возврат ложь;
    КонецЕсли;
КонецФункции

Печать БСП по табличному документу

3 reborn85 17 3
	МодульУправлениеПечатьюКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("УправлениеПечатьюКлиент");
	ИдентификаторПечатнойФормы = "ПечатьДокумент";
	
	КоллекцияПечатныхФорм = МодульУправлениеПечатьюКлиент.НоваяКоллекцияПечатныхФорм(ИдентификаторПечатнойФормы);
	ПечатнаяФорма = МодульУправлениеПечатьюКлиент.ОписаниеПечатнойФормы(КоллекцияПечатныхФорм, ИдентификаторПечатнойФормы);
	ПечатнаяФорма.СинонимМакета = НСтр("ru = 'Наименование заголовка'");
	ПечатнаяФорма.ТабличныйДокумент = ТабличныйДокумент;  //указываем подготовленный табличный документ
	ПечатнаяФорма.ТабличныйДокумент.АвтоМасштаб = Истина;  //по ширине страницы

	МодульУправлениеПечатьюКлиент.ПечатьДокументов(КоллекцияПечатныхФорм);

Загрузка коммерческих предложений из FTP сайта в 1С УТ 11.4 в формате XML и создание по ним документов "Заказ клиента"

Yuriy K. 18 2
Процедура ЮКОЗ_ЗагрузкаКП() Экспорт
	
	//Инициализируем константные переменные
	КаталогВрФл 		= КаталогВременныхФайлов();
	ВидНоменклатуры 	= РегистрыСведений.ЮКОЗ_ДополнительныеНастройки.ПолучитьНастройки("ВидыНоменклатурыТовар");
	ЕдиницаИзмШТ 		= РегистрыСведений.ЮКОЗ_ДополнительныеНастройки.ПолучитьНастройки("ЕдиницаИзмерения_ШТ");
	ПриоритетСредний 	= РегистрыСведений.ЮКОЗ_ДополнительныеНастройки.ПолучитьНастройки("ПриоритетСредний");
	СкладОсновной 		= РегистрыСведений.ЮКОЗ_ДополнительныеНастройки.ПолучитьНастройки("СкладОсновной");
	ТиповоеСоглашение 	= РегистрыСведений.ЮКОЗ_ДополнительныеНастройки.ПолучитьНастройки("ТиповоеСоглашение");
	ВалютаДок 			= Константы.ВалютаРегламентированногоУчета.Получить(); 
	АдресFTP			= РегистрыСведений.ЮКОЗ_ДополнительныеНастройки.ПолучитьНастройки("АдресFTP");
	ЛогинFTP			= РегистрыСведений.ЮКОЗ_ДополнительныеНастройки.ПолучитьНастройки("ЛогинFTP");
	ПарольFTP			= РегистрыСведений.ЮКОЗ_ДополнительныеНастройки.ПолучитьНастройки("ПарольFTP");
	
	//Соединямся с FTP-сервером и ищем необработанные файлы xml
	ФТПСоединение = Новый FTPСоединение(АдресFTP,, ЛогинFTP, ПарольFTP,, Истина);
	НайдемФайлаНаФТП = ФТПСоединение.НайтиФайлы("/", "*.xml");
	
	//Если файлов нет, значит завершаем работу
	Если НайдемФайлаНаФТП.Количество() = 0 Тогда
		ФТПСоединение = Неопределено;
		Возврат;
	КонецЕсли;
	
	//Подготавливаем таблицу значений для заполнения загружаемыми данными
	ДанныеИзФайлаТовары = Новый ТаблицаЗначений();
	ДанныеИзФайлаТовары.Колонки.Добавить("Артикул");
	ДанныеИзФайлаТовары.Колонки.Добавить("ИД");
	ДанныеИзФайлаТовары.Колонки.Добавить("Производитель");
	ДанныеИзФайлаТовары.Колонки.Добавить("Номенклатура");
	ДанныеИзФайлаТовары.Колонки.Добавить("Количество");
	ДанныеИзФайлаТовары.Колонки.Добавить("Цена");
	ДанныеИзФайлаТовары.Колонки.Добавить("Размер");
	ДанныеИзФайлаТовары.Колонки.Добавить("Цвет");
	ДанныеИзФайлаТовары.Колонки.Добавить("Серия");
	ДанныеИзФайлаТовары.Колонки.Добавить("ЦенаСоСкидкой");

	//Циклом обходим каждый найденный на FTP файл xml	
	Для каждого ФайлФТП из НайдемФайлаНаФТП Цикл
		
		//Очищаем нашу таблицу значений, чтобы она могла хранить данные только по одному файлу xml
		ДанныеИзФайлаТовары.Очистить();
		
		//Получаем номер коммерческого предложения из имени файла xml
		НомерКП = ФайлФТП.ИмяБезРасширения;
		
		//Очищаем дату коммерческого предложения кототрую мы впоследствии возьмом из тела файла xml
		ДатаКП = "";
						
		//Обернём код в попытку, мало ли будут ошибки при загрузке и обработке файла
		Попытка
			
		//Загружаем файл на локальный компьютер	
		ПутьКФайлуОбъект = КаталогВрФл + ФайлФТП.Имя;
		ФТПСоединение.Получить(ФайлФТП.ПолноеИмя, ПутьКФайлуОбъект);	
		
		//Перемещаем загруженный файл в директорию обработанных файлов на FTP
		//Специально помещаем в начале, чтобы регламентное задание в случае ошибок в этом файле каждый раз не спотыкалось об него
		ФТПСоединение.Переместить(ФайлФТП.ПолноеИмя, "OldFiles" + "\" + ФайлФТП.Имя);
		
		//Инициализируем чтение файла xml
		ЧтениеXML = Новый ЧтениеXML;
		ЧтениеXML.ОткрытьФайл(ПутьКФайлуОбъект);
		
		//Циклом обходим узлы XML файла и при совпадении с нужным именем узла записываем его значение в нашу таблицу значений
		Пока ЧтениеXML.Прочитать() Цикл
			Если ЧтениеXML.ТипУзла <> ТипУзлаXML.НачалоЭлемента Тогда Продолжить; КонецЕсли;
			ИмяУзла = ЧтениеXML.ЛокальноеИмя;	
			Если ИмяУзла = "PRODUCT" Тогда
				НоваяСтрока = ДанныеИзФайлаТовары.Добавить();
				Продолжить;
			КонецЕсли;
			Если ИмяУзла = "ID" Тогда
				ЧтениеXML.Прочитать();
				НоваяСтрока.ИД = СокрЛП(ЧтениеXML.Значение);
				Продолжить;
			КонецЕсли;
			Если ИмяУзла = "ARTICLE" Тогда
				ЧтениеXML.Прочитать();
				НоваяСтрока.Артикул = СокрЛП(ЧтениеXML.Значение);
				Продолжить;
			КонецЕсли;
			Если ИмяУзла = "SIZE" Тогда
				ЧтениеXML.Прочитать();
				НоваяСтрока.Размер = СокрЛП(ЧтениеXML.Значение);
				Продолжить;
			КонецЕсли;
			Если ИмяУзла = "COLOR" Тогда
				ЧтениеXML.Прочитать();
				НоваяСтрока.Цвет = СокрЛП(ЧтениеXML.Значение);
				Продолжить;
			КонецЕсли;
			Если ИмяУзла = "NAME" И ЧтениеXML.КонтекстПространствИмен.Глубина = 5 Тогда
				ЧтениеXML.Прочитать();
				НоваяСтрока.Серия = СокрЛП(ЧтениеXML.Значение);
				Продолжить;
			КонецЕсли;
			Если ИмяУзла = "PROPERTY_PROVIDER_NAME" И ЧтениеXML.КонтекстПространствИмен.Глубина = 5 Тогда
				ЧтениеXML.Прочитать();
				НоваяСтрока.Производитель = СокрЛП(ЧтениеXML.Значение);
				Продолжить;
			КонецЕсли;
			Если ИмяУзла = "NAME" Тогда
				ЧтениеXML.Прочитать();
				НоваяСтрока.Номенклатура = СокрЛП(ЧтениеXML.Значение);
				Продолжить;
			КонецЕсли;
			Если ИмяУзла = "QUANTITY" Тогда
				ЧтениеXML.Прочитать();
				НоваяСтрока.Количество = СокрЛП(ЧтениеXML.Значение);
				Продолжить;
			КонецЕсли;
			Если ИмяУзла = "PRICE" Тогда
				ЧтениеXML.Прочитать();
				НоваяСтрока.Цена = СокрЛП(ЧтениеXML.Значение);
				Продолжить;
			КонецЕсли;
			Если ИмяУзла = "PRICE_DISCOUNT" Тогда
				ЧтениеXML.Прочитать();
				НоваяСтрока.ЦенаСоСкидкой = СокрЛП(ЧтениеXML.Значение);
				Продолжить;
			КонецЕсли;
			Если ИмяУзла = "DATE" Тогда
				ЧтениеXML.Прочитать();
				ДатаСтр = СокрЛП(ЧтениеXML.Значение);
				ДатаКП = Дата(ДатаСтр);
				Продолжить;
			КонецЕсли;
		КонецЦикла;
		
		//Закрываем чтение XML и удаляем ранее загруженный временный файл из нашего компьютера
		ЧтениеXML.Закрыть();
		УдалитьФайлы(ПутьКФайлуОбъект);
		
		//Дата коммерческого предложения обязательно должна быть заполнена, если нет, то вызываем ошибку с пояснением для журнала регистрации
		Если НЕ ЗначениеЗаполнено(ДатаКП) Тогда
			ВызватьИсключение "Пустая дата по КП " + НомерКП;	
		КонецЕсли;
		
		//Запросом найдем уже созданный ранее заказ клиента по загружаемому файлу
		//Плохо, что запрос в цикле, но в данном случае можно ;) дабы не усложнять код.
		ЗапросСущЗаказа = Новый Запрос();
		ЗапросСущЗаказа.УстановитьПараметр("НомерКП", НомерКП);
		ЗапросСущЗаказа.УстановитьПараметр("ДатаКП", НачалоДня(ДатаКП));
		ЗапросСущЗаказа.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1
		                        |	ЗаказКлиента.Ссылка КАК Ссылка,
		                        |	ЗаказКлиента.Проведен КАК Проведен
		                        |ИЗ
		                        |	Документ.ЗаказКлиента КАК ЗаказКлиента
		                        |ГДЕ
		                        |	ЗаказКлиента.НомерПоДаннымКлиента = &НомерКП
		                        |	И ЗаказКлиента.ДатаПоДаннымКлиента = &ДатаКП";
		Результат_ЗапросСущЗаказа = ЗапросСущЗаказа.Выполнить().Выбрать();
		
		//Если заказ клиента найден и он проведен, то обновлять\изменять мы его уже не можем и вызываем ошибку с пояснением,
		//если еще не проведен, то получаем ссылку на документ и работаем дальше
		Если Результат_ЗапросСущЗаказа.Следующий() Тогда
			Если Результат_ЗапросСущЗаказа.Проведен Тогда
				ВызватьИсключение "Заказ уже проведен по КП " + НомерКП;	
			КонецЕсли;
			ДокЗаказ = Результат_ЗапросСущЗаказа.Ссылка.ПолучитьОбъект();
			
		//Если заказ клиента по загружаемому xml файлу еще не было, то создаем и заполняем его	
		Иначе
			ДокЗаказ = Документы.ЗаказКлиента.СоздатьДокумент();
			ДокЗаказ.Дата = ТекущаяДата();		
			ДокЗаказ.ЮКОЗ_НомерКПИзСайта = НомерКП;
			ДокЗаказ.Приоритет = ПриоритетСредний;
			ДокЗаказ.ХозяйственнаяОперация = Перечисления.ХозяйственныеОперации.РеализацияКлиенту;
			ДокЗаказ.ЦенаВключаетНДС = Истина;
			ДокЗаказ.НалогообложениеНДС = Перечисления.ТипыНалогообложенияНДС.ПродажаОблагаетсяНДС;
			ДокЗаказ.НомерПоДаннымКлиента = НомерКП;
			ДокЗаказ.ДатаПоДаннымКлиента = ДатаКП;
			ДокЗаказ.Склад = СкладОсновной;
			ДокЗаказ.Статус = Перечисления.СтатусыЗаказовКлиентов.КОтгрузке;
			ДокЗаказ.ЮКОЗ_Статус = Перечисления.ЮКОЗ_СтатусыЗаказовКлиентов.Согласование;
			ДокЗаказ.Валюта = ВалютаДок;
			ДокЗаказ.Соглашение = ТиповоеСоглашение;
			ДокЗаказ.НеОтгружатьЧастями = Истина;
			ДокЗаказ.ПорядокОплаты = Перечисления.ПорядокОплатыПоСоглашениям.РасчетыВВалютеОплатаВВалюте;
			ДокЗаказ.ФормаОплаты = Перечисления.ФормыОплаты.Безналичная;
		КонецЕсли;
		
		//Очистим табличную часть Товары (на тот случай, если заказ клиента уже был ранее создан и там были какие-то данные)
		ДокЗаказ.Товары.Очистить();
		
		//Обходим данные из файла через нашу таблицу значений
		Для каждого стр из ДанныеИзФайлаТовары Цикл
			
			//Проверям на заполнение обязательный полей (артикул, производитель, номенклатура), если хоть что-то не заполнено, то вызываем ошибку с пояснением
			Если НЕ ЗначениеЗаполнено(стр.Артикул) И НЕ ЗначениеЗаполнено(стр.ИД) Тогда
				ВызватьИсключение "Пустой артикул и ID по КП " + НомерКП;	
			КонецЕсли;
			Если НЕ ЗначениеЗаполнено(стр.Производитель) Тогда
				ВызватьИсключение "Пустой производитель по КП " + НомерКП;	
			КонецЕсли;
			Если НЕ ЗначениеЗаполнено(стр.Номенклатура) Тогда
				ВызватьИсключение "Пустая номенклатура по КП " + НомерКП;	
			КонецЕсли;
			
			//Пытаемся найти уже созданную номенклатуру по артикулу, а если он не заполнен, то по ИД.
			ЗапросСущТовара = Новый Запрос();
			ЗапросСущТовара.УстановитьПараметр("ИД", стр.ИД);
			ЗапросСущТовара.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1
			                        |	Номенклатура.Ссылка КАК Ссылка
			                        |ИЗ
			                        |	Справочник.Номенклатура КАК Номенклатура
			                        |ГДЕ" + Символы.ПС;
			Если ЗначениеЗаполнено(стр.Артикул) Тогда						
				ЗапросСущТовара.Текст = ЗапросСущТовара.Текст + "Номенклатура.Артикул = &Артикул";
			Иначе	
			    ЗапросСущТовара.Текст = ЗапросСущТовара.Текст + "Номенклатура.ЮКОЗ_IDИзСайта = &ИД";
			КонецЕсли;
			Результат_ЗапросСущТовара = ЗапросСущТовара.Выполнить().Выбрать();
			
			//Формируем представление строки описания номенклатуры (строковая характеристика)
			ДобТоварЮКОЗ_Характеристика = ?(ЗначениеЗаполнено(стр.Серия), стр.Серия + ", ", "") +
				                           ?(ЗначениеЗаполнено(стр.Размер), стр.Размер + ", ", "") +
										   ?(ЗначениеЗаполнено(стр.Цвет), стр.Цвет, "");

			//Получаем ссылку на номенклатуру если она найдена
			Если Результат_ЗапросСущТовара.Следующий() Тогда
				ТоварСсылка = Результат_ЗапросСущТовара.Ссылка;
				
			//Если номенклатура не найдена, то создаем её	
			Иначе
				ТоварНовый = Справочники.Номенклатура.СоздатьЭлемент();
				
				//Каждая номенлатура должна находится в своей группе в справочнике номенклатура, где название группы - это наименование производителя
				//проверяем это запросом
				ЗапросСущГруппы = Новый Запрос();
				ЗапросСущГруппы.УстановитьПараметр("Производитель", стр.Производитель);
				ЗапросСущГруппы.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1
				                        |	Номенклатура.Ссылка КАК Ссылка
				                        |ИЗ
				                        |	Справочник.Номенклатура КАК Номенклатура
				                        |ГДЕ
				                        |	Номенклатура.Наименование = &Производитель
				                        |	И Номенклатура.ЭтоГруппа";
				Результат_ЗапросСущГруппы = ЗапросСущГруппы.Выполнить().Выбрать();
				
				//Если группа найдено, то берем ссылку на неё
				Если Результат_ЗапросСущГруппы.Следующий() Тогда
					ГруппаТовараСсылка = Результат_ЗапросСущГруппы.Ссылка;
					
				//Если группа не найдена, то создаем её	
				Иначе
					ГруппаТовараСсылка = Справочники.Номенклатура.СоздатьГруппу();
					ГруппаТовараСсылка.Наименование = стр.Производитель;
					ГруппаТовараСсылка.Записать();
					ГруппаТовараСсылка = ГруппаТовараСсылка.Ссылка;
				КонецЕсли;
				
				//Указываем, что номенклатуру мы создаем в группе которую нашли\создали чуть ранее
				ТоварНовый.Родитель = ГруппаТовараСсылка;
				
				//Формируем представление наименования номенклатуры, оно должно содержать артикул, а если его нет, то ИД
				//Также записываем артикул, если его нет, то ИД вместо него.
				Если ЗначениеЗаполнено(стр.Артикул) Тогда						
					ТоварНовый.Артикул = стр.Артикул;
					ТоварНовый.Наименование = Строка(?(ЗначениеЗаполнено(стр.Артикул), "(" + стр.Артикул + ") ", "") + стр.Номенклатура);
				Иначе	
					ТоварНовый.Наименование = Строка(?(ЗначениеЗаполнено(стр.ИД), "(" + стр.ИД + ") ", "") + стр.Номенклатура);
			    	ТоварНовый.Артикул = стр.ИД;
				КонецЕсли;
				
				//Добавляем в наименование номенклатуры строковое описание номенклатуры, которое мы сформировали ранее,
				//при условии, что описание номенклатуры есть и оно уже не встречается в наименовании номенклатуры
				Если ЗначениеЗаполнено(ДобТоварЮКОЗ_Характеристика) Тогда 
					Если СтрНайти(СтрЗаменить(ТоварНовый.Наименование, ",", ""), 
								  СтрЗаменить(ДобТоварЮКОЗ_Характеристика, ",", "")) = 0 Тогда
						ТоварНовый.Наименование = ТоварНовый.Наименование + ", " + ДобТоварЮКОЗ_Характеристика;	
					КонецЕсли;
				КонецЕсли;
				
				//Заполняем остальные поля номенклатуры
				ТоварНовый.ЮКОЗ_IDИзСайта = стр.ИД;
				ТоварНовый.ТипНоменклатуры = Перечисления.ТипыНоменклатуры.Товар;
				ТоварНовый.ВидНоменклатуры = ВидНоменклатуры;
  			    ТоварНовый.НаименованиеПолное = стр.Номенклатура + ?(ЗначениеЗаполнено(ДобТоварЮКОЗ_Характеристика), 
																	  ", " + ДобТоварЮКОЗ_Характеристика, "");
				ТоварНовый.СтавкаНДС = Перечисления.СтавкиНДС.НДС20;
				ТоварНовый.ЕдиницаИзмерения = ЕдиницаИзмШТ;
				ТоварНовый.ЕдиницаДляОтчетов = ЕдиницаИзмШТ;
				ТоварНовый.ИспользованиеХарактеристик = Перечисления.ВариантыИспользованияХарактеристикНоменклатуры.НеИспользовать;
				ТоварНовый.ВариантОформленияПродажи = Перечисления.ВариантыОформленияПродажи.РеализацияТоваровУслуг;
				
				//Ищем производителя, если его нет, то создаем нового и указываем его в номенклатуре
				ПроизводительСсылка = Справочники.Производители.НайтиПоНаименованию(стр.Производитель);
				Если НЕ ЗначениеЗаполнено(ПроизводительСсылка) Тогда
					НовыйПроизводитель = Справочники.Производители.СоздатьЭлемент();
					НовыйПроизводитель.Наименование = стр.Производитель;
					НовыйПроизводитель.Записать();
					ПроизводительСсылка = НовыйПроизводитель.Ссылка;
				КонецЕсли;
				
				ТоварНовый.Производитель = ПроизводительСсылка;
				
				//Записываем новую номенклатуру и получаем ссылку на неё
				ТоварНовый.Записать();
				ТоварСсылка = ТоварНовый.Ссылка;
				
			КонецЕсли;
			
			//Добавляем в табличную часть Товары номенклатуру с заполнением данных из файла xml
			ДобТовар = ДокЗаказ.Товары.Добавить();
			ДобТовар.Номенклатура = ТоварСсылка;
			ДобТовар.Количество = стр.Количество;
			ДобТовар.КоличествоУпаковок = стр.Количество;
			ДобТовар.Упаковка = ДобТовар.Номенклатура.ЕдиницаИзмерения;
			ДобТовар.Цена = стр.Цена;
			ДобТовар.СтавкаНДС = ДобТовар.Номенклатура.СтавкаНДС;
			ДобТовар.Склад = СкладОсновной;
			ДобТовар.ЮКОЗ_Характеристика = ДобТоварЮКОЗ_Характеристика;
			
			//Вычисляем процент ручной скидки, если в файле xml была указана цена со скидкой и она меньше, чем обычная цена
			Если ЗначениеЗаполнено(стр.ЦенаСоСкидкой) И ЗначениеЗаполнено(стр.Цена) Тогда 
				стрЦенаСоСкидкой = Число(стр.ЦенаСоСкидкой);
				стрЦена = Число(стр.Цена);		
				Если стрЦенаСоСкидкой > 0 И стрЦена > 0 И стрЦена > стрЦенаСоСкидкой Тогда
					ДобТовар.ПроцентРучнойСкидки = (стрЦенаСоСкидкой / стрЦена - 1) * 100 * -1;
				КонецЕсли;
			КонецЕсли;
						
		КонецЦикла;
		
		//Посчитаем сумму строки, а также НДС
		СтруктураПересчетаСуммы = ОбработкаТабличнойЧастиКлиентСервер.ПараметрыПересчетаСуммыНДСВСтрокеТЧ(ДокЗаказ);	
		СтруктураДействий = Новый Структура;	
		СтруктураДействий.Вставить("ПересчитатьСумму", "КоличествоУпаковок");
		СтруктураДействий.Вставить("ПересчитатьСуммуНДС", СтруктураПересчетаСуммы);
		СтруктураДействий.Вставить("ПересчитатьСуммуСНДС", СтруктураПересчетаСуммы);
		ОбработкаТабличнойЧастиСервер.ОбработатьТЧ(ДокЗаказ.Товары, СтруктураДействий, Неопределено);
		
		//Запишем заказ клиента без проведения
		ДокЗаказ.Записать(РежимЗаписиДокумента.Запись);
		
		//Обработаем исключения в блоке попытки с записью в журнал регистрации для дальнейшего анализа
		Исключение
			ЗаписьЖурналаРегистрации("Ошибка обработки КП из сайта: " + ОписаниеОшибки(), УровеньЖурналаРегистрации.Ошибка);
		КонецПопытки;
		
	КонецЦикла;
	
	//После обработки всех файлов, закроем FTP соединение.
	ФТПСоединение = Неопределено;
	
КонецПроцедуры

Запуск длительной процедуры в фоне

Автор: HostHost

2 FastCode 29 4
НаименованиеЗадания = НСтр("ru = 'Заполнение документа ""Начисление зарплаты""'");

Результат = ДлительныеОперации.ЗапуститьВыполнениеВФоне(

        УникальныйИдентификатор,

        "Документы.НачислениеЗаПервуюПоловинуМесяца.ПодготовитьДанныеДляЗаполнения",

        СтруктураПараметров,

        НаименованиеЗадания);