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