Thanks, I hashed this together. Ok well this isnt what u suggested exactly but i use an array to track the ID's already added then cycle through the the array querying the database for records where the ID in the array = the IDP field.
Im not a great programmer but this works. BUT it makes a lot of record calls if the tree is big. Any further comments would be great. (copy it into notpad and it will look nicer.
Nodes = rsCats.RecordCount ' count total number of records / nodes
NodeFree = 1 ' next free position in array
NodeC = 0 ' current position to query against categoryIDP
NodeIDs(0) = 0 ' set the initial node to the root.
While Nodes > NodeC
rsCats.Close
sqlstr = "Select * From Categories where categoryidp = " & NodeIDs(NodeC)
rsCats.Open sqlstr, strConn, adOpenStatic, adLockBatchOptimistic, adCmdText
While Not rsCats.EOF
Elements = Elements + 1
Id = "ID" & rsCats.Fields("categoryid"

.Value
Idp = "ID" & rsCats.Fields("categoryidp"

.Value
Item = rsCats.Fields("categoryname"

.Value
Set tmpnode = TreeView1.Nodes.Add(Idp, tvwChild, Id, Item)
NodeIDs(NodeFree) = rsCats.Fields("categoryid"

.Value
NodeFree = NodeFree + 1
rsCats.MoveNext
Wend
NodeC = NodeC + 1 ' increment to check next node ID in array
Wend