Change event using an Array in VBA

nmounir

Board Regular
Joined
Oct 16, 2020
Messages
107
Office Version
  1. 365
Platform
  1. Windows
Hello everyone,
I have a list of CDs that have maturity dates. when i select a certain date in the future, the table lists down the CD's that will be expired by then. This is done by an excel formula. that said, this list can expand or contrast according to the date selected (date is selected via a drop down list in cell L45). Once the list populates, the user should manually input (hard coding) the new interest rate in percentage (Column L) at which this CD will be renewed at. What i am trying to do here is that if a later date is selected and the interest rates were already manually input, then the user comes and decides to select an earlier date, the list would shrink and so the interest rate that was manually input should then be removed automatically. I am trying to write a code as an array since my sheet is very slow. I wrote this but it is not working and am getting a "Next without for" error despite the fact that i have two For loops in the code

for next image 1.PNG


for next image 2.PNG


Here is the code used

for next image Code.PNG
 

Excel Facts

Return population for a City
If you have a list of cities in A2:A100, use Data, Geography. Then =A2.Population and copy down.
I changed it to Target.Address instead of Target.Value and same issue persists. Code doesn't fire up
I wouldn't use an array for what you are doing but the below might give you some ideas on why your wasn't working.
Some key points
1) Your spreadsheet was running very slowly because your check for whether you wanted to run the code was "inside" the loop.
(ie Target.Address = $D$30). It should be the first thing the change event does so it doesn't run anything else if it fails to qualify.
By having it inside the loops it will cycle through all the code even though D30 didn't change.

2) You are not loading MyCDs before entering the loop. It is again inside the loop and using the loop variables so that it is never actually just loading the array starting values.

VBA Code:
Private Sub Worksheet_Change(ByVal Target As Range)

    Dim MyCDs As Variant
    Dim Dimension1 As Long
    Dim LastRowCDs As Long, LastRowInt As Long
    
    If Target.Address = "$D$30" Then
        Application.ScreenUpdating = False
        Application.EnableEvents = False
        LastRowCDs = Range("J" & Rows.Count).End(xlUp).Row
        LastRowInt = Range("L" & Rows.Count).End(xlUp).Row
        MyCDs = Range(Cells(47, "J"), Cells(Application.Max(LastRowCDs, LastRowInt), "M")).Value
        
        For Dimension1 = LBound(MyCDs, 1) To UBound(MyCDs, 1)
                If MyCDs(Dimension1, 1) = "" Then MyCDs(Dimension1, 3) = 0
        Next Dimension1
        
        Range("J47").Offset(0, 2).Resize(UBound(MyCDs, 1)).Value = Application.Index(MyCDs, 0, 3)
        
    End If
    
    Application.EnableEvents = True
    Application.EnableEvents = True

End Sub
 
Upvote 0
Solution
I wouldn't use an array for what you are doing but the below might give you some ideas on why your wasn't working.
Some key points
1) Your spreadsheet was running very slowly because your check for whether you wanted to run the code was "inside" the loop.
(ie Target.Address = $D$30). It should be the first thing the change event does so it doesn't run anything else if it fails to qualify.
By having it inside the loops it will cycle through all the code even though D30 didn't change.

2) You are not loading MyCDs before entering the loop. It is again inside the loop and using the loop variables so that it is never actually just loading the array starting values.

VBA Code:
Private Sub Worksheet_Change(ByVal Target As Range)

    Dim MyCDs As Variant
    Dim Dimension1 As Long
    Dim LastRowCDs As Long, LastRowInt As Long
   
    If Target.Address = "$D$30" Then
        Application.ScreenUpdating = False
        Application.EnableEvents = False
        LastRowCDs = Range("J" & Rows.Count).End(xlUp).Row
        LastRowInt = Range("L" & Rows.Count).End(xlUp).Row
        MyCDs = Range(Cells(47, "J"), Cells(Application.Max(LastRowCDs, LastRowInt), "M")).Value
       
        For Dimension1 = LBound(MyCDs, 1) To UBound(MyCDs, 1)
                If MyCDs(Dimension1, 1) = "" Then MyCDs(Dimension1, 3) = 0
        Next Dimension1
       
        Range("J47").Offset(0, 2).Resize(UBound(MyCDs, 1)).Value = Application.Index(MyCDs, 0, 3)
       
    End If
   
    Application.EnableEvents = True
    Application.EnableEvents = True

End Sub
This is absolutely brilliant, it works very fast and i feel the difference in the speed of the sheet. I now understand what mistakes I made when building this array; you explained it very well. I should load the array first before looping and the target should be placed first and never have it the loop.
Thanks again Alex for your patience and help with this. Much appreciated.
 
Upvote 0

Forum statistics

Threads
1,214,905
Messages
6,122,175
Members
449,071
Latest member
cdnMech

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top