Когда вы пишете код в 1С:Предприятие, рано или поздно сталкиваетесь с понятием возвращаемого значения. Это фундаментальная концепция, без которой невозможно создать эффективные функции, процедуры или методы. Но что это такое на самом деле? Почему одни функции возвращают данные, а другие — нет? И как правильно работать с результатами выполнения кода?

В этой статье мы разберёмся, что такое возвращаемое значение в 1С 8.3 и 1С 7.7, какие типы данных могут быть результатом выполнения функции, как обрабатывать эти значения и какие ошибки чаще всего допускают разработчики. Вы узнаете, чем отличается Возврат от Выполнить, как возвращаемые значения используются в стандартных механизмах платформы (например, в запросах или обработках событий) и почему их правильное применение делает код чище и надёжнее.

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

1. Что такое возвращаемое значение в 1С: базовое определение

Возвращаемое значение — это результат работы функции, который передаётся в точку вызова после её выполнения. В отличие от процедур, которые просто выполняют действия (например, выводят сообщение или изменяют данные), функции обязательно возвращают какой-либо результат. Этот результат может быть любого типа: число, строка, булево значение, объект, массив и даже Неопределено.

В 1С:Предприятие для возврата значения используется оператор Возврат (или Return в английской версии платформы). Например:

Функция Сложить(Число1, Число2)

Возврат Число1 + Число2;

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

Здесь функция Сложить принимает два параметра, складывает их и возвращает результат. Если вызвать эту функцию в коде:

Результат = Сложить(5, 3);

то переменная Результат получит значение 8.

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

📊 Как часто вы используете функции с возвращаемыми значениями в 1С?
Постоянно, это основа моего кода
Иногда, когда нужно вернуть результат
Рядом, но предпочитаю процедуры
Что это?

2. Чем отличается функция от процедуры в контексте возвращаемых значений

В есть два типа подпрограмм: функции и процедуры. Их главное отличие как раз в возвращаемом значении:

  • 🔄 Функция — всегда возвращает результат с помощью оператора Возврат. Если в теле функции нет явного возврата, платформа вернёт Неопределено.
  • Процедура — не возвращает значения. Она выполняет действия (например, изменяет данные в базе, выводит сообщение), но не передаёт результат обратно.

Пример процедуры:

Процедура ПоказатьПриветствие(Имя)

Сообщить("Привет, " + Имя + "!");

КонецПроцедуры

Эта процедура ничего не возвращает — она просто выводит сообщение.

А теперь сравним с функцией:

Функция ПолучитьПриветствие(Имя)

Возврат "Привет, " + Имя + "!";

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

Здесь результат можно использовать дальше:

Текст = ПолучитьПриветствие("Иван");

Сообщить(Текст);

Почему это важно? Потому что функции делают код более гибким. Вы можете:

  • 🔄 Использовать результат функции в выражениях (Если Сложить(а, б) > 10 Тогда...)
  • 📊 Передавать результат другой функции (Логарифм(Сложить(х, у)))
  • 📋 Сохранять результат в переменную для дальнейшей обработки
💡

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

3. Типы данных, которые могут быть возвращаемыми значениями

В 1С:Предприятие функция может вернуть значение практически любого типа. Вот основные категории:

Тип данных Пример возвращаемого значения Когда используется
Число Возврат 42; Математические расчёты, количественные показатели
Строка Возврат "Ошибка!"; Сообщения, названия, текстовые данные
Булево Возврат Истина; или Возврат Ложь; Проверка условий (например, ПроверитьДокумент())
Дата Возврат ТекущаяДата(); Работа с временными метками
Объект Возврат Справочники.Номенклатура.НайтиПоНаименованию("Товар1"); Поиск и возвращение ссылок на объекты базы
Массив Возврат Новый Массив(1, 2, 3); Возврат нескольких значений или коллекций
Неопределено Возврат; (без значения) Если результат не определён или функция не нашла данных

Особенно полезно возвращать объекты (например, ссылки на справочники или документы), так как это позволяет дальнейшую работу с ними без повторного поиска. Например:

Функция НайтиКонтрагентаПоИНН(ИНН)

Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ Ссылка ИЗ Справочник.Контрагенты ГДЕ ИНН = &ИНН";

Запрос.УстановитьПараметр("ИНН", ИНН);

РезультатЗапроса = Запрос.Выполнить();

