VBA Заполнить данные в другой столбец - PullRequest
0 голосов
/ 02 апреля 2020

Я постараюсь быть максимально понятным. Дело в том, что у меня есть форма classi c для ввода данных, которая имеет 19 столбцов. В зависимости от сложности проекта, иногда у нас есть дополнительные шаги, которые необходимо выполнить, для моей пользовательской формы это означает дополнительный столбец. Я создал кнопку добавления для таких ситуаций, чтобы добавить дополнительный столбец в указанное c место в таблице. Теперь проблема заключается в вводе данных в мою таблицу, поскольку каждое текстовое поле имеет свое собственное заранее определенное место (столбец), в котором необходимо хранить данные, но когда я добавляю столбец, он последовательно сохраняет данные в неправильном столбце. Мой вопрос заключается в том, можно ли сделать заявление if, которое распознает, что я добавил дополнительный столбец, и что в соответствии с этим сохранит оставшиеся данные в правильном месте. Я также подумал, если будет проще заполнить данные на основе имен моих заголовков.

Sub Submit()

Dim sh As Worksheet
Dim iRow As Long
Set sh = ThisWorkbook.Sheets("PFU")

If frmForm.txtRowNumber.value = "" Then
    iRow = [Counta(PFU!A:A)] + 2
Else
    iRow = frmForm.txtRowNumber.value
End If

With sh
    .Cells(iRow, 1) = iRow - 2
    .Cells(iRow, 2) = frmForm.txtID.value
    .Cells(iRow, 3) = frmForm.txtName.value
    .Cells(iRow, 4) = frmForm.cmbNatureIPR.value
    .Cells(iRow, 5) = frmForm.cmbStatus.value
    .Cells(iRow, 6) = frmForm.txtCity.value
    .Cells(iRow, 7) = frmForm.txtCountry.value
    .Cells(iRow, 8) = frmForm.txtGrantDate.value
    .Cells(iRow, 9) = frmForm.txtGrantNumber.value
    .Cells(iRow, 10) = frmForm.txtAgent.value
    .Cells(iRow, 11) = frmForm.txtCurrentOwner.value
    .Cells(iRow, 12) = frmForm.txtTargetOwner.value
    .Cells(iRow, 13) = frmForm.cmbDVStatus.value
    .Cells(iRow, 14) = frmForm.txtVerifiedOwner.value
    .Cells(iRow, 15) = frmForm.txtVerifiedApp.value
    .Cells(iRow, 16) = frmForm.txtVerifiedGrant.value
    .Cells(iRow, 17) = frmForm.cmbVerifiedStatus.value
    .Cells(iRow, 18) = frmForm.cmbRecAction.value
    .Cells(iRow, 19) = frmForm.txtComment.value
End With

End Sub

Это мой код для кнопки добавления

Private Sub cmdAddStep_Click()

Dim Table As ListObject
Dim ws As Worksheet

Set ws = Worksheets("PFU")

  If MsgBox("Are you sure you want to add additional colum?", vbYesNo + vbQuestion, "Added") = vbYes 
 Then
Set Table = ws.ListObjects("Table4")
Table.ListColumns.Add 12
Table.HeaderRowRange(12) = "New header"
End If

Call Reset


End Sub

1 Ответ

0 голосов
/ 02 апреля 2020

Вы ничего не говорите, даже если я думаю, что вы должны ... У меня нет времени ждать.

Я подготовил решение, работая в следующих обстоятельствах: Вы можете вставить, сколько столбцов вы нужно, , но вы НЕ будете заполнять данные в этих столбцах , как в первом коде. Код может быть адаптирован, чтобы также справиться с такой ситуацией. Не очень сложно.

Вы должны построить строку, связывающую в ее логике c заголовок столбца с элементами управления формы, из которых используется значение:

strHeaders = "HeaderB;2|HeaderC;3|HeaderD;4|HeaderE;5|HeaderF;6|HeaderG;7|HeaderH;8|HeaderI;9|HeaderJ;10"

Логика построения c просто: заголовок связан с управляющим тегом , разделенным ";". Каждый заголовок разделен "|". Таким образом, вы должны назначить соответствующие теги элементам управления формы (начиная с 2).

Sub SafeInsertOnHeader()
   Dim ws As Worksheet, Table As ListObject, strHeaders As String, h As Long
   Dim arrH As Variant, arrInt As Variant, El As Variant, Ctrl As Control, iRow As Long
   Set ws = ThisWorkbook.Sheets("PFU")
   Set Table = ws.ListObjects("Table1")
   strHeaders = "HeaderB;2|HeaderC;3|HeaderD;4|HeaderE;5|HeaderF;6|HeaderG;7|HeaderH;8|HeaderI;9|HeaderJ;10"
   arrH = Split(strHeaders, "|")

    If frmForm.txtRowNumber.value = "" Then
        iRow = [Counta(PFU!A:A)] + 2
    Else
        iRow = frmForm.txtRowNumber.value
    End If

   ws.Cells(iRow, 1) = iRow - 2 'independent of a control value

   For h = 1 To Table.HeaderRowRange.Count 'iterare through the headers
        For Each El In arrH                'iterate through the array elements
            arrInt = Split(El, ";")        'create each element array (header and tag)
            If Table.HeaderRowRange.Columns(h) = arrInt(0) Then
                For Each Ctrl In frmForm.Controls
                   If Ctrl.Tag = arrInt(1) Then 'for the tag matching the array association
                        ws.Cells(iRow, h).value = Ctrl.value
                   End If
                Next
            End If
        Next
   Next h
End Sub

Если вам нужно использовать новый вставленный столбец, во время кода вставки столбца строка strHeaders будет изменена с помощью соответствующий header;tag. Строка будет сохраняться в реестре и использоваться каждый раз при чтении реестра.

Следующий подход еще проще. Вы непосредственно будете использовать имя заголовка в качестве управляющего тега:

Sub SafeInsertOnHeaderBis()
   Dim ws As Worksheet, Table As ListObject, strHeaders As String, h As Long
   Dim arrH As Variant, El As Variant, Ctrl As Control, iRow As Long
   Set ws = ThisWorkbook.Sheets("PFU")
   Set Table = ws.ListObjects(1) ' ws.ListObjects("Table1")
   strHeaders = "HeaderA|HeaderB|HeaderC|HeaderD|HeaderE|HeaderF|HeaderG|HeaderH|HeaderI|HeaderJ|HeaderK"
   arrH = Split(strHeaders, "|")
    'I used your way of last row determinig but it can be done a little better
    If frmForm.txtRowNumber.value = "" Then
        iRow = [Counta(PFU!A:A)] + 2
    Else
        iRow = frmForm.txtRowNumber.value
    End If

   'Each control will have like tag the header name!
   ws.Cells(iRow, 1) = iRow - 2

   For h = 1 To Table.HeaderRowRange.Count
        For Each El In arrH
            If Table.HeaderRowRange.Columns(h) = El Then
                For Each Ctrl In frmForm.Controls
                   If Ctrl.Tag = El Then
                        ws.Cells(iRow, h).value = Ctrl.value
                   End If
                Next
            End If
        Next
   Next h
End Sub

Так, например, для headerA необходимо выбрать txtID элемент управления формы, нажать F4, чтобы открыть Properties, прокрутите вниз, пока не увидите свойство Tag, и заполните его значение строкой headerA. Сделайте одинаковые ассоциации для всех ваших пар header/control name, сохраните форму и наслаждайтесь ее использованием, вставляя столбцы ...

...