При разработке и кастомизации управляемых форм в 1С:Предприятии программисты часто сталкиваются с дилеммой: использовать стандартные проверенные временем механизмы платформы или внедрять более гибкие, современные подходы. Одним из таких спорных объектов является форма констант. Исторически сложилось, что платформа предоставляет готовый механизм для редактирования констант через специальный реквизит формы с типом КонстантыНабор. Однако с ростом масштабов систем, увеличением нагрузок и развитием стандартов разработки (в частности, Библиотеки стандартных подсистем — БСП) этот подход подвергся серьезной переоценке.
В рамках этой статьи мы детально разберем архитектурные особенности работы с константами в 1С. Мы проанализируем две ключевые проблемы: во-первых, выясним, почему использование свойства элемента формы ВыделенныйТекст для программной установки значений является грубейшей ошибкой, приводящей к непредсказуемым багам; во-вторых, сравним классический метод сохранения через общий НаборКонстант и современный метод точечной записи с помощью Установить() с точки зрения производительности СУБД и блокировок данных.
Рассмотрим ситуацию, с которой столкнулся один из участников обсуждения. В прикладном решении автор формы пытался заполнить строковое поле ввода программно, используя следующий неочевидный прием:
НовоеЗначениеКонстанты = ПолучитьСтрокуЗначения(); // некое выражение
ЭтотОбъект.ТекущийЭлемент.ВыделенныйТекст = НовоеЗначениеКонстанты;
На первый взгляд разработчику могло показаться, что раз значение визуально меняется на форме, значит, при последующей интерактивной записи набора констант платформа подхватит эти данные и сохранит их в базу. Однако такой подход является крайне опасным антипаттерном. Разберем по шагам, к каким последствиям приводит подобная манипуляция.
1. Жесткая зависимость от фокуса ввода и интерактивного выделения
Свойство ВыделенныйТекст (SelectedText) предназначено исключительно для работы с текстом, который пользователь *физически выделил курсором мыши или клавиатурой* в текущий момент времени. Если в момент выполнения программного кода фокус ввода сместился на другой элемент формы, или если в целевом поле ввода не было активного выделения, поведение платформы становится абсолютно непредсказуемым. Вместо полной замены старого значения новым, платформа может выполнить одну из следующих некорректных операций:
2. Ограничения контекста выполнения
Обращение к элементам формы и их интерактивным свойствам возможно только на стороне клиента (&НаКлиенте). Попытка использовать свойство ВыделенныйТекст в серверных процедурах приведет к ошибке компиляции. Кроме того, платформа накладывает жесткое ограничение: данное свойство невозможно применить к полям ввода, расположенным внутри табличных частей или таблиц значений. При динамической работе с таблицами этот метод полностью теряет работоспособность.
3. Системные баги платформы 1С
Использование недокументированного или нецелевого поведения свойств элементов управления часто натыкается на внутренние ошибки самой платформы. Например, в официальном реестре ошибок 1С зарегистрирован баг № 20025124. Его суть заключается в том, что попытка очистить поле ввода путем записи пустой строки "" в свойство ВыделенныйТекст управляемой формы попросту игнорируется системой. Старый текст остается на экране, вводя пользователя в заблуждение.
4. Обход стандартных бизнес-процессов формы
Когда мы изменяем данные «в обход» реквизита — напрямую воздействуя на визуальное представление элемента формы — платформа не всегда корректно регистрирует факт изменения данных. В результате:
ПриИзменении() для этого элемента формы.Проанализируем правильный подход к изменению данных на управляемой форме. Запомните золотое правило разработки в 1С: всегда изменяйте данные в реквизитах, а не в элементах отображения. Платформа 1С спроектирована по принципу Model-View-Controller (MVC). Элемент формы (поле ввода) — это лишь визуальное отражение (View) связанного с ним реквизита (Model). Как только вы меняете значение реквизита, платформа автоматически обновляет его визуальное представление на экране.
Если поле ввода связано с реквизитом набора констант, правильный программный код должен выглядеть следующим образом:
&НаКлиенте
Процедура УстановитьЗначениеКонстантыПравильно()
// Пишем напрямую в реквизит формы, связанный с константой через ПутьКДанным
НаборКонстант.ИмяСтроковойКонстанты = "Новое корректное значение";
// Платформа сама установит модифицированность формы
// и корректно обновит текст в поле ввода на экране.
КонецПроцедуры
Теперь перейдем ко второму, более глобальному вопросу темы: какой способ сохранения констант предпочтительнее в современных реалиях разработки?
Существует два принципиально разных подхода:
НаборКонстант): На форму выводится стандартный реквизит типа КонстантыНабор. Пользователь меняет значения на форме, после чего вызывается метод Записать() для всего набора сразу.Установить()): Элементы формы привязываются к обычным несвязанным реквизитам формы. При изменении конкретной настройки на сервере вызывается метод Константы.ИмяКонстанты.Установить(Значение).Проанализируем ситуацию с точки зрения производительности СУБД, блокировок данных и логики построения бизнес-приложений.
Для небольших, малонагруженных баз данных с малым количеством одновременно работающих пользователей классический способ вполне жизнеспособен и прост в реализации. Однако в высоконагруженных корпоративных системах (ERP, КА, УТ) он превращается в серьезную архитектурную проблему.
1. Избыточные блокировки таблиц в СУБД
Начиная с версии платформы 8.2.11, структура хранения констант в базе данных изменилась. Каждая константа теперь хранится в своей отдельной таблице СУБД (таблицы с именами вида _ConstXXXX), состоящей ровно из одной строки. Это было сделано специально для снижения конкуренции за ресурсы базы данных.
Однако, когда вы используете НаборКонстант и вызываете его запись:
// Приводит к блокировке множества таблиц!
НаборКонстант.Записать();
Платформа открывает транзакцию и пытается перезаписать абсолютно все константы, которые включены в данный набор на форме, даже если пользователь изменил значение всего одной константы (например, снял или установил одну «галочку»). СУБД накладывает эксклюзивную блокировку на таблицы всех этих констант. Если в этот же момент параллельный сеанс (другой пользователь или фоновое задание) попытается прочитать или обновить любую другую константу из этого набора, он будет заблокирован. Это неизбежно ведет к критическим ошибкам ожидания блокировки данных.
2. Избыточная нагрузка на сервер и СУБД
Запись неизмененных констант порождает массу непроизводительной работы для системы:
ПередЗаписью и ПриЗаписи в модулях менеджера значения константы.Современные стандарты разработки фирмы «1С» и Библиотека стандартных подсистем (БСП) рекомендуют полностью отказаться от использования НабораКонстант на формах настроек и панелей администрирования. Вместо этого применяется концепция независимых реквизитов формы и точечной записи.
Разберем по шагам, как устроен этот механизм в БСП:
РеквизитАдресСервера, РеквизитИспользоватьЗаказы и т.д.), которые не привязаны напрямую к базе данных.ПриИзменении выполняется быстрый, легкий асинхронный вызов сервера, который записывает значение только этой конкретной константы через метод Установить().Посмотрим на пример реализации такого механизма:
&НаКлиенте
Процедура ИспользоватьИнтеграциюПриИзменении(Элемент)
// Получаем новое значение напрямую из реквизита формы
НовоеЗначение = ЭтотОбъект.ИспользоватьИнтеграцию;
// Запускаем точечное сохранение на сервере
ЗаписатьКонстантуНаСервере("ИспользоватьИнтеграцию", НовоеЗначение);
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ЗаписатьКонстантуНаСервере(ИмяКонстанты, Значение)
// Быстрая точечная запись в СУБД. Блокируется только одна таблица конкретной константы!
Константы[ИмяКонстанты].Установить(Значение);
КонецПроцедуры
При таком подходе транзакция записи длится миллисекунды, блокируется только одна крошечная таблица конкретной константы, а другие пользователи базы данных даже не замечают выполнения этой операции. Это гарантирует максимальную производительность и стабильность информационной системы.
Подводя итоги нашего анализа, сформулируем основные правила и рекомендации по проектированию форм редактирования констант:
ВыделенныйТекст для программного заполнения данных на форме. Это ненадежный механизм, зависящий от фокуса ввода и интерактивных действий пользователя. Всегда производите запись непосредственно в связанный реквизит формы.НабораКонстант на форме допустимо в целях экономии времени разработки, однако помните о потенциальных блокировках.НабораКонстант в пользу независимых реквизитов формы и точечной записи измененных значений с помощью метода Константы.ИмяКонстанты.Установить().Соблюдение этих несложных правил позволит вам создавать быстрые, надежные и отказоустойчивые решения на платформе «1С:Предприятие 8», готовые к любым нагрузкам и масштабированию.