Как программно отредактировать или удалить записи в документе Корректировка записей регистров в УТ 10.3

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

Документ Корректировка записей регистров в конфигурации «Управление торговлей 10.3» (и других на базе обычных форм) является универсальным инструментом. Он не имеет привычных табличных частей для хранения данных, а выступает в роли «контейнера» или оболочки для движений по практически любым регистрам системы. В процессе эксплуатации, особенно после свертки базы, часто возникает необходимость программно «почистить» такие документы — например, удалить записи по неиспользуемым типам цен или обнулить остатки товаров, которые ошибочно попали в корректировку.

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

Понимание структуры документа

Прежде чем приступать к написанию кода, проанализируем ситуацию. У документа КорректировкаЗаписейРегистров нет реквизитов, в которых хранятся данные регистров. Вместо этого он напрямую управляет наборами записей. При открытии документа в интерфейсе система динамически считывает данные из регистров, по которым данный документ является регистратором, и выводит их на соответствующие закладки.

Существует два основных способа программного изменения данных в таком документе:

  1. Работа через объект документа: использование коллекции Движения.
  2. Прямая работа с наборами записей: создание объекта НаборЗаписей конкретного регистра с отбором по документу-регистратору.

Разберем каждый из этих способов подробнее.

Способ 1: Использование коллекции «Движения» объекта документа

Этот метод удобен, когда вы уже работаете с объектом документа (например, в процессе его создания или модификации других реквизитов). Проанализируем алгоритм действий:


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

// Выбираем конкретный регистр, который нужно отредактировать
НаборДвижений = ДокОбъект.Движения.ЦеныНоменклатуры;

// Читаем текущие движения из базы в память
НаборДвижений.Прочитать();

// Проходим циклом с конца, чтобы безопасно удалять строки
Индекс = НаборДвижений.Количество() - 1;
Пока Индекс >= 0 Цикл
    ТекущаяСтрока = НаборДвижений[Индекс];
    
    // Условие: например, удаляем записи с определенным типом цен
    Если ТекущаяСтрока.ТипЦен.ПометкаУдаления Тогда
        НаборДвижений.Удалить(Индекс);
    КонецЕсли;
    
    Индекс = Индекс - 1;
КонецЦикла;

// Устанавливаем флаг записи для коллекции
НаборДвижений.Записывать = Истина;

// Записываем сам документ, при этом запишутся и измененные движения
ДокОбъект.Записать();

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

Способ 2: Прямая работа с наборами записей (рекомендуемый)

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

Рассмотрим пример удаления записей из регистра сведений ЦеныНоменклатуры, где тип цены помечен на удаление:


// 1. Создаем набор записей для нужного регистра
НаборЗаписей = РегистрыСведений.ЦеныНоменклатуры.СоздатьНаборЗаписей();

// 2. Устанавливаем жесткий отбор по регистратору (нашему документу)
НаборЗаписей.Отбор.Регистратор.Установить(СсылкаНаДокумент);

// 3. Читаем данные
НаборЗаписей.Прочитать();

// 4. Выгружаем данные в Таблицу Значений для быстрой обработки
ТЗ = НаборЗаписей.Выгрузить();

// 5. Ищем строки, которые НЕ нужно удалять (оставляем валидные данные)
ПараметрыОтбора = Новый Структура;
// Здесь может быть сложная логика фильтрации через Запрос или перебор
// В данном примере просто удалим лишнее из ТЗ в цикле
КоллекцияДляУдаления = Новый Массив;

Для Каждого СтрокаТЗ Из ТЗ Цикл
    Если СтрокаТЗ.ТипЦен.ПометкаУдаления Тогда
        КоллекцияДляУдаления.Добавить(СтрокаТЗ);
    КонецЕсли;
КонецЦикла;

Для Каждого СтрокаДляУдаления Из КоллекцияДляУдаления Цикл
    ТЗ.Удалить(СтрокаДляУдаления);
КонецЦикла;

// 6. Очищаем набор, загружаем обновленную ТЗ и записываем
НаборЗаписей.Загрузить(ТЗ);
НаборЗаписей.Записать();

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

Работа со служебной таблицей «ТаблицаРегистров»

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

Если вы программно полностью удалили все записи из какого-то регистра (например, очистили ПартииТоваровНаСкладах), крайне желательно удалить соответствующую строку из ТаблицаРегистров объекта документа. Рассмотрим, как это сделать:


ОбъектДок = СсылкаНаДокумент.ПолучитьОбъект();
СтрокаРегистра = ОбъектДок.ТаблицаРегистров.Найти("ПартииТоваровНаСкладах", "Имя");
Если СтрокаРегистра <> Неопределено Тогда
    ОбъектДок.ТаблицаРегистров.Удалить(СтрокаРегистра);
    ОбъектДок.Записать();
КонецЕсли;

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

Особенности для регистров накопления (остатки товаров)

Если ваша задача — корректировка остатков товаров в организации (как описано в ситуации со сверткой), следует учитывать следующие моменты:

Массовая обработка данных: советы по оптимизации

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

  1. Используйте индексированные таблицы значений: Если вы фильтруете данные набора записей по сложному условию, выгрузите их в ТаблицаЗначений, добавьте индексы по ключевым полям поиска и только потом обрабатывайте.
  2. Минимизируйте количество вызовов Записать(): Группируйте изменения. Если вы меняете несколько регистров в одном документе, лучше сделать это через объект документа один раз.
  3. Транзакции: При массовом изменении наборов записей оборачивайте код в транзакцию (НачатьТранзакцию() / ЗафиксироватьТранзакцию()). Однако помните о блокировках: если база активно используется, делайте фиксацию транзакции каждые 10-50 документов.

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

← На главную