Secondo me alcuni loop di lettura non servono in quanto memorizzi nelle variabili solamente il contenuto dell'ultimo record letto, esempio:

codice:
Set Data4.Recordset = Db.OpenRecordset("select * from limiti where datalimite <= #" & Format(datai, "mm/dd/yyyy") & "# order by datalimite ") 
Do Until Data4.Recordset.EOF 
   datalimite = Data4.Recordset!datalimite 
   primolimite = Data4.Recordset!primolimite 
   secondolimite = Data4.Recordset!secondolimite 
   terzolimite = Data4.Recordset!terzolimite 
   Data4.Recordset.MoveNext 
Loop 
Data4.Recordset.Close
Io lo modificherei in questo modo:

codice:
Set Data4.Recordset = Db.OpenRecordset("select * from limiti where datalimite <= #" & Format(datai, "mm/dd/yyyy") & "# order by datalimite ")
If Not Data4.Recordset.EOF Then
   Data4.MoveLast
   datalimite = Data4.Recordset!datalimite
   primolimite = Data4.Recordset!primolimite
   secondolimite = Data4.Recordset!secondolimite
   terzolimite = Data4.Recordset!terzolimite
End If
Data4.Recordset.Close
Già togliendo alcuni di questi loop dovresti migliorare in prestazioni.
Ciao