Как изменить значения в движениях документов без их перепроведения в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

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

Особенности платформенной модели работы с движениями

Для понимания архитектуры работы с регистрами выделим ключевые платформенные ограничения:

  1. Невозможность изолированного изменения одной строки: В регистрах, подчиненных регистратору (регистры накопления, бухгалтерии, а также подчиненные регистры сведений), нельзя обновить одну запись запросом или точечным методом. Любое движение принадлежит регистратору. Модификация выполняется исключительно целиком для конкретного регистратора через объект НаборЗаписей.
  2. Пересчет итогов и нагрузка на СУБД: При выполнении метода Записать() у набора записей платформой выполняется автоматический пересчет агрегатов и таблиц итогов на дату документа. Массовая перезапись движений в цикле создает существенную нагрузку на сервер баз данных и приводит к блокировкам.
  3. Обход прикладных проверок: Чтобы при записи набора не срабатывали типовые модули контроля остатков и обработчики событий конфигурации (ПередЗаписью, ПриЗаписи), необходимо использовать свойство ОбменДанными.Загрузка = Истина. При этом платформенный пересчет итогов СУБД продолжает выполняться в штатном режиме.

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

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

Посмотрим на пример кода для изменения склада в регистре накопления:


// Определим исходные параметры замены
СтарыйСклад = Справочники.Склады.НайтиПоНаименованию("Склад А");
НовыйСклад  = Справочники.Склады.НайтиПоНаименованию("Склад Б");

// 1. Получим список регистраторов, где в движениях фигурирует старый склад
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ РАЗЛИЧНЫЕ
    |	Регистр.Регистратор КАК Регистратор
    |ИЗ
    |	РегистрНакопления.ТоварыНаСкладах КАК Регистр
    |ГДЕ
    |	Регистр.Склад = &СтарыйСклад";

Запрос.УстановитьПараметр("СтарыйСклад", СтарыйСклад);
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();

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

КонецЦикла;

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

Универсальный обход регистров по метаданным

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

Посмотрим на пример поиска регистров, содержащих ссылку нужного типа:


ТипСклад = Новый ОписаниеТипов("СправочникСсылка.Склады");

Для Каждого МетаРегистр Из Метаданные.РегистрыНакопления Цикл
    ЕстьИзмерение = Ложь;
    Для Каждого Измерение Из МетаРегистр.Измерения Цикл
        Если Измерение.Тип.СодержитТип(ТипЗнч(СтарыйСклад)) Тогда
            ЕстьИзмерение = Истина;
            Прервать;
        КонецЕсли;
    КонецЦикла;
    
    Если ЕстьИзмерение Тогда
        // Формируем динамический запрос и обрабатываем наборы аналогично базовому алгоритму
    КонецЕсли;
КонецЦикла;

Риски прямой модификации движений и альтернативные решения

Применяя прямую перезапись наборов записей в обход документов, проанализируем критические риски, с которыми столкнется информационная база:

  1. Стирание правок при перепроведении: В самих документах реквизиты остаются прежними. Если пользователь случайно или регламентно (при закрытии месяца, восстановлении последовательности или отмене проведения) перепроведет документ, платформа сотрет отредактированные наборы и заново запишет старый склад из табличных частей документа.
  2. Разрывы партий и отрицательные остатки: Изменение склада в движениях без учета всей цепочки товародвижения может привести к тому, что расходные движения по новому складу окажутся раньше по времени, чем поступления. Это приведет к возникновению отрицательных остатков и зависанию стоимостных сумм на старом складе.
  3. Нарушение регламентных расчетов: В базах с партионным учетом или механизмом распределения затрат прямое вмешательство в движения искажает алгоритмы расчета себестоимости.
  4. Даты запрета изменения: Попытка записи набора в закрытом периоде может заблокироваться механизмом даты запрета загрузки данных либо исказить уже сданную налоговую и бухгалтерскую отчетность.

Альтернативный безопасный вариант: Чтобы исключить риск рассинхронизации данных и сохранить аудиторский след, рекомендуется использовать типовой документ «Корректировка регистров» на границу открытого периода. В нем формируются сторнирующие записи по старому складу и приходующие записи по новому складу. Это гарантирует сохранение исторической достоверности учета и защищает систему от ошибок при случайных перепроведениях прошлых документов.

← На главную