Умная маршрутизация: о сложностях интеграции с 1С (часть 2)

27.08.21

Интеграция - WEB-интеграция

В статье будет много примеров кода с комментариями работы расширения для обмена данными УТ11.4 с Яндекс.Маршрутизацией через выгрузку/загрузку EXCEL файла.

Скачать файлы

Наименование Файл Версия Размер
Умная маршрутизация: кейс интеграции с 1С. Расширение
.cfe 494,94Kb
38
.cfe 494,94Kb 38 Скачать бесплатно
Пример заполнения EXCEL
.xlsx 15,98Kb
34
.xlsx 15,98Kb 34 Скачать бесплатно

Принцип работы, какие задачи решает и кому подходит - описано в первой части статьи: Умная маршрутизация: кейс интеграции с 1С (часть 1)

Во второй части описана доработка "Рабочего места менеджера по доставке" в УТ 11.4 для обмена данными с Яндекс.Маршрутизацией.

Идея. Нам нужны 2 кнопки: “Загрузить” и “Выгрузить”

Создаём расширение, в нем обработку с тремя кнопками кода и – вуаля:

 

 

  1. Есть нажать на первую кнопку (левую зеленую) формируется готовый Excel. Его нужно подгрузить в Яндекс.Маршрутизацию.
  2. Яндекс.Маршрутизация оптимизирует маршруты водителей и возвращает Excel – Маршрутный лист с параметрами поездки. Если нажать кнопку 2, Маршрутный лист загрузится в 1С и раскидает заказы по маршрутным листам.
  3. Позже появилась кнопка 3 (верхняя длинная) «Стоимость работы водителей». Она открывает отчёт с итогами работы за день/неделю/месяц и авторасчёт зарплаты водителей.

Стоп, нужно же где-то взять список заказов, которые необходимо сегодня доставить. Вспоминаем, что в УТ это Обработки.РабочееМестоМенеджераПоДоставке.

Переносим кнопки туда.

 

Формируем Excel с заказами

 

Чтобы сформировать Excel, нужно решить 3 проблемы (по факту больше, конечно, но кто бы научил точно оценивать все проблемы до начала разработки):

 

Шаг 1. У нас база клиент-серверная, значит Excel сформируется на сервере, а сохранить его надо будет на клиенте. Тут всё стандартно:

&НаКлиенте
Процедура ЯМ_ЯМ_СохранитьВЭксельПосле(Команда)
    //Сохраняем в Эксель на клиенте
    СохранитьПрочитатьЭксельЯндексМаршрутизации("Сохранение");
КонецПроцедуры

&НаКлиенте
Процедура СохранитьПрочитатьЭксельЯндексМаршрутизации(ТипКоманды)
    //Прочитать Эксель на клиенте
    Режим = РежимДиалогаВыбораФайла[ТипКоманды]; 
    ДиалогФайла = Новый ДиалогВыбораФайла(Режим); 
    Если ТипКоманды = "Сохранение" Тогда
        ДиалогФайла.ПолноеИмяФайла = "YaRouting_" + Формат(ТекущаяДата(),"ДФ=yyyyMMdd_HHMMss"); 
    КонецЕсли;
    Фильтр = "Документ Excel (*.xlsx)|*.xlsx|";                 
    ДиалогФайла.Фильтр = Фильтр; 
    ДиалогФайла.МножественныйВыбор = Ложь; 
    ДиалогФайла.Заголовок = "Выберите файл"; 
    Если ДиалогФайла.Выбрать() Тогда 
        Если ТипКоманды = "Сохранение" Тогда
            ОднаКнига = Новый ПакетОтображаемыхДокументов;
            //Создав объект "ОднаКнига", мы можем в его состав поместить несколько табличных документов каким-то таким образом:
            ДобавитьСтраницыВКнигу(ОднаКнига);
            //А сохранить в одну книгу все это хозяйство можно так:
            ОднаКнига.Записать(ДиалогФайла.ПолноеИмяФайла, ТипФайлаПакетаОтображаемыхДокументов.XLSX);
        Иначе
            //Открытие файла
            Адрес = ПоместитьВоВременноеХранилище(Новый ДвоичныеДанные(ДиалогФайла.ПолноеИмяФайла));
            ПрочитатьИОбработатьФайлЯндексМаршрутизации(Адрес, ДиалогФайла.ПолноеИмяФайла);
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

 

Шаг 2. Если вы посмотрели шаблон Excel Яндекс.Маршрутизации https://yandex.ru/routing/doc/vrp/concepts/example.html, то увидели, что в нём несколько страниц. Т.е. нужно сохранить не просто Excel, а сохранить в 1С многостраничный Excel.

Для этого мы на клиенте создаём: 

ОднаКнига = Новый ПакетОтображаемыхДокументов;

и затем серверной процедурой ДобавитьСтраницыВКнигу(ОднаКнига) создаём 4 отдельных Табличных документа, сохраняем их как листы книги ОднаКнига, а на клиенте - многостраничный Excel

ОднаКнига.Записать(ДиалогФайла.ПолноеИмяФайла, ТипФайлаПакетаОтображаемыхДокументов.XLSX).

Для красоты вынес код в общий модуль: и читать удобнее, и использовать повторно.

&НаСервере
Процедура ДобавитьСтраницыВКнигу(ОднаКнига)
    ЯМ_ИнтеграцияСЯндексМаршрутизацией.ДобавитьСтраницыЭкселяДляЯндексМаршрутизации(ОднаКнига, ПолучитьЗаказыНаДоставку(), УникальныйИдентификатор);
КонецПроцедуры

Основная процедура общего модуля заполняет начальные параметры и добавляет 4 страницы в книгу Excel:

