При импорте или первоначальном наполнении справочника Номенклатура в отраслевом решении «Альфа-Авто» (разработка компании «1С-Рарус») часто возникает ситуация, когда поле каталожного номера остается незаполненным. В то же время сами каталожные номера могут быть ошибочно занесены в поле наименования товара. Чтобы исправить эту ситуацию, рационально использовать встроенную обработку «Универсальные подбор и обработка объектов» и выполнить произвольный алгоритм для копирования данных.
В этой статье мы подробно разберем, как правильно составить и выполнить такой алгоритм, как определить системное имя нужного реквизита, обойти контроль уникальности платформы и избежать ошибок, связанных с ограничением длины строковых полей.
Разберем весь процесс по шагам.
В интерфейсе программы поле может называться «Каталожный номер», «№ по кат.» или «Артикул». Однако для написания программного кода нам необходимо знать его точное имя в метаданных конфигурации 1С. В решениях «Альфа-Авто» под синонимом «№ по кат.» обычно скрывается стандартный реквизит Артикул.
Если у вас возникли сомнения относительно точного имени реквизита, мы можем запустить простой поисковый цикл в произвольном алгоритме обработки:
Для каждого РеквизитМетаданных Из Объект.Метаданные.Реквизиты Цикл
Если Найти(ВРег(РеквизитМетаданных.Синоним), "КАТ") > 0
Или Найти(ВРег(РеквизитМетаданных.Синоним), "НОМЕР") > 0 Тогда
Сообщить("Имя реквизита: " + РеквизитМетаданных.Имя + " | Синоним: " + РеквизитМетаданных.Синоним);
КонецЕсли;
КонецЦикла;
Запустив этот код, мы увидим в окне сообщений точное имя реквизита, которое затем будем использовать для присвоения значений. В нашем случае целевым реквизитом является Артикул.
Казалось бы, простейший вариант алгоритма выглядит следующим образом:
Объект.Артикул = Объект.Наименование;
Объект.Записать();
Однако при выполнении этого кода на реальной базе данных вы гарантированно столкнетесь с ошибками записи. Рассмотрим причины их возникновения и способы устранения.
В конфигурациях «Альфа-Авто» на уровне метаданных или бизнес-логики часто включен жесткий контроль уникальности артикулов. Если в справочнике встретятся элементы с одинаковыми наименованиями (или у них совпадут начальные части наименований), то при вызове метода Записать() система выдаст ошибку транзакции, и обработка прервется.
Самый простой способ избежать аварийного завершения работы — обернуть процесс записи в конструкцию Попытка - Исключение. В этом случае ошибочные элементы будут просто пропускаться, а корректные — успешно запишутся:
Попытка
Объект.Артикул = Объект.Наименование;
Объект.Записать();
Исключение
Сообщить("Не удалось записать элемент: " + Объект.Ссылка + " Ошибка: " + ОписаниеОшибки());
КонецПопытки;
Длина реквизита Артикул в базе данных строго ограничена (например, 25 или 50 символами). Длина поля Наименование может быть существенно больше (до 150–1000 символов). Если попытаться записать слишком длинную строку в артикул, платформа автоматически усечет ее или вызовет ошибку СУБД. При усечении строк повышается вероятность появления дубликатов, что опять же приведет к ошибке уникальности.
Чтобы контролировать этот процесс, применим встроенную функцию Лев() и функцию удаления лишних пробелов СокрЛП(). Предположим, что ограничение длины артикула в вашей конфигурации составляет 50 символов:
Попытка
Объект.Артикул = Лев(СокрЛП(Объект.Наименование), 50);
Объект.Записать();
Исключение
Сообщить("Ошибка сохранения элемента: " + Объект.Наименование);
КонецПопытки;
Если для вашей компании критически важно заполнить артикул для всех без исключения элементов, но из-за дублирующихся или длинных наименований возникают ошибки уникальности, можно автоматически генерировать уникальный суффикс на основе системного кода элемента номенклатуры (который гарантированно уникален в пределах справочника).
Реализуем алгоритм автоматического сокращения наименования с добавлением кода в качестве суффикса:
МаксДлинаАртикула = 50; // Установите лимит символов для вашего реквизита
СуффиксУникальности = "_" + СокрЛП(Объект.Код);
ДопустимаяДлинаИмени = МаксДлинаАртикула - СтрДлина(СуффиксУникальности);
Если ДопустимаяДлинаИмени > 0 Тогда
Объект.Артикул = Лев(СокрЛП(Объект.Наименование), ДопустимаяДлинаИмени) + СуффиксУникальности;
Иначе
Объект.Артикул = СуффиксУникальности;
КонецЕсли;
Попытка
Объект.Записать();
Исключение
Сообщить("Критическая ошибка записи: " + Объект.Ссылка);
КонецПопытки;
Вместо усложнения программного кода, вы можете временно отключить проверку уникальности каталожных номеров на уровне самой конфигурации «Альфа-Авто».
Выполните следующие действия перед запуском обработки:
Еще один профессиональный прием для обхода проверок при записи — использование свойства объекта ОбменДанными.Загрузка = Истина. При установке этого флага платформа записывает объект напрямую в базу данных, отключая выполнение прикладных проверок в модуле объекта и модуле менеджера.
Важное предупреждение: Используйте этот метод с осторожностью, так как при этом также могут не заполниться важные связанные регистры сведений (цены, штрихкоды и др.).
Пример использования флага загрузки:
Объект.ОбменДанными.Загрузка = Истина;
Объект.Артикул = Лев(СокрЛП(Объект.Наименование), 50);
Попытка
Объект.Записать();
Исключение
Сообщить("Не удалось записать объект даже в режиме загрузки: " + Объект.Ссылка);
КонецПопытки;
// Обязательно сбрасываем флаг в Ложь, если объект продолжает использоваться в сессии
Объект.ОбменДанными.Загрузка = Ложь;
Мы проанализировали различные варианты решения задачи переноса данных наименования в артикул. Выбор конкретного метода зависит от структуры данных вашей информационной базы, требований к уникальности каталожных номеров и объемов обрабатываемой номенклатуры.