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

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

Как программно очистить дополнительные реквизиты в 1С

Как программно очистить дополнительные реквизиты в 1С: работа с табличной частью ДополнительныеРеквизиты, хранилищем значений, обходом справочников и документов. Примеры кода и проверка результата.

Дополнительные реквизиты в конфигурациях на базе БСП (Библиотека стандартных подсистем) хранятся не в отдельных колонках таблиц, а в служебной табличной части объекта с именем ДополнительныеРеквизиты. Поэтому «очистить реквизит» через присвоение пустого значения полю объекта не получится — нужно работать именно с этой табличной частью: удалять строки или очищать значения в них.

Задача возникает в типовых сценариях: массовая чистка данных перед свёрткой базы, удаление ошибочно загруженных свойств после обмена, сброс значений устаревшего реквизита, который вывели из использования. Во всех случаях логика одна — найти в табличной части строки, связанные с нужным свойством из плана видов характеристик ДополнительныеРеквизитыИСведения, и обработать их.

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

Где физически хранятся дополнительные реквизиты

В конфигурациях с БСП (Управление торговлей, ERP, Комплексная автоматизация, ЗУП и другие) объекты, поддерживающие дополнительные реквизиты, содержат табличную часть ДополнительныеРеквизиты с ключевыми колонками: Свойство (ссылка на ПВХ ДополнительныеРеквизитыИСведения) и Значение. Для нестроковых типов значение хранится в колонке Значение, для длинных строк — в колонке ТекстоваяСтрока.

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

Как получить ссылку на очищаемое свойство

Прежде чем чистить данные, нужно однозначно определить свойство. Надёжнее всего искать его по имени или заголовку в пределах конкретного набора свойств объекта, потому что одноимённые свойства могут существовать у разных наборов (например, у «Номенклатуры» и «Контрагентов»).

Функция НайтиСвойство(ИмяСвойства)

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ ПЕРВЫЕ 1

| Свойства.Ссылка КАК Свойство

|ИЗ

| ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения КАК Свойства

|ГДЕ

| Свойства.Имя = &Имя

| И НЕ Свойства.ПометкаУдаления";

Запрос.УстановитьПараметр("Имя", ИмяСвойства);

Выборка = Запрос.Выполнить().Выбрать();

Если Выборка.Следующий() Тогда

Возврат Выборка.Свойство;

Иначе

Возврат Неопределено;

КонецЕсли;

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

Поле Имя у свойства формируется автоматически и не всегда совпадает с видимым заголовком. Если имя неизвестно, ищите по Заголовок, но учитывайте, что заголовки могут дублироваться — тогда добавьте отбор по набору свойств через табличную часть набора ДополнительныеРеквизиты справочника НаборыДополнительныхРеквизитовИСведений.

Очистка реквизитов в одном объекте

Для разовой обработки одного элемента справочника или документа достаточно получить объект, найти строки табличной части и удалить их. Удалять нужно в цикле с конца или через массив найденных строк — удаление по индексу в прямом цикле пропускает элементы.

Процедура ОчиститьРеквизитОбъекта(СсылкаНаОбъект, Свойство) Экспорт

Объект = СсылкаНаОбъект.ПолучитьОбъект();

НайденныеСтроки = Объект.ДополнительныеРеквизиты.НайтиСтроки(

Новый Структура("Свойство", Свойство));

Для Каждого Строка Из НайденныеСтроки Цикл

Объект.ДополнительныеРеквизиты.Удалить(Строка);

КонецЦикла;

Объект.Записать();

КонецПроцедуры

Если нужно не удалить строку, а только сбросить значение (например, чтобы строка осталась для журнала изменений), замените удаление на присвоение: Строка.Значение = Неопределено; и очистку Строка.ТекстоваяСтрока = "";. Однако пустые строки в табличной части — плохая практика: типовые механизмы БСП при записи объекта сами удаляют строки с незаполненными значениями, поэтому надёжнее удалять строку целиком.

Типичные ошибки
01
Удаление строк табличной части по индексу в прямом цикле — после каждого удаления индексы сдвигаются, часть строк пропускается. Используйте НайтиСтроки() и удаляйте по ссылкам на строки.
02
Очистка только колонки Значение без колонки ТекстоваяСтрока — для многострочных свойств текст остаётся и отображается в карточке объекта.
03
Поиск свойства по заголовку без учёта набора — очищается чужой одноимённый реквизит другого вида объектов.

Массовая очистка по всем объектам вида

Когда очистить реквизит нужно у всех элементов справочника или всех документов вида, обход делается через выборку ссылок запросом. Ключевые правила: обрабатывать объекты порциями, записывать в транзакции с разумным размером пачки и не использовать Записать() без необходимости в режиме обмена данными, если нужно зафиксировать изменения в планах обмена.

Процедура ОчиститьРеквизитМассово(Свойство) Экспорт

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ РАЗЛИЧНЫЕ

