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

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

Случайный ввод опечатки в поле даты (например, 216 год вместо 2016 года) — распространенная проблема при ручном заполнении документов или сбоях обмена данными. На первый взгляд кажется, что достаточно просто перевыбрать год в реквизите и перепровести документ. Однако на уровне платформы 1С:Предприятие проведение документа с датой из далекого прошлого вызывает серьезные скрытые технические последствия. Разберем по шагам, чем опасна эта ситуация, как правильно исправить данные и вернуть производительность информационной базы.

Чем опасен ввод даты из далекого прошлого

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

В результате СУБД начинает хранить и поддерживать пустые помесячные срезы за весь образовавшийся период — от 216 до текущего года. Это приводит к следующим неприятным последствиям:

  1. Лавинообразное раздувание таблиц итогов: размер таблиц базы данных резко увеличивается на гигабайты из-за создания сотен тысяч пустых строк агрегатов и итогов.
  2. Падение производительности: любое последующее проведение документов, закрытие месяца или построение отчетов с обращением к виртуальным таблицам остатков и оборотов начинает выполняться с критическими задержками.
  3. Ошибки совместимости с СУБД: например, в Microsoft SQL Server стандартный тип данных DATETIME не поддерживает значения ранее 1753 года, из-за чего платформа использует внутренние смещения дат, что создает дополнительную нагрузку при пересчете индексов.

Шаг 1. Поиск всех объектов с поврежденными датами

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

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


ВЫБРАТЬ
    Ссылка КАК ДокументСсылка,
    Дата КАК ДатаДокумента,
    Проведен КАК Проведен
ИЗ
    Документ.ЗаказНаПеремещение
ГДЕ
    ГОД(Дата) < 2000

Аналогичным образом проанализируем движения регистров накопления, по которым делает записи документ:


ВЫБРАТЬ
    Регистратор,
    Период
ИЗ
    РегистрНакопления.ТоварыКПеремещению
ГДЕ
    ГОД(Период) < 2000

Шаг 2. Исправление документа и перепроведение

Разберем порядок непосредственного исправления ошибочного объекта:

  1. Открываем найденный документ и отменяем его проведение, чтобы снять некорректные движения по регистрам.
  2. Устанавливаем правильную дату (например, меняем 0216 год на 2016).
  3. Записываем и проводим документ заново.

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

Шаг 3. Сброс и полный пересчет итогов

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

Способ 1. Использование встроенных средств администрирования:

  1. Открываем меню Все функции (или Функции для технического специалиста).
  2. Находим стандартную обработку Управление итогами и агрегатами.
  3. Выбираем регистры, по которым делал движения проблемный документ.
  4. Отключаем использование итогов для этих регистров (это очистит раздутые таблицы).
  5. Включаем использование итогов обратно и устанавливаем период расчета итогов на актуальный рабочий месяц.

Способ 2. Программное управление итогами:

Для гарантированного сброса можно программно переключить итоги по регистру через код обработки:


Регистр = РегистрыНакопления.ТоварыКПеремещению;
// Отключаем итоги для очистки пустых срезов
Регистр.УстановитьИспользованиеИтогов(Ложь);
// Включаем итоги заново с пересчетом
Регистр.УстановитьИспользованиеИтогов(Истина);
Регистр.ПересчитатьИтоги();

Шаг 4. Обслуживание базы данных и сжатие таблиц

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

  1. Тестирование и исправление: запускаем конфигуратор в монопольном режиме и открываем Администрирование → Тестирование и исправление информационной базы. Включаем флажки Переиндексация таблиц информационной базы, Пересчет итогов и Сжатие таблиц информационной базы.
  2. Обслуживание на уровне СУБД (для клиент-серверного варианта): выполняем реорганизацию/перестроение индексов (REBUILD INDEX) и операцию сжатия базы данных (SHRINK DATABASE) средствами MS SQL Server или PostgreSQL.
  3. Восстановление последовательностей: если конфигурация использует учет по последовательностям документов (партионный учет, взаиморасчеты), запускаем процедуру восстановления последовательностей, чтобы актуализировать границы учета.

Шаг 5. Предотвращение появления ошибочных дат в будущем

Чтобы исключить повторение подобных сбоев, настроим превентивные механизмы защиты.

1. Настройка даты запрета изменения данных

Самый простой и эффективный способ для пользовательского ввода — включить механизм даты запрета редактирования (раздел Администрирование → Настройки пользователей и прав → Даты запрета изменения). Установка запрета на прошлые периоды не позволит провести документ с датой старше разрешенной границы.

2. Программный контроль через подписку на событие

Если документы создаются интеграциями или загрузками из внешних файлов в обход стандартных проверок, создадим подписку на событие ОбработкаПроверкиЗаполнения для всех документов метаданных:


Процедура ПроверитьКорректностьДатыПередЗаписью(Источник, Отказ, ПроверяемыеРеквизиты) Экспорт

    МинимальныйГод = 2010;
    
    Если ГОД(Источник.Дата) < МинимальныйГод Тогда
        ОбщегоНазначенияКлиентСервер.СообщитьПользователю(
            СтрШаблон("Год даты документа (%1) не может быть меньше %2!", Формат(Источник.Дата, "ДФ=yyyy"), МинимальныйГод),
            Источник,
            "Дата",
            ,
            Отказ
        );
    КонецЕсли;

КонецПроцедуры

Использование события ОбработкаПроверкиЗаполнения предпочтительнее ПередЗаписью, так как оно корректно визуализирует ошибку на форме пользователя с подсветкой поля Дата и не вызывает аварийных прерываний системных транзакций.

← На главную