Команды справочников и документов 1С 8.3: как вызвать их из формы и из кода
Содержание
К команде объекта 1С нельзя обратиться как к методу: у команды нет вызова вида Справочники.Номенклатура.Команды.Печать(). Команда — это элемент командного интерфейса. Её выполняет платформа, когда пользователь нажимает кнопку, а код работает в процедуре ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды) модуля команды.
Поэтому «обратиться к команде» на практике значит одно из трёх: вывести её на форму кнопкой, открыть по навигационной ссылке или вынести логику в общий модуль и вызывать его и из команды, и из любого другого кода. Всё описанное относится к платформе 8.3 и управляемым формам, от конфигурации не зависит.
Что такое команда объекта метаданных
В конфигураторе у справочника, документа, регистра или обработки есть ветка Команды. Это команды объекта. Отдельно в ветке Общие → Общие команды живут глобальные команды, которые не привязаны к одному объекту.
У каждой команды три части:
- 🧩 свойства — где показывать, с каким параметром работать, меняет ли данные;
- 📄 модуль команды — клиентский код с процедурой
ОбработкаКоманды; - 🔐 право «Просмотр» в ролях — без него пользователь команду не увидит.
Свойства, которые влияют на вызов
| Свойство | Что задаёт | На что влияет при обращении |
|---|---|---|
Группа | Место в интерфейсе: панель навигации, панель действий, командная панель формы | Где платформа покажет кнопку |
Тип параметра команды | Тип ссылки, с которой работает команда | В каких формах команда появится автоматически |
Режим использования параметра | Одиночный или Множественный | Что придёт в ПараметрКоманды: ссылка или массив |
Изменяет данные | Признак модификации | Команда недоступна, если форма открыта только для просмотра |
Отображение, Картинка, Сочетание клавиш | Внешний вид | На логику не влияют |
Если Тип параметра команды задан, например СправочникСсылка.Контрагенты, платформа сама добавит команду в формы, где есть значение этого типа: форма списка, форма элемента, формы документов с реквизитом-контрагентом (при подходящей группе).
Синтаксис: модуль команды и обработчик
Модуль открывается двойным щелчком по команде или через контекстное меню Открыть модуль команды. Конструктор создаёт заготовку:
&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
// Вставить содержимое обработчика.
КонецПроцедуры
Обработчик выполняется на клиенте. Запросы к базе и запись объектов здесь недоступны. Серверную часть выносят в общий модуль с флагами Сервер и Вызов сервера.
Пример: команда документа «Заказ клиента », которая считает сумму по выделенным заказам.
&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
Если ПараметрКоманды = Неопределено Тогда
Возврат;
КонецЕсли;
Сумма = ЗаказыСервер.СуммаЗаказов(ПараметрКоманды);
ПоказатьОповещениеПользователя("Сумма выделенных заказов",, Формат(Сумма, "ЧДЦ=2; ЧН=0"));
КонецПроцедуры
А в общем модуле ЗаказыСервер (флаги Сервер и Вызов сервера):
Функция СуммаЗаказов(Ссылки) Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ЕСТЬNULL(СУММА(Заказ.СуммаДокумента), 0) КАК Сумма
|ИЗ
| Документ.ЗаказКлиента КАК Заказ
|ГДЕ
| Заказ.Ссылка В (&Ссылки)";
Запрос.УстановитьПараметр("Ссылки", Ссылки);
Выборка = Запрос.Выполнить().Выбрать();
Выборка.Следующий();
Возврат Выборка.Сумма;
КонецФункции
Параметр Ссылки принимает и одну ссылку, и массив: условие В (&Ссылки) работает в обоих случаях. Имена документа и реквизита замените на свои.
Держите в модуле команды минимум кода: проверка параметра, вызов общего модуля, показ результата. Тогда ту же логику можно вызвать из обработки, регламентного задания или другой команды.
Параметры вызова: ПараметрКоманды и ПараметрыВыполненияКоманды
ПараметрКоманды
Сюда платформа передаёт значение, с которым работает команда:
- 📌 при режиме Одиночный — одна ссылка указанного типа;
- 📚 при режиме Множественный — массив ссылок, даже если выделена одна строка;
- ⭕
Неопределено— если тип параметра не задан или строка в списке не выделена.
Чтобы код не падал при смене режима, проверяйте тип:
Если ТипЗнч(ПараметрКоманды) = Тип("Массив") Тогда
Ссылки = ПараметрКоманды;
Иначе
Ссылки = Новый Массив;
Ссылки.Добавить(ПараметрКоманды);
КонецЕсли;
ПараметрыВыполненияКоманды
Объект с данными о том, откуда команду вызвали. Свойства, которые нужны чаще всего:
| Свойство | Что содержит | Зачем нужно |
|---|---|---|
Источник | Форма, из которой нажали команду | Передать владельцем в ОткрытьФорму, прочитать данные формы |
Уникальность | Ключ уникальности | Не открывать вторую копию той же формы |
Окно | Окно, где выполнена команда | Открыть новую форму в том же окне |
НавигационнаяСсылка | Навигационная ссылка источника | Для истории и избранного |
Типичное использование в команде, которая открывает форму:
&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
ПараметрыФормы = Новый Структура("Контрагент", ПараметрКоманды);
ОткрытьФорму("Обработка.СверкаВзаиморасчетов.Форма.Форма",
ПараметрыФормы,
ПараметрыВыполненияКоманды.Источник,
ПараметрыВыполненияКоманды.Уникальность,
ПараметрыВыполненияКоманды.Окно);
КонецПроцедуры
Если команду вызвали не из формы (например, из панели навигации раздела), Источник может быть пустым. Не обращайтесь к его реквизитам без проверки.
Как обратиться к команде объекта с формы и из кода
Способ 1. Кнопка на форме
Самый частый случай. В редакторе управляемой формы:
- Откройте вкладку
Командный интерфейсформы. - Найдите нужную команду объекта в списке и включите видимость.
- Либо перетащите команду из списка глобальных команд в дерево элементов формы — появится кнопка.
Кнопку можно создать и программно. У элемента КнопкаФормы есть свойство ИмяКоманды:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Кнопка = Элементы.Добавить("КнопкаСверка", Тип("КнопкаФормы"), Элементы.ФормаКоманднаяПанель);
Кнопка.ИмяКоманды = "СверитьВзаиморасчеты";
КонецПроцедуры
Здесь СверитьВзаиморасчеты — команда формы. Для команды объекта метаданных строку с полным именем удобно подсмотреть в свойстве ИмяКоманды кнопки, которую вы один раз перетащили на форму вручную, и скопировать в код.
Способ 2. Навигационная ссылка
Команду без обязательного параметра можно открыть через ПерейтиПоНавигационнойСсылке по ссылке вида e1cib/command/<полное имя команды>:
ПерейтиПоНавигационнойСсылке("e1cib/command/Справочник.Контрагенты.Команда.СверкаВзаиморасчетов");
Точную строку проще взять из самого клиента: откройте команду и скопируйте ссылку через меню Ещё → получить ссылку (название пункта может отличаться в разных версиях платформы). Параметр команды так не передать, поэтому способ годится для команд-«открывашек».
Способ 3. Общая процедура вместо вызова команды
Если нужно выполнить действие команды из другого кода, не пытайтесь «нажать» её программно. Вынесите тело в экспортную клиентскую процедуру общего модуля:
// Общий модуль СверкаКлиент (флаг «Клиент (управляемое приложение)»)
Процедура ВыполнитьСверку(Ссылки, Владелец = Неопределено) Экспорт
// логика команды
КонецПроцедуры
Модуль команды сокращается до одной строки:
СверкаКлиент.ВыполнитьСверку(ПараметрКоманды, ПараметрыВыполненияКоманды.Источник);
Теперь ту же процедуру вызывает кнопка на любой форме, другая команда или обработчик оповещения.
Команды формы: вызов напрямую
С командами формы проще. У команды формы есть свойство Действие — имя процедуры модуля формы. Это обычная процедура с параметром Команда, и её можно вызвать из того же модуля:
&НаКлиенте
Процедура Обновить(Команда)
ОбновитьНаСервере();
КонецПроцедуры
&НаКлиенте
Процедура ПриОткрытии(Отказ)
Обновить(Неопределено);
КонецПроцедуры
Если внутри обработчика используется параметр Команда, передавайте Команды.Обновить вместо Неопределено.
Команда и метод: в чём разница
Эти понятия путают чаще всего. Сравнение:
| Признак | Команда объекта | Экспортный метод модуля |
|---|---|---|
| Где описана | Ветка Команды объекта или общие команды | Модуль объекта, менеджера, общий модуль |
| Как вызывается | Платформой при нажатии в интерфейсе | Из кода по имени: Объект.Метод(), Справочники.Имя.Метод() |
| Где выполняется | На клиенте | Там, где разрешено директивой и флагами модуля |
| Возвращает значение | Нет, это процедура | Может, если это функция |
| Права | Право «Просмотр» на команду в роли | Права на объект и данные |
| Видна пользователю | Да, кнопкой или пунктом меню | Нет |
Вывод простой. Команда — точка входа для пользователя. Метод — место, где живёт логика. Хорошая команда почти пустая и вызывает метод.
Пара примеров вызова методов, чтобы не путать:
// Метод модуля менеджера (функция с Экспорт)
Цена = Справочники.Номенклатура.ПолучитьЦену(Ссылка, ТекущаяДата());
// Метод модуля объекта (на сервере)
ОбъектДокумента = Ссылка.ПолучитьОбъект();
ОбъектДокумента.ЗаполнитьТабличнуюЧасть();
ПолучитьЦену и ЗаполнитьТабличнуюЧасть — условные имена ваших экспортных процедур, а не встроенные методы платформы.
Как получить результат выполнения команды
ОбработкаКоманды ничего не возвращает. Результат передают другими способами.
Оповещение открытых форм
Если команда изменила данные, сообщите об этом формам:
ОповеститьОбИзменении(Ссылка); // обновит динамические списки с этой ссылкой
Оповестить("СверкаВыполнена", Ссылка); // своё событие
В форме, которая ждёт результат, событие ловят в обработчике ОбработкаОповещения(ИмяСобытия, Параметр, Источник):
&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
Если ИмяСобытия = "СверкаВыполнена" Тогда
Элементы.Список.Обновить();
КонецЕсли;
КонецПроцедуры
Третий параметр Оповестить (источник) необязателен. Из модуля команды при нужде передают ПараметрыВыполненияКоманды.Источник.
Описание оповещения при закрытии формы
Если команда открывает форму выбора или ввода, результат приходит после её закрытия. Обработчик удобнее держать в клиентском общем модуле, например СверкаКлиент:
// Модуль команды
&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
Оповещение = Новый ОписаниеОповещения("ПослеВыбораПериода", СверкаКлиент, ПараметрКоманды);
ОткрытьФорму("ОбщаяФорма.ВыборПериода", , ПараметрыВыполненияКоманды.Источник, , , , Оповещение);
КонецПроцедуры
// Общий модуль СверкаКлиент
Процедура ПослеВыбораПериода(Результат, Ссылки) Экспорт
Если Результат = Неопределено Тогда
Возврат; // пользователь закрыл форму без выбора
КонецЕсли;
// работа с выбранным периодом
КонецПроцедуры
Процедура-обработчик оповещения обязана быть экспортной, иначе платформа её не найдёт. Третий параметр ОписаниеОповещения попадает в обработчик вторым аргументом — так в него доходят ссылки из команды. ОбщаяФорма.ВыборПериода — пример имени, подставьте свою форму.
Сообщение пользователю
Для коротких итогов хватает ПоказатьОповещениеПользователя (всплывающее окно) или Сообщить (окно сообщений). Для вопроса «Продолжить?» используйте ПоказатьВопрос с описанием оповещения, а не модальный Вопрос.
Ошибки при вызове команд и как их избежать
Ошибки ниже не про конкретное сообщение, а про подход. Именно они дают трудноуловимые сбои.
- ⚠️ Запрос или запись прямо в модуле команды. Модуль клиентский, такой код не скомпилируется или упадёт. Всё серверное — в общий модуль с флагом
Вызов сервера. - ⚠️ Расчёт на одиночный параметр. Сегодня режим «Одиночный», завтра коллега переключит на «Множественный» — и код вида
ПараметрКоманды.Наименованиеупадёт на массиве. Нормализуйте параметр в массив, как в примере выше. - ⚠️ Много серверных вызовов в цикле. Цикл по массиву ссылок с вызовом сервера на каждой итерации тормозит при сотне строк. Передайте весь массив за один вызов.
- ⚠️ Необъявленный экспорт. Процедура, указанная в
ОписаниеОповещения, безЭкспортне вызовется. - ⚠️ Правка типовой конфигурации. Свою команду к типовому справочнику добавляйте через расширение конфигурации (доступно с платформы 8.3.6). Так она переживёт обновление без ручного сравнения.
Если команда массово меняет документы, проверьте её сначала на копии базы. Перепроведение сотен документов в рабочей базе в разгар дня заблокирует таблицы для других пользователей.