Как из внешней обработки обратиться к реквизитам документа или справочника в 1С БСП

Программист 1С v8.3 (Управляемые формы) 1С:Документооборот IT и автоматизация бизнеса
← На главную

При разработке внешних обработок в экосистеме 1С, особенно в конфигурациях на базе Библиотеки стандартных подсистем (БСП), таких как 1С:Документооборот, 1С:ERP или 1С:Управление торговлей, разработчики часто сталкиваются с задачей интеграции обработки в существующие экранные формы. Распространенный сценарий — запуск обработки прямо из формы элемента справочника или документа для автоматического изменения реквизитов или создания связанных объектов без открытия дополнительных диалоговых окон.

В этой статье мы подробно разберем, как получить доступ к реквизитам текущего документа или справочника из кода внешней обработки БСП, как правильно зарегистрировать обработку в системе, разберем типичные ошибки и рассмотрим альтернативные, более современные стандарты работы с контекстом формы.

Постановка задачи и разбор типичных заблуждений

Представим ситуацию: нам необходимо внедрить внешнюю обработку в справочник ВнутренниеДокументы. По нажатию кнопки обработки на форме элемента должна выполниться процедура на сервере, которая считает данные текущего документа и выполнит с ними определенные действия (например, создаст задачи или заполнит адреса).

Начинающие разработчики часто пытаются использовать конструкцию ЭтотОбъект.Ссылка непосредственно в модуле объекта внешней обработки, ожидая получить ссылку на элемент справочника, из которого была запущена обработка. Это серьезная ошибка. В контексте модуля внешней обработки ключевое слово ЭтотОбъект указывает на саму внешнюю обработку, а не на документ-источник. Конструкция Объект.Ссылка доступна только в модулях управляемых форм, а при выполнении серверной команды без открытия формы контекст отображения отсутствует.

Для корректного решения этой задачи БСП предоставляет стандартизированный механизм передачи параметров через массив ОбъектыНазначенияМассив в экспортный метод модуля объекта внешней обработки.

Шаг 1. Создание функции регистрации обработки (СведенияОВнешнейОбработке)

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

Ниже представлен корректный шаблон регистрации обработки для справочника ВнутренниеДокументы:


Функция СведенияОВнешнейОбработке() Экспорт

    ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке();
    
    // Определяем назначение обработки
    МассивНазначений = Новый Массив;
    МассивНазначений.Добавить("Справочник.ВнутренниеДокументы");
    
    ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиЗаполнениеОбъекта();
    ПараметрыРегистрации.Назначение = МассивНазначений;
    ПараметрыРегистрации.Версия = "1.0";
    ПараметрыРегистрации.Наименование = "Создание задач по мероприятиям СВА";
    ПараметрыРегистрации.БезопасныйРежим = Ложь;
    ПараметрыРегистрации.Информация = "Внешняя обработка для создания задач по документам СВА";
    
    // Создаем таблицу команд
    ТаблицаКоманд = ПолучитьТаблицуКоманд();
    ДобавитьКоманду(ТаблицаКоманд, 
                    "Создать задачи СВА", 
                    "СозданиеЗадачПоМероприятиямСВА", 
                    ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовСерверногоМетода());
                    
    ПараметрыРегистрации.Команды = ТаблицаКоманд;
    
    Возврат ПараметрыРегистрации;

КонецФункции

Для заполнения таблицы команд мы используем вспомогательные процедуры, которые также размещаем в модуле объекта обработки:


Функция ПолучитьТаблицуКоманд()
    Команды = Новый ТаблицаЗначений;
    Команды.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));
    Команды.Колонки.Добавить("Идентификатор", Новый ОписаниеТипов("Строка"));
    Команды.Колонки.Добавить("Использование", Новый ОписаниеТипов("Строка"));
    Команды.Колонки.Добавить("ПоказыватьОповещение", Новый ОписаниеТипов("Булево"));
    Команды.Колонки.Добавить("Модификатор", Новый ОписаниеТипов("Строка"));
    Возврат Команды;
КонецФункции

Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование, ПоказыватьОповещение = Ложь, Модификатор = "")
    НоваяКоманда = ТаблицаКоманд.Добавить();
    НоваяКоманда.Представление = Представление;
    НоваяКоманда.Идентификатор = Идентификатор;
    НоваяКоманда.Использование = Использование;
    НоваяКоманда.ПоказыватьОповещение = ПоказыватьОповещение;
    НоваяКоманда.Модификатор = Модификатор;
КонецПроцедуры

Разбор важной ошибки регистрации

Если при попытке зарегистрировать обработку в справочнике дополнительных отчетов и обработок вы получаете ошибку вида: "Итератор для значения не определен Для Каждого ПолноеИмяОбъектаМетаданных Из РегистрационныеДанные.Назначение Цикл", это означает, что вы не заполнили или передали некорректный тип в свойство Назначение. Всегда следите, чтобы в Назначение передавался заполненный массив строк с полными именами объектов метаданных (например, "Справочник.ФизическиеЛица" или "Документ.РеализацияТоваровУслуг"), а не значение Неопределено.

Шаг 2. Реализация обработчика ВыполнитьКоманду и получение ссылки на объект

Когда пользователь нажимает кнопку вызова внешней обработки на форме документа, БСП автоматически обращается к экспортной процедуре модуля объекта нашей обработки — ВыполнитьКоманду. Именно в эту процедуру платформа передает контекстные данные.

