Почему не очищается запись регистра сведений Аналитика учета по партнерам и как это исправить

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

При работе с современными конфигурациями на базе 1С:ERP или 1С:Управление торговлей 11 (УТ 11) программисты часто сталкиваются с ситуацией, когда программное удаление записей из некоторых регистров сведений не дает результата. Запись либо не удаляется вовсе, либо появляется снова (дублируется) сразу после выполнения кода. Особенно часто это проявляется при попытке очистить регистр АналитикаУчетаПоПартнерам. Рассмотрим подробнее, почему это происходит и как правильно организовать процесс очистки.

Анализ проблемы: почему стандартные методы не работают

Проанализируем типичную ситуацию. Программист пытается удалить запись, используя МенеджерЗаписи или НаборЗаписей. Код выглядит корректно, условия Выбран() срабатывают, метод Удалить() или Записать() выполняется без ошибок, но при повторном запросе к базе данных запись оказывается на месте. Разберем основные причины такого поведения:

  1. Автоматическая генерация ключей аналитики. В УТ 11 регистр АналитикаУчетаПоПартнерам является служебным. Он хранит соответствие между набором измерений (Организация, Партнер, Контрагент и др.) и уникальным ссылочным ключом из справочника КлючиАналитикиУчетаПоПартнерам. Система спроектирована так, чтобы при любом обращении к аналитике (например, при записи документа или изменении связанных данных) проверять наличие записи в регистре и, если ее нет, создавать ее автоматически.
  2. Связь со справочником ключей. Записи в регистре жестко привязаны к элементам справочника КлючиАналитикиУчетаПоПартнерам. Если вы удаляете запись в регистре, но оставляете сам элемент в справочнике ключей, механизмы платформы или подписки на события могут восстановить запись в регистре для поддержания целостности данных.
  3. Замена ссылок. Если задача выполняется в рамках обработки по поиску и замене дублей, то замена партнера в самом ключе аналитики инициирует перезапись этого ключа. В момент записи ключа срабатывает внутренняя логика конфигурации, которая «прописывает» этот ключ в регистр сведений по актуальным измерениям.

Метод 1. Использование Набора Записей для удаления

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


НаборДанных = РегистрыСведений.АналитикаУчетаПоПартнерам.СоздатьНаборЗаписей();
НаборДанных.Отбор.Партнер.Установить(Элем.Партнер);
НаборДанных.Отбор.Организация.Установить(Элем.Организация);
// Устанавливаем все остальные измерения, если они известны
НаборДанных.ОбменДанными.Загрузка = Истина;
НаборДанных.Записать();

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

Метод 2. Удаление через Менеджер Записи

Рассмотрим вариант использования МенеджерЗаписи. Этот метод удобен, когда нужно работать ровно с одной строкой регистра, зная все ее измерения. Выясним причину, по которой МенеджерЗаписи.Прочитать() может не находить запись: чаще всего это происходит из-за неполного заполнения измерений или несовпадения типов данных в измерениях.


МенеджерЗаписи = РегистрыСведений.АналитикаУчетаПоПартнерам.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Партнер = СсылкаНаПартнера;
МенеджерЗаписи.Организация = СсылкаНаОрганизацию;
МенеджерЗаписи.Контрагент = СсылкаНаКонтрагента;
// Обязательно заполняем все измерения регистра
МенеджерЗаписи.Прочитать();
Если МенеджерЗаписи.Выбран() Тогда
    МенеджерЗаписи.Удалить();
КонецЕсли;

Если после этого кода запись остается, значит, она пересоздается. Проанализируем ситуацию дальше.

Выясняем причину появления дублей через Стек вызовов

Когда запись «возвращается» или двоится, необходимо понять, какой именно кусок кода ее создает. Для этого рекомендуется использовать следующий алгоритм отладки:

  1. Установим точку останова в модуле менеджера или модуле набора записей регистра АналитикаУчетаПоПартнерам в процедуре ПередЗаписью или ПриЗаписи.
  2. Запустим процесс удаления или замены ссылок.
  3. Когда программа остановится на точке останова, откроем окно Стек вызовов.
  4. Посмотрим, из какой функции или подписки на событие пришел вызов.

Как правило, выясняется, что запись инициируется методом Записать() одного из элементов справочника КлючиАналитикиУчетаПоПартнерам или при выполнении стандартных процедур замены ссылок. В УТ 11 механизмы ведения аналитики работают очень активно, и любая манипуляция с объектами-владельцами (Партнер, Договор) может привести к обновлению аналитических регистров.

Правильный алгоритм очистки аналитики

Для того чтобы очистка была успешной и окончательной, разберем по шагам правильную последовательность действий:

  1. Замена ссылок в первичных объектах. Сначала выполняем замену ссылок во всех документах и справочниках (кроме ключей аналитики).
  2. Работа со справочником ключей. Не стоит пытаться вручную «подправлять» регистр аналитики. Вместо этого нужно найти неиспользуемые ключи в справочнике КлючиАналитикиУчетаПоПартнерам. Если ключ больше не нужен (его владелец-партнер помечен на удаление или заменен), следует удалять сам элемент справочника.
  3. Использование ведущих измерений. В регистре АналитикаУчетаПоПартнерам измерение Партнер обычно является Ведущим. Это означает, что при удалении объекта «Партнер» из базы данных, все записи в этом регистре, связанные с ним, будут удалены платформой автоматически. Попытка удалять записи регистра при живом объекте-владельце часто бессмысленна.
  4. Финальное удаление объектов. После замены ссылок необходимо запустить стандартную обработку Удаление помеченных объектов. Она корректно обработает связи, проверит наличие ссылок и удалит ключи аналитики вместе с записями регистров.

Пример комплексной очистки

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


// Создаем набор записей с фильтром по партнеру
Набор = РегистрыСведений.АналитикаУчетаПоПартнерам.СоздатьНаборЗаписей();
Набор.Отбор.Партнер.Установить(СтарыйПартнер);

// Очищаем набор и записываем изменения с отключением бизнес-логики
Набор.ОбменДанными.Загрузка = Истина;
Набор.Записать();

// Если записи восстанавливаются, значит нужно найти и пометить на удаление 
// соответствующие ключи аналитики
Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
|	Ключи.Ссылка КАК Ссылка
|ИЗ
|	Справочник.КлючиАналитикиУчетаПоПартнерам КАК Ключи
|ГДЕ
|	Ключи.Партнер = &Партнер";
Запрос.УстановитьПараметр("Партнер", СтарыйПартнер);

Результат = Запрос.Выполнить().Выбрать();
Пока Результат.Следующий() Цикл
    ОбъектКлюч = Результат.Ссылка.ПолучитьОбъект();
    ОбъектКлюч.УстановитьПометкуУдаления(Истина);
КонецЦикла;

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

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

← На главную