2016-08-19 8 views
0

Я новичок в Excel VBA и изучаю через пробную версию, а также часы и часы в Stack Overflow. Я потратил несколько часов на поиски решения (все еще выясняю, как наилучшим образом отвечать на вопросы VBA в Google ...), но не нашел того, что я мог понять, поэтому любая помощь или направление к существующей теме было бы оценено МОСТ.Excel VBA - ввод данных Userform в новой строке, вставленной в именованный диапазон с скопированными формулами

Первоначально я хотел, чтобы мой код вводил данные пользовательской формы в следующую пустую строку в определенном именованном диапазоне, но теперь я понимаю, что мне нужно, чтобы она была более гибкой.

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

есть, на данный момент, A50: E50. F50: V50 содержат формулы, которые необходимо переносить через столько строк, сколько у моего диапазона.

Когда пользователь нажимает кнопку «ОК» на пользовательской форме, мне нужно:

  • новой строки должны быть вставлены в пределах существующего диапазона (в пределах «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. Если она запустилась в колонке А, c может быть просто заменена на 1 везде, с c + 2, например, заменяется на 3.

+0

Это отлично работает для моих целей. Большое спасибо за четкое объяснение! Теперь просто любопытно - есть ли простой способ вставить строку в диапазон без пустой строки в конце диапазона? – Hummuston

+0

@ Hummuston - Я не выполнял много работы (т. Е. Нет) с программно заданными диапазонами, но вы можете ** расширить ** текущий диапазон, произнеся «ActiveWorkbook.Names» («ContractInputField»). RefersTo = "= 'Budget Input '! $ A50: $ E "& (J + 1)'. Ваш вопрос показывает, что текущий диапазон - это только одна строка, поэтому вы можете ** заменить ** диапазон на «ActiveWorkbook.Names» («ContractInputField»). RefersTo = «=« Ввод бюджета »! $ A" & (J + 1) & ": $ E" & (J + 1) '. – YowE3K