Процедура ДобавитьСтраницыЭкселяДляЯндексМаршрутизации(ОднаКнига, ЗаказыНаДоставку, УникальныйИдентификатор) Экспорт
    //Определяем режим времени суток
    РежимВремени = Новый Структура;
    РежимВремени.Вставить("ТекущаяДата",    ТекущаяДата());
    РежимВремени.Вставить("СейчасВечер",     ?(Час(РежимВремени.ТекущаяДата)>= 15, Истина, Ложь)        );
    РежимВремени.Вставить("СейчасВыходной", ?(ДеньНедели(РежимВремени.ТекущаяДата)>=6, Истина, Ложь));
    РежимВремени.Вставить("Суффикс",         ?(РежимВремени.СейчасВечер, "_НОЧЬ", "_ДЕНЬ"));
    РежимВремени.Вставить("СуффиксОбщий",   ?(РежимВремени.СейчасВыходной, "_ВЫХОДНОЙ", ?(РежимВремени.СейчасВечер, "_НОЧЬ", "_ДЕНЬ")));
   
    //Добавляем страницу Опций   
    ДобавитьСтраницуВЭксель(ОднаКнига, "Orders", УникальныйИдентификатор, ЗаказыНаДоставку, РежимВремени);
    ДобавитьСтраницуВЭксель(ОднаКнига, "Vehicles", УникальныйИдентификатор,,РежимВремени);
    ДобавитьСтраницуВЭксель(ОднаКнига, "Depot", УникальныйИдентификатор,,РежимВремени);
    ДобавитьСтраницуВЭксель(ОднаКнига, "Options", УникальныйИдентификатор,,РежимВремени);
   
КонецПроцедуры

И, наконец, код добавления страниц:

&НаСервере
Процедура ДобавитьСтраницуВЭксель(ОднаКнига, НазваниеСтраницыЭксель, УникальныйИдентификатор, ЗаказыНаДоставку = Неопределено, РежимВремени)
    Элт = ОднаКнига.Состав.Добавить();
    Элт.Наименование = НазваниеСтраницыЭксель;
    Элт.Данные = ВыгрузитьТабДокВовременноеХранилищеНаСервере(НазваниеСтраницыЭксель, УникальныйИдентификатор, ЗаказыНаДоставку, РежимВремени);
КонецПроцедуры

Как вы заметили, всё довольно просто. Нужно указать название нового листа Элт.Наименование  и добавить данные  Элт.Данные.

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

 

Шаг 3. Шапки страниц с названием колонок (именно по ним Яндекс.Маршрутизация считывает значения параметров) мы храним в виде макетов и называем их как страницы в формируемом Excel. Это позволяет использовать парадигму, так называемого, самопишушегося кода

Макет = Обработки.РабочееМестоМенеджераПоДоставке.ПолучитьМакет("" + НазваниеСтраницыЭксель);

 

 

Orders

 

Vehicles

Depot

 

Options

 

Шаг 4. Самая неаккуратная процедура заполнения строки:

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

        ЗаполнитьСтрокуИДобавитьТабДок(Макет, ТабДок, ПараметрыСклада);

    ///////////////////  "Options"
    ИначеЕсли НазваниеСтраницыЭксель = "Options" Тогда
        ЗаполнитьСтрокуИДобавитьТабДок(Макет, ТабДок, ПолучитьЗаполненныеПараметрыСтрокиОпций());
    ///////////////////  "Vehicles"   
    ИначеЕсли НазваниеСтраницыЭксель = "Vehicles" Тогда
        Машины = ПолучитьСписокМашин();
        Для Каждого Автомобиль ИЗ Машины Цикл
            ПараметрыМашины = ПолучитьЗаполненныеПараметрыСтрокиМашины();           

            ЗаполнитьЗначенияСвойств(ПараметрыМашины,Автомобиль.ТранспортноеСредство);
           
            ПараметрыМашины.ЯМ_НазваниеМашины = "" + Автомобиль.ТранспортноеСредство + " - [" + Автомобиль.Водитель + "]"; 
            ПараметрыМашины.ЯМ_ЛогинКурьера = Автомобиль.ТранспортноеСредство["ЯМ_ЛогинКурьера" + РежимВремени.Суффикс];
            ПараметрыМашины.ЯМ_ВремяНачалаИКонцаСмены = Автомобиль.ТранспортноеСредство["ЯМ_ВремяНачалаИКонцаСмены" + РежимВремени.Суффикс];
           
            ЗаполнитьСтрокуИДобавитьТабДок(Макет, ТабДок, ПараметрыМашины);

        КонецЦикла;
    ///////////////////  "Orders"   
    ИначеЕсли НазваниеСтраницыЭксель = "Orders" Тогда
        Для Каждого СтрЗаказа ИЗ ЗаказыНаДоставку Цикл
            ПараметрыЗаказа = ПолучитьЗаполненныеПараметрыСтрокиЗаказов();
            УточненныеПараметрыЗаказа = ПолучитьУточненныеПараметрыЗаказа(СтрЗаказа);           

            ЗаполнитьЗначенияСвойств(ПараметрыЗаказа, УточненныеПараметрыЗаказа);           

            //Подбираем наиболее подходящее временное окно
            Если УточненныеПараметрыЗаказа.Свойство("ВременноеОкно" + РежимВремени.СуффиксОбщий) Тогда
                ПараметрыЗаказа.ВременноеОкно = УточненныеПараметрыЗаказа["ВременноеОкно" + РежимВремени.СуффиксОбщий];
            ИначеЕсли УточненныеПараметрыЗаказа.Свойство("ВременноеОкно" + РежимВремени.Суффикс) Тогда
                ПараметрыЗаказа.ВременноеОкно = УточненныеПараметрыЗаказа["ВременноеОкно" + РежимВремени.Суффикс];
            КонецЕсли;
           
            //ПараметрыМашины.ЯМ_НазваниеМашины = "" + Автомобиль.ТранспортноеСредство + " - [" + Автомобиль.Водитель + "]"; 
            //ПараметрыМашины.ЯМ_ЛогинКурьера = Автомобиль.ТранспортноеСредство.ЯМ_ЛогинКурьера_ДЕНЬ;
            //ПараметрыМашины.ЯМ_ВремяНачалаИКонцаСмены = Автомобиль.ТранспортноеСредство.ЯМ_ВремяНачалаИКонцаСмены_ДЕНЬ;
           
            ЗаполнитьСтрокуИДобавитьТабДок(Макет, ТабДок, ПараметрыЗаказа);

        КонецЦикла;
    КонецЕсли;   
КонецПроцедуры

Тут мы себе помогли, сделав предзаполнение параметров процедурами:

ПолучитьЗаполненныеПараметрыСтрокиСклада()
ПолучитьЗаполненныеПараметрыСтрокиОпций()
ПолучитьЗаполненныеПараметрыСтрокиМашины()
ПолучитьЗаполненныеПараметрыСтрокиЗаказов()

