При разработке в среде 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда стандартные приемы работы из модулей форм не срабатывают в модулях команд. Типичный пример — попытка обратиться к переменной Объект для получения ссылки на текущий документ. Давайте разберем, почему возникает ошибка "Переменная не определена" и как правильно передать контекст данных в общую команду.
Проанализируем ситуацию: когда мы пишем код в модуле формы документа, платформа автоматически предоставляет нам доступ к основному реквизиту формы через имя Объект. Однако Общая команда — это самостоятельный объект метаданных. Ее модуль не связан жестко ни с одной формой. Когда пользователь нажимает кнопку команды, система должна откуда-то узнать, с какими именно данными нужно работать. Для этого используется механизм параметров.
Основной способ получения ссылки на объект — это первый параметр обработчика ОбработкаКоманды. Рассмотрим структуру стандартной процедуры, которая создается автоматически при добавлении модуля команды:
&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
// ПараметрКоманды — это и есть ваша ссылка
КонецПроцедуры
Выясним, что именно попадает в ПараметрКоманды. Это зависит от настройки свойства команды "Тип параметра команды". Если вы указали там конкретный тип, например, ДокументСсылка.РеализацияТоваровУслуг, то при вызове команды из формы этого документа в параметр придет готовая ссылка. Рассмотрим пример получения уникального идентификатора напрямую на клиенте:
&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
// Проверяем, что ссылка не пустая
Если ПараметрКоманды = Неопределено Или ПараметрКоманды.Пустая() Тогда
Возврат;
КонецЕсли;
// Получаем UUID прямо на клиенте, это работает быстро
УникальныйИдентификаторДокумента = Строка(ПараметрКоманды.УникальныйИдентификатор());
// Далее можем передать его в серверную функцию
ДанныеФайла = ПолучитьФайлНаСервере(УникальныйИдентификаторДокумента);
КонецПроцедуры
Важно помнить, что общие команды часто отображаются не только в формах объектов, но и в списках (динамических списках). Если пользователь выделит несколько строк в списке и нажмет вашу команду, ПараметрКоманды превратится в Массив ссылок. Разберем, как универсально обработать такую ситуацию, чтобы избежать ошибок выполнения:
&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
МассивСсылок = Новый Массив;
Если ТипЗнч(ПараметрКоманды) = Тип("Массив") Тогда
МассивСсылок = ПараметрКоманды;
Иначе
МассивСсылок.Добавить(ПараметрКоманды);
КонецЕсли;
Для Каждого ТекущаяСсылка Из МассивСсылок Цикл
// Обрабатываем каждую ссылку по отдельности
UUID = Строка(ТекущаяСсылка.УникальныйИдентификатор());
// Вызов вашей логики
КонецЦикла;
КонецПроцедуры
Иногда ссылки недостаточно. Например, если команда вызывается из формы нового, еще не записанного документа, ссылка в ПараметрКоманды будет пустой. Но нам могут понадобиться данные, которые пользователь уже ввел на форме. В этом случае мы можем обратиться к свойству Источник второго параметра процедуры. Источник — это программная ссылка на саму форму, из которой была вызвана команда.
Рассмотрим, как получить доступ к реквизитам формы:
&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
// Получаем доступ к форме
ФормаИсточника = ПараметрыВыполненияКоманды.Источник;
// Если мы точно знаем, что команда вызывается из формы документа
Попытка
ТекущаяДатаДокумента = ФормаИсточника.Объект.Дата;
Сообщить("Дата документа на форме: " + ТекущаяДатаДокумента);
Исключение
// Форма не содержит объекта или реквизита Дата
КонецПопытки;
КонецПроцедуры
Если ваша задача требует чтения данных из базы или выполнения сложных расчетов (как в случае с получением файлов из хранилища), необходимо выносить код в серверную функцию. Обратите внимание, что методы 1С, работающие с файловой системой (например, ПолучитьИмяВременногоФайла), ведут себя по-разному на клиенте и сервере. Проанализируем правильную структуру вызова:
&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
// 1. Подготовка данных на клиенте
СсылкаНаОбъект = ПараметрКоманды;
// 2. Вызов сервера
Результат = ОбработатьДанныеНаСервере(СсылкаНаОбъект);
КонецПроцедуры
&НаСервереБезКонтекста
Функция ОбработатьДанныеНаСервере(СсылкаНаОбъект)
// Здесь мы уже можем работать с метаданными и запросами
UUID = СсылкаНаОбъект.УникальныйИдентификатор();
// Логика получения данных из хранилища
Возврат "Успешно";
КонецФункции
Использование директивы &НаСервереБезКонтекста является предпочтительным для общих команд, так как это ускоряет работу системы, не передавая лишние данные формы на сервер и обратно.
Чтобы ваша команда корректно получала ссылку, проверьте следующие настройки в дереве метаданных:
ПараметрыВыполненияКоманды.Источник.Таким образом, для успешного получения ссылки в модуле общей команды мы отказываемся от использования переменной Объект и переходим к работе с ПараметрКоманды. Это делает код более универсальным и устойчивым к изменениям в структуре форм. При необходимости можно воспользоваться готовым решением для отображения GUID объектов из форм и списков.