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

Ciclos en 1C: cómo procesar listas, partes de tablas y selecciones

Analizamos todos los tipos de ciclos en 1C: «Para», «Para cada uno» y «Mientras». Aprendemos a procesar partes de tablas, consultas de selección, estructuras y coincidencias. Mostramos errores típicos al eliminar filas y técnicas para optimizar el rendimiento.

К

Kodik

Autor

8 min de lectura

Trabajar con datos en 1C es, de hecho, un trabajo constante con colecciones. Directorios, documentos, registros: todos estos son conjuntos de datos que deben ordenarse, filtrarse y transformarse. Sin comprender los ciclos, no escribirás ningún procesamiento serio. En este artículo analizaremos todos los tipos de ciclos en 1C, mostraremos ejemplos reales y hablaremos sobre las dificultades que no se mencionan en la documentación.

Tres ballenas: tipos de ciclos en 1C

En la plataforma 1C:Enterprise hay tres diseños para organizar ciclos. Cada una está diseñada para su propio escenario.

Ciclo «Para» — cuando conocemos el número de iteraciones

Bucle de conteo clásico. Se utiliza cuando se sabe de antemano cuántas veces se debe realizar una acción.

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

Un matiz importante: la variable del contador aumenta automáticamente en 1 después de cada iteración. En 1C no se puede establecer un paso arbitrario, como en otros idiomas. Si necesitas un paso que no sea uno, tendrás que hacer trampa:

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

Un escenario típico es recorrer la matriz por índice:

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

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

Ciclo «Para todos»: un soldado universal

El ciclo más popular en 1C. Funciona con cualquier colección: matrices, listas de valores, partes de tablas, resultados de consultas, estructuras y coincidencias.

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

La principal ventaja es que no tienes que pensar en índices, límites y número de elementos. Simplemente trabajas con cada elemento de la colección.

El ciclo "Hasta" es cuando la condición de salida se desconoce de antemano

Se ejecuta mientras la condición sea verdadera. Ideal para situaciones en las que el número de iteraciones se desconoce de antemano.

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

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

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

Ten cuidado: si la condición nunca se vuelve falsa, obtendrás un bucle infinito y la plataforma se bloqueará. Siempre proporcione una salida de emergencia:

Счетчик = 0;
Пока НеВыполненоУсловие И Счетчик < 10000 Цикл
    // lógica de procesamiento
    Счетчик = Счетчик + 1;
КонецЦикла;
🔥 100.000+ estudiantes ya están con nosotros

¿Cansado de leer teoría?
¡Hora de programar!

Kodik — una app donde aprendes a programar con práctica. Mentor IA, lecciones interactivas, proyectos reales.

🤖 IA 24/7
🎓 Certificados
💰 Gratis
🚀 Empezar
Se unieron hoy

Procesamiento de partes tabulares de documentos

Las partes de la tabla son una de las estructuras de datos más comunes con las que trabaja el desarrollador de 1C. Analicemos algunas tareas prácticas.

Cálculo de la cantidad en la parte tabular

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

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

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

Eliminar filas de la parte tabular

Aquí es donde comienza la parte más interesante. El error clásico de un principiante es eliminar líneas en un ciclo directo:

// ❌ NO SE PUEDE HACER ASÍ: ¡salta las líneas!
Для Каждого СтрокаТЧ Из Документ.Товары Цикл
    Если СтрокаТЧ.Количество = 0 Тогда
        Документ.Товары.Удалить(СтрокаТЧ);
    КонецЕсли;
КонецЦикла;

Cuando se elimina una línea, la colección se desplaza y el siguiente elemento «se desliza» más allá. El enfoque correcto es omitir la parte de la tabla en orden inverso. Pero el ciclo estándar «Para» en 1C no admite la cuenta atrás, por lo que usamos «Hasta»:

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

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

Búsqueda de duplicados en la parte tabular

Una tarea que se repite constantemente: encontrar y combinar productos idénticos.

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

Ten en cuenta que al eliminar un duplicado no aumentamos Ind2, porque el siguiente elemento se moverá a su lugar.

Trabajar con muestras de consultas

El resultado de la solicitud en 1C no es una matriz, sino un objeto especial que se trata de una manera especial.

Recorrido básico de la muestra

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

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

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

El método Следующий() mueve el puntero al siguiente registro y devuelve Истина si el registro existe. Cuando los registros terminan, se devuelve Ложь y el ciclo termina.

