найти наименьшее число, ближайшее к целому числу в массиве Excel - PullRequest
0 голосов
/ 06 марта 2020

У меня есть динамический c список значений в таблице Excel. Мне нужно найти способ определить наименьшее число в массиве, которое ближе всего к целому числу. пример: в одном случае список включает следующие числа: 1,56, 1,65, 1,71, 1,84, 1,94, 2,00, 2,06, 2,03, 2,22 ....... 2,95, 3,05, 3,81, 4,00 и т. д. c. число, которое я хочу найти в этом случае, составляет 2,00. Есть ли в Excel функция, которую я могу использовать для этого?

Ответы [ 2 ]

1 голос
/ 06 марта 2020

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

=MIN(IF((ROUND(ABS(ROUND(A2:INDEX(A:A,COUNTA(A:A)),0)-A2:INDEX(A:A,COUNTA(A:A))),10)=MIN(ROUND(ABS(ROUND(A2:INDEX(A:A,COUNTA(A:A)),0)-A2:INDEX(A:A,COUNTA(A:A))),10))),A2:INDEX(A:A,COUNTA(A:A))))

Должен быть введен как формула массива, используя Ctrl Сдвиг Ввод

enter image description here

enter image description here

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

РЕДАКТИРОВАТЬ

Это только эксперимент, чтобы увидеть, если вы получите правильный ответ, используя десятичные типы

Option Explicit
Option Base 1

Sub findClosestToInt()

Dim sht As Worksheet
Dim LastRow As Long, nRows As Long, nData As Long, nMins As Long
Dim i As Long
Dim data() As Variant, differences() As Variant, minData() As Variant
Dim minDiff As Variant, minValue As Variant, maxData As Variant


Set sht = ActiveSheet
LastRow = sht.Cells(sht.Rows.Count, "A").End(xlUp).Row
Debug.Print ("LR=" & LastRow)
nRows = LastRow - 1


ReDim data(LastRow - 1)
ReDim differences(LastRow - 1)

' store data as decimal

nData = 0
For i = 2 To LastRow
    If sht.Cells(i, 1) <> "" Then
        nData = nData + 1
        data(nData) = CDec(sht.Cells(i, 1))
    End If
Next i

ReDim Preserve data(nData)
ReDim differences(nData)

Debug.Print ("nData=" & nData)

' find differences from nearest integer

For i = 1 To nData
    differences(i) = Abs(data(i) - Round(data(i), 0))
    Debug.Print (differences(i)) ' no rounding errors
Next i

minDiff = Application.WorksheetFunction.Min(differences)

Debug.Print ("minDiff=" & minDiff)

ReDim minData(nData)

' find min of data where difference is equal to min difference

nMins = 0
For i = 1 To nData
    If differences(i) = minDiff Then
        nMins = nMins + 1
        minData(nMins) = data(i)
    End If
Next i

ReDim Preserve minData(nMins)

minValue = Application.WorksheetFunction.Min(minData)

Debug.Print ("minValue=" & minValue)

End Sub

Результат равен 1,99, что является правильным. Если вы просто используете (скажем) double, вы получите неправильный ответ.

Я думаю, что можно нормально использовать функцию рабочего листа Мин, как только вы отработали различия.

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

1 голос
/ 06 марта 2020

Просто мысль:

Формула для диф:

=ABS(IFERROR(MID($A2,1,FIND(".",$A2,1)-1),$A2)-$A2)

Формула для мин:

=INDEX($A$2:$B$14,MATCH(MIN($B$2:$B$14),$B$2:$B$14,0),1)

Результаты:

enter image description here

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