简体   繁体   English

Excel VBA-在具有复制公式的命名范围内插入的新行中输入用户窗体数据

[英]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. 我是Excel VBA的新手,正在学习反复试验和堆栈溢出方面的时间。 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. 我花了几个小时寻找解决方案(仍在弄清楚如何最好地解决Google VBA问题...),但没有找到我能理解的解决方案,因此,对现有线程的任何帮助或指导将不胜感激。

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. 目前是A50:E50。 F50:V50 contain formulas that need to be carried through as many rows as my range has. F50:V50包含的公式需要与我的范围一样多的行。

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) 在现有范围内插入新行(在“ ContractInputField”内,在该范围的最后一个条目的下方,以及不在该范围内并且已经具有宝贵内容的其他行的上方)
  • 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) 复制上一行中存在的公式的新行(当前为第50行,但第一个“ ok”将增长到51,然后第二个“ ok”将增长到51,依此类推)
  • 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. 1)您会注意到我在代码中摆脱了ActiveCell。 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 . 2)为了摆脱ActiveCell,我不得不包含一个变量c ,以防万一ContractInputLine1不在A列中。如果它确实在A列中开始,则c随处都可以替换为1,例如c + 2 。 ,被3取代。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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