Проблема нарушения хронологического порядка в общем (полном) журнале документов — это классическая «болезнь» платформы 1С:Предприятие 7.7, которую часто называют «клюшками». Ситуация, когда документ с более поздней датой оказывается выше документа с более ранней, может поставить в тупик даже опытного администратора. Особенно остро это проявляется в распределенных информационных базах (РИБ). Разберем детально, почему это происходит и как вернуть документы в правильное положение.
Для начала проанализируем, как система 1С 7.7 физически хранит информацию о порядке документов. Вся информация для общих журналов хранится в системной таблице 1SJOURN. Ключевым полем, отвечающим за сортировку, является DATE_TIME_IDDOC. Это составной индекс, который формируется из трех компонентов:
Если визуальный порядок нарушен, значит, значение в поле DATE_TIME_IDDOC не соответствует реальным данным в колонках «Дата» и «Время». Это может произойти из-за сбоя при записи документа, некорректной работы компонент РИБ или прямого вмешательства в базу данных внешними средствами.
Выясним одну из самых распространенных причин — наличие документов с некорректной датой. Платформа 7.7 крайне чувствительна к документам, у которых дата не заполнена или имеет значение «00.00.0000». Рассмотрим, как это влияет на систему: такие записи могут «сбивать» движок базы данных, заставляя его неверно интерпретировать границы индексных страниц.
Также стоит проверить периодические реквизиты. Если в системе есть периодические константы или реквизиты справочников с пустой датой, это может косвенно влиять на работу общих механизмов запросов к БД, хотя основная причина обычно кроется именно в 1SJOURN.
В условиях РИБ документы создаются в разных узлах. Каждый узел имеет свой префикс ID. Когда документы мигрируют в «дочку» или «центр», они выстраиваются внутри одной секунды согласно своим внутренним идентификаторам IDDOC. Если в разных узлах время было рассинхронизировано (хотя бы на секунду), или если документы создавались программно без явного указания времени, их порядок может показаться случайным.
Проанализируем ситуацию: если два документа имеют идентичную дату и время до секунды, их взаимное расположение определяется исключительно алфавитным порядком их IDDOC. В РИБ это часто приводит к тому, что документы «перемешиваются» внутри одной временной отметки.
Посмотрим на настройки операционной системы и самой платформы 1С. В 7.7 существует параметр «Год начала столетия». Если на разных рабочих станциях или на сервере установлены разные значения (например, у одного пользователя 1921 год, а у другого 1945), то при записи документа двухзначный ввод года может интерпретироваться по-разному. Это приводит к тому, что в базе данных год может записаться как 1921 вместо 2021, и документ «улетит» в начало журнала. Даже если визуально в журнале стоит 21 год, индекс базы данных будет ориентироваться на полное значение.
Первым делом попробуем стандартные средства. Выполним следующие шаги:
Если штатное средство не помогает, попробуем «жесткий» метод для DBF-версии: удалим все файлы с расширением .cdx в каталоге базы данных и запустим 1С. Система предложит восстановить индексы с нуля.
Если реиндексация не исправляет порядок, значит, проблема в самих данных внутри поля DATE_TIME_IDDOC. В этом случае нам поможет программный перенос позиции. Разберем пример кода на языке 1С 7.7, который принудительно перезаписывает позицию документа, заставляя платформу пересчитать индекс:
Процедура ИсправитьПорядокДокументов()
Док = СоздатьОбъект("Документ");
// Выбираем период, в котором замечен беспорядок
Док.ВыбратьДокументы(ВыбНачДата, ВыбКонДата);
Пока Док.ПолучитьДокумент() = 1 Цикл
Состояние("Обработка: " + Док.ТекущийДокумент());
// Используем метод УстановитьПозицию для перезаписи индекса
Док.УстановитьПозицию(СформироватьПозициюДокумента(Док.ДатаДок, Док.ВремяДок));
Попытка
Док.Записать();
Исключение
Сообщить("Не удалось обновить документ: " + Док.ТекущийДокумент());
КонецПопытки;
КонецЦикла;
Предупреждение("Исправление завершено!");
КонецПроцедуры
Функция СформироватьПозициюДокумента принимает дату и время, возвращая объект, который система использует для позиционирования. Метод Записать() в данном контексте обновит запись в 1SJOURN, актуализировав индексное поле.
Если ваша база работает на MS SQL Server, проанализируем настройки сортировки (Collation). Платформа 7.7 требует строго определенного порядка сортировки — Cyrillic_General_BIN. Если при создании базы данных или переносе на новый сервер был выбран другой тип (например, CI_AS), то SQL-сервер будет сортировать строки с идентификаторами по своим правилам, которые отличаются от логики 1С. Это приведет к «каше» в журналах.
В этом случае поможет только пересоздание базы данных на SQL с правильным Collation и загрузка данных через выгрузку/загрузку .zip (через конфигуратор).
Для продвинутых пользователей существуют наборы утилит (например, от автора Z1), которые позволяют делать выборочную реиндексацию или дефрагментацию индексов (indexdefrag) в обход стандартного ТиИ. Это особенно полезно, когда база имеет огромный размер и полное тестирование занимает слишком много времени. Также для SQL-версий полезно использовать SQL Profiler, чтобы увидеть, по какому именно индексу идет выборка при открытии журнала, и нет ли там подсказок (hints), которые заставляют SQL игнорировать основной индекс.
Важное примечание: Всегда проверяйте, не является ли «неправильный» порядок следствием работы функции ПриВыводеСтроки. В 1С 7.7 часто в колонку «Дата» выводится текстовое значение через функцию, которая может брать данные из связанных справочников, в то время как реальная дата документа в базе другая. В таком случае нужно исправлять данные в самих документах, а не бороться с индексами.