Как исправить ошибку «Запись не верна: период не может быть пустым» при проведении документа в 1С?

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

При работе в программных продуктах на платформе «1С:Предприятие 8» пользователи и администраторы периодически сталкиваются с системными сообщениями, которые блокируют проведение документов и останавливают закрытие отчетных периодов. Одной из самых распространенных является ошибка: «Запись не верна: период не может быть пустым». Особенно часто она проявляется при проведении сложных регламентных документов распределения затрат, таких как Косвенные расходы.

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

Почему возникает ошибка пустого периода?

С технической точки зрения, в платформе 1С существуют периодические регистры (это могут быть регистры сведений, регистры накопления или регистры бухгалтерии). У таких регистров есть обязательное системное поле — Период. Оно отвечает за временную привязку записи в базе данных. Платформа 1С жестко контролирует, чтобы у каждой строки, записываемой в периодический регистр, это поле было заполнено корректной датой.

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

Методика диагностики: ищем причину вместе

Давайте проанализируем ситуацию. Документ Косвенные расходы формирует множество движений в различных регистрах для распределения затрат по подразделениям, номенклатурным группам или статьям расходов. Ошибка указывает на конкретный документ (например, с номером 01.00.0000001). Мы можем решить эту проблему, разделив процесс диагностики на несколько уровней: от простых пользовательских проверок до детального анализа кода.

Шаг 1. Проверка даты и аналитики на стороне пользователя

Прежде чем привлекать разработчика и открывать конфигуратор, выполним базовые проверки данных в режиме «1С:Предприятие»:

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

Шаг 2. Использование отладчика и установка точки останова

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

Рассмотрим пошагово, как поймать ошибку «на горячем»:

  1. Запустите конфигуратор 1С под учетной записью с правами администратора или разработчика.
  2. Откройте дерево метаданных (конфигурацию) и найдите документ КосвенныеРасходы (или соответствующий документ в вашей конфигурации).
  3. Кликните правой кнопкой мыши по документу и выберите «Открыть модуль объекта».
  4. Найдите предопределенную процедуру ОбработкаПроведения. Именно внутри нее формируются все движения по регистрам.
  5. Установите точку останова в самом конце процедуры (перед записью движений) и запустите сеанс отладки.

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

Шаг 3. Анализ коллекции движений и вычисление выражения

Когда выполнение программы остановится на точке прерывания перед записью движений, откройте окно вычисления выражений с помощью комбинации клавиш Shift + F9. Нам нужно проанализировать коллекцию Движения документа. Например, если документ делает записи в регистр накопления ПрочиеРасходы, введите в поле выражения:

Движения.ПрочиеРасходы.Выгрузить()

Эта команда выгрузит все сформированные движения в таблицу значений, которую вы сможете детально изучить. Пролистайте таблицу и найдите колонку Период. Обратите внимание на строки, в которых дата отображается как 01.01.0001 00:00:00. Наличие таких строк — это и есть прямая причина падения системы.

Использование условных точек останова

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

  1. Найдите строку кода, в которой происходит добавление записи или запись набора в регистр (например, Движения.Записать(); или цикл заполнения).
  2. Установите обычную точку останова (нажатием клавиши F9).
  3. Нажмите правой кнопкой мыши на установленную точку останова и выберите пункт «Свойства точки останова...».
  4. В открывшемся окне в поле «Условие» введите логическое выражение. Например, если вы перебираете строки таблицы движений в цикле с переменной СтрокаДвижения, условие может выглядеть так:

СтрокаДвижения.Период = '00010101000000'

Теперь отладчик сработает и прервет выполнение программы только тогда, когда условие выполнится — то есть когда система обнаружит ту самую строку с пустой датой. Это сэкономит вам массу времени и позволит мгновенно определить контекст возникновения ошибки (какая именно статья затрат или аналитика привела к сбою).

Типичные ошибки в коде и способы их устранения

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

Сценарий А. Забыли присвоить период новой записи

Иногда при ручном формировании движений разработчики забывают инициализировать поле периода для каждой строки набора записей. Рассмотрим неправильный пример кода:


