I have data in a delimited text file containing list of items and their relationship with each other, as shown below
where each Item Id is distinct and parent wbs column shows the relationship with parent items.
i am able to import the above data to excel, but unable to figure out how to structure them in tree format in excel and also make sure that under each node the items are sorted again by their sequence numbers
For i = 3 To LastRow
Dim found As Boolean = False
For k = 2 To wbssht.UsedRange.Rows.Count
If wbssht.Cells(k, 1).value = sht.Cells(i, 3).value Then
wbssht.Rows(k + 1).insert
wbssht.Cells(k + 1, 1).value = sht.Cells(i, 1).value
wbssht.Cells(k + 1, 3).value = wbssht.Cells(k, 3).value + 2
wbssht.Cells(k + 1, 2).value = Space(wbssht.Cells(k + 1, 3).value) & sht.Cells(i, 2).value
wbssht.Cells(k + 1, 4).value = sht.Cells(k, 3).value 'parentwbs
wbssht.Cells(k + 1, 5).value = sht.Cells(k, 4).value 'sequence
found = True
Exit For
End If
Next
If found = False Then
wbssht.Cells(wbssht.UsedRange.Rows.Count + 1, 1).value = sht.Cells(i, 1).value
wbssht.Cells(wbssht.UsedRange.Rows.Count, 2).value = sht.Cells(i, 2).value
wbssht.Cells(wbssht.UsedRange.Rows.Count, 3).value = 0
wbssht.Cells(wbssht.UsedRange.Rows.Count, 4).value = sht.Cells(i, 3).value
wbssht.Cells(wbssht.UsedRange.Rows.Count, 5).value = sht.Cells(i, 4).value
End If
Next
I am trying to achieve an indented output structure as image below in excel.
I know its probably really simple, but may need some different approach.
Try this code:
Private Sub TreeView1_KeyUp(KeyCode As Integer, ByVal Shift As Integer)
'Checking what button is pressed.
Select Case KeyCode
'If F5 is pressed.
Case Is = 116
'Declarations.
Dim RngList As Range
Dim RngTarget As Range
Dim DblNameOffset As Double
Dim DblParentOffset As Double
Dim DblSequenceOffset As Double
Dim StrMarker As String
Dim NodNode As Node
Dim DblRow As Double
Dim DblCounter01 As Double
Dim DblItemMax
Dim ObjTreeView As Object
'Setting RngList as the first value in the Item ID column.
Set RngList = Sheets("Sheet1").Range("A2")
'Setting ObjTreeView.
Set ObjTreeView = ActiveSheet.Shapes("TreeView1")
'Setting StrMarker as a value that won't be in any Item ID value nor in any Sequence value.
StrMarker = " | "
'Setting the variables as offests of each column of data from the Item ID column.
DblNameOffset = 1
DblParentOffset = 2
DblSequenceOffset = 3
'Changing RngList to cover the whole Item ID list.
Set RngList = RngList.Parent.Range(RngList, RngList.End(xlDown))
'Setting DblItemMax as the count of Item IDs.
DblItemMax = Excel.WorksheetFunction.CountA(RngList)
'Checking that RngList does not contain any non unique value, non numeric value, blank cell.
For Each RngTarget In RngList
Select Case True
Case Is = (Excel.WorksheetFunction.CountIf(RngList, RngTarget.Value) > 1)
MsgBox "Non unique item ID found. The treeview will not be updated.", vbCritical + vbOKOnly, "Invalid item ID: " & RngTarget.Value
Exit Sub
Case Is = (RngTarget.Value = "")
MsgBox "Blank ID found. The treeview will not be updated.", vbCritical + vbOKOnly, "Invalid item ID in cell " & RngTarget.Address(False, False)
Exit Sub
Case Is = (IsNumeric(RngTarget.Value) = False)
MsgBox "Non numeric item ID found. The treeview will not be updated.", vbCritical + vbOKOnly, "Invalid item ID: " & RngTarget.Value
Exit Sub
End Select
Next
'Clearing ObjTreeView of any previous nodes.
ObjTreeView.OLEFormat.Object.Object.Nodes.Clear
'Covering each Item ID from the smalles to the greatest.
For DblCounter01 = 1 To DblItemMax
'Setting DblRow as the number of row in RngList that contains the given Item ID.
With Excel.WorksheetFunction
DblRow = .Match(.Small(RngList, DblCounter01), RngList, 0)
End With
'Setting RngTarget as the cell that contains the given Item ID.
Set RngTarget = RngList.Cells(DblRow, 1)
'Checking if the given parent name exist in RngList.
If Excel.WorksheetFunction.CountIf(RngList, RngTarget.Offset(0, DblParentOffset).Value) = 0 Then
'If it doesn't exist, the new node is added with no parent node.
ActiveSheet.Shapes("TreeView1").OLEFormat.Object.Object.Nodes.Add , , "K" & RngTarget.Value, RngTarget.Offset(0, DblSequenceOffset) & StrMarker & RngTarget.Offset(0, DblNameOffset)
Else
'If it exists, the new node is added under its parent node.
ActiveSheet.Shapes("TreeView1").OLEFormat.Object.Object.Nodes.Add "K" & RngTarget.Offset(0, DblParentOffset), tvwChild, "K" & RngTarget.Value, RngTarget.Offset(0, DblSequenceOffset) & StrMarker & RngTarget.Offset(0, DblNameOffset)
End If
Next
'Sorting each node (they were added with the Sequence value at the beginning of it text).
For Each NodNode In ActiveSheet.Shapes("TreeView1").OLEFormat.Object.Object.Nodes
NodNode.Sorted = True
Next
'Cutting out the sequence value from the text of each node using the properly placed StrMarker.
For Each NodNode In ActiveSheet.Shapes("TreeView1").OLEFormat.Object.Object.Nodes
NodNode.Text = Split(NodNode.Text, StrMarker)(1)
Next
End Select
End Sub
It's a private sub that will activate when you press F5 while the treeview is selected. Therefore you'll have to place it in the module of the sheet where the treeview is located. It assumes that your treeview is named TreeView1. It also assumes that your list is placed in the cells A1 of a sheet named Sheet1; that means that in cell A1 of Sheet1 you'll find the header "Item ID" while in cell A2 you'll find the first ID. Note that you can have the list in one sheet and the treeview in another one. Anyway you can edit the code itself accordingly to your needs (perhaps you can change the list address, the treeview name or the key to be pressed to activate it). Other paramaters can also be costumized.
The code checks for any empty, non numeric non unique Item ID and if it finds any of them it terminates itself.
The list can be sorted in any order. The code should work anyway. In your data sample the first item (27521) has a parent name (18133) with no match in the Item ID column. In case like this, the code create a node with no parent node. In any case it is assumed that any Item ID has a father with a lower Item ID.