Функции облегчают чтение кода, а по сути являются сохранённым результатом нашего 2-х месячного подбора параметров. Значения по умолчанию для нашей компании. Приведу их в спойлере, чтобы не загромождать статью:

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

        ЗаполнитьСтрокуИДобавитьТабДок(Макет, ТабДок, ПараметрыСклада);
       
    ///////////////////  "Options"
    ИначеЕсли НазваниеСтраницыЭксель = "Options" Тогда
        ЗаполнитьСтрокуИДобавитьТабДок(Макет, ТабДок, ПолучитьЗаполненныеПараметрыСтрокиОпций());
    ///////////////////  "Vehicles"   
    ИначеЕсли НазваниеСтраницыЭксель = "Vehicles" Тогда
        Машины = ПолучитьСписокМашин();
        Для Каждого Автомобиль ИЗ Машины Цикл
            ПараметрыМашины = ПолучитьЗаполненныеПараметрыСтрокиМашины();
           
            ЗаполнитьЗначенияСвойств(ПараметрыМашины,Автомобиль.ТранспортноеСредство);
           
            ПараметрыМашины.ЯМ_НазваниеМашины = "" + Автомобиль.ТранспортноеСредство + " - [" + Автомобиль.Водитель + "]"; 
            ПараметрыМашины.ЯМ_ЛогинКурьера = Автомобиль.ТранспортноеСредство["ЯМ_ЛогинКурьера" + РежимВремени.Суффикс];
            ПараметрыМашины.ЯМ_ВремяНачалаИКонцаСмены = Автомобиль.ТранспортноеСредство["ЯМ_ВремяНачалаИКонцаСмены" + РежимВремени.Суффикс];
           
            ЗаполнитьСтрокуИДобавитьТабДок(Макет, ТабДок, ПараметрыМашины);

        КонецЦикла;
    ///////////////////  "Orders"   
    ИначеЕсли НазваниеСтраницыЭксель = "Orders" Тогда
        Для Каждого СтрЗаказа ИЗ ЗаказыНаДоставку Цикл
            ПараметрыЗаказа = ПолучитьЗаполненныеПараметрыСтрокиЗаказов();
            УточненныеПараметрыЗаказа = ПолучитьУточненныеПараметрыЗаказа(СтрЗаказа);
           
            ЗаполнитьЗначенияСвойств(ПараметрыЗаказа, УточненныеПараметрыЗаказа);
           
            //Подбираем наиболее подходящее временное окно
            Если УточненныеПараметрыЗаказа.Свойство("ВременноеОкно" + РежимВремени.СуффиксОбщий) Тогда
                ПараметрыЗаказа.ВременноеОкно = УточненныеПараметрыЗаказа["ВременноеОкно" + РежимВремени.СуффиксОбщий];
            ИначеЕсли УточненныеПараметрыЗаказа.Свойство("ВременноеОкно" + РежимВремени.Суффикс) Тогда
                ПараметрыЗаказа.ВременноеОкно = УточненныеПараметрыЗаказа["ВременноеОкно" + РежимВремени.Суффикс];
            КонецЕсли;
           
            //ПараметрыМашины.ЯМ_НазваниеМашины = "" + Автомобиль.ТранспортноеСредство + " - [" + Автомобиль.Водитель + "]"; 
            //ПараметрыМашины.ЯМ_ЛогинКурьера = Автомобиль.ТранспортноеСредство.ЯМ_ЛогинКурьера_ДЕНЬ
            //ПараметрыМашины.ЯМ_ВремяНачалаИКонцаСмены = Автомобиль.ТранспортноеСредство.ЯМ_ВремяНачалаИКонцаСмены_ДЕНЬ;
           
            ЗаполнитьСтрокуИДобавитьТабДок(Макет, ТабДок, ПараметрыЗаказа);

        КонецЦикла;
       
    КонецЕсли;

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

Далее мы уточняем значение параметров строки и запускаем лаконичную  ЗаполнитьСтрокуИДобавитьТабДок(Макет, ТабДок, ЗначенияПараметров).

&НаСервере
Процедура ЗаполнитьСтрокуИДобавитьТабДок(Макет, ТабДок, ЗначенияПараметров)
   
    ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
    ЗаполнитьЗначенияСвойств(ОбластьСтрока.Параметры, ЗначенияПараметров);
    ТабДок.Вывести(ОбластьСтрока);
   
КонецПроцедуры

Такой минималистичный код получился благодаря нашим ПолучитьЗаполненныеПараметры…() и тому, что мы идентично назвали параметры ячеек в макетах страниц (Проблемы шаг 3)

 

Шаг 5. Как хранить дополнительные параметры? Чтобы ускорить разработку, мы решили хранить все параметры в реквизитах Справочников. Сейчас, я бы хранил все параметры, используя стандартный механизм 1С Дополнительных Значений. Это обезопасит пользователей от потери данных, введенных в эти доп. реквизиты, например, если кто-то из сотрудников (админ, конечно, кто же ещё) снесёт расширение, а потом его опять запустит. Но было решено так:

 

 

Внешний вид карточек ТС, клиентов, склада можно посмотреть в первой части статьи - Умная маршрутизация: кейс интеграции с 1С (часть 1) 

 

Шаг 6. Но ведь нам нужны данные - список заказов. А в обработке РабочееМестоМенеджераПоДоставке этот самый список не Список, а деревоЗначений. Что ж, берём поисковик и рисуем рекурсию:

&НаСервере
Функция ПолучитьЗаказыНаДоставку()
   
    ДеревоЗнач = РеквизитФормыВЗначение("РаспоряженияНаДоставку");
    ЗаказыНаДоставку = ПолучитьПустуюТЗ();
    ОбходДереваДетально(ДеревоЗнач, ЗаказыНаДоставку);
   
    Возврат ЗаказыНаДоставку;

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

&НаСервере
Функция ПолучитьПустуюТЗ()
   
    ТЗ = Новый ТаблицаЗначений;
    ТЗ.Колонки.Добавить("Распоряжение");
    ТЗ.Колонки.Добавить("Перевозчик");
    ТЗ.Колонки.Добавить("Адрес");
    ТЗ.Колонки.Добавить("Номер");
    ТЗ.Колонки.Добавить("ПолучательОтправитель");
    ТЗ.Колонки.Добавить("Вес");

    Возврат ТЗ;
   