НоваяЗапись = Движения.ПрочиеРасходы.Добавить();
НоваяЗапись.Организация = Объект.Организация;
НоваяЗапись.СтатьяРасходов = Выборка.СтатьяРасходов;
НоваяЗапись.Сумма = Выборка.СуммаРасходов;
// Поле НоваяЗапись.Период осталось пустым!

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


НоваяЗапись = Движения.ПрочиеРасходы.Добавить();
НоваяЗапись.Период = ЭтотОбъект.Дата; // Заполняем период датой документа
НоваяЗапись.Организация = Объект.Организация;
НоваяЗапись.СтатьяРасходов = Выборка.СтатьяРасходов;
НоваяЗапись.Сумма = Выборка.СуммаРасходов;

Сценарий Б. Ошибка при использовании метода Загрузить()

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

Движения.ПрочиеРасходы.Загрузить(ТаблицаДвижений);

Если в исходной таблице значений ТаблицаДвижений колонка Период отсутствует вовсе или содержит пустые даты, то при вызове метода Загрузить платформа заполнит движения значениями по умолчанию (пустой датой). Решение здесь заключается в проверке структуры таблицы ТаблицаДвижений. Перед загрузкой убедитесь, что колонка добавлена и заполнена:


// Проверяем наличие колонки Период в таблице значений
Если ТаблицаДвижений.Колонки.Найти("Период") = Неопределено Тогда
    ТаблицаДвижений.Колонки.Добавить("Период", Новый ОписаниеТипов("Дата"));
КонецЕсли;

Для Каждого СтрокаТЗ Из ТаблицаДвижений Цикл
    Если Не ЗначениеЗаполнено(СтрокаТЗ.Период) Тогда
        СтрокаТЗ.Период = ЭтотОбъект.Дата;
    КонецЕсли;
КонецЦикла;

Движения.ПрочиеРасходы.Загрузить(ТаблицаДвижений);

Сценарий В. Левое соединение в запросах проведения (Самый частый случай)

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

Рассмотрим классический пример опасного запроса:


ВЫБРАТЬ
    ВТ_Затраты.СтатьяРасходов КАК СтатьяРасходов,
    ВТ_Затраты.Сумма КАК Сумма,
    ТаблицаНастроек.ДатаНачалаРаспределения КАК ПериодРаспределения
ИЗ
    ВТ_Затраты КАК ВТ_Затраты
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.НастройкиРаспределенияРасходов КАК ТаблицаНастроек
        ПО ВТ_Затраты.Подразделение = ТаблицаНастроек.Подразделение

Если для какого-то подразделения из таблицы ВТ_Затраты в регистре НастройкиРаспределенияРасходов отсутствует соответствующая запись настроек, то в результате левого соединения поле ТаблицаНастроек.ДатаНачалаРаспределения вернет значение NULL. В дальнейшем при обходе выборки этого запроса значение NULL неявно преобразуется в пустую дату (01.01.0001 00:00:00), которая и запишется в движения регистра.

Как исправить такой запрос? Нам необходимо обязательно обрабатывать возможные значения NULL с помощью функции ЕСТЬNULL. Изменим наш запрос следующим образом:


ВЫБРАТЬ
    ВТ_Затраты.СтатьяРасходов КАК СтатьяРасходов,
    ВТ_Затраты.Сумма КАК Сумма,
    // Если дата настроек не найдена, подставляем дату документа
    ЕСТЬNULL(ТаблицаНастроек.ДатаНачалаРаспределения, &ДатаДокумента) КАК ПериодРаспределения
ИЗ
    ВТ_Затраты КАК ВТ_Затраты
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.НастройкиРаспределенияРасходов КАК ТаблицаНастроек
        ПО ВТ_Затраты.Подразделение = ТаблицаНастроек.Подразделение

Благодаря использованию функции ЕСТЬNULL, мы страхуем систему от появления пустых дат в результирующей выборке. В качестве резервного значения (второго параметра функции) рекомендуется передавать параметр &ДатаДокумента, который мы предварительно устанавливаем перед выполнением запроса:

Запрос.УстановитьПараметр("ДатаДокумента", ЭтотОбъект.Дата);

Профилактика и полезные советы

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

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

← На главную