При работе с крупными базами данных 1С:Предприятие на платформе MS SQL Server пользователи и администраторы иногда сталкиваются с критической ошибкой: «Дата '01.02.0001 0:00:00' не может быть записана в базу данных на MS SQL Server с нулевым смещением дат». Эта проблема чаще всего проявляется при пересчете итогов регистров накопления или бухгалтерии, а также при обмене данными в распределенных информационных базах (РИБ).
В этой статье мы подробно разберем природу возникновения данной ошибки, проанализируем структуру хранения дат в SQL-сервере и рассмотрим несколько эффективных способов решения проблемы — от стандартных инструментов 1С до прямого вмешательства в таблицы базы данных.
Для начала проанализируем техническую сторону вопроса. В MS SQL Server тип данных DATETIME имеет жесткое ограничение: он поддерживает диапазон дат только от 01.01.1753 до 31.12.9999. В то же время платформа 1С оперирует датами начиная с 01.01.0001.
Для преодоления этого различия при создании базы данных в 1С предлагается параметр «Смещение дат»:
Рассмотрим ситуации, когда в таблицах итогов внезапно появляются записи из «начала времен» (XVIII век или 0001 год), и как с этим бороться.
Если ошибка возникает при пересчете итогов, это сигнализирует о наличии «мусорных» записей в таблицах AccumRgT (итоги регистров накопления). Проанализируем ситуацию: иногда в этих таблицах появляются записи с датой 01.01.1753 или 01.02.1753, хотя в таблицах движений (AccumRg) таких периодов нет. Это происходит из-за внутренних сбоев механизма итогов.
Для исправления ситуации можно попробовать физически очистить проблемные таблицы. Рассмотрим шаги:
ПолучитьСтруктуруХраненияБазыДанных().XXXX на номер вашей таблицы):
SELECT * FROM _AccumRegTotalsXXXX WHERE _Period < '1900-01-01'
Если такие записи найдены, их можно удалить. Рассмотрим более радикальный, но часто эффективный метод — полную очистку итогов регистра с последующим пересчетом в самой 1С:
-- Очистка таблицы итогов конкретного регистра
TRUNCATE TABLE _AccumRegTotalsXXXX;
Важно: После очистки таблицы в SQL необходимо зайти в 1С (Конфигуратор) и запустить «Тестирование и исправление» с установленным флажком «Пересчет итогов». Система заново сформирует правильные записи на основании таблицы движений.
Иногда причина кроется не в самих записях итогов, а в таблице настроек, где хранится информация о периоде, по который рассчитаны итоги. Если там затесалась дата 0001 года, 1С будет пытаться рассчитать следующий месяц (01.02.0001) и упадет с ошибкой.
Для регистров бухгалтерии и накопления существуют служебные таблицы параметров (например, _AccumRegOptions или таблицы параметров бухгалтерских регистров). Проанализируем пример исправления через SQL, если ошибка блокирует работу:
_Period (период рассчитанных итогов) и _MinPeriod.
UPDATE _AccountingSettXXXX -- Пример для регистра бухгалтерии
SET _Period = '2001-01-01 00:00:00.000',
_MinPeriod = '5999-11-01 00:00:00.000'
WHERE ... -- условие для конкретного регистра
После этого выполните программную установку периода итогов из встроенного языка 1С:
РегистрыНакопления.ВашРегистр.УстановитьПериодРассчитанныхИтогов(ДобавитьМесяц(ТекущаяДата(), -1));
Если база была создана с нулевым смещением и ошибки повторяются регулярно, самым надежным способом будет перевод всей базы на смещение 2000. Это невозможно сделать «на лету» простым изменением значения в SQL-таблице _YearOffset, так как все существующие даты в базе записаны без смещения. Если просто поменять 0 на 2000, 1С начнет интерпретировать 2023 год как 4023 год.
Разберем правильную последовательность действий:
.dt)..dt в эту новую базу. В процессе загрузки платформа 1С автоматически пересчитает все даты и запишет их в SQL с корректным смещением.Этот метод гарантированно избавляет от проблем с датами DATETIME в SQL навсегда.
Иногда ошибка возникает только при обмене, особенно при обновлении конфигурации в узлах. Если вы не можете быстро пересоздать базу через .dt, рассмотрим временный «хак» для проведения обновления, предложенный опытными администраторами:
_YearOffset на стороне SQL временно меняется значение 0 на 2000._YearOffset возвращается обратно в 0.Внимание: Этот метод является крайне рискованным и должен применяться только в исключительных случаях профессионалами, так как любое обращение к данным в период измененного смещения может привести к повреждению дат в документах!
Для предотвращения подобных сбоев рекомендуется выполнять следующие действия:
chdbfl.exe для исправления физической целостности, а затем вернуть в SQL.Подводя итог, отметим, что наиболее стабильным решением остается работа со смещением 2000. Если же вы вынуждены работать с нулевым смещением, знание структуры таблиц _AccumRegTotals и умение очищать их через SQL-запросы помогут вам быстро вернуть систему в работоспособное состояние без длительных процедур выгрузки-загрузки данных. Для комплексной оценки правильности настроек сервера и выявления потенциальных недочетов можно использовать инструмент для чек-апа СУБД.