Новости:

Название темы должно отражать суть задачи.
Темы типа "ПОМОГИТЕ!!!", "Срочно!" и т.п. будут удаляться без объяснения причин

Главное меню

выборка данных из кучи xml файлов в таблицу excel

Автор dr_peper, 21.07.2021, 08:22:06

« назад - далее »

dr_peper

Всем привет. Стоит задача выбрать из кучи xml файлов нужную информацию и добавить ее в таблицу excel. Изучая форумы, литературу и иные источники написал код vba, который должен это делать, но он прокручивается в пустую, не пойму в чем дело. Ошибок ни каких не выдает и данных тоже не выбирает. Знающие люди направьте на путь истинный.
пример xml файла прилагаю
мой код

Private Sub CommandButtonImport_Click()

Dim fd As Office.FileDialog
    Set fd = Application.FileDialog(msoFileDialogFilePicker)
    With fd
            .Filters.Clear
            .Title = "Select Multiple XML Files"
            .Filters.Add "XML File", "*.xml", 1
            .AllowMultiSelect = True
                       
        If .Show = True Then
            Dim xdoc As Object
            Set xdoc = CreateObject("MSXML2.DOMdocument")
            xdoc.async = False: xdoc.validateOnParse = False
            row_number = 1
            For i = 1 To .SelectedItems.Count
                xmlFileName = fd.SelectedItems(i)
                xdoc.Load (xmlFileName)
                xdoc.SetProperty "SelectionNamespaces", "xmlns:ns='urn:customs.ru:Information:ExchangeDocuments:ED_Container:5.13.1'"
                Set xdocE = xdoc.DocumentElement
                For Each xdocE In xdoc.SelectNodes("ns:ED_Container/ns:ContainerDoc/ns:DocBody/ns:ESADout_CU")
                Aplication.Range("DTRange").Cells(row_number, 1).Value = xdocE.SelectSingleNode("/comment()").Text
                Aplication.Range("DTRange").Cells(row_number, 2).Value = xdocE.SelectSingleNode("ns:CustomsProcedure").Text
                Aplication.Range("DTRange").Cells(row_number, 3).Value = xdocE.SelectSingleNode("ns:CustomsModeCode").Text
                Aplication.Range("DTRange").Cells(row_number, 4).Value = xdocE.SelectSingleNode("ns:catESAD_cu:GoodsNumeric").Text
                Aplication.Range("DTRange").Cells(row_number, 5).Value = xdocE.SelectSingleNode("ns:catESAD_cu:GoodsTNVEDCode").Text
                row_number = row_number + 1
                Next xdocE
     
              Next i
        End If
                         
    End With

End Sub



вытягиваю данные вот в такую таблицу
INFORMATION            
            
DT   napr   proc   goods   TN_VED

dr_peper

на всякий случай это файл с таблицей

Дмитрий Щербаков(The_Prist)

Цитата: dr_peper от 21.07.2021, 08:22:06направьте на путь истинный
начать я бы рекомендовал с пошаговой отладки и просмотра чего так откуда получаете: Отлов ошибок и отладка кода VBA
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...

dr_peper

Так ошибок не выдаёт и ничего не выбирает. В том то и дело  :'(. Сижу ломаю голову, может вообще код кривой. Я так то не очень силён в vba, тем более по отношению к xml

Дмитрий Щербаков(The_Prist)

Цитата: dr_peper от 21.07.2021, 15:24:09ошибок не выдаёт и ничего не выбирает
так почитайте статью и примените пошаговую отладку, чтобы посмотреть что на каком шаге у Вас происходит и какие значения получаете.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...

dr_peper

Спасибо за совет, по всей видимости код не отрабатывает эти строки