КонецФункции

//Рекурсивная процедура
&НаСервере
Процедура ОбходДереваДетально(ПереданноеДер, ТЗ)
   
    Для Каждого СтрПолученногоДерева Из ПереданноеДер.Строки Цикл
       
        //Сообщить(СтрПолученногоДерева.Номенклатура);
        Если ЗначениеЗаполнено(СтрПолученногоДерева.Распоряжение) Тогда
            НовСтр = ТЗ.Добавить();
            ЗаполнитьЗначенияСвойств(НовСтр, СтрПолученногоДерева);
        КонецЕсли; 
       
        Если СтрПолученногоДерева.Строки.Количество()>0 Тогда           
            ОбходДереваДетально(СтрПолученногоДерева, ТЗ);           
        КонецЕсли;
       
    КонецЦикла;
   
КонецПроцедуры

Ну вот и всё! Многостраничный EXCEL с заполненными строками для Яндекс.Маршрутизации сформирован, сохранён, казалось бы, можно идти пить чай, но нет… нужно теперь загрузить ответ от Яндекс.Маршрутизации. Ну его этот чай, поехали!

 

Загружаем данные в 1С

 

Шаг 7. Теперь файл - на клиенте, а обработка - на сервере.

&НаКлиенте
Процедура ЯМ_ЯМ_ЗагрузитьМаршрутныеЛистыИзЭксельПосле(Команда)   
    СохранитьПрочитатьЭксельЯндексМаршрутизации("Открытие");
КонецПроцедуры

Процедура получилась универсальной (см. шаг 1), несколько строчек помещаем во временное хранилище и отправляем на сервер:

Адрес = ПоместитьВоВременноеХранилище(Новый ДвоичныеДанные(ДиалогФайла.ПолноеИмяФайла));
            ПрочитатьИОбработатьФайлЯндексМаршрутизации(Адрес, ДиалогФайла.ПолноеИмяФайла);

&НаСервере
Процедура ПрочитатьИОбработатьФайлЯндексМаршрутизации(Адрес, ИмяФайла)
       //вывод в таблицу значений
       ЯМ_ИнтеграцияСЯндексМаршрутизацией.ПрочитатьИОбработатьФайлЯндексМаршрутизации(Адрес, ИмяФайла);  
КонецПроцедуры

 

Шаг 8. Используем современные методы чтения Excel:

Процедура ПрочитатьИОбработатьФайлЯндексМаршрутизации(Адрес, ИмяФайла) Экспорт
    //Необходимо чтение файлов XLS или XLSX
    Расширение = Прав(ИмяФайла, 4);
    Расширение = СтрЗаменить(Расширение, ".", "");
   
    ФайлПриемник = ПолучитьИмяВременногоФайла(Расширение);
    ДанныеХранилища = ПолучитьИзВременногоХранилища(Адрес);
    ДанныеХранилища.Записать(ФайлПриемник);
  
    ТабДок = Новый ТабличныйДокумент;
    ТабДок.Прочитать(ФайлПриемник, СпособЧтенияЗначенийТабличногоДокумента.Значение); 
  
    //вывод в таблицу значений   
    ПЗ = Новый ПостроительЗапроса;
    //ПЗ.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабДок.Область());
    //Загружаем не весь Эксель, а только лист "Маршруты"
    ПЗ.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабДок.ПолучитьОбласть("Маршруты").Область());
    ПЗ.ДобавлениеПредставлений = ТипДобавленияПредставлений.НеДобавлять;
    ПЗ.ЗаполнитьНастройки();
    ПЗ.Выполнить();
   
    ТаблицаЗначений = ПЗ.Результат.Выгрузить();
    ДозаполнитьТЗДаннымиДляЗагрузки(ТаблицаЗначений);  
   
    ЗагрузитьТочкиВМаршрутныеЛисты(ТаблицаЗначений);  

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

Вот этот кусок кода мой любимый:

    //вывод в таблицу значений   
    ПЗ = Новый ПостроительЗапроса;
    //ПЗ.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабДок.Область());
    //Загружаем не весь Эксель, а только лист "Маршруты"
    ПЗ.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабДок.ПолучитьОбласть("Маршруты").Область());
    ПЗ.ДобавлениеПредставлений = ТипДобавленияПредставлений.НеДобавлять;
    ПЗ.ЗаполнитьНастройки();
    ПЗ.Выполнить();
    ТаблицаЗначений = ПЗ.Результат.Выгрузить();

Он подходит для любого Excel, нужно лишь подставить верное название листа. Если Excel одностраничный, то пишем так:

    ПЗ = Новый ПостроительЗапроса;
    ПЗ.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабличныйДокумент.Область());
    ПЗ.ДобавлениеПредставлений = ТипДобавленияПредставлений.НеДобавлять;
    ПЗ.ЗаполнитьНастройки();
    ПЗ.Выполнить();
    ТаблицаЗначений = ПЗ.Результат.Выгрузить();

Т.е. на входе любой Excel, а на выходе - удобная ТаблицаЗначений, в которой колонки названы как в исходном Excel. И не нужно сопоставлять колонки по ячейкам.

 

Шаг 9. Привязываем данные из Excel к своим данным в 1С. Поэтому привожу код без пояснений, он очень персональный, и вам точно не подойдёт, но для целостной картины нужен:

