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