Циклический просмотр строкового значения на основе вхождений значения и разбор значений в новые строки - PullRequest
0 голосов
/ 14 мая 2019

Итак, я пытаюсь сделать что-то немного более сложное, но я не уверен, как справиться с этим, так как я очень плохо знаком с синтаксисом кодирования VBA (но с некоторым опытом в других языках программирования)

В основном,Я пытаюсь проанализировать этот текст:

<Step>

    <Description>

        This is a description

    </Description>

    <Validation>

        This is how we validate

    </Validation>

</Step>

<Step>

    <Description>

        This is another description.

    </Description>

    <Validation>

        And this is another validation.

    </Validation>

</Step>

И он анализируется на основе ключевых токенов, которые начинают и заканчивают текст.Итак, начальные операторы - это квадратные скобки, за которыми следует дескриптор поля, и поэтому они закрыты квадратными скобками и косой чертой.

Сейчас я использую UDF с именем Supermid (взято из этого сайта), который возвращает значения между двумя заданными словами (в данном случае начальные и конечные токены, которые я только что описал).Поэтому, если приведенный выше текст находится в ячейке A1, Supermid(A1, "<Validation>","</Validation>") вернет сообщение «Вот как мы проверяем».

У меня возникла проблема, когда я хочу перебрать указанный выше текст и проанализировать егоотдельно для каждого <Step> </Step> экземпляра.

Так как есть два <Steps>, инкапсулирующих токен описания и токен проверки, я бы хотел разделить их.

Таким образом, это выглядело бы примерно так:

Step 1  This is a description   This is how we validate
Step 2  This is another description And this is another validation

По сути, я хочу пройтись по всему полю, и каждое обнаруженное обрабатывается как его собственная сущность, которая повторяется иразбирается в соответствии с соответствующими столбцами (столбец B для описания, столбец C для проверки)

Я думаю, что псевдокод будет выглядеть примерно так, если я включу supermid и значение, которое я хочуparse находится в ячейке A1:

For i = 0; i < Steps; i++:
     Range("C1").Formula = "=supermid($A1, ""<Feature Description>"", ""</Feature Description>"")"
     Range("D1").Formula = "=supermid($A1, ""<Feature Validation>"", ""</Feature Validation>"")"]
     Range("B1").Formula = ""Step" & i" //this is to clarify which step number it is

Моя главная проблема - преобразование этого псевдо-кода в синтаксис VBA, так как я никогда не работал с ним в глубокой степени, и я учусь по ходу дела.Я думаю, что мне нужно посчитать вхождения Beginning <Step>, сохранить его в Long и использовать его в качестве итератора для 'i'.

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

Есть ли способ итерировать номер ячейки для каждой итерации цикла?И как я могу ссылаться на это значение «i» при отображении «Шаги»?

Если кто-нибудь может указать мне правильное направление, это будет ПОГОДНО оценено!

Спасибо !!!

Ответы [ 3 ]

1 голос
/ 14 мая 2019

Если у вас Excel 2016+ с функцией TEXTJOIN, вы можете использовать встроенные функции Excel. (Если у вас их нет, вы можете запрограммировать нечто подобное в VBA).

  • Я вставил ваш документ в A1:A16 (удаляя посторонние переводы строки).
  • Я превратил его в действительный документ XML, "обернув" его в два других токена <t></t>
  • XPATH: //Step[1]/* возвращает всех потомков шага # 1
  • Затем я использовал функцию FILTERXML, чтобы извлечь каждый Шаг , используя выражение XPath, и соединил результаты с помощью функции TEXTJOIN.

=IFERROR(TEXTJOIN(" ",TRUE,FILTERXML("<t>" &TEXTJOIN(CHAR(10),TRUE,$A$1:$A$16)& "</t>","//Step[" & ROWS($1:1)&"]/*")),"")

Функция ROWS при перетаскивании генерирует число Step для извлечения. Функция IFERROR вернет пустую строку, когда вы вернете все шаги

Формула выше - это массив формула. Поскольку это формула массива, вам необходимо «подтвердить» ее, удерживая ctrl + shift при нажатии , введите . Если вы сделаете это правильно, Excel поместит фигурные скобки {...} вокруг формулы, как показано в строке формул

enter image description here

0 голосов
/ 14 мая 2019

Поэтому я решил не идти по XML-маршруту (поскольку при использовании этих типов тегов я не собирался это делать, это было больше, чем просто соглашение, с которым я был знаком в HTML), а вместо этого просто выбрал крайне неудачный маршрут VBA.

Вот что я придумал:

Dim cell As Range
Dim rng As Range
Dim Jdescription As String
Dim steps As Integer
Dim name, desc, valid As Integer
Dim newDescription As String
name = 1
desc = 1
valid = 1

Set rng = Sheets("Scratch2").Range("A1:A" & LastRowDescription)
For Each cell In rng.Cells
    Jdescription = cell.Value
    steps = (Len(Jdescription) - Len(Replace(Jdescription, "<Step>", ""))) / Len("<Step>")
    For i = 1 To steps
         newDescription = Left(Jdescription, 7 + InStr(Jdescription, "</Step>"))
         Sheets("Scratch2").Cells(name, 2).Value = "Step " & i
         name = name + 1
         Sheets("Scratch2").Cells(desc, 3).Value = SuperMid(newDescription, "<Description>", "</Description>")
         desc = desc + 1
         Sheets("Scratch2").Cells(valid, 4).Value = SuperMid(newDescription, "<Validation>", "</Validation>")
         valid = valid + 1
         Jdescription = Replace(Jdescription, newDescription, "")
    Next i
Next cell
0 голосов
/ 14 мая 2019

Например:

Sub Tester()

    'in your VBProject, add a reference to:
    '  "Microsoft XML v6.0"

    Dim steps As Object, step As Object, i As Long
    Dim oXMLDoc As New MSXML2.DOMDocument60, xmlData

    'XML needs a root element
    xmlData = "<?xml version=""1.0""?><data>" & ActiveSheet.Range("A5").Value & "</data>"

    oXMLDoc.LoadXML xmlData
    oXMLDoc.setProperty "SelectionLanguage", "XPath"

    Set steps = oXMLDoc.SelectNodes("//data/Step")
    For Each step In steps
        i = i + 1
        Debug.Print "****** Step" & i
        Debug.Print "Description", step.SelectSingleNode("Description").nodeTypedValue
        Debug.Print "Validation", step.SelectSingleNode("Validation").nodeTypedValue
    Next step

End Sub

Я храню ваши данные в ячейке листа, но они могут поступать откуда угодно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...