+ Reply to Thread
Results 1 to 13 of 13

Shortening of VERY LONG UserForm VBA Code

Hybrid View

  1. #1
    Forum Contributor
    Join Date
    04-04-2014
    Location
    Tetbury, England
    MS-Off Ver
    Excel 2010
    Posts
    254

    Shortening of VERY LONG UserForm VBA Code

    HiUserForm.png

    I have a UserForm (pic attached) that allows the user to input sales for up to 5 years for each month.
    They can do this by entering a 'master' percentage at the top which calculates the following years sales based on the previous or they can enter everything manually.
    Also, entering a 'master' percentage doesn't stop the user from changing a percentage on one particular month, so it's pretty much 100% able to do whatever the user wants.
    It also has totals.

    The code works perfect BUT it needs to be applied to 10's of other UserForms which form part of a big workbook.

    So, can any of this code be shortened because at the moment when I create a new UserForm I have to change every bit of code ever so slightly to make sure it works with the new TextBox names?

    Submits the data onto the worksheet:

    Private Sub cmdSY1_5S1C_Click()
    
    Dim ws As Worksheet:    Set ws = Worksheets("MASTER")
    Dim i As Integer
    
        'Year 1:
    
        For i = 1 To 12
            If Me.Controls("txtY1M" & i).Value <> "" Then
            ws.Cells(17, 19 + i).Value = Me.Controls("txtY1M" & i).Value
        End If
        Next i
        
        'Year 2:
        
        For i = 1 To 12
            If Me.Controls("txtY2M" & i).Value <> "" Then
            ws.Cells(17, 31 + i).Value = Me.Controls("txtY2M" & i).Value
        End If
        Next i
        
        'Year 3:
        
        For i = 1 To 12
            If Me.Controls("txtY3M" & i).Value <> "" Then
            ws.Cells(17, 43 + i).Value = Me.Controls("txtY3M" & i).Value
        End If
        Next i
        
        'Year 4:
        
        For i = 1 To 12
            If Me.Controls("txtY3M" & i).Value <> "" Then
            ws.Cells(17, 55 + i).Value = Me.Controls("txtY3M" & i).Value
        End If
        Next i
        
        'Year 5:
        
        For i = 1 To 12
            If Me.Controls("txtY3M" & i).Value <> "" Then
            ws.Cells(17, 67 + i).Value = Me.Controls("txtY3M" & i).Value
        End If
        Next i
    
        frmY1_5VATSalesType1.Hide
    
    End Sub
    The second submit button just opens the next UserForm.

    Makes all the individual percentage boxes equal the master above it:

    Private Sub txtIncDecST1M1_Change()
        If txtIncDecST1M1.Value > "" Then
            txtIncDec1.Value = txtIncDecST1M1.Value
            txtIncDec2.Value = txtIncDecST1M1.Value
            txtIncDec3.Value = txtIncDecST1M1.Value
            txtIncDec4.Value = txtIncDecST1M1.Value
            txtIncDec5.Value = txtIncDecST1M1.Value
            txtIncDec6.Value = txtIncDecST1M1.Value
            txtIncDec7.Value = txtIncDecST1M1.Value
            txtIncDec8.Value = txtIncDecST1M1.Value
            txtIncDec9.Value = txtIncDecST1M1.Value
            txtIncDec10.Value = txtIncDecST1M1.Value
            txtIncDec11.Value = txtIncDecST1M1.Value
            txtIncDec12.Value = txtIncDecST1M1.Value
        End If
    End Sub
    Private Sub txtIncDecST1M2_Change()
        If txtIncDecST1M2.Value > "" Then
            txtIncDec13.Value = txtIncDecST1M2.Value
            txtIncDec14.Value = txtIncDecST1M2.Value
            txtIncDec15.Value = txtIncDecST1M2.Value
            txtIncDec16.Value = txtIncDecST1M2.Value
            txtIncDec17.Value = txtIncDecST1M2.Value
            txtIncDec18.Value = txtIncDecST1M2.Value
            txtIncDec19.Value = txtIncDecST1M2.Value
            txtIncDec20.Value = txtIncDecST1M2.Value
            txtIncDec21.Value = txtIncDecST1M2.Value
            txtIncDec22.Value = txtIncDecST1M2.Value
            txtIncDec23.Value = txtIncDecST1M2.Value
            txtIncDec24.Value = txtIncDecST1M2.Value
        End If
    End Sub
    Private Sub txtIncDecST1M3_Change()
        If txtIncDecST1M3.Value > "" Then
            txtIncDec25.Value = txtIncDecST1M3.Value
            txtIncDec26.Value = txtIncDecST1M3.Value
            txtIncDec27.Value = txtIncDecST1M3.Value
            txtIncDec28.Value = txtIncDecST1M3.Value
            txtIncDec29.Value = txtIncDecST1M3.Value
            txtIncDec30.Value = txtIncDecST1M3.Value
            txtIncDec31.Value = txtIncDecST1M3.Value
            txtIncDec32.Value = txtIncDecST1M3.Value
            txtIncDec33.Value = txtIncDecST1M3.Value
            txtIncDec34.Value = txtIncDecST1M3.Value
            txtIncDec35.Value = txtIncDecST1M3.Value
            txtIncDec36.Value = txtIncDecST1M3.Value
        End If
    End Sub
    Private Sub txtIncDecST1M4_Change()
        If txtIncDecST1M4.Value > "" Then
            txtIncDec37.Value = txtIncDecST1M4.Value
            txtIncDec38.Value = txtIncDecST1M4.Value
            txtIncDec39.Value = txtIncDecST1M4.Value
            txtIncDec40.Value = txtIncDecST1M4.Value
            txtIncDec41.Value = txtIncDecST1M4.Value
            txtIncDec42.Value = txtIncDecST1M4.Value
            txtIncDec43.Value = txtIncDecST1M4.Value
            txtIncDec44.Value = txtIncDecST1M4.Value
            txtIncDec45.Value = txtIncDecST1M4.Value
            txtIncDec46.Value = txtIncDecST1M4.Value
            txtIncDec47.Value = txtIncDecST1M4.Value
            txtIncDec48.Value = txtIncDecST1M4.Value
        End If
    End Sub
    Upon exit of entering an individual percentage, the following years sales will re-calculate (very long as it works for 60 months):

    Private Sub txtIncDec1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec1.Value <> "" Then
            txtY2M1 = txtY1M1 * (1 + Val(txtIncDec1 / 100))
        End If
    End Sub
    Private Sub txtIncDec2_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec2.Value <> "" Then
            txtY2M2 = txtY1M2 * (1 + Val(txtIncDec2 / 100))
        End If
    End Sub
    Private Sub txtIncDec3_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec3.Value <> "" Then
            txtY2M3 = txtY1M3 * (1 + Val(txtIncDec3 / 100))
        End If
    End Sub
    Private Sub txtIncDec4_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec4.Value <> "" Then
            txtY2M4 = txtY1M4 * (1 + Val(txtIncDec4 / 100))
        End If
    End Sub
    Private Sub txtIncDec5_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec5.Value <> "" Then
            txtY2M5 = txtY1M5 * (1 + Val(txtIncDec5 / 100))
        End If
    End Sub
    Private Sub txtIncDec6_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec6.Value <> "" Then
            txtY2M6 = txtY1M6 * (1 + Val(txtIncDec6 / 100))
        End If
    End Sub
    Private Sub txtIncDec7_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec7.Value <> "" Then
            txtY2M7 = txtY1M7 * (1 + Val(txtIncDec7 / 100))
        End If
    End Sub
    Private Sub txtIncDec8_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec8.Value <> "" Then
            txtY2M8 = txtY1M8 * (1 + Val(txtIncDec8 / 100))
        End If
    End Sub
    Private Sub txtIncDec9_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec9.Value <> "" Then
            txtY2M9 = txtY1M9 * (1 + Val(txtIncDec9 / 100))
        End If
    End Sub
    Private Sub txtIncDec10_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec10.Value <> "" Then
            txtY2M10 = txtY1M10 * (1 + Val(txtIncDec10 / 100))
        End If
    End Sub
    Private Sub txtIncDec11_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec11.Value <> "" Then
            txtY2M11 = txtY1M11 * (1 + Val(txtIncDec11 / 100))
        End If
    End Sub
    Private Sub txtIncDec12_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec12.Value <> "" Then
            txtY2M12 = txtY1M12 * (1 + Val(txtIncDec12 / 100))
        End If
    End Sub
    Private Sub txtIncDec13_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec13.Value <> "" Then
            txtY3M1 = txtY2M1 * (1 + Val(txtIncDec13 / 100))
        End If
    End Sub
    Private Sub txtIncDec14_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec14.Value <> "" Then
            txtY3M2 = txtY2M2 * (1 + Val(txtIncDec14 / 100))
        End If
    End Sub
    Private Sub txtIncDec15_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec15.Value <> "" Then
            txtY3M3 = txtY2M3 * (1 + Val(txtIncDec15 / 100))
        End If
    End Sub
    Private Sub txtIncDec16_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec16.Value <> "" Then
            txtY3M4 = txtY2M4 * (1 + Val(txtIncDec16 / 100))
        End If
    End Sub
    Private Sub txtIncDec17_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec17.Value <> "" Then
            txtY3M5 = txtY2M5 * (1 + Val(txtIncDec17 / 100))
        End If
    End Sub
    Private Sub txtIncDec18_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec18.Value <> "" Then
            txtY3M6 = txtY2M6 * (1 + Val(txtIncDec18 / 100))
        End If
    End Sub
    Private Sub txtIncDec19_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec19.Value <> "" Then
            txtY3M7 = txtY2M7 * (1 + Val(txtIncDec19 / 100))
        End If
    End Sub
    Private Sub txtIncDec20_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec20.Value <> "" Then
            txtY3M8 = txtY2M8 * (1 + Val(txtIncDec20 / 100))
        End If
    End Sub
    Private Sub txtIncDec21_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec21.Value <> "" Then
            txtY3M9 = txtY2M9 * (1 + Val(txtIncDec21 / 100))
        End If
    End Sub
    Private Sub txtIncDec22_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec22.Value <> "" Then
            txtY3M10 = txtY2M10 * (1 + Val(txtIncDec22 / 100))
        End If
    End Sub
    Private Sub txtIncDec23_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec23.Value <> "" Then
            txtY3M11 = txtY2M11 * (1 + Val(txtIncDec23 / 100))
        End If
    End Sub
    Private Sub txtIncDec24_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec24.Value <> "" Then
            txtY3M12 = txtY2M12 * (1 + Val(txtIncDec24 / 100))
        End If
    End Sub
    Private Sub txtIncDec25_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec25.Value <> "" Then
            txtY4M1 = txtY3M1 * (1 + Val(txtIncDec25 / 100))
        End If
    End Sub
    Private Sub txtIncDec26_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec26.Value <> "" Then
            txtY4M2 = txtY3M2 * (1 + Val(txtIncDec26 / 100))
        End If
    End Sub
    Private Sub txtIncDec27_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec27.Value <> "" Then
            txtY4M3 = txtY3M3 * (1 + Val(txtIncDec27 / 100))
        End If
    End Sub
    Private Sub txtIncDec28_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec28.Value <> "" Then
            txtY4M4 = txtY3M4 * (1 + Val(txtIncDec28 / 100))
        End If
    End Sub
    Private Sub txtIncDec29_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec29.Value <> "" Then
            txtY4M5 = txtY3M5 * (1 + Val(txtIncDec29 / 100))
        End If
    End Sub
    Private Sub txtIncDec30_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec30.Value <> "" Then
            txtY4M6 = txtY3M6 * (1 + Val(txtIncDec30 / 100))
        End If
    End Sub
    Private Sub txtIncDec31_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec31.Value <> "" Then
            txtY4M7 = txtY3M7 * (1 + Val(txtIncDec31 / 100))
        End If
    End Sub
    Private Sub txtIncDec32_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec32.Value <> "" Then
            txtY4M8 = txtY3M8 * (1 + Val(txtIncDec32 / 100))
        End If
    End Sub
    Private Sub txtIncDec33_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec33.Value <> "" Then
            txtY4M9 = txtY3M9 * (1 + Val(txtIncDec33 / 100))
        End If
    End Sub
    Private Sub txtIncDec34_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec34.Value <> "" Then
            txtY4M10 = txtY3M10 * (1 + Val(txtIncDec34 / 100))
        End If
    End Sub
    Private Sub txtIncDec35_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec35.Value <> "" Then
            txtY4M11 = txtY3M11 * (1 + Val(txtIncDec35 / 100))
        End If
    End Sub
    Private Sub txtIncDec36_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec36.Value <> "" Then
            txtY4M12 = txtY3M12 * (1 + Val(txtIncDec36 / 100))
        End If
    End Sub
    Private Sub txtIncDec37_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec37.Value <> "" Then
            txtY5M1 = txtY4M1 * (1 + Val(txtIncDec37 / 100))
        End If
    End Sub
    Private Sub txtIncDec38_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec38.Value <> "" Then
            txtY5M2 = txtY4M2 * (1 + Val(txtIncDec38 / 100))
        End If
    End Sub
    Private Sub txtIncDec39_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec39.Value <> "" Then
            txtY5M3 = txtY4M3 * (1 + Val(txtIncDec39 / 100))
        End If
    End Sub
    Private Sub txtIncDec40_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec40.Value <> "" Then
            txtY5M4 = txtY4M4 * (1 + Val(txtIncDec40 / 100))
        End If
    End Sub
    Private Sub txtIncDec41_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec41.Value <> "" Then
            txtY5M5 = txtY4M5 * (1 + Val(txtIncDec41 / 100))
        End If
    End Sub
    Private Sub txtIncDec42_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec42.Value <> "" Then
            txtY5M6 = txtY4M6 * (1 + Val(txtIncDec42 / 100))
        End If
    End Sub
    Private Sub txtIncDec43_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec43.Value <> "" Then
            txtY5M7 = txtY4M7 * (1 + Val(txtIncDec43 / 100))
        End If
    End Sub
    Private Sub txtIncDec44_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec44.Value <> "" Then
            txtY5M8 = txtY4M8 * (1 + Val(txtIncDec44 / 100))
        End If
    End Sub
    Private Sub txtIncDec45_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec45.Value <> "" Then
            txtY5M9 = txtY4M9 * (1 + Val(txtIncDec45 / 100))
        End If
    End Sub
    Private Sub txtIncDec46_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec46.Value <> "" Then
            txtY5M10 = txtY4M10 * (1 + Val(txtIncDec46 / 100))
        End If
    End Sub
    Private Sub txtIncDec47_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec47.Value <> "" Then
            txtY5M11 = txtY4M11 * (1 + Val(txtIncDec47 / 100))
        End If
    End Sub
    Private Sub txtIncDec48_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    On Error Resume Next
        If txtIncDec48.Value <> "" Then
            txtY5M12 = txtY4M12 * (1 + Val(txtIncDec48 / 100))
        End If
    End Sub
    Last edited by PDBartlett; 04-11-2014 at 06:31 AM.

  2. #2
    Forum Contributor
    Join Date
    04-04-2014
    Location
    Tetbury, England
    MS-Off Ver
    Excel 2010
    Posts
    254

    Re: Shortening of VERY LONG UserForm VBA Code

    I couldn't fit the rest of the code on:

    Function to allow the total TextBoxes to work upon ANY change in the data input:

    Function TotalSales(Yr As Long) As Double
    Dim ctl As MSForms.Control
    Dim Mth As Long
    
        For Mth = 1 To 12
            Set ctl = Me.Controls("txtY" & Yr & "M" & Mth)
            If ctl.Value <> "" Then
                TotalSales = TotalSales + Val(ctl.Value)
            End If
       Next Mth
    
    End Function

  3. #3
    Forum Contributor
    Join Date
    04-04-2014
    Location
    Tetbury, England
    MS-Off Ver
    Excel 2010
    Posts
    254

    Re: Shortening of VERY LONG UserForm VBA Code

    Year 1-3:

    Private Sub txtY1M1_Change()
    On Error Resume Next
        txtY1Total.Value = TotalSales(Yr:=1)
            If txtIncDec1.Value = txtIncDecST1M1 Then
                txtY2M1 = txtY1M1 * (1 + Val(txtIncDecST1M1 / 100))
            Else
                txtY2M1 = txtY1M1 * (1 + Val(txtIncDec1 / 100))
            End If
    End Sub
    Private Sub txtY1M2_Change()
    On Error Resume Next
        txtY1Total.Value = TotalSales(Yr:=1)
            If txtIncDec2.Value = txtIncDecST1M1 Then
                txtY2M2 = txtY1M2 * (1 + Val(txtIncDecST1M1 / 100))
            Else
                txtY2M2 = txtY1M2 * (1 + Val(txtIncDec2 / 100))
            End If
    End Sub
    Private Sub txtY1M3_Change()
    On Error Resume Next
        txtY1Total.Value = TotalSales(Yr:=1)
            If txtIncDec3.Value = txtIncDecST1M1 Then
                txtY2M3 = txtY1M3 * (1 + Val(txtIncDecST1M1 / 100))
            Else
                txtY2M3 = txtY1M3 * (1 + Val(txtIncDec3 / 100))
            End If
    End Sub
    Private Sub txtY1M4_Change()
    On Error Resume Next
        txtY1Total.Value = TotalSales(Yr:=1)
            If txtIncDec4.Value = txtIncDecST1M1 Then
                txtY2M4 = txtY1M4 * (1 + Val(txtIncDecST1M1 / 100))
            Else
                txtY2M4 = txtY1M4 * (1 + Val(txtIncDec4 / 100))
            End If
    End Sub
    Private Sub txtY1M5_Change()
    On Error Resume Next
        txtY1Total.Value = TotalSales(Yr:=1)
            If txtIncDec5.Value = txtIncDecST1M1 Then
                txtY2M5 = txtY1M5 * (1 + Val(txtIncDecST1M1 / 100))
            Else
                txtY2M5 = txtY1M5 * (1 + Val(txtIncDec5 / 100))
            End If
    End Sub
    Private Sub txtY1M6_Change()
    On Error Resume Next
        txtY1Total.Value = TotalSales(Yr:=1)
            If txtIncDec6.Value = txtIncDecST1M1 Then
                txtY2M6 = txtY1M6 * (1 + Val(txtIncDecST1M1 / 100))
            Else
                txtY2M6 = txtY1M6 * (1 + Val(txtIncDec6 / 100))
            End If
    End Sub
    Private Sub txtY1M7_Change()
    On Error Resume Next
        txtY1Total.Value = TotalSales(Yr:=1)
            If txtIncDec7.Value = txtIncDecST1M1 Then
                txtY2M7 = txtY1M7 * (1 + Val(txtIncDecST1M1 / 100))
            Else
                txtY2M7 = txtY1M7 * (1 + Val(txtIncDec7 / 100))
            End If
    End Sub
    Private Sub txtY1M8_Change()
    On Error Resume Next
        txtY1Total.Value = TotalSales(Yr:=1)
            If txtIncDec8.Value = txtIncDecST1M1 Then
                txtY2M8 = txtY1M8 * (1 + Val(txtIncDecST1M1 / 100))
            Else
                txtY2M8 = txtY1M8 * (1 + Val(txtIncDec8 / 100))
            End If
    End Sub
    Private Sub txtY1M9_Change()
    On Error Resume Next
        txtY1Total.Value = TotalSales(Yr:=1)
            If txtIncDec9.Value = txtIncDecST1M1 Then
                txtY2M9 = txtY1M9 * (1 + Val(txtIncDecST1M1 / 100))
            Else
                txtY2M9 = txtY1M9 * (1 + Val(txtIncDec9 / 100))
            End If
    End Sub
    Private Sub txtY1M10_Change()
    On Error Resume Next
        txtY1Total.Value = TotalSales(Yr:=1)
            If txtIncDec10.Value = txtIncDecST1M1 Then
                txtY2M10 = txtY1M10 * (1 + Val(txtIncDecST1M1 / 100))
            Else
                txtY2M10 = txtY1M10 * (1 + Val(txtIncDec10 / 100))
            End If
    End Sub
    Private Sub txtY1M11_Change()
    On Error Resume Next
        txtY1Total.Value = TotalSales(Yr:=1)
            If txtIncDec11.Value = txtIncDecST1M1 Then
                txtY2M11 = txtY1M11 * (1 + Val(txtIncDecST1M1 / 100))
            Else
                txtY2M11 = txtY1M11 * (1 + Val(txtIncDec11 / 100))
            End If
    End Sub
    Private Sub txtY1M12_Change()
    On Error Resume Next
        txtY1Total.Value = TotalSales(Yr:=1)
            If txtIncDec12.Value = txtIncDecST1M1 Then
                txtY2M12 = txtY1M12 * (1 + Val(txtIncDecST1M1 / 100))
            Else
                txtY2M12 = txtY1M12 * (1 + Val(txtIncDec12 / 100))
            End If
    End Sub
    Private Sub txtY2M1_Change()
    On Error Resume Next
        txtY2Total.Value = TotalSales(Yr:=2)
            If txtIncDec13.Value = txtIncDecST1M2 Then
                txtY3M1 = txtY2M1 * (1 + Val(txtIncDecST1M2 / 100))
            Else
                txtY3M1 = txtY2M1 * (1 + Val(txtIncDec13 / 100))
            End If
    End Sub
    Private Sub txtY2M2_Change()
    On Error Resume Next
        txtY2Total.Value = TotalSales(Yr:=2)
            If txtIncDec14.Value = txtIncDecST1M2 Then
                txtY3M2 = txtY2M2 * (1 + Val(txtIncDecST1M2 / 100))
            Else
                txtY3M2 = txtY2M2 * (1 + Val(txtIncDec14 / 100))
            End If
    End Sub
    Private Sub txtY2M3_Change()
    On Error Resume Next
        txtY2Total.Value = TotalSales(Yr:=2)
            If txtIncDec15.Value = txtIncDecST1M2 Then
                txtY3M3 = txtY2M3 * (1 + Val(txtIncDecST1M2 / 100))
            Else
                txtY3M3 = txtY2M3 * (1 + Val(txtIncDec15 / 100))
            End If
    End Sub
    Private Sub txtY2M4_Change()
    On Error Resume Next
        txtY2Total.Value = TotalSales(Yr:=2)
            If txtIncDec16.Value = txtIncDecST1M2 Then
                txtY3M4 = txtY2M4 * (1 + Val(txtIncDecST1M2 / 100))
            Else
                txtY3M4 = txtY2M4 * (1 + Val(txtIncDec16 / 100))
            End If
    End Sub
    Private Sub txtY2M5_Change()
    On Error Resume Next
        txtY2Total.Value = TotalSales(Yr:=2)
            If txtIncDec17.Value = txtIncDecST1M2 Then
                txtY3M5 = txtY2M5 * (1 + Val(txtIncDecST1M2 / 100))
            Else
                txtY3M5 = txtY2M5 * (1 + Val(txtIncDec17 / 100))
            End If
    End Sub
    Private Sub txtY2M6_Change()
    On Error Resume Next
        txtY2Total.Value = TotalSales(Yr:=2)
            If txtIncDec18.Value = txtIncDecST1M2 Then
                txtY3M6 = txtY2M6 * (1 + Val(txtIncDecST1M2 / 100))
            Else
                txtY3M6 = txtY2M6 * (1 + Val(txtIncDec18 / 100))
            End If
    End Sub
    Private Sub txtY2M7_Change()
    On Error Resume Next
        txtY2Total.Value = TotalSales(Yr:=2)
            If txtIncDec19.Value = txtIncDecST1M2 Then
                txtY3M7 = txtY2M7 * (1 + Val(txtIncDecST1M2 / 100))
            Else
                txtY3M7 = txtY2M7 * (1 + Val(txtIncDec19 / 100))
            End If
    End Sub
    Private Sub txtY2M8_Change()
    On Error Resume Next
        txtY2Total.Value = TotalSales(Yr:=2)
            If txtIncDec20.Value = txtIncDecST1M2 Then
                txtY3M8 = txtY2M8 * (1 + Val(txtIncDecST1M2 / 100))
            Else
                txtY3M8 = txtY2M8 * (1 + Val(txtIncDec20 / 100))
            End If
    End Sub
    Private Sub txtY2M9_Change()
    On Error Resume Next
        txtY2Total.Value = TotalSales(Yr:=2)
            If txtIncDec21.Value = txtIncDecST1M2 Then
                txtY3M9 = txtY2M9 * (1 + Val(txtIncDecST1M2 / 100))
            Else
                txtY3M9 = txtY2M9 * (1 + Val(txtIncDec21 / 100))
            End If
    End Sub
    Private Sub txtY2M10_Change()
    On Error Resume Next
        txtY2Total.Value = TotalSales(Yr:=2)
            If txtIncDec22.Value = txtIncDecST1M2 Then
                txtY3M10 = txtY2M10 * (1 + Val(txtIncDecST1M2 / 100))
            Else
                txtY3M10 = txtY2M10 * (1 + Val(txtIncDec22 / 100))
            End If
    End Sub
    Private Sub txtY2M11_Change()
    On Error Resume Next
        txtY2Total.Value = TotalSales(Yr:=2)
            If txtIncDec23.Value = txtIncDecST1M2 Then
                txtY3M11 = txtY2M11 * (1 + Val(txtIncDecST1M2 / 100))
            Else
                txtY3M11 = txtY2M11 * (1 + Val(txtIncDec23 / 100))
            End If
    End Sub
    Private Sub txtY2M12_Change()
    On Error Resume Next
        txtY2Total.Value = TotalSales(Yr:=2)
            If txtIncDec24.Value = txtIncDecST1M2 Then
                txtY3M12 = txtY2M12 * (1 + Val(txtIncDecST1M2 / 100))
            Else
                txtY3M12 = txtY2M12 * (1 + Val(txtIncDec24 / 100))
            End If
    End Sub
    Private Sub txtY3M1_Change()
    On Error Resume Next
        txtY3Total.Value = TotalSales(Yr:=3)
            If txtIncDec25.Value = txtIncDecST1M3 Then
                txtY4M1 = txtY3M1 * (1 + Val(txtIncDecST1M3 / 100))
            Else
                txtY4M1 = txtY3M1 * (1 + Val(txtIncDec25 / 100))
            End If
    End Sub
    Private Sub txtY3M2_Change()
    On Error Resume Next
        txtY3Total.Value = TotalSales(Yr:=3)
            If txtIncDec26.Value = txtIncDecST1M3 Then
                txtY4M2 = txtY3M2 * (1 + Val(txtIncDecST1M3 / 100))
            Else
                txtY4M2 = txtY3M2 * (1 + Val(txtIncDec26 / 100))
            End If
    End Sub
    Private Sub txtY3M3_Change()
    On Error Resume Next
        txtY3Total.Value = TotalSales(Yr:=3)
            If txtIncDec27.Value = txtIncDecST1M3 Then
                txtY4M3 = txtY3M3 * (1 + Val(txtIncDecST1M3 / 100))
            Else
                txtY4M3 = txtY3M3 * (1 + Val(txtIncDec27 / 100))
            End If
    End Sub
    Private Sub txtY3M4_Change()
    On Error Resume Next
        txtY3Total.Value = TotalSales(Yr:=3)
            If txtIncDec28.Value = txtIncDecST1M3 Then
                txtY4M4 = txtY3M4 * (1 + Val(txtIncDecST1M3 / 100))
            Else
                txtY4M4 = txtY3M4 * (1 + Val(txtIncDec28 / 100))
            End If
    End Sub
    Private Sub txtY3M5_Change()
    On Error Resume Next
        txtY3Total.Value = TotalSales(Yr:=3)
            If txtIncDec29.Value = txtIncDecST1M3 Then
                txtY4M5 = txtY3M5 * (1 + Val(txtIncDecST1M3 / 100))
            Else
                txtY4M5 = txtY3M5 * (1 + Val(txtIncDec29 / 100))
            End If
    End Sub
    Private Sub txtY3M6_Change()
    On Error Resume Next
        txtY3Total.Value = TotalSales(Yr:=3)
            If txtIncDec30.Value = txtIncDecST1M3 Then
                txtY4M6 = txtY3M6 * (1 + Val(txtIncDecST1M3 / 100))
            Else
                txtY4M6 = txtY3M6 * (1 + Val(txtIncDec30 / 100))
            End If
    End Sub
    Private Sub txtY3M7_Change()
    On Error Resume Next
        txtY3Total.Value = TotalSales(Yr:=3)
            If txtIncDec31.Value = txtIncDecST1M3 Then
                txtY4M7 = txtY3M7 * (1 + Val(txtIncDecST1M3 / 100))
            Else
                txtY4M7 = txtY3M7 * (1 + Val(txtIncDec31 / 100))
            End If
    End Sub
    Private Sub txtY3M8_Change()
    On Error Resume Next
        txtY3Total.Value = TotalSales(Yr:=3)
            If txtIncDec32.Value = txtIncDecST1M3 Then
                txtY4M8 = txtY3M8 * (1 + Val(txtIncDecST1M3 / 100))
            Else
                txtY4M8 = txtY3M8 * (1 + Val(txtIncDec32 / 100))
            End If
    End Sub
    Private Sub txtY3M9_Change()
    On Error Resume Next
        txtY3Total.Value = TotalSales(Yr:=3)
            If txtIncDec33.Value = txtIncDecST1M3 Then
                txtY4M9 = txtY3M9 * (1 + Val(txtIncDecST1M3 / 100))
            Else
                txtY4M9 = txtY3M9 * (1 + Val(txtIncDec33 / 100))
            End If
    End Sub
    Private Sub txtY3M10_Change()
    On Error Resume Next
        txtY3Total.Value = TotalSales(Yr:=3)
            If txtIncDec34.Value = txtIncDecST1M3 Then
                txtY4M10 = txtY3M10 * (1 + Val(txtIncDecST1M3 / 100))
            Else
                txtY4M10 = txtY3M10 * (1 + Val(txtIncDec34 / 100))
            End If
    End Sub
    Private Sub txtY3M11_Change()
    On Error Resume Next
        txtY3Total.Value = TotalSales(Yr:=3)
            If txtIncDec35.Value = txtIncDecST1M3 Then
                txtY4M11 = txtY3M11 * (1 + Val(txtIncDecST1M3 / 100))
            Else
                txtY4M11 = txtY3M11 * (1 + Val(txtIncDec35 / 100))
            End If
    End Sub
    Private Sub txtY3M12_Change()
    On Error Resume Next
        txtY3Total.Value = TotalSales(Yr:=3)
            If txtIncDec36.Value = txtIncDecST1M3 Then
                txtY4M12 = txtY3M12 * (1 + Val(txtIncDecST1M3 / 100))
            Else
                txtY4M12 = txtY3M12 * (1 + Val(txtIncDec36 / 100))
            End If
    End Sub

  4. #4
    Forum Contributor
    Join Date
    04-04-2014
    Location
    Tetbury, England
    MS-Off Ver
    Excel 2010
    Posts
    254

    Re: Shortening of VERY LONG UserForm VBA Code

    Year 4-5:

    Private Sub txtY4M1_Change()
    On Error Resume Next
        txtY4Total.Value = TotalSales(Yr:=4)
            If txtIncDec37.Value = txtIncDecST1M4 Then
                txtY5M1 = txtY4M1 * (1 + Val(txtIncDecST1M4 / 100))
            Else
                txtY5M1 = txtY4M1 * (1 + Val(txtIncDec37 / 100))
            End If
    End Sub
    Private Sub txtY4M2_Change()
    On Error Resume Next
        txtY4Total.Value = TotalSales(Yr:=4)
            If txtIncDec38.Value = txtIncDecST1M4 Then
                txtY5M2 = txtY4M2 * (1 + Val(txtIncDecST1M4 / 100))
            Else
                txtY5M2 = txtY4M2 * (1 + Val(txtIncDec38 / 100))
            End If
    End Sub
    Private Sub txtY4M3_Change()
    On Error Resume Next
        txtY4Total.Value = TotalSales(Yr:=4)
            If txtIncDec39.Value = txtIncDecST1M4 Then
                txtY5M3 = txtY4M3 * (1 + Val(txtIncDecST1M4 / 100))
            Else
                txtY5M3 = txtY4M3 * (1 + Val(txtIncDec39 / 100))
            End If
    End Sub
    Private Sub txtY4M4_Change()
    On Error Resume Next
        txtY4Total.Value = TotalSales(Yr:=4)
            If txtIncDec40.Value = txtIncDecST1M4 Then
                txtY5M4 = txtY4M4 * (1 + Val(txtIncDecST1M4 / 100))
            Else
                txtY5M4 = txtY4M4 * (1 + Val(txtIncDec40 / 100))
            End If
    End Sub
    Private Sub txtY4M5_Change()
    On Error Resume Next
        txtY4Total.Value = TotalSales(Yr:=4)
            If txtIncDec41.Value = txtIncDecST1M4 Then
                txtY5M5 = txtY4M5 * (1 + Val(txtIncDecST1M4 / 100))
            Else
                txtY5M5 = txtY4M5 * (1 + Val(txtIncDec41 / 100))
            End If
    End Sub
    Private Sub txtY4M6_Change()
    On Error Resume Next
        txtY4Total.Value = TotalSales(Yr:=4)
            If txtIncDec42.Value = txtIncDecST1M4 Then
                txtY5M6 = txtY4M6 * (1 + Val(txtIncDecST1M4 / 100))
            Else
                txtY5M6 = txtY4M6 * (1 + Val(txtIncDec42 / 100))
            End If
    End Sub
    Private Sub txtY4M7_Change()
    On Error Resume Next
        txtY4Total.Value = TotalSales(Yr:=4)
            If txtIncDec43.Value = txtIncDecST1M4 Then
                txtY5M7 = txtY4M7 * (1 + Val(txtIncDecST1M4 / 100))
            Else
                txtY5M7 = txtY4M7 * (1 + Val(txtIncDec43 / 100))
            End If
    End Sub
    Private Sub txtY4M8_Change()
    On Error Resume Next
        txtY4Total.Value = TotalSales(Yr:=4)
            If txtIncDec44.Value = txtIncDecST1M4 Then
                txtY5M8 = txtY4M8 * (1 + Val(txtIncDecST1M4 / 100))
            Else
                txtY5M8 = txtY4M8 * (1 + Val(txtIncDec44 / 100))
            End If
    End Sub
    Private Sub txtY4M9_Change()
    On Error Resume Next
        txtY4Total.Value = TotalSales(Yr:=4)
            If txtIncDec45.Value = txtIncDecST1M4 Then
                txtY5M9 = txtY4M9 * (1 + Val(txtIncDecST1M4 / 100))
            Else
                txtY5M9 = txtY4M9 * (1 + Val(txtIncDec45 / 100))
            End If
    End Sub
    Private Sub txtY4M10_Change()
    On Error Resume Next
        txtY4Total.Value = TotalSales(Yr:=4)
            If txtIncDec46.Value = txtIncDecST1M4 Then
                txtY5M10 = txtY4M10 * (1 + Val(txtIncDecST1M4 / 100))
            Else
                txtY5M10 = txtY4M10 * (1 + Val(txtIncDec46 / 100))
            End If
    End Sub
    Private Sub txtY4M11_Change()
    On Error Resume Next
        txtY4Total.Value = TotalSales(Yr:=4)
            If txtIncDec47.Value = txtIncDecST1M4 Then
                txtY5M11 = txtY4M11 * (1 + Val(txtIncDecST1M4 / 100))
            Else
                txtY5M11 = txtY4M11 * (1 + Val(txtIncDec47 / 100))
            End If
    End Sub
    Private Sub txtY4M12_Change()
    On Error Resume Next
        txtY4Total.Value = TotalSales(Yr:=4)
            If txtIncDec48.Value = txtIncDecST1M4 Then
                txtY5M12 = txtY4M12 * (1 + Val(txtIncDecST1M4 / 100))
            Else
                txtY5M12 = txtY4M12 * (1 + Val(txtIncDec48 / 100))
            End If
    End Sub
    Private Sub txtY5M1_Change()
    On Error Resume Next
        txtY5Total.Value = TotalSales(Yr:=5)
    End Sub
    Private Sub txtY5M2_Change()
    On Error Resume Next
        txtY5Total.Value = TotalSales(Yr:=5)
    End Sub
    Private Sub txtY5M3_Change()
    On Error Resume Next
        txtY5Total.Value = TotalSales(Yr:=5)
    End Sub
    Private Sub txtY5M4_Change()
    On Error Resume Next
        txtY5Total.Value = TotalSales(Yr:=5)
    End Sub
    Private Sub txtY5M5_Change()
    On Error Resume Next
        txtY5Total.Value = TotalSales(Yr:=5)
    End Sub
    Private Sub txtY5M6_Change()
    On Error Resume Next
        txtY5Total.Value = TotalSales(Yr:=5)
    End Sub
    Private Sub txtY5M7_Change()
    On Error Resume Next
        txtY5Total.Value = TotalSales(Yr:=5)
    End Sub
    Private Sub txtY5M8_Change()
    On Error Resume Next
        txtY5Total.Value = TotalSales(Yr:=5)
    End Sub
    Private Sub txtY5M9_Change()
    On Error Resume Next
        txtY5Total.Value = TotalSales(Yr:=5)
    End Sub
    Private Sub txtY5M10_Change()
    On Error Resume Next
        txtY5Total.Value = TotalSales(Yr:=5)
    End Sub
    Private Sub txtY5M11_Change()
    On Error Resume Next
        txtY5Total.Value = TotalSales(Yr:=5)
    End Sub
    Private Sub txtY5M12_Change()
    On Error Resume Next
        txtY5Total.Value = TotalSales(Yr:=5)
    End Sub

  5. #5
    Forum Contributor
    Join Date
    04-04-2014
    Location
    Tetbury, England
    MS-Off Ver
    Excel 2010
    Posts
    254

    Re: Shortening of VERY LONG UserForm VBA Code

    If even some of this code could be shortened it would be a huge help!

  6. #6
    Forum Guru Kyle123's Avatar
    Join Date
    03-10-2010
    Location
    Leeds
    MS-Off Ver
    365 Win 11
    Posts
    7,238

    Re: Shortening of VERY LONG UserForm VBA Code

    Can you attach your workbook please?

  7. #7
    Forum Contributor
    Join Date
    04-04-2014
    Location
    Tetbury, England
    MS-Off Ver
    Excel 2010
    Posts
    254

    Re: Shortening of VERY LONG UserForm VBA Code

    Hi Kyle

    Business Modelling Template Upload.xlsm

    I've cut a load of stuff out so the workbook is just showing the sales element.
    It has 5 types of sales, I have userforms for 3 so far which all work fine.

    Look on the P&L Input sheet to click on the buttons to bring up the UserForm itself.

    So it's just, can the code be shortened?
    Can you rename textboxes faster? (other thread)

    Thanks!

  8. #8
    Forum Guru Kyle123's Avatar
    Join Date
    03-10-2010
    Location
    Leeds
    MS-Off Ver
    365 Win 11
    Posts
    7,238

    Re: Shortening of VERY LONG UserForm VBA Code

    Ok this took a little more grey matter that anticipated

    This is a complete replacement for your code (other than writing it back to the worksheet), there's some complex(ish) stuff going on here to reduce the amount of code required and I'm still not particularly happy with it, try to work through to see how much you can follow and post back if there are any specific issues and I'll happily explain.

    As an aside, you don't need to keep re-creating the same form, you can simply show it multiple times.

    Class module: MonthNode
    Option Explicit
    
    Public nextYear As MonthNode
    
    Public WithEvents total As MSForms.textbox
    Public WithEvents percentage As MSForms.textbox
    Public Parent As Object
    Public year As Long
    Private Sub percentage_Change()
    
        If Not nextYear Is Nothing And Len(percentage) <> 0 Then
            On Error Resume Next
                nextYear.total.value = Val(total.value * (1 + Val(percentage.value / 100)))
            On Error GoTo 0
        End If
    End Sub
    Private Sub total_Change()
    
        Parent.ValuesChanged year 'Fake event
        If Not nextYear Is Nothing And Not percentage Is Nothing Then
            If Len(percentage) <> 0 Then
                On Error Resume Next
                    nextYear.total.value = Val(Val(total.value) * (1 + Val(percentage.value / 100)))
                On Error GoTo 0
            End If
        End If
    End Sub
    Class module: yearChange
    Option Explicit
    
    Public WithEvents ChangeAll As MSForms.textbox
    Public grid As Variant
    Public year As Long
    
    Private Sub ChangeAll_Change()
    
        Dim x As Long
        Dim y As Long
        Dim oMonth As MonthNode
        Dim node As MonthNode
        y = 1
        For x = 1 To 12
            Set node = grid(x)
            Do While y <= (year - 1)
                Set node = node.nextYear
                y = y + 1
            Loop
            y = 1
            node.percentage.value = ChangeAll.value
        Next x
    End Sub
    Userform code:
    Option Explicit
    Private boxList(1 To 12) As MonthNode
    Private yearChangeBoxes(1 To 12) As yearChange
    Private totals(1 To 5) As MSForms.Label
    Const textBoxClass As String = "Forms.Textbox.1"
    Private Sub UserForm_Initialize()
    
        Dim x           As Long
        Dim y           As Long
        Dim node        As MonthNode
        Dim months()    As Variant
        
        months = Array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec")
        
        For x = 1 To 12
            For y = 1 To 5
                If y = 1 Then
                    Set node = New MonthNode
                    Set boxList(x) = node
                    With Me.Controls.Add("Forms.Label.1")
                        .Top = x * .Height + 15
                        .left = 10
                        .Width = 20
                        .Caption = months(x - 1)
                    End With
                    
                Else
                    Set node.nextYear = New MonthNode
                    Set node = node.nextYear
                End If
                
                Set node.Parent = Me 'We need to bubble events
                node.year = y
                
                Set node.total = Me.Controls.Add(textBoxClass)
                With node.total
                    .left = 30 + (130 * (y - 1))
                    .Top = 10 + x * .Height
                    .Width = 80
                End With
                
                With Me.Controls.Add("Forms.Label.1")
                    .left = node.total.left
                    .Top = x
                    .Caption = "Year " & y
                    .Height = 10
                End With
    
                
                
                If y <> 5 Then
                    Set node.percentage = Me.Controls.Add(textBoxClass)
                    With node.percentage
                        .left = node.total.left + 80 + 5
                        .Top = 10 + x * .Height
                        .Width = 30
                    End With
                    
                    If x = 12 Then
                        'Add our bulk changes
                        Set yearChangeBoxes(y) = New yearChange
                        Set yearChangeBoxes(y).ChangeAll = Me.Controls.Add(textBoxClass)
                        With yearChangeBoxes(y).ChangeAll
                            .left = node.percentage.left
                            .Top = 0
                            .Width = 30
                        End With
                        yearChangeBoxes(y).grid = boxList
                        yearChangeBoxes(y).year = y
                        
                        'Add our total labels
                        Set totals(y) = Me.Controls.Add("Forms.Label.1")
                        With totals(y)
                            .Top = 30 + x * .Height
                            .Caption = 0
                            .left = node.total.left + 10
                        End With
                    End If
                End If
                
            Next y
        Next x
        
    End Sub
    
    Public Sub ValuesChanged(year As Long)
    
        Dim x As Long
        Dim y As Long
        Dim total As Double
        Dim node As MonthNode
        y = 1
        For x = 1 To 12
            Set node = boxList(x)
            Do While y <= (year - 1)
                Set node = node.nextYear
                y = y + 1
            Loop
            y = 1
            total = total + Val(node.total)
        Next x
        totals(year).Caption = total
        
    End Sub
    Attached Files Attached Files
    Last edited by Kyle123; 04-11-2014 at 09:58 AM.

  9. #9
    Forum Contributor
    Join Date
    04-04-2014
    Location
    Tetbury, England
    MS-Off Ver
    Excel 2010
    Posts
    254

    Re: Shortening of VERY LONG UserForm VBA Code

    To be perfectly honest I don't know what is going on with your code haha!

    Shall I replace all my code with all of the above and what happens?

  10. #10
    Forum Guru Kyle123's Avatar
    Join Date
    03-10-2010
    Location
    Leeds
    MS-Off Ver
    365 Win 11
    Posts
    7,238

    Re: Shortening of VERY LONG UserForm VBA Code

    haha does it do what you want?

  11. #11
    Forum Contributor
    Join Date
    04-04-2014
    Location
    Tetbury, England
    MS-Off Ver
    Excel 2010
    Posts
    254

    Re: Shortening of VERY LONG UserForm VBA Code

    Something wrong with this?
    User defined type not defined?

    boxList(1 To 12) As MonthNode

  12. #12
    Forum Contributor
    Join Date
    04-04-2014
    Location
    Tetbury, England
    MS-Off Ver
    Excel 2010
    Posts
    254

    Re: Shortening of VERY LONG UserForm VBA Code

    Ahh ok I think I have it working on your spreadsheet, but how can I incorporate it into mine?

  13. #13
    Forum Guru Kyle123's Avatar
    Join Date
    03-10-2010
    Location
    Leeds
    MS-Off Ver
    365 Win 11
    Posts
    7,238

    Re: Shortening of VERY LONG UserForm VBA Code

    I've rejigged the code to make it more efficient:
    YearChange class:
    Option Explicit
    
    Public WithEvents ChangeAll     As MSForms.textbox
    Public grid                     As Variant
    Public year                     As Long
    
    Private Sub ChangeAll_Change()
    
        Dim x   As Long
        
        For x = 1 To 12
            grid(x, year).percentage.Value = ChangeAll.Value
        Next x
        
    End Sub
    Userform:
    Option Explicit
    Private boxList(1 To 12, 1 To 5) As MonthNode
    Private yearChangeBoxes(1 To 12) As yearChange
    Private totals(1 To 5) As MSForms.Label
    Const textBoxClass As String = "Forms.Textbox.1"
    Private Sub UserForm_Initialize()
    
        Dim x           As Long
        Dim y           As Long
        Dim node        As MonthNode
        Dim months()    As Variant
        
        months = Array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec")
        
        For x = 1 To 12
            For y = 1 To 5
                If y = 1 Then
                    Set node = New MonthNode
                    With Me.Controls.Add("Forms.Label.1")
                        .Top = x * .Height + 15
                        .left = 10
                        .Width = 20
                        .Caption = months(x - 1)
                    End With
                    
                Else
                    Set node.nextYear = New MonthNode
                    Set node = node.nextYear
                End If
                
                Set boxList(x, y) = node 'Store the created node
                
                Set node.Parent = Me 'We need to bubble events
                node.year = y
                
                Set node.total = Me.Controls.Add(textBoxClass)
                With node.total
                    .left = 30 + (130 * (y - 1))
                    .Top = 10 + x * .Height
                    .Width = 80
                End With
                
                With Me.Controls.Add("Forms.Label.1")
                    .left = node.total.left
                    .Top = x
                    .Caption = "Year " & y
                    .Height = 10
                End With
    
                If x = 12 Then                                'Add our total labels
                    Set totals(y) = Me.Controls.Add("Forms.Label.1")
                    With totals(y)
                        .Top = 30 + x * .Height
                        .Caption = 0
                        .left = node.total.left + 10
                    End With
                End If
                
                
                If y <> 5 Then
                    Set node.percentage = Me.Controls.Add(textBoxClass)
                    With node.percentage
                        .left = node.total.left + 80 + 5
                        .Top = 10 + x * .Height
                        .Width = 30
                    End With
                    
                    If x = 12 Then
                        'Add our bulk changes
                        Set yearChangeBoxes(y) = New yearChange
                        Set yearChangeBoxes(y).ChangeAll = Me.Controls.Add(textBoxClass)
                        With yearChangeBoxes(y).ChangeAll
                            .left = node.percentage.left
                            .Top = 0
                            .Width = 30
                        End With
                        yearChangeBoxes(y).grid = boxList
                        yearChangeBoxes(y).year = y
                        
    
                    End If
                End If
                
            Next y
        Next x
        
    End Sub
    
    Public Sub ValuesChanged(year As Long)
    
        Dim x       As Long
        Dim total   As Double
        
        For x = 1 To 12
         total = total + Val(boxList(x, year).total)
        Next x
        totals(year).Caption = total
        
    End Sub
    The way this code works, so you get an idea is that it creates 12 lists of Months held in boxList. Each list contains 5 months, one for each year, since we tell each month what the next month in the chain is, each month node is responsible for updating the node next down the chain when the percentage changes. As a diagram, it looks like this \1

    This type of structure would normally be referred to as a singly linked list (singly as each node only knows the next node and not the previous one); however we have made the structure more efficient by indexing each node in the boxList array allowing direct access to any node - I think it's clearer in the diagram.
    Attached Images Attached Images
    Last edited by Kyle123; 04-14-2014 at 07:00 AM.

+ Reply to Thread

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. Shortening of long array formula by short formula
    By paradise2sr in forum Excel Formulas & Functions
    Replies: 2
    Last Post: 10-29-2013, 05:51 AM
  2. [SOLVED] Macro line too long, needs shortening?
    By Hyflex in forum Excel Programming / VBA / Macros
    Replies: 1
    Last Post: 11-09-2011, 01:46 PM
  3. Shortening long IF statement?
    By Lukus in forum Excel General
    Replies: 1
    Last Post: 12-21-2009, 05:44 PM
  4. Shortening Code
    By T De Villiers in forum Excel Programming / VBA / Macros
    Replies: 2
    Last Post: 02-20-2007, 11:46 AM
  5. Shortening Code
    By T De Villiers in forum Excel Programming / VBA / Macros
    Replies: 0
    Last Post: 02-20-2007, 11:17 AM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts

Search Engine Friendly URLs by vBSEO 3.6.0 RC 1