Необходимо разложить элементы текста из файла xml,расположенные в столбце "А" по столбцам, начиная с "B". Элементы в строках разделены строго одним пробелом, можно было бы элементы разложить по разделителю "пробел", но в тексте,заключенном в кавычках может быть разное количество пробелов и их как-то надо игнорировать, т.е. ориетироваться только на пробелы между элементами. В тексте, который в кавычках, должно остаться по одному пробелу между словами,а если число в кавычках,то там пробелов не должно остаться. Текст в кавычках является частью элемента и он должен остаться в элементе. Как это сделать попроще в VBA, что посоветуете? Пример с макросом прилагается.
Необходимо разложить элементы текста из файла xml,расположенные в столбце "А" по столбцам, начиная с "B". Элементы в строках разделены строго одним пробелом, можно было бы элементы разложить по разделителю "пробел", но в тексте,заключенном в кавычках может быть разное количество пробелов и их как-то надо игнорировать, т.е. ориетироваться только на пробелы между элементами. В тексте, который в кавычках, должно остаться по одному пробелу между словами,а если число в кавычках,то там пробелов не должно остаться. Текст в кавычках является частью элемента и он должен остаться в элементе. Как это сделать попроще в VBA, что посоветуете? Пример с макросом прилагается.Неопытный
Public Sub SplitNodeAttributes() Dim vOut() As Variant, vIn As Variant Dim LRow As Long, pSheet As Worksheet Dim pReg As Object, pMatch As Object Dim iRow As Long, iCol As Long, sVal As String
Set pSheet = ActiveSheet: LRow = pSheet.Cells(pSheet.Rows.Count, 1).End(xlUp).Row vIn = pSheet.Range(pSheet.Cells(1, 1), pSheet.Cells(LRow, 1)).Value ReDim vOut(1 To LRow, 0 To pSheet.Columns.Count - 2) Set pReg = CreateObject("VBScript.RegExp") pReg.Global = True: pReg.IgnoreCase = True pReg.Pattern = "<[а-я]+\d+|[а-я]+\d+="".*?"""
For iRow = 1 To LRow Set pMatch = pReg.Execute(vIn(iRow, 1)) If pMatch.Count = 0 Then vOut(iRow, 0) = vIn(iRow, 1) Else sVal = pMatch(0).Value If Mid$(sVal, 1, 1) = "<" Then sVal = Mid$(sVal, 2) vOut(iRow, 0) = sVal For iCol = 1 To pMatch.Count - 1 vOut(iRow, iCol) = pMatch(iCol).Value Next iCol End If Next iRow pSheet.Range(pSheet.Cells(1, 2), pSheet.Cells(LRow, pSheet.Columns.Count)).Value = vOut End Sub
[/vba] Хотя по мне, так лучше разбирать xml используя библиотеку Microsoft XML
Где-то так [vba]
Код
Public Sub SplitNodeAttributes() Dim vOut() As Variant, vIn As Variant Dim LRow As Long, pSheet As Worksheet Dim pReg As Object, pMatch As Object Dim iRow As Long, iCol As Long, sVal As String
Set pSheet = ActiveSheet: LRow = pSheet.Cells(pSheet.Rows.Count, 1).End(xlUp).Row vIn = pSheet.Range(pSheet.Cells(1, 1), pSheet.Cells(LRow, 1)).Value ReDim vOut(1 To LRow, 0 To pSheet.Columns.Count - 2) Set pReg = CreateObject("VBScript.RegExp") pReg.Global = True: pReg.IgnoreCase = True pReg.Pattern = "<[а-я]+\d+|[а-я]+\d+="".*?"""
For iRow = 1 To LRow Set pMatch = pReg.Execute(vIn(iRow, 1)) If pMatch.Count = 0 Then vOut(iRow, 0) = vIn(iRow, 1) Else sVal = pMatch(0).Value If Mid$(sVal, 1, 1) = "<" Then sVal = Mid$(sVal, 2) vOut(iRow, 0) = sVal For iCol = 1 To pMatch.Count - 1 vOut(iRow, iCol) = pMatch(iCol).Value Next iCol End If Next iRow pSheet.Range(pSheet.Cells(1, 2), pSheet.Cells(LRow, pSheet.Columns.Count)).Value = vOut End Sub
[/vba] Хотя по мне, так лучше разбирать xml используя библиотеку Microsoft XMLanvg
Добрый день! anvg ! Спасибо за помощь! Почти всё работает, за небольшим исключением, например, если взять такой текст: <Проверка ПN="1" П11="0.4" П12="0" П13="4.23" /> <Проверка ПN="2" П11="0.7" П12="0.876" П13="0" /> <Проверка ПN="3" П14="Текст3 " /> то почему-то пропускает элемент: Проверка ПN="1" Хотя в приведенном примере не пропускает, попробую разобраться с кодом.
Добрый день! anvg ! Спасибо за помощь! Почти всё работает, за небольшим исключением, например, если взять такой текст: <Проверка ПN="1" П11="0.4" П12="0" П13="4.23" /> <Проверка ПN="2" П11="0.7" П12="0.876" П13="0" /> <Проверка ПN="3" П14="Текст3 " /> то почему-то пропускает элемент: Проверка ПN="1" Хотя в приведенном примере не пропускает, попробую разобраться с кодом.Неопытный
зачем разбирать xml регулярными выражениями, если можно работать с ним, как с объектом?
. Добрый вечер! Вы имеете в виду Объект RegExp? Если в xml файле есть несколько разновидностей строк, то надо делать общий (сложный) для всех pattern, или лучше для каждой разновидности свой и потом как-то распознавать где какая разновидность и к ней применять соответствующий.
зачем разбирать xml регулярными выражениями, если можно работать с ним, как с объектом?
. Добрый вечер! Вы имеете в виду Объект RegExp? Если в xml файле есть несколько разновидностей строк, то надо делать общий (сложный) для всех pattern, или лучше для каждой разновидности свой и потом как-то распознавать где какая разновидность и к ней применять соответствующий.Неопытный
Сообщение отредактировал Неопытный - Среда, 18.09.2013, 23:32
Неопытный, В 4 строке нарушение структуры XML, после < идёт не название узла, а его атрибут (AttributeName="AttributeValue". Добавил учёт и этого, только вот теперь в столбце B будет не имя узла для таких случае, а ИмяАтрибута="ЕгоЗначение" - не запутаетесь?
nerv (Александр) Кстати, почему на вашей "маске" "[^"]+" не выводится начальный <? Не могу сообразить.
Неопытный, В 4 строке нарушение структуры XML, после < идёт не название узла, а его атрибут (AttributeName="AttributeValue". Добавил учёт и этого, только вот теперь в столбце B будет не имя узла для таких случае, а ИмяАтрибута="ЕгоЗначение" - не запутаетесь?
nerv (Александр) Кстати, почему на вашей "маске" "[^"]+" не выводится начальный <? Не могу сообразить.anvg
anvg! Большое спасибо! Освободили от изучения сложного и запутанного синтаксиса паттернов. Практически всё работает. За незначительным исключением : <Индекс>655030</Индекс> (не выводится индекс) и еще маленький вопрос: А в такой строчке: <Сбор ПN="09" П000000000013=" 00204 "> (где последние две цифры в П000000000013 любые) сделать так, чтобы в колонку выводилось не П000000000003="00204", а только" 00204 ", и сделать " 00204 " в виде "00204", лучше сделать в pattern или проще потом обработать в колонке двугими способами?
anvg! Большое спасибо! Освободили от изучения сложного и запутанного синтаксиса паттернов. Практически всё работает. За незначительным исключением : <Индекс>655030</Индекс> (не выводится индекс) и еще маленький вопрос: А в такой строчке: <Сбор ПN="09" П000000000013=" 00204 "> (где последние две цифры в П000000000013 любые) сделать так, чтобы в колонку выводилось не П000000000003="00204", а только" 00204 ", и сделать " 00204 " в виде "00204", лучше сделать в pattern или проще потом обработать в колонке двугими способами?Неопытный
Сообщение отредактировал Неопытный - Четверг, 19.09.2013, 10:07