{}const=>[]async()letfn</>var
1CDevelopment

Cycles in 1C: how to process lists, tabular parts and selections

We analyze all types of cycles in 1C — "For", "For Each" and "While". We learn to process tabular parts, query selections, structures and matches. We show typical errors when deleting rows and methods of optimizing performance.

К

Kodik

Author

7 min read

Working with data in 1C is, in fact, constant work with collections. Directories, documents, registers — all these are data arrays that need to be sorted, filtered and converted. Without understanding the cycles, you will not write any serious processing. In this article, we will analyze all types of loops in 1C, show real examples, and talk about the pitfalls that the documentation is silent about.

Three whales: types of cycles in 1C

In the 1C: Enterprise platform, there are three designs for organizing cycles. Each is tailored to its own scenario.

The "For" loop — when we know the number of iterations

Classic counting loop. Used when you know in advance how many times you need to perform an action.

Для Счетчик = 1 По 10 Цикл
    Сообщить("Iteration No." + Счетчик);
КонецЦикла;

An important nuance: the counter variable is automatically increased by 1 after each iteration. In 1C, you cannot set an arbitrary step, as in some other languages. If you need a step other than one, you have to cheat:

Для Индекс = 0 По 9 Цикл
    РеальныйШаг = Индекс * 3;
    Сообщить("Value: " + РеальныйШаг);
КонецЦикла;

A typical scenario is to traverse the array by index:

МассивТоваров = Новый Массив;
МассивТоваров.Добавить("Laptop");
МассивТоваров.Добавить("Monitor");
МассивТоваров.Добавить("Keyboard");

Для Инд = 0 По МассивТоваров.ВГраница() Цикл
    Сообщить(МассивТоваров[Инд]);
КонецЦикла;

The "For Everyone" cycle - a universal soldier

The most popular cycle in 1C. It works with any collection: arrays, lists of values, table parts, query results, structures and matches.

Для Каждого Элемент Из МассивТоваров Цикл
    Сообщить(Элемент);
КонецЦикла;

The main advantage is that you don't need to think about indexes, boundaries, and the number of elements. You just work with each element of the collection.

The "Until" cycle — when the exit condition is unknown in advance

Executed as long as the condition is true. Ideal for situations where the number of iterations is unknown in advance.

Остаток = 1000;
Месяц = 0;

Пока Остаток > 0 Цикл
    Остаток = Остаток - 150;
    Месяц = Месяц + 1;
КонецЦикла;

Сообщить("Funds will run out in " + Месяц + " months");

Be careful: if the condition never becomes false, you will get an infinite loop and the platform will hang. Always provide an emergency exit:

Счетчик = 0;
Пока НеВыполненоУсловие И Счетчик < 10000 Цикл
    // processing logic
    Счетчик = Счетчик + 1;
КонецЦикла;
🔥 100,000+ students already with us

Tired of reading theory?
Time to code!

Kodik — an app where you learn to code through practice. AI mentor, interactive lessons, real projects.

🤖 AI 24/7
🎓 Certificates
💰 Free
🚀 Start learning
Joined today

Processing of tabular parts of documents

Tabular parts are one of the most common data structures that a 1C developer works with. Let's analyze a few practical tasks.

Calculation of the amount in the table part

ИтогоСумма = 0;

Для Каждого СтрокаТЧ Из Документ.Товары Цикл
    ИтогоСумма = ИтогоСумма + СтрокаТЧ.Количество * СтрокаТЧ.Цена;
КонецЦикла;

Сообщить("Total amount: " + ИтогоСумма);

Deleting rows from the tabular part

This is where the fun begins. The classic beginner's mistake is to delete lines in a forward loop:

// ❌ DON'T DO THIS — skip the lines!
Для Каждого СтрокаТЧ Из Документ.Товары Цикл
    Если СтрокаТЧ.Количество = 0 Тогда
        Документ.Товары.Удалить(СтрокаТЧ);
    КонецЕсли;
