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