К статье
Практический материал

Разработка и Конфигурация · 9 мин

Как перебрать элементы структуры в 1С

Способы перебора элементов структуры в 1С: цикл Для каждого, доступ по ключу, проверка наличия ключа, типовые ошибки и примеры кода для разработчика.

Структура в 1С — это коллекция пар «ключ-значение», где ключ всегда строка, а значение может быть любого типа. Перебор её элементов встречается постоянно: при разборе параметров процедуры, обработке данных из JSON, формировании отчётов, передаче настроек между модулями. Встроенный язык 1С даёт несколько способов обойти структуру, и у каждого есть свои ограничения.

Главная особенность: структура не гарантирует порядок элементов. Даже если вы добавляли ключи в определённой последовательности, при переборе они могут выдаваться в другом порядке, особенно после сериализации или передачи между клиентом и сервером. Если порядок важен — используйте массив или список значений, а структуру применяйте только для именованного доступа.

Перебор структуры циклом «Для каждого»

Основной способ — цикл Для каждого ... Цикл. На каждой итерации переменная цикла получает объект типа КлючИЗначение (KeyAndValue), у которого есть два свойства: Ключ и Значение.

Структура = Новый Структура;

Структура.Вставить("Номенклатура", "Стол офисный");

Структура.Вставить("Количество", 5);

Структура.Вставить("Цена", 12000);

Для Каждого Элемент Из Структура Цикл

Сообщить(Элемент.Ключ + " = " + Элемент.Значение);

КонецЦикла;

Этот вариант подходит, когда нужно обработать все элементы без исключения: вывести их в лог, скопировать в другую коллекцию, сформировать строку параметров запроса. Цикл работает и на клиенте, и на сервере, и в тонком, и в толстом клиенте — это универсальный синтаксис.

Учтите, что изменять состав структуры внутри цикла (добавлять или удалять ключи) небезопасно: поведение такого перебора не гарантировано и может привести к пропуску элементов или ошибке. Если нужно удалить часть ключей, сначала соберите их в отдельный массив, а удаляйте уже после завершения цикла.

Доступ к значению по ключу и проверка наличия

Частая задача — не перебрать всё, а получить конкретный элемент. Прямое обращение Структура.Количество работает, только если ключ точно существует, иначе возникнет ошибка. Безопасный вариант — метод Свойство().

Значение = Неопределено;

Если Структура.Свойство("Количество", Значение) Тогда

// ключ есть, Значение заполнено

Иначе

// ключа нет, работаем по сценарию по умолчанию

КонецЕсли;

Метод Свойство() возвращает Истина, если ключ найден, и через второй параметр отдаёт значение. Это стандартный приём при разборе необязательных параметров процедур: вызывающий код может передать неполный набор параметров, а вы аккуратно извлекаете только то, что есть.

Перебор с фильтрацией и преобразованием значений

На практике редко нужны все элементы подряд. Типовой сценарий — отобрать элементы по типу значения или по шаблону ключа и обработать только их.

Для Каждого Элемент Из Структура Цикл

Если ТипЗнч(Элемент.Значение) = Тип("Число") Тогда

СтруктураРезультат.Вставить(Элемент.Ключ, Элемент.Значение * 1.2);

КонецЕсли;

КонецЦикла;

Другой распространённый случай — копирование структуры с исключением служебных ключей. Здесь удобно проверять вхождение ключа в заранее подготовленный список исключений и пропускать такие элементы через Продолжить.

Если нужно только прочитать значения без ключей (например, сложить все числовые значения), переменная цикла всё равно даст вам пару «ключ-значение» — просто игнорируйте свойство Ключ. Отдельного метода «получить список значений» у структуры нет.

Структура или соответствие: что выбрать для перебора

Соответствие — близкий по смыслу тип, но с произвольными ключами любого типа, а не только строками-идентификаторами. Синтаксис перебора у обоих типов одинаковый: тот же цикл «Для каждого» с объектом КлючИЗначение.

КритерийСтруктураСоответствие
Тип ключаСтрока-идентификаторЛюбой тип
Обращение через точкуДа (Структура.Ключ)Нет, только МойСоотв[Ключ]
Конструктор с ключамиНовый Структура("Ключ1,Ключ2")Нет
Проверка ключаСвойство()Получить() возвращает Неопределено
Типичное применениеПараметры, настройкиКэши, индексы по ссылкам

Если ключи — это ссылки на объекты, даты или строки с пробелами, берите соответствие. Если вы описываете именованные параметры и хотите обращаться к ним через точку — структура удобнее.

Сравнение вариантов перебора

Для каждого по структуре

Универсальный вариант, подходит для полной обработки всех элементов

Свойство() для точечного доступа

Когда нужен один-два ключа; безопасно при отсутствии ключа

Копирование через ЗаполнитьЗначенияСвойств

Когда структуру нужно перенести в объект или другую структуру без ручного цикла

Типовые ошибки при переборе структуры

Первая ошибка — прямое обращение к несуществующему ключу. Код Структура.Скидка упадёт с ошибкой, если ключ не вставлен. Всегда используйте Свойство(), когда наличие ключа не гарантировано контрактом процедуры.

