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