Aplication.Range("DTRange").Cells(row_number, 1).Value = xdocE.SelectSingleNode("comment()").Text
                Aplication.Range("DTRange").Cells(row_number, 2).Value = xdocE.SelectSingleNode("dout:CustomsProcedure").Text
                Aplication.Range("DTRange").Cells(row_number, 3).Value = xdocE.SelectSingleNode("dout:CustomsModeCode").Text
                Aplication.Range("DTRange").Cells(row_number, 4).Value = xdocE.SelectSingleNode("atc:catESAD_cu:GoodsNumeric").Text
                Aplication.Range("DTRange").Cells(row_number, 5).Value = xdocE.SelectSingleNode("atc:catESAD_cu:GoodsTNVEDCode").Text
                row_number = row_number + 1
                Next xdocE


с for each сразу перескакивает на next i, что не так не пойму.
Он их не запускает при пошаговой отработке.

Дмитрий Щербаков(The_Prist)

Цитата: dr_peper от 22.07.2021, 04:00:59for each сразу перескакивает на next i
это значит, что нет доступных элементов для перебора в узле "ns:ED_Container/ns:ContainerDoc/ns:DocBody/ns:ESADout_CU".
Запишите так:
For Each xdocE In xdoc.SelectNodes("ED_Container/ContainerDoc/DocBody/ESADout_CU")
да и вообще везде уберите ns:
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...

dr_peper

Цитата: Дмитрий Щербаков(The_Prist) от 22.07.2021, 09:14:55
это значит, что нет доступных элементов для перебора в узле "ns:ED_Container/ns:ContainerDoc/ns:DocBody/ns:ESADout_CU".
Запишите так:
For Each xdocE In xdoc.SelectNodes("ED_Container/ContainerDoc/DocBody/ESADout_CU")
да и вообще везде уберите ns:


В xml  файле несколько пространств имен, сейчас немного по другому выглядит данная часть кода. Если убрать указание на конкретное пространство имен наверное тогда комп вообще ничего не поймет откуда что брать.

xdoc.Load (xmlFileName)
                xdoc.SetProperty "SelectionNamespaces", "xmlns:cont='urn:customs.ru:Information:ExchangeDocuments:ED_Container:5.13.1'"
                xdoc.SetProperty "SelectionNamespaces", "xmlns:dout='urn:customs.ru:Information:CustomsDocuments:ESADout_CU:5.17.0'"
                xdoc.SetProperty "SelectionNamespaces", "xmlns:atc='urn:customs.ru:CUESADCommonAggregateTypesCust:5.17.0'"
                Set xdocE = xdoc.DocumentElement
                For Each xdocE In xdoc.SelectNodes("cont:ED_Container/cont:ContainerDoc/cont:DocBody/dout:ESADout_CU")
                Application.Range("DTRange").Cells(row_number, 1).Value = xdocE.SelectSingleNode("comment()").Text
                Application.Range("DTRange").Cells(row_number, 2).Value = xdocE.SelectSingleNode("dout:CustomsProcedure").Text
                Application.Range("DTRange").Cells(row_number, 3).Value = xdocE.SelectSingleNode("dout:CustomsModeCode").Text
                Application.Range("DTRange").Cells(row_number, 4).Value = xdocE.SelectSingleNode("atc:catESAD_cu:GoodsNumeric").Text
                Application.Range("DTRange").Cells(row_number, 5).Value = xdocE.SelectSingleNode("atc:catESAD_cu:GoodsTNVEDCode").Text
                row_number = row_number + 1
                Next xdocE
   
   
              Next i

Дмитрий Щербаков(The_Prist)

Цитата: dr_peper от 22.07.2021, 09:33:41наверное тогда
Может сначала надо попробовать? Я вот попробовал, прежде чем посоветовать. А Вы, прежде чем написать? Уберите отсылки на пространства имен - в схеме у Вас в приложенном файле узлы ими не отмечены.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...

dr_peper

Цитата: Дмитрий Щербаков(The_Prist) от 22.07.2021, 10:14:05
Может сначала надо попробовать?

Я тысячекратно извиняюсь. Конечно нужно пробовать, т.к. не попробуешь не узнаешь.

