Пять самых больших значений в столбце
Моя цель состоит в том, чтобы отправить сообщение о пяти самых больших значениях в столбце. Но поскольку я использую ">", значения в столбце перед L не учитываются для La или Lb, если на то пошло. Например:
7
8
5
3
6
2
L становится 8
, но La (второй по величине) становится 6
(но должен был быть 7
), Lb (третий по величине) становится 2
, а Lc =0
, Ld=0
.
Sub maxtest3()
Dim L As Integer, La As Integer, Lb As Integer, Lc As Integer, Ld As Integer
Dim a As Variant
L = 0
La = 0
Lb = 0
Lc = 0
Ld = 0
For Each a In Range("A1:A20")
If a.Value > L Then
L = a.Value
Else
If a.Value > La Then
La = a.Value
Else
If a.Value > Lb Then
Lb = a.Value
Else
If a.Value > Lc Then
Lc = a.Value
Else
If a.Value > Ld Then
Ld = a.Value
Else
End If
End If
End If
End If
End If
Next
MsgBox (L & " " & La & " " & Lb & " " & Lc & " " & Ld)
End Sub
Я знаю, что тот, кто видит это, может решить проблему с помощью одной строки кода, но, пожалуйста, воздержитесь от этого. это делается ради обучения новичка.4 ответа:
Вложенные операторы
If ... Else ...
можно было бы проще записать в виде оператораSelect Case . Это может даже улучшить читаемость.Проблема заключалась в том, что последующие значения перезаписывали предыдущие. Существующие значения необходимо переместить дальше в очередь, прежде чем они будут перезаписаны. Хотя следующий код немного многословен, он должен адекватно продемонстрировать решение.
Sub maxtest3() Dim L As Variant, a As Range, rng As Range Set rng = Range("A1:A" & Cells(Rows.Count, "A").End(xlUp).Row) ReDim L(1 To 5) For Each a In rng Select Case a.Value Case Is > L(1) L(5) = L(4) L(4) = L(3) L(3) = L(2) L(2) = L(1) L(1) = a.Value Case Is > L(2) L(5) = L(4) L(4) = L(3) L(3) = L(2) L(2) = a.Value Case Is > L(3) L(5) = L(4) L(4) = L(3) L(3) = a.Value Case Is > L(4) L(5) = L(4) L(4) = a.Value Case Is > L(5) L(5) = a.Value End Select Next a MsgBox Join(L, Chr(32)) End Sub
Я изменил ваш L x vars на простой одномерный массив. Это позволяет использовать функцияJoin для упрощения конкатенации строк в
MsgBox
.
Sub test() Range("A1", "A6").Copy 'adjust the column you want to sort Range("B1", "B6").PasteSpecial 'adjust to a free column Columns("B").Sort key1:=Range("B1"), _ 'adjust order1:=xlDescending, Header:=xlNo Dim i As Integer Dim str As String For i = 1 To 5 str = str & " " & Cells(i, 2).Value 'adjust to the column you pasted too Next Range("B1", "B6").Clear 'adjust MsgBox str End Sub
Джипед уже объяснил логику, почему ваша попытка
If Block
терпит неудачу. С другой стороны, поскольку вы используете Excel, вы можете использовать доступные функции .
Что-то вроде:Sub maxtest3() Dim L As Integer, La As Integer, Lb As Integer, Lc As Integer, Ld As Integer With Application.WorksheetFunction L = .Large(Range("A1:A20"), 1) La = .Large(Range("A1:A20"), 2) Lb = .Large(Range("A1:A20"), 3) Lc = .Large(Range("A1:A20"), 4) Ld = .Large(Range("A1:A20"), 5) End With MsgBox (L & " " & La & " " & Lb & " " & Lc & " " & Ld) End Sub
Надеюсь, это поможет.
Sub maxtest3() Dim L(4) As Integer Dim Lp(4) As Integer Dim i, j As Integer Dim RC As Boolean Dim a As Variant For i = 0 To 4 L(i) = 0 For Each a In Range("A1:A20") 'If the current cell location has been used before sets RC = False RC = True For j = 0 To i - 1 If Lp(j) = a.Row Then RC = False Next j 'If the current cell value is greater than the current value in L(i) 'AND the location has not been used already, sets L(i) to the current 'value and sets Lp(i) to the location of the current value If a.Value > L(i) And RC = True Then L(i) = a.Value Lp(i) = a.Row End If Next Next i MsgBox (L(0) & " " & L(1) & " " & L(2) & " " & L(3) & " " & L(4))
Конец Sub
Эта программа повторяет цикл выбора диапазона пять отдельных раз. Каждый раз, когда он делает петлю, он выбирает следующее по величине число. Переменные L(i) и Lp(i) представляют собой массивы из пяти элементов, каждый из которых будет содержать ваши пять самых больших чисел и их позиции в выбранном диапазоне. Это позволяет программе пропускать числа, которые она уже выбрала как более крупные.
Что нужно учитывать: Если одно и то же число появляется больше, чем попав в диапазон значений, каждый экземпляр можно выбрать как "самое большое" значение.
В настоящее время эта программа рассматривает только положительные целые числа. Если бы все числа в диапазоне были отрицательными числами, он вернул бы все нули. Чтобы исправить это, измените значение инициализации для L (i) с 0 на -32768 (самое большое отрицательное значение, которое можно сохранить в целом числе)