Для типа команды ВызовСерверногоМетода процедура должна иметь строго определенную сигнатуру:


Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначенияМассив) Экспорт

    Если ИдентификаторКоманды = "СозданиеЗадачПоМероприятиямСВА" Тогда
        
        // Массив всегда содержит как минимум один элемент — ссылку на объект, из формы которого вызвали обработку
        Если ОбъектыНазначенияМассив.Количество() > 0 Тогда
            СсылкаНаДокумент = ОбъектыНазначенияМассив[0];
            ВыполнитьОбработкуДокументаНаСервере(СсылкаНаДокумент);
        КонецЕсли;
        
    КонецЕсли;

КонецПроцедуры

Теперь в процедуре ВыполнитьОбработкуДокументаНаСервере мы имеем полноценную ссылку на элемент справочника или документ. Мы можем легко прочитать любые его реквизиты:


Процедура ВыполнитьОбработкуДокументаНаСервере(СсылкаНаДокумент)
    
    // Пример чтения реквизитов объекта базы данных
    ЗаголовокДокумента = СсылкаНаДокумент.Заголовок;
    Организация        = СсылкаНаДокумент.Организация;
    ДатаСоздания       = СсылкаНаДокумент.ДатаРегистрации;
    
    // Выполняем полезное действие, например, создаем задачу
    НоваяЗадача = Задачи.ЗадачаИсполнителя.СоздатьЗадачу();
    НоваяЗадача.Наименование = "Выполнить аудит по документу: " + ЗаголовокДокумента;
    НоваяЗадача.Дата = ТекущаяДата();
    НоваяЗадача.Предмет = СсылкаНаДокумент;
    НоваяЗадача.Записать();
    
КонецПроцедуры

Шаг 3. Решение проблемы записи: Серверный метод против Заполнения формы

При использовании типа команды ВызовСерверногоМетода мы работаем напрямую с базой данных через ссылки. Если вам необходимо изменить реквизиты самого текущего документа, из которого запущена обработка, вам придется получать объект через ПолучитьОбъект() и записывать его в базу данных на сервере:


ОбъектДокумента = СсылкаНаДокумент.ПолучитьОбъект();
ОбъектДокумента.Комментарий = "Обработано внешней обработкой " + ТекущаяДата();
ОбъектДокумента.Записать();

В чем опасность такого подхода? Если пользователь запустил обработку из открытой формы элемента, внес туда какие-то изменения на клиенте и еще не сохранил их, то при выполнении нашего кода на сервере произойдет следующее:

  1. Сервер запишет новые данные в базу данных.
  2. Пользователь нажмет на форме кнопку "Записать", и платформа выдаст ошибку блокировки: "Данные были изменены или удалены другим пользователем". Изменения пользователя или изменения обработки будут затерты.

Чтобы избежать этой проблемы, современный стандарт БСП рекомендует использовать тип команды ЗаполнениеФормы вместо непосредственного вызова серверного метода.

При типе команды ЗаполнениеФормы в экспортную процедуру модуля объекта передается три параметра:


Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения, ПараметрыВыполнения) Экспорт

    Если ИдентификаторКоманды = "ИмяВашейКоманды" Тогда
        
        // Получаем контекст открытой формы пользователя
        ФормаДокумента = ПараметрыВыполнения.ЭтаФорма;
        
        // Изменяем реквизит прямо на форме пользователя без немедленной записи в СУБД
        ФормаДокумента.Объект.Комментарий = "Данные автоматически обновлены обработкой!";
        
        // Включаем признак модифицированности формы (чтобы появилась звездочка изменения)
        ФормаДокумента.Модифицированность = Истина;
        
    КонецЕсли;

КонецПроцедуры

При использовании этого подхода данные изменятся прямо на экране пользователя. Пользователь визуально оценит результат работы обработки и сам примет решение — нажать кнопку "Записать" или закрыть форму без сохранения изменений.

Шаг 4. Особенности работы с файлами Excel и безопасным режимом

В реальной практике обработки часто создаются для импорта данных из файлов (например, загрузка задач из Excel-файла, упомянутая автором темы на форуме). При разработке такого функционала в БСП необходимо учитывать два важных нюанса:

  1. Ограничения клиент-серверного взаимодействия: Если обработка выполняется на сервере (через ВызовСерверногоМетода), сервер физически не имеет доступа к локальным дискам вашего компьютера (диск C:\, рабочий стол пользователя и т.д.). Для работы с файлами необходимо использовать тип команды ВызовКлиентскогоМетода, создавать у обработки управляемую форму, запрашивать файл на клиенте с помощью метода НачатьПомещениеФайлаНаСервер() и передавать полученный двоичный файл во временное хранилище на сервер для последующего разбора.
  2. Безопасный режим исполнения: По умолчанию при регистрации внешних обработок администраторы базы данных часто включают опцию БезопасныйРежим = Истина. В безопасном режиме платформа запрещает использование внешних COM-объектов (например, Новый COMОбъект("Excel.Application")) и обращение к файловой системе сервера. Чтобы ваша обработка могла корректно работать с файлами в безопасном режиме, используйте встроенные кроссплатформенные средства чтения (такие как ТабличныйДокумент для чтения xls/xlsx файлов) или явно запрашивайте профили безопасности БСП в функции регистрации:

// В функцию СведенияОВнешнейОбработке добавляем разрешения
Разрешения = Новый Массив;
РазрешениеВременныеФайлы = РаботаВБезопасномРежиме.РазрешениеНаИспользованиеКаталогаВременныхФайлов(Истина, Истина);
Разрешения.Добавить(РазрешениеВременныеФайлы);

ПараметрыРегистрации.Вставить("Разрешения", Разрешения);

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

← На главную