Как реализовать обратный цикл с задаваемым шагом в 1С:Предприятие

Программист IT и автоматизация бизнеса
← На главную

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

Метод 1: Использование цикла «Для» с пересчетом индекса

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


ПервыйИндекс = 0;
ПоследнийИндекс = 9;
Для Номер = ПервыйИндекс По ПоследнийИндекс Цикл
    ТекущийИндексОбратногоХода = ПоследнийИндекс - Номер;
    // Теперь переменная ТекущийИндексОбратногоХода будет принимать значения от 9 до 0
    Сообщить(ТекущийИндексОбратногоХода);
КонецЦикла;

Этот способ считается наиболее безопасным с точки зрения производительности и читаемости, так как исключает риск «вечного цикла». Однако он не всегда удобен, если нам требуется специфический шаг (например, уменьшение на 2 или 3).

Метод 2: Реализация через цикл «Пока» с ручным управлением

Выясним, как реализовать более гибкий обход с произвольным шагом. Для этого идеально подходит конструкция Пока. Если вы пишете такой код в режиме предприятия, вам пригодится встраиваемая консоль кода на основе Monaco-editor (удобно через встраиваемая консоль кода на основе Monaco-editor). Рассмотрим по шагам, как настроить такой цикл:

  1. Инициализируем переменную счетчика начальным значением.
  2. Устанавливаем условие выхода (счетчик больше или равен конечному значению).
  3. Внутри тела цикла вручную уменьшаем значение счетчика на величину шага.

НачальноеЗначение = 10;
КонечноеЗначение = 0;
Шаг = 2;

ТекущийИндекс = НачальноеЗначение;
Пока ТекущийИндекс >= КонечноеЗначение Цикл
    // Выполнение полезной нагрузки
    Сообщить("Обратный индекс: " + ТекущийИндекс);
    
    // Ручное декрементирование с заданным шагом
    ТекущийИндекс = ТекущийИндекс - Шаг;
КонецЦикла;

Данный подход позволяет полностью имитировать поведение конструкции Step -N из других языков программирования. Важно помнить, что при использовании Пока программист сам несет ответственность за изменение условия, чтобы избежать зацикливания.

Метод 3: Оптимальное удаление строк из коллекции

Одной из самых частых причин поиска «обратного цикла» является задача удаления строк из ТаблицыЗначений или ТабличнойЧасти. При этом важно учитывать производительность способов обхода таблицы значений (поможет система анализа производительности кода и запросов 1С), так как при удалении в прямом цикле индексы смещаются, и итератор пропускает элементы. Проанализируем современный подход к решению этой проблемы.

Вариант А: Классический обратный обход


КоллекцияСтрок = Объект.Товары;
Для Индекс = -(КоллекцияСтрок.Количество() - 1) По 0 Цикл
    ТекСтр = КоллекцияСтрок[ -Индекс ];
    Если НеобходимоУдалить(ТекСтр) Тогда
        КоллекцияСтрок.Удалить(ТекСтр);
    КонецЕсли;
КонецЦикла;

Вариант Б: Использование массива для удаления (рекомендуемый)

Рассмотрим более эффективный метод, который стал стандартом в современной разработке. Вместо того чтобы мучиться с индексами, мы сначала собираем объекты в массив, а затем удаляем их:


МассивНаУдаление = Новый Массив;
Для Каждого СтрокаТЧ Из Объект.Товары Цикл
    Если УсловиеУдаления(СтрокаТЧ) Тогда
        МассивНаУдаление.Добавить(СтрокаТЧ);
    КонецЕсли;
КонецЦикла;

Для Каждого СтрокаДляУдаления Из МассивНаУдаление Цикл
    Объект.Товары.Удалить(СтрокаДляУдаления);
КонецЦикла;

Этот способ работает быстрее в больших коллекциях, так как платформа 1С оптимизирована для работы с массивами объектов.

Метод 4: Использование 1С:Исполнитель (новые возможности)

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

Например, обход в обратном порядке с шагом в 1С:Исполнитель выглядит так:


// Пример на языке 1С:Исполнитель
для i в (0..10).step(2).reversed() {
    // i примет значения 10, 8, 6, 4, 2, 0
    print(i)
}

Или использование метода downTo:


для i в 10.downTo(0).step(1) {
    print(i)
}

Хотя в классической платформе 8.3 этот синтаксис пока недоступен, понимание этих концепций помогает писать более чистый код уже сегодня, используя методы-заглушки или объекты-итераторы.

Сравнительный анализ подходов

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

Таким образом, несмотря на отсутствие прямого оператора Step в классическом BSL 1С, мы обладаем полным набором инструментов для эффективной реализации любой логики обхода данных.

← На главную