В процессе сопровождения и обновления конфигураций 1С программисты часто сталкиваются с ситуацией, когда в существующий регистр (накопления, сведений или расчета) добавляется новое измерение с включенным свойством Запрет незаполненных значений. Если обработчики обновления не отработали корректно или в базе остались старые документы с пустыми значениями в этом поле, система может начать блокировать любые попытки программной корректировки таких записей. Разберем подробно, почему это происходит и как решить проблему без снятия конфигурации с поддержки.
Прежде всего, проанализируем разницу между двумя ключевыми свойствами метаданных, которые часто путают. От этого зависит выбор метода решения задачи.
Записать()) или установкой свойства ОбменДанными.Загрузка = Истина.NOT NULL. Если это свойство включено, платформа 1С на уровне ядра проверяет наличие данных в момент фиксации транзакции записи. Именно здесь возникает ошибка: "Запись не верна! Значение поля не может быть пустым!".Рассмотрим ситуацию: если в метаданных стоит Запрет незаполненных значений, то даже режим ОбменДанными.Загрузка = Истина может не спасти, так как платформа не может записать в таблицу БД запись, нарушающую ее структурную целостность.
Если ваша задача — просто избавиться от "битых" остатков, которые висят на пустом измерении, и вы не планируете восстанавливать в них данные, самым простым и безопасным методом будет полная очистка движений конкретного документа-регистратора.
Выясним причину, почему это работает: при записи пустого набора записей платформа не проверяет значения измерений, так как самих строк данных в наборе нет. Мы просто удаляем все записи этого документа из таблицы регистра.
Рассмотрим пример кода для очистки движений:
Процедура ОчиститьДвиженияДокумента(СсылкаНаДокумент)
// Создаем набор записей для конкретного регистра
Набор = РегистрыНакопления.РасчетыСПоставщиками.СоздатьНаборЗаписей();
Набор.Отбор.Регистратор.Установить(СсылкаНаДокумент);
// Включаем режим загрузки, чтобы обойти лишние прикладные проверки в модулях
Набор.ОбменДанными.Загрузка = Истина;
// Записываем пустой набор (удаляем старые записи)
Попытка
Набор.Записать();
Сообщить("Движения документа успешно очищены.");
Исключение
Сообщить("Ошибка при очистке: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
В случае, если вам необходимо не просто удалить записи, а корректно "закрыть" остатки (списать их), вам придется создать движение с тем же набором измерений, который был изначально. Но так как пустое измерение записать нельзя, проанализируем вариант с использованием технического элемента.
Посмотрим на алгоритм действий:
ОбъектыРасчетов), специальный служебный элемент с наименованием "Удалить (не используется)" или "Технический добор".КорректировкаРегистров), где спишите остаток уже по этому техническому элементу.Пример кода для программной замены значения в измерениях:
Процедура ЗаменитьПустоеИзмерение(РегистраторСсылка, ТехническоеЗначение)
Набор = РегистрыНакопления.РасчетыСПоставщиками.СоздатьНаборЗаписей();
Набор.Отбор.Регистратор.Установить(РегистраторСсылка);
Набор.Прочитать();
Для Каждого Запись Из Набор Цикл
// Проверяем, пустое ли измерение ОбъектРасчетов
Если Запись.ОбъектРасчетов.Пустая() Тогда
Запись.ОбъектРасчетов = ТехническоеЗначение;
КонецЕсли;
КонецЦикла;
Набор.ОбменДанными.Загрузка = Истина;
Набор.Записать();
КонецПроцедуры
В некоторых версиях платформы и при определенных настройках метаданных (если свойство "Запрет" не привело к жесткому NOT NULL в базе), программная запись с флагом ОбменДанными.Загрузка = Истина может сработать. Это происходит потому, что данный флаг отключает проверку Fill Check и выполнение кода в событиях ПередЗаписью и ПриЗаписи, где часто располагаются дополнительные проверки, написанные разработчиками конфигурации.
Попробуем выполнить запись в этом режиме:
Набор = РегистрыНакопления.ВашРегистр.СоздатьНаборЗаписей();
Набор.Отбор.Регистратор.Установить(СсылкаНаДокумент);
// ... заполнение набора ...
Набор.ОбменДанными.Загрузка = Истина;
Набор.Записать();
Если после выполнения этого кода вы все равно получаете ошибку о невозможности записи пустого поля, значит, ограничение установлено на уровне Запрета незаполненных значений в метаданных, и вам следует вернуться к Способу 1 или Способу 2.
Многие полагают, что штатный механизм Тестирование и исправление с галочкой "Очищать ссылки" или "Проставлять значения по умолчанию" решит проблему. Однако, проанализируем ситуацию: если в базе уже есть записи с NULL или пустыми ссылками, а вы включили Запрет незаполненных значений, ТиИ может попытаться исправить записи, но столкнется с тем же самым платформенным ограничением при записи. В некоторых случаях ТиИ может поместить записи в "Объект не найден", что тоже потребует последующей ручной или программной обработки.
При возникновении ошибки "Значение поля не может быть пустым" в регистрах:
НаборЗаписей.Записать() (без добавления строк).Такой подход позволяет корректно обслуживать базу данных, сохраняя целостность учета и не прибегая к внесению изменений в типовую конфигурацию.