Вторая — попытка изменить значение через переменную цикла. Запись Элемент.Значение = 10 не изменит элемент структуры: для присваивания обращайтесь к самой структуре по ключу — Структура[Элемент.Ключ] = 10.

Третья — ожидание фиксированного порядка элементов. Не стройте логику на том, что первый добавленный ключ будет первым в цикле. Если порядок критичен, храните ключи отдельно в массиве и обходите структуру по этому массиву.

Типичные ошибки
01
Обращение к ключу без проверки Свойство() — ошибка времени выполнения при отсутствии ключа
02
Присваивание через Элемент.Значение — структура не меняется, изменение молча теряется
03
Удаление ключей внутри цикла перебора — пропуск элементов или непредсказуемое поведение
04
Расчёт на порядок добавления — порядок перебора не гарантирован

Практический сценарий: разбор параметров процедуры

Классический паттерн в конфигурациях — процедура, принимающая структуру параметров с необязательными значениями. Перебор позволяет применить только переданные настройки, не трогая остальные.

Процедура ПрименитьНастройки(Параметры)

Для Каждого Элемент Из Параметры Цикл

Если Элемент.Ключ = "Валюта" Тогда

ВалютаДокумента = Элемент.Значение;

ИначеЕсли Элемент.Ключ = "Склад" Тогда

СкладОтгрузки = Элемент.Значение;

Иначе

ЗаписьЖурналаРегистрации("Настройки",

УровеньЖурналаРегистрации.Предупреждение, , ,

"Неизвестный параметр: " + Элемент.Ключ);

КонецЕсли;

КонецЦикла;

КонецПроцедуры

Ветка «Иначе» с записью в журнал — полезная практика: опечатка в имени параметра у вызывающего кода не пройдёт незамеченной. Без неё ошибка проявится косвенно и гораздо позже.

Порядок действий при разборе структуры параметров
  1. 1
    Определите список допустимых ключей и их типы
  2. 2
    Переберите структуру циклом Для каждого
  3. 3
    Для каждого элемента проверьте ключ и приведите значение к нужному типу
  4. 4
    Неизвестные ключи зафиксируйте в журнале регистрации
  5. 5
    Проверьте обязательные параметры после цикла и сообщите об их отсутствии

Проверка результата и отладка

Убедиться, что перебор отработал правильно, проще всего выводом содержимого структуры. В отладчике добавьте структуру в табло — она раскроется списком ключей и значений. Программно можно вывести количество элементов методом Структура.Количество() и сравнить с ожидаемым числом обработанных.

Для контрольного вывода удобен цикл с конкатенацией: соберите строки вида «ключ = значение» и выведите одним сообщением. Это быстрее читается в журнале, чем десятки отдельных сообщений.

Контрольные точки

Как проверить результат

Количество элементов
Норма

Структура.Количество() совпадает с числом обработанных в цикле

Тревожный признак

Часть элементов пропущена — проверяйте условия внутри цикла

Значения после изменения
Норма

Изменённые значения видны при повторном чтении по ключу

Тревожный признак

Значения старые — вероятно, присваивание шло через Элемент.Значение

Журнал регистрации
Норма

Нет предупреждений о неизвестных ключах

Тревожный признак

Есть записи о неизвестных параметрах — опечатка в имени ключа

Частые вопросы

Можно ли перебрать структуру по индексу, как массив?

Нет. Структура не поддерживает обращение по числовому индексу. Если нужен индексный доступ, скопируйте ключи или значения в массив и работайте с ним.

Как узнать количество элементов в структуре?

Методом Количество(): Структура.Количество(). Пустая структура вернёт 0, цикл по ней просто не выполнит ни одной итерации — отдельная проверка перед циклом не обязательна.

Как изменить значение элемента внутри цикла перебора?

Через обращение к структуре по ключу: Структура[Элемент.Ключ] = НовоеЗначение. Присваивание свойству Значение переменной цикла структуру не меняет.

Чем отличается проверка Свойство() от сравнения с Неопределено?

Свойство() различает ситуации «ключа нет» и «ключ есть, но значение Неопределено». Сравнение значения с Неопределено эти случаи не отличит, что важно, когда Неопределено — допустимое осмысленное значение параметра.

Работает ли перебор структуры на тонком клиенте и в веб-клиенте?

Да, цикл «Для каждого» и методы Свойство(), Вставить(), Удалить() доступны во всех режимах исполнения, включая управляемые формы и веб-клиент.

Что делать, если ключи содержат пробелы или кириллицу со спецсимволами?

Структура требует, чтобы ключи были допустимыми идентификаторами. Для произвольных строк используйте соответствие — синтаксис перебора у него такой же, а ограничений на ключи нет.

Итог

Что важно запомнить

Перебор структуры выполняется циклом «Для каждого» с объектом КлючИЗначение. Для точечного доступа используйте Свойство(), изменяйте значения только через структуру по ключу, не рассчитывайте на порядок элементов и не меняйте состав коллекции внутри цикла. Для произвольных ключей берите соответствие.