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