Ошибка 1С: Итератор для объекта не определен — Способы устранения
- Отказ выполнения цикла
Для Каждого ... Из ... Цикл. - Текст ошибки:
{Обработка.Имя(Строка)}: Итератор для объекта не определен. - Сбой происходит, когда в качестве источника для перебора передается неитерируемый тип (например, примитивный тип,
Неопределено,РезультатЗапросавместо выборки/таблицы или объект ссылочного типа).
1. Причина возникновения ошибки
Цикл Для Каждого Элемент Из Коллекция Цикл во встроенном языке 1С требует, чтобы объект Коллекция поддерживал интерфейс итерирования (коллекции: Массив, Структура, Соответствие, ТаблицаЗначений, ДеревоЗначений, СписокЗначений, ВыборкаИзРезультатаЗапроса и ТабличныеЧасти).
Если переменная содержит РезультатЗапроса (напрямую, без выгрузки или выборки), СправочникСсылка, ДокументОбъект или Неопределено, среда 1С генерирует данное исключение.
2. Способы исправления типовых ошибок
Ошибка 1: Попытка обхода Результата Запроса напрямую:
// НЕПРАВИЛЬНО:
Результат = Запрос.Выполнить();
Для Каждого Стр Из Результат Цикл // Ошибка: Итератор не определен!
// ПРАВИЛЬНО (через выборку):
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
// Логика работы с Выборка.Поле
КонецЦикла;
// ПРАВИЛЬНО (через выгрузку в ТЗ):
Таблица = Запрос.Выполнить().Выгрузить();
Для Каждого Стр Из Таблица Цикл
// Логика работы
КонецЦикла;Ошибка 2: Переменная содержит Неопределено или не проинициализирована:
// Защитная проверка перед циклом
Если ТипЗнч(КоллекцияЭлементов) = Тип("Массив")
ИЛИ ТипЗнч(КоллекцияЭлементов) = Тип("ТаблицаЗначений") Тогда
Для Каждого Элемент Из КоллекцияЭлементов Цикл
// Безопасный обход
КонецЦикла;
КонецЕсли;Ошибка 3: Попытка обхода реквизитов объекта метаданных:
// Для обхода реквизитов документа нужно обращаться к его метаданным:
Для Каждого Реквизит Из Метаданные.Документы.РеализацияТоваровУслуг.Реквизиты Цикл
Сообщить(Реквизит.Имя);
КонецЦикла; Частые вопросы (FAQ)
Можно ли перебирать структуру циклом 'Для Каждого'?
Да, Структура поддерживает итератор. На каждом шаге цикла возвращается объект типа КлючИЗначение, содержащий свойства .Ключ (имя свойства) и .Значение.
Почему нельзя обойти ТабличнуюЧасть объекта, полученного через Ссылку?
Ссылка (например, СправочникСсылка) не загружает табличные части в память клиента целиком. Чтобы обойти табличную часть ссылки, нужно либо получить объект (Ссылка.ПолучитьОбъект().ИмяТЧ), либо прочитать ТЧ через запрос.
Что быстрее при обработке запроса: Выборка (Пока Выборка.Следующий()) или ТЗ (Для Каждого)?
Выборка значительно экономит оперативную память на больших объемах данных, так как подгружает записи порционно, тогда как Выгрузить() аллоцирует всю таблицу в RAM целиком.
Поддерживает ли тип Строка посимвольный обход через 'Для Каждого'?
Нет, строка во встроенном языке 1С не является итерируемой коллекцией. Для посимвольного перебора используется цикл 'Для Счетчик = 1 По СтрДлина(Строка) Цикл' и функция Сред(Строка, Счетчик, 1).