Процедура ДозаполнитьТЗДаннымиДляЗагрузки(ТЗ)

    ТЗ.Колонки.Добавить("Вес");
    ТЗ.Колонки.Добавить("КлючСвязи");
    ТЗ.Колонки.Добавить("Распоряжение");
    ТЗ.Колонки.Добавить("Перевозчик");
    ТЗ.Колонки.Добавить("ПолучательОтправитель");
    ТЗ.Колонки.Добавить("Склад");
    ТЗ.Колонки.Добавить("Доставлено");
    ТЗ.Колонки.Добавить("ДоставляетсяПолностью");
    ТЗ.Колонки.Добавить("ВремяС");
    ТЗ.Колонки.Добавить("ВремяПо");
    ТЗ.Колонки.Добавить("АдресЗначенияПолей");
    ТЗ.Колонки.Добавить("ДополнительнаяИнформация");
    ТЗ.Колонки.Добавить("ИдентификаторМашиныДля1С");
   
    ПрефиксУИД = "" + Формат(ТекущаяДата(),"ДФ=ddMMyyhhmmss") + "_";
   
    Для Каждого Стр ИЗ ТЗ Цикл
        Стр.Вес = Стр.ВесЗаказа_Кг;
        Если ЗначениеЗаполнено(Стр.ИдентификаторМашины) Тогда
            Стр.ИдентификаторМашиныДля1С = СформироватьПравильныйКлюч(Стр.ИдентификаторМашины);
            Если ЗначениеЗаполнено(Стр.НомерЗаказа) И НЕ Стр.ТипТочки = "Склад" Тогда
                ГУИДНачало = СтрНайти(Стр.НомерЗаказа,"[GUID ");
                ГУИД = Сред(Стр.НомерЗаказа,ГУИДНачало + 6,36);
                НовыйGUID = Новый УникальныйИдентификатор(ГУИД);               

                //Если Стр.НомерЗаказа = "ЭПУТ-003737 - 02.10.2020 11:34:19 [GUID 8dcf91c6-03cc-11eb-9aff-c86000c31ebb]"
                //    ИЛИ Стр.НомерЗаказа = "ЭПУТ-003716 - 02.10.2020 11:34:19 [GUID 07cd4366-02f6-11eb-9aff-c86000c31ebb]" Тогда
                //    а=1;
                //КонецЕсли;
              
                ЗаказКлиента = Документы.ЗаказКлиента.ПолучитьСсылку(НовыйGUID);              

                Если СтрНайти("" + ЗаказКлиента,"Объект не найден") > 0 Тогда
                    ЗаказКлиента = Документы.ПоручениеЭкспедитору.ПолучитьСсылку(НовыйGUID);
                КонецЕсли;
               
                Если СтрНайти("" + ЗаказКлиента,"Объект не найден") > 0 Тогда
                    ЗаказКлиента = Документы.ЗаказНаПеремещение.ПолучитьСсылку(НовыйGUID);
                КонецЕсли;
               
                Если ЗначениеЗаполнено(ЗаказКлиента) Тогда
                    Стр.Распоряжение = ЗаказКлиента;
                    //Если ТипЗнч(ЗаказКлиента) = Тип("ДокументСсылка.ЗаказНаПеремещение") Тогда
                    //    Стр.Склад = ЗаказКлиента.СкладОтправитель;
                    //Иначе
                    //    Стр.Склад = ЗаказКлиента.Склад;
                    //КонецЕсли;
                    //Пока делаем для всех склад МСК-Опт
                    Стр.Склад = Справочники.Склады.НайтиПоНаименованию("МСК- Опт");
                    Стр.ПолучательОтправитель = Справочники.Партнеры.НайтиПоНаименованию(Стр.ТорговаяСеть);
                    Стр.Доставлено = Ложь;
                    Стр.ДоставляетсяПолностью = Истина;
                    Стр.Адрес = ЗаказКлиента.АдресДоставки;
                    Стр.АдресЗначенияПолей = ЗаказКлиента.АдресДоставкиЗначенияПолей;
                    Стр.ДополнительнаяИнформация = ЗаказКлиента.ДополнительнаяИнформацияПоДоставке;
                    Если ТипЗнч(ЗаказКлиента) = Тип("ДокументСсылка.ЗаказКлиента")
                        ИЛИ ТипЗнч(ЗаказКлиента) = Тип("ДокументСсылка.ЗаказНаПеремещение") Тогда
                        Стр.Перевозчик = ЗаказКлиента.ПеревозчикПартнер;
                        Если ЗначениеЗаполнено(Стр.Перевозчик) Тогда
                            Стр.Адрес = ЗаказКлиента.АдресДоставкиПеревозчика;
                            Стр.АдресЗначенияПолей = ЗаказКлиента.АдресДоставкиПеревозчикаЗначенияПолей;
                        КонецЕсли;
                    КонецЕсли;
                    //Уникальный номер связи строк
                    АдресУИД = Стр.Адрес;
                    АдресУИД = СтрЗаменить(АдресУИД," ","");
                    АдресУИД = СтрЗаменить(АдресУИД,",","");
                    АдресУИД = СтрЗаменить(АдресУИД,".","");
                    Стр.КлючСвязи = "" + ПрефиксУИД + Прав(АдресУИД, 12) + Лев(АдресУИД, 12) + Прав(АдресУИД, 12);
                КонецЕсли;
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

 

Шаг 10. И, наконец, привязываем наши Заказы к машинам (Маршрутным листам, сформированным Яндекс.Маршрутизацией):

