Разработка и Конфигурация · 9 мин
1С: как прервать выполнение кода по условию
Как в 1С прервать цикл или выполнение процедуры: операторы Прервать, Продолжить, Возврат. Примеры кода, типичные ошибки, прерывание по условию Если.
Во встроенном языке 1С нет отдельной конструкции «прервать если», но задача решается комбинацией условного оператора Если и операторов управления выполнением: Прервать, Продолжить и Возврат. Выбор зависит от того, что именно нужно остановить: текущую итерацию цикла, цикл целиком или всю процедуру.
Чаще всего вопрос возникает у начинающих разработчиков, когда внутри цикла Для или Для Каждого по определенному условию нужно выйти досрочно — например, при поиске элемента в таблице значений или при обнаружении ошибки в данных. Ниже разобраны все три оператора, их отличия, типовые сценарии и ошибки, которые приводят к бесконечным циклам и зависанию сеанса.
Какие операторы прерывания есть в языке 1С
Встроенный язык 1С предоставляет три оператора досрочного завершения выполнения. Каждый действует на свой уровень вложенности, и перепутать их — частая причина логических ошибок.
- Прервать — немедленно завершает ближайший вложенный цикл (Для, Для Каждого, Пока). Управление переходит к оператору, следующему за
КонецЦикла. - Продолжить — завершает текущую итерацию цикла и переходит к следующей, не выходя из цикла.
- Возврат — завершает выполнение всей процедуры или функции, в которой находится, независимо от глубины вложенности циклов и условий.
Все три оператора обычно размещаются внутри условия Если ... Тогда ... КонецЕсли;, потому что безусловный Прервать в начале цикла делает цикл бессмысленным. Именно эта связка и отвечает на вопрос «как прервать если».
Как прервать цикл по условию
Типовая задача — перебрать коллекцию и остановиться, когда нужный элемент найден. Без прерывания цикл продолжал бы бесполезный перебор оставшихся элементов, что на больших таблицах заметно замедляет код.
НайденныйЭлемент = Неопределено;
Для Каждого Строка Из ТаблицаТоваров Цикл
Если Строка.Артикул = ИскомыйАртикул Тогда
НайденныйЭлемент = Строка;
Прервать;
КонецЕсли;
КонецЦикла;
Как только условие внутри Если выполнилось, оператор Прервать завершает цикл, и выполнение продолжается со строки после КонецЦикла. Важно, что прерывается только тот цикл, внутри которого стоит оператор.
Прерывание вложенных циклов
При вложенных циклах Прервать выходит только из внутреннего. Если нужно остановить оба уровня, используют флаг-признак:
НужноОстановить = Ложь;
Для Каждого Группа Из Группы Цикл
Для Каждого Элемент Из Группа.Элементы Цикл
Если Элемент.Ошибка Тогда
НужноОстановить = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если НужноОстановить Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Альтернатива — вынести обход в отдельную функцию и использовать Возврат, который выходит сразу из всех уровней вложенности.
Если Строка.Сумма < 0 Тогда
Прервать; // выход из цикла
КонецЕсли;Как пропустить итерацию: оператор Продолжить
Если цикл останавливать не нужно, а требуется лишь пропустить «плохие» элементы, применяется Продолжить. Это аналог continue в других языках.
Для Каждого Строка Из ТаблицаДокументов Цикл
Если Не Строка.Проведен Тогда
Продолжить; // непроведенные пропускаем
КонецЕсли;
// обработка только проведенных документов
ОбщаяСумма = ОбщаяСумма + Строка.Сумма;
КонецЦикла;
Такой прием делает код плоским и читаемым: вместо глубокой вложенности Если Проведен Тогда ... большой блок ... КонецЕсли условие-фильтр выносится в начало итерации.
Прервать, Продолжить или Возврат
Найден нужный элемент или обнаружена критическая ошибка данных — дальнейший перебор бессмысленен. Выходит только из текущего цикла.
Текущий элемент не подходит под условие обработки, но остальные нужно проверить. Цикл продолжается.
Ошибка делает бессмысленным выполнение всей процедуры, либо результат уже получен. Выходит из всей процедуры или функции.
Как прервать выполнение процедуры или функции
Оператор Возврат завершает текущую процедуру или функцию. В функции он обычно возвращает значение: Возврат Результат;. В процедуре — просто Возврат;.
Функция НайтиКонтрагентаПоИНН(ИНН)
Если ПустаяСтрока(ИНН) Тогда
Возврат Неопределено; // досрочный выход при некорректном параметре
КонецЕсли;
// дальше — запрос к базе и основная логика
...
КонецФункции
Досрочный Возврат в начале функции — рекомендуемый прием проверки входных параметров. Он избавляет от вложенных условий и сразу показывает, при каких условиях функция не выполняется.
Помните: Возврат внутри цикла завершает не цикл, а всю процедуру. Если цель — только выйти из цикла, нужен именно Прервать.
Как прервать цикл Пока и избежать бесконечного выполнения
Цикл Пока выполняется, пока истинно его условие. Если условие никогда не станет ложным, сеанс зависнет. Поэтому внутри таких циклов почти всегда нужна «страховка» через Прервать:
Счетчик = 0;
Пока Истина Цикл
Запись = ПолучитьСледующуюЗапись();
Если Запись = Неопределено Тогда
Прервать; // данных больше нет
КонецЕсли;
Счетчик = Счетчик + 1;
Если Счетчик > 100000 Тогда
Прервать; // защита от бесконечного цикла
КонецЕсли;
КонецЦикла;
Особенно опасны циклы, в которых условие зависит от данных, изменяемых внутри тела цикла: если изменение по какой-то причине не происходит (например, запрос вернул пустую выборку), выполнение никогда не завершится.
Как прервать длительную операцию на форме
Операторы языка прерывают только программный код. Если пользователю нужно остановить длительную фоновую операцию, применяются другие механизмы:
- для фоновых заданий — метод
Отменить()объекта фонового задания или отмена через консоль заданий; - для длительных операций на БСП — механизм длительных операций с проверкой отмены внутри обработчика;
- для интерактивного прерывания пользователем — обработка ожидания с проверкой флага отмены между порциями обработки данных.
Обработку больших объемов данных разумно выполнять порциями (например, по 1000 записей) с проверкой признака отмены между порциями. Тогда прерывание происходит быстро и без отката всей транзакции.
Типичные ошибки при прерывании по условию
Отдельная группа ошибок связана с транзакциями: если цикл выполняется внутри транзакции и прерывается по ошибке, нужно явно решить — откатывать транзакцию (ОтменитьТранзакцию) или фиксировать частично обработанные данные. Просто выйти из цикла, оставив транзакцию открытой, нельзя.
Как проверить, что прерывание работает правильно
После внедрения логики прерывания проверьте поведение на граничных случаях: пустая коллекция, условие срабатывает на первом элементе, условие срабатывает на последнем, условие не срабатывает ни разу. Удобно использовать отладчик: поставьте точку останова на строке с Прервать и убедитесь, что управление действительно попадает туда в ожидаемых сценариях.
Как проверить результат
Цикл завершается сразу, элементы не перебираются
Перебор продолжается после найденного элемента
Цикл отрабатывает до конца и завершается штатно
Сеанс зависает или цикл бесконечный
Выполняется и после Прервать, и после обычного завершения
Пропускается из-за ошибочного Возврат вместо Прервать
Что важно запомнить
Прерывание по условию в 1С — это связка Если + Прервать (выход из цикла), Продолжить (пропуск итерации) или Возврат (выход из процедуры). Прервать действует только на ближайший цикл; для вложенных циклов нужен флаг или Возврат. В циклах Пока всегда добавляйте счетчик-предохранитель.
Частые вопросы
Есть ли в 1С аналог break и continue?
Да. Аналог break — оператор Прервать, аналог continue — оператор Продолжить. Оба работают в циклах Для, Для Каждого и Пока.
Как выйти сразу из двух вложенных циклов?
Либо установите флаг во внутреннем цикле и проверьте его во внешнем с повторным Прервать, либо вынесите обход в отдельную функцию и используйте Возврат — он завершает функцию со всеми циклами сразу.
Можно ли прервать выполнение запроса?
Нет, операторы языка на запрос не действуют. Длительный запрос можно отменить только средствами СУБД или прервав сеанс/фоновое задание, в котором он выполняется.
Чем отличается Возврат в процедуре и в функции?
В процедуре Возврат просто завершает выполнение. В функции после Возврат указывается возвращаемое значение; если его не указать, функция вернет Неопределено.
Почему после Прервать код за циклом не выполняется?
Скорее всего, вместо Прервать использован Возврат, который завершает всю процедуру. Проверьте оператор внутри условия и замените его на Прервать, если нужно выйти только из цикла.
Как прервать обработку, запущенную пользователем, без зависания формы?
Выполняйте обработку порциями через обработчик ожидания или в фоновом задании, а между порциями проверяйте флаг отмены, который устанавливает пользователь кнопкой на форме.