К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как из функции вернуть несколько значений в 1С

Как вернуть несколько значений из функции в 1С: структура, массив, параметры по ссылке и составной тип. Примеры кода, сравнение способов и типичные ошибки.

Во встроенном языке 1С функция формально возвращает одно значение через оператор Возврат. Однако на практике часто нужно получить из функции сразу несколько результатов: например, сумму документа, количество строк и признак успешного расчёта. Для этого существует несколько рабочих приёмов, и выбор между ними влияет на читаемость, производительность и удобство сопровождения кода.

Основные способы — вернуть структуру, массив, соответствие либо передать результат через параметры, объявленные с ключевым словом Знач отсутствующим (то есть по ссылке). У каждого подхода есть свои сценарии применения, ограничения и типичные ошибки, которые разбираются ниже.

Почему функция в 1С возвращает только одно значение

Оператор Возврат в функции принимает одно выражение. Вернуть «список значений через запятую», как в некоторых других языках, нельзя — синтаксис этого не позволяет. Однако это ограничение обходится тем, что возвращаемое значение может быть объектом-контейнером, внутри которого хранится сколько угодно полей.

Такими контейнерами выступают Структура, Массив, Соответствие и СписокЗначений. Дополнительный путь — вообще не использовать возвращаемое значение, а изменять параметры, переданные в функцию по ссылке. Оба подхода легальны, широко применяются в типовых конфигурациях и не считаются «костылём», если оформлены аккуратно.

Способ 1. Вернуть структуру — универсальное решение

Структура — самый читаемый способ вернуть несколько значений, потому что каждое поле имеет имя. Вызывающий код обращается к результату по понятным ключам, а не по индексам, которые легко перепутать.

Функция РассчитатьИтоги(ТаблицаТоваров) Экспорт

Результат = Новый Структура;

Результат.Вставить("Сумма", 0);

Результат.Вставить("КоличествоСтрок", 0);

Результат.Вставить("ЕстьОшибки", Ложь);

Для Каждого Строка Из ТаблицаТоваров Цикл

Результат.Сумма = Результат.Сумма + Строка.Сумма;

Результат.КоличествоСтрок = Результат.КоличествоСтрок + 1;

КонецЦикла;

Возврат Результат;

КонецФункции

Использование на стороне вызова выглядит так:

Итоги = РассчитатьИтоги(Товары);

Если НЕ Итоги.ЕстьОшибки Тогда

Сообщить("Итоговая сумма: " + Итоги.Сумма);

КонецЕсли;

Рекомендуется сразу инициализировать все поля структуры значениями по умолчанию. Тогда вызывающий код никогда не столкнётся с обращением к несуществующему ключу, даже если тело функции завершится досрочно через Возврат в середине логики.

Способ 2. Вернуть массив или соответствие

Массив подходит, когда возвращаемые значения однотипные и их порядок очевиден — например, границы периода: дата начала и дата окончания. Но полагаться на индексы рискованно: при изменении порядка заполнения массива весь вызывающий код придётся перепроверять.

Функция ПолучитьГраницыПериода(Период) Экспорт

Результат = Новый Массив;

Результат.Добавить(НачалоМесяца(Период));

Результат.Добавить(КонецМесяца(Период));

Возврат Результат;

КонецФункции

Соответствие удобно, когда набор возвращаемых ключей формируется динамически — например, функция возвращает ставки НДС по списку номенклатуры, где ключом служит ссылка на товар. Для фиксированного набора полей соответствие менее удобно, чем структура: ключи пишутся строками и не контролируются синтаксис-помощником.

Способ 3. Вернуть значения через параметры по ссылке

Если параметр функции объявлен без ключевого слова Знач, он передаётся по ссылке, и изменения внутри функции видны вызывающему коду. Это позволяет вернуть дополнительные данные, не упаковывая их в контейнер.

Функция ПровестиДокумент(ДокументСсылка, ТекстОшибки, КоличествоПроведённых) Экспорт

ТекстОшибки = "";

КоличествоПроведённых = 0;

// ... логика проведения ...

Возврат Истина; // основной результат — признак успеха

КонецФункции

Вызывающая сторона обязана заранее объявить переменные и передать их в функцию:

ТекстОшибки = "";

Проведено = 0;

Если ПровестиДокумент(Ссылка, ТекстОшибки, Проведено) Тогда

Сообщить("Проведено строк: " + Проведено);

Иначе

Сообщить("Ошибка: " + ТекстОшибки);

КонецЕсли;

Этот приём типичен для функций, где основной результат — булево «успех/ошибка», а дополнительные сведения (текст ошибки, детали) выносятся в параметры. Недостаток — сигнатура функции становится длиннее, а связь между параметрами и результатом не всегда очевидна при чтении.

Сравнение способов

Структура

Универсальный вариант: именованные поля, легко расширять. Подходит почти всегда. Небольшие накладные расходы на создание объекта.

Массив

Подходит для однотипных значений с очевидным порядком. Риск путаницы с индексами при доработках.

Соответствие

Подходит при динамическом наборе ключей. Менее читаемо при фиксированном наборе полей.

Параметры по ссылке

Удобно для пары «результат + текст ошибки». Удлиняет сигнатуру, хуже читается при большом числе выходных параметров.

Что выбрать в разных ситуациях

