Иногда меня спрашивают, почему я присвоил себе ник "Гений 1С". Наверное потому, что я вижу проблему под тем углом, о котором никто не задумывается. Вот и с загрузкой данных в 1С из Excel - казалось бы - все понятно, зачем изобретать велосипед. За свою трудовую деятельность каждый 1С-ник пишет сотни подобных загрузок. Есть и готовые загрузки, обычно платные и не совершенные. Казалось бы, что тут можно поменять и улучшить? А вот можно!

Пять лет назад, в 2017 году меня впервые посетила мысль об универсальном загрузчике из Excel и я написал первую версию. Файл настроек выглядел так:

Конечно, решение было неудобным и непрактичным, но тогда зародились первые зерна мысли, которая звучала так - зачем каждый раз писать обработчик загрузки, если можно использовать некий движок загрузки? По сути, возникла мысль выделить некие общие особенности загрузки в движок, а управлять загрузкой уже настройками.

Причем не хотелось бы на выходе получить такого монстра, как Конвертация Данных от 1С, который сложно изучать и применять. А наоборот, получить такой продукт, которым бы хотелось пользоваться, причем без особого изучения. Сел - и поехал.

И вот недавно я делал проект по загрузке данных из Excel в 1С УНФ. Пользователи готовили таблицы, я их загружал в базу 1С.

У меня была загрузка номенклатуры в 1С из Розницы, я ее адаптировал под УНФ, в целом получилось неплохо.

Но надо было загружать еще и контрагентов. Готовой обработки на Infostart я не нашел - там были обработки разной степени полезности и полноты, все равно их пришлось бы доделывать. Писать с нуля одноразовую обработку не хотелось.

Ну и сама 1С, разумеется, по традиции не дает никаких штатных обработок по загрузке данных. Типовая обработка загрузки из табличного документа не умеет заполнять номера телефонов и адреса, например.

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

И тут меня осенило. По сути я применил ООП-подход, где есть некий базовый код, который занимается считыванием данных из таблицы, а есть некий перегружаемый код, который уже грузит эти данные в базу.

Или другими словами - есть некий базовый код движка и есть дополнительный, частный код, который применяется уже в каждом отдельном случае.

В итоге обработка выглядит на текущий момент так:

Как видно, здесь используется файл настройки загрузки. Пока что для быстроты я написал его на языке 1С, об этом говорит КОД в первой строке файла:

КОД
//Загрузка юрлиц

Настройки = Параметры.Настройки;

Настройки.Вставить("СтрокаШапки", 1);

Настройки.Колонки.Добавить(Новый Структура("ИД, Имя, Обязательно", "Наименование", "Наименовние в программе", истина));
Настройки.Колонки.Добавить(Новый Структура("ИД, Имя", "НаименованиеПолное", "Наименование для печатной формы"));
Настройки.Колонки.Добавить(Новый Структура("ИД, Имя", "ЮридическаяФорма", "О контрагенте"));
Настройки.Колонки.Добавить(Новый Структура("ИД, Имя", "ИНН", "ИНН"));
Настройки.Колонки.Добавить(Новый Структура("ИД, Имя", "КПП", "КПП"));
Настройки.Колонки.Добавить(Новый Структура("ИД, Имя", "ОКПО", "ОКПО"));
Настройки.Колонки.Добавить(Новый Структура("ИД, Имя", "ОГРН", "ОГРН"));
Настройки.Колонки.Добавить(Новый Структура("ИД, Имя", "Банк", "Банк"));
Настройки.Колонки.Добавить(Новый Структура("ИД, Имя", "БИК", "БИК"));
Настройки.Колонки.Добавить(Новый Структура("ИД, Имя", "РасчетныйСчет", "Р/с"));
Настройки.Колонки.Добавить(Новый Структура("ИД, Имя", "Телефон", "Телефон"));   
Настройки.Колонки.Добавить(Новый Структура("ИД, Имя", "ТелефонПримечание", "Телефон примечание"));   
Настройки.Колонки.Добавить(Новый Структура("ИД, Имя", "Емейл", "E-mail"));
Настройки.Колонки.Добавить(Новый Структура("ИД, Имя", "ЮридическийАдрес", "Юридический адрес"));   
Настройки.Колонки.Добавить(Новый Структура("ИД, Имя", "ФактическийАдрес", "Фактический адрес"));   
Настройки.Колонки.Добавить(Новый Структура("ИД, Имя", "Тег", "Тег"));   
Настройки.Колонки.Добавить(Новый Структура("ИД, Имя", "Группа", "Группа"));   
Настройки.Колонки.Добавить(Новый Структура("ИД, Имя", "ТипКонтрагента", "Тип контрагента"));   

