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