В процессе реструктуризации баз данных, слияния учетных систем или изменения правил нумерации перед разработчиком часто возникает задача массового изменения кодов справочников. Типичный пример — необходимость заменить первый символ существующего кода номенклатуры (например, ведущий ноль) на определенную цифру или букву. На первый взгляд задача кажется тривиальной, однако при ее реализации в системе 1С необходимо учитывать как тонкости работы со строковыми функциями, так и особенности хранения и генерации кодов в базе данных.
В этой статье мы подробно разберем, почему стандартные методы глобальной замены строк не подходят для этой задачи, рассмотрим три эффективных способа замены первого символа с помощью встроенного языка 1С, а также изучим критически важные аспекты записи изменений в базу данных, включая работу с уникальностью кодов и автонумерацией.
Разберем типичную ошибку, которую часто совершают начинающие разработчики. Попытка использовать функцию СтрЗаменить для решения этой задачи приводит к нежелательным результатам. Рассмотрим следующий пример:
// Неправильный подход
СтарыйКод = "000000013";
НовыйКод = СтрЗаменить(СтарыйКод, "0", "1");
// В результате мы получим "111111113" вместо ожидаемого "100000013"
Функция СтрЗаменить производит поиск и замену всех вхождений указанного символа (или подстроки) во всей исходной строке. Если нам нужно изменить только самый первый символ, использование этой функции недопустимо, так как она безвозвратно испортит структуру кода, заменяя все внутренние нули. Нам необходимы инструменты, которые работают с конкретными позициями символов в строке.
Проанализируем самый простой и эффективный способ решения задачи. Встроенный язык 1С предоставляет функцию Сред(), которая позволяет получить подстроку, начиная с определенной позиции. Синтаксис функции выглядит следующим образом: Сред(Строка, НачальныйНомер, [Длина]). Если параметр Длина не указан, функция вернет всю оставшуюся часть строки до самого конца.
Для замены первого символа на единицу нам достаточно взять символ "1" и "склеить" его с оставшейся частью старого кода, начиная со второго символа. Рассмотрим этот алгоритм на практике:
СтарыйКод = "000000013";
НовыйКод = "1" + Сред(СтарыйКод, 2);
// Результат: "100000013"
Этот способ является наиболее предпочтительным. Он работает быстро, не требует вычисления длины строки и легко читается в коде.
Рассмотрим альтернативный метод, который также часто применяется разработчиками. Он основан на использовании функции Прав(), которая выделяет заданное количество символов с правого конца строки, и функции СтрДлина(), определяющей общую длину строки.
Математика этого способа проста: нам нужно взять из старого кода все символы справа, кроме одного (первого). Количество символов для извлечения будет равно общей длине строки минус единица. Разберем этот пример по шагам:
СтарыйКод = "000000013";
ДлинаОставшейсяЧасти = СтрДлина(СтарыйКод) - 1;
ОставшаясяЧасть = Прав(СтарыйКод, ДлинаОставшейсяЧасти);
НовыйКод = "1" + ОставшаясяЧасть;
// Результат: "100000013"
Этот вариант полностью работоспособен, однако он более громоздкий по сравнению с использованием функции Сред(), так как требует выполнения дополнительной операции по расчету длины строки.
В реальных задачах массовой обработки данных важно предусмотреть проверку входящих значений. Если запустить алгоритм замены первого символа без разбора, то элементы, у которых код уже начинается с нужной цифры, могут быть обработаны повторно или некорректно. Чтобы избежать этого, мы можем использовать функцию Лев() для проверки первого символа перед выполнением преобразования:
СтарыйКод = "000000013";
// Проверяем, действительно ли первый символ слева равен "0"
Если Лев(СтарыйКод, 1) = "0" Тогда
НовыйКод = "1" + Сред(СтарыйКод, 2);
Иначе
// Если первый символ уже изменен или отличается, оставляем код прежним
НовыйКод = СтарыйКод;
КонецЕсли;
Этот подход гарантирует, что программа обработает только те коды, которые действительно требуют корректировки.
Разработчики часто забывают, что простое изменение строковой переменной в коде не меняет данные в самой базе 1С. Кроме того, код существующего элемента справочника нельзя изменить напрямую через ссылку (тип СправочникСсылка), так как этот объект доступен только для чтения. Чтобы применить наш алгоритм к реальному товару или группе товаров, необходимо получить объект для записи и обязательно использовать обработку исключений на случай непредвиденных ошибок блокировки или уникальности.
Проанализируем пример безопасной перезаписи кода для конкретной номенклатурной позиции:
// СсылкаНоменклатуры - это существующая ссылка на элемент в базе данных
НоменклатураОбъект = СсылкаНоменклатуры.ПолучитьОбъект();
// Применяем наш проверенный алгоритм
НоменклатураОбъект.Код = "1" + Сред(НоменклатураОбъект.Код, 2);
// Обязательно используем транзакционную попытку записи
Попытка
НоменклатураОбъект.Записать();
Исключение
Сообщить("Не удалось записать новый код для " + СсылкаНоменклатуры + ". Причина: " + ОписаниеОшибки());
КонецПопытки;
Если код для элемента создается с нуля на основе числового идентификатора (например, при импорте данных), вместо сложного сложения строк с лидирующими нулями безопаснее использовать встроенную функцию Формат(). Например, нам нужно получить код длиной 9 символов, где первый символ — всегда «1», а далее идет порядковый номер с лидирующими нулями:
ПорядковыйНомер = 13;
// ЧГ=0 убирает разделители групп (пробелы)
// ЧЦ=8 задает фиксированную длину числовой части (8 знаков с нулями)
// ЧВ=0 обеспечивает вывод лидирующих нулей
НовыйКод = "1" + Формат(ПорядковыйНомер, "ЧЦ=8; ЧГ=0; ЧВ=0");
// Результат: "100000013"
Если вам требуется изменить коды у сотен или тысяч позиций номенклатуры, писать специальный код в конфигураторе или создавать внешнюю обработку не обязательно. Для этого можно использовать стандартный системный инструмент «Групповое изменение реквизитов», который присутствует практически во всех типовых конфигурациях 1С (раздел Администрирование — Обслуживание — Корректировка данных).
Пошагово разберем, как выполнить эту процедуру:
Код заблокирован для редактирования. Чтобы сделать его доступным, нажмите кнопку «Дополнительные параметры» в нижней или верхней части формы и установите флажки «Показывать служебные реквизиты» и «Разрешить изменение служебных реквизитов».Код.
Объект.Код = "1" + Сред(Объект.Код, 2);
Массовое перекодирование — это ответственная операция, которая при неаккуратном исполнении может нарушить стабильную работу всей информационной базы. Выясним основные риски и способы их минимизации:
1. Нарушение уникальности кодов. В справочнике номенклатуры по умолчанию включена проверка уникальности кодов на уровне платформы. Если в вашей базе при замене первого символа (например, «000000013» превращается в «100000013») система обнаружит, что элемент с кодом «100000013» уже существует, транзакция записи будет прервана с ошибкой «Код не уникальный!». Чтобы избежать этой проблемы при массовой перекодировке, разработчики часто выполняют процесс в два этапа: сначала заменяют первый символ на временный буквенный префикс (например, «Х»), а вторым проходом меняют его на целевую цифру.
2. Сбой механизма автонумерации. Платформа 1С генерирует новые коды автоматически. Для этого она находит в базе максимальное строковое значение кода и увеличивает его числовую часть на единицу. Замена ведущего нуля на единицу резко сдвигает лексикографический максимум кодов вверх. Это может привести к тому, что при создании последующих товаров вручную автонумерация начнет давать сбои, выдавать ошибки неуникальности или некорректные номера. Чтобы восстановить стабильную работу автонумерации после массового изменения кодов, обязательно запустите стандартную обработку «Обновление нумерации объектов» (ее можно вызвать через функции для технического специалиста или написать простую однострочную команду в табло конфигуратора: ОбновитьНумерациюОбъектов(Метаданные.Справочники.Номенклатура);).
3. Проблемы с синхронизацией и обменами данными. Если ваша база 1С синхронизируется с интернет-магазином, CRM-системой, мобильными приложениями или другими конфигурациями (например, «Управление торговлей» обменивается данными с «Бухгалтерией предприятия»), обязательно проверьте правила обмена. Если сопоставление номенклатуры в этих правилах настроено по коду, изменение первого символа приведет к полной рассинхронизации данных при следующем сеансе обмена и массовому созданию дублирующих позиций. Перед изменением кодов убедитесь, что синхронизация настроена по внутреннему уникальному идентификатору (GUID/Ссылка), а не по текстовому коду.
4. Запрет редактирования кодов в интерфейсе пользователя. В большинстве типовых конфигураций поле «Код» на форме карточки номенклатуры заблокировано от случайных изменений обычными пользователями. Если возникла необходимость скорректировать код вручную, администратор должен временно разрешить редактирование кодов. В зависимости от конфигурации это делается либо через настройки прав доступа, либо через регистр сведений «Стратегии редактирования номеров объектов».
Резюме: Замена первого символа кода в 1С технически реализуется очень просто с помощью встроенной функции Сред(). Однако перед выполнением этой операции на рабочей базе данных обязательно создайте резервную копию, проверьте базу на наличие дубликатов кодов и обновите нумерацию объектов после завершения процедуры.