Здравствуйте форумчане! Задача следующая импортировать массивы определенные тегами из xml в xls Далее преобразовать полученные данные в txt
Есть макрос, работает, но имеется проблема импортируется только первая строка массива
Подскажите пожалуйста что поправить в макросе чтобы было счастье
файлы прилагаю
[vba]
Код
Sub GetXML() Dim arFiles, x, lRow&, c As Range arFiles = Application.GetOpenFilename("XML files,*.xml", , "Выберите файлы", , True) If Not IsArray(arFiles) Then Exit Sub lRow = ActiveSheet.UsedRange.Row + ActiveSheet.UsedRange.Rows.Count For Each x In arFiles For Each c In [a1:c1].SpecialCells(xlCellTypeConstants) Cells(lRow, c.Column) = FindTag(x, (c)) Next lRow = lRow + 1 Next End Sub Private Function FindTag$(ByRef ff, ByRef sTag$) With CreateObject("Microsoft.XMLDOM") .async = "false" .Load (ff) FindTag = .getElementsByTagName(sTag).Item(0).Text End With End Function
[/vba]
Спасибо!
Здравствуйте форумчане! Задача следующая импортировать массивы определенные тегами из xml в xls Далее преобразовать полученные данные в txt
Есть макрос, работает, но имеется проблема импортируется только первая строка массива
Подскажите пожалуйста что поправить в макросе чтобы было счастье
файлы прилагаю
[vba]
Код
Sub GetXML() Dim arFiles, x, lRow&, c As Range arFiles = Application.GetOpenFilename("XML files,*.xml", , "Выберите файлы", , True) If Not IsArray(arFiles) Then Exit Sub lRow = ActiveSheet.UsedRange.Row + ActiveSheet.UsedRange.Rows.Count For Each x In arFiles For Each c In [a1:c1].SpecialCells(xlCellTypeConstants) Cells(lRow, c.Column) = FindTag(x, (c)) Next lRow = lRow + 1 Next End Sub Private Function FindTag$(ByRef ff, ByRef sTag$) With CreateObject("Microsoft.XMLDOM") .async = "false" .Load (ff) FindTag = .getElementsByTagName(sTag).Item(0).Text End With End Function
Sub GetXML() Dim arFiles, x, lRow&, c As Range, a() arFiles = Application.GetOpenFilename("XML files,*.xml", , "Выберите файлы", , True) If Not IsArray(arFiles) Then Exit Sub lRow = ActiveSheet.UsedRange.Row + ActiveSheet.UsedRange.Rows.Count For Each x In arFiles For Each c In [a1:c1].SpecialCells(xlCellTypeConstants) a = FindTag(x, (c)) Cells(lRow, c.Column).Resize(UBound(a), 1) = a Next lRow = lRow + 1 Next End Sub
Private Function FindTag(ByRef ff, ByRef sTag$) Dim a(), x As Object, i& With CreateObject("Microsoft.XMLDOM") .async = "false" .Load (ff) Set x = .getElementsByTagName(sTag) ReDim a(1 To x.Length, 1 To 1)
For i = 0 To UBound(a) - 1 a(i + 1, 1) = x.Item(i).Text Next FindTag = a End With End Function
[/vba] Неуверен насчёт x.Length...
Наощупь так может быть: [vba]
Код
Option Explicit
Sub GetXML() Dim arFiles, x, lRow&, c As Range, a() arFiles = Application.GetOpenFilename("XML files,*.xml", , "Выберите файлы", , True) If Not IsArray(arFiles) Then Exit Sub lRow = ActiveSheet.UsedRange.Row + ActiveSheet.UsedRange.Rows.Count For Each x In arFiles For Each c In [a1:c1].SpecialCells(xlCellTypeConstants) a = FindTag(x, (c)) Cells(lRow, c.Column).Resize(UBound(a), 1) = a Next lRow = lRow + 1 Next End Sub
Private Function FindTag(ByRef ff, ByRef sTag$) Dim a(), x As Object, i& With CreateObject("Microsoft.XMLDOM") .async = "false" .Load (ff) Set x = .getElementsByTagName(sTag) ReDim a(1 To x.Length, 1 To 1)
For i = 0 To UBound(a) - 1 a(i + 1, 1) = x.Item(i).Text Next FindTag = a End With End Function
Sub GetXML() Dim arFiles, x, lRow&, c arFiles = Application.GetOpenFilename("XML files,*.xml", , "Выберите файлы", , True) If Not IsArray(arFiles) Then Exit Sub lRow = ActiveSheet.UsedRange.Row + ActiveSheet.UsedRange.Rows.Count For Each x In arFiles c = FindTag(x) Cells(lRow, 1).Resize(UBound(c), 3) = c lRow = lRow + UBound(c) Next End Sub
Private Function FindTag(ByRef ff) Dim objListOfNodes As Object, XPath As String, RZ, i As Integer With CreateObject("Microsoft.XMLDOM") .async = "false" .Load (ff) XPath = "//СведенияОполучателе" Set objListOfNodes = .SelectNodes(XPath) i = 0 ReDim RZ(1 To objListOfNodes.Length, 1 To 3) For Each objNode In objListOfNodes i = i + 1 For Each oElem In objNode.ChildNodes
Select Case oElem.BaseName Case "ФИО" RZ(i, 1) = oElem.Text Case "НомерСчета" RZ(i, 2) = oElem.Text Case "СуммаКдоставке" RZ(i, 3) = Val(oElem.Text) End Select
Next Next
End With FindTag = RZ End Function
[/vba]
А так? [vba]
Код
Sub GetXML() Dim arFiles, x, lRow&, c arFiles = Application.GetOpenFilename("XML files,*.xml", , "Выберите файлы", , True) If Not IsArray(arFiles) Then Exit Sub lRow = ActiveSheet.UsedRange.Row + ActiveSheet.UsedRange.Rows.Count For Each x In arFiles c = FindTag(x) Cells(lRow, 1).Resize(UBound(c), 3) = c lRow = lRow + UBound(c) Next End Sub
Private Function FindTag(ByRef ff) Dim objListOfNodes As Object, XPath As String, RZ, i As Integer With CreateObject("Microsoft.XMLDOM") .async = "false" .Load (ff) XPath = "//СведенияОполучателе" Set objListOfNodes = .SelectNodes(XPath) i = 0 ReDim RZ(1 To objListOfNodes.Length, 1 To 3) For Each objNode In objListOfNodes i = i + 1 For Each oElem In objNode.ChildNodes
Select Case oElem.BaseName Case "ФИО" RZ(i, 1) = oElem.Text Case "НомерСчета" RZ(i, 2) = oElem.Text Case "СуммаКдоставке" RZ(i, 3) = Val(oElem.Text) End Select
Sub GetXML() Dim arFiles, x, lRow&, cv, arr arFiles = Application.GetOpenFilename("XML files,*.xml", , "Выберите файлы", , True) If Not IsArray(arFiles) Then Exit Sub lRow = ActiveSheet.UsedRange.Row + ActiveSheet.UsedRange.Rows.Count For Each x In arFiles cv = [a1:c1].Value arr = FindTag(x, cv) Next Range("A" & lRow).Resize(UBound(arr), 3) = arr End Sub Private Function FindTag(ByRef ff, ByVal sTag) Dim col As New Collection Dim a(1 To 3), k&, arr, i&, j& With CreateObject("Microsoft.XMLDOM") .async = "false" .Load (ff) Do While Err = 0 On Error Resume Next a(1) = .getElementsByTagName(sTag(1, 1)).Item(k).Text a(2) = .getElementsByTagName(sTag(1, 2)).Item(k).Text a(3) = .getElementsByTagName(sTag(1, 3)).Item(k).Text k = k + 1 If Err = 0 Then col.Add a(), CStr(k) Loop ReDim arr(1 To col.Count, 1 To 3) For i = 1 To col.Count For j = 1 To 3 arr(i, j) = col.Item(i)(j) Next Next End With FindTag = arr End Function
[/vba]
А я так сочинил [vba]
Код
Sub GetXML() Dim arFiles, x, lRow&, cv, arr arFiles = Application.GetOpenFilename("XML files,*.xml", , "Выберите файлы", , True) If Not IsArray(arFiles) Then Exit Sub lRow = ActiveSheet.UsedRange.Row + ActiveSheet.UsedRange.Rows.Count For Each x In arFiles cv = [a1:c1].Value arr = FindTag(x, cv) Next Range("A" & lRow).Resize(UBound(arr), 3) = arr End Sub Private Function FindTag(ByRef ff, ByVal sTag) Dim col As New Collection Dim a(1 To 3), k&, arr, i&, j& With CreateObject("Microsoft.XMLDOM") .async = "false" .Load (ff) Do While Err = 0 On Error Resume Next a(1) = .getElementsByTagName(sTag(1, 1)).Item(k).Text a(2) = .getElementsByTagName(sTag(1, 2)).Item(k).Text a(3) = .getElementsByTagName(sTag(1, 3)).Item(k).Text k = k + 1 If Err = 0 Then col.Add a(), CStr(k) Loop ReDim arr(1 To col.Count, 1 To 3) For i = 1 To col.Count For j = 1 To 3 arr(i, j) = col.Item(i)(j) Next Next End With FindTag = arr End Function
И не будет работать. Почему? А потому,что хозяйка макросов до настоящей поры не изучила структуру XML файлов. Нет таких тегов ИдФайл ТипИнф ВерсПрог ТелОтпр ДолжнОтпр ФамОтпр КолДок ВерсФорм, Это атрибуты нода с тегом Файл Раз уж вы занялись программированием ,установите себе Notepad++, и в цвете увидите структуру файла XML.
И не будет работать. Почему? А потому,что хозяйка макросов до настоящей поры не изучила структуру XML файлов. Нет таких тегов ИдФайл ТипИнф ВерсПрог ТелОтпр ДолжнОтпр ФамОтпр КолДок ВерсФорм, Это атрибуты нода с тегом Файл Раз уж вы занялись программированием ,установите себе Notepad++, и в цвете увидите структуру файла XML.doober
doober, подскажите пожалуйста, возможно ли программно получить массив имен nodes и их значения из файла, если заранее неизвестно количество атрибутов этих элементов? Т.к. файлы могут быть и с разной структурой. Или нужно каждый Node указать в макросе?
И как вообще это сделать?
doober, подскажите пожалуйста, возможно ли программно получить массив имен nodes и их значения из файла, если заранее неизвестно количество атрибутов этих элементов? Т.к. файлы могут быть и с разной структурой. Или нужно каждый Node указать в макросе?
Первая строка заполняется тегами из xml файла через одну ячейку Файл пусто Документ пусто СвБанк пусто СвБанк пусто АдрМНКО пусто СвНП пусто НПФЛ пусто ФИОФЛ пусто СвСчет пусто Открыт
[vba]
Код
Sub GetXML() Dim arFiles, x, lRow&, c arFiles = Application.GetOpenFilename("XML files,*.xml", , "Выберите файлы", , True) If Not IsArray(arFiles) Then Exit Sub lRow = ActiveSheet.UsedRange.Row + ActiveSheet.UsedRange.Rows.Count lLastCol = ActiveSheet.Range("iv1").End(xlToLeft).Column ArrCol = ActiveSheet.Range(ActiveSheet.Cells(1, 1), ActiveSheet.Cells(1, lLastCol)) lRow = 2
For Each x In arFiles For n = 1 To lLastCol Step 2 c = Findattributes(x, ArrCol(1, n)) Cells(lRow, n).Resize(UBound(c), UBound(c, 2)) = c Next Next End Sub
Private Function Findattributes(ByRef ff, Fl) Dim objListOfNodes As Object, XPath As String, RZ, i As Integer With CreateObject("Microsoft.XMLDOM") .async = "false" .Load (ff) XPath = "//" & Fl Set objListOfNodes = .SelectNodes(XPath) If objListOfNodes.Length > 0 Then ReDim RZ(1 To objListOfNodes(0).Attributes.Length, 1 To 2) For i = 0 To objListOfNodes(0).Attributes.Length - 1 RZ(i + 1, 1) = objListOfNodes(0).Attributes(i).Name RZ(i + 1, 2) = objListOfNodes(0).Attributes(i).Value Next End If
End With Findattributes = RZ End Function
[/vba]
PS:Борода у Хоттабыча сильно поредела
Цитата
И как вообще это сделать?
Так.
Первая строка заполняется тегами из xml файла через одну ячейку Файл пусто Документ пусто СвБанк пусто СвБанк пусто АдрМНКО пусто СвНП пусто НПФЛ пусто ФИОФЛ пусто СвСчет пусто Открыт
[vba]
Код
Sub GetXML() Dim arFiles, x, lRow&, c arFiles = Application.GetOpenFilename("XML files,*.xml", , "Выберите файлы", , True) If Not IsArray(arFiles) Then Exit Sub lRow = ActiveSheet.UsedRange.Row + ActiveSheet.UsedRange.Rows.Count lLastCol = ActiveSheet.Range("iv1").End(xlToLeft).Column ArrCol = ActiveSheet.Range(ActiveSheet.Cells(1, 1), ActiveSheet.Cells(1, lLastCol)) lRow = 2
For Each x In arFiles For n = 1 To lLastCol Step 2 c = Findattributes(x, ArrCol(1, n)) Cells(lRow, n).Resize(UBound(c), UBound(c, 2)) = c Next Next End Sub
Private Function Findattributes(ByRef ff, Fl) Dim objListOfNodes As Object, XPath As String, RZ, i As Integer With CreateObject("Microsoft.XMLDOM") .async = "false" .Load (ff) XPath = "//" & Fl Set objListOfNodes = .SelectNodes(XPath) If objListOfNodes.Length > 0 Then ReDim RZ(1 To objListOfNodes(0).Attributes.Length, 1 To 2) For i = 0 To objListOfNodes(0).Attributes.Length - 1 RZ(i + 1, 1) = objListOfNodes(0).Attributes(i).Name RZ(i + 1, 2) = objListOfNodes(0).Attributes(i).Value Next End If
doober, Вы не Хоттабыч, Вы реально Бог VBA, Я до сих пор не могу понять как это возможно такое создать и как Вы это делаете, реально всё что Вы делаете работает Я в восторге))))
doober, Вы не Хоттабыч, Вы реально Бог VBA, Я до сих пор не могу понять как это возможно такое создать и как Вы это делаете, реально всё что Вы делаете работает Я в восторге)))) Валерьянка
Сообщение отредактировал Валерьянка - Пятница, 13.06.2014, 16:30