Если РезультатЗапроса.Пустой() Тогда

Возврат Неопределено;

Иначе

Возврат РезультатЗапроса[0].Ссылка;

КонецЕсли;

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

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

💡

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

4. Как правильно обрабатывать возвращаемые значения

Просто получить возвращаемое значение недостаточно — нужно уметь с ним работать. Вот ключевые правила:

  1. Проверяйте на Неопределено. Если функция может вернуть "пустое" значение, всегда проверяйте его перед использованием:
    Контрагент = НайтиКонтрагентаПоИНН("1234567890");
    

    Если Контрагент = Неопределено Тогда

    Сообщить("Контрагент не найден!");

    Иначе

    // Работаем с найденным контрагентом

    КонецЕсли;

  2. Используйте в выражениях. Возвращаемые значения можно сразу подставлять в условия или расчёты:
    Если СуммаДокумента() > 10000 Тогда
    

    ПрименитьСкидку();

    КонецЕсли;

  3. Сочетайте функции. Результат одной функции можно передавать как параметр другой:
    Итог = РассчитатьНДС(ПолучитьСуммуЗаказа(НомерЗаказа));

Ошибка многих новичков — игнорирование возвращаемого значения. Например, если функция возвращает булево значение (например, ПроверитьДокумент()), но результат не используется, это может привести к логическим ошибкам:

// Плохо: результат функции игнорируется

ПроверитьДокумент(Документ.Ссылка);

// Хорошо: результат используется

Если ПроверитьДокумент(Документ.Ссылка) Тогда

Сообщить("Документ корректен");

Иначе

Сообщить("Ошибка в документе!");

КонецЕсли;

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

// Возвращает массив строк с ошибками валидации документа.

// Если ошибок нет, возвращает пустой массив.

Функция ПроверитьДокумент(Документ)

// ... код проверки ...

Возврат МассивОшибок;

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

Что будет, если не обработать возвращаемое значение?

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

5. Типичные ошибки при работе с возвращаемыми значениями

Даже опытные разработчики иногда допускают ошибки при работе с возвращаемыми значениями. Вот самые распространённые:

  • 🚨 Забывают оператор Возврат. Если в функции нет явного возврата, она вернёт Неопределено, что может вызвать ошибки:
    Функция ПолучитьКурсВалюты()
    

    // Забыли Возврат!

    Курс = Справочники.Валюты.НайтиПоКоду("USD").Курс;

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

    Здесь функция всегда будет возвращать Неопределено, несмотря на расчёт курса.

  • 🔄 Возвращают не тот тип данных. Например, функция должна вернуть число, но возвращает строку:
    Функция ПолучитьКоличество()
    

    Возврат "10"; // Ошибка: строка вместо числа!

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

    Это приведёт к ошибке при попытке математических операций с результатом.

  • ⚠️ Игнорируют Неопределено. Если не проверить возвращаемое значение на Неопределено, может произойти ошибка при обращении к свойствам объекта:
    Контрагент = НайтиКонтрагента("Несуществующий");
    

    Имя = Контрагент.Наименование; // ОШИБКА! Контрагент = Неопределено

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

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

// Плохо: функция меняет документ и возвращает результат

Функция ОбновитьИВернутьСумму(Документ)

Документ.Сумма = 100; // Побочный эффект!

Возврат Документ.Сумма;

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

// Хорошо: разделить на процедуру и функцию

Процедура ОбновитьСуммуДокумента(Документ, НоваяСумма)

Документ.Сумма = НоваяСумма;

КонецПроцедуры

Функция ПолучитьСуммуДокумента(Документ)

Возврат Документ.Сумма;

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

✅ Убедиться, что функция возвращает ожидаемый тип данных

✅ Проверить возвращаемое значение на Неопределено

✅ Удостовериться, что функция не имеет побочных эффектов

✅ Документировать формат возвращаемого значения-->

6. Возвращаемые значения в стандартных механизмах 1С

