Разработка и Конфигурация · 11 мин
Как в 1С выполнить команду программно
Как программно выполнить команду в 1С: Выполнить(), команды формы, запуск внешних программ, обработчики. Примеры кода, ошибки и ограничения безопасности.
Программный вызов команды — одна из базовых задач при доработке конфигураций 1С. Под «командой» разработчики обычно понимают три разные вещи: выполнение произвольного фрагмента кода на встроенном языке, вызов команды формы или глобальной команды интерфейса и запуск внешней программы операционной системы. У каждого сценария свой механизм, свои ограничения и свои риски.
Выбор способа зависит от контекста: код выполняется на клиенте или на сервере, в управляемом или обычном приложении, в безопасном режиме или с полными правами. Ошибка в выборе приводит либо к падению с сообщением «Метод объекта не обнаружен», либо к тому, что действие просто не срабатывает без видимых причин.
Ниже разобраны основные механизмы с примерами кода, условиями применения и типичными ошибками. Примеры даны для управляемых форм на платформе 8.3, где это уместно отмечены отличия обычного приложения.
Определите, какую именно команду нужно выполнить
Термин «команда» в 1С перегружен. Глобальная команда — это элемент командного интерфейса, привязанный к объекту метаданных (например, команда открытия списка документов). Команда формы — элемент конкретной формы, связанный с обработчиком. Команда ОС — запуск исполняемого файла или скрипта операционной системы. Наконец, «выполнить команду» часто означает «выполнить строку кода», переданную как текст.
Прежде чем писать код, ответьте на вопросы: где должен выполняться вызов (клиент или сервер), есть ли у вас доступ к нужному объекту (форма открыта или нет), требуется ли интерактивность (вопросы пользователю, предупреждения). От ответов зависит выбор механизма и набор директив компиляции.
Выполнение произвольного кода через Выполнить()
Метод Выполнить(СтрокаКода) выполняет переданный текст как фрагмент встроенного языка. Типичное применение — пользовательские алгоритмы в отчётах, обменах и настройках, где формула или обработчик хранится в базе как строка.
Процедура ВыполнитьАлгоритм(ТекстАлгоритма, Результат)
Выполнить(ТекстАлгоритма);
КонецПроцедуры
Ключевые ограничения: метод недоступен в безопасном режиме (внешние обработки, расширения, регламентные задания с включённым профилем безопасности) и не работает в контексте тонкого клиента при вызове на клиенте в ряде сценариев — надёжнее использовать его только на сервере. Код внутри строки не видит локальные переменные вызывающей процедуры, кроме тех, что переданы через параметры окружения (например, переменные модуля или экспортные переменные).
Альтернатива Выполнить() — метод Вычислить(Выражение), который возвращает значение выражения и удобен для формул: Результат = Вычислить("Цена Количество 1.2"). Ограничения по безопасному режиму у него те же.
Программный вызов команды формы
Самый надёжный способ «нажать кнопку программно» — вызвать её обработчик напрямую, как обычную процедуру. Если обработчик команды называется ЗаполнитьПоОстаткам, достаточно вызвать ЗаполнитьПоОстаткам(Неопределено) из другого обработчика формы. Параметр команды можно передать как Неопределено, если логика его не использует.
Когда нужен именно вызов через механизм команд (например, чтобы сработала стандартная логика платформы), используется коллекция ЭтаФорма.Команды. Однако у программного вызова команд формы есть ограничение: платформа не предоставляет универсального метода «ВыполнитьКоманду» для произвольной команды формы в управляемом приложении — поэтому на практике вызывают обработчик напрямую либо выносят общую логику в отдельную процедуру, которую вызывают и из команды, и из кода.
&НаКлиенте
Процедура КнопкаОбновить(Команда)
ОбновитьДанныеНаСервере();
КонецПроцедуры
&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи)
// Имитируем нажатие кнопки "Обновить"
КнопкаОбновить(Неопределено);
КонецПроцедуры
Если одна и та же логика нужна и кнопке, и программному вызову, вынесите её в отдельную процедуру без параметра Команда. Тогда не придётся передавать фиктивное Неопределено и код станет читаемее.
Вызов стандартных команд объекта и глобальных команд
Стандартные действия — записать, провести, пометить на удаление — вызываются методами объекта, а не через интерфейсные команды. Для документа это ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение), для справочника — СправочникОбъект.Записать(). Такой вызов надёжнее любой имитации нажатий: он работает на сервере, в фоновых заданиях и не зависит от открытых форм.
Глобальные команды интерфейса (открытие списка, создание документа) программно «нажимаются» через соответствующие методы: ОткрытьФорму("Список.Документы.РеализацияТоваровУслуг") или ОткрытьФорму("Документ.РеализацияТоваровУслуг.ФормаОбъекта"). Это эквивалент выбора пункта меню пользователем, доступный только на клиенте.
Запуск внешних программ и команд операционной системы
Для запуска внешней программы или команды ОС в управляемом приложении используются два метода. ЗапуститьПриложение(СтрокаКоманды, Каталог, ДождатьсяЗавершения, КодВозврата) — асинхронный вариант, доступный на клиенте. КомандаСистемы(СтрокаКоманды, КакОповестить) — выполняет команду оболочки, на сервере работает с учётом прав учётной записи агента сервера 1С.
&НаКлиенте
Процедура ЗапуститьОбработкуФайлов(Команда)
СтрокаКоманды = "C:\Tools\converter.exe /in:D:\data\file.csv";
ЗапуститьПриложение(СтрокаКоманды, "D:\data\", Истина, КодВозврата);
Если КодВозврата = 0 Тогда
Сообщить("Обработка завершена успешно");
Иначе
Сообщить("Ошибка, код возврата: " + КодВозврата);
КонецЕсли;
КонецПроцедуры
В тонком и веб-клиенте для методов, запускающих приложения и работающих с файловой системой, требуется включённое расширение работы с файлами, иначе вызов завершится ошибкой. На сервере учитывайте, что интерактивные программы (с окнами) запускать бессмысленно — у сеанса сервера нет рабочего стола.
Выполнение команд в обычном приложении и через COM
В обычном приложении доступен дополнительный приём: интерактивный вызов стандартных действий через ЭтаФорма.ВыполнитьКоманду(...) для командных панелей, а также метод ВыполнитьДействие() у отдельных элементов. Эти механизмы не переносятся в управляемые формы — при миграции их заменяют прямыми вызовами обработчиков и методов объекта.
Отдельный сценарий — выполнение команды в другой базе 1С через COM-соединение (V83.COMConnector). После установки соединения строка кода выполняется в контексте внешней базы методом Соединение.Execute() недоступно — вместо этого используют вызовы экспортных процедур общих модулей внешней базы либо Выполнить через объектную модель там, где она доступна. На практике надёжнее публиковать в вызываемой базе специальный экспортный метод и обращаться именно к нему.
Сравнение способов
Для алгоритмов, хранящихся строкой в базе. Не работает в безопасном режиме, требует контроля прав.
Для команд формы. Просто и надёжно, но только внутри модуля этой формы.
Для стандартных действий с данными. Работает везде, включая фоновые задания.
Для внешних программ и скриптов ОС. Требует прав и расширения работы с файлами на клиенте.
Проверка результата и типичные ошибки
После программного выполнения команды результат нужно проверять, а не предполагать. Для внешних программ анализируйте код возврата (ноль обычно означает успех, но соглашение зависит от конкретной программы). Для записи объектов оборачивайте вызов в попытку и читайте текст исключения. Для Выполнить() ошибка синтаксиса в строке кода проявится только в момент выполнения — компилятор модуль не проверяет.
Как проверить результат
Нет исключения, объект в базе имеет ожидаемый статус проведения
Исключение с текстом ошибки или объект остался непроведённым
Код возврата 0 (или ожидаемый), выходной файл создан и не пуст
Ненулевой код, файл отсутствует или нулевого размера
Переменные-результаты заполнены, исключений нет
Ошибка синтаксиса или «Переменная не определена» в момент вызова
Частые вопросы
Можно ли выполнить произвольный код на клиенте?
Метод Выполнить() ориентирован на серверный контекст; в тонком клиенте его применение ограничено и не рекомендуется. Для клиентской логики храните алгоритмы в виде предопределённых вариантов и выбирайте нужный условным оператором, а не строкой кода.
Почему Выполнить() выдаёт ошибку во внешней обработке?
Внешние обработки по умолчанию открываются в безопасном режиме, где Выполнить() и Вычислить() запрещены. Либо отключите безопасный режим при открытии (параметр БезопасныйРежим = Ложь, что требует прав и оправдано только для доверенных обработок), либо перенесите логику в явный код.
Как программно провести документ из формы списка?
Получите объект выделенной ссылки: ДокОбъект = Ссылка.ПолучитьОбъект(), затем ДокОбъект.Записать(РежимЗаписиДокумента.Проведение). Делайте это в серверной процедуре, чтобы не гонять объект между клиентом и сервером.
Как дождаться завершения внешней программы?
В ЗапуститьПриложение передайте третий параметр ДождатьсяЗавершения = Истина и четвёртым параметром получите код возврата. Учтите, что на время ожидания интерфейс клиента будет заблокирован — для длительных операций лучше фоновое выполнение на сервере.
Можно ли вызвать команду другой открытой формы?
Напрямую — нет, у формы нет публичного механизма вызова команд извне. Варианты: оповещения (Оповестить/ОбработкаОповещения), экспортные процедуры формы при получении на неё ссылки, либо перенос общей логики в общий модуль, доступный обеим формам.
Чем опасен Выполнить() с пользовательскими алгоритмами?
Код выполняется с правами текущего сеанса и может изменять или удалять любые доступные данные. Ограничьте круг лиц, редактирующих алгоритмы, храните историю изменений и тестируйте новые алгоритмы на копии базы.
Что важно запомнить
Сначала определите, что за «команда» нужна: строка кода — Выполнить() на сервере, действие формы — прямой вызов обработчика, стандартное действие с данными — методы объекта, внешняя программа — ЗапуститьПриложение или КомандаСистемы. Всегда проверяйте результат и учитывайте ограничения безопасного режима и контекста выполнения.