В процессе разработки на платформе 1С:Предприятие 8 (особенно при работе с управляемыми формами) часто возникает необходимость программно определить настройки интерфейса. Одна из таких задач — узнать максимально допустимую длину строки для локального реквизита формы, который не связан напрямую с реквизитами объектов метаданных (справочников, документов и т.д.).
Разработчики часто путают два принципиально разных понятия: текущую длину введенного пользователем текста и максимально допустимое ограничение длины, заданное для этого реквизита. Функция СтрДлина() возвращает лишь количество символов в текущем значении переменной, но не отвечает на вопрос, сколько всего символов пользователь может ввести в это поле. В этой статье мы подробно разберем, как элегантно решить эту задачу программными методами платформы.
Если реквизит принадлежит объекту конфигурации (например, справочнику), мы легко можем получить его параметры через глобальный контекст Метаданные. Однако локальные реквизиты формы, созданные интерактивно в редакторе формы или добавленные динамически в коде, отсутствуют в общей структуре метаданных. Попытка обратиться к ним стандартными путями вызовет ошибку выполнения.
Рассмотрим рабочие и элегантные способы получения длины строкового реквизита формы в зависимости от контекста выполнения (на клиенте и на сервере).
Для программного исследования структуры управляемой формы на сервере предусмотрен специальный метод ПолучитьРеквизиты(). Он возвращает массив описаний всех реквизитов формы в виде объектов РеквизитФормы. У каждого такого объекта есть свойство ТипЗначения, содержащее объект ОписаниеТипов. Из него мы можем извлечь квалификаторы строки.
Разберем по шагам, как реализовать этот алгоритм в виде универсальной функции:
&НаСервере
Функция ПолучитьМаксимальнуюДлинуРеквизитаНаСервере(ИмяРеквизита)
// Получаем массив описаний всех реквизитов формы
МассивРеквизитов = ПолучитьРеквизиты();
// Обходим коллекцию в поиске нужного реквизита по имени
Для Каждого ТекущийРеквизит Из МассивРеквизитов Цикл
Если ВРег(ТекущийРеквизит.Имя) = ВРег(ИмяРеквизита) Тогда
// Извлекаем описание типов реквизита
ОписаниеТиповРеквизита = ТекущийРеквизит.ТипЗначения;
// Получаем квалификаторы строки
КвалификаторыСтроки = ОписаниеТиповРеквизита.КвалификаторыСтроки;
// Возвращаем установленную длину
Возврат КвалификаторыСтроки.Длина;
КонецЕсли;
КонецЦикла;
Возврат Неопределено;
КонецФункции
Важный нюанс: Метод ПолучитьРеквизиты() доступен только на сервере. Если вам требуется получить ограничение длины в клиентском коде (например, для быстрой валидации ввода без лишнего серверного вызова), данный метод напрямую вызвать не получится.
Проанализируем альтернативную ситуацию. Что делать, если длина строки нужна на клиенте, а серверные вызовы крайне нежелательны из-за требований к производительности? Если для вашего реквизита на форме уже создано поле ввода, мы можем обратиться к свойствам самого элемента управления.
У элементов формы типа «Поле ввода» есть полезное свойство ОграничениеТипа, которое доступно как на сервере, так и на клиенте. Оно хранит объект ОписаниеТипов, привязанный к элементу.
Посмотрим на пример реализации клиентской функции:
&НаКлиенте
Функция ПолучитьМаксимальнуюДлинуЧерезЭлемент(ИмяПоляВвода)
// Находим элемент формы по имени
ЭлементФормы = Элементы[ИмяПоляВвода];
// Проверяем, что у элемента доступно свойство ОграничениеТипа
ОписаниеТиповЭлемента = ЭлементФормы.ОграничениеТипа;
// Извлекаем квалификаторы строки и возвращаем длину
КвалификаторыСтроки = ОписаниеТиповЭлемента.КвалификаторыСтроки;
Возврат КвалификаторыСтроки.Длина;
КонецФункции
Этот способ является максимально элегантным, так как избавляет разработчика от необходимости перебирать все реквизиты формы в цикле. Однако помните, что он сработает только в том случае, если на форме уже физически создан элемент управления, связанный с целевым реквизитом.
При использовании свойства КвалификаторыСтроки.Длина необходимо учитывать специфику платформы «1С:Предприятие»:
Длина вернет значение 0. Обязательно обрабатывайте этот случай в кодовой логике, чтобы избежать некорректных расчетов.Длина все равно вернет исходное числовое ограничение.Проанализируем пример комплексной обработки полученного значения:
МаксимальнаяДлина = ПолучитьМаксимальнуюДлинуРеквизитаНаСервере("МойСтроковыйРеквизит");
Если МаксимальнаяДлина = 0 Тогда
ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Реквизит имеет неограниченную длину.");
Иначе
ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Введено символов: "
+ СтрДлина(Объект.МойСтроковыйРеквизит)
+ " из доступных "
+ МаксимальнаяДлина);
КонецЕсли;
Если вы создаете реквизиты управляемой формы программно во время инициализации интерфейса, наиболее производительным решением будет кэширование параметров. Вместо того чтобы каждый раз заново анализировать структуру формы через «тяжелые» вызовы или переборы элементов, сохраняйте исходные параметры генерации (включая длину создаваемых строк):
ФиксированнаяСтруктура или временном соответствии).Это позволит в любой момент времени мгновенно получить нужные настройки реквизитов на клиенте без обращения к метаданным и без вызова контекстных серверных процедур.