Возвращаемые значения активно используются в стандартных объектах и методах 1С:Предприятие. Вот несколько примеров:

  • 📊 Запросы. Метод Выполнить() возвращает объект РезультатЗапроса, с которым можно дальше работать:
    Запрос = Новый Запрос("ВЫБРАТЬ Первые 10 ИЗ Справочник.Номенклатура");
    

    Результат = Запрос.Выполнить(); // Возвращает РезультатЗапроса

  • 🔍 Поиск объектов. Методы вроде НайтиПоНаименованию() или НайтиПоКоду() возвращают ссылки на объекты или Неопределено:
    Товар = Справочники.Номенклатура.НайтиПоНаименованию("Молоко");
    

    Если Товар = Неопределено Тогда

    Сообщить("Товар не найден!");

    КонецЕсли;

  • 📝 Обработки событий. Некоторые обработчики (например, ПередЗаписью) могут возвращать Ложь, чтобы отменить действие:
    Процедура ПередЗаписью(Отказ)
    

    Если Не ПроверитьДокумент(ЭтотОбъект) Тогда

    Отказ = Истина; // Отменяем запись

    КонецЕсли;

    КонецПроцедуры

Особенно важно понимать возвращаемые значения при работе с запросами. Например, если запрос не нашёл данных, результат будет пустым, но не Неопределено:

Запрос = Новый Запрос("ВЫБРАТЬ Ссылка ИЗ Документ.ЗаказПокупателя ГДЕ Номер = '00000'");

Результат = Запрос.Выполнить();

Если Результат.Пустой() Тогда

Сообщить("Заказов не найдено!");

Иначе

Заказ = Результат[0].Ссылка;

КонецЕсли;

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

💡

В стандартных методах 1С возвращаемые значения часто имеют специфические типы (например, РезультатЗапроса). Всегда изучайте документацию, чтобы правильно их обрабатывать.

7. Практические примеры использования возвращаемых значений

Давайте рассмотрим несколько реальных примеров, где возвращаемые значения делают код чище и эффективнее.

Пример 1: Валидация данных

Функция проверяет корректность email и возвращает булево значение:

Функция ПроверитьEmail(Адрес)

Если НЕ СтрНачинаетсяС(Адрес, "@") И НРег(Адрес) <> НРег(Адрес) Тогда

Возврат Ложь;

Иначе

Возврат Истина;

КонецЕсли;

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

// Использование:

Если ПроверитьEmail("test@example.com") Тогда

Сообщить("Email корректен");

Иначе

Сообщить("Ошибка в email!");

КонецЕсли;

Пример 2: Расчёт скидки

Функция возвращает размер скидки в зависимости от суммы заказа:

Функция РассчитатьСкидку(СуммаЗаказа)

Если СуммаЗаказа > 10000 Тогда

Возврат 0.1; // 10%

ИначеЕсли СуммаЗаказа > 5000 Тогда

Возврат 0.05; // 5%

Иначе

Возврат 0; // Без скидки

КонецЕсли;

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

// Использование:

Скидка = РассчитатьСкидку(12000);

ИтоговаяСумма = 12000 * (1 - Скидка);

Пример 3: Поиск дублей в справочнике

Функция ищет дублирующиеся элементы и возвращает массив найденных ссылок:

Функция НайтиДублиНоменклатуры()

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Номенклатура.Ссылка КАК Ссылка

|ИЗ

| Справочник.Номенклатура КАК Номенклатура

|ГРУППИРОВАТЬ ПО

| Номенклатура.Наименование

|ИМЕЮЩИЕ

| КОЛИЧЕСТВО() > 1";

Результат = Запрос.Выполнить();

Возврат Результат.Выгрузить().ВыгрузитьКолонку("Ссылка");

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

// Использование:

Дубли = НайтиДублиНоменклатуры();

Для Каждого Элемент Из Дубли Цикл

Сообщить("Найден дубль: " + Элемент.Наименование);

КонецЦикла;

Эти примеры показывают, как возвращаемые значения помогают:

  • 🔄 Делать код модульным (каждая функция решает одну задачу)
  • 📊 Упрощать логику (результат одной функции используется в другой)
  • 🛠 Уменьшать повторяемость кода (одну и ту же функцию можно вызвать в разных местах)

8. Оптимизация кода с помощью возвращаемых значений

