VBA Вставка данных из нескольких строк на основе списка - PullRequest
0 голосов
/ 23 апреля 2020

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

Private sub button1_click()
Dim rw  as integer
Dim ws as worksheets
Set worksheets(“Sheet1”)
Rw = ws.cells.find(what:=“*”, searchorder:=xlrows, searchdirection:=xlprevious, lookin:xlvalues).row + 1
Ws.cells(rw, 3).value = me.textbox1.value
Ws.cells(rw, 5).value = me.listbox1.value
End sub

Пожалуйста, помогите мне ?

1 Ответ

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

Я создал новый Workbook и новый UserForm с ListBox, TextBox и CommandButton с именами по умолчанию для этого примера.

Option Explicit
____________________________________________________________________________________

Private Sub CommandButton1_Click()

Dim NextBlankRow As Long
Dim TargetRange As Range
Dim ListBoxItem As Long
Dim SelectedItemsArray As Variant
Dim ArrayElementCounter As Long

ArrayElementCounter = 0

With Me.ListBox1
ReDim SelectedItemsArray(0 To .ListCount - 1)
    For ListBoxItem = 0 To .ListCount - 1
        If .Selected(ListBoxItem) Then
            SelectedItemsArray(ArrayElementCounter) = .List(ListBoxItem)
            ArrayElementCounter = ArrayElementCounter + 1
        End If
    Next ListBoxItem
End With

ReDim Preserve SelectedItemsArray(0 To ArrayElementCounter - 1)

With ThisWorkbook.Sheets("Sheet1")
    NextBlankRow = .Cells(Rows.Count, 3).End(xlUp).Row + 1
    Set TargetRange = .Range("C" & NextBlankRow & ":C" & NextBlankRow + UBound(SelectedItemsArray))
End With

Dim TargetCell As Range

ArrayElementCounter = 0
For Each TargetCell In TargetRange
    TargetCell.Value = Me.TextBox1.Value
    TargetCell.Offset(0, 2).Value = SelectedItemsArray(ArrayElementCounter)
    ArrayElementCounter = ArrayElementCounter + 1
Next TargetCell

End Sub

____________________________________________________________________________________

Private Sub UserForm_Initialize()

Dim ListBoxItemArray As Variant

ListBoxItemArray = Array("Listbox Item 1", "Listbox Item 2", "Listbox Item 3")

Dim ItemToAdd As Long

For ItemToAdd = LBound(ListBoxItemArray) To UBound(ListBoxItemArray)
    Me.ListBox1.AddItem (ListBoxItemArray(ItemToAdd))
Next ItemToAdd

End Sub

Вот скриншоты входов и выходов:

Данные, выбранные / введенные в UserForm

[Screenshot of UserForm with selected listbox items and textbox text[1]

Вывод на рабочий лист

Screenshot of output to the worksheet


Объяснение:

Private Sub UserForm_Initialize() событие заполняет ListBox для целей моего примера - вы можете игнорировать это, когда дело доходит до вашего кода, но я счел необходимым указать, как я заполнил ListBox Items и какими значениями.

Код события Private Sub CommandButton1_Click() разбит на 4 основных раздела (начиная с объявления переменных):

  1. With Me.LisBox1...End With

Очень Первое, что мы здесь делаем, это устанавливаем размер массива с помощью оператора ReDim. Для UpperBound или предела массива установлено свойство ListCount минус 1, что возвращает 1 меньше количества элементов в ListBox. Это гарантирует, что наш массив достаточно большой, чтобы вместить все значения элементов списка, если они все были выбраны, например, но делает это динамически, поэтому вы не тратите память, используя неоднозначное число, для проверки вашего кода в будущем, например 100, когда у вас может быть только 30 предметов. Если элементы добавлены или удалены, массив будет всегда правильного размера.

Причина, по которой мы минус 1, состоит в том, что я объявил от Option Base до 0 для массива, что означает, что он начинается с (или Lower Bound is) 0, а не с 1. См. Option Base Заявление для получения дополнительной информации.

Далее мы проходим oop через каждый ListBox элемент и оцениваем, является ли он Selected или нет. Если это так, мы используем свойство List(), чтобы присвоить значение этого элемента массиву. См. Для ... Следующие циклы для получения дополнительной информации о том, как они работают, и см. Использование массивов для их работы.

Теперь у нас есть SelectedItemsArray() полных значений для каждого выбранного элемента в списке.

ReDim Preserve SelectedItemsArray(0 To ArrayElementCounter - 1)

Так же, как и раньше, мы устанавливаем размер нашего массива, но на этот раз, включая часть оператора Preserve. Это означает, что мы можем изменить размер массива, но сохранить все текущие значения в нем - Если бы мы не использовали Preserve, массив был бы изменен, но потерял бы все значения. Мы снова устанавливаем Upper Bound динамически, чтобы изменить размер массива до количества выбранных элементов. (См. Using Arrays информацию о размерах массива et c.)

With ThisWorkbook.Sheets("Sheet1")...End With

В этом блоке With мы находим последнюю использованную строку Column C и присваиваем эту строку + 1 (поэтому она ссылается на следующую пустую строку) на LastUsedRow. Мы также определяем наш диапазон, который мы хотим записать в наши данные динамически, используя переменную LastUsedRow и Upper Bound нашего массива. Это сделано для того, чтобы в следующем разделе кода было записано правильное количество ячеек.

For Each TargetCell In TargetRange...Next TargetCell

Еще один l oop, но на этот раз используется For Each...Next. Очень похоже на For...Next l oop, но этот цикл проходит через элементы массива или коллекции - в этом случае мы будем проходить через каждую ячейку в нашем TargetRange.

Для каждой ячейки в диапазоне, помня, что наш диапазон установлен в Column C из следующей пустой строки, значение TextBox записывается в столбец C и каждое значение элемента ListBox из нашего массива записывается в столбец E. При выполнении итерации l oop увеличивается ArrayItemCounter, что обеспечивает запись следующего элемента массива в столбец E с каждым l oop.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...