Как удалить движения у непроведенных документов и устранить ошибки структуры данных в 1С 7.7 SQL?

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

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

Причины возникновения ошибок памяти и расхождения метаданных

Проанализируем механику работы платформы 1С 7.7 на MS SQL Server, чтобы понять истоки проблемы:

  1. Ограничение 32-разрядной адресации памяти: Исполняемый файл платформы 1cv7s.exe является 32-битным приложением. В архитектуре Windows одному такому процессу доступно не более 2 Гб виртуального адресного пространства, независимо от того, сколько физической оперативной памяти установлено на сервере (даже если там 12 Гб или больше). Во время проверки служебных данных ТиИ строит в оперативной памяти графы ссылочной целостности. При сотнях тысяч «висячих» записей движений лимит в 2 Гб мгновенно исчерпывается.
  2. Механизм фиксации движений в журнале: В таблице общего журнала _1SJOURN состояние документа определяется полем CLOSED (младший бит CLOSED & 1 = 1 означает проведенность), а также колонками RF<ID_Регистра>, в которых хранятся флаги формирования движений по конкретным регистрам. Если снять признак проведения, но оставить строки в таблицах движений (RA...), платформа фиксирует логическое нарушение целостности данных.
  3. Несоответствие словаря данных DDS и таблиц SQL: Ошибка «Нарушена структура таблицы SC...» возникает, когда состав колонок или их типы в MS SQL Server не совпадают с описанием в файле словаря 1Cv7.DDS (например, если файл 1Cv7.MD обновлялся простой подменой без корректного сохранения в Конфигураторе). При попытке штатной реструктуризации платформа может полностью очистить проблемный справочник.

Удаление зависших движений прямыми запросами через 1С++

Рассмотрим наиболее быстрый способ очистки движений у непроведенных и помеченных на удаление документов. Использование штатных методов СделатьНепроведенным() или Удалить() на базах большого объема занимает десятки часов. Для выполнения очистки напрямую в СУБД применим компоненту 1С++ и объект ODBCRecordset.

Разберем готовый алгоритм обхода всех регистров конфигурации и удаления записей движений, принадлежащих непроведенным документам:


вРекордСет = СоздатьОбъект("ODBCRecordset");
Состояние("Начинаем чистку регистров у непроведенных документов...");

Для СЦ = 1 По Метаданные.Регистр() Цикл
    вМетаРегистр = Метаданные.Регистр(СЦ);
    вИдент = вМетаРегистр.Идентификатор;
    
    ТекстЗапроса = "
    |DELETE FROM $Регистр." + вИдент + " 
    |WHERE IDDOC IN (
    |    SELECT 
    |        рег.IDDOC
    |    FROM 
    |        $Регистр." + вИдент + " as рег (NOLOCK)
    |        INNER JOIN _1SJourn as жОбщий (NOLOCK) ON рег.IDDOC = жОбщий.IDDOC
    |    WHERE
    |        жОбщий.CLOSED & 1 = 0
    |    GROUP BY
    |        рег.IDDOC
    |)
    |";
    
    Попытка
        вРекордСет.ВыполнитьИнструкцию(ТекстЗапроса);
    Исключение
        Сообщить("Ошибка при очистке регистра " + вИдент + ": " + ОписаниеОшибки());
    КонецПопытки;
КонецЦикла;
Сообщить("Очистка движений непроведенных документов успешно завершена.");

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


вРекордСет = СоздатьОбъект("ODBCRecordset");
вРекордСет.УстановитьТекстовыйПараметр("ВыбДата", ДатаСвертки);

Для СЦ = 1 По Метаданные.Регистр() Цикл
    вМетаРег = Метаданные.Регистр(СЦ);
    вИдент = вМетаРег.Идентификатор;
    
    ТекстЗапроса = "
    |DELETE FROM $Регистр." + вИдент + " 
    |WHERE IDDOC IN (
    |    SELECT 
    |        жОбщий.IDDOC
    |    FROM
    |        _1SJourn as жОбщий (NOLOCK)
    |    WHERE 
    |        жОбщий.DATE_TIME_IDDOC <= :ВыбДата~
    |)
    |";
    
    Попытка
        вРекордСет.ВыполнитьИнструкцию(ТекстЗапроса);
    Исключение
        Сообщить("Ошибка обработки регистра " + вИдент + ": " + ОписаниеОшибки());
    КонецПопытки;