Anulación de la selección jerárquica

Para los directorios con jerarquía, es conveniente utilizar una selección con agrupaciones:

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

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

Solicitudes por lotes con múltiples resultados

Cuando una consulta devuelve varias tablas, procesamos cada una de ellas:

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

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

Recorrido por estructuras y coincidencias

Las estructuras y las coincidencias son pares de clave-valor. Se omiten a través de Для Каждого:

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

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

Para las coincidencias, la sintaxis es similar, pero la coincidencia permite claves de cualquier tipo, no solo cadenas.

Gestión del ciclo: Interrumpir y Continuar

Dos operadores permiten controlar de forma flexible el progreso del ciclo.

Прервать - sale inmediatamente del ciclo:

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

Продолжить — omite el código de iteración restante y pasa al siguiente:

Для Каждого Контрагент Из СписокКонтрагентов Цикл
    Если Контрагент.ЭтоГруппа Тогда
        Продолжить; // grupos omitidos
    КонецЕсли;
    
    // procesamiento solo de elementos
    ОбработатьКонтрагента(Контрагент);
КонецЦикла;

Consejos prácticos sobre el rendimiento

Hay varias reglas que te ayudarán a escribir bucles rápidos y fiables en 1C.

No se dirija a la base de datos dentro del ciclo. Cada llamada a la base de datos es una solicitud de red. Si tienes 10.000 filas, harás 10.000 llamadas al servidor. En su lugar, obtenga todos los datos que necesita con una sola consulta antes del ciclo:

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

// ✅ Rápido: una solicitud, luego un ciclo
Запрос = Новый Запрос;
Запрос.Текст = "SELECT Nomenclature, Remainder FROM ...";
ТаблицаОстатков = Запрос.Выполнить().Выгрузить();

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

Utiliza TablaDeValores.EncontrarFilas() en lugar de bucles anidados. En lugar de recorrer con un bucle anidado, usa los métodos de búsqueda integrados, funcionan mucho más rápido:

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

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

Para grandes volúmenes de datos, utiliza la indexación a través de la Correspondencia:

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

Для Каждого Строка1 Из Таблица1 Цикл
    НайденнаяСтрока = Индекс.Получить(Строка1.Ключ);
    Если НайденнаяСтрока <> Неопределено Тогда
        // trabajamos con la línea encontrada
    КонецЕсли;
КонецЦикла;

Esta técnica convierte O(n²) en O(n) y es de importancia crítica cuando se procesan miles de filas.

Hoja de trucos: ¿qué ciclo elegir?

Tarea

Ciclo

¿Por qué?

Recorrido de la matriz con índice

Para … Por

Se requiere acceso por índice

Omitir la parte de la tabla

Para todos

La versión más leída

Eliminar líneas de la colección

Hasta (recorrido inverso)

Evitamos omitir elementos

Selección de resultados de la consulta

Mientras que Selección.Siguiente()

La única forma de evitarlo

Repetición hasta la condición

Hasta

Número de iteraciones desconocido

Evitación de la estructura/conformidad

Para todos

Obteniendo pares clave-valor

Conclusión

Los bucles en 1C son una herramienta que utilizarás en cada procesamiento, cada informe y cada módulo. Recuerda las tres reglas principales: no te metas en la base de datos dentro de un ciclo, elimina los elementos en orden inverso y usa Coincidencia para una búsqueda rápida. Estas tres técnicas distinguen a un desarrollador 1C novato de uno experimentado.

Si acabas de empezar tu viaje en la programación o quieres dominar nuevas tecnologías, echa un vistazo a la aplicación Kodik. Allí encontrarás cursos estructurados en Python, JavaScript, HTML, CSS y otros lenguajes que te ayudarán a comprender los conceptos básicos y pasar a tareas reales. Y en nuestro Canal de Telegram siempre puedes hacer una pregunta, obtener el apoyo de una comunidad de más de 2000 desarrolladores y estar al tanto de los nuevos materiales. La programación es más fácil de lo que parece cuando hay personas dispuestas a ayudar.

🎯Deja de postergar

¿Te gustó el artículo?
¡Hora de practicar!

En Kodik no solo lees — escribes código de inmediato. Teoría + práctica = habilidades reales.

Práctica instantánea
🧠IA explica código
🏆Certificado

Sin registro • Sin tarjeta