При разработке и сопровождении конфигураций на платформе 1С:Предприятие 7.7 разработчики часто сталкиваются с нестандартным поведением системы при подключении внешних библиотек. Типичная ситуация: простая операция установки значения константы перестает работать без выдачи каких-либо явных ошибок.
Рассмотрим конкретный пример кода, который вызывается для сохранения настройки:
Константа.SmtpСервер = SmtpСервер;
// или метод:
// Константа.SmtpСервер.Установить(SmtpСервер);
При этом наблюдается странная картина: если отключить загрузку внешней компоненты FormEx.dll, значение успешно сохраняется в базу данных. Стоит подключить FormEx в процедуре ПриНачалеРаботыСистемы() — и метод присвоения значения константе перестает производить запись, хотя на чистой типовой базе проблема может не воспроизводиться. Разберем по шагам механизм возникновения этой проблемы и выясним, как правильно её устранить.
Проанализируем внутреннее устройство работы FormEx. При загрузке этой внешней компоненты в платформе активируются хуки (низкоуровневые перехватчики) движка блокировок 1С 7.7. Любая штатная попытка записи значения константы вызывает внутреннюю блокировку таблицы констант (_1SCONST), что автоматически инициирует вызов предопределенного события глобального модуля конфигурации:
Процедура ПриНачалеБлокировкиОбъекта(Объект)
// Обработчик события перехвата блокировки
КонецПроцедуры
Здесь кроются две важные особенности, о которых необходимо знать каждому разработчику:
Объект передает ссылку на соответствующий объект данных. Однако при блокировке константы FormEx передает в качестве параметра обычную строку с идентификатором константы (ТипЗначенияСтр(Объект) = "Строка").ПриНачалеБлокировкиОбъекта выполняется платформой в момент низкоуровневой подготовки к фиксации блокировки. Если внутри этого обработчика происходит любое штатное чтение или запись другой константы (или работа с метаданными через встроенный язык), целостность цепочки вызовов ядра 1С нарушается. Платформа молча сбрасывает текущую операцию блокировки и транзакцию без выдачи синтаксической ошибки, из-за чего сохранение константы отменяется.Разберем самое правильное и надежное решение проблемы. Если в конфигурации используется процедура ПриНачалеБлокировкиОбъекта (например, для логирования действий пользователей или предотвращения параллельного редактирования), необходимо в самом начале процедуры поставить проверку типов и отсекать объекты, не являющиеся документами или справочниками.
Посмотрим на пример корректного кода глобального модуля:
Процедура ПриНачалеБлокировкиОбъекта(Объект)
Тип = ТипЗначенияСтр(Объект);
Если (Тип <> "Документ") И (Тип <> "Справочник") Тогда
Возврат;
КонецЕсли;
// Код обработки блокировок для справочников и документов
КонецПроцедуры
Такая проверка предотвратит выполнение лишней логики и вложенных обращений к базе данных в момент фиксации значения строковых идентификаторов констант.
Если в процедурах ПриНачалеБлокировкиОбъекта или ОбработкаБлокировкиОбъекта требуется вести журнал пользователей, заблокировавших объекты, категорически нельзя обращаться к объектам метаданных через штатные методы 1С (такие как чтение констант или поиск в служебных справочниках). Всю запись служебной информации следует выносить либо во внешние структуры (текстовые лог-файлы), либо осуществлять запись напрямую через внешние компоненты прямого доступа к базе данных.
Посмотрим на типовой блок загрузки внешних компонент в процедуре ПриНачалеРаботыСистемы(). При совместном использовании нескольких библиотек (таких как 1C++, FormEx и сетевых модулей) критически важно соблюдать последовательность загрузки:
Процедура ПриНачалеРаботыСистемы()
// 1. Базовые расширения ядра загружаем в первую очередь
Если ЗагрузитьВнешнююКомпоненту("1cpp.dll") = 0 Тогда
Сообщить("Не удалось загрузить 1cpp.dll");
КонецЕсли;
// 2. Библиотеки интерфейсных перехватов и событий
Если ЗагрузитьВнешнююКомпоненту("FormEx.dll") = 0 Тогда
Сообщить("Не удалось загрузить FormEx.dll");
КонецЕсли;
КонецПроцедуры
Соблюдение порядка инициализации и контроль логики внутри системных обработчиков событий FormEx гарантирует стабильную запись констант и корректную работу транзакций в 1С:Предприятии 7.7.