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

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

Как перебрать все свойства структуры в 1С

Как перебрать все свойства структуры в 1С: цикл Для Каждого, КлючИЗначение, проверка наличия ключа методом Свойство(), типичные ошибки и готовые примеры кода.

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

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

Базовый перебор через «Для Каждого»

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

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

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

СтруктураДанных.Вставить("Количество", 10);

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

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

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

КонецЦикла;

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

Цикл работает и с фиксированной структурой (ФиксированнаяСтруктура) — для чтения перебор доступен, хотя изменять значения такой структуры нельзя.

Проверка наличия конкретного свойства методом Свойство()

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

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

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

Сообщить("Скидка: " + ЗначениеСкидки);

Иначе

Сообщить("Скидка не задана");

КонецЕсли;

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

Количество свойств и очистка структуры

Узнать, сколько свойств содержит структура, можно методом Количество(). Это полезно для проверки «пустая ли структура» перед перебором, хотя сам цикл по пустой структуре просто не выполнится ни разу и ошибки не вызовет.

Если СтруктураДанных.Количество() = 0 Тогда

Сообщить("Структура пустая");

КонецЕсли;

Для удаления отдельного свойства используется Удалить("ИмяКлюча"), для полной очистки — Очистить(). Учтите ограничение: удалять элементы структуры внутри цикла Для Каждого по этой же структуре нельзя — коллекция изменяется во время обхода, и поведение цикла станет некорректным. Сначала соберите ключи для удаления в отдельный массив, затем удаляйте их после цикла.

Копирование и фильтрация свойств при переборе

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

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

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

Если Элемент.Ключ = "СлужебныйПризнак" Тогда

Продолжить;

КонецЕсли;

Если Элемент.Значение <> Неопределено Тогда

НоваяСтруктура.Вставить(Элемент.Ключ, Элемент.Значение);

КонецЕсли;

КонецЦикла;

Обратите внимание: Вставить не вызывает ошибки, если ключ уже существует, — значение просто перезаписывается. Это удобно при слиянии структур, но может скрыть ошибку, если вы ожидали, что ключ встречается один раз.

Сравнение двух структур по содержимому

Оператор сравнения = для структур сравнивает ссылки, а не содержимое: две структуры с одинаковыми ключами и значениями будут «не равны». Поэтому поэлементное сравнение делается вручную через перебор.

Порядок сравнения двух структур
  1. 1
    Сравните Количество() обеих структур — при различии структуры точно разные
  2. 2
    Переберите первую структуру циклом Для Каждого
  3. 3
    Для каждого ключа проверьте его наличие во второй структуре через Свойство()
  4. 4
    Сравните значения найденных ключей
  5. 5
    Если все проверки пройдены — структуры равны по содержимому
Функция СтруктурыРавны(Структура1, Структура2)

Если Структура1.Количество() <> Структура2.Количество() Тогда

Возврат Ложь;

КонецЕсли;

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

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

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

Возврат Ложь;

КонецЕсли;

Если Элемент.Значение <> Значение2 Тогда

Возврат Ложь;

КонецЕсли;

КонецЦикла;

Возврат Истина;

КонецФункции

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

Чем перебор структуры отличается от перебора соответствия

Структура или соответствие

Структура

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

Соответствие

Ключ — значение любого типа (число, ссылка, дата). Обращение только через квадратные скобки. Подходит для произвольных ключей и больших словарей.

Синтаксис перебора у обоих типов одинаковый: Для Каждого Элемент Из Коллекция Цикл с доступом к Элемент.Ключ и Элемент.Значение. Разница — в типе ключей и способе доступа. В структуре ключ обязан быть допустимым идентификатором: начинаться с буквы, не содержать пробелов и спецсимволов. Если ключи приходят извне (например, из данных пользователя) и могут содержать произвольные строки — используйте соответствие.

Ещё одно отличие: у соответствия нет метода Свойство(). Проверка наличия ключа выполняется обращением Соответствие.Получить(Ключ), которое вернёт Неопределено при отсутствии ключа.

Типичные ошибки при работе со свойствами структуры

Типичные ошибки
01
Обращение Структура.Ключ без проверки — ошибка «Поле объекта не обнаружено», если ключа нет. Используйте Свойство() с двумя параметрами.
02
Удаление ключей внутри цикла Для Каждого — некорректный обход коллекции. Удаляйте после цикла по списку ключей.
03
Сравнение структур оператором = — сравниваются ссылки, а не содержимое. Нужен поэлементный перебор.
04
Ожидание фиксированного порядка обхода — порядок ключей не гарантирован. Сортируйте ключи вручную, если порядок важен.
05
Попытка индексации Структура[0] — у структуры нет числовых индексов, только перебор или доступ по имени ключа.

Отдельно стоит упомянуть работу со структурой, полученной из JSON или из параметров формы: там часто встречаются ключи с регистром, отличным от ожидаемого. Имена свойств в 1С не чувствительны к регистру — Структура.Цена и Структура.ЦЕНА обращаются к одному ключу, — но при сравнении Элемент.Ключ со строковым литералом оператором = регистр тоже не учитывается, что обычно упрощает жизнь.

Проверка результата перебора

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

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

Вывод всех ключей
Норма

В сообщениях видны все ожидаемые ключи с корректными значениями

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

Часть ключей отсутствует — проверьте, не изменялась ли структура до цикла

Доступ к необязательному ключу
Норма

Код работает и при наличии, и при отсутствии ключа

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

Ошибка «Поле объекта не обнаружено» — доступ идёт напрямую, без Свойство()

Сравнение структур
Норма

Одинаковые по содержимому структуры признаются равными

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

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

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

Итог

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

Перебор свойств структуры выполняется циклом Для Каждого с доступом к Элемент.Ключ и Элемент.Значение. Наличие ключа проверяется методом Свойство(), количество — методом Количество(). Не изменяйте структуру внутри цикла обхода и не сравнивайте структуры оператором равенства.

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

Как узнать, пустая ли структура, без перебора?

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

Можно ли перебрать свойства фиксированной структуры?

Да, цикл Для Каждого работает с ФиксированнаяСтруктура так же, как с обычной. Ограничение касается только изменения: добавлять, удалять и менять значения в фиксированной структуре нельзя.

Как обратиться к свойству, имя которого хранится в переменной?

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

Почему порядок ключей при переборе каждый раз разный?

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

Как скопировать все свойства одной структуры в другую?

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

Что вернёт обращение к несуществующему ключу соответствия?

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