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
Related
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!"
How do I execute my timer1.enabled=true after TreeView FOR statement has reached the last item. My timer starts counting while the treeview is working still.
This is the code I have so far.
Private Sub Command17_Click()
Dim objRootNode As Node
Dim objChildNode As Node
Dim iRootCounter As Integer
Dim iChildCounter As Integer
Dim countt As Integer
Dim ii As Integer
For iRootCounter = 1 To TreeView2.Nodes.Count
ii = TreeView2.Nodes(iRootCounter).Index
Set objRootNode = TreeView2.Nodes(iRootCounter)
If objRootNode.Image = 4 Then
Set objChildNode = objRootNode.Child ' Gets first child
For iChildCounter = 1 To objRootNode.Children
If objChildNode.Image = 3 Then
objRootNode.Image = 9
End If
Set objChildNode = objChildNode.Next ' Get next node
Next
End If
If TreeView2.Nodes(iRootCounter).Index = TreeView2.Nodes.Count - 0 Then
If startt = True Then
Timer1.Enabled = True
Exit For
End If
End If
Next
End Sub
When I run this code, the treeview items remain in processing mode, meaning it's still doing its job changing image index for each item after I run another code, then this button gets triggered.
Just add Timer1.Enabled = False at the beginning of the TreeView update. Then, set it back to True before exiting.
Better yet, stop the timer in the Timer1_Timer event handler:
Private Sub Timer1_Timer()
' Stop timer until all code is execute
Timer1.Enabled = False
Command17_Click
' Restart timer
Timer1.Enabled = True
End Sub
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
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'd like to use excel 2010 to realize a function to first compare values from 2 different Excel sheets and then sort them based on another column value.
For example:
In sheet 1, I've got:
Name Value
Test 1 100.5
Test 1 200.6
Test 1 300.3
Test 2 100.8
Test 2 200.6
Test 3 200.5
In sheet 2, I've got :
Name
Test 1
Test 1
Test 1
Test 3
what I want to achieve is if the name from sheet 1 is not in sheet 2, delete the whole line in sheet 1 and sort by descending the name based on the column value.
Desired:
Name Value
Test 1 300.3
Test 1 200.6
Test 1 100.5
Test 3 200.5
Here is what I get so far:
Sub test()
Dim wb As Workbook
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim i As Integer, j As Integer
Dim lastRow1 As Integer, lastRow2 As Integer
On Error GoTo 0
Set wb = ActiveWorkbook
Set ws1 = wb.Worksheets("Sheet1")
Set ws2 = wb.Worksheets("Sheet2")
lastRow1 = ws1.UsedRange.Rows.Count
lastRow2 = ws2.UsedRange.Rows.Count
For i = 2 To lastRow1
For j = 2 To lastRow2
If ws1.Cells(i, 1).Value <> "" Then 'This will omit blank cells at the end (in the event that the column lengths are not equal.
If InStr(1, ws2.Cells(j, 1).Value, ws1.Cells(i, 1).Value, vbTextCompare) < 1 Then
Rows(i).EntireRow.delete
Exit For
End If
End If
Next j
Next i
End Sub
Please suggest and help. thank you very much in advance.
I changed your code so it is working:
Sub test()
Dim wb As Workbook
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim i As Integer, j As Integer
Dim lastRow1 As Integer, lastRow2 As Integer
On Error GoTo 0
Set wb = ActiveWorkbook
Set ws1 = wb.Worksheets("Sheet1")
Set ws2 = wb.Worksheets("Sheet2")
lastRow1 = ws1.Cells(Rows.Count, 1).End(xlUp).Row 'last used cell in column A
lastRow2 = ws2.Cells(Rows.Count, 1).End(xlUp).Row 'last used cell in column A
Dim same As Boolean
same = False
For i = lastRow1 To 2 Step -1 'bottom to top
For j = 2 To lastRow2
Debug.Print ws1.Cells(i, 1).Value
Debug.Print ws2.Cells(j, 1).Value
If ws1.Cells(i, 1).Value <> "" Then 'This will omit blank cells at the end (in the event that the column lengths are not equal.
If ws1.Cells(i, 1).Value = ws2.Cells(j, 1).Value Then
same = True 'set True if match
End If
End If
Next j
If same = False Then 'if no match
Rows(i).EntireRow.Delete
End If
same = False
Next i
'sort
lastRow1 = ws1.Cells(Rows.Count, 1).End(xlUp).Row
Range("A2:B" & lastRow1).Sort key1:=Range("A2:A" & lastRow1), order1:=xlAscending, Header:=xlNo, key2:=Range("B2:B" & lastRow1), order2:=xlAscending, Header:=xlNo
End Sub
Still thinking about the rest of the answer, but in advance I would advise you to start at the bottom of the list (so from lastrow to the second row) The reason for this is that you are removing rows which your counter does not take into account. You may also want to look into the MATCH function in Excel to see if a certain value is used in a list instead of going through the whole list.