Настройки.Вставить("ФункцияПоиска", "УНФНайтиКонтрагентаЮрлицо");
Настройки.Вставить("ФункцияСоздания", "УНФСоздатьКонтрагента");
Настройки.Вставить("ФункцияЗаполнения", "УНФЗаполнитьКонтрагентаЮрлицо");       
Настройки.Вставить("ФункцияПослеЗаписи", "УНФПослеЗаписиКонтрагентаЮрлицо");   

В будущем планирую формировать структуру настроек из файла с отступами - формат чуть более простой чем JSON.

Файл настроек содержит не код, а лишь описание полей файла Excel и опций загрузки.

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

В файле настроек содержатся также названия методов для поиска, создания, заполнения данных.

Эти методы описываются в отдельной секции формы загрузки - в области ФункцииЗагрузки:

Код по заполнению контрагента выглядит, например, так:

Таким образом я разделил код движка и прикладной код загрузки. Движок загружает таблицу данных, на выходе формирует таблицу, у которой названия колонок уже маркированы идентификаторами, указанными в настройках, а не пользовательскими названиями колонок в Excel. С этой таблицей уже можно просто работать.

Движок (обработку универсальной загрузки) теперь можно дорабатывать. После этого брать свежую версию движка, копировать туда свои функции и получать все тот же код, но еще более удобный за счет доработок движка. По сути теперь можно вкладывать силы не в усовершенствование каждой отдельной обработки загрузки, а вкладываться в разработку движка и это даст пользу для каждой обработки загрузки.

Я лично планирую сделать в движке доработки, которые уже применял в своих обработках загрузки:

  1. Возможность пользователю самому выбирать названия и номера колонок

  2. Возможность разных названий колонок для одной колонки (учитывать ошибки в названиях колонок)

  3. Опции для того, чтобы пропускать создание новых элементов и новых элементов в значениях полей. Например, не создавать новых контрагентов или не создавать новые банки.

  4. Предварительный просмотр - вывод таблицы, где будет показано, какие элементы будут созданы, какие значения полей будут у новых элементов. Причем ненужные для загрузки данные можно убрать в пользовательском режиме.

  5. Автоматизировать работу с дополнительными пользовательскими реквизитами.

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

А пользователи инструмента программисты получают движок, понятный и прозрачный, к которому можно привыкнуть, который не требует долгого изучения. В который можно просто вставить свой код и быстро загрузить нужные данные.

Пользователи за счет гибких возможностей движка без программистов могут использовать гибко уже готовые загрузки, что снизит нагрузку на разработчиков.

