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

Программист 1С v7.7 Управленческий учет Торговля и дистрибуция
← На главную

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

Понимание механизма проведения в 1С 7.7

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


Процедура ПроведениеПоРегистрам()
    // ...
    // Удаление движений по регистрам.
    Для Номер = 1 По Метаданные.Регистр() Цикл
        ОчиститьДвижения("Регистр." + Метаданные.Регистр(Номер).Идентификатор);
    КонецЦикла;
    // ...
КонецПроцедуры

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

Способ 1: Использование дополнительного параметра в методе Провести()

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

Рассмотрим по шагам реализацию этого метода:

  1. В процедуре ОбработкаПроведения добавим прием параметра.
  2. Опишем логику, которая будет проверять значение этого параметра.
  3. Модифицируем блок удаления движений и блок записи новых движений.

Пример модифицированного кода в модуле документа:


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

Теперь из внешней обработки мы можем вызвать перепроведение именно в этом режиме:


Док = СоздатьОбъект("Документ.Реализация");
Если Док.НайтиДокумент(НужныйДокумент) = 1 Тогда
    Док.Провести(0, "ТолькоВзаиморасчеты");
КонецЕсли;

Способ 2: Временная подмена программного кода

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

  1. Открываем конфигуратор и находим модуль нужного документа.
  2. В процедуре ОбработкаПроведения временно комментируем вызовы процедур, отвечающих за формирование движений по регистрам товаров (например, регистр ОстаткиТМЦ или ПартииНаличие).
  3. Также комментируем строки с ОчиститьДвижения() именно для этих «неприкосновенных» регистров.
  4. Сохраняем конфигурацию, запускаем предприятие и перепроводим нужные документы.
  5. После завершения операции возвращаем код в исходное состояние.

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

Способ 3: Использование внешних компонент и прямых запросов (SQL)

Если ваша база работает на MS SQL Server, можно воспользоваться возможностями внешней компоненты 1С++. Этот путь предназначен для опытных разработчиков, так как он подразумевает прямую работу с таблицами базы данных, минуя объектную модель 1С.

Выясним причину, почему это эффективно: при обычном проведении 1С выполняет множество проверок, блокировок и транзакций. Прямой SQL-запрос UPDATE к таблице движений регистра (таблицы вида RA*) позволяет изменить суммы или аналитику во взаиморасчетах мгновенно. Однако помните о необходимости последующего пересчета итогов (таблицы RG*), так как 1С 7.7 хранит остатки отдельно от движений.

Риски и технические нюансы

Проанализируем ситуацию с последовательностями. В 1С 7.7 любое перепроведение документа, даже частичное, может сдвинуть границу последовательности назад. Если вы изменили движения только по взаиморасчетам, но документ входит в последовательность «ПартионныйУчет», система пометит, что с этого момента последовательность не актуальна.

Чтобы избежать этой проблемы при массовом исправлении долгов, часто используют следующий алгоритм:

  1. Запоминаем текущее значение границы последовательности.
  2. Выполняем выборочное перепроведение документов программно.
  3. Программно устанавливаем границу последовательности обратно на исходное время через объект Последовательность.

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


Посл = Последовательность.ОсновнаяПоследовательность;
Посл.Установить(ДатаГраницы, ДокГраницы);

Резюме

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

← На главную