Разработка и Конфигурация · 13 мин
Как программно очистить дополнительные реквизиты в 1С
Как программно очистить дополнительные реквизиты в 1С: работа с табличной частью ДополнительныеРеквизиты, хранилищем значений, обходом справочников и документов. Примеры кода и проверка результата.
Дополнительные реквизиты в конфигурациях на базе БСП (Библиотека стандартных подсистем) хранятся не в отдельных колонках таблиц, а в служебной табличной части объекта с именем ДополнительныеРеквизиты. Поэтому «очистить реквизит» через присвоение пустого значения полю объекта не получится — нужно работать именно с этой табличной частью: удалять строки или очищать значения в них.
Задача возникает в типовых сценариях: массовая чистка данных перед свёрткой базы, удаление ошибочно загруженных свойств после обмена, сброс значений устаревшего реквизита, который вывели из использования. Во всех случаях логика одна — найти в табличной части строки, связанные с нужным свойством из плана видов характеристик ДополнительныеРеквизитыИСведения, и обработать их.
Ниже разобраны рабочие примеры кода для управляемых форм и внешних обработок, отличия очистки реквизитов от дополнительных сведений, а также проверки, которые помогут убедиться, что данные удалены корректно и ничего лишнего не задето.
Где физически хранятся дополнительные реквизиты
В конфигурациях с БСП (Управление торговлей, ERP, Комплексная автоматизация, ЗУП и другие) объекты, поддерживающие дополнительные реквизиты, содержат табличную часть ДополнительныеРеквизиты с ключевыми колонками: Свойство (ссылка на ПВХ ДополнительныеРеквизитыИСведения) и Значение. Для нестроковых типов значение хранится в колонке Значение, для длинных строк — в колонке ТекстоваяСтрока.
Важно отличать дополнительные реквизиты от дополнительных сведений. Сведения хранятся не в объекте, а в регистре сведений ДополнительныеСведения с измерением Объект и Свойство. Путаница между ними — частая причина «не работающего» кода: разработчик очищает табличную часть, а данные на самом деле лежат в регистре.
Как получить ссылку на очищаемое свойство
Прежде чем чистить данные, нужно однозначно определить свойство. Надёжнее всего искать его по имени или заголовку в пределах конкретного набора свойств объекта, потому что одноимённые свойства могут существовать у разных наборов (например, у «Номенклатуры» и «Контрагентов»).
Функция НайтиСвойство(ИмяСвойства)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| Свойства.Ссылка КАК Свойство
|ИЗ
| ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения КАК Свойства
|ГДЕ
| Свойства.Имя = &Имя
| И НЕ Свойства.ПометкаУдаления";
Запрос.УстановитьПараметр("Имя", ИмяСвойства);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
Возврат Выборка.Свойство;
Иначе
Возврат Неопределено;
КонецЕсли;
КонецФункции
Поле Имя у свойства формируется автоматически и не всегда совпадает с видимым заголовком. Если имя неизвестно, ищите по Заголовок, но учитывайте, что заголовки могут дублироваться — тогда добавьте отбор по набору свойств через табличную часть набора ДополнительныеРеквизиты справочника НаборыДополнительныхРеквизитовИСведений.
Очистка реквизитов в одном объекте
Для разовой обработки одного элемента справочника или документа достаточно получить объект, найти строки табличной части и удалить их. Удалять нужно в цикле с конца или через массив найденных строк — удаление по индексу в прямом цикле пропускает элементы.
Процедура ОчиститьРеквизитОбъекта(СсылкаНаОбъект, Свойство) Экспорт
Объект = СсылкаНаОбъект.ПолучитьОбъект();
НайденныеСтроки = Объект.ДополнительныеРеквизиты.НайтиСтроки(
Новый Структура("Свойство", Свойство));
Для Каждого Строка Из НайденныеСтроки Цикл
Объект.ДополнительныеРеквизиты.Удалить(Строка);
КонецЦикла;
Объект.Записать();
КонецПроцедуры
Если нужно не удалить строку, а только сбросить значение (например, чтобы строка осталась для журнала изменений), замените удаление на присвоение: Строка.Значение = Неопределено; и очистку Строка.ТекстоваяСтрока = "";. Однако пустые строки в табличной части — плохая практика: типовые механизмы БСП при записи объекта сами удаляют строки с незаполненными значениями, поэтому надёжнее удалять строку целиком.
Массовая очистка по всем объектам вида
Когда очистить реквизит нужно у всех элементов справочника или всех документов вида, обход делается через выборку ссылок запросом. Ключевые правила: обрабатывать объекты порциями, записывать в транзакции с разумным размером пачки и не использовать Записать() без необходимости в режиме обмена данными, если нужно зафиксировать изменения в планах обмена.
Процедура ОчиститьРеквизитМассово(Свойство) Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| ТЧ.Ссылка КАК Ссылка
|ИЗ
| Справочник.Номенклатура.ДополнительныеРеквизиты КАК ТЧ
|ГДЕ
| ТЧ.Свойство = &Свойство";
Запрос.УстановитьПараметр("Свойство", Свойство);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
НачатьТранзакцию();
Попытка
Объект = Выборка.Ссылка.ПолучитьОбъект();
Строки = Объект.ДополнительныеРеквизиты.НайтиСтроки(
Новый Структура("Свойство", Свойство));
Для Каждого Строка Из Строки Цикл
Объект.ДополнительныеРеквизиты.Удалить(Строка);
КонецЦикла;
Объект.Записать();
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ЗаписьЖурналаРегистрации("ОчисткаДопРеквизитов",
УровеньЖурналаРегистрации.Ошибка, , ,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецЦикла;
КонецПроцедуры
Запрос по табличной части сразу отбирает только те объекты, где свойство реально заполнено — это существенно быстрее, чем перебирать все элементы справочника. На больших объёмах добавьте паузу между пачками и запускайте обработку в нерабочее время: запись объектов может вызывать блокировки и срабатывание подписок на события.
- 1Сделайте резервную копию базы или выгрузку затрагиваемых объектов
- 2Найдите ссылку на свойство по имени в пределах нужного набора
- 3Отладьте код на одном тестовом объекте и проверьте результат в карточке
- 4Запустите массовую обработку с транзакциями и журналированием ошибок
- 5Проверьте запросом, что строк с этим свойством не осталось
Очистка дополнительных сведений через регистр
Для дополнительных сведений объект изменять не нужно — достаточно удалить записи регистра сведений ДополнительныеСведения. Это быстрее и безопаснее: не срабатывают обработчики записи объектов, не меняется дата изменения элемента, нет блокировок самих справочников и документов.
Процедура ОчиститьДопСведение(Свойство) Экспорт
НаборЗаписей = РегистрыСведений.ДополнительныеСведения.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Свойство.Установить(Свойство);
НаборЗаписей.Записать(); // запись пустого набора = удаление
КонецПроцедуры
Запись пустого набора с отбором удаляет все записи по этому свойству одной операцией. Если нужно очистить сведение только у конкретных объектов, добавьте отбор по измерению Объект или удаляйте записи в цикле по выборке. Учтите, что массовое удаление по отбору только по свойству затронет все объекты базы, где это свойство используется.
Обход записи объекта и обмен данными
Иногда запись объекта нежелательна: срабатывают бизнес-процессы, проверки заполнения, подписки на события. В таких случаях используют Объект.ОбменДанными.Загрузка = Истина перед записью. Это отключает проверки, но и отключает контроль целостности — применяйте режим осознанно и только для служебных чисток.
Объект.ОбменДанными.Загрузка = Истина;
Объект.Записать();
Обратный эффект: при установленном режиме загрузки изменения не регистрируются в планах обмена, и очищенные значения не уйдут в подчинённые базы. Если база распределённая, решите заранее: либо чистить во всех узлах отдельно, либо писать в штатном режиме, чтобы изменения уехали по обмену. Проверить регистрацию изменений можно через стандартную обработку «Регистрация изменений для обмена данными».
Сравнение вариантов записи
Срабатывают проверки, подписки и регистрация в планах обмена. Подходит для распределённых баз и когда важна история изменений. Медленнее на больших объёмах.
Быстро, без проверок и бизнес-логики, но без регистрации в обмене и без контроля целостности. Только для служебных чисток в однопользовательском режиме.
Только для дополнительных сведений. Самый быстрый вариант, объект не трогается вообще, но обмен данными также не регистрирует изменения без дополнительных действий.
Проверка результата и контрольные точки
После обработки выполните контрольный запрос: он должен вернуть ноль строк по очищаемому свойству. Проверяйте и табличную часть, и регистр сведений — если не уверены, где именно хранились данные.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| КОЛИЧЕСТВО(*) КАК Количество
|ИЗ
| Справочник.Номенклатура.ДополнительныеРеквизиты КАК ТЧ
|ГДЕ
| ТЧ.Свойство = &Свойство";
Дополнительно откройте вручную несколько карточек объектов, включая те, что раньше содержали очищенные значения. Убедитесь, что остальные дополнительные реквизиты на месте, а объект не «переехал» по дате изменения неожиданным образом. Если в базе работает полнотекстовый поиск, обновите индекс — старые значения могут находиться поиском до переиндексации.
Как проверить результат
Возвращает 0 строк по очищенному свойству
Остаются строки — часть объектов не обработана или свойство дублируется
Очищенный реквизит пуст, остальные реквизиты заполнены
Пропали другие реквизиты — задет чужой набор свойств
Нет ошибок записи за период обработки
Ошибки блокировок или проверок заполнения — часть объектов не записана
FAQ
Чем отличается очистка дополнительного реквизита от удаления самого свойства?
Очистка удаляет значения у объектов, но само свойство остаётся в настройках и может заполняться снова. Удаление (пометка на удаление) элемента плана видов характеристик убирает реквизит из интерфейса, но строки с ним в табличных частях физически остаются. Полное удаление — это сначала очистка данных, затем пометка свойства и штатное удаление помеченных объектов.
Почему после очистки реквизит всё равно виден в карточке объекта?
Если свойство входит в набор дополнительных реквизитов вида объекта, поле отображается в карточке всегда, просто пустое. Чтобы убрать его из формы, нужно исключить свойство из набора в разделе «Администрирование — Общие настройки — Дополнительные реквизиты».
Можно ли очистить реквизиты без программирования?
Да, частично. Типовая обработка «Групповое изменение реквизитов» позволяет массово установить значение дополнительного реквизита, включая пустое, у отобранных объектов. Она подходит для разовых операций, но не удаляет строки табличной части физически и не работает с помеченными на удаление свойствами.
Что делать, если свойство не находится по имени?
Откройте свойство в интерфейсе и посмотрите его точное имя в форме элемента или выгрузите список свойств запросом по заголовку. Имя формируется автоматически и может содержать суффиксы. Если свойство создано не через механизм БСП, а добавлено в конфигураторе как обычный реквизит, оно хранится иначе и очищается прямым присвоением.
Влияет ли очистка на права пользователей и RLS?
Сама очистка значений прав не меняет. Но если дополнительные реквизиты используются в настройках ограничения доступа на уровне записей или в шаблонах ограничений, после удаления значений часть объектов может стать недоступной пользователям или, наоборот, открыться. Перед чисткой проверьте, не задействовано ли свойство в профилях групп доступа.
Почему обработка работает медленно на большой базе?
Основные причины: запись каждого объекта со срабатыванием подписок, блокировки при параллельной работе пользователей, отсутствие отбора запросом только заполненных объектов. Ускорить можно выборкой по табличной части, пакетной обработкой с транзакциями, запуском в монопольном или нерабочем режиме и отключением полнотекстового поиска на время обработки.
Что важно запомнить
Дополнительные реквизиты очищаются удалением строк из табличной части объекта по отбору Свойство, дополнительные сведения — записью пустого набора в регистр ДополнительныеСведения. Перед массовой обработкой сделайте резервную копию, отладьте код на одном объекте и после завершения проверьте результат контрольным запросом и просмотром карточек.