| ТЧ.Ссылка КАК Ссылка

|ИЗ

| Справочник.Номенклатура.ДополнительныеРеквизиты КАК ТЧ

|ГДЕ

| ТЧ.Свойство = &Свойство";

Запрос.УстановитьПараметр("Свойство", Свойство);

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

НачатьТранзакцию();

Попытка

Объект = Выборка.Ссылка.ПолучитьОбъект();

Строки = Объект.ДополнительныеРеквизиты.НайтиСтроки(

Новый Структура("Свойство", Свойство));

Для Каждого Строка Из Строки Цикл

Объект.ДополнительныеРеквизиты.Удалить(Строка);

КонецЦикла;

Объект.Записать();

ЗафиксироватьТранзакцию();

Исключение

ОтменитьТранзакцию();

ЗаписьЖурналаРегистрации("ОчисткаДопРеквизитов",

УровеньЖурналаРегистрации.Ошибка, , ,

ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));

КонецПопытки;

КонецЦикла;

КонецПроцедуры

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

Порядок действий при массовой очистке
  1. 1
    Сделайте резервную копию базы или выгрузку затрагиваемых объектов
  2. 2
    Найдите ссылку на свойство по имени в пределах нужного набора
  3. 3
    Отладьте код на одном тестовом объекте и проверьте результат в карточке
  4. 4
    Запустите массовую обработку с транзакциями и журналированием ошибок
  5. 5
    Проверьте запросом, что строк с этим свойством не осталось

Очистка дополнительных сведений через регистр

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

Процедура ОчиститьДопСведение(Свойство) Экспорт

НаборЗаписей = РегистрыСведений.ДополнительныеСведения.СоздатьНаборЗаписей();

НаборЗаписей.Отбор.Свойство.Установить(Свойство);

НаборЗаписей.Записать(); // запись пустого набора = удаление

КонецПроцедуры

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

Обход записи объекта и обмен данными

Иногда запись объекта нежелательна: срабатывают бизнес-процессы, проверки заполнения, подписки на события. В таких случаях используют Объект.ОбменДанными.Загрузка = Истина перед записью. Это отключает проверки, но и отключает контроль целостности — применяйте режим осознанно и только для служебных чисток.

Объект.ОбменДанными.Загрузка = Истина;

Объект.Записать();

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

Сравнение вариантов записи

Штатная запись (Записать)

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

ОбменДанными.Загрузка = Истина

Быстро, без проверок и бизнес-логики, но без регистрации в обмене и без контроля целостности. Только для служебных чисток в однопользовательском режиме.

Прямое удаление из регистра сведений

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

Проверка результата и контрольные точки

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

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| КОЛИЧЕСТВО(*) КАК Количество

|ИЗ

| Справочник.Номенклатура.ДополнительныеРеквизиты КАК ТЧ

|ГДЕ

| ТЧ.Свойство = &Свойство";

Дополнительно откройте вручную несколько карточек объектов, включая те, что раньше содержали очищенные значения. Убедитесь, что остальные дополнительные реквизиты на месте, а объект не «переехал» по дате изменения неожиданным образом. Если в базе работает полнотекстовый поиск, обновите индекс — старые значения могут находиться поиском до переиндексации.

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

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

Контрольный запрос по табличной части
Норма

Возвращает 0 строк по очищенному свойству

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

Остаются строки — часть объектов не обработана или свойство дублируется

Карточка объекта в интерфейсе
Норма

Очищенный реквизит пуст, остальные реквизиты заполнены

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

Пропали другие реквизиты — задет чужой набор свойств

Журнал регистрации
Норма

Нет ошибок записи за период обработки

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

Ошибки блокировок или проверок заполнения — часть объектов не записана

FAQ

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

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

Почему после очистки реквизит всё равно виден в карточке объекта?

Если свойство входит в набор дополнительных реквизитов вида объекта, поле отображается в карточке всегда, просто пустое. Чтобы убрать его из формы, нужно исключить свойство из набора в разделе «Администрирование — Общие настройки — Дополнительные реквизиты».

Можно ли очистить реквизиты без программирования?

Да, частично. Типовая обработка «Групповое изменение реквизитов» позволяет массово установить значение дополнительного реквизита, включая пустое, у отобранных объектов. Она подходит для разовых операций, но не удаляет строки табличной части физически и не работает с помеченными на удаление свойствами.

Что делать, если свойство не находится по имени?

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

Влияет ли очистка на права пользователей и RLS?

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

Почему обработка работает медленно на большой базе?

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

Итог

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

Дополнительные реквизиты очищаются удалением строк из табличной части объекта по отбору Свойство, дополнительные сведения — записью пустого набора в регистр ДополнительныеСведения. Перед массовой обработкой сделайте резервную копию, отладьте код на одном объекте и после завершения проверьте результат контрольным запросом и просмотром карточек.