Процедура ЗагрузитьТочкиВМаршрутныеЛисты(ТЗ) Экспорт
   
    //Обрабатываем ТЗ
    ЗаданияНаПеревозку = НайтиВсеЗаданияНаПеревозку(ТЗ);
   
    Для Каждого ТекЗадание Из ЗаданияНаПеревозку Цикл
        Если ЗначениеЗаполнено(ТекЗадание.Значение) Тогда
           
            П = Новый Структура;
            П.Вставить("ИдентификаторМашиныДля1С",ТекЗадание.Ключ);
            НайденныеСтроки = ТЗ.НайтиСтроки(П);
           
            Если НайденныеСтроки.Количество() > 2 Тогда
                Попытка
                    //Очищаем зание перед загрузкой
                    ОбЗадание = ТекЗадание.Значение.ПолучитьОбъект();
                    ОбЗадание.Маршрут.Очистить();
                    ОбЗадание.Распоряжения.Очистить();
                    ОбЗадание.ЯМ_Км_План = 0;        
                   
                    ТЗНайденныеСтроки = ТЗ.СкопироватьКолонки();
                   
                    Для Каждого Стр Из НайденныеСтроки Цикл
                                                                       
                        //Считаем километры ЯМ_Км_План
                        Если ЗначениеЗаполнено(Стр.ДлинаПутиДоТочки_Км) Тогда
                            ОбЗадание.ЯМ_Км_План = ОбЗадание.ЯМ_Км_План + Стр.ДлинаПутиДоТочки_Км;
                            //ОбЗадание.ЯМ_Км_Факт = ОбЗадание.ЯМ_Км_Факт + Стр.ДлинаПутиДоТочки_Км;
                        КонецЕсли;
                       
                        Если Стр.ТипТочки = "Склад" Тогда
                            //Парсим время
                            Попытка
                                Если СтрНайти(Стр.ВремяПрибытияНаЗаказ_Склад,"1.") > 0 Тогда
                                    ТекДатаСтрока = "" + Формат(ОбЗадание.Дата + 24*60*60,"ДФ=yyyyMMdd");
                                    СтрВремя = СтрЗаменить(Стр.ВремяПрибытияНаЗаказ_Склад,"1.","");
                                Иначе
                                    ТекДатаСтрока = "" + Формат(ОбЗадание.Дата,"ДФ=yyyyMMdd");
                                    СтрВремя = Стр.ВремяПрибытияНаЗаказ_Склад;
                                КонецЕсли;
                                СтрВремя = СтрЗаменить(СтрВремя,":","");
   
                                ТекДата = Дата(ТекДатаСтрока + СтрВремя);
                               
                                Если Не ЗначениеЗаполнено(ОбЗадание.ДатаВремяРейсаПланС) Тогда
                                    ОбЗадание.ДатаВремяРейсаПланС      = ТекДата;
                                Иначе
                                    Если ТекДата > ОбЗадание.ДатаВремяРейсаПланС Тогда
                                        ОбЗадание.ДатаВремяРейсаПланПо = ТекДата;
                                    Иначе
                                        ОбЗадание.ДатаВремяРейсаПланПо = ОбЗадание.ДатаВремяРейсаПланС; 
                                        ОбЗадание.ДатаВремяРейсаПланС  = ТекДата;
                                    КонецЕсли;
                                КонецЕсли;
                            Исключение
                            КонецПопытки;
                        Иначе
                            //Копируем строки массива в ТЗ,чтобы потом загрузить в документ
                            НовСтр_ТЗНайденныеСтроки = ТЗНайденныеСтроки.Добавить();
                            ЗаполнитьЗначенияСвойств(ТЗНайденныеСтроки,Стр);
                            НовСтр_Маршрут         = ОбЗадание.Маршрут.Добавить();
                            ЗаполнитьЗначенияСвойств(НовСтр_Маршрут,Стр);
                           
                            НовСтр_Распоряжения = ОбЗадание.Распоряжения.Добавить();
                            ЗаполнитьЗначенияСвойств(НовСтр_Распоряжения,Стр);
                        КонецЕсли;
                    КонецЦикла;
                   
                    //ТЗНайденныеСтроки.Свернуть("Адрес,ВремяС,ВремяПо,КлючСвязи,Доставлено,АдресЗначенияПолей,ДополнительнаяИнформация","Вес");
                    //ОбЗадание.Маршрут.Загрузить(ТЗНайденныеСтроки);
                   
                    ТЗНов = ОбЗадание.Маршрут.Выгрузить();
                    ТЗНов.Свернуть("Адрес,Зона,ВремяС,ВремяПо,КлючСвязи,Доставлено,АдресЗначенияПолей,ДополнительнаяИнформация","Вес,Объем");
                    ОбЗадание.Маршрут.Загрузить(ТЗНов);
                   
                    //ОбЗадание.Статус = Перечисления.СтатусыЗаданийНаПеревозку.КПогрузке;
                    //ОбЗадание.ЯМ_ПлатимЗаЧасРаботыПередРейсом = Истина;
                    ОбЗадание.ЯМ_Час_План = (ОбЗадание.ДатаВремяРейсаПланПо - ОбЗадание.ДатаВремяРейсаПланС)/3600;
                    ОбЗадание.Записать();
                Исключение
                КонецПопытки;
            КонецЕсли

            //Заполняем документ Задание на перевозку

        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Ура. Теперь можно допить чай. Осталось нарисовать для начальника волшебную кнопку “Стоимость Работ Водителей”:

&НаКлиенте
Процедура ЯМ_ЯМ_СтоимостьРаботВодителейПосле(Команда)
    //
    ОткрытьФорму("Отчет.ЯМ_СтоимостьРаботВодителей.Форма");
КонецПроцедуры

 

Делаем отчёт о работе водителя

 

Шаг 11. Делаем запрос на СКД:

ВЫБРАТЬ
    СУММА(1) КАК ВсегоТочек,
    СУММА(ВЫБОР
            КОГДА ЗаданиеНаПеревозкуМаршрут.Доставлено
                ТОГДА 1
            ИНАЧЕ 0
        КОНЕЦ) КАК ДоставленоТочек,
    СУММА(ВЫБОР
            КОГДА ЗаданиеНаПеревозкуМаршрут.Доставлено
                ТОГДА 0
            ИНАЧЕ 1
        КОНЕЦ) КАК НеДоставленоТочек,
    МАКСИМУМ(ЗаданиеНаПеревозкуМаршрут.Ссылка.ЯМ_ТарифЗаКм) КАК ЯМ_ТарифЗаКм,
    МАКСИМУМ(ЗаданиеНаПеревозкуМаршрут.Ссылка.ЯМ_ТарифЗаТочку) КАК ЯМ_ТарифЗаТочку,
    МАКСИМУМ(ЕСТЬNULL(ЗаданиеНаПеревозкуМаршрут.Ссылка.ЯМ_Км_План, 0)) КАК ЯМ_Км_План,
    МАКСИМУМ(ЕСТЬNULL(ЗаданиеНаПеревозкуМаршрут.Ссылка.ЯМ_Км_Факт, 0)) КАК ЯМ_Км_Факт,
    МАКСИМУМ(ЗаданиеНаПеревозкуМаршрут.Ссылка.ЯМ_СтоимостьРейса) КАК ЯМ_СтоимостьРейса,
    ЗаданиеНаПеревозкуМаршрут.Ссылка.ТранспортноеСредство КАК ТранспортноеСредство,
    ЗаданиеНаПеревозкуМаршрут.Ссылка.Водитель КАК Водитель,
    ЗаданиеНаПеревозкуМаршрут.Ссылка КАК ЗаданиеНаПеревозку,
    ЕСТЬNULL(ЗаданиеНаПеревозкуМаршрут.Ссылка.ЯМ_Час_План, 0) КАК ЯМ_Час_План,
    ЕСТЬNULL(ЗаданиеНаПеревозкуМаршрут.Ссылка.ЯМ_Час_Факт, 0) КАК ЯМ_Час_Факт
