Запуск процедур обработок в 1С: все рабочие способы
Содержание
Чтобы вызвать процедуру обработки, недостаточно знать её имя — нужен объект обработки, из которого эту процедуру дёргают. Частая ошибка новичка: написать Обработки.ЗагрузкаДанных.ВыполнитьЗагрузку() и получить «Значение не является значением объектного типа
». Обработки.ЗагрузкаДанных — это менеджер, у него нет вашей процедуры. Сначала Создать(), потом вызов метода у полученного объекта.
Разберём три сценария: внешняя обработка из файла .epf, встроенная обработка конфигурации и выполнение произвольного кода строкой через Выполнить. Плюс то, на чём спотыкаются: экспортные процедуры, перехват ошибок и разница между клиентом и сервером.
Что считать «процедурой обработки» и где у неё вход
Обработка в 1С — это объект метаданных с собственным модулем. Процедуры и функции живут в двух местах:
- 📄 Модуль объекта — методы самой обработки как сущности. Их вызывают у экземпляра, полученного через
Создать(). - 🖥 Модуль формы — обработчики команд и событий конкретной формы. Снаружи, из другого кода, к ним напрямую не обращаются.
- ⚙️ Модуль менеджера — методы, которые вызывают без создания экземпляра, прямо у менеджера:
Обработки.ИмяОбработки.МетодМенеджера().
Ключевое правило: процедуру модуля объекта видно снаружи, только если она помечена Экспорт.
// Модуль объекта обработки
Процедура ВыполнитьЗагрузку(ИмяФайла) Экспорт
// код загрузки
КонецПроцедуры
Без Экспорт вызов Объект.ВыполнитьЗагрузку(...) упадёт с «Метод объекта не обнаружен
». Это не баг — это область видимости.
Коротко, от какого объекта что вызывают:
| Что вызываем | Откуда | Как получить |
|---|---|---|
| Метод модуля объекта | экземпляр обработки | Обработки.Имя.Создать() или ВнешниеОбработки.Создать(путь) |
| Метод модуля менеджера | менеджер, без экземпляра | Обработки.Имя.Метод() |
| Обработчик модуля формы | только сама форма | снаружи недоступен |
Как создать и запустить внешнюю обработку из файла .epf
Внешняя обработка лежит отдельным файлом и не входит в конфигурацию. Запускают её через глобальный менеджер ВнешниеОбработки.
Способ 1 — создать объект и вызвать метод. Подходит, когда нужно отработать программно, без открытия формы:
Обработка = ВнешниеОбработки.Создать("C:\Обработки\Загрузка.epf", Ложь);
Обработка.ВыполнитьЗагрузку("C:\Данные\прайс.xlsx");
Первый параметр Создать() — путь к файлу (или имя уже подключённой обработки). Второй — безопасный режим. Передавайте второй параметр явно: в безопасном режиме обработке запрещены файловые операции, COM и запуск внешних программ. Если обработка должна читать файл с диска или ходить во внешнюю систему — безопасный режим нужно отключить (Ложь) и понимать, что вы запускаете чужой код с полными правами.
Способ 2 — подключить и открыть форму. Когда у обработки есть интерфейс и её запускает пользователь:
ИмяОбработки = ВнешниеОбработки.Подключить("C:\Обработки\Загрузка.epf");
Форма = ВнешниеОбработки.ПолучитьФорму(ИмяОбработки);
Форма.Открыть();
Подключить() регистрирует обработку в текущем сеансе и возвращает её уникальное имя. ПолучитьФорму() и Создать() принимают уже это имя, а не путь. Отличие от Создать() по пути: подключённую обработку можно многократно открывать и создавать по короткому имени, не передавая путь к файлу каждый раз — удобно, когда обработку дёргают из нескольких мест сеанса.
ПолучитьФорму() и его Открыть() вызывают на клиенте — именно там живёт интерфейс. Сам же разбор данных, ради которого обработку и запускают, обычно уходит на сервер. Где проходит эта граница — в разделе про клиент и сервер ниже.
Путь к файлу вычисляется в том контексте, где выполняется Создать(). Если код идёт на сервере, путь C:\... — это диск сервера, а не компьютера пользователя. В тонком и веб-клиенте прямого доступа к файлу у сервера нет — об этом ниже.
Как обратиться к встроенной обработке конфигурации
Обработка, добавленная в дерево конфигурации, доступна через глобальный менеджер Обработки.
Создать экземпляр и вызвать экспортную процедуру модуля объекта:
Обработка = Обработки.ЗакрытиеМесяца.Создать();
Обработка.ВыполнитьЗакрытие(ТекущаяДата());
Открыть форму встроенной обработки на клиенте — через ОткрытьФорму:
ОткрытьФорму("Обработка.ЗакрытиеМесяца.Форма.Форма");
Третий сегмент — имя формы в метаданных. Если у обработки назначена основная форма, хватает "Обработка.ЗакрытиеМесяца.ФормаОбъекта" или просто пути до нужной формы.
Метод модуля менеджера вызывают вообще без Создать():
Результат = Обработки.ЗакрытиеМесяца.ПроверитьГотовность();
💡 Разделение по назначению: тяжёлую бизнес-логику держите в модуле объекта (экспортные процедуры), а то, что нужно дёргать из разных мест без создания экземпляра, — в модуле менеджера.
Как вызвать обработку динамически через объект метаданных
Иногда имя обработки заранее неизвестно — например, нужно перебрать все обработки конфигурации или выбрать одну по строке из настроек. Тогда идут через коллекцию метаданных.
Перебор всех обработок:
Для Каждого ОписаниеОбработки Из Метаданные.Обработки Цикл
Сообщить(ОписаниеОбработки.Имя + " — " + ОписаниеОбработки.Синоним);
КонецЦикла;
Метаданные.Обработки даёт объекты описания (имя, синоним, комментарий), но не экземпляры. Чтобы получить рабочий объект по имени-строке, обращайтесь к менеджеру через квадратные скобки:
ИмяОбработки = "ЗакрытиеМесяца"; // пришло из настройки
МенеджерОбработки = Обработки[ИмяОбработки];
Объект = МенеджерОбработки.Создать();
Объект.ВыполнитьЗакрытие(ТекущаяДата());
Запись Обработки[ИмяОбработки] возвращает тот же менеджер, что и Обработки.ЗакрытиеМесяца, только имя задаётся строкой. Это и есть «вызов через объект метаданных»: метаданные дают список имён, а менеджер по имени — рабочий экземпляр.
Если нужного имени в конфигурации нет, Обработки[ИмяОбработки] вызовет исключение. Проверяйте вход заранее — например, собрав допустимые имена в один проход по Метаданные.Обработки.
Как передать параметры в процедуру и забрать результат
Чаще всего обработку зовут не просто «запустись», а «отработай вот эти данные и верни, что получилось». Здесь важны две вещи: как параметры передаются и чем процедура отличается от функции.
По умолчанию параметр передаётся по ссылке: если процедура меняет его внутри, изменение видно в вызывающем коде. Чтобы запретить это и передать по значению — ставят Знач перед именем параметра.
// Модуль объекта обработки
Процедура ЗаполнитьТаблицу(Знач Период, ТаблицаРезультата) Экспорт
// Период менять нельзя — он пришёл по значению (Знач)
// ТаблицаРезультата заполняется здесь и возвращается вызывающему по ссылке
КонецПроцедуры
Вызов с подготовленной таблицей, которую процедура заполнит:
Обработка = Обработки.АнализПродаж.Создать();
Итог = Новый ТаблицаЗначений;
Обработка.ЗаполнитьТаблицу(КонецМесяца(ТекущаяДата()), Итог);
// Итог заполнен внутри процедуры
Если из вызова нужно именно значение — делайте не процедуру, а функцию с Возврат:
Функция ПосчитатьИтог(Знач Данные) Экспорт
Сумма = 0;
Для Каждого Строка Из Данные Цикл
Сумма = Сумма + Строка.Сумма;
КонецЦикла;
Возврат Сумма;
КонецФункции
💡 Практичный приём для необязательных параметров — значение по умолчанию прямо в объявлении: Процедура Выполнить(РежимОтладки = Ложь) Экспорт. Тогда старый код, который зовёт Выполнить() без аргумента, продолжит работать после того, как вы добавите параметр.
Как выполнить произвольный код процедуры строкой
Когда код процедуры хранится как текст (в реквизите, в настройке, в макете), его исполняют операторами Выполнить и Вычислить.
Выполнить(СтрокаКода)— исполняет строку как операторы, ничего не возвращает.Вычислить(Выражение)— вычисляет выражение и возвращает результат.
Выполнить("Сообщить('Обработка запущена');");
НалоговаяБаза = 100000;
Ставка = Вычислить("НалоговаяБаза * 0.2");
Вычислить видит локальные переменные того метода, где вызван, — в примере выше НалоговаяБаза доступна. Это удобно для настраиваемых формул: храните выражение строкой, подставляйте значения переменными, считайте Вычислить.
Выполнить и Вычислить — дыра в безопасности, если строка приходит от пользователя или из обмена. Исполняется произвольный код с правами сеанса. На сервере и в безопасном режиме эти операторы ограничены. Не пускайте в них внешние данные без жёсткой проверки, а лучше замените явным разбором допустимых формул.
Отдельно: эти операторы не умеют объявлять процедуры. Строка "Процедура Тест() ... КонецПроцедуры" в Выполнить не скомпилируется — исполняются только операторы, а не определения методов.
Как перехватить ошибку при вызове
Любой из способов выше может упасть: нет файла, метод не экспортный, внутри обработки необработанное исключение. Оборачивайте вызов в Попытка.
Попытка
Обработка = ВнешниеОбработки.Создать("C:\Обработки\Загрузка.epf", Ложь);
Обработка.ВыполнитьЗагрузку("C:\Данные\прайс.xlsx");
Исключение
Инфо = ИнформацияОбОшибке();
ЗаписьЖурналаРегистрации("ВнешняяОбработка.Запуск",
УровеньЖурналаРегистрации.Ошибка, , ,
ПодробноеОписаниеОшибки(Инфо));
Сообщить("Не удалось выполнить обработку: " + ОписаниеОшибки());
КонецПопытки;
Что использовать внутри Исключение:
| Метод | Что даёт |
|---|---|
ОписаниеОшибки() | короткий текст ошибки — показать пользователю |
ИнформацияОбОшибке() | объект с причиной, модулем, строкой — для разбора |
ПодробноеОписаниеОшибки(Инфо) | полный стек — в журнал регистрации |
Свою ошибку с понятным текстом бросают через ВызватьИсключение:
Если НЕ ЗначениеЗаполнено(ИмяФайла) Тогда
ВызватьИсключение "Не указан файл для загрузки";
КонецЕсли;
Типовые ошибки запуска и причины:
Экспорт, либо опечатка в имени. Добавьте Экспорт и сверьте регистр и символы имени.Объект = Обработки.Имя.Создать(), потом Объект.Метод().Создать() значение Ложь, если источнику доверяете.Клиент или сервер: где физически выполняется код
Это чаще всего ломает запуск в тонком и веб-клиенте. Место выполнения задают директивы компиляции:
&НаКлиенте— код идёт на компьютере пользователя, есть доступ к его файловой системе и формам.&НаСервере/&НаСервереБезКонтекста— код идёт на сервере 1С, доступа к диску пользователя нет.
ВнешниеОбработки.Создать() можно вызвать и на клиенте, и на сервере — но путь к файлу всегда локален для той стороны, где выполняется строка. В файловой базе клиент и сервер — один компьютер, поэтому в ней всё «просто работает». В клиент-серверной базе через тонкий клиент путь C:\Обработки\... на сервере указывает на диск сервера.
Рабочая схема для тонкого/веб-клиента, когда файл у пользователя:
- На клиенте выбрать файл (
НачатьПомещениеФайла/ диалог выбора) и положить его во временное хранилище. - Передать адрес хранилища в серверную процедуру.
- На сервере получить двоичные данные из хранилища, записать во временный файл сервера и создать обработку оттуда.
&НаСервере
Процедура ЗапуститьОбработкуНаСервере(АдресВХранилище)
ВременныйФайл = ПолучитьИмяВременногоФайла("epf");
ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресВХранилище);
ДвоичныеДанные.Записать(ВременныйФайл);
Обработка = ВнешниеОбработки.Создать(ВременныйФайл, Ложь);
Обработка.ВыполнитьЗагрузку();
УдалитьФайлы(ВременныйФайл);
КонецПроцедуры
Тот же разбор нужен при запуске из фонового задания. Фоновое задание выполняется на сервере и без пользователя: диалогов, предупреждений и обращений к файловой системе клиента там быть не может. Поэтому процедуру, которую планируете гонять фоном, пишут «серверно» — без Вопрос, Предупреждение и клиентских методов, а результат и ошибки отдают через возвращаемое значение, параметр или журнал регистрации.
Параметры = Новый Массив;
Параметры.Добавить(КонецМесяца(ТекущаяДата()));
ФоновыеЗадания.Выполнить("РегламентныеОперации.ВыполнитьЗакрытие",
Параметры, , "Фоновое закрытие месяца");
Первый аргумент — имя экспортного метода в формате ИмяОбщегоМодуля.ИмяМетода; метод должен лежать в серверном общем модуле. Параметры передаются массивом в том же порядке, что и в объявлении процедуры. Внутри такой метод уже создаёт обработку через Обработки.ЗакрытиеМесяца.Создать() и вызывает её логику.
Запуск внешней обработки на сервере с отключённым безопасным режимом исполняет её код с правами серверного процесса. Включайте такой путь только для обработок из доверенного источника и, по возможности, через механизм дополнительных отчётов и обработок с профилями безопасности.
Перед запуском внешней обработки стоит пройтись по короткому чек-листу:
Частые вопросы
Чем `Выполнить` отличается от `Вычислить`?
Выполнить исполняет строку как операторы и ничего не возвращает. Вычислить вычисляет выражение и возвращает значение. Для формулы-строки нужен Вычислить.Почему процедура обработки не видна из другого модуля?
Экспорт. Обработчики модуля формы снаружи недоступны в принципе — их вызывает только сама форма.Можно ли вызвать обработку по имени-строке?
Обработки[ИмяОбработки].Создать(). Имя можно взять из настройки или собрать перебором Метаданные.Обработки.Внешняя обработка не находит файл, хотя путь верный. В чём дело?
Безопасно ли пускать в `Выполнить` строку из реквизита, который заполняет пользователь?
Выполнить.