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