Комментарии (27)


  1. manyakRus
    22.12.2023 07:05

    Давно уже есть
    https://infostart.ru/1c/tools/95495/
    Не нужен никакой файл настроек, надо просто в шапке файла Excel написать нормальные названия колонок "Код", "Наименование" и др.


    1. fixin Автор
      22.12.2023 07:05

      Ну вот, взяли и все опошлили.

      В 1с есть тоже "Универсальная загрузка данных из табличного документа", я про нее писал.

      Это поделие того же класса. Как контактную информацию и расчетные счета контрагентов загружать будете?

      Вы попытались сравнить пугач с Пулеметом Максим экстра-класса, окститесь. Перечитайте вдумчивее.


  1. elephanthathi
    22.12.2023 07:05

    зачем вводить какой-то файл настроек?

    вроде статья начиналась за упрощение?

    в первой строке таблицы пишешь нужные поля/настройки/код
    и оттуда адинэской забираешь настройки конвертации
    все счастливы и в воздух лифчики бросают


    1. fixin Автор
      22.12.2023 07:05

      1. это надо менять источник данных, который иногда весит очень много.

      2. Пользователь может ошибиться, ковыряя исходные данные

      3. это надо каждый файл обрабатывать

      4. настройки не укладываются в одно значение на колонку, их намного больше


  1. Spiller26
    22.12.2023 07:05

    У меня есть код загрузки, который загоняет всё в ТЗ, а затем по шаблонам (номерам колонок и строк) вытаскиваю данные, затем для наглядности всё выходиться в Табличный Документ на форме, чтобы пользователь смог просмотреть/отредактировать/добавить данные.


    1. fixin Автор
      22.12.2023 07:05

      Отлично. Но это отдельаня обработка или движок? Вот в чем по сути вопрос.

      Это конкретная загрузка чего-то одного или можно переделать в загрузку другого.

      А если потом добавишь фичу в первую загрузку, во вторую она перейдет или нет?

      Условно есть загрузка номенлатуры и контрагентов. Это две обработк или одна?


  1. AseevAndrew05
    22.12.2023 07:05

    Честно, не увидел гениальности.
    Но право на жизнь, конечно же, имеет.


    1. fixin Автор
      22.12.2023 07:05

      Ну тут уж на вкус и цвет. Но лично мне нравится замечать то, мимо чего проходят остальные. Если это не Гений, то не знаю,что такое Гений.


      1. AseevAndrew05
        22.12.2023 07:05

        Я что-то похожее делал в прошлом году, но вот гениальности в этом не увидел. Может потому что уже давно пишу на Java, для души. И у меня часто проскакивают какие-то решения, которые в 1С не очень и приняты. Но, опять же, гениальности в этом не вижу.


        1. fixin Автор
          22.12.2023 07:05

          Возможно у вас "синдром самозванца"


  1. Naf2000
    22.12.2023 07:05

    Надо выложить готовый продукт, а не полуфабрикат. Здесь пока много кода, от которого можно абстрагироваться.


    1. fixin Автор
      22.12.2023 07:05

      Готовый продукт написать может любой кодер, тем более я уже применил этот продукт на практике при загрузке двух файлов контрагентов (юр лиц и физиков).

      Идеи важнее.


  1. CrushBy
    22.12.2023 07:05

    А в 1С разве нельзя CTRL+C / CTRL+V из Excel (то есть из clipboard) прямо в любую табличную часть, как в lsFusion ? Тогда пользователь, при желании, сможет сам подгонять любой excel-файл под колонки в таблице и загружать без помощи программиста 1С.


    1. fixin Автор
      22.12.2023 07:05

      Это слишком упрощенный подход к загрузке данных. Некий частный вырожденный случай.

      Данные обычно переносятся из разных систем, странно ожидать наличия соответствия данных в приемнике. К тому же есть нюансы - а создавать ли новые элементы в тот же справочник Стран, которые приходят из этого файла, этим всем хочется управлять.


      1. CrushBy
        22.12.2023 07:05

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


        1. fixin Автор
          22.12.2023 07:05

          Когда не нужно создавать, ко мне не обращаются. Когда достаточно самолечения, доктор не нужен. Но доктор должен чем-то лечить, у него должны быть инструменты. Вот это и есть инструмент.


  1. gennayo
    22.12.2023 07:05

    Больше велосипедов хороших и разных!


    1. fixin Автор
      22.12.2023 07:05

      Даем стране угля!


  1. Grigorenkovic
    22.12.2023 07:05

    Самый быстрый способ, который нашел когда-то, это через коннектор odbc excel driver. Позволяет подключить файл как внешний источник данных и работать как с таблицами БД


    1. fixin Автор
      22.12.2023 07:05

      а скорость не всегда важна. об этом я писал в своей прошлой статье https://habr.com/ru/articles/777840/


  1. Naf2000
    22.12.2023 07:05

    В общем случае для получения и обработки внешних данных применяется Паттерн шаблонный метод, условно состоящий из трех этапов, которые подставляются как кубики в общий алгоритм:

    1. Получение сырых внешних данных. Это может быть чтение excel, результат rest-запроса или обращение к внешней бд, например. На выходе получаем коллекцию (обычно таблицу значений) данных примитивных типов: строки, числа, даты, булево. Применительно к чтению эксель зададим на вход коллекцию структур, описывающие искомые поля: имя в результате, номер колонки или имя (тогда ищем по имени строки-заголовка), тип значения. Задаём другие параметры: лист поиска, номер строки заголовка - опционально.

    2. Насыщение данных из нашей ИС - добавление полей-сущностей по параметрам сырых данных. Здесь входящие структуры это тексты запросов (или из части): имя таблицы-сущности, условия поиска, сортировка выбора. Например поиск номенклатуры по артикулу, в определенной папке, сначала ищем полное соответствие артикула, потом по началу значения.

    3. Обработка данных. Необязательно непосредственная запись. Это может быть наполнение табличной части документа в интерактивном режиме.

      Вот собственно комбинируя эти "кубики" весь шаблон и строится.


  1. dmitry_b_77
    22.12.2023 07:05

    Писали уже про построитель запросов? Добавляем синонимы, программно выводим реквизиты на форму и дело в шляпе.


    1. fixin Автор
      22.12.2023 07:05

      Шляпа. Расскажите как при загрузке клиентов из файла таким методом вы будете создавать расчетные счета, страны, вносить адреса, телефоны.

      Вот не люблю, когда задачу пытаются выхолащивать и упрощать. То ли по незнанию, то ли по непониманию.


  1. itmind
    22.12.2023 07:05

    Зачем использовать дополнительный файл настроек? Программисту проще сразу в коде написать что надо.


    1. fixin Автор
      22.12.2023 07:05

      Речь идет о разделении движка и прикладного уровня. Как вы это разделите - не суть. Я прикладной код прямо в этой же форме пишу. Но речь об выделении некоего общего кода (движка).


      1. gennayo
        22.12.2023 07:05

        Это же библиотечный подход! И как это раньше никто до такого не додумался, интересно?


      1. Naf2000
        22.12.2023 07:05

        Прямо в форме записываете объекты в базу? Хай-левел программинг!