Шаблоны сопоставления: как не настраивать одно и то же каждый понедельник
Каждый понедельник в девять утра бухгалтер открывает почту, скачивает прайс от одного и того же поставщика, открывает обработку и начинает тыкать мышкой: колонка «Артикул поставщика» → реквизит «Артикул», колонка «Наименование товара» → «Наименование», колонка «Ед. изм.» → «ЕдиницаИзмерения». Пять минут работы, которая ничем не отличается от прошлого понедельника. И от позапрошлого. И от всех предыдущих десяти месяцев. «Опять эти же колонки, опять руками» — знакомое чувство, если вы хоть раз обрабатывали регулярные прайсы вручную.
Автосопоставление — про которое я писал в прошлой статье — тут помогает, но не решает проблему целиком. Оно угадывает по словарю синонимов и алгоритму Левенштейна, честно старается, и в большинстве случаев угадывает правильно. Но оно не помнит, что именно для этого конкретного поставщика три недели назад бухгалтер вручную поправила два поля, потому что автомат ошибся — спутал что-то со служебным полем или не смог сопоставить нестандартное название колонки. В следующий понедельник программа снова наступит на те же грабли, и снова придётся их объезжать вручную. Автомат одинаково туп каждый раз — у него нет памяти о том, что уже было исправлено. А у бухгалтера, которая делает это не в первый раз, есть вполне понятное раздражение: «я же это уже настраивала, почему опять всё сначала?».
Почему это не просто «было бы удобно»
Первая версия обработки умела Dry Run и запись — и прекрасно работала для разовых загрузок: перенести остатки при переходе на новую систему, один раз выгрузить справочник контрагентов, разово залить прайс от нового партнёра. Для таких сценариев автосопоставление плюс ручная корректировка — это нормально, тут не о чем беспокоиться.
Но всё меняется, как только показываешь программу человеку, который грузит один и тот же тип файла регулярно. Здесь стало очевидно: без памяти о сопоставлении инструмент не масштабируется на реальный бизнес-процесс. Каждая загрузка превращается в маленький ритуал — одни и те же клики, одни и те же исправления, одна и та же пятиминутная возня, которая с точки зрения бизнеса не создаёт никакой ценности, а просто отнимает время и вызывает вполне законное «ну сколько можно».
Это не мелочь уровня UX, а архитектурное ограничение. Пять минут, помноженные на пятьдесят загрузок в год, на несколько поставщиков — это уже не пять минут, а несколько рабочих дней, которые тратятся на клики мышкой в одном и том же порядке. Бухгалтеры это чувствуют острее, чем кто-либо: любая рутинная операция, которую можно было автоматизировать, но не автоматизировали, воспринимается как личное неуважение к их времени.
Что внутри шаблона
Формат — обычный JSON. Ничего экзотического: структура с массивом пар «колонка файла → реквизит приёмника», плюс путь к объекту-приёмнику, чтобы шаблон сразу подставлял нужный справочник или документ.
Файл выглядит примерно так:
{
"ПутьПриемника": "Справочник.Номенклатура",
"Сопоставления": [
{ "Колонка": "Артикул поставщика", "Реквизит": "Артикул" },
{ "Колонка": "Наименование товара", "Реквизит": "Наименование" },
{ "Колонка": "Ед. изм.", "Реквизит": "ЕдиницаИзмерения" },
{ "Колонка": "Страна", "Реквизит": "СтранаПроисхождения" }
]
}
Собирается и читается штатными средствами платформы — ЗаписьJSON/ЧтениеJSON, без ручной конкатенации строк. Это принципиальный момент. Как только начинаешь собирать JSON вручную через сложение строк с кавычками, рано или поздно ловишь наименование товара с кавычкой внутри — и весь файл ломается на ровном месте. Встроенный механизм экранирует спецсимволы сам.
Грабли, о которых лучше сказать сразу: не всё сопоставляется одинаково легко
Здесь стоит быть честным с самого начала, а не в конце статьи. Механизм сопоставления работает только с обычными реквизитами объекта — теми, что возвращает ПолучитьРеквизитыОбъекта. Артикул, Наименование, Единица измерения — это реквизиты справочника, и с ними всё работает без сюрпризов.
А вот с ценой — та самая история, которая набила мне шишку на тестах. Казалось бы, естественно ожидать колонку «Цена» в прайсе и сопоставить её так же легко, как Артикул. Но в типовой БП цены хранятся не как реквизит справочника Номенклатура, а в отдельном регистре сведений — со своей структурой измерений и периодичностью. Когда я в тесте попытался сопоставить колонку «Цена» из файла, программа честно вернула статус «НеНайдено»: для неё это просто не существующий реквизит, регистры сведений текущий механизм не читает вообще.
Узнать это на бою, а не на тесте — то ещё удовольствие: бухгалтер грузит прайс, видит «Цена» с розовой подсветкой «НеНайдено» и совершенно резонно решает, что программа сломана. На деле программа работает правильно — просто честно показывает архитектурную границу: обычные реквизиты — да, регистры — пока нет. Отдельная задача на будущее — научиться писать и в регистры тоже, но это уже другая, более сложная механика, и в текущей версии её нет. Если у вас цена именно в регистре — сопоставляйте пока всё остальное через шаблон, а цену заводите отдельно, вручную или отдельной обработкой.
Сценарий использования
На практике всё сводится к трём шагам. Первый раз — как обычно: загрузили файл, прогнали автосопоставление, руками поправили то, что программа не угадала (и цену, если она в регистре, — отдельно). Дальше — кнопка «Сохранить шаблон», вводим название («Прайс — Ромашка ООО»), файл падает на диск.
В следующий понедельник — загрузили новый файл от того же поставщика, нажали «Загрузить шаблон», выбрали тот же JSON-файл. Сопоставление применяется мгновенно: программа сверяет заголовки колонок текущего файла с тем, что записано в шаблоне, и расставляет реквизиты без всякого автосопоставления заново. Пять минут ручной работы превращаются в один клик — и то самое понедельничное раздражение просто не успевает возникнуть.
Грабли: если поставщик переименовал колонку
Шаблон сопоставляет колонки по заголовку, и сравнение идёт без учёта регистра — «Артикул» и «АРТИКУЛ» для него одно и то же. Это спасает от мелких расхождений вроде разного регистра в экспорте у самого поставщика.
Но если поставщик решил переименовать «Ед. изм.» в «Единица измерения» — казалось бы, косметическая правка — шаблон эту колонку просто не найдёт и оставит несопоставленной, со статусом «НеНайдено».
Это осознанное поведение, не баг. Можно было добавить нечёткое сравнение внутрь применения шаблона, но это вернуло бы всю непредсказуемость автосопоставления, только спрятанную глубже. Шаблон ценен именно тем, что детерминирован: применил — получил ровно то, что было в прошлый раз, без сюрпризов. Если заголовок изменился — правильный путь: донастроить сопоставление руками один раз и пересохранить шаблон. Две минуты работы, которые случаются редко.
Ещё одна тонкость: путь к объекту-приёмнику не перезатирается
Шаблон хранит не только сопоставление колонок, но и путь к объекту-приёмнику — скажем, Справочник.Номенклатура. При загрузке шаблона путь подставляется автоматически, но только если поле было пустым. Если пользователь уже что-то выбрал вручную перед загрузкой шаблона — значит, у него была на то причина, и программа не станет тихо менять объект у него из-под рук.
Идея переиспользования между проектами
Раз шаблон — это просто файл на диске, ничто не мешает отдать его другому человеку. Настроил сопоставление для прайса от конкретного поставщика — скинул JSON-файл коллеге, который работает с тем же контрагентом в соседнем отделе. Ему не нужно повторять настройку с нуля: загрузил шаблон, увидел заполненные поля — и работает.
На практике это особенно полезно, когда с одним и тем же поставщиком работают несколько человек: один настраивает сопоставление один раз, остальные пользуются готовым результатом — включая ту самую цену, которую всё равно придётся донастраивать отдельно, если она в регистре.
Что дальше
Шаблоны закрывают проблему регулярной, повторяющейся загрузки — но не решают более широкую задачу: что делать, если один файл должен превратиться не в строку справочника, а в целый документ с шапкой и табличной частью. Это уже другая история.
Если кому-то интересно посмотреть, как всё это реализовано целиком — обработка «Универсальный загрузчик Excel/CSV в 1С» есть на Инфостарт Маркетплейсе, там же можно попробовать бесплатную демо-версию перед покупкой.
Вступайте в нашу телеграмм-группу Инфостарт