Я всегда получаю ошибку в столбце 11 при попытке заполнить ListBox.
У меня есть таблица Excel на листе оценок с данными испытаний от B3 до P24. Первые 4 столбца — это текстовые данные, остальные 11 столбцов — числа от 1 до 100. Первая строка таблицы содержит в столбце 4 текст — имя оценщика, выбранное в поле со списком.
Я создал пользовательскую форму, в которой поместил ListBox. У меня также есть поле со списком с именами оценщиков. Я хочу заполнить ListBox только записями, где в столбце 4 указано имя эксперта, выбранного в поле со списком.
После инициализации UserForm я вызываю подпрограмму FilterPopulateListBox.
Private Sub FilterPopulateListBox()
Dim PSelectedAssessor As String
PSelectedAssessor = CmbAssessors.Value ' Get the currently selected assessor's name
Dim PWs As Worksheet
Set PWs = ThisWorkbook.Sheets("Evaluations")
Dim PLastRow As Long
PLastRow = PWs.Cells(PWs.Rows.Count, "B").End(xlUp).Row
Dim PData As Range
Set PData = PWs.Range("B3:P" & PLastRow)
' Clear previous entries in the ListBox
With lstEvaluations
.Clear
.ColumnCount = 15 ' Assuming there are 15 columns from B to P
.ColumnWidths = "50;50;50;50;50;50;50;50;50;50;50;50;50;50;50"
Debug.Print lstEvaluations.ColumnCount ' Should print 15
' Loop through each row in the range and add to ListBox if the fourth column matches
Dim PRow As Range
For Each PRow In PData.Rows
If PRow.Cells(1, 4).Value = PSelectedAssessor Then ' Check if fourth column matches the ComboBox
Dim PRowArray() As Variant
PRowArray = Application.Transpose(Application.Transpose(PRow.Value))
.AddItem PRowArray(1) ' Add first column value
Dim i As Integer
For i = 1 To UBound(PRowArray) ' Add other columns
.List(.ListCount - 1, i - 1) = CStr(PRowArray(i))
Next i
End If
Next PRow
End With
End Sub
в этой строке кода
.List(.ListCount - 1, i - 1) = CStr(PRowArray(i))
Я всегда получаю ошибку, когда i = 11
Когда i=11, значение PRowArray(i) равно 17, а строка
.List(.ListCount - 1, i - 1) = PRowArray(i)
показывает окно ошибки «Ошибка времени выполнения '380': не удалось установить свойство List. Недопустимое значение свойства».
При отладке, когда я указываю курсором на начало строки на .List(.ListCount - 1, i - 1)
, он говорит. «Не удалось получить свойство List. Неверный аргумент», но PROwArray(i) показывает значение 17.
Когда i меньше 11, отображается либо «Null» (перед выполнением этой строки — когда строка выделена), либо значение PROwArray(i), когда строка выполняется и выделяется следующая строка.
Я читаю форумы и Я спросил 5
Чтобы добиться того, что вы пытаетесь, вам нужно использовать .list = myArray
. Который способен загружать гораздо больше столбцов. Но, имея уже добавленные значения, вам следует использовать myArray = .column
, затем сохранить существующие и добавить новые данные.
Существует ограничение на использование несвязанного источника данных в ListBox. Максимальное количество столбцов — 10 (индекс 0–9). Ошибка возникает в i=11
(индекс столбца 10).
Рассмотрите возможность заполнения списка массивом, особенно если вы имеете дело с более чем 10 столбцами.
Option Explicit
Private Sub FilterPopulateListBox()
Dim PSelectedAssessor As String
PSelectedAssessor = CmbAssessors.Value ' Get the currently selected assessor's name
Dim PWs As Worksheet
Set PWs = ThisWorkbook.Sheets(1) ' modify as needed
Dim PLastRow As Long
PLastRow = PWs.Cells(PWs.Rows.Count, "B").End(xlUp).Row
Dim PData As Range
Set PData = PWs.Range("B3:P" & PLastRow)
Dim arrRes(), iR As Long, i As Integer
ReDim arrRes(1 To 15, 1 To PData.Rows.Count)
' Clear previous entries in the ListBox
With lstEvaluations
.Clear
.ColumnCount = 15 ' Assuming there are 15 columns from B to P
.ColumnWidths = "50;50;50;50;50;50;50;50;50;50;50;50;50;50;50"
Debug.Print lstEvaluations.ColumnCount ' Should print 15
' Loop through each row in the range and add to ListBox if the fourth column matches
Dim PRow As Range
For Each PRow In PData.Rows
If PRow.Cells(1, 4).Value = PSelectedAssessor Then ' Check if fourth column matches the ComboBox
Dim PRowArray() As Variant
PRowArray = Application.Transpose(Application.Transpose(PRow.Value))
iR = iR + 1
For i = 1 To UBound(PRowArray) ' Add other columns
arrRes(i, iR) = CStr(PRowArray(i))
Next i
End If
Next PRow
If iR > 0 Then
ReDim Preserve arrRes(1 To 15, 1 To iR)
.Column = arrRes
End If
End With
End Sub
Спасибо, выше. Мне просто нужно было изменить имя листа, и все работает. Теперь мне нужно понять это и «скопировать-вставить», чтобы создать подпрограмму при изменении значения поля со списком :)
Спасибо. Если можете, пожалуйста, помогите еще и с расширением условия. Будучи наивным 48-летним человеком, никогда не программистом (Паскаль и C, когда я был молод), я подумал, что просто расширим условие If (PRow.Cells(1, 4).Value = PSelectedAssessor) Затем с помощью AND (PRow.Cells(1, 1). Value = PSSelectedClass), чтобы он также проверял значение в другом поле со списком. Но я столкнулся с «Ошибкой времени выполнения 9: индекс вне диапазона» в строке ReDim Preserve arrRes (1 To 15, 1 To iR). Я предполагаю, что это потому, что там не было записей с выбранной комбинацией условий. Можете ли вы помочь?
@taller Прекрасный ответ +:); ты опередил меня на несколько минут. В любом случае вас может заинтересовать мой небольшой обходной путь в приложении к моему собственному сообщению, а также ссылка на ссылку.
@Radovan Добавьте предложение If
, чтобы избежать ошибки из-за отсутствия записей.
Пользовательская форма имеет не только встроенное ограничение в 10 столбцов при использовании метода .AddItem
.
Он даже игнорирует это, когда для свойства .ColumnWidth
явно установлено большее количество столбцов — он принимает начальное значение в 10 столбцов, что приводит только к ошибке 380 (невозможно установить свойство List — неверное значение свойства).
Обычно это ограничение можно обойти двумя способами:
.AddItem
, вы можете получить выгоду от минимального присвоения массива свойству .List на основе фактического количества столбцов с помощью следующей процедуры в качестве начального шага кода после определения нужного количества столбцов:Sub fixColumnCount(lbx As MSForms.ListBox, ByVal colCnt As Long)
'Auth.: T.M. (c) 2023-08
'Purp.: fix ColumnCount to an exact number (even greater than default of 10 cols) !!!!!!!!!!!!!
'Note: example call (here: to number of column captions (Row 1:1) in given range)
' fixColumnCount Me.ListBox1, rng.Columns.Count + 1
With lbx
.ColumnCount = colCnt
'.Column = Split(String(.ColumnCount, " "), " ")
.Column = Split(Space(.ColumnCount)) ' assign initial Array of empty strings to .Column prop
.Clear
End With
End Sub
Загрузка списка таким образом позволяет разместить максимум 10 столбцов (от 0 до 9).