Как установить признак проведения документа в 1С 7.7 без фактического перепроведения?

Программист 1С v7.7 1C:Бухгалтерия Бухгалтерский учет IT и автоматизация бизнеса
← На главную

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

Попытка решить проблему «в лоб» через стандартное перепроведение документов часто приводит к плачевным результатам. Алгоритмы проведения в базе-приемнике могут отличаться от базы-источника, из-за чего оригинальные проводки «плывут», заменяются неверными данными или вовсе задваиваются. Нам же необходимо сохранить проводки в том виде, в котором они были выгружены, но при этом заставить систему считать документ проведенным. Разберемся, как устроена эта механика на уровне базы данных 1С 7.7, и как решить эту задачу безопасно.

Физическая структура хранения проведения в 1С 7.7

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

Каждый документ в системе записывается в несколько таблиц базы данных:

  1. 1SJOURN (в SQL-версии — _1SJOURN) — общий журнал документов. Здесь хранится дата, время, номер, тип документа, а также статус его проведения.
  2. DH* — таблица шапки конкретного вида документа.
  3. DT* — таблица табличной части документа (если она есть).
  4. 1SENTRY — таблица бухгалтерских проводок (если в системе установлена компонента «Бухгалтерский учет»).
  5. RA* — таблицы движений по регистрам (если установлена компонента «Оперативный учет»).

Связующим звеном между всеми этими таблицами выступает уникальный девятисимвольный идентификатор документа — IDDOC.

За статус проведения документа отвечает числовое поле CLOSED в таблице 1SJOURN. Это поле представляет собой битовую маску, где каждый бит отвечает за свое состояние:

Складывая эти биты, платформа получает итоговое состояние документа. Рассмотрим типичные значения поля CLOSED:

Следовательно, наша задача — изменить значение поля CLOSED с 4 (или 0, если проводки были залиты отдельно) на 5 (для бухгалтерской базы) либо на 7 (для комплексной).

Решение 1. Прямой SQL-запрос через внешнюю компоненту 1С++

Если ваша база данных 1С 7.7 работает на Microsoft SQL Server, лучшим и самым быстрым решением будет использование прямого запроса к СУБД с помощью популярной компоненты 1С++. Это позволит мгновенно обновить статус проведения тысяч документов без их физической перезаписи.

Проанализируем пример кода на встроенном языке 1С 7.7:


// Создаем объект для работы с прямыми запросами
ЗапросSQL = СоздатьОбъект("ODBCRecordset");

// Формируем текст запроса для обновления поля CLOSED
// Устанавливаем значение 5 (проведен + есть проводки) для конкретного документа
ТекстЗапроса = "
|UPDATE _1SJOURN
|SET CLOSED = 5
|WHERE IDDOC = :ВыбДокумент
|";

// Подготавливаем параметр (передаем ссылку на документ)
ЗапросSQL.УстановитьТекстовыйПараметр("ВыбДокумент", ВыбранныйДокумент);

// Выполняем обновление в транзакции
ЗапросSQL.Выполнить(ТекстЗапроса);
Предупреждение("Статус проведения документа успешно изменен!");

Если вам нужно обновить сразу группу документов (например, за определенный период по конкретному виду документа), вы можете модернизировать запрос, добавив условия по дате (поле DATE_TIME_IDDOC) или по идентификатору вида документа (поле IDDOCDEF).

Решение 2. Модификация DBF-файла напрямую (для файловых баз)

Если база данных файловая (хранится в формате DBF/CDX), мы можем использовать стандартный встроенный объект 1С 7.7 XBase для работы с базой на физическом уровне.

Важное предупреждение: При редактировании файлов базы данных напрямую программным путем обязательно делайте резервную копию! Также критически важно открывать DBF-файл совместно с его индексным файлом CDX, иначе индексы «слетят», и база потребует полного переиндексирования.

Рассмотрим пошагово, как реализовать этот алгоритм:


Процедура ИзменитьФлагПроведенияВDBF(ВыбДок)
    // Получаем внутренний 9-значный IDDOC документа
    ВнутреннийID = ЗначениеВСтрокуВнутр(ВыбДок);
    // Извлекаем чистый IDDOC (9 символов начиная с 11-й позиции в системной строке)
    IDDOC = Сред(ВнутреннийID, 11, 9);
    
    ПутьКБазе = КаталогИБ();
    ФайлDBF = СоздатьОбъект("XBase");
    
    // Открываем таблицу журналов вместе с индексами
    ФайлDBF.ОткрытьФайл(ПутьКБазе + "1SJOURN.dbf", ПутьКБазе + "1SJOURN.cdx");
    
    Если ФайлDBF.Открыт() = 0 Тогда
        Сообщить("Не удалось открыть файл 1SJOURN.dbf!", "!");
        Возврат;
    КонецЕсли;
    
    // Устанавливаем индексный порядок по IDDOC для быстрого поиска
    ФайлDBF.ТекущийИндекс("IDDOC");
    
    // Ищем запись нашего документа
    Если ФайлDBF.Найти(IDDOC, 0) = 1 Тогда
        // Получаем текущее значение битовой маски
        ТекущееЗначение = ФайлDBF.CLOSED;
        
        // Проверяем, есть ли уже проводки (битовое значение 4)
        // Если флаг проведения (1) отсутствует, добавляем его
        Если (ТекущееЗначение % 2) = 0 Тогда
            НовоеЗначение = ТекущееЗначение + 1; // Устанавливаем бит проведения
            
            // Записываем новое значение в файл
            ФайлDBF.CLOSED = НовоеЗначение;
            ФайлDBF.Записать();
            Сообщить("Документ " + ВыбДок + " успешно помечен как проведенный!");
        Иначе
            Сообщить("Документ уже имеет признак проведения.");
        EndIf;
    Иначе
        Сообщить("Документ не найден в таблице 1SJOURN!", "!");
    КонецЕсли;
    
    // Обязательно закрываем файл для освобождения блокировок
    ФайлDBF.ЗакрытьФайл();
КонецПроцедуры

Решение 3. Обход через программный код проведения («Пустое проведение»)

Существует еще один изящный способ, не требующий прямого вмешательства в СУБД. Мы можем временно отключить генерацию движений в самом коде документа.

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


Процедура ОбработкаПроведения()
    // Если включен режим переноса данных, мы не формируем проводки заново
    Если ГлРежимПереносаБезПроведения = 1 Тогда
        // Просто выходим из процедуры. 
        // Платформа сама установит флаг проведения документу, 
        // но новые проводки генерироваться не будут.
        Возврат;
    КонецЕсли;

    // ... Здесь идет ваш стандартный код проведения документа ...
    // ВыбратьСтрокиДокумента();
    // Пока ПолучитьСтроку() = 1 Цикл
    //     Регистр.Продажи.Движение...
    // КонецЦикла;
КонецПроцедуры

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

Полезный совет: Как не перепутать «отключенные проводки»

В компоненте «Бухгалтерский учет» 1С 7.7 существует штатная фича — возможность отключения проводок у конкретной операции. Если вы откроете Журнал операций и нажмете клавишу F8 на клавиатуре (или выберете соответствующий пункт меню), проводки документа станут «выключенными».

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

← На главную