Выбор зависит от характера возвращаемых данных и того, как их будет потреблять вызывающий код. Ориентируйтесь на простые правила, проверенные практикой сопровождения типовых и самописных конфигураций.

Маршрут решения

Как выбрать способ

Нужно вернуть 2–5 разнотипных именованных значенийИспользуйте структуру с полями, инициализированными значениями по умолчанию
Возвращается однотипный набор (список ссылок, список сумм)Используйте массив или таблицу значений
Основной результат — признак успеха, плюс нужен текст ошибкиВерните булево, а текст ошибки передайте через параметр по ссылке
Набор ключей формируется динамически в циклеИспользуйте соответствие
Функция вызывается в цикле тысячи разИзбегайте лишних аллокаций: рассмотрите параметры по ссылке или переиспользование структуры

Отдельный случай — функции, вызываемые с клиента на сервере. Структуры, массивы и соответствия сериализуются при передаче между клиентом и сервером без проблем, поэтому все описанные способы работают и в клиент-серверном взаимодействии. А вот вернуть через параметры по ссылке значение с сервера на клиент не получится: изменения параметров при серверном вызове на клиенте не отражаются.

Проверка результата и типичные ошибки

После внедрения любого из способов проверьте, что вызывающий код корректно читает все поля результата, включая сценарии досрочного выхода из функции. Особое внимание уделите веткам с ошибками: именно там чаще всего забывают заполнить часть возвращаемых данных.

Типичные ошибки
01
Обращение к ключу структуры, который не был добавлен, — ошибка времени выполнения. Решение: инициализировать все поля при создании структуры.
02
Передача параметра с ключевым словом Знач и ожидание, что изменения вернутся вызывающему коду, — изменения теряются.
03
Ожидание возврата параметров по ссылке при вызове сервера с клиента — на клиенте переменные остаются прежними.
04
Возврат массива с «магическими» индексами без комментариев — при доработке порядок элементов путается.
05
Смешение подходов: часть результата в структуре, часть в параметрах по ссылке — код становится трудным для сопровождения.
Контрольные точки

Как проверить результат

Все поля структуры заполнены при любом пути выполнения
Норма

В вызывающем коде нет обращений к отсутствующим ключам

Тревожный признак

Ошибка «Поле объекта не обнаружено» в отдельных сценариях

Параметры по ссылке изменяются
Норма

После вызова переменные содержат новые значения

Тревожный признак

Переменные не изменились — проверьте, не указано ли Знач

Клиент-серверный вызов
Норма

Результат возвращается через Возврат структуры

Тревожный признак

Данные пытаются вернуть через параметры — на клиенте их нет

Производительность и оформление кода

Создание структуры — недорогая операция, и в обычном коде ею можно пренебречь. Но если функция вызывается внутри плотного цикла десятки тысяч раз, лишние аллокации объектов начинают влиять на время выполнения. В таких случаях либо выносите накопление результата за пределы функции, либо используйте параметры по ссылке с заранее созданными переменными.

По оформлению полезно документировать состав возвращаемой структуры в комментарии к функции — это стандарт в типовых конфигурациях: в описании указывают, какие ключи содержит результат и какого они типа. Такой комментарий избавляет коллег от необходимости читать всё тело функции.

Если функция возвращает структуру, не дополняйте её новыми полями «на всякий случай». Каждое лишнее поле — это обязательство поддерживать его заполнение во всех ветках логики. Добавляйте ключи только по факту потребности вызывающего кода.
ПЗ
Практическое замечание

FAQ: частые вопросы о возврате нескольких значений

Можно ли вернуть из функции таблицу значений вместе с другими данными?

Да. Таблицу значений можно положить в структуру как одно из полей, например Результат.Вставить("Таблица", ТЗ). При передаче между клиентом и сервером таблица значений сериализуется, но для больших таблиц лучше использовать массив структур — он передаётся быстрее и занимает меньше памяти.

Что вернёт функция, если забыть оператор Возврат?

Функция без явного возврата значения вернёт Неопределено. Если вызывающий код ожидает структуру и обратится к её полю, возникнет ошибка. Поэтому полезно проверять результат на Неопределено перед обращением к полям, если досрочный выход без значения допустим по логике.

Можно ли вернуть несколько значений из процедуры?

Да, но только через параметры по ссылке — оператор Возврат в процедуре не принимает значение. Если из процедуры нужно вернуть данные, часто разумнее преобразовать её в функцию, возвращающую структуру.

Что лучше для возврата ошибки: исключение или поле в структуре?

Если ошибка — штатная ситуация бизнес-логики (недостаток остатков, неверные данные), возвращайте её полем в структуре с признаком успеха. Исключения оставьте для нештатных сбоев: отсутствия связи, нарушения прав доступа, программных ошибок.

Работает ли возврат структуры во внешних соединениях (COM, веб-сервисы)?

Через COM-соединение структура передаётся корректно между базами 1С. Для веб-сервисов и HTTP-интерфейсов структуру нужно сериализовать, чаще всего в JSON, с помощью ЗаписьJSON, а на принимающей стороне прочитать обратно.

Итог

Что важно запомнить

Функция 1С возвращает одно значение, но оно может быть составным. Основной приём — вернуть структуру с именованными полями, инициализированными заранее. Для пары «успех + текст ошибки» удобны параметры по ссылке, но они не работают при вызове сервера с клиента. Массив и соответствие применяйте для однотипных или динамических наборов данных.