2016-08-19 71 views
0

我是Excel VBA的全新用戶,並且正在通過反覆試驗和在Stack Overflow上花費幾個小時來學習。我花了幾個小時尋找一個解決方案(仍然想出如何最好的谷歌VBA的問題...),但沒有找到一個我能理解,所以任何幫助或方向現有的線程將最受讚賞。Excel VBA - 使用複製的公式在指定範圍中插入新行中輸入用戶窗體數據

我原本希望我的代碼將用戶表單數據輸入到特定命名範圍內的下一個空行,但現在我意識到我需要它更加靈活。

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

是,在這一刻,是A50:E50。 F50:V50包含需要通過我的範圍所具有的行數的公式。

當用戶點擊「OK」用戶窗體上,我需要:

  • 一個新行到現有的範圍內被插入(內「ContractInputField」,該範圍的和上述其他的最後一個條目下面行不在範圍內,並且已經有珍貴的內容)
  • 新行復制上面行中存在的公式(當前行50,但會增長到51與第一個「好」,然後51與第二個「 OK「等)
  • 要輸入到新行中的用戶表單數據

下面是我爲我的原來的做法代碼:

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 

我喜歡的任何指導!謝謝!

回答

0

你可以嘗試:

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 

注:

1)你會發現我得到了在代碼擺脫ActiveCell的。這只是我個人的偏好 - 我不喜歡激活或選擇東西,除非我絕對必須 - 如果您覺得有必要,請將其改回。

2)在擺脫ActiveCell的,我必須包括一個可變c以防萬一ContractInputLine1沒有在列A如果它開始在A列,c可以只用1到處取代,c + 2,例如,由3取代。

+0

這很適合我的目的。非常感謝您的明確解釋!現在只是好奇 - 是否有一種簡單的方法可以將一行插入到一個範圍內,而不會在範圍的末尾留空行? – Hummuston

+0

@Hummuston - 我沒有用編程的方式設置範圍,也沒有做很多工作,但是你可以通過說'ActiveWorkbook.Names(「ContractInputField」)來擴展**當前範圍。RefersTo =「='預算輸入'!$ A50:$ E「&(J + 1)'。您的問題顯示當前範圍只有一行,因此您可能希望**用'ActiveWorkbook.Names(「ContractInputField」)替換**範圍。RefersTo =「='預算輸入'!$ A」&( J + 1)&「:$ E」&(J + 1)'。 – YowE3K