ПОМЕСТИТЬ ВТТочки
ИЗ
    Документ.ЗаданиеНаПеревозку.Маршрут КАК ЗаданиеНаПеревозкуМаршрут
ГДЕ
    ЗаданиеНаПеревозкуМаршрут.Ссылка.Дата >= &ДатаНачала
    И ЗаданиеНаПеревозкуМаршрут.Ссылка.Дата <= &ДатаОкончания
    И ЗаданиеНаПеревозкуМаршрут.Ссылка.Проведен = ИСТИНА
СГРУППИРОВАТЬ ПО
    ЗаданиеНаПеревозкуМаршрут.Ссылка,
    ЗаданиеНаПеревозкуМаршрут.Ссылка.ТранспортноеСредство,
    ЗаданиеНаПеревозкуМаршрут.Ссылка.Водитель,
    ЕСТЬNULL(ЗаданиеНаПеревозкуМаршрут.Ссылка.ЯМ_Час_Факт, 0),
    ЕСТЬNULL(ЗаданиеНаПеревозкуМаршрут.Ссылка.ЯМ_Час_План, 0)
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТТочки.ВсегоТочек КАК ВсегоТочек,
    ВТТочки.ДоставленоТочек КАК ДоставленоТочек,
    ВТТочки.НеДоставленоТочек КАК НеДоставленоТочек,
    ВТТочки.ЯМ_ТарифЗаКм КАК ЯМ_ТарифЗаКм,
    ВТТочки.ЯМ_ТарифЗаТочку КАК ЯМ_ТарифЗаТочку,
    ВТТочки.ЯМ_Км_План КАК ЯМ_Км_План,
    ВТТочки.ЯМ_Км_Факт КАК ЯМ_Км_Факт,
    ВТТочки.ЯМ_СтоимостьРейса КАК ЯМ_СтоимостьРейса,
    ВТТочки.ТранспортноеСредство КАК ТранспортноеСредство,
    ВТТочки.Водитель КАК Водитель,
    ВТТочки.ЗаданиеНаПеревозку КАК ЗаданиеНаПеревозку,
    ВТТочки.ЯМ_Час_План КАК ЯМ_Час_План,
    ВТТочки.ЯМ_Час_Факт КАК ЯМ_Час_Факт,
    ВТТочки.ЯМ_Км_План - ВТТочки.ЯМ_Км_Факт КАК Км_Разница,
    ВТТочки.ЯМ_Час_План - ВТТочки.ЯМ_Час_Факт КАК Час_Разница
ИЗ
    ВТТочки КАК ВТТочки

 

Шаг 12. Проставляем Ресурсы и Настройки:

 

 

 

Шаг 13. Отчёт готов!

 

 

Ну да, не 3 проблемы, а 13. Обычно при оценке проекта первое впечатление не врёт, поэтому… его нужно смело умножать на 3 и прибавлять ещё 2, на всякий случай. Но кто бы научил правильно считать эти эстимэйты…

 

Благодарю за ваше бесценное время!

 

 

Само расширение можно скачать из вложения к статье. Там же можно увидеть полный листинг кода.

Шаблон Excel можно взять на сайте Яндекс.Маршрутизации: https://yandex.ru/routing/doc/vrp/concepts/example.html

Там же есть описание всех параметров: https://yandex.ru/routing/doc/vrp/concepts/excel-fill-guide.html

Также во вложении к публикации шаблон с примером заполнения EXCEL, который мы после 2-х месяцев подбора выработали под потребности нашей компании (напомню, 3-5 машин, около 40 заказов в день, доставка в две смены, без выходных). 

См. также

Интеграция Альфа Авто 5 / Альфа Авто 6 и AUTOCRM / Инфотек

Сайты и интернет-магазины WEB-интеграция Платформа 1С v8.3 Конфигурации 1cv8 1С:Управление торговлей 11 Автомобили, автосервисы Россия Управленческий учет Платные (руб)

Интеграционный модуль обмена между конфигурацией Альфа Авто 5 и Альфа Авто 6 и порталом AUTOCRM. Данный модуль универсален. Позволяет работать с несколькими обменами AUTOCRM разных брендов в одной информационной базе в ручном и автоматическом режиме. Без существенных изменений типовой конфигурации. Проверено с брендами: Интеграция 1С и GEELY Интеграция 1С и HAVAL Интеграция 1С и KIA Интеграция 1С и FORD Интеграция 1С и LADA ГАРАНТИЯ 100% ВНЕДРЕНИЯ!

36000 руб.

03.08.2020    15725    10    17    

11

Интеграция 1С — Битрикс24. Обмен задачами

Сайты и интернет-магазины Интеграция WEB-интеграция Платформа 1С v8.3 Конфигурации 1cv8 Управленческий учет Платные (руб)

Интеграция 1С и Битрикс24. Разработка имеет двухстороннюю синхронизацию 1С и Битрикс24 задачами. Решение позволяет создавать пользователя в 1С из Битрикс24 и наоборот. Данная разработка технически подходит под все основные конфигурации линейки продуктов 1С:Предприятие 8.3 (8.3.18.1289). При приобретении предоставляется 1 месяц бесплатных обновлений разработки. Доступна демо-версия продукта с подключением Вашего Битрикс24

5040 руб.

04.05.2021    17540    6    15    

13

Интеграция с сервисом vetmanager

WEB-интеграция Платформа 1С v8.3 Бухгалтерский учет 1С:Бухгалтерия 3.0 Бытовые услуги, сервис Платные (руб)

Внешняя обработка разрабатывалась для загрузки документов из Ветменеджер в 1С: Бухгалтерия 3.0

12000 руб.

02.02.2021    16350    42    49    

23

[Расширение] БОР-Навигатор.Культура

Зарплата Бюджетный учет WEB-интеграция Обмен с ГосИС Платформа 1С v8.3 Сложные периодические расчеты 1С:Зарплата и кадры государственного учреждения 3 Государственные, бюджетные структуры Россия Бюджетный учет Платные (руб)

