Как изменить владельца элемента справочника из формы самого элемента в 1С 7.7?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

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

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

Причины возникновения ошибок и ограничения платформы

Проанализируем, почему прямые попытки изменить системный атрибут Владелец в модуле формы элемента приводят к сбоям:

  1. Ошибка «Объект не может быть перепозиционирован!»
    Возникает при попытке присвоить значение атрибуту Владелец напрямую через контекст формы или результат функции ТекущийЭлемент(). В платформе 1С 7.7 системные атрибуты иерархии и подчиненности (Владелец, Родитель) доступны для записи только для объектов, программно созданных с помощью функции СоздатьОбъект(). В контексте открытой формы элемента эти свойства предназначены исключительно для чтения.
  2. Ошибка «Объект заблокирован»
    Если попытаться обойти первое ограничение и программно создать экземпляр справочника через СоздатьОбъект("Справочник.Модели") в модуле открытой формы, позиционироваться на текущем элементе и изменить атрибут Владелец, то при вызове метода Записать() платформа выдаст ошибку блокировки. Это происходит потому, что интерактивно открытая форма элемента удерживает монопольную транзакционную блокировку на редактируемую запись базы данных.

Рассмотрим практические способы решения этой задачи, применяемые разработчиками.

Способ 1. Изменение владельца из формы списка справочника

Наиболее простое и надежное решение, не требующее ухищрений с блокировками, — перенести механизм смены подчиненности в форму списка подчиненного справочника.

Для этого выполним следующие действия:

  1. Разместим на форме списка справочника реквизит диалога (например, НовыйВладелец с типом соответствующего справочника-владельца) и кнопку вызова процедуры переноса.
  2. В модуле формы списка напишем программный код:

Процедура ИзменитьВладельца()
    
    Если ТекущийЭлемент().Выбран() = 0 Тогда
        Предупреждение("Не выбран элемент для перемещения!");
        Возврат;
    КонецЕсли;
    
    Если ПустоеЗначение(НовыйВладелец) = 1 Тогда
        Предупреждение("Укажите нового владельца!");
        Возврат;
    КонецЕсли;
    
    Спр = СоздатьОбъект("Справочник.Модели");
    Если Спр.НайтиЭлемент(ТекущийЭлемент()) = 1 Тогда
        Спр.Владелец = НовыйВладелец;
        Спр.Записать();
        Сообщить("Владелец успешно изменен.");
    КонецЕсли;
    
КонецПроцедуры

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

Способ 2. Закрытие формы элемента с передачей параметров

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

Разберем логику работы этого метода:

  1. В форме элемента при нажатии кнопки смены владельца заполняется системная переменная Форма.Параметр (например, значение нового владельца или специальный список значений) и вызывается команда Форма.Закрыть(0).
  2. Вызывающий контекст (форма списка или форма справочника-владельца), открывший форму элемента через ОткрытьФорму() или ОткрытьФормуМодально(), перехватывает возвращенный параметр после закрытия.
  3. Вызывающий модуль создаёт объект СоздатьОбъект("Справочник..."), находит нужный элемент (который уже снимается с блокировки после закрытия его формы) и меняет атрибут Владелец с последующим вызовом Записать().

Способ 3. Использование отложенного выполнения через ОбработкаОжидания

Другим решением для выполнения операции из самой формы элемента является применение таймера отложенного вызова ОбработкаОжидания.

Посмотрим на пример реализации данного подхода:


// Переменные модуля формы элемента
Перем глНовыйВладелец;
Перем глЭлементДляСмены;

Процедура ОтложеннаяСменаВладельца()
    // Отключаем таймер
    ОбработкаОжидания("ОтложеннаяСменаВладельца", 0);
    
    Спр = СоздатьОбъект("Справочник.Модели");
    Если Спр.НайтиЭлемент(глЭлементДляСмены) = 1 Тогда
        Спр.Владелец = глНовыйВладелец;
        Спр.Записать();
    КонецЕсли;
КонецПроцедуры

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

Способ 4. Использование внешней обработки или ВК FormEx

Если стандартный диалог элемента справочника неудобен из-за жестких ограничений блокировок, разработчики часто прибегают к созданию произвольной формы редактирования (на базе внешней обработки) или используют внешнюю компоненту FormEx.

При использовании FormEx в процедуре ПриЗакрытии() можно сгенерировать внешнее событие. После физического закрытия окна формы срабатывает обработчик внешнего события в глобальном модуле или вызывающей форме, где снятая блокировка позволяет безопасно выполнить смену владельца через СоздатьОбъект.

Резюме

Платформа 1С 7.7 блокирует редактирование структуры иерархии из контекста открытой формы элемента. Наиболее простым и архитектурно чистым решением является сбыт этой функции на **форму списка** или использование **отложенного выполнения после закрытия формы редактирования**.

← На главную