Разработка и Конфигурация · 11 мин
Как получить результат функции в 1С
Как получить результат функции в 1С: оператор Возврат, вызов функций из модулей, возврат нескольких значений через структуру, типичные ошибки и проверка результата.
Функция во встроенном языке 1С — это именованный блок кода, который выполняет вычисления и возвращает значение тому, кто её вызвал. Получить результат функции можно только если она объявлена ключевым словом Функция (а не Процедура) и содержит оператор Возврат с выражением. Если функция завершилась без Возврат, вызывающий код получит значение Неопределено — это одна из самых частых причин неочевидных ошибок в прикладном коде.
Результат функции присваивают переменной, используют в выражении, передают в другую функцию или проверяют в условии. Способ получения зависит от того, где объявлена функция: в том же модуле, в общем модуле, в модуле объекта или в модуле менеджера. Ниже разобраны все основные сценарии с примерами кода, ограничения платформы и типичные ошибки, из-за которых результат теряется или оказывается не тем, что ожидал разработчик.
Как функция возвращает значение: оператор Возврат
Оператор Возврат завершает выполнение функции и передаёт значение обратно в точку вызова. Выражение после Возврат может быть любым: литерал, переменная, вычисление, результат запроса. Как только оператор выполнен, код функции ниже него не отработает — это важно учитывать при ветвлениях.
Функция РассчитатьСуммуСНДС(Сумма, СтавкаНДС) Экспорт
Если СтавкаНДС = 0 Тогда
Возврат Сумма;
КонецЕсли;
Возврат Сумма + Сумма * СтавкаНДС / 100;
КонецФункции
Если хотя бы одна ветка логики не содержит Возврат, при прохождении по ней функция вернёт Неопределено. Проверяйте все пути выполнения: условия Если...Иначе, обработку исключений, циклы с досрочным выходом. Полезная практика — объявить в начале функции переменную результата со значением по умолчанию и вернуть её в конце, тогда «пустой» исход исключён.
Оператор Возврат без выражения допустим только в процедурах. В функции он вернёт Неопределено, что почти всегда является ошибкой логики, а не осознанным решением.
Получение результата при вызове в том же модуле
Простейший случай — функция объявлена и вызывается в одном модуле, например в модуле формы или модуле объекта. Результат присваивают переменной или сразу используют в выражении:
СуммаИтог = РассчитатьСуммуСНДС(10000, 20);
Если РассчитатьСуммуСНДС(10000, 20) > 11000 Тогда
// действие при превышении порога
КонецЕсли;
Присваивание в переменную предпочтительнее, если результат нужен несколько раз: повторный вызов функции с теми же параметрами — это лишние вычисления, а если внутри есть запрос к базе данных — ещё и лишняя нагрузка на СУБД. Вызов прямо в условии оправдан для одноразовой проверки.
Обратите внимание на контекст компиляции: в управляемой форме функция с директивой &НаСервере недоступна из клиентского кода напрямую — потребуется серверный вызов из клиентской процедуры. Директиву &НаСервереБезКонтекста выбирают, когда функции не нужны данные формы: такой вызов работает быстрее, потому что не сериализует форму целиком.
Вызов функции из общего модуля
Общие модули — стандартное место для функций, которые нужны в нескольких объектах конфигурации. Чтобы функция была видна снаружи, после списка параметров ставится ключевое слово Экспорт:
// Общий модуль РасчетыСервер
Функция ПолучитьКурсВалюты(Валюта, ДатаКурса) Экспорт
// запрос к регистру сведений
Возврат Курс;
КонецФункции
// Вызов из любого другого модуля:
Курс = РасчетыСервер.ПолучитьКурсВалюты(ВалютаUSD, ТекущаяДатаСеанса());
Имя общего модуля становится частью пространства имён, поэтому оно должно быть уникальным и не конфликтовать с именами объектов конфигурации. Вызов записывается как ИмяМодуля.ИмяФункции(). Если модуль имеет флаг «Сервер», его функции недоступны на клиенте; флаг «Клиент (управляемое приложение)» — наоборот. Для универсальных расчётов обычно включают «Сервер» и «Вызов сервера», а клиентские функции выносят в отдельный модуль.
Если функция вызывается часто и возвращает одни и те же данные в течение сеанса, рассмотрите общий модуль с повторным использованием возвращаемых значений (свойство «Повторное использование возвращаемых значений»). Это кэширование на уровне платформы: повторный вызов с теми же параметрами не выполняет код заново.
- 1Создайте общий модуль и включите нужные флаги компиляции (Сервер, Вызов сервера)
- 2Объявите функцию с ключевым словом Экспорт и оператором Возврат
- 3Вызовите функцию по схеме ИмяМодуля.ИмяФункции(Параметры) и присвойте результат переменной
- 4Проверьте результат на Неопределено перед использованием
- 5Прогоните вызов через отладчик, убедившись, что выполнилась именно нужная ветка
Возврат нескольких значений: структура и другие способы
Оператор Возврат передаёт одно значение, но на практике функция часто должна вернуть несколько связанных данных. Стандартное решение — вернуть структуру:
Функция ДанныеКонтрагента(Ссылка) Экспорт
Результат = Новый Структура;
Результат.Вставить("Наименование", "");
Результат.Вставить("ИНН", "");
Результат.Вставить("Найден", Ложь);
// ... заполнение из запроса
Возврат Результат;
КонецФункции
Альтернативы структуре — массив (когда значения однотипные и порядок важнее имён), соответствие (для произвольных ключей) и возврат через параметры. Параметры в 1С по умолчанию передаются по ссылке, поэтому изменение параметра внутри функции видно вызывающему коду. Этот приём работает, но считается менее читаемым: у функции появляется скрытый «побочный выход», который легко пропустить при ревью кода.
Сравнение вариантов
Подходит почти всегда: именованные поля, легко расширять. Ограничение — имена ключей должны быть валидными идентификаторами
Подходит для однотипных значений и когда количество заранее неизвестно; смысл элементов держится только на порядке
Подходит для доработки существующего кода без смены сигнатуры; усложняет чтение и отладку
Получение результата функций запроса и встроенных методов
Многие встроенные методы платформы — тоже функции, и их результат нужно корректно принимать. Классический пример — работа с запросом: метод Выполнить() возвращает результат запроса, из которого затем получают выборку или выгрузку:
РезультатЗапроса = Запрос.Выполнить();
Если РезультатЗапроса.Пустой() Тогда
Возврат Неопределено;
КонецЕсли;
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
// обработка строки
КонецЦикла;
Другие частые функции платформы: НайтиПоКоду() и НайтиПоНаименованию() возвращают ссылку или пустую ссылку, Найти() для строк — позицию или 0, ВыбратьСтроку() табличного документа — признак выбора. Перед использованием результата уточняйте в синтакс-помощнике, что именно возвращает метод: тип возвращаемого значения указан в описании, и он может меняться в зависимости от параметров.
Как проверить результат
Ожидаемый тип и содержимое (число, строка, ссылка, структура)
Неопределено или значение другого типа — ищите ветку без Возврат
Непустая ссылка, Пустая() возвращает Ложь
Пустая ссылка — элемент не найден, обращение к реквизитам даст ошибку
Пустой() = Ложь, выборка содержит строки
Пустой() = Истина — проверяйте параметры и текст запроса
Асинхронные вызовы и получение результата
При включённом режиме использования модальности и асинхронных методах (например, НачатьВызовСервера, работа с файлами через НачатьПомещениеФайла) результат не возвращается напрямую в точку вызова. Вместо этого описывается оповещение — отдельная процедура, которую платформа вызовет после завершения операции и передаст результат параметром:
Оповещение = Новый ОписаниеОповещения("ПослеПомещенияФайла", ЭтотОбъект);
НачатьПомещениеФайла(Оповещение, , , Истина, УникальныйИдентификатор);
&НаКлиенте
Процедура ПослеПомещенияФайла(Результат, Адрес, ВыбранноеИмяФайла, ДопПараметры) Экспорт
Если Результат Тогда
// работа с адресом во временном хранилище
КонецЕсли;
КонецПроцедуры
Главная ошибка в асинхронном сценарии — попытка использовать результат сразу после строки вызова. Код после НачатьПомещениеФайла выполняется до завершения операции, поэтому вся логика обработки результата должна находиться внутри процедуры оповещения.
Типичные ошибки и их диагностика
Больше всего проблем доставляют не сами вызовы, а невнимательность к контракту функции. Если результат «теряется», проверяйте в первую очередь: есть ли Возврат во всех ветках, не перекрыто ли имя функции локальной переменной, тот ли модуль реально вызывается (при дублировании имён общих модулей платформа может обратиться не к тому).
Отладчик — основной инструмент диагностики: точка останова на строке Возврат и просмотр значения выражения покажут, что именно уходит наружу. Для серверных вызовов убедитесь, что в конфигураторе включена отладка на сервере, иначе точки в серверном коде не сработают.
FAQ
Что вернёт функция, если в ней нет оператора Возврат?
Функция вернёт значение Неопределено. Ошибки при сохранении модуля не будет, поэтому такой дефект обнаруживается только при выполнении. Проверяйте результат на Неопределено или гарантируйте возврат значения во всех ветках.
Чем функция отличается от процедуры в 1С?
Функция обязана вернуть значение через оператор Возврат, и её вызов можно использовать в выражениях и присваиваниях. Процедура ничего не возвращает — её вызов является отдельным оператором. Передать данные из процедуры можно только через параметры, переданные по ссылке.
Как вернуть из функции таблицу значений?
Таблица значений возвращается как обычное значение: создайте её через Новый ТаблицаЗначений, заполните и верните оператором Возврат. Учтите, что передача таблицы между клиентом и сервером в управляемой форме имеет ограничения — на клиенте таблица значений недоступна, используйте массив структур или данные формы.
Можно ли вызвать функцию, не сохраняя результат в переменную?
Да, вызов функции можно записать как отдельный оператор, и возвращаемое значение просто отбрасывается. Так делают, когда важен побочный эффект функции, например запись в регистр. Но если функция имеет побочные эффекты и при этом возвращает значение, стоит задуматься о разделении логики.
Почему отладчик не останавливается внутри функции в общем модуле?
Чаще всего модуль выполняется на сервере, а отладка серверного кода не включена. Проверьте настройки отладки в конфигураторе и флажок отладки в свойствах информационной базы. Также убедитесь, что точка останова стоит в том экземпляре модуля, который реально исполняется.
Как вернуть результат функции с сервера на клиент?
Объявите в модуле формы функцию с директивой &НаСервере или &НаСервереБезКонтекста и вызовите её из клиентской процедуры — возвращаемое значение придёт в точку вызова. Передавать можно только сериализуемые типы: примитивы, структуры, массивы; ссылки и таблицы значений напрямую не передаются.
Что важно запомнить
Результат функции в 1С возвращается оператором Возврат и принимается присваиванием при вызове. Для вызова извне нужна экспортная функция, для нескольких значений — структура, для асинхронных операций — оповещение. Всегда проверяйте результат на Неопределено и наличие Возврат во всех ветках.