Как обеспечить уникальность записей в регистре сведений при использовании строк разного регистра (например, «м» и «М»)?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке механизмов интеграции или сопоставления данных программисты 1С часто сталкиваются с ситуацией, когда необходимо хранить в измерениях регистра сведений строки, различающиеся только высотой букв (регистром). Например, в системе-источнике значение «м» (строчная) может означать одно, а «М» (заглавная) — другое. Однако при попытке записи второй строки платформа 1С выдает ошибку: «Запись с такими ключевыми полями уже существует». Разберем подробно, почему так происходит и какие существуют эффективные способы решения этой задачи.

Почему 1С «не видит» разницу между «м» и «М» в измерениях?

Проанализируем техническую причину такого поведения. Платформа «1С:Предприятие» при работе с большинством СУБД (MS SQL Server, PostgreSQL) использует настройки сравнения строк (так называемый Collation) с признаком Case Insensitive (CI). Это означает, что на уровне базы данных строковые значения «Иванов», «иванов» и «ИВАНОВ» считаются идентичными при проверке уникальности индекса.

Поскольку измерения регистра сведений составляют уникальный ключ записи (индекс), СУБД просто не позволяет создать две строки, которые с ее точки зрения одинаковы. Это заложено в архитектуру платформы для того, чтобы поиск в справочниках и документах был удобен пользователю и не зависел от того, нажал он клавишу Shift или нет.

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

Решение 1. Использование справочника-соответствия (Нормализация)

Это самый «чистый» архитектурный подход. Вместо того чтобы пытаться записать сырые строки напрямую в регистр, мы создадим вспомогательный справочник. Рассмотрим по шагам, как это реализовать:

  1. Создадим справочник СоответствияПолов (или универсальный справочник имен).
  2. В качестве основного реквизита будем использовать Наименование. Поскольку поиск в справочниках тоже регистронезависим, мы можем использовать код или дополнительный реквизит для хранения точного строкового значения.
  3. В регистре сведений вместо строки будем использовать ссылку на этот справочник.

Такой подход позволяет хранить сколько угодно вариантов написания («м», «М», «муж», «Мужчина»), связывая их с одним значением перечисления 1С. Посмотрим на пример кода при загрузке данных:


// Поиск или создание элемента соответствия
Функция ПолучитьСсылкуСоответствия(ЗначениеИзИсточника)
    Ссылка = Справочники.СоответствияПолов.НайтиПоНаименованию(ЗначениеИзИсточника, Истина);
    
    // Если нужно строгое соответствие (хотя НайтиПоНаименованию в 1С регистронезависим), 
    // можно дополнительно проверить найденный объект в цикле или через запрос.
    Если Ссылка.Пустая() Тогда
        НовыйОбъект = Справочники.СоответствияПолов.СоздатьЭлемент();
        НовыйОбъект.Наименование = ЗначениеИзИсточника;
        НовыйОбъект.Записать();
        Возврат НовыйОбъект.Ссылка;
    КонецЕсли;
    
    Возврат Ссылка;
КонецФункции

Решение 2. Добавление технического измерения (Признак регистра)

Если нам принципиально нужно использовать именно строковое измерение в регистре, мы можем добавить второе измерение, которое будет выступать «разделителем» уникальности. Назовем его ЭтоВерхнийРегистр с типом Булево.

Проанализируем ситуацию: теперь ключ уникальности будет состоять из двух полей: (Строка, Ложь) для «м» и (Строка, Истина) для «М». С точки зрения СУБД это разные записи. Разберем пример записи в регистр:


МенеджерЗаписи = РегистрыСведений.СоответствияДанных.СоздатьМенеджерЗаписи();
МенеджерЗаписи.ВходящееЗначение = ТекущаяСтрока;
// Определяем, есть ли в строке заглавные буквы
МенеджерЗаписи.ЭтоВерхнийРегистр = (ТекущаяСтрока = ВРег(ТекущаяСтрока)); 
МенеджерЗаписи.ЗначениеПеречисления = ПолученноеЗначение;
МенеджерЗаписи.Записать(Истина);

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

Решение 3. Использование хеш-суммы (MD5 или CRC32)

Для продвинутых задач, когда входящие строки могут быть длинными и сложными, а регистр букв важен, можно использовать вычисление хеша. Хеширование чувствительно к регистру символов, поэтому строки «м» и «М» дадут абсолютно разные хеш-суммы.

Выясним, как это работает в 1С с использованием объекта ХешированиеДанных. Мы добавим в регистр измерение ХешКлюч (тип Строка или Число).


Функция ПолучитьХешСтроки(ВходящаяСтрока)
    ХешОбъект = Новый ХешированиеДанных(ХешФункция.MD5);
    ХешОбъект.Добавить(ВходящаяСтрока);
    Возврат СтрЗаменить(ХешОбъект.ХешСумма, " ", ""); 
КонецФункции

Теперь при поиске в регистре мы будем передавать не только саму строку, но и её MD5-хеш. Это гарантирует 100% точность попадания в нужную запись даже при огромных объемах данных.

Решение 4. Преобразование в двоичные данные

Это специфический, но надежный метод. Платформа 1С при сравнении ДвоичныеДанные учитывает каждый бит. Если сделать измерение типа ХранилищеЗначения невозможно (так как это не может быть ведущим полем ключа), то можно использовать преобразование строки в HEX-последовательность или хранить результат функции ПолучитьДвоичныеДанныеИзСтроки().

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

Решение 5. Нормализация при вводе (НРег)

Зачастую проблема «м» и «М» надумана на этапе проектирования. Если в вашей бизнес-логике «м» и «М» — это одно и то же (мужской пол), самым правильным решением будет принудительное приведение всех входящих данных к нижнему или верхнему регистру перед записью и перед поиском. Используем встроенную функцию НРег().


// При записи
ЗначениеДляРегистра = НРег(ЗначениеИзФайла);

// При поиске в запросе
"ВЫБРАТЬ * ИЗ РегистрСведений.Соответствия ГДЕ Измерение = НРЕГ(&Параметр)"

Рассмотрим подробнее работу запроса: в 1С соединение таблиц по строковым полям происходит без учета регистра. Это означает, что если в регистре лежит «м», а вы ищете «М», 1С все равно найдет эту запись. Если же ваша задача — именно различать их как разные сущности, используйте Решение 2 (доп. измерение) или Решение 3 (хеш).

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

← На главную