Почему не работает проверка длины наименования справочника при записи и как это исправить?

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

В процессе разработки конфигураций на платформе «1С:Предприятие» перед нами часто встает задача жесткого контроля вводимых данных. Одним из классических примеров является ограничение длины наименования элемента справочника. На первый взгляд, задача выглядит тривиальной: достаточно написать несколько строк кода в модуле объекта. Однако на практике разработчики часто сталкиваются с ситуацией, когда проверка обходится, и в базу данных записываются некорректные элементы.

В этой статье мы подробно разберем, почему стандартная проверка длины строки может не работать, как на это влияют маски ввода, как правильно организовать валидацию данных, а также рассмотрим важные аспекты серверной отладки и правила написания обработчиков событий в модуле объекта.

Выясняем причину: почему простая проверка длины строки дает сбой?

Рассмотрим стандартную ситуацию. Разработчик хочет заставить пользователей вводить наименование строго определенной длины (например, ровно 17 символов). Для этого в модуле объекта справочника создается следующий обработчик события:


Процедура ПередЗаписью(Отказ)
    Если СтрДлина(ЭтотОбъект.Наименование) <> 17 Тогда
        Отказ = Истина;
    КонецЕсли;
КонецПроцедуры

Казалось бы, логика безупречна. Если длина наименования не равна 17, транзакция записи должна отменяться. Но при тестировании выясняется, что система спокойно записывает элементы, в которых визуально введено гораздо меньше символов.

Проанализируем ситуацию подробнее. Главный виновник такого поведения — маска ввода, настроенная на поле ввода наименования в форме. Маска ввода (например, для ввода артикулов, серийных номеров или кодов) автоматически форматирует текст. Если маска предусматривает фиксированную длину и разделение символов точками, дефисами или пробелами, то при неполном заполнении поля платформа 1С автоматически дополняет незаполненные позиции пробелами.

В результате в базу данных отправляется строка, которая визуально кажется короткой, но на самом деле содержит концевые пробелы. Метод СтрДлина() честно подсчитывает эти пробелы, возвращает значение 17, и проверка успешно проходится, допуская запись некорректных данных.

Решение 1: Использование функции СокрЛП для удаления невидимых пробелов

Самый простой и быстрый способ решить проблему с концевыми пробелами — использовать встроенную функцию СокрЛП() (Сократить Левые и Правые пробелы). Данная функция удаляет все незначащие пробелы в начале и в конце текстовой строки.

Модернизируем наш код в модуле объекта справочника:


Процедура ПередЗаписью(Отказ)
    Если СтрДлина(СокрЛП(ЭтотОбъект.Наименование)) <> 17 Тогда
        Отказ = Истина;
    КонецЕсли;
КонецПроцедуры

Теперь перед проверкой длины все скрытые концевые пробелы, которые подставила маска ввода, будут безжалостно удалены, и платформа корректно определит реальную длину значимой части строки.

Решение 2: Глубокая очистка строки от разделителей и внутренних пробелов

Хотя функция СокрЛП() отлично справляется с пробелами по краям строки, она имеет серьезный недостаток — она совершенно не трогает пробелы внутри текста.

Представим ситуацию: пользователь вводил данные по маске типа 99.99.99.99, но пропустил символы в середине строки. В результате получилось значение вида "12. .56.78". Функция СокрЛП() вернет эту же строку без изменений, так как пробелы находятся внутри. Метод СтрДлина() опять вернет полную длину, хотя фактически данные введены некорректно.

Чтобы гарантировать 100% надежность проверки, нам необходимо очистить строку от всех нерелевантных символов (пробелов, точек, дефисов и других разделителей маски) перед анализом ее длины. Разберем по шагам, как это реализовать:


Процедура ПередЗаписью(Отказ)
    
    // Очищаем наименование от пробелов и точек-разделителей
    ЧистоеНаименование = СтрЗаменить(ЭтотОбъект.Наименование, " ", "");
    ЧистоеНаименование = СтрЗаменить(ЧистоеНаименование, ".", "");
    
    // Проверяем длину очищенной строки (например, ожидаем ровно 8 цифр без учета точек)
    Если СтрДлина(ЧистоеНаименование) <> 8 Тогда
        Отказ = Истина;
        Общего НазначенияКлиентСервер.СообщитьПользователю("Наименование заполнено некорректно!");
    КонецЕсли;
    
