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

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

В практике разработчика и администратора 1С часто возникают ситуации, когда необходимо изменить определенное значение (реквизит) в уже проведенных документах, а также во всех связанных с ними движениях по регистрам. При этом критически важно избежать штатного перепроведения документа. Это может быть связано с тем, что период уже закрыт для редактирования, или алгоритмы проведения настолько сложны и изменчивы, что повторное проведение может привести к непредсказуемому изменению итогов. Разберем подробно, какими инструментами и методами можно решить эту задачу.

Различие между изменением реквизитов и изменением движений

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

Способ 1: Использование стандартной обработки «Поиск и замена значений»

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

  1. Программа ищет все упоминания старой ссылки во всех таблицах базы данных (включая шапки документов, табличные части и, что самое важное, наборы записей всех регистров).
  2. Выполняется прямая замена старой ссылки на новую.
  3. Запись объектов происходит "тихо", без вызова процедуры ОбработкаПроведения.

Важно: Этот метод подходит только для замены ссылочных типов (справочники, документы). Если вам нужно поменять текстовую строку или число, этот метод не сработает.

Способ 2: Программный метод через наборы записей

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

Посмотрим на пример кода, который меняет значение в движениях конкретного документа:


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

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

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

// Устанавливаем признак обмена данными, чтобы обойти проверки
НаборЗаписей.ОбменДанными.Загрузка = Истина;

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

В данном примере использование Записать(Истина) с предварительным отбором по регистратору гарантирует, что мы перезапишем только движения конкретного документа. Установка свойства ОбменДанными.Загрузка = Истина позволяет избежать выполнения подписок на события, которые могут быть привязаны к записи набора записей.

Способ 3: Функция БСП «ОбщегоНазначения.ЗаменитьСсылки»

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

Эта функция позволяет передать массив пар "что заменить" и "на что заменить". Ключевым параметром здесь является возможность отключить бизнес-логику. Выясним, как это выглядит в коде:


ПарыЗамен = Новый Массив;
Замена = Новый Структура("ЧтоЗаменить, НаЧтоЗаменить", СсылкаСтарая, СсылкаНовая);
ПарыЗамен.Добавить(Замена);

Параметры = ОбщегоНазначения.ПараметрыЗаменыСсылок();
Параметры.ВключатьБизнесЛогику = Ложь; // Это отключает проведение и проверки

ОбщегоНазначения.ЗаменитьСсылки(ПарыЗамен, Параметры);

Главный недостаток этого метода — он работает "коврово" по всей базе. Если вам нужно заменить значения только в конкретном типе документов или за определенный период, придется предварительно отобрать ссылки или использовать другие методы.

Способ 4: Инструменты разработчика (авторства Сергея Старых)

Для продвинутых пользователей и разработчиков существует незаменимый пакет "Инструменты разработчика". В его составе есть обработка Подбор и обработка объектов БД, а также специализированный Редактор наборов записей. Рассмотрим их преимущества:

Риски и важные рекомендации

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

Поэтому мы рекомендуем придерживаться следующего правила:

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

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

← На главную