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

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

При разработке в среде 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда стандартные приемы работы из модулей форм не срабатывают в модулях команд. Типичный пример — попытка обратиться к переменной Объект для получения ссылки на текущий документ. Давайте разберем, почему возникает ошибка "Переменная не определена" и как правильно передать контекст данных в общую команду.

Почему переменная Объект недоступна в общей команде

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

Решение 1: Использование ПараметрКоманды

Основной способ получения ссылки на объект — это первый параметр обработчика ОбработкаКоманды. Рассмотрим структуру стандартной процедуры, которая создается автоматически при добавлении модуля команды:


&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
    // ПараметрКоманды — это и есть ваша ссылка
КонецПроцедуры

Выясним, что именно попадает в ПараметрКоманды. Это зависит от настройки свойства команды "Тип параметра команды". Если вы указали там конкретный тип, например, ДокументСсылка.РеализацияТоваровУслуг, то при вызове команды из формы этого документа в параметр придет готовая ссылка. Рассмотрим пример получения уникального идентификатора напрямую на клиенте:


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

Решение 2: Обработка множественного выбора (Массив ссылок)

Важно помнить, что общие команды часто отображаются не только в формах объектов, но и в списках (динамических списках). Если пользователь выделит несколько строк в списке и нажмет вашу команду, ПараметрКоманды превратится в Массив ссылок. Разберем, как универсально обработать такую ситуацию, чтобы избежать ошибок выполнения:


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

Решение 3: Получение данных через ПараметрыВыполненияКоманды.Источник

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

Рассмотрим, как получить доступ к реквизитам формы:


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

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

Особенности работы на сервере

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


&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
    // 1. Подготовка данных на клиенте
    СсылкаНаОбъект = ПараметрКоманды;
    
    // 2. Вызов сервера
    Результат = ОбработатьДанныеНаСервере(СсылкаНаОбъект);
КонецПроцедуры

&НаСервереБезКонтекста
Функция ОбработатьДанныеНаСервере(СсылкаНаОбъект)
    // Здесь мы уже можем работать с метаданными и запросами
    UUID = СсылкаНаОбъект.УникальныйИдентификатор();
    // Логика получения данных из хранилища
    Возврат "Успешно";
КонецФункции

Использование директивы &НаСервереБезКонтекста является предпочтительным для общих команд, так как это ускоряет работу системы, не передавая лишние данные формы на сервер и обратно.

Рекомендации по настройке команды

Чтобы ваша команда корректно получала ссылку, проверьте следующие настройки в дереве метаданных:

  1. Тип параметра команды: Убедитесь, что выбран нужный тип (Документ, Справочник или составной тип). Если оставить "Не определено", параметр может прийти пустым.
  2. Использование параметра команды: Должно стоять "Одиночный" или "Множественный", в зависимости от ваших задач.
  3. Группа: Укажите, где должна появиться кнопка (например, "Панель навигации формы.Важное" или "Командная панель формы.Важное"). Это определит, какой контекст будет передаваться в ПараметрыВыполненияКоманды.Источник.

Таким образом, для успешного получения ссылки в модуле общей команды мы отказываемся от использования переменной Объект и переходим к работе с ПараметрКоманды. Это делает код более универсальным и устойчивым к изменениям в структуре форм. При необходимости можно воспользоваться готовым решением для отображения GUID объектов из форм и списков.

← На главную