В процессе эксплуатации системы 1С:Предприятие, особенно после переноса данных из других конфигураций или некорректного импорта из внешних файлов (Excel, XML), часто возникает ситуация, когда документы оказываются заполнены частично. Одной из типичных проблем является наличие «битых» или пустых строк в табличных частях. В данной статье мы подробно разберем, как создать обработку, которая автоматически найдет такие документы и пометит их на удаление, чтобы не засорять базу данных.
Прежде всего, проанализируем ситуацию: нам необходимо проверить реквизит Физлицо в табличной части Список документа Приказ. Если это поле не заполнено, документ должен быть помечен на удаление.
Важно понимать разницу между типами данных. Если реквизит является ссылкой на справочник (в нашем случае Справочник.ФизическиеЛица), то использование метода ПустаяСтрока() технически неверно. Этот метод предназначен исключительно для строковых типов данных. Для проверки заполненности ссылочных полей, дат или чисел в 1С предусмотрена универсальная функция ЗначениеЗаполнено(). Она возвращает Ложь, если значение является «пустым» для своего типа (пустая ссылка, 0, пустая дата и т.д.).
Рассмотрим простейший, но не самый быстрый способ решения задачи. Этот метод подойдет, если документов в базе немного. Мы будем последовательно выбирать каждый документ, заходить в его табличную часть и проверять строки.
Разберем пример кода для кнопки выполнения:
Процедура КнопкаВыполнитьНажатие(Кнопка)
// Выбираем все документы типа Приказ
Выборка = Документы.Приказ.Выбрать();
Пока Выборка.Следующий() Цикл
ДокументОбъект = Выборка.ПолучитьОбъект();
НужноУдалить = Ложь;
// Перебираем строки табличной части "Список"
Для каждого СтрокаТЧ Из ДокументОбъект.Список Цикл
// Проверяем, заполнено ли физическое лицо
Если Не ЗначениеЗаполнено(СтрокаТЧ.Физлицо) Тогда
НужноУдалить = Истина;
Прервать; // Если нашли хотя бы одну пустую строку, дальше можно не искать
КонецЕсли;
КонецЦикла;
// Если условие выполнено и документ еще не помечен на удаление
Если НужноУдалить И Не ДокументОбъект.ПометкаУдаления Тогда
Попытка
ДокументОбъект.УстановитьПометкуУдаления(Истина);
Сообщить("Документ " + ДокументОбъект + " помечен на удаление.");
Исключение
Сообщить("Не удалось обработать документ: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Важное примечание: Метод УстановитьПометкуУдаления(Истина) не только меняет флаг в памяти, но и сразу записывает объект в базу данных. Это удобно, но требует осторожности при работе в транзакциях.
Если документов в базе тысячи, первый способ будет работать крайне медленно, так как 1С придется считывать из базы данных все поля каждого документа. Проанализируем более эффективный подход: сначала найдем ссылки на «проблемные» документы с помощью запроса, а затем обработаем только их.
Рассмотрим подробнее реализацию этого метода. Мы обратимся напрямую к таблице табличной части документа.
Процедура ВыполнитьПометкуЧерезЗапрос()
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| ПриказСписок.Ссылка КАК Ссылка
|ИЗ
| Документ.Приказ.Список КАК ПриказСписок
|ГДЕ
| ПриказСписок.Физлицо = ЗНАЧЕНИЕ(Справочник.ФизическиеЛица.ПустаяСсылка)";
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
// Получаем объект только для тех документов, которые точно нужно пометить
ДокументОбъект = Выборка.Ссылка.ПолучитьОбъект();
Если Не ДокументОбъект.ПометкаУдаления Тогда
// Используем режим загрузки для ускорения и обхода лишних проверок
ДокументОбъект.ОбменДанными.Загрузка = Истина;
ДокументОбъект.УстановитьПометкуУдаления(Истина);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
В этом коде мы использовали ключевое слово РАЗЛИЧНЫЕ. Выясним причину: если в одном документе будет несколько пустых строк, запрос без этого слова вернет одну и ту же ссылку несколько раз. Это приведет к лишним операциям чтения и записи.
Проанализируем несколько критически важных моментов, которые помогут избежать ошибок при массовом изменении данных:
ДокументОбъект.ОбменДанными.Загрузка = Истина позволяет временно отключить прикладные проверки в модуле объекта (например, проверки на корректность заполнения других полей или подписки на события). Это значительно ускоряет процесс и позволяет пометить документ на удаление даже в том случае, если он не проходит стандартную проверку по другим реквизитам.Список в запросе и искать записи, где НомерСтроки ЕСТЬ NULL.ПометкаУдаления в значение Истина без написания кода.Таким образом, мы выяснили, что наиболее эффективным и правильным способом решения задачи является использование запроса с последующим получением объекта. Это гарантирует высокую скорость работы и точность выборки данных, необходимых для обработки.