КонецЦикла;

When a row is deleted, the collection shifts, and the next element "slips" past. The correct approach is to go around the tabular part in reverse order. But the standard "For" loop in 1C does not support a countdown, so we use "While":

// ✅ Correct backtracking
Инд = Документ.Товары.Количество() - 1;

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

Duplicate search in the table part

The task that is constantly encountered: to find and combine identical products.

Инд = 0;
Пока Инд < Документ.Товары.Количество() Цикл
    ТекСтрока = Документ.Товары[Инд];
    
    Инд2 = Инд + 1;
    Пока Инд2 < Документ.Товары.Количество() Цикл
        СравнСтрока = Документ.Товары[Инд2];
        
        Если ТекСтрока.Номенклатура = СравнСтрока.Номенклатура Тогда
            ТекСтрока.Количество = ТекСтрока.Количество + СравнСтрока.Количество;
            Документ.Товары.Удалить(Инд2);
        Иначе
            Инд2 = Инд2 + 1;
        КонецЕсли;
    КонецЦикла;
    
    Инд = Инд + 1;
КонецЦикла;

Please note: when deleting a duplicate, we do not increase Ind2, because the next element will move to its place.

Working with samples from requests

The result of a query in 1C is not an array, but a special object that is handled in a special way.

Basic sampling

Запрос = Новый Запрос;
Запрос.Текст = 
    "SELECT
    |    Nomenclature.Name AS Name,
    |    Nomenclature.Price AS Price
    | FROM | Reference Book.Nomenclature AS Nomenclature
    |WHERE
    |    Nomenclature.Price > 0";

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

Пока Выборка.Следующий() Цикл
    Сообщить(Выборка.Наименование + ": " + Выборка.Цена + " RUB");
КонецЦикла;

The Следующий() method moves the pointer to the next record and returns Истина if the record exists. When the records end, Ложь is returned and the loop ends.

Hierarchical sampling bypass

For directories with a hierarchy, it is convenient to use a selection with groupings:

Результат = Запрос.Выполнить();
ВыборкаГруппы = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);

Пока ВыборкаГруппы.Следующий() Цикл
    Сообщить("== Group: " + ВыборкаГруппы.Категория + " ==");
    
    ВыборкаДетали = ВыборкаГруппы.Выбрать();
    Пока ВыборкаДетали.Следующий() Цикл
        Сообщить("   " + ВыборкаДетали.Наименование);
    КонецЦикла;
КонецЦикла;

Batch requests with multiple results

When a query returns multiple tables, we process each one:

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

Для Каждого РезультатЗапроса Из МассивРезультатов Цикл
    Выборка = РезультатЗапроса.Выбрать();
    Пока Выборка.Следующий() Цикл
        // line processing
    КонецЦикла;
КонецЦикла;

Bypassing structures and matches

Structures and matches are key-value pairs. They are bypassed through Для Каждого:

Параметры = Новый Структура;
Параметры.Вставить("Organization", "Romashka LLC");
Параметры.Вставить("Period", ТекущаяДата());
Параметры.Вставить("Warehouse", "Primary");

Для Каждого КлючЗначение Из Параметры Цикл
    Сообщить(КлючЗначение.Ключ + " = " + КлючЗначение.Значение);
КонецЦикла;

For matches, the syntax is similar, but the match allows keys of any type — not just strings.

Cycle Management: Abort and Continue

Two operators allow you to flexibly control the progress of the cycle.

Прервать — immediately exits the loop:

Для Каждого Товар Из Каталог Цикл
    Если Товар.Наименование = "Searched product" Тогда
        НайденныйТовар = Товар;
        Прервать;
    КонецЕсли;
КонецЦикла;

Продолжить — skips the remaining iteration code and proceeds to the next one:

Для Каждого Контрагент Из СписокКонтрагентов Цикл
    Если Контрагент.ЭтоГруппа Тогда
        Продолжить; // groups are skipped
    КонецЕсли;
    
    // processing of elements only
    ОбработатьКонтрагента(Контрагент);
