При интеграции конфигурации «1С:Управление торговлей 11» с интернет-магазинами (особенно под управлением 1С-Битрикс) технические специалисты часто сталкиваются со следующими проблемами:
В этой статье мы подробно разберем, почему возникает эта проблема с точки зрения архитектуры метаданных 1С, рассмотрим штатные способы исправления данных в базе с помощью стандартных инструментов и приведем примеры программного решения этой задачи.
Для начала проанализируем, как устроено хранение единиц измерения в современных версиях «1С:Управление торговлей 11». В отличие от старых редакций (например, УТ 10.3), где базовые единицы измерения хранились в простом классификаторе, в УТ 11 разработчики объединили единицы измерения и упаковки в один справочник — УпаковкиЕдиницыИзмерения.
В этой системе сущности разделяются по своему назначению:
Если при заполнении базы для каждого товара создавалась своя индивидуальная единица измерения вместо выбора общей базовой единицы, то в справочнике УпаковкиЕдиницыИзмерения создается колоссальное количество дублирующих записей. При выгрузке на сайт модуль интеграции CommerceML добросовестно выгружает каждую такую уникальную «индивидуальную» единицу для каждого товара отдельно. В результате база данных сайта засоряется тысячами одинаковых записей, а стандартный импорт Битрикса начинает выдавать ошибки.
Кроме того, если у базовых единиц или упаковок в 1С не заполнен числовой код по ОКЕИ, в XML-файл выгрузки передаются пустые значения. 1С-Битрикс сопоставляет единицы измерения именно по коду ОКЕИ (таблица b_catalog_measure на стороне сайта). При отсутствии кода сопоставление ломается, и товары либо не загружаются вовсе, либо им присваивается дефолтное значение.
Просто удалить лишние единицы измерения вручную в базе, где насчитывается более 30 000 товаров, физически невозможно. К тому же, ручное удаление приведет к нарушению ссылочной целостности, так как единицы измерения задействованы в проведенных документах движения товаров.
Для решения этой проблемы мы воспользуемся встроенным в платформу инструментом «Поиск и удаление дублей». Рассмотрим этот процесс по шагам:
Важное примечание: Этот процесс может занять значительное время на больших базах данных. Программа не просто удалит помеченные элементы, а корректно перепишет ссылки во всей номенклатуре, ценах, штрихкодах и исторических документах движения товаров, заменив дубли на выбранный оригинал.
Если в базе данных у множества упаковок или единиц измерения не заполнен код по ОКЕИ, мы можем быстро исправить это с помощью стандартной обработки Групповое изменение реквизитов. Однако здесь есть важный технический нюанс: поле связи с классификатором ОКЕИ или сам код могут являться служебными реквизитами, которые по умолчанию скрыты в интерфейсе обработки.
Разберем по шагам, как получить доступ к изменению этих полей:
Код по ОКЕИ Из списка Пустые значения или Наименование Равно шт.Если вам требуется гибкая логика заполнения (например, сопоставить коды для разных видов единиц измерения: для штук прописать 796, для килограммов — 166, для метров — 006), лучшим решением будет написание небольшой внешней обработки. Рассмотрим пример кода на встроенном языке 1С, который решает эту задачу:
// Создаем запрос для поиска элементов с незаполненным кодом ОКЕИ
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| УпаковкиЕдиницыИзмерения.Ссылка КАК Ссылка,
| УпаковкиЕдиницыИзмерения.Наименование КАК Наименование
|ИЗ
| Справочник.УпаковкиЕдиницыИзмерения КАК УпаковкиЕдиницыИзмерения
|ГДЕ
| (УпаковкиЕдиницыИзмерения.КодПОКЕИ = """" ИЛИ УпаковкиЕдиницыИзмерения.КодПОКЕИ ЕСТЬ NULL)";
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Проводник = 0;
Пока Выборка.Следующий() Цикл
// Определяем правильный код ОКЕИ по наименованию единицы измерения
ТекущийКодОКЕИ = "";
ИмяВРегистре = ВРег(Выборка.Наименование);
Если Найти(ИмяВРегистре, "ШТ") > 0 Тогда
ТекущийКодОКЕИ = "796";
ИначеЕсли Найти(ИмяВРегистре, "КГ") > 0 ИЛИ Найти(ИмяВРегистре, "КИЛОГРАМ") > 0 Тогда
ТекущийКодОКЕИ = "166";
ИначеЕсли Найти(ИмяВРегистре, "М") > 0 ИЛИ Найти(ИмяВРегистре, "МЕТР") > 0 Тогда
ТекущийКодОКЕИ = "006";
КонецЕсли;
// Если код определен, записываем его в элемент справочника
Если ЗначениеЗаполнено(ТекущийКодОКЕИ) Тогда
ОбъектЕдиницы = Выборка.Ссылка.ПолучитьОбъект();
ОбъектЕдиницы.КодПОКЕИ = ТекущийКодОКЕИ;
Попытка
ОбъектЕдиницы.Записать();
Проводник = Проводник + 1;
Исключение
Сообщить("Не удалось обновить элемент: " + Выборка.Ссылка + ". Ошибка: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецЦикла;
Сообщить("Успешно обработано и заполнено элементов: " + Проводник);
Этот код анализирует текстовое наименование единицы измерения (переводя его в верхний регистр функцией ВРег для исключения проблем с регистрозависимостью) и прописывает соответствующий код ОКЕИ. Перед запуском данного кода в рабочей базе обязательно сделайте резервную копию (бэкап) конфигурации.
Чтобы избежать повторного лавинообразного роста дубликатов единиц измерения и упаковок при добавлении новых товаров, рекомендуем придерживаться следующих правил ведения учета:
Применение описанных выше методик очистки базы данных позволит полностью восстановить работоспособность модуля выгрузки 1С-Битрикс, сократит объем передаваемых XML-данных и избавит интернет-магазин от лишнего мусора в базе данных.