КонецЦикла;

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


Для СЦ = 1 По Метаданные.Регистр() Цикл
    вИдент = Метаданные.Регистр(СЦ).Идентификатор;
    ТекстСбросаФлагов = "
    |UPDATE _1SJourn 
    |SET $ФлагРегистра." + вИдент + " = 0 
    |WHERE CLOSED & 1 = 0
    |";
    вРекордСет.ВыполнитьИнструкцию(ТекстСбросаФлагов);
КонецЦикла;

Исправление структуры таблиц справочников без потери данных

Когда при запуске базы или загрузке копии возникает ошибка «Нарушена структура таблицы SC496» (или SC597), ни в коем случае нельзя выполнять реструктуризацию через стандартное сохранение конфигурации, так как 1С просто пересоздаст таблицу заново и сотрет все записи.

Разберем по шагам правильный алгоритм синхронизации структуры базы данных с метаданными:

  1. Открываем файл описания структуры 1Cv7.DDS в текстовом редакторе (он находится в каталоге базы данных).
  2. Находим секцию проблемной таблицы, например Table SC496. Изучаем перечень полей, их типы (CHAR, NUMERIC, DATETIME) и длину.
  3. В среде управления MS SQL Server (Query Analyzer или Management Studio) выполняем команду анализа фактической таблицы: EXEC sp_help 'SC496';
  4. Сравниваем реальные колонки таблицы SQL со списком из 1Cv7.DDS. Выясняем, каких колонок не хватает или где не совпадают типы данных.
  5. Прямыми командами SQL приводим структуру к эталону. Например, если в таблице базы отсутствует колонка реквизита, добавляем ее командой: ALTER TABLE SC496 ADD SP497 CHAR(9) NOT NULL DEFAULT ' 0 '; Если же в таблице SQL остались устаревшие колонки, которых больше нет в конфигурации, аккуратно удаляем их: ALTER TABLE SC496 DROP COLUMN SP999;
  6. После того как состав полей в SQL станет полностью идентичен описанию в 1Cv7.DDS, база запустится в штатном режиме без потери информации в справочниках.

Обход ошибки «Недостаточно свободной памяти» и корректный пересчет итогов

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

  1. Расширение адресного пространства (4GB Patch): Для исполняемого файла 1cv7s.exe можно включить поддержку флага LARGEADDRESSAWARE. Это делается консольной утилитой editbin /LARGEADDRESSAWARE 1cv7s.exe. На 64-битной операционной системе сервер выделит процессу 1С до 4 Гб виртуальной памяти вместо стандартных 2 Гб, что исключит аварийный сбой при длительных проверках.
  2. Раздельный запуск процедур ТиИ: Не запускайте тестирование со всеми отмеченными пунктами сразу. Выполняйте их строго по очереди:
    • Сначала «Реиндексация».
    • Затем «Проверка физической целостности».
    • «Пересчет итогов» (при этом снимите флажок «Проверка служебных данных», так как именно он переполняет память анализом связей).
  3. Отказ от встроенной выгрузки: Ошибка «Ошибка чтения из архива» при выгрузке базы через Конфигуратор вызвана тем, что встроенный архиватор не умеет работать с архивами и файлами таблиц объемом более 2 Гб. Все резервные копии и переносы баз SQL-версии 7.7 следует выполнять исключительно средствами MS SQL Server (создание бэкапа и восстановление через файлы .BAK).

Используя прямой доступ к данным через ODBCRecordset и ручную синхронизацию структуры таблиц с файлом 1Cv7.DDS, можно гарантированно очистить информационную базу от ошибочных движений и восстановить ее работоспособность без потерь критически важных справочников.

← На главную