Проблема VBA: поиск минимальных и максимальных значений с пропуском недопустимых входных данных
Я работаю над проблемой VBA для поиска максимальных и минимальных значений в последовательности с пропуском недопустимых входных данных.
Проблема, с которой я столкнулся, заключается в том, что когда первое значение в последовательности недопустимо, переменная minnum автоматически получает значение 0. Например:
- Ввод 3, a, 1, 2 дает min = 0, max = 2
Однако, эта ошибка не возникает, если первый ввод допустим. Например:
- Ввод 3, 1, a, 2 дает min = 1, max = 2
Вот код VBA, с которым я работаю:
Sub minmaxnum()
Dim maxnum As Long
Dim minnum As Double
Dim n As Integer
Dim num As Double
Dim i As Integer
n = InputBox("How many numbers do you want to enter?")
maxnum = 0
minnum = 1E+39
On Error Resume Next
For i = 1 To n
num = InputBox("Enter those numbers: ")
If num > maxnum Then
maxnum = num
End If
If num < minnum Then
minnum = num
End If
Next i
MsgBox "Maxnum is: " & maxnum & vbCrLf & "Minnum is: " & minnum
End Sub
Как можно изменить этот код, чтобы правильно обрабатывать недопустимые входные данные, особенно когда первый ввод недопустим?
Проблема возникает из-за того, что On Error Resume Next приводит к тому, что неверные входные данные, такие как “a”, преобразуются в 0, что делает 0 минимальным значением, когда первый ввод является неверным. Вот как это исправить и правильно обрабатывать неверные входные данные:
Содержание
- Понимание проблемы
- Решение 1: Использование проверки IsNumeric
- Решение 2: Проверка ошибок с объектом Err
- Полная надежная реализация
- Лучшие практики для проверки ввода в VBA
- Тестирование и крайние случаи
Понимание проблемы
Когда активен On Error Resume Next и для InputBox предоставляется неверный ввод, такой как “a”, VBA автоматически преобразует его в 0. Поскольку ваш minnum начинается с 1E+39, это 0 становится новым минимумом, что приводит к неверным результатам.
Ключевое замечание с Stack Overflow заключается в том, что хотя On Error Resume Next предотвращает сбои, “он почти гарантирует, что программа не будет делать то, что вы хотите”, если используется без надлежащей проверки ошибок.
Решение 1: Использование проверки IsNumeric
Наиболее прямой подход - проверять ввод перед обработкой:
Sub minmaxnum()
Dim maxnum As Double
Dim minnum As Double
Dim n As Integer
Dim num As Double
Dim i As Integer
Dim inputStr As String
n = InputBox("Сколько чисел вы хотите ввести?")
maxnum = -1E+39 ' Инициализируем очень маленьким числом
minnum = 1E+39 ' Инициализируем очень большим числом
Dim hasValidInput As Boolean
hasValidInput = False
For i = 1 To n
inputStr = InputBox("Введите число " & i & ": ")
' Проверяем, нажал ли пользователь Отмена
If inputStr = "" Then Exit For
' Проверяем, является ли ввод числовым
If IsNumeric(inputStr) Then
num = CDbl(inputStr)
hasValidInput = True
If num > maxnum Then
maxnum = num
End If
If num < minnum Then
minnum = num
End If
Else
' Обрабатываем неверный ввод
MsgBox "Неверный ввод '" & inputStr & "'. Пожалуйста, введите число.", vbExclamation
i = i - 1 ' Повторяем эту итерацию
End If
Next i
If hasValidInput Then
MsgBox "Максимум: " & maxnum & vbCrLf & "Минимум: " & minnum
Else
MsgBox "Не было введено ни одного корректного числа.", vbInformation
End If
End Sub
Решение 2: Проверка ошибок с объектом Err
Как рекомендовано на Automate Excel, можно объединить On Error Resume Next с надлежащей проверкой ошибок:
Sub minmaxnum_with_error_checking()
Dim maxnum As Double
Dim minnum As Double
Dim n As Integer
Dim num As Double
Dim i As Integer
Dim hasValidInput As Boolean
n = InputBox("Сколько чисел вы хотите ввести?")
maxnum = -1E+39
minnum = 1E+39
hasValidInput = False
On Error Resume Next
For i = 1 To n
num = InputBox("Введите число " & i & ": ")
' Проверяем, возникла ли ошибка или пользователь нажал Отмена
If Err.Number <> 0 Or num = 0 Then
Err.Clear
' Проверяем, был ли ввод пустым (нажата Отмена)
If num = 0 Then Exit For
' В противном случае продолжаем - это был неверный числовой ввод
i = i - 1
GoTo ContinueLoop
End If
hasValidInput = True
If num > maxnum Then
maxnum = num
End If
If num < minnum Then
minnum = num
End If
ContinueLoop:
Next i
If hasValidInput Then
MsgBox "Максимум: " & maxnum & vbCrLf & "Минимум: " & minnum
Else
MsgBox "Не было введено ни одного корректного числа.", vbInformation
End If
End Sub
Полная надежная реализация
Вот наиболее надежное решение, которое обрабатывает все крайние случаи:
Sub robust_minmax()
Dim maxnum As Double
Dim minnum As Double
Dim n As Integer
Dim num As Double
Dim i As Integer
Dim inputStr As String
Dim hasValidInput As Boolean
Dim validCount As Integer
' Получаем количество вводимых чисел
n = InputBox("Сколько чисел вы хотите ввести?")
If n <= 0 Then Exit Sub
' Инициализируем экстремальными значениями
maxnum = -1E+39
minnum = 1E+39
hasValidInput = False
validCount = 0
For i = 1 To n
inputStr = InputBox("Введите число " & i & ": ")
' Проверяем на отмену
If inputStr = "" Then Exit For
' Проверяем числовой ввод
If IsNumeric(inputStr) Then
num = CDbl(inputStr)
hasValidInput = True
validCount = validCount + 1
' Обновляем минимум и максимум
If validCount = 1 Then
' Первое корректное значение устанавливает и минимум, и максимум
maxnum = num
minnum = num
Else
If num > maxnum Then
maxnum = num
End If
If num < minnum Then
minnum = num
End If
End If
Else
' Обрабатываем неверный ввод с возможностью повторной попытки
Dim response As VbMsgBoxResult
response = MsgBox("Неверный ввод '" & inputStr & "'. Попробовать снова?", vbQuestion + vbYesNo, "Неверный ввод")
If response = vbNo Then
Exit For
Else
i = i - 1 ' Повторяем эту итерацию
End If
End If
Next i
' Отображаем результаты или сообщение об ошибке
If hasValidInput Then
MsgBox "Результаты:" & vbCrLf & _
"Корректных значений введено: " & validCount & vbCrLf & _
"Максимальное значение: " & maxnum & vbCrLf & _
"Минимальное значение: " & minnum, vbInformation, "Анализ завершен"
Else
MsgBox "Не было введено ни одного корректного числа.", vbExclamation, "Нет корректного ввода"
End If
End Sub
Лучшие практики для проверки ввода в VBA
На основе результатов исследований, вот ключевые лучшие практики:
-
Используйте функцию
IsNumeric- Как рекомендовано на FasterCapital, это стандартный способ проверки числового ввода в VBA. -
Надлежащая обработка ошибок - При использовании
On Error Resume Nextвсегда проверяйте объектErrи используйтеErr.Clear, как рекомендовано на Automate Excel. -
Правильная инициализация переменных - Избегайте использования 0 в качестве начальных значений для расчетов минимума/максимума, так как 0 может быть корректным вводом.
-
Обработка отмены пользователем - Проверяйте пустые строки, когда пользователь отменяет диалоговые окна ввода.
-
Предоставление четких обратных связей - Дайте пользователям информативные сообщения о неверных вводах.
Тестирование и крайние случаи
Протестируйте ваше решение с этими сценариями:
| Тестовый случай | Ожидаемый результат |
|---|---|
| Первый ввод неверный, затем корректные числа | Пропустить неверный, обработать корректные |
| Все вводы неверные | Показать сообщение об ошибке, без мин/макс |
| Смешанные корректные/некорректные вводы | Обрабатывать только корректные числа |
| Пользователь отменяет ввод | Корректный выход |
| Пустая строка как ввод | Обрабатывать как отмену |
| Десятичные числа | Работать с типом Double |
| Очень большие числа | Обрабатывать научную нотацию |
Полное решение выше обрабатывает все эти случаи, предоставляя пользователям четкие обратные связи и поддерживая надежную обработку ошибок на протяжении всего процесса.