Вызов функции во встроенном языке 1С 8.3: от синтаксиса до фоновых заданий
Содержание
Чтобы запустить функцию в 1С 8.3, её нужно вызвать по имени и забрать результат в переменную: Итог = МояФункция(Параметр1, Параметр2);. Процедуру вызывают так же, но без присваивания — отдельной строкой МояПроцедура();. Функция обязана вернуть значение через оператор Возврат, процедура ничего не возвращает. Если метод объявлен с ключевым словом Экспорт, его видно за пределами своего модуля.
Разовый прогон одной функции делают прямо в отладчике Конфигуратора через окно Отладка → Вычислить выражение, а в рабочей базе вызов встраивают в команду формы, обработчик события или фоновое задание. Ниже — все способы вызова, передача параметров, контекст клиент/сервер и разбор ошибок, которые чаще всего мешают коду запуститься.
Синтаксис вызова процедур и функций
Разница между процедурой и функцией в 1С одна: функция возвращает значение, процедура — нет.
// Объявление
Функция СуммаСНДС(Сумма, Ставка = 20) Экспорт
Возврат Сумма + Сумма * Ставка / 100;
КонецФункции
Процедура ЗаписатьВЖурнал(Текст) Экспорт
ЗаписьЖурналаРегистрации("МояПодсистема", , , , Текст);
КонецПроцедуры
Вызов выглядит так:
Цена = СуммаСНДС(1000); // 1200, ставка по умолчанию
Цена = СуммаСНДС(1000, 10); // 1100
ЗаписатьВЖурнал("Расчёт выполнен");
Ключевые правила запуска:
- 🔹 Результат функции нужно куда-то деть. Присвойте его переменной, передайте в другую функцию или в условие. Можно вызвать функцию и как процедуру, отдельной строкой — тогда результат просто отбрасывается.
- 🔹 Процедуру нельзя вызвать как функцию. Строка
Х = МояПроцедура();вызывает ошибкуОбращение к процедуре как к функции. - 🔹 Скобки обязательны даже без параметров.
ОбновитьДанные()— вызов,ОбновитьДанныебез скобок вызовом не является. - 🔹 Регистр и язык. Встроенный язык 1С понимает и русский, и английский синтаксис (
Функция/Function,Возврат/Return), регистр в именах не важен.
Запустить функцию по имени, собранному в строку, умеют операторы Выполнить("…") и Вычислить("…"). Вычислить возвращает результат выражения, Выполнить исполняет оператор. На сервере они работают в безопасном режиме с ограничениями, поэтому в типовом коде их применяют редко — обычно только в универсальных обработках.
Где виден метод: модули, экспорт и контекст выполнения
Запустится функция или нет, зависит от того, из какого модуля вы её зовёте и объявлена ли она экспортной. Встроенный язык 1С разделяет код на модули, и видимость метода определяется их типом.
| Где объявлена функция | Как вызвать из другого места | Условие |
|---|---|---|
| Общий модуль | ОбщийМодуль.Метод() | Метод с Экспорт, модуль не глобальный |
| Глобальный общий модуль | просто Метод() | Флаг «Глобальный» у модуля |
| Модуль объекта (документа, справочника) | Объект.Метод() | Экспорт, есть ссылка на объект |
| Модуль менеджера | Документы.Реализация.Метод() | Экспорт в модуле менеджера |
| Модуль формы | внутри самой формы — по имени | за пределами формы напрямую не вызвать |
Общие модули — главный инструмент для кода, который нужен в разных местах. У модуля есть флаги Клиент (управляемое приложение), Сервер, Вызов сервера, Глобальный. Они задают, откуда метод доступен. Серверный метод клиент напрямую не вызовет: нужен либо флаг «Вызов сервера», либо серверный контекст формы.
Вот как выглядит вызов из разных мест на практике:
// Метод общего модуля (обычный, не глобальный)
Итог = РасчётыСервер.СуммаДокумента(СсылкаНаДокумент);
// Метод глобального общего модуля — без префикса модуля
ЗаписатьСобытие("Старт обработки");
// Метод менеджера документа
НомерНовый = Документы.РеализацияТоваровУслуг.ПолучитьСледующийНомер();
// Метод модуля объекта — через ссылку на объект
Объект = СсылкаНаДокумент.ПолучитьОбъект();
Объект.ПересчитатьСтроки();
Если имя общего модуля или метода указано неверно, платформа сообщит об этом ещё на этапе синтаксического контроля (Текстовое меню → Синтаксический контроль или Ctrl+F7). Запускать базу ради проверки опечатки не нужно.
Директивы компиляции на клиенте и сервере
В модуле формы перед каждым методом ставят директиву — где он исполняется:
&НаКлиенте— выполняется в сеансе пользователя, видит элементы формы, может показывать окна.&НаСервере— выполняется на сервере, имеет полный доступ к данным, но не к интерфейсу.&НаСервереБезКонтекста— то же, но без передачи данных формы туда-обратно. Работает быстрее, используйте по умолчанию для серверных расчётов.&НаКлиентеНаСервереБезКонтекста— общий код, который должен исполняться и там, и там.
Типовая схема: клиентский обработчик нажатия кнопки вызывает серверный метод формы, тот считает и возвращает результат.
&НаКлиенте
Процедура РассчитатьНажатие(Команда)
ЗаполнитьИтогНаСервере(); // прыжок клиент → сервер
КонецПроцедуры
&НаСервере
Процедура ЗаполнитьИтогНаСервере()
Объект.Итог = ПодсчётДанных(); // доступ к базе — только здесь
КонецПроцедуры
Каждый вызов &НаСервере из клиента — это обращение к серверу по сети. В цикле такие вызовы резко тормозят форму. Собирайте данные за один серверный вызов, а не по одному в цикле.
Передача параметров и возврат значения
По умолчанию параметры в 1С передаются по ссылке: если функция меняет параметр, изменение видно снаружи. Чтобы защитить значение от изменения, добавьте перед параметром ключевое слово Знач — тогда передаётся копия.
Процедура Удвоить(Знач Входное, Результат)
Входное = Входное * 2; // снаружи не изменится — передано по значению
Результат = Входное; // изменится — передано по ссылке
КонецПроцедуры
Что полезно знать о параметрах:
- 🔸 Значения по умолчанию задаются только для простых типов:
Функция Расчёт(Сумма, Ставка = 20). Необязательные параметры идут в конце списка. - 🔸 Пропустить параметр в середине можно запятой:
Метод(Знач1, , Знач3)— второй возьмёт значение по умолчанию. - 🔸 Вернуть несколько значений можно двумя путями: завести выходные параметры (по ссылке) либо вернуть структуру через
Возврат Новый Структура("Сумма, Налог", С, Н). Второй вариант читается чище. - 🔸 Ранний выход.
Возврат Значение;в функции иВозврат;в процедуре прерывают выполнение и передают управление обратно вызвавшему коду.
Распространённая ошибка — ждать, что по значению передастся таблица значений или структура. Объектные типы передаются ссылкой на один и тот же объект, и Знач копирует только саму ссылку, а не содержимое. Чтобы получить независимую копию, используйте метод Скопировать() у таблицы значений или рекурсивное копирование структуры.
Ещё одна тонкость — число параметров должно совпадать с объявлением. Платформа не подставит недостающий аргумент сама, если у него нет значения по умолчанию. Для методов, которым может прийти разный набор данных, удобно принимать одну структуру параметров: вызывающий код заполняет только нужные поля, а функция проверяет наличие каждого через Параметры.Свойство("Поле").
Асинхронный вызов и запуск в фоне
Если функция долго считает, запускать её в основном потоке нельзя — форма «зависнет». В 1С 8.3 есть два механизма: асинхронные вызовы на клиенте и фоновые задания на сервере.
Асинхронные методы на клиенте. Диалоги (выбор файла, вопрос пользователю) в тонком и веб-клиенте работают только асинхронно. Начиная с платформы 8.3.18 доступен современный синтаксис Асинх/Ждать:
&НаКлиенте
Асинх Процедура СпроситьИЗаписать()
Ответ = Ждать ВопросАсинх("Записать документ?", РежимДиалогаВопрос.ДаНет);
Если Ответ = КодВозвратаДиалога.Да Тогда
ЗаписатьНаСервере();
КонецЕсли;
КонецПроцедуры
В более старых релизах тот же результат давали через ОписаниеОповещения: вы указываете процедуру-обработчик, которую платформа вызовет после ответа пользователя.
Фоновые задания на сервере. Чтобы запустить функцию в отдельном потоке на сервере, применяют объект ФоновыеЗадания. Метод должен быть экспортной процедурой серверного общего модуля:
&НаСервереБезКонтекста
Функция ЗапуститьФон()
Параметры = Новый Массив;
Параметры.Добавить(ТекущаяДата());
Задание = ФоновыеЗадания.Выполнить("РасчётыСервер.ПересчитатьОстатки", Параметры);
Возврат Задание.УникальныйИдентификатор;
КонецФункции
В типовых конфигурациях на Библиотеке стандартных подсистем для долгих операций есть готовый общий модуль ДлительныеОперации с методами ВыполнитьФункцию и ВыполнитьПроцедуру. Он сам создаёт фоновое задание и показывает пользователю индикатор прогресса — писать обвязку вручную не нужно.
Фоновое задание выполняется от имени своего сеанса и не видит данных формы. Передавайте в него только сериализуемые значения (ссылки, примитивы, структуры из них), а результат возвращайте через регистр, временное хранилище или сам объект задания.
Как запустить одну функцию для проверки
Иногда нужно просто прогнать метод и посмотреть результат, не встраивая вызов в интерфейс. Способы по возрастанию трудозатрат:
- Окно «Вычислить выражение». В режиме отладки встаньте на точку останова, откройте
Отладка → Вычислить выражение(или выделите вызов и нажмитеShift+F9), впишитеМояФункция(123)и нажмите «Рассчитать». Результат виден сразу. - Табло. Добавьте выражение в Табло (
Отладка → Табло) — оно будет пересчитываться на каждом шаге. - Временная команда. В обработке или форме заведите кнопку с одной строкой вызова. Самый наглядный способ для метода, которому нужен контекст формы.
- Внешняя обработка. Для разовой проверки серверного кода соберите внешнюю обработку
с модулем объекта и запустите её через
Файл → Открыть.
Отладка и разбор ошибок при вызове
Отладчик 1С встроен в Конфигуратор. Чтобы он заработал, в настройках информационной базы должна быть включена отладка, а запуск вести из Конфигуратора командой Отладка → Начать отладку (F5) либо подключиться к
уже запущенному сеансу через Отладка → Подключение.
Базовые приёмы:
- 🔺 Точка останова —
F9на строке. Выполнение встанет здесь, и можно посмотреть значения переменных. - 🔺 Шаги —
F11заходит внутрь вызываемой функции,F10выполняет её целиком не заходя,Shift+F11выходит из текущего метода. - 🔺 Стек вызовов показывает, какая функция кого вызвала — помогает понять, откуда пришли «неправильные» параметры.
- 🔺 Отладка на сервере требует, чтобы отладка по протоколу была разрешена в настройках кластера; иначе серверные
&НаСервере-методы под отладчик не попадут.
Частые ошибки, из-за которых функция не запускается:
Экспорт, правильно ли указан общий модуль, совпадает ли директива компиляции (клиентский код не видит серверные методы напрямую).Х = МояПроцедура()). Процедура ничего не возвращает — либо уберите присваивание, либо замените объявление на Функция с оператором Возврат.Неопределено. Чаще всего это пустой результат поиска или незаполненный реквизит — добавьте проверку перед вызовом.Оптимизация и хорошие привычки при вызове
Код, который запускается правильно, должен ещё и не тормозить. Несколько правил, проверенных на типовых конфигурациях:
- ⚡ Минимум серверных вызовов. Один «толстый» вызов
&НаСервередешевле десяти мелких. Собирайте нужные данные за одно обращение. - ⚡ Без контекста, где можно.
&НаСервереБезКонтекстане гоняет данные формы туда-обратно — используйте его для чистых расчётов. - ⚡ Функции без побочных эффектов. Функция, которая только считает и возвращает результат, предсказуема и легко тестируется. Запись в базу выносите в процедуры.
- ⚡ Понятные имена.
РассчитатьНДСПоСтавкевместоРасчёт2. Через полгода читать код будете вы же. - ⚡ Проверка входных данных. В начале метода проверьте параметры на
Неопределенои пустые ссылки — это дешевле, чем ловить ошибку в середине расчёта.
Частые вопросы
Можно ли вызвать функцию формы из общего модуля?
Почему клиентский код не видит мою серверную функцию?
В чём разница между `Выполнить` и `Вычислить`?
Вычислить("Выражение") возвращает результат выражения, его можно присвоить. Выполнить("Оператор") исполняет оператор и ничего не возвращает. Оба работают со строкой кода и на сервере ограничены безопасным режимом.Как передать несколько значений обратно из функции?
Знач), либо вернуть структуру: Возврат Новый Структура("Сумма, Налог", С, Н). Структура нагляднее и не путает порядок выходных параметров.