Функция не возвращает желаемое значение - PullRequest
0 голосов
/ 03 июля 2019

Я работаю над функцией VBA, которая читает 11-ю строку другого листа и находит минимальное значение в строке.

Однако абсолютное значение минимума должно быть меньше 100. (В строке отображаются обапроценты и обычные значения, и мне нужен только минимальный процент.)

Вот что я до сих пор: (он только вернул значение ноль)

Function Loss(worksheet1 As Worksheet) As Long
    Dim min As Double
    Dim i As Integer
    Dim myRight As Long, Colcount As Long

    min = 0

    myRight = ActiveSheet.Cells(1, ActiveSheet.Columns.Count).End(xlToLeft).Column

    For Colcount = 1 To myRight
        If (ActiveSheet.Cells(11, Colcount) > min) And Abs(ActiveSheet.Cells(11, Colcount) <= 100) Then
            min = ActiveSheet.Cells(11, Colcount)
        End If
        Exit For
    Next Colcount
End Function

образецданные

1 Ответ

0 голосов
/ 04 июля 2019

Сочетание:

min = 0

и

If (ActiveSheet.Cells(11, Colcount) > min) And Abs(ActiveSheet.Cells(11, Colcount) <= 100) Then

выглядит так, как если бы оно находило максимальное значение данных в диапазоне от 0 до 100. Если максимальное значение данных меньше 0, то похоже, что 0 будет возвращено.

В правой части сравнения есть более тонкая ошибка:

Abs(ActiveSheet.Cells(11, Colcount) <= 100)

Мы знаем из повествования вопроса, что вы хотите, чтобы это предложение возвращало True для значений ячеек от -100 до 100 включительно и False в противном случае. Фактически он возвращает True для значений ячеек, меньших или равных 100, и False в противном случае - поэтому, например, значение ячейки -198 заставит это предложение вернуть True.

Что должно сказать это предложение:

Abs(ActiveSheet.Cells(11, Colcount)) <= 100

Нам нужно взять абсолютное значение ячейки и затем сравнить его со значением 100. Ранее мы сравнивали исходное значение ячейки со значением 100 (что привело бы к истинному или ложному), а затем принимали абсолютное значение истинного или False (что ничего не меняет - True остается True, а False остается False).

Чтобы найти минимальное значение данных, тогда min должен начинаться с 100, а сравнение должно быть .Cells(11, Colcount) < min.

Объединение всего этого с предложениями в комментариях от bobajob и меня дает нам:

Option Explicit

Function Loss(worksheet1 As Worksheet) As Double

Dim min As Double
Dim i As Integer
Dim myRight As Long, Colcount As Long

min = 100

With worksheet1
    myRight = .Cells(1, .Columns.Count).End(xlToLeft).Column

    On Error GoTo err_handler

    For Colcount = 1 To myRight
        If (.Cells(11, Colcount).Value < min) And (Abs(.Cells(11, Colcount).Value) <= 100) Then
            min = .Cells(11, Colcount).Value
        End If
    Next Colcount

    On Error GoTo 0
End With

Loss = min

Exit Function

err_handler:

Select Case Err.Number
' Type mismatch
Case 13:
    With worksheet1.Cells(11, Colcount)
        MsgBox "Error in column " & Colcount & "; with value " & .Value & "; of type " & TypeName(.Value)
    End With

    ' Stop running the macro
    Stop
' For all other errors, just stop
Case Else:
    ' Stop running the macro
    Stop
End Select

End Function

Дополнительные примечания:

  • Я добавил Опция Явная как первая строка, требующая объявления переменных. Это необходимо для перейти в верхней части модуля, прежде чем любые подпрограммы или функции
  • Я указывал свойство Value каждый раз, когда мы смотрим на значение ячейки. Хотя Value является свойством по умолчанию для объекта Range, я предпочитаю указать, к какому свойству обращаются явно
  • Если строка 1 проверяемого листа не имеет одинакового количества столбцов в строке 11 этого листа вы можете получить неверные результаты. Это потому что мы вычисляем myRight в строке 1, а затем читаем данные из ряда 11
  • Я изменил тип возвращаемого значения функции с Long на Double на соответствовать типу данных min
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...