В практике программирования на платформе 1С:Предприятие часто встречается конструкция Пока Истина Цикл. Для начинающих разработчиков она может выглядеть странно или даже пугающе: кажется, что программа рискует «зависнуть» навсегда. Однако опытные специалисты и даже разработчики типовых решений от фирмы «1С» регулярно используют этот прием. Разберем подробно, для чего нужна эта конструкция, какие задачи она решает и как не превратить её в «говнокод».
Конструкция Пока Истина Цикл — это создание бесконечного цикла, который не имеет условия завершения в самом заголовке. Выход из такого цикла осуществляется принудительно изнутри его тела с помощью команд Прервать, Возврат или (реже) путем генерации исключения. Рассмотрим, почему это иногда удобнее классического цикла Пока [Условие] Цикл.
Основное назначение такой конструкции — имитация цикла с постусловием. Во многих языках программирования (например, Pascal) существует оператор Repeat...Until, который гарантирует, что тело цикла выполнится хотя бы один раз, а проверка условия произойдет в самом конце. В языке 1С встроенного цикла с постусловием нет, поэтому программисты используют «вечный» цикл с проверкой внутри.
Представим ситуацию, когда решение о выходе из цикла зависит от десяти различных условий, которые вычисляются в процессе выполнения кода. Если мы попытаемся вынести их все в заголовок цикла, код станет нечитаемым. Проанализируем пример из обсуждения на форуме:
// Сложный вариант с флагами в заголовке
НужноПродолжать = Истина;
Пока НужноПродолжать Цикл
// ... какие-то действия ...
Если Условие1 Тогда
НужноПродолжать = Ложь;
ИначеЕсли Условие2 И НЕ Условие3 Тогда
НужноПродолжать = Ложь;
КонецЕсли;
Если НужноПродолжать Тогда
// ... еще действия ...
КонецЕсли;
КонецЦикла;
А теперь посмотрим, как тот же алгоритм выглядит с использованием Пока Истина. Рассмотрим, насколько чище становится код:
Пока Истина Цикл
// ... какие-то действия ...
Если Условие1 Тогда
Прервать;
КонецЕсли;
Если Условие2 И НЕ Условие3 Тогда
Прервать;
КонецЕсли;
// Выполняем полезную работу, если не выскочили раньше
ТабДокумент.Вывести(ОбластьМакета);
КонецЦикла;
Важный момент: такая структура позволяет избежать лишних вложенных условий Если...Тогда и флагов, которые только запутывают логику. Мы просто «выскакиваем» из процесса, как только понимаем, что продолжать нет смысла.
Выясним, в каких реальных задачах 1С без этой конструкции обойтись сложно. Рассмотрим несколько сценариев.
1. Обход иерархических структур (DOM в HTML)
При парсинге веб-страниц нам часто нужно подниматься вверх по дереву элементов до тех пор, пока мы не найдем тег BODY или нужный нам контейнер. Выясним, как это реализовано в типовых функциях:
Функция НайтиРодителяПоТегу(Элемент_HTML, НазваниеТега)
ТекущийЭлемент = Элемент_HTML;
Пока Истина Цикл
Если ТекущийЭлемент.tagName = "BODY" Тогда
Возврат Неопределено; // Дошли до корня, ничего не нашли
ИначеЕсли ТекущийЭлемент.tagName = НазваниеТега Тогда
Возврат ТекущийЭлемент; // Нашли нужный тег
КонецЕсли;
ТекущийЭлемент = ТекущийЭлемент.parentNode;
КонецЦикла;
КонецФункции
2. Чтение файлов с неопределенным концом (Excel, Текстовые файлы)
Допустим, мы читаем данные из Excel и должны остановиться, если встретим пять пустых строк подряд или слово «Итого». Заранее количество строк нам неизвестно. Проанализируем логику:
СчетчикПустых = 0;
НомерСтроки = 1;
Пока Истина Цикл
Значение = Лист.Cells(НомерСтроки, 1).Value;
Если Значение = "Итого" Тогда
Прервать;
КонецЕсли;
Если ПустаяСтрока(Значение) Тогда
СчетчикПустых = СчетчикПустых + 1;
Иначе
СчетчикПустых = 0;
КонецЕсли;
Если СчетчикПустых >= 5 Тогда
Прервать;
КонецЕсли;
// Обработка данных строки...
НомерСтроки = НомерСтроки + 1;
КонецЦикла;
Некоторые программисты опасаются, что постоянная проверка Истина в заголовке замедляет систему. Разберем этот миф с точки зрения работы интерпретатора 1С. Как было отмечено экспертами, на уровне байт-кода конструкция Пока Истина Цикл генерирует минимальный набор инструкций:
PushTrue (положить Истину в стек)JZ (переход, если ложь — но здесь всегда истина, поэтому перехода не будет)Это практически «бесплатная» операция для процессора. Намного важнее то, что происходит внутри цикла. Если внутри нет «тормозящих» факторов, таких как запросы в цикле или ожидание внешних событий, цикл будет работать максимально быстро.
Главный риск использования Пока Истина Цикл — это возможность создания действительно бесконечного цикла, который «подвесит» рабочий процесс сервера или сеанс пользователя. Чтобы этого избежать, придерживайтесь следующих правил:
Прервать не сработает. Например, при чтении данных всегда добавляйте ограничение по максимальному количеству итераций (например, 1 000 000), если не уверены в источнике данных.Приостановить() или Ждать(). Без паузы одно ядро процессора будет загружено на 100%, что снизит общую производительность сервера.Конструкция Пока Истина Цикл — это мощный инструмент в руках разработчика 1С, когда нужно реализовать цикл с постусловием или обработать множество условий выхода без загромождения кода. Она активно используется в типовых конфигурациях (УТ 11, ERP 2) и не является признаком плохого тона, если применяется осознанно. Главное — обеспечивать читаемость кода и гарантировать наличие выхода из цикла при любых обстоятельствах.