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

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

Как удалить ключ из структуры в 1С

Как удалить ключ из структуры в 1С: метод Удалить(), проверка существования ключа, типичные ошибки, примеры кода и отличия от соответствия.

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

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

Метод Удалить(): синтаксис и базовый пример

Для удаления элемента структуры используется метод Удалить(), которому передаётся строковое имя ключа. Метод ничего не возвращает — он изменяет саму структуру.

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

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

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

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

// Удаляем ключ "Цена"

СтруктураДанных.Удалить("Цена");

После выполнения Удалить("Цена") в структуре останутся два ключа: «Номенклатура» и «Количество». Попытка обратиться к СтруктураДанных.Цена после удаления приведёт к ошибке «Поле объекта не обнаружено».

Имя ключа чувствительно к написанию, но не к регистру: Удалить("цена") и Удалить("Цена") обратятся к одному и тому же ключу. Однако лишний пробел или опечатка в имени сделают ключ «несуществующим», и метод завершится ошибкой.

Проверка существования ключа перед удалением

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

Проверка через метод Свойство()

Метод Свойство() возвращает Истина, если ключ найден, и может одновременно вернуть значение ключа через второй параметр:

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

СтруктураДанных.Удалить("Цена");

КонецЕсли;

Это самый надёжный способ: он отличает ситуацию «ключа нет» от ситуации «ключ есть, но значение равно Неопределено», что важно при обработке данных, где Неопределено — осмысленное значение.

Проверка через сравнение с Неопределено

Альтернативный вариант — обратиться к ключу через Свойство() с выходным параметром и сравнить результат:

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

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

// Ключ существует, значение в переменной ЗначениеКлюча

СтруктураДанных.Удалить("Цена");

КонецЕсли;

Прямое обращение СтруктураДанных.Цена для проверки использовать нельзя: если ключа нет, будет та же ошибка, которую мы пытаемся избежать.

Безопасное удаление ключа
  1. 1
    Убедитесь, что переменная содержит именно структуру, а не Неопределено или другой тип
  2. 2
    Проверьте наличие ключа методом Свойство("ИмяКлюча")
  3. 3
    Если ключ найден — вызовите Удалить("ИмяКлюча")
  4. 4
    Проверьте результат: повторный вызов Свойство() должен вернуть Ложь

Удаление нескольких ключей и очистка структуры

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

ЛишниеКлючи = Новый Массив;

ЛишниеКлючи.Добавить("ВременныйФлаг");

ЛишниеКлючи.Добавить("СлужебныйСчетчик");

ЛишниеКлючи.Добавить("Кэш");

Для Каждого ИмяКлюча Из ЛишниеКлючи Цикл

Если СтруктураДанных.Свойство(ИмяКлюча) Тогда

СтруктураДанных.Удалить(ИмяКлюча);

КонецЕсли;

КонецЦикла;

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

Важно понимать разницу: Очистить() сохраняет переменную валидной (структура существует, но пуста), а присвоение СтруктураДанных = Неопределено уничтожает сам объект. Если на структуру ссылаются другие переменные или она передана в процедуру по ссылке, предпочтителен именно Очистить().

Удаление ключей при переборе структуры в цикле

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

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

КлючиКУдалению = Новый Массив;

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

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

КлючиКУдалению.Добавить(Элемент.Ключ);

КонецЕсли;

КонецЦикла;

Для Каждого ИмяКлюча Из КлючиКУдалению Цикл

СтруктураДанных.Удалить(ИмяКлюча);

КонецЦикла;

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

Отличия от соответствия и связанные ограничения

В 1С есть два похожих объекта: структура и соответствие. У соответствия тоже есть метод Удалить(), и синтаксис идентичен, но поведение при отсутствующем ключе отличается: соответствие при удалении несуществующего ключа не выбрасывает исключение, а просто ничего не делает. Это частая причина путаницы при переносе кода между двумя типами.

ПараметрСтруктураСоответствие
Тип ключаТолько строкаЛюбой тип
Удаление несуществующего ключаОшибка исполненияБез ошибки
Проверка ключаСвойство()Прямое обращение, вернёт Неопределено
Доступ через точкуДаНет

Ещё одно ограничение структуры: если она создана с фиксированным набором ключей (например, получена из типовых механизмов БСП как фиксированная структура, объект типа ФиксированнаяСтруктура), методы Вставить() и Удалить() недоступны — попытка вызова завершится ошибкой. В таком случае нужно создать изменяемую копию.

// Копия фиксированной структуры в обычную

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

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

Если Элемент.Ключ <> "УдаляемыйКлюч" Тогда

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

КонецЕсли;

КонецЦикла;

Типичные ошибки
01
Вызов Удалить() без проверки Свойство() — исключение при отсутствии ключа и прерывание обработки
02
Удаление элементов внутри цикла Для Каждого по самой структуре — ошибка изменения коллекции во время обхода
03
Попытка удалить ключ из ФиксированнойСтруктуры — метод недоступен, нужна копия в обычную структуру
04
Опечатка в имени ключа при вызове Удалить() — ошибка, хотя разработчик уверен, что ключ существует
05
Проверка ключа через прямое обращение Структура.Ключ — та же ошибка, что и при удалении, если ключа нет

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

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

СтруктураДанных.Удалить("Цена");

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

// Удаление прошло успешно

КонецЕсли;

Сообщить("Осталось ключей: " + СтруктураДанных.Количество());

В конфигураторе состояние структуры удобно смотреть через табло (Ctrl+Shift+F9 при остановке в отладчике): там видны все ключи и значения. Если ключ не удалился, первым делом проверяйте точное написание имени — включая пробелы и спецсимволы, которые могли попасть в ключ при программном формировании.

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

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

Свойство("ИмяКлюча") после удаления
Норма

Возвращает Ложь

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

Возвращает Истина — ключ не удалён, проверьте имя

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

Уменьшилось на число удалённых ключей

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

Не изменилось — удаление не выполнилось

Повторный запуск кода
Норма

Без ошибок благодаря проверке Свойство()

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

Исключение — значит, проверка отсутствует или не срабатывает

Когда удалять ключ, а когда пересоздать структуру

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

Удаление ключей оправдано, когда структура большая, а исключить нужно один-два элемента, либо когда структура передаётся по ссылке и должна измениться «на месте» для вызывающего кода. В остальных случаях пересоздание обычно безопаснее и понятнее для сопровождения.

Итог

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

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

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

Что произойдёт, если удалить несуществующий ключ из структуры?

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

Как удалить все ключи из структуры сразу?

Вызовите метод Очистить() — он удалит все элементы, оставив пустую, но рабочую структуру. Это предпочтительнее цикла с удалением по одному ключу и безопаснее, чем присвоение Неопределено, если на структуру есть внешние ссылки.

Можно ли удалить ключ из структуры во время её перебора в цикле?

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

Почему метод Удалить() недоступен для моей структуры?

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

Чувствительно ли имя ключа к регистру при удалении?

Нет, ключи структуры регистронезависимы: Удалить("Цена") и Удалить("ЦЕНА") удалят один и тот же ключ. Но чувствительны пробелы и остальные символы — "Цена " с пробелом и "Цена" это разные ключи.

Как удалить ключ, значение которого равно Неопределено?

Проверяйте наличие ключа через Свойство(), а не через сравнение значения: ключ со значением Неопределено — это существующий ключ, и Удалить() отработает штатно. Ошибка возникает только когда ключа в структуре нет совсем.