КонецПроцедуры

Такой подход полностью исключает возможность сохранения полупустых значений, замаскированных под корректный ввод.

Как отлаживать код на сервере, если отладка отключена?

Часто разработчики сталкиваются с аппаратными ограничениями среды разработки. Например, когда код выполняется на сервере приложений, где из соображений производительности или безопасности администраторами отключена серверная отладка. Как в таких условиях понять, что именно содержится в переменной?

Рассмотрим три эффективных метода «слепой» отладки:

  1. Использование Журнала регистрации. Мы можем временно интегрировать в код запись в системный лог. Это абсолютно безопасный метод, не нарушающий работу пользователей:
    
    ЗаписьЖурналаРегистрации("ОтладкаПроверки", 
        УровеньЖурналаРегистрации.Информация, 
        , 
        , 
        "Значение: '" + ЭтотОбъект.Наименование + "'; Длина: " + СтрДлина(ЭтотОбъект.Наименование));
    
    После выполнения кода достаточно зайти в Журнал регистрации в режиме «1С:Предприятие» и проанализировать записанные данные.
  2. Инициирование умышленного исключения. Для мгновенного получения информации прямо на экран можно использовать принудительный вызов ошибки. Этот метод прерывает транзакцию и выводит диагностическое сообщение в стандартном окне ошибки:
    
    ВызватьИсключение "Отладка! Значение: '" + ЭтотОбъект.Наименование + "', Длина: " + СтрДлина(ЭтотОбъект.Наименование);
    
    В тексте ошибки вы увидите точное содержимое строки, включая все скрытые пробелы.
  3. Тестирование во внешней обработке. Напишите логику проверки во внешней обработке и запустите ее на локальной файловой копии базы данных. На файловых базах отладка всегда доступна по умолчанию без необходимости изменения настроек сервера.

Важнейшее правило для обработчика ПередЗаписью

Разрабатывая проверки в модуле объекта, начинающие программисты часто забывают о существовании механизмов синхронизации и обмена данными (например, РИБ или интеграции через EnterpriseData).

Если в базу данных будут загружаться элементы из другой системы, жесткое прерывание транзакции через Отказ = Истина заблокирует весь процесс обмена данными. При загрузке данных интерактивные правила валидации применяться не должны!

Давайте посмотрим на единственно верный шаблон написания процедуры ПередЗаписью в модуле объекта:


Процедура ПередЗаписью(Отказ)
    
    // КРИТИЧЕСКИ ВАЖНО: пропускаем проверку при загрузке данных
    Если ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;
    
    // Наша логика проверки
    ОчищенныйТекст = СтрЗаменить(СокрЛП(ЭтотОбъект.Наименование), " ", "");
    Если СтрДлина(ОчищенныйТекст) <> 17 Тогда
        Отказ = Истина;
    КонецЕсли;
    
КонецПроцедуры

Использование свойства ОбменДанными.Загрузка гарантирует, что ваши проверки не нарушат стабильность обмена данными и автоматического обновления конфигурации.

Как правильно создавать стандартные обработчики в Модуле объекта?

Иногда разработчики совершают досадные опечатки при ручном написании сигнатур процедур (например, пишут ПередЗаписью(Отказ, Источник) или путают буквы в названии). Чтобы избежать подобных ошибок, всегда используйте встроенные инструменты Конфигуратора.

Разберем по шагам, как сгенерировать шаблон процедуры:

  1. Откройте модуль объекта нужного справочника или документа.
  2. Обратите внимание на правый верхний угол окна редактора кода — там находится выпадающий список «События объекта».
  3. Кликните по нему и найдите необходимое событие (например, ПередЗаписью или ПриЗаписи).
  4. Платформа автоматически создаст процедуру с абсолютно точным именем и правильным набором входящих параметров.

Использование шаблонов конфигуратора — это признак хорошего тона в разработке и надежная защита от трудночитаемых синтаксических ошибок.

← На главную