I am creating a console that finds blocks with a certain attribute value and replace it with another (akin to find(textbox1) and replace(textbox2) in Word).
For Each blk In ss
If (blk.HasAttributes) Then
attr = blk.GetAttributes()
For i = 0 To UBound(attr)
If attr(i).TagString = "item" And _
attr(i).TextString = TextBox1.Value Then
attr(i).TextString = TextBox2.Value
Exit For
End If
Next
End If
Next
Although I have solved it, a new problem arose. My colleagues now want to filter by 2 attributes. For example, the attribute with the tag "item" can have the value "coke". But you might want to change only the name of the blocks that contain the soda and not the drug. As such, I picked another attribute which differentiates them (textbox11).
For Each blk In ss
If (blk.HasAttributes) Then
attr = blk.GetAttributes()
For i = 0 To UBound(attr)
If attr(i).TagString = "origin" And attr(i).TextString = TextBox11.Value Then
attr = 0
attr = blk.GetAttributes()
For o = 0 To UBound(attr)
If attr(i).TagString = "item" And _
attr(i).TextString = TextBox1.Value Then
attr(i).TextString = TextBox2.Value
Exit For
End If
End If
Next
End If
Next
But it's not working. How would you approach the problem?
Assuming that I've correctly understood what you are looking to achieve with the program, perhaps the following approach would suffice:
Dim flg As Boolean
Dim idx As Long
For Each blk In ss
If blk.HasAttributes Then
attr = blk.GetAttributes()
flg = False
idx = -1
For i = 0 To UBound(attr)
Select Case attr(i).TagString
Case "origin"
If attr(i).TextString = TextBox11.Value Then flg = True
Case "item"
idx = i
End Select
Next i
If flg And idx >= 0 Then
If attr(idx).TextString = TextBox1.Value Then
attr(idx).TextString = TextBox2.Value
End If
End If
End If
Next blk
Since we cannot make the assumption that the origin
attribute will be encountered before the item
attribute within the array of attributes held by the block, the above code iterates over the entire array and populates the values of two variables if given conditions are satisfied (specifically, if the origin
attribute is encountered and contains a specific value, and if the item
attribute is encountered whilst iterating over the array).
You could slightly improve the efficiency for blocks with many attributes by testing the values of flg
& idx
on each iteration of the for
loop and exiting the for
loop if these hold appropriate values, or alternatively, you could use a Do
or While
loop which tests these variables on each iteration (along with the magnitude of the i
variable) to avoid the use of Exit
; but I should imagine that the performance improvement would be negligible in both cases.