Правильное использование возвращаемых значений может значительно улучшить производительность и читаемость кода. Вот несколько советов:

  1. Избегайте вложенных вызовов. Если функция возвращает объект, не вызывайте сразу его методы в цепочке:
    // Плохо: если НайтиДокумент вернёт Неопределено, будет ошибка
    

    Сумма = НайтиДокумент(123).Сумма;

    // Хорошо: сначала проверяем результат

    Док = НайтиДокумент(123);

    Если Док <> Неопределено Тогда

    Сумма = Док.Сумма;

    КонецЕсли;

  2. Используйте структуры для сложных данных. Если функции нужно вернуть несколько значений, лучше использовать Структура:
    Функция ПолучитьДанныеКонтрагента(Контрагент)
    

    Данные = Новый Структура;

    Данные.Вставить("ИНН", Контрагент.ИНН);

    Данные.Вставить("Адрес", Контрагент.Адрес);

    Данные.Вставить("Баланс", ПолучитьБаланс(Контрагент));

    Возврат Данные;

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

  3. Кэшируйте результаты. Если функция выполняет тяжёлые вычисления, можно кэшировать её результат:
    Перем КэшКурсовВалют;
    
    

    Функция ПолучитьКурсВалюты(Валюта)

    Если КэшКурсовВалют = Неопределено Тогда

    КэшКурсовВалют = Новый Соответствие;

    КонецЕсли;

    Если НЕ КэшКурсовВалют.Содержит(Валюта) Тогда

    Курс = Справочники.Валюты.НайтиПоКоду(Валюта).Курс;

    КэшКурсовВалют.Вставить(Валюта, Курс);

    КонецЕсли;

    Возврат КэшКурсовВалют[Валюта];

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

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

Для Каждого Товар Из СписокТоваров Цикл

Цена = ПолучитьЦенуТовара(Товар);

Если Цена = Неопределено Тогда

Прервать; // или Продолжить

КонецЕсли;

// Обработка цены

КонецЦикла;

И наконец, помните о рекурсии. Функции могут вызывать сами себя, возвращая промежуточные результаты. Например, рекурсивный поиск в дереве справочника:

Функция НайтиВПодчиненных(Родитель, ИскомоеНаименование)

Если Родитель.Наименование = ИскомоеНаименование Тогда

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

Иначе

Для Каждого Подчиненный Из Родитель.Подчиненные Цикл

Результат = НайтиВПодчиненных(Подчиненный, ИскомоеНаименование);

Если Результат <> Неопределено Тогда

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

КонецЕсли;

КонецЦикла;

КонецЕсли;

Возврат Неопределено;

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

💡

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

FAQ: Частые вопросы о возвращаемых значениях в 1С

Может ли функция в 1С возвращать несколько значений?

Прямо — нет, но можно вернуть Структуру, Массив или Соответствие, которые содержат несколько значений. Например:

Функция ПолучитьДанные()

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

Результат.Вставить("Имя", "Иван");

Результат.Вставить("Возраст", 30);

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

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

Затем можно обращаться к полям структуры: Данные = ПолучитьДанные(); Имя = Данные.Имя;

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

Функция вернёт Неопределено. Это не вызовет ошибку, но может привести к логическим проблемам, если код ожидает конкретное значение. Всегда проверяйте такие случаи.

Как вернуть ошибку из функции?

Есть несколько подходов:

  1. Вернуть Неопределено или специальное значение (например, -1 для чисел).
  2. Вернуть структуру с полем Успех и Ошибка:
    Функция ВыполнитьОперацию()
    

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

    Попытка

    // Код операции

    Результат.Вставить("Успех", Истина);

    Исключение

    Результат.Вставить("Успех", Ложь);

    Результат.Вставить("Ошибка", ОписаниеОшибки());

    КонецПопытки;

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

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

  3. Выбросить исключение с помощью ВызватьИсключение.
Можно ли возвращать объекты (например, документы) из функции?

Да, это один из самых распространённых сценариев. Например, функция может возвращать ссылку на документ:

Функция СоздатьЗаказ(Контрагент)

Заказ = Документы.ЗаказПокупателя.СоздатьДокумент();

Заказ.Контрагент = Контрагент;

Заказ.Записать();

Возврат Заказ.Ссылка;

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

Но помните: если объект будет изменён после возврата, это повлияет на оригинальные данные в базе.

Как возвращаемые значения работают в асинхронных операциях (например, с Подождать)?

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

Функция ДолгаяОперация()

Подождать 5000; // Имитация долгой работы

Возврат "Готово!";

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

// Вызов (заблокируется на 5 секунд)

Результат = ДолгаяОперация();

Сообщить(Результат);

Для настоящей асинхронности в 1С используют механизмы вроде Планировщик или Фоновые задания, но они не возвращают значения напрямую.