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

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

В практике начинающего разработчика 1С часто возникает задача: создать внешнюю обработку, которая должна «подхватить» данные того документа, из которого она была вызвана. Это классический сценарий для создания систем выгрузки данных, формирования специфических печатных форм или заполнения объектов. В данной статье мы подробно разберем, как правильно организовать получение ссылки на документ, как передать её на сервер и как обработать данные программно.

Проблема контекста: почему ЭтотОбъект не работает

Разберем типичную ошибку новичка. При попытке выполнить код Док = ЭтотОбъект; внутри модуля формы внешней обработки, вы получаете доступ к данным самой формы обработки, а не к документу, из которого она открыта. Проанализируем ситуацию: обработка — это самостоятельный объект метаданных. Когда вы запускаете её команду, платформа создает экземпляр обработки, и контекст «текущего документа» теряется, если его не передать явно.

Способ 1: Использование владельца формы (для простых случаев)

Если ваша обработка открывается непосредственно из формы документа (например, через метод ОткрытьФорму), то у формы обработки появляется свойство ВладелецФормы. Рассмотрим, как это использовать на клиенте:


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

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

Способ 2: Стандарт БСП (Дополнительные отчеты и обработки)

Наиболее правильным и современным методом для конфигураций на базе БСП (Бухгалтерия 3.0, УТ 11, ERP) является интеграция через механизм «Дополнительные отчеты и обработки». В этом случае вам не нужно заботиться о поиске владельца. Рассмотрим основные шаги:

  1. В модуле объекта обработки создается функция СведенияОВнешнейОбработке().
  2. В параметрах команды указывается вид обработки: ДополнительнаяОбработка или ЗаполнениеОбъекта.
  3. При вызове такой обработки система сама передает параметр ОбъектыНазначения.

Проанализируем пример кода в модуле объекта для регистрации:


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

В форме обработки при создании на сервере вы сможете получить ссылку из параметров: ОбъектыНазначения = Параметры.ОбъектыНазначения;. Это будет массив ссылок, даже если выбран один документ.

Способ 3: Ручной выбор документа и передача на сервер

Если автоматическое получение ссылки не удается настроить, можно пойти по пути добавления реквизита на форму обработки. Рассмотрим ситуацию, когда пользователь сам выбирает документ в поле ДокСсылка. Выясним причину частой ошибки при использовании РеквизитФормыВЗначение.

Метод РеквизитФормыВЗначение предназначен для преобразования данных формы (структуры) в прикладной объект. Если у вас в реквизите уже лежит ДокументСсылка, этот метод выдаст ошибку «Несоответствие типов». Для получения объекта из ссылки на сервере нужно использовать метод ПолучитьОбъект().

Рассмотрим правильный код взаимодействия клиента и сервера:


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

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

Алгоритм выгрузки всех данных документа в файл

Выясним, как программно обойти все данные документа, включая табличные части, не зная заранее их имен. Это полезно для универсальных обработок выгрузки. Проанализируем следующий серверный код:


&НаСервере
Процедура ВыполнитьПолнуюВыгрузку(ДокСсылка)
    Текст = Новый ТекстовыйДокумент;
    
    // 1. Записываем общие данные
    Текст.ДобавитьСтроку("ТипДокумента: " + ДокСсылка.Метаданные().Имя);
    Текст.ДобавитьСтроку("Дата: " + ДокСсылка.Дата);
    Текст.ДобавитьСтроку("Номер: " + ДокСсылка.Номер);
    
    // 2. Перебор шапки документа
    Для каждого Реквизит Из ДокСсылка.Метаданные().Реквизиты Цикл
        ИмяРеквизита = Реквизит.Имя;
        Значение = ДокСсылка[ИмяРеквизита];
        Текст.ДобавитьСтроку(ИмяРеквизита + " = " + Значение);
    КонецЦикла;
    
    // 3. Перебор табличных частей
    Для каждого ТЧМетаданные Из ДокСсылка.Метаданные().ТабличныеЧасти Цикл
        Текст.ДобавитьСтроку("--- Табличная часть: " + ТЧМетаданные.Имя);
        
        // Получаем строки конкретной ТЧ
        ТаблицаДанных = ДокСсылка[ТЧМетаданные.Имя];
        
        Для каждого СтрокаТЧ Из ТаблицаДанных Цикл
            СтрокаВыгрузки = "";
            Для каждого РеквизитТЧ Из ТЧМетаданные.Реквизиты Цикл
                СтрокаВыгрузки = СтрокаВыгрузки + РеквизитТЧ.Имя + ":" + СтрокаТЧ[РеквизитТЧ.Имя] + "; ";
            КонецЦикла;
            Текст.ДобавитьСтроку(СтрокаВыгрузки);
        КонецЦикла;
    КонецЦикла;
    
    // 4. Сохранение (внимание: путь должен быть доступен серверу!)
    ПутьКФайлу = "C:\Temp\Export.txt"; 
    Текст.Записать(ПутьКФайлу);
    Сообщить("Файл успешно сохранен по пути: " + ПутьКФайлу);
КонецПроцедуры

Важные рекомендации по разработке

При работе с файловой системой и передачей данных между клиентом и сервером стоит придерживаться следующих правил:

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

← На главную