xdoc.SetProperty "SelectionNamespaces", "xmlns:cont='urn:customs.ru:Information:ExchangeDocuments:ED_Container:5.13.1'"
                xdoc.SetProperty "SelectionNamespaces", "xmlns:dout='urn:customs.ru:Information:CustomsDocuments:ESADout_CU:5.17.0'"
                xdoc.SetProperty "SelectionNamespaces", "xmlns:atc='urn:customs.ru:CUESADCommonAggregateTypesCust:5.17.0'"
                Set xdocE = xdoc.DocumentElement
                For Each xdocE In xdoc.SelectNodes("ED_Container/ContainerDoc/DocBody/ESADout_CU")
                Application.Range("DTRange").Cells(row_number, 1).Value = xdocE.SelectSingleNode("/comment()").Text
                Application.Range("DTRange").Cells(row_number, 2).Value = xdocE.SelectSingleNode("CustomsProcedure").Text
                Application.Range("DTRange").Cells(row_number, 3).Value = xdocE.SelectSingleNode("CustomsModeCode").Text
                Application.Range("DTRange").Cells(row_number, 4).Value = xdocE.SelectSingleNode("GoodsNumeric").Text
                Application.Range("DTRange").Cells(row_number, 5).Value = xdocE.SelectSingleNode("GoodsTNVEDCode").Text
                row_number = row_number + 1


Выбирает но не все

Application.Range("DTRange").Cells(row_number, 4).Value = xdocE.SelectSingleNode("GoodsNumeric").Text
                Application.Range("DTRange").Cells(row_number, 5).Value = xdocE.SelectSingleNode("GoodsTNVEDCode").Text


по этим 2 строчкам дает ошибку Run time error 91.
Я так понимаю несоответствие типа данных. Им не подходит значение Text?

dr_peper

Вот такое сообщение выдает. Не задана объектная переменная - не пойму что он хочет.

dr_peper

как я понял проблема в этой строке
For Each xdocE In xdoc.SelectNodes("ED_Container/ContainerDoc/DocBody/ESADout_CU")  
пробовал написать так
For Each xdocE In xdoc.SelectNodes("ED_Container/ContainerDoc/DocBody/ESADout_CU/ESADout_CUGoodsShipment/ESADout_CUGoods")
не помогло. Заполняется только первый столбец.

Дмитрий Щербаков(The_Prist)

Цитата: dr_peper от 23.07.2021, 02:33:50по этим 2 строчкам дает ошибку
Сложно что-то говорить наверняка, когда Вы работаете с одним файлом, а на форум приложили другой :) Но. Ошибка явно не в этой строке
For Each xdocE In xdoc.SelectNodes("ED_Container/ContainerDoc/DocBody/ESADout_CU")
т.к. другие-то свойства из узла определяются и записываются. Проблема именно в тех узлах, на которых ошибку дает. Возможно, Вы просто неправильно к ним обращаетесь. Может быть там надо использовать не .Text, а NodeValue. А возможно они вообще не являются узлами и к ним надо обращаться через Nodes/ChildNodes
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...

dr_peper

Цитата: Дмитрий Щербаков(The_Prist) от 23.07.2021, 09:38:36
наверняка, когда Вы работаете с одним файлом, а на форум приложили другой

Структура файла полностью идентична, только содержимое подчищено. Эти 2 поля не должен был трогать, т.к. в них нет конфиденциальной информации.

Дмитрий Щербаков(The_Prist)

Так и просмотрите структуру-то. У Вас эти поля вложены в подчиненные узлы, а Вы хотите их напрямую из узла ESADout_CU получить. Вот так работает без проблем:
Application.Range("DTRange").Cells(row_number, 4).Value = xdocE.SelectSingleNode("ESADout_CUGoodsShipment/ESADout_CUGoods/catESAD_cu:GoodsNumeric").Text
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...

Яндекс.Метрика Рейтинг@Mail.ru