简体   繁体   中英

Excel VBA - Input Userform data in new row inserted in named range with copied formulas

I'm brand new to Excel VBA and am learning through trial and error and hours on Stack Overflow. I've spent a few hours looking for a solution (still figuring out how to best Google VBA questions...) but haven't found one I could understand so any help or direction toward an existing thread would be MOST appreciated.

I originally wanted my code to input userform data into the next empty row within a specific named range, but now I realize I need it to be more flexible.

Sheets("Budget Input").Range("ContractInputField") 

is, at this moment, A50:E50. F50:V50 contain formulas that need to be carried through as many rows as my range has.

When the user clicks "ok" on the userform, I need:

  • a new row to be inserted within the existing range (within "ContractInputField", below the last entry of the range and above other rows that are not in the range and already have precious content)
  • that new row to copy the formulas that exist in the row above(currently row 50 but would grow to 51 with the first "ok" then 51 with the second "ok" and so on)
  • the userform data to be entered into that new row

Here's the code I had for my original approach:

Private Sub cmdOK_Click()
 Dim J As Long

Sheets("Budget Input").Activate
ActiveSheet.Range("ContractInputLine1").Activate

Do While IsEmpty(ActiveCell.Offset(J, 0)) = False
    J = J + 1
Loop

ActiveCell.Offset(J, 0).Value = Me.txtContractorName.Value
ActiveCell.Offset(J, 1).Value = Me.txtContractPurpose.Value
ActiveCell.Offset(J, 2).Value = Me.txtFlatRate.Value
ActiveCell.Offset(J, 3).Value = Me.txtContractHourlyRate.Value
ActiveCell.Offset(J, 4).Value = Me.txtContractHours.Value
ActiveCell.Offset(J, 16).Value = Me.ContractYear2.Value
ActiveCell.Offset(J, 17).Value = Me.ContractYear3.Value
ActiveCell.Offset(J, 18).Value = Me.ContractYear4.Value


'Clear boxes before next round of entry
Dim ctl As Control

For Each ctl In Me.Controls
    If TypeName(ctl) = "TextBox" Or TypeName(ctl) = "ComboBox" Then
        ctl.Value = " "
    ElseIf TypeName(ctl) = "CheckBox" Then
        ctl.Value = False
    End If

Next ctl

End Sub

I'd love any guidance! Thanks!

You could try:

Private Sub cmdOK_Click()
    Dim J As Long
    Dim c As Long

    With Sheets("Budget Input")
        J = .Range("ContractInputLine1").Row
        c = .Range("ContractInputLine1").Column

        Do While Not IsEmpty(.Cells(J, c))
            J = J + 1
        Loop

        'Insert a new row for the new data, to ensure we don't start writing
        ' beyond the end of the ContractInputField range.  (Assumption is
        ' that there is already at least 1 blank row included at the end of
        ' ContractInputField or else even this won't stop the range being
        ' exceeded.)
        .Rows(J).EntireRow.Insert

        'Copy values, formulae, and formats from the previous row
        .Rows(J).EntireRow.FillDown

        'Replace values with values from the form    
        .Cells(J, c + 0).Value = Me.txtContractorName.Value
        .Cells(J, c + 1).Value = Me.txtContractPurpose.Value
        .Cells(J, c + 2).Value = Me.txtFlatRate.Value
        .Cells(J, c + 3).Value = Me.txtContractHourlyRate.Value
        .Cells(J, c + 4).Value = Me.txtContractHours.Value
        .Cells(J, c + 16).Value = Me.ContractYear2.Value
        .Cells(J, c + 17).Value = Me.ContractYear3.Value
        .Cells(J, c + 18).Value = Me.ContractYear4.Value
    End With

    'Clear boxes before next round of entry
    Dim ctl As Control

    For Each ctl In Me.Controls
        If TypeName(ctl) = "TextBox" Or TypeName(ctl) = "ComboBox" Then
            ctl.Value = " "
        ElseIf TypeName(ctl) = "CheckBox" Then
            ctl.Value = False
        End If

    Next ctl

End Sub

Note:

1) You'll notice I got rid of ActiveCell in the code. That is just my personal preference - I don't like Activating or Selecting things unless I absolutely have to - so change it back if you feel there is a need to.

2) In getting rid of ActiveCell, I had to include a variable c just in case ContractInputLine1 wasn't in column A. If it does start in column A, c can just be replaced with 1 everywhere, with c + 2 , for instance, being replaced by 3 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM