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

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

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

Метод 1: Получение ссылки в модуле объекта через «ВыполнитьКоманду»

Если ваша обработка зарегистрирована в информационной базе с видом ЗаполнениеОбъекта и не имеет основной формы (или выполняется как серверная команда), основным «входом» для платформы является экспортная процедура в модуле объекта. Проанализируем её структуру.

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


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

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

Метод 2: Получение ссылки в форме управляемой обработки

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

В модуле формы обработки следует использовать обработчик события ПриСозданииНаСервере. Разберем пример кода:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // БСП передает массив ссылок в структуру Параметры
    Если Параметры.Свойство("ОбъектыНазначения") Тогда
        МассивСсылок = Параметры.ОбъектыНазначения;
        Если МассивСсылок.Количество() > 0 Тогда
            Объект.ДокументСсылка = МассивСсылок[0];
        КонецЕсли;
    КонецЕсли;
    
КонецПроцедуры

Здесь мы обращаемся к свойству Параметры.ОбъектыНазначения. Важно помнить, что если вы планируете изменять данные документа непосредственно из формы, вам необходимо будет передать эту ссылку обратно на сервер или использовать клиентские методы взаимодействия с владельцем формы.

Особенности работы с незаписанными документами

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

Важные моменты:

  1. Стандартный механизм БСП «Заполнение объекта» обычно скрывает команды для новых, незаписанных объектов.
  2. Если вам все же нужно получить данные «на лету», следует использовать тип команды ЗаполнениеФормы.
  3. В контексте формы владельца (откуда запущена обработка) можно получить данные через ЭтаФорма.ВладелецФормы.Объект. Это позволит прочитать реквизиты, которые пользователь ввел, но еще не сохранил.

Метод 3: Работа в старых конфигурациях (Обычные формы)

Несмотря на повсеместный переход на управляемое приложение, иногда приходится работать с конфигурациями типа УТ 10.3 или старыми редакциями УПП. Посмотрим на пример, как это реализовано там. В таких системах часто используется свойство ВладелецФормы.


// В модуле формы внешней обработки (Обычные формы)
Процедура ПриОткрытии()
    Если ТипЗнч(ВладелецФормы) = Тип("ФормаДокумента") Тогда
        СсылкаНаДокумент = ВладелецФормы.Ссылка;
        // Если документ новый, ссылки не будет, работаем с объектом
        ДокументОбъект = ВладелецФормы.ДокументОбъект;
    КонецЕсли;
КонецПроцедуры

В данном случае ВладелецФормы.Ссылка вернет ссылку на объект, а если нам нужно модифицировать данные без записи в БД (только на экране), мы обращаемся напрямую к ДокументОбъект владельца.

Как модифицировать документ после получения ссылки

Получение ссылки — это только половина дела. Чтобы изменить данные документа в базе, нам нужно получить его объектную копию. Рассмотрим правильный алгоритм работы на сервере:


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

Обратите внимание: использование метода ПолучитьОбъект() и последующая запись Записать() приведут к блокировке объекта и обновлению версии данных. Если в этот момент форма документа открыта у пользователя, он получит сообщение о том, что данные были изменены другим пользователем (или процессом). Чтобы избежать этого, рекомендуется использовать клиентские методы обновления формы через ОповеститьОбИзменении.

Рекомендации по отладке

Выясним причину, почему ссылка может не приходить. Если вы написали код, но ОбъектыНазначения пуст, проверьте функцию СведенияОВнешнейОбработке в модуле объекта. Убедитесь, что для команды правильно указан ВариантЗапуска (например, ВызовСерверногоМетода или ОткрытиеФормы).

Для быстрой проверки содержимого параметров без подключения отладчика, можно использовать метод ОбщегоНазначенияКлиентСервер.СообщитьПользователю или простое Сообщить:


Сообщить("Количество объектов назначения: " + ОбъектыНазначения.Количество());
Для Каждого ТекСсылка Из ОбъектыНазначения Цикл
    Сообщить("Тип объекта: " + ТипЗнч(ТекСсылка) + ", Ссылка: " + ТекСсылка);
КонецЦикла;

Этот нехитрый прием позволит быстро понять, передает ли БСП контекст в вашу обработку или ошибка кроется в регистрации команды.

← На главную