Разработка и Конфигурация · 9 мин
Как перебрать элементы структуры в 1С
Способы перебора элементов структуры в 1С: цикл Для каждого, доступ по ключу, проверка наличия ключа, типовые ошибки и примеры кода для разработчика.
Структура в 1С — это коллекция пар «ключ-значение», где ключ всегда строка, а значение может быть любого типа. Перебор её элементов встречается постоянно: при разборе параметров процедуры, обработке данных из JSON, формировании отчётов, передаче настроек между модулями. Встроенный язык 1С даёт несколько способов обойти структуру, и у каждого есть свои ограничения.
Главная особенность: структура не гарантирует порядок элементов. Даже если вы добавляли ключи в определённой последовательности, при переборе они могут выдаваться в другом порядке, особенно после сериализации или передачи между клиентом и сервером. Если порядок важен — используйте массив или список значений, а структуру применяйте только для именованного доступа.
Перебор структуры циклом «Для каждого»
Основной способ — цикл Для каждого ... Цикл. На каждой итерации переменная цикла получает объект типа КлючИЗначение (KeyAndValue), у которого есть два свойства: Ключ и Значение.
Структура = Новый Структура;
Структура.Вставить("Номенклатура", "Стол офисный");
Структура.Вставить("Количество", 5);
Структура.Вставить("Цена", 12000);
Для Каждого Элемент Из Структура Цикл
Сообщить(Элемент.Ключ + " = " + Элемент.Значение);
КонецЦикла;
Этот вариант подходит, когда нужно обработать все элементы без исключения: вывести их в лог, скопировать в другую коллекцию, сформировать строку параметров запроса. Цикл работает и на клиенте, и на сервере, и в тонком, и в толстом клиенте — это универсальный синтаксис.
Учтите, что изменять состав структуры внутри цикла (добавлять или удалять ключи) небезопасно: поведение такого перебора не гарантировано и может привести к пропуску элементов или ошибке. Если нужно удалить часть ключей, сначала соберите их в отдельный массив, а удаляйте уже после завершения цикла.
Доступ к значению по ключу и проверка наличия
Частая задача — не перебрать всё, а получить конкретный элемент. Прямое обращение Структура.Количество работает, только если ключ точно существует, иначе возникнет ошибка. Безопасный вариант — метод Свойство().
Значение = Неопределено;
Если Структура.Свойство("Количество", Значение) Тогда
// ключ есть, Значение заполнено
Иначе
// ключа нет, работаем по сценарию по умолчанию
КонецЕсли;
Метод Свойство() возвращает Истина, если ключ найден, и через второй параметр отдаёт значение. Это стандартный приём при разборе необязательных параметров процедур: вызывающий код может передать неполный набор параметров, а вы аккуратно извлекаете только то, что есть.
Перебор с фильтрацией и преобразованием значений
На практике редко нужны все элементы подряд. Типовой сценарий — отобрать элементы по типу значения или по шаблону ключа и обработать только их.
Для Каждого Элемент Из Структура Цикл
Если ТипЗнч(Элемент.Значение) = Тип("Число") Тогда
СтруктураРезультат.Вставить(Элемент.Ключ, Элемент.Значение * 1.2);
КонецЕсли;
КонецЦикла;
Другой распространённый случай — копирование структуры с исключением служебных ключей. Здесь удобно проверять вхождение ключа в заранее подготовленный список исключений и пропускать такие элементы через Продолжить.
Если нужно только прочитать значения без ключей (например, сложить все числовые значения), переменная цикла всё равно даст вам пару «ключ-значение» — просто игнорируйте свойство Ключ. Отдельного метода «получить список значений» у структуры нет.
Структура или соответствие: что выбрать для перебора
Соответствие — близкий по смыслу тип, но с произвольными ключами любого типа, а не только строками-идентификаторами. Синтаксис перебора у обоих типов одинаковый: тот же цикл «Для каждого» с объектом КлючИЗначение.
| Критерий | Структура | Соответствие |
|---|---|---|
| Тип ключа | Строка-идентификатор | Любой тип |
| Обращение через точку | Да (Структура.Ключ) | Нет, только МойСоотв[Ключ] |
| Конструктор с ключами | Новый Структура("Ключ1,Ключ2") | Нет |
| Проверка ключа | Свойство() | Получить() возвращает Неопределено |
| Типичное применение | Параметры, настройки | Кэши, индексы по ссылкам |
Если ключи — это ссылки на объекты, даты или строки с пробелами, берите соответствие. Если вы описываете именованные параметры и хотите обращаться к ним через точку — структура удобнее.
Сравнение вариантов перебора
Универсальный вариант, подходит для полной обработки всех элементов
Когда нужен один-два ключа; безопасно при отсутствии ключа
Когда структуру нужно перенести в объект или другую структуру без ручного цикла
Типовые ошибки при переборе структуры
Первая ошибка — прямое обращение к несуществующему ключу. Код Структура.Скидка упадёт с ошибкой, если ключ не вставлен. Всегда используйте Свойство(), когда наличие ключа не гарантировано контрактом процедуры.
Вторая — попытка изменить значение через переменную цикла. Запись Элемент.Значение = 10 не изменит элемент структуры: для присваивания обращайтесь к самой структуре по ключу — Структура[Элемент.Ключ] = 10.
Третья — ожидание фиксированного порядка элементов. Не стройте логику на том, что первый добавленный ключ будет первым в цикле. Если порядок критичен, храните ключи отдельно в массиве и обходите структуру по этому массиву.
Практический сценарий: разбор параметров процедуры
Классический паттерн в конфигурациях — процедура, принимающая структуру параметров с необязательными значениями. Перебор позволяет применить только переданные настройки, не трогая остальные.
Процедура ПрименитьНастройки(Параметры)
Для Каждого Элемент Из Параметры Цикл
Если Элемент.Ключ = "Валюта" Тогда
ВалютаДокумента = Элемент.Значение;
ИначеЕсли Элемент.Ключ = "Склад" Тогда
СкладОтгрузки = Элемент.Значение;
Иначе
ЗаписьЖурналаРегистрации("Настройки",
УровеньЖурналаРегистрации.Предупреждение, , ,
"Неизвестный параметр: " + Элемент.Ключ);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Ветка «Иначе» с записью в журнал — полезная практика: опечатка в имени параметра у вызывающего кода не пройдёт незамеченной. Без неё ошибка проявится косвенно и гораздо позже.
- 1Определите список допустимых ключей и их типы
- 2Переберите структуру циклом Для каждого
- 3Для каждого элемента проверьте ключ и приведите значение к нужному типу
- 4Неизвестные ключи зафиксируйте в журнале регистрации
- 5Проверьте обязательные параметры после цикла и сообщите об их отсутствии
Проверка результата и отладка
Убедиться, что перебор отработал правильно, проще всего выводом содержимого структуры. В отладчике добавьте структуру в табло — она раскроется списком ключей и значений. Программно можно вывести количество элементов методом Структура.Количество() и сравнить с ожидаемым числом обработанных.
Для контрольного вывода удобен цикл с конкатенацией: соберите строки вида «ключ = значение» и выведите одним сообщением. Это быстрее читается в журнале, чем десятки отдельных сообщений.
Как проверить результат
Структура.Количество() совпадает с числом обработанных в цикле
Часть элементов пропущена — проверяйте условия внутри цикла
Изменённые значения видны при повторном чтении по ключу
Значения старые — вероятно, присваивание шло через Элемент.Значение
Нет предупреждений о неизвестных ключах
Есть записи о неизвестных параметрах — опечатка в имени ключа
Частые вопросы
Можно ли перебрать структуру по индексу, как массив?
Нет. Структура не поддерживает обращение по числовому индексу. Если нужен индексный доступ, скопируйте ключи или значения в массив и работайте с ним.
Как узнать количество элементов в структуре?
Методом Количество(): Структура.Количество(). Пустая структура вернёт 0, цикл по ней просто не выполнит ни одной итерации — отдельная проверка перед циклом не обязательна.
Как изменить значение элемента внутри цикла перебора?
Через обращение к структуре по ключу: Структура[Элемент.Ключ] = НовоеЗначение. Присваивание свойству Значение переменной цикла структуру не меняет.
Чем отличается проверка Свойство() от сравнения с Неопределено?
Свойство() различает ситуации «ключа нет» и «ключ есть, но значение Неопределено». Сравнение значения с Неопределено эти случаи не отличит, что важно, когда Неопределено — допустимое осмысленное значение параметра.
Работает ли перебор структуры на тонком клиенте и в веб-клиенте?
Да, цикл «Для каждого» и методы Свойство(), Вставить(), Удалить() доступны во всех режимах исполнения, включая управляемые формы и веб-клиент.
Что делать, если ключи содержат пробелы или кириллицу со спецсимволами?
Структура требует, чтобы ключи были допустимыми идентификаторами. Для произвольных строк используйте соответствие — синтаксис перебора у него такой же, а ограничений на ключи нет.
Что важно запомнить
Перебор структуры выполняется циклом «Для каждого» с объектом КлючИЗначение. Для точечного доступа используйте Свойство(), изменяйте значения только через структуру по ключу, не рассчитывайте на порядок элементов и не меняйте состав коллекции внутри цикла. Для произвольных ключей берите соответствие.