I want to scan and match items of treeview1 in treeview2 and add child items to treeview2.
Here's my current code:
Dim FoundIt As Boolean, ii As Integer, ix As Integer
Dim NodX As Node, NodX2 As Node, namme As String
On Error Resume Next
For Each NodX In TreeView1.Nodes
ii = NodX.Index
For Each NodX2 In TreeView2.Nodes
ix = NodX.Index
On Error Resume Next
If NodX.FullPath = NodX2.FullPath Then
If TreeView1.Nodes(ii).Parent.Text = TreeView2.Nodes(ix).Parent.Text Then
If TreeView1.Nodes(ii).Parent.Image = 9 And TreeView1.Nodes(ii).Image = 3 Then
namme = TreeView2.Nodes(ix).Parent.Key
TreeView2.Nodes.Add namme, tvwChild, TreeView1.Nodes(ii).Parent.Child.Text, TreeView1.Nodes(ii).Parent.Child.Text, 5
Pause 0
End If
End If
End If
'Exit For
Next
Next
next
Currently, treeview1 items may have parent image as 9 and child as 3
so based on that I want to add all items that has image index 3 to treeview2 matching parent child section for each.
enter image description here
Here is code that should get you pretty close to what you want:
Dim objNode1 As Node
Dim objNode2 As Node
Dim objMatchNode As Node
Dim objChildNode1 As Node
Dim objChildNode2 As Node
Dim iCounter1 As Integer
Dim iCounter2 As Integer
Dim fFound As Boolean
On Error Resume Next
For Each objNode1 In TreeView1.Nodes
' Find matching node in Treeview2
For Each objNode2 In TreeView2.Nodes
If objNode2.Text = objNode1.Text Then
' Match found
Set objMatchNode = objNode2
Exit For
End If
Next
If Not objMatchNode Is Nothing Then
' Check all children
If objNode1.Children > 0 Then
' Get first Child
Set objChildNode1 = objNode1.Child
' Loop through all children
For iCounter1 = 1 To objNode1.Children
If objChildNode1.Image = 3 And objNode1.Image = 9 Then
' Check if it already exists in Treeview2
If objMatchNode.Children > 0 Then
' Get first Child
Set objChildNode2 = objMatchNode.Child
' Set Found flag to False
fFound = False
' Loop through all children
For iCounter2 = 1 To objMatchNode.Children
' Check for match
If objChildNode2.Text = objChildNode1.Text Then
fFound = True
Exit For
End If
' Get next node
Set objChildNode2 = objChildNode2.Next
Next
If Not fFound Then
' Add to Treeview2
TreeView2.Nodes.Add objMatchNode.Key, tvwChild, objChildNode1.Key, objChildNode1.Text, 3
End If
End If
End If
' Get next node
Set objChildNode1 = objChildNode1.Next
Next
End If
End If
' Give UI some time to do other things
DoEvents
Next
Related
Treeview1 has a-z zip names and each zip has child items.
Treeview2 has same zip names but each extra unwanted child items may exist. I need to remove the extra items from Treeview2.
Here's a solution that should work, with useful functions for later in your project:
Private Sub PruneTreeView(ByRef p_objSourceTreeView As TreeView, ByRef p_objTargetTreeView As TreeView)
Dim objSourceNode As Node
Dim objMatchNode As Node
Dim objSourceChildNode As Node
Dim objTargetChildNode As Node
Dim fFound As Boolean
Dim iNodeIndex As Integer
Dim sSummary As String
' Build summary string
sSummary = "Prune TreeView Summary:" & vbCrLf
' Get first node from Source TreeView
Set objSourceNode = p_objSourceTreeView.Nodes(1)
Do While Not objSourceNode Is Nothing
' Check if node has children, otherwise no need to look for match
If objSourceNode.Children > 0 Then
' Find matching node in Target TreeView
Set objMatchNode = GetMatchingNode(p_objTargetTreeView, p_objTargetTreeView.Nodes(1), objSourceNode)
If Not objMatchNode Is Nothing Then
sSummary = sSummary & "Source Node '" & objSourceNode.Text & "' Found in Target." & vbCrLf
' Check all children in Target Node
If objMatchNode.Children > 0 Then
' Set Found flag to False
fFound = False
' Get first Child of Target
Set objTargetChildNode = objMatchNode.Child
Do While Not objTargetChildNode Is Nothing
' Look for match in Source Tree
fFound = Not GetMatchingNode(p_objSourceTreeView, objSourceNode.Child, objTargetChildNode) Is Nothing
' Keep Index reference
iNodeIndex = objTargetChildNode.Index
sSummary = sSummary & "Target Child Node '" & objMatchNode.Text & ":" & objTargetChildNode.Text & "'"
' Go to next sibling
Set objTargetChildNode = GetNextSibling(p_objTargetTreeView, objTargetChildNode)
If fFound Then
sSummary = sSummary & " Found in Target." & vbCrLf
Else
' No Match found
sSummary = sSummary & " Not Found in Target: Deleting at Index " & iNodeIndex & vbCrLf
p_objTargetTreeView.Nodes.Remove iNodeIndex
End If
DoEvents
Loop
End If
End If ' MatchNode exists
End If ' Source Node Children > 0
' Go to next sibling
Set objSourceNode = GetNextSibling(p_objSourceTreeView, objSourceNode)
Loop
End Sub
The following are Helper functions I wrote to handle common tasks while looking up nodes:
Function GetMatchingNode(ByRef p_objTreeView As TreeView, ByRef p_objStartNode As Node, ByRef p_objCompareToNode As Node) As Node
Dim objNode As Node
' Get First Node
Set objNode = p_objStartNode
' Check all Siblings and match on Text property
Do While Not objNode Is Nothing
If objNode.Text = p_objCompareToNode.Text Then
' Match found
Set GetMatchingNode = objNode
Exit Do
Else
Set objNode = GetNextSibling(p_objTreeView, objNode)
End If
Loop
Set GetMatchingNode = objNode
End Function
Function GetNextSibling(ByRef p_objTreeView As TreeView, ByRef p_objNode As Node) As Node
If HasSibling(p_objTreeView, p_objNode) Then
Set GetNextSibling = p_objTreeView.Nodes(GetNextSiblingIndex(p_objNode))
Else
Set GetNextSibling = Nothing
End If
End Function
Function HasSibling(ByRef p_objTreeView As TreeView, ByRef p_objNode As Node) As Boolean
HasSibling = Not (p_objNode.LastSibling Is p_objNode)
End Function
Function GetNextSiblingIndex(ByRef p_objNode As Node) As Integer
With p_objNode
GetNextSiblingIndex = .Index + .Children + 1
End With
End Function
all credits go to Étienne Laneville
Private Sub PruneTreeView(ByRef p_objSourceTreeView As TreeView, ByRef p_objTargetTreeView As TreeView)
Dim objSourceNode As Node
Dim objMatchNode As Node
Dim objSourceChildNode As Node
Dim objTargetChildNode As Node
Dim fFound As Boolean
Dim iNodeIndex As Integer
Dim sSummary As String
' Build summary string
sSummary = "Prune TreeView Summary:" & vbCrLf
' Get first node from Source TreeView
Set objSourceNode = p_objSourceTreeView.Nodes(1)
Do While Not objSourceNode Is Nothing
' Check if node has children, otherwise no need to look for match
If objSourceNode.Children > 0 Then
' Find matching node in Target TreeView
Set objMatchNode = GetMatchingNode(p_objTargetTreeView, p_objTargetTreeView.Nodes(1), objSourceNode)
If Not objMatchNode Is Nothing Then
sSummary = sSummary & "Source Node '" & objSourceNode.Text & "' Found in Target." & vbCrLf
' Check all children in Target Node
If objMatchNode.Children > 0 Then
' Set Found flag to False
fFound = False
' Get first Child of Target
Set objTargetChildNode = objMatchNode.Child
Do While Not objTargetChildNode Is Nothing
' Look for match in Source Tree
fFound = Not GetMatchingNode(p_objSourceTreeView, objSourceNode.Child, objTargetChildNode) Is Nothing
' Keep Index reference
iNodeIndex = objTargetChildNode.Index
sSummary = sSummary & "Target Child Node '" & objMatchNode.Text & ":" & objTargetChildNode.Text & "'"
' Go to next sibling
Set objTargetChildNode = GetNextSibling(p_objTargetTreeView, objTargetChildNode)
If fFound Then
sSummary = sSummary & " Found in Target." & vbCrLf
Else
' No Match found
sSummary = sSummary & " Not Found in Target: Deleting at Index " & iNodeIndex & vbCrLf
p_objTargetTreeView.Nodes.Remove iNodeIndex
End If
DoEvents
Loop
End If
End If ' MatchNode exists
End If ' Source Node Children > 0
' Go to next sibling
Set objSourceNode = GetNextSibling(p_objSourceTreeView, objSourceNode)
DoEvents
Loop
End Sub
Listview1,Listview2 compare both parent and child items.
the items are named some-name.zip a-z and child files are loaded in each parent.
Listview1 is Target
Listview2 is my loaded files i want to compare with Listview1
image = 4 'green icon
image = 3 ' Red icon
Compare 2 listview and if it matches then listview2 image = 4 else image = 3
if child matches then image = 4 else image = 3
startt = True
Dim FoundIt As Boolean, ii As Integer, ix As Integer
Dim NodX As Node, NodX2 As Node
For Each NodX In TreeView1.Nodes
ix = NodX.Index
For Each NodX2 In TreeView2.Nodes
ii = NodX2.Index
If NodX.FullPath = NodX2.FullPath Then
FoundIt = True
On Error Resume Next
Exit For
End If
DoEvents
'pause 0
If TreeView2.Nodes(ii).Index = TreeView2.Nodes.Count - 0 Then
Exit For
Exit Sub
End If
Next
If FoundIt Then
TreeView1.Nodes(ix).Image = 4
TreeView2.Nodes(ii).Image = 4
Else
TreeView2.Nodes(ix).Image = 3
End If
If TreeView2.Nodes(ii).Index = TreeView2.Nodes.Count - 0 Then
DoEvents
'Call Command16_Click
If downnn = True Then
Exit For
Exit Sub
End If
End If
FoundIt = False
Next
End Sub
Here's a Sub that takes in two TreeView controls and compares their contents. If a node in the Source TreeView doesn't have a corresponding node in the Target TreeView, its Image gets set to 3. Otherwise, Image is set to 4:
Private Sub CompareTreeViews(ByRef p_objSourceTreeView As TreeView, ByRef p_objTargetTreeView As TreeView)
Dim objSourceNode As Node
Dim objTargetNode As Node
Dim objMatchNode As Node
Dim objSourceChildNode As Node
Dim objTargetChildNode As Node
Dim iSourceCounter As Integer
Dim iTargetCounter As Integer
Dim fFound As Boolean
Dim fChildrenMatch As Boolean
On Error Resume Next
For Each objSourceNode In p_objSourceTreeView.Nodes
' Reset ChildrenMatch flag, used to track if all children match
fChildrenMatch = True
' Find matching node in Source TreeView
For Each objTargetNode In p_objTargetTreeView.Nodes
If objTargetNode.Text = objSourceNode.Text Then
' Match found
Set objMatchNode = objTargetNode
Exit For
End If
Next
If Not objMatchNode Is Nothing Then
' Check all children
If objSourceNode.Children > 0 Then
' Get first Child and Loop through all Children
Set objSourceChildNode = objSourceNode.Child
For iSourceCounter = 1 To objSourceNode.Children
' Check if it exists in Target Treeview
If objMatchNode.Children > 0 Then
' Set Found flag to False
fFound = False
' Get first Child and Loop through all Children
Set objTargetChildNode = objMatchNode.Child
For iTargetCounter = 1 To objMatchNode.Children
' Check for match
If objTargetChildNode.Text = objSourceChildNode.Text Then
fFound = True
Exit For
End If
' Get next node
Set objTargetChildNode = objTargetChildNode.Next
Next
' Mark Node
Select Case fFound
Case True
objSourceChildNode.Image = 4
Case False
objSourceChildNode.Image = 3
fChildrenMatch = False
End Select
' Get next node
Set objSourceChildNode = objSourceChildNode.Next
End If
DoEvents
Next ' Source Child
End If
End If
Select Case fChildrenMatch
Case True
objSourceNode.Image = 4
Case False
objSourceNode.Image = 3
End Select
DoEvents
Next ' Source Node
End Sub
Based on your question, you want to call the Sub this way:
Label1.Caption = "Comparing..."
CompareTreeViews TreeView2, TreeView1
Label1.Caption = "Done!"
Given the following Images:
image = 4 is green icon
image = 3 is red icon
My ii index is not moving onto next item, it shows the same index as it passes through the loop as I have checked by stepping through each loop.
I want to change all child items icon to Image = 3
Dim FoundIt As Boolean, ii As Integer, ix As Integer
Dim NodX As Node, NodX2 As Node
On Error Resume Next
For Each NodX2 In TreeView2.Nodes
If NodX2.Parent.Image = 4 Then
ii = NodX2.Child.Index
TreeView2.Nodes(ii).Parent.Child.Image = 3
Debug.Print ii ' when i step through it repeats the same index,only the first child changes to image = 3
Pause 0
End If
Next
Your first For Each loop should use NodX. Inside that loop you can iterate through all children of NodX using NodX2:
Dim objNode As Node
Dim objChildNode As Node
Dim iCounter As Integer
Dim fProceed As Boolean
On Error Resume Next
For Each objNode In TreeView2.Nodes
If objNode.Image = 4 Then
' Check for Children
If objNode.Children > 0 Then
' Get first Child
Set objChildNode = objNode.Child
' Initialize flag
fProceed = True
' Loop through all children
For iCounter = 1 To objNode.Children
' Set image to 3 if it was 5
If objChildNode.Image <> 5 Then
fProceed = False
Exit For
End If
' Get next node
Set objChildNode = objChildNode.Next
Next
If fProceed Then
' Get first Child again
Set NodX2 = NodX.Child
' Loop through all children
For iCounter = 1 To objNode.Children
' Set image to 3
objChildNode.Image = 3
' Get next node
Set objChildNode = objChildNode.Next
Next
End If
End If
End If
Next
This is the code i have, after execution it starts to delete unmatched items from treeview2.
if some zip files does not contain matched files than the contents of zip file gets deleted but zip remains with the size of 1k and its empty.
Instead of leaving the dead empty zip can i rather move the zip to newly created folder in the zip path and leave the contents as it is and move on.
Private Sub Command9_Click()
Dim objNode1 As Node
Dim objNode2 As Node
Dim objMatchNode As Node
Dim objChildNode1 As Node
Dim objChildNode2 As Node
Dim iCounter1 As Integer
Dim iCounter2 As Integer
Dim fFound As Boolean
On Error Resume Next
For Each objNode1 In TreeView2.Nodes
' Find matching node in Treeview2
For Each objNode2 In TreeView1.Nodes
If objNode2.Text = objNode1.Text Then
' Match found
Set objMatchNode = objNode2
Exit For
End If
Next
If Not objMatchNode Is Nothing Then
' Check all children
If objNode1.Children > 0 Then
' Get first Child
Set objChildNode1 = objNode1.Child
' Loop through all children
For iCounter1 = 1 To objNode1.Children
'If objChildNode1.Image = 3 And objNode1.Image = 9 Then
' Check if it already exists in Treeview2
If objMatchNode.Children > 0 Then
' Get first Child
Set objChildNode2 = objMatchNode.Child
' Set Found flag to False
fFound = False
' Loop through all children
For iCounter2 = 1 To objMatchNode.Children
' Check for match
If objChildNode2.Text = objChildNode1.Text Then
fFound = True
Exit For
End If
' Get next node
Set objChildNode2 = objChildNode2.Next
DoEvents
Next
If fFound Then
' Add to Treeview2
'TreeView2.Nodes.Add objMatchNode.Key, tvwChild, objChildNode1.Key, objChildNode1.Text, 3
Else
DeleteFileFromArchive objChildNode1.Text, "C:\Users\sarah\Desktop\rom test\" & objNode2.Text
End If
End If
' End If
' Get next node
Set objChildNode1 = objChildNode1.Next
DoEvents
Next
End If
End If
Next
End Sub
The following code will find the nodes that are empty and delete them. You can add code to delete the actual Zip file in here, where it says "Delete Zip":
Private Sub DeleteFromTreeView(ByRef p_objTreeView As TreeView)
Dim objNode As Node
Dim fDelete As Boolean
Dim iDeleteIndex As Integer
Dim sDeleteName As String
' Get first node from TreeView
Set objNode = p_objTreeView.Nodes(1)
Do While Not objNode Is Nothing
' Set Delete flag to false
fDelete = False
' Check if node has children, otherwise delete file
If objNode.Children = 0 Then
fDelete = True
iDeleteIndex = objNode.Index
sDeleteName = objNode.Text
End If
' Go to next sibling
Set objNode = GetNextSibling(p_objTreeView, objNode)
If fDelete Then
' Delete Zip
p_objTreeView.Nodes.Remove iDeleteIndex
End If
Loop
End Sub
You can run this code on your TreeView after your existing code. The sDeleteName will contain the name of the Zip you want to delete, just add some code to delete the file using something like this:
Sub DeleteFile(p_sFilePath)
Dim objFSO As New FileSystemObject
If objFSO.FileExists(p_sFilePath) Then objFSO.DeleteFile p_sFilePath
End Sub
This Sub uses the FileSystemObject so make sure you add a reference to Microsoft Scripting Runtime in your project.
You will also need the following Helper functions you might already have in your project:
Function GetNextSibling(ByRef p_objTreeView As TreeView, ByRef p_objNode As Node) As Node
If HasSibling(p_objTreeView, p_objNode) Then
Set GetNextSibling = p_objTreeView.Nodes(GetNextSiblingIndex(p_objNode))
Else
Set GetNextSibling = Nothing
End If
End Function
Function HasSibling(ByRef p_objTreeView As TreeView, ByRef p_objNode As Node) As Boolean
HasSibling = Not (p_objNode.LastSibling Is p_objNode)
End Function
Function GetNextSiblingIndex(ByRef p_objNode As Node) As Integer
With p_objNode
GetNextSiblingIndex = .Index + .Children + 1
End With
End Function
I have a treeview control on the form which looks like:
I want to iterate the treeview and write the contents of the treeview to ini file. So the ini file for the given tree would look like:
[EnvironmentSystem]
UpdateRate=50.0
InclinationAngle=20.7
Latitude=34.0
[Reflection]
NumReflectionLevel=5
NumSunLightLevel=5
NumWeatherLevel=3
TextureNameFormat=Reflection%01d%01d%02d.tga
[CloudsClear]
MaxClouds=48
MaxCloudParticles=51
3DCloudMaterial=CloudMaterial
3DCloudHorizontalSize=1400.0
3DCloudVerticalSize=600.0
3DCloudSizeDeviation=0.6
3DCloudParticleDensity=2.4
ParticleSize=300.0
ParticleSizeDeviation=0.3
MinBaseAltitude=400.0
MaxBaseAltitude=2450.0
UseBottomRow=TRUE
Here is the code that I have written:
Private Sub TvSaveToIniBtn_Click()
Dim nodx As Node
Dim i As Long
Dim sectionCount As Integer
sectionCount = TreeView1.Nodes(1).Children
Set nodx = TreeView1.Nodes(1).Child.FirstSibling
For i = 1 To sectionCount
SaveNodesToIni (nodx.Text)
Set nodx = nodx.Next
Next
End Sub
Sub SaveNodesToIni(sName As Variant)
Dim tvn As Node
Set tvn = TreeView1.Nodes(sName)
Dim chil As Integer
Dim a As Integer
Dim ret As Integer
Dim keyValuePair() As String
Dim nElements As Integer
chil = tvn.Children: If chil = 0 Then Exit Sub ' if no children the exit
Set tvn = tvn.Child.FirstSibling
For a = 1 To chil
keyValuePair = Split(tvn.Text, "=")
nElements = UBound(keyValuePair) - LBound(keyValuePair) + 1
If nElements > 0 Then
ret = WritePrivateProfileString(sName, keyValuePair(0), keyValuePair(1), "C:\\MyPrograms\\config.ini")
End If
Set tvn = tvn.Next
Next
End Sub
It is not giving the correct output, it gets stuck at the second section of reflection and is not able to read the third one. Something wrong with the code.