КонецЦикла;

Practical performance tips

There are several rules that will help you write fast and reliable loops in 1C.

Do not access the database inside the loop. Each call to the database is a network request. If you have 10,000 rows, you will make 10,000 calls to the server. Instead, get all the data you need in one query before the loop:

// ❌ Slow: request inside the loop
Для Каждого СтрокаТЧ Из Документ.Товары Цикл
    Остаток = РегистрыНакопления.ОстаткиТоваров
        .ПолучитьПоследнийСрез(, "Nomenclature = &Nom");
КонецЦикла;

// ✅ Fast: one request, then a cycle
Запрос = Новый Запрос;
Запрос.Текст = "SELECT Nomenclature, Remainder FROM ...";
ТаблицаОстатков = Запрос.Выполнить().Выгрузить();

Для Каждого СтрокаТЧ Из Документ.Товары Цикл
    НайденнаяСтрока = ТаблицаОстатков.Найти(
        СтрокаТЧ.Номенклатура, "Nomenclature");
    Если НайденнаяСтрока <> Неопределено Тогда
        Остаток = НайденнаяСтрока.Остаток;
    КонецЕсли;
КонецЦикла;

Use TableValues.FindRows() instead of nested loops. Instead of iterating through a nested loop, use built-in search methods — they work much faster:

// ❌ Nested loop O(n²)
Для Каждого Строка1 Из Таблица1 Цикл
    Для Каждого Строка2 Из Таблица2 Цикл
        Если Строка1.Ключ = Строка2.Ключ Тогда
            // ...
        КонецЕсли;
    КонецЦикла;
КонецЦикла;

// ✅ Search via FindStrings O(n)
Для Каждого Строка1 Из Таблица1 Цикл
    Отбор = Новый Структура("Key", Строка1.Ключ);
    НайденныеСтроки = Таблица2.НайтиСтроки(Отбор);
    Для Каждого НайдСтрока Из НайденныеСтроки Цикл
        // ...
    КонецЦикла;
КонецЦикла;

For large volumes of data, use indexing through Match:

Индекс = Новый Соответствие;
Для Каждого Строка Из Таблица2 Цикл
    Индекс.Вставить(Строка.Ключ, Строка);
КонецЦикла;

Для Каждого Строка1 Из Таблица1 Цикл
    НайденнаяСтрока = Индекс.Получить(Строка1.Ключ);
    Если НайденнаяСтрока <> Неопределено Тогда
        // we work with the found string
    КонецЕсли;
КонецЦикла;

This technique turns O(n²) into O(n) and is critically important when processing thousands of rows.

Cheat sheet: which cycle to choose?

Task

Cycle

Why

Iterating through an array with an index

For … By

Need access by index

Bypass the tabular part

For everyone

The most readable version

Removing rows from a collection

So far (backward pass)

Avoid skipping elements

Selecting a query result

While Selection.Next()

The only way to get around

Repeat until condition

Bye

Number of iterations unknown

Structure/compliance bypass

For everyone

Getting key-value pairs

Conclusion

Loops in 1C are a tool that you will use in every processing, every report, and every module. Remember the three main rules: do not go into the base inside the loop, delete elements in reverse order and use Match for a quick search. These three techniques distinguish a novice 1C developer from an experienced one.

If you are just starting out in programming or want to master new technologies, take a look at the application Code. There you will find structured courses in Python, JavaScript, HTML, CSS and other languages that will help you understand the basics and move on to real tasks. And in our Telegram channel you can always ask a question, get support from a community of more than 2,000 developers, and keep up to date with new materials. Programming is easier than it seems when there are those who are ready to help.

🎯Stop procrastinating

Liked the article?
Time to practice!

In Kodik, you don't just read — you write code immediately. Theory + practice = real skills.

Instant practice
🧠AI explains code
🏆Certificate

No registration • No card