Расширение конфигурации, включающее в себя объекты, необходимые для подготовки и сдачи отчета "Штатная численность" системы "БОР-Навигатор.Культура" в программе "1С:Зарплата и кадры государственного учреждения", редакция 3.1.

8400 руб.

01.02.2019    25735    9    0    

7

Заполнение по ИНН или наименованию реквизитов контрагента по данным сайта ФНС

Обмен с ГосИС WEB-интеграция Платформа 1С v8.3 Управляемые формы 1С:Комплексная автоматизация 1.х 1С:Бухгалтерия 2.0 1С:Управление торговлей 10 1С:Управление производственным предприятием 1С:Управление нашей фирмой 1.6 1С:Бухгалтерия государственного учреждения 1С:Документооборот 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Платные (руб)

Обработка является альтернативой механизму, разработанному фирмой 1С и заполняющему реквизиты контрагента по ИНН или наименованию. Не требуется действующей подписки ИТС. Вызывается как внешняя дополнительная обработка, т.е. используется, непосредственно, из карточки контрагента. Заполнение по ИНН или наименованию реквизитов контрагента по данным сайта ФНС (egrul.nalog.ru) для БП 2.0, БП 3.0, БГУ 1.0, БГУ 2.0, УТ 10.3, УТ 11.x, КА 1.1, КА 2.x, УПП 1.x, ERP 2.x, УНФ 1.5, УНФ 1.6, УНФ 3.0, ДО 2.1

2400 руб.

28.04.2016    88569    160    215    

318
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. user612295_death4321 29.08.21 22:09 Сейчас в теме
Яндекс маршрутизация не предоставляет API ? Почему пришлось взаимодействовать через Excel ?
minotavr_x86; zqzq; Albert_2008; +3 Ответить
4. greencactus 82 02.09.21 20:42 Сейчас в теме
(1) Да, API отличный.
Но ведь Эксель же обязательно нужен в любой автоматизации :)
А если серьёзно, то у нас так настроен процесс постройки маршрутного листа - формируется Эксель - утверждается,
потом загружается в маршрутизацию другим сотрудником
формируется маршрут - если что не так прям в экселе правятся параметры (для скорости) - загружается повторно
Если всё ок - отправляется электронно водителям для загрузки в машину и обратно в 1С.
Для нас через API было сложнее на момент написания кода, сейчас всё уже работает как часы, можно и на API перейти.
Подробнее почему именно так описал в первой части статьи https://infostart.ru/1c/articles/1499581/
5. user612295_death4321 02.09.21 21:54 Сейчас в теме
(4) Понятно. Ну мы примерно так же внедряли похожую систему Maxoptra. Обкатали на экселях, далее написали подсистему.

Автоматизация транспортной логистики, тема специфическая)) У каждого логиста свой взгляд на правильный маршрут)
2. tamepjlah 3 01.09.21 05:49 Сейчас в теме
За статью, однозначно, плюс.
Глаз зацепился за фразу
Т.е. на входе любой Excel, а на выходе - удобная ТаблицаЗначений, в которой колонки названы как в исходном Excel. И не нужно сопоставлять колонки по ячейкам.

и поскольку обслуживаю несколько мелких фирм с огромными хотелками, ушел писать универсальную загрузку. И при тестировании обнаружилось, что не такой уж любой Excel может быть на входе.
1) Пытаюсь загрузить файл - файл1 (я не активно пишу комментарии, поэтому как вставить картинку в текст не знаю, пусть будут прикреплённые файлы). На строчке ПЗ.Результат.Выгрузить() получаем ошибку "Ожидается выражение "ВЫБРАТЬ""
2) Пытаюсь загрузить файл - файл2. На выходе получаем очень странную таблицу значений (файл3) со странными названиями колонок. Плюс к этому почему-то имеются дубли колонок (например _11 и _12 и _13 или _81 и _82) - стоит отметить, что в колонках 6-36 указана дата 01.01.1900 с форматом ячейки ДД.
3) Попробовал убрать объединение ячеек и в колонках 6-36 указал число. На выходе получил таблицу значений (файл4) с интересными строками _1-_9. При этом пропали данные за 1 число (на скрине этого не видно, но их нет).
Прикрепленные файлы:
3. greencactus 82 02.09.21 20:36 Сейчас в теме
(2) Клёвый комент!! 5 баллов за пробу.
_1 _2 _3 это 1С пытается сделать колонки уникальными в случае если названия колонок в первоначальном Экселе одинаковые. Или если 1С не смогла создать колонку с таким названием (например как у вас - название колонки это число, а в 1С все переменные должны начинаться с буквы или _, поэтому 1С создаёт колонки с пустым названием и добавляет к пустым названием _НомерПоПорядку)
Если шаблон Экселя одинаковый, то эти «Не правильные_Правильные» названия будут всегда одинаковыми и на них можно ссылаться.

Ещё я бы удалил первые 6 строк в вашем Экселе и строкой с названиями колонок сделал бы строку номер 7 (нижняя колонка шапки) . У меня так несколько загрузчиков запчастей из Автодока и Автопитера работают и там такие же как у вас «Не правильные» колонки.

Ещё раз спасибо за коммент - прям мёд на сердце :)
6. tamepjlah 3 03.09.21 05:44 Сейчас в теме
(3) Получается, что данный код загрузки из Excel подходит для автоматизированного обмена между базами. А если в выгрузке добавят или удалят колонку, то и наименования колонок могут измениться "неведомым" образом?
7. greencactus 82 12.11.22 02:18 Сейчас в теме
(6) Долго не заходил на инфостарт =)

Хотел написать, нет, но ты прав. Если в Экселе будет много колонок, которые не называются по человечески (Сумма, Цена, Количество остатков) то вставив в середину новую или удалив первую, названия колонок собьётся.

Если колонки с человеческими названиями, то собьются только если у тебя добавится колонка с одинаковым названием раньше твоей (Типа Номенклатура, Номенклатура, Цена, Сумма, Сумма, Сумма).

А если новые колонки будут иметь новые уникальные названия, то всё ок. Хоть добавляй, хоть удаляй, хоть местами меняй.

А для обмена между базами мне больше http-сервисы нравятся и быстрее работают и результат он-лайн =)
Оставьте свое сообщение