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