How to speed up a treeview population in Access? I have the following function that causes a significant visual jittering and lag in my access database - This is a treeview selection based on data in a table (tblDATA) with the fields:
Object | Attribute | Property | Value
I have tried echo and me.painting but figured my actual for loops need to be looked at for optimisation - wondering if there is a better way to cycle through a Recordset and populate a Treeview ?
' [1] Update the treeview
'------------------------------------

Private Sub btnUpdateFilter_Click()
    
    'Me.Painting = False
    'Echo False
    'DoCmd.Hourglass True
    
    Dim sArea As String, N As Integer
    Dim oData_distinct As DAO.Recordset
    Dim oData As DAO.Recordset
    Dim oNone As DAO.Recordset
    Dim rs As DAO.Recordset
    Dim element As Variant
    Dim Arr_distinct() As Variant
    
    If IsNull(cbxAttributeFilter01) Or IsNull(cbxPropertyFilter01) Then Exit Sub
    

    Set oData_distinct = CurrentDb.OpenRecordset(&quot;SELECT DISTINCT [Value] FROM tblData WHERE Attribute = &quot; &amp; cbxAttributeFilter01 _
                                                &amp; &quot; AND Property = &quot; &amp; cbxPropertyFilter01, dbOpenSnapshot)
    
    Set oNone = CurrentDb.OpenRecordset(&quot;SELECT [Tagname] FROM tblData WHERE NOT Attribute = &quot; &amp; cbxAttributeFilter01 _
                                                &amp; &quot; AND NOT Property = &quot; &amp; cbxPropertyFilter01, dbOpenSnapshot)
    
    Set oData = CurrentDb.OpenRecordset(&quot;SELECT [Tagname], [Value] FROM tblData WHERE [Attribute] = &quot; &amp; cbxAttributeFilter01 _
                                                &amp; &quot; AND [Property] = &quot; &amp; cbxPropertyFilter01, dbOpenSnapshot)
    
    
    If oData.RecordCount = 0 Then TreeView.Nodes.Clear: Exit Sub
    
    Arr_distinct = oData_distinct.GetRows(oData_distinct.RecordCount)
    
    TreeView.Nodes.Clear
    
    ' Standard
    TreeView.Nodes.Add , , &quot;MISC&quot;, &quot;MISC&quot;
    For Each element In Arr_distinct
        If Not element = &quot;&quot; Then
            If IsNumeric(element) Then element = &quot;_&quot; &amp; element
            TreeView.Nodes.Add , , element, element    ' ADD Parent
        End If
    Next element
    
    Dim sTemp As String
    
    With oData
        .MoveFirst
        Do While Not .EOF
            sTemp = !Value
            If IsNumeric(sTemp) Then sTemp = &quot;_&quot; &amp; sTemp
            If sTemp = &quot;&quot; Or sTemp = &quot; &quot; Then sTemp = &quot;MISC&quot;
            On Error Resume Next
            TreeView.Nodes.Add sTemp, tvwChild, DLookup(&quot;Tagname&quot;, &quot;MASTER&quot;, &quot;ID = &quot; &amp; !Tagname), DLookup(&quot;Tagname&quot;, &quot;MASTER&quot;, &quot;ID = &quot; &amp; !Tagname)
        .MoveNext
        Loop
    End With
        
    With oNone
        .MoveFirst
        Do While Not .EOF
            On Error Resume Next
            TreeView.Nodes.Add &quot;MISC&quot;, tvwChild, DLookup(&quot;Tagname&quot;, &quot;MASTER&quot;, &quot;ID = &quot; &amp; !Tagname), DLookup(&quot;Tagname&quot;, &quot;MASTER&quot;, &quot;ID = &quot; &amp; !Tagname)
            .MoveNext
        Loop
    End With
   
   'DoCmd.Hourglass False
   'Echo True
   'Me.Painting = True
   
End Sub
```
Avoid the multiple DLookUps with eachTreeView.Nodes.Add call for every row of recordset! At the very least store your DLookUp value once and apply it to treeview. This cuts down the repetitive 4 calculations down to 2 for every row.
But since DLookUp essentially is a query anyway, simply integrate a JOIN to Master object in SQL queries of OpenRecordset calls. This cuts down the repetitive 4 calculations to 0 for every row.
sql = &quot;SELECT d.[Tagname], m.[Tagname] AS [MasterTagname] &quot; _
       &amp; &quot;FROM tblData d &quot; _
       &amp; &quot;LEFT JOIN Master m &quot; _
       &amp; &quot;    ON m.ID = d.[Tagname] &quot; _
       &amp; &quot;WHERE NOT d.[Attribute] = &quot; &amp; cbxAttributeFilter01 _
       &amp; &quot;  AND NOT d.[Property] = &quot; &amp; cbxPropertyFilter01

Set oNone = CurrentDb.OpenRecordset(sql, dbOpenSnapshot)

sql = &quot;SELECT d.[Tagname], m.[Tagname] AS [MasterTagname] &quot; _
       &amp; &quot;FROM tblData d &quot; _
       &amp; &quot;LEFT JOIN Master m &quot; _
       &amp; &quot;    ON m.ID = d.[Tagname] &quot; _
       &amp; &quot;WHERE d.[Attribute] = &quot; &amp; cbxAttributeFilter01 _
       &amp; &quot;  AND d.[Property] = &quot; &amp; cbxPropertyFilter01

Set oData = CurrentDb.OpenRecordset(sql, dbOpenSnapshot) 

...

TreeView.Nodes.Add sTemp, tvwChild, !MasterTagname, !MasterTagname

...

TreeView.Nodes.Add &quot;MISC&quot;, tvwChild, !MasterTagname, !MasterTagname

Also, best practice in VBA is to never use On Error Resume Next but to handle any error that raises which in this case may be a missing or Null DLookUp result. Therefore, enclose If logic.
...

If Not IsNull(!MasterTagName)
   TreeView.Nodes.Add sTemp, tvwChild, !MasterTagname, !MasterTagname
End If

...

If Not IsNull(!MasterTagName)
   TreeView.Nodes.Add &quot;MISC&quot;, tvwChild, !MasterTagname, !MasterTagname
End If