При разработке и сопровождении конфигураций на платформе 1С программисты часто сталкиваются с задачами изменения визуального представления персональных данных. Типичный пример — страховой номер индивидуального лицевого счета (СНИЛС). Изначально поле может быть создано как простой текстовый реквизит длиной 11 символов, куда пользователи вводят сплошной поток цифр. Со временем для удобства бухгалтеров или операторов возникает необходимость настроить маску ввода вида 999-999-999 99.
Однако простое изменение маски в свойствах реквизита или элемента формы решает проблему лишь частично: новые данные будут вводиться красиво, но старые записи в динамических списках (столбцах справочников и документов) продолжат отображаться в прежнем «сжатом» формате. Давайте подробно разберем, почему так происходит, как программно привести данные в порядок и как реализовать эту задачу в соответствии с лучшими практиками разработки на платформе 1С.
Разберем внутренние механизмы платформы 1С. Когда вы задаете маску отображения 999-999-999 99 в свойствах реквизита справочника, важно обратить внимание на свойство «Помещать в строку разделители». Если это свойство включено, платформа ожидает, что в базе данных СНИЛС будет храниться как строка длиной 15 символов, содержащая дефисы и пробелы.
Старые записи, которые были внесены до установки маски, хранятся в базе как 11-символьные строки (например, 12345678901). Динамический список считывает данные напрямую из таблицы базы данных и выводит их «как есть». Поскольку длина строки старых записей не соответствует шаблону маски (11 символов вместо требуемых 15), платформа не может корректно применить маску при выводе списка, и данные отображаются в старом формате. При открытии карточки элемента срабатывает механизм автозаполнения формы, и маска применяется визуально, но при записи элемента без изменения данных они могут остаться в старом формате, пока пользователь вручную не перезапишет строку.
Если перед нами стоит задача быстро исправить данные непосредственно в базе данных (чтобы длина строки всех СНИЛС стала равной 15 символам и содержала дефисы с пробелами), мы можем написать простую обработку. Проанализируем алгоритм, который успешно применил автор темы.
Чтобы избежать ошибок при обработке частично заполненной базы (где часть СНИЛС уже имеет дефисы, а часть — нет), сначала необходимо очистить все строки от разделителей, а затем заново программно отформатировать их по единому шаблону.
Рассмотрим пример кода для обработки элементов справочника:
Выборка = Справочники.ФизическиеЛица.Выбрать();
Пока Выборка.Следующий() Цикл
// Получаем объект для редактирования
ОбъектСпр = Выборка.Ссылка.ПолучитьОбъект();
СтрокаСНИЛС = ОбъектСпр.СНИЛС;
// Шаг 1: Очищаем строку от дефисов и пробелов, приводя к чистому 11-значному формату
СтрокаСНИЛС = СтрЗаменить(СтрокаСНИЛС, "-", "");
СтрокаСНИЛС = СтрЗаменить(СтрокаСНИЛС, " ", "");
// Проверяем, что получилась корректная длина строки перед форматированием
Если СтрДлина(СтрокаСНИЛС) = 11 Тогда
// Шаг 2: Формируем строку по маске "999-999-999 99"
НовыйСНИЛС = Лев(СтрокаСНИЛС, 3) + "-" +
Сред(СтрокаСНИЛС, 4, 3) + "-" +
Сред(СтрокаСНИЛС, 7, 3) + " " +
Сред(СтрокаСНИЛС, 10, 2);
ОбъектСпр.СНИЛС = НовыйСНИЛС;
Попытка
ОбъектСпр.Записать();
Исключение
Сообщить("Не удалось записать элемент: " + ОбъектСпр.Ссылка + " Ошибка: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецЦикла;
Важный нюанс: Вместо последовательного вызова СтрЗаменить для удаления пробелов и дефисов, можно использовать более изящный метод платформы, предложенный в обсуждении:
ЧистаяСтрока = СтрСоединить(СтрРазделить(ИсходныйСНИЛС, "- "), "");
Этот метод разбивает строку в массив по указанным символам-разделителям (дефис и пробел), а затем соединяет элементы массива обратно в одну строку, эффективно удаляя все лишние знаки за одну операцию.
В профессиональной разработке на платформе 1С хранение СНИЛС вместе с дефисами и пробелами в базе данных считается плохим тоном. Рассмотрим причины, почему этого стоит избегать:
Решение: Хранить в базе данных строго 11 цифр СНИЛС, а маску использовать исключительно для удобства ввода на форме.
Выясним, как правильно настроить свойства реквизита и формы:
СНИЛС справочника. Установите длину строки равной 11.999-999-999 99.При таких настройках пользователь будет видеть красивую разметку при вводе данных, но при сохранении в базу запишутся только чистые цифры.
Если мы храним в базе данных «чистые» 11 цифр, возникает вопрос: как сделать так, чтобы в списке справочника бухгалтеры видели СНИЛС красивым, с дефисами и пробелами? Для решения этой задачи у нас есть два эффективных инструмента.
Мы можем настроить произвольный запрос для динамического списка справочника. Проанализируем структуру такого запроса:
ВЫБРАТЬ
СпрФизическиеЛица.Ссылка КАК Ссылка,
СпрФизическиеЛица.Код КАК Код,
СпрФизическиеЛица.Наименование КАК Наименование,
ВЫБОР
КОГДА ДЛИНАСТРОКИ(СпрФизическиеЛица.СНИЛС) = 11
ТОГДА ПОДСТРОКА(СпрФизическиеЛица.СНИЛС, 1, 3) + "-" +
ПОДСТРОКА(СпрФизическиеЛица.СНИЛС, 4, 3) + "-" +
ПОДСТРОКА(СпрФизическиеЛица.СНИЛС, 7, 3) + " " +
ПОДСТРОКА(СпрФизическиеЛица.СНИЛС, 10, 2)
ИНАЧЕ СпрФизическиеЛица.СНИЛС
КОНЕЦ КАК СНИЛСПредставление
ИЗ
Справочник.ФизическиеЛица КАК СпрФизическиеЛица
На форме списка мы просто скрываем реальное поле СНИЛС и выводим колонку СНИЛСПредставление. Пользователь видит красивый отформатированный текст, при этом данные в базе остаются в идеальном системном виде.
Если конфигурация разработана на управляемых формах, мы можем воспользоваться условным оформлением списка. Однако, поскольку СНИЛС является произвольной строкой, стандартный формат 1С не всегда может автоматически преобразовать его через маску формата. Поэтому первый вариант с запросом или программным заполнением в событии ПриПолученииДанныхНаСервере (если используются обычные формы) является более надежным.
Раз уж мы коснулись работы со СНИЛС, крайне важно упомянуть проверку корректности вводимых данных (валидацию). СНИЛС содержит контрольное число (последние две цифры), которое рассчитывается по определенному математическому алгоритму на основе первых девяти цифр.
Рекомендуется добавить проверку контрольного числа в модуль объекта справочника в обработчик события ПередЗаписью, чтобы исключить ввод ошибочных номеров пользователями.
Посмотрим на пример функции валидации СНИЛС, которую можно использовать в любой конфигурации (включая самописные системы без БСП):
Функция СНИЛССоответствуетТребованиям(Знач ИсходныйСНИЛС) Экспорт
// Очищаем строку от возможных разделителей
ЧистыйСНИЛС = СтрСоединить(СтрРазделить(ИсходныйСНИЛС, "- "), "");
// Проверяем длину
Если СтрДлина(ЧистыйСНИЛС) <> 11 Тогда
Возврат Ложь;
КонецЕсли;
// Проверяем, что строка состоит только из цифр
Для Позиция = 1 По 11 Цикл
КодСимвола = КодСимвола(ЧистыйСНИЛС, Позиция);
Если КодСимвола < 48 Или КодСимвола > 57 Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
// Проверка контрольного числа по стандартному алгоритму РФ
НомерСНИЛС = Лев(ЧистыйСНИЛС, 9);
КонтрольноеЧисло = Число(Прав(ЧистыйСНИЛС, 2));
// Номера меньше 001-001-998 не проверяются по контрольному числу
Если Число(НомерСНИЛС) <= 1001998 Тогда
Возврат Истина;
КонецЕсли;
Сумма = 0;
Для Индекс = 1 По 9 Цикл
Множитель = 10 - Индекс;
Цифра = Число(Сред(НомерСНИЛС, Индекс, 1));
Сумма = Сумма + (Цифра * Множитель);
КонецЦикла;
Остаток = Сумма % 101;
Если Остаток = 100 Или Остаток = 101 Тогда
РасчетноеКонтрольное = 0;
Иначе
РасчетноеКонтрольное = Остаток;
КонецЕсли;
Возврат (РасчетноеКонтрольное = КонтрольноеЧисло);
КонецФункции
Эту функцию можно вызывать в форме элемента при изменении поля ввода СНИЛС или непосредственно перед записью объекта в базу данных. Это гарантирует стопроцентную чистоту вашей информационной базы.
Несмотря на то, что у автора темы полностью самописная конфигурация, при работе с типовыми решениями (1С:Бухгалтерия, 1С:ЗУП, 1С:ERP) изобретать велосипед не нужно. В составе БСП уже есть готовые и протестированные модули для работы с персональными данными.
Вы можете использовать готовые методы общего модуля ФизическиеЛицаКлиентСервер:
ФизическиеЛицаКлиентСервер.СНИЛСВФормате(СтрокаСНИЛС) — автоматически преобразует чистую строку из 11 символов в красивый формат с разделителями.ФизическиеЛицаКлиентСервер.ПроверитьСНИЛС(СтрокаСНИЛС) — выполняет полную валидацию номера на корректность и возвращает булево значение.Даже в самописной конфигурации вы всегда можете подсмотреть реализацию этих функций в БСП и перенести их код в свой общий модуль для обеспечения надежности работы системы.