VBA – Как я могу дать код ошибки на основе суммы моих значений текстового поля в форме пользователя?

Поэтому в настоящее время у меня есть пользовательская форма с тремя полями ввода и кнопкой сохранения. Три входа должны быть между 0.0 и 1.0, что я и сделал, используя приведенный ниже код.

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

На самом деле застрял на этом и попробовал несколько разных методов, которые не работали.

Есть какой-либо способ сделать это?

Private Sub CommandButton1_Click() Dim textbox1 As Integer Dim textbox2 As Integer Dim textbox3 As Integer On Error GoTo errHandler textbox1 = CInt(UserForm1.textbox1.Value) If textbox1 > 1 Then MsgBox "Invalid Input, Please enter value between 0.0 and 1.0" Else UserForm1.Hide End If On Error GoTo errHandler textbox2 = CInt(UserForm1.textbox2.Value) If textbox2 > 1 Then MsgBox "Invalid Input, Please enter value between 0.0 and 1.0" Else UserForm1.Hide End If Exit Sub On Error GoTo errHandler textbox3 = CInt(UserForm1.textbox3.Value) If textbox3 > 1 Then MsgBox "Invalid Input, Please enter value between 0.0 and 1.0" Else UserForm1.Hide End If Exit Sub errHandler: MsgBox Err.Description End Sub 

Я принял некоторые вольности, отвечая на ваши вопросы, потому что видел возможности улучшить ваш код и просто получить ответ. Код ниже должен быть легче читать / управлять, и я надеюсь, что это поможет вам в написании лучшего кода в будущем ниже. Код сначала, а затем я объясню процесс:

 Private Sub CommandButton1_Click() Dim Inputs(1 To 3) As Variant Dim Total As Double ' It is better to anticipate errors (check the values that could cause an error) than it is to ' use a GoTo block that catches everything. ' On Error GoTo errHandler Inputs(1) = GetInputFromTextbox(UserForm1.textbox1) Inputs(2) = GetInputFromTextbox(UserForm1.textbox2) Inputs(3) = GetInputFromTextbox(UserForm1.textbox3) ' Handle the errors all in the same block (simply for readability) If IsEmpty(Inputs(1)) Then InvalidInput "Textbox1" UserForm1.Hide ElseIf IsEmpty(Inputs(2)) Then InvalidInput "Textbox2" UserForm1.Hide ElseIf IsEmpty(Inputs(3)) Then InvalidInput "Textbox3" UserForm1.Hide Else ' This will only execute if the three previous inputs are valid Total = Application.WorksheetFunction.Sum(Inputs) If Total <> 1 Then TotalInputsInvalid Total End If End If End Sub ' Define the function as a variant so it can return a null value ' This is important since the user could enter a 0 value and the default return of ' the function, if defined as a numeric type, would be 0. This would, in turn, prevent error handling. Private Function GetInputFromTextbox(ByVal InputMember As Object) As Variant If IsNumeric(InputMember.Value) Then If CDbl(InputMember.Value) < 1 Then GetInputFromTextbox = Round(CDbl(InputMember.Value), 2) End If End If ' Notice that, if the conditions for a valid input are not met, nothing happens. ' This allows us to handle errors within the calling routine. End Function ' This will alert the user if the input given is invalid. Private Sub InvalidInput(ByVal MemberName As String) MsgBox "There is an invalid input in " & MemberName & ". Please enter value between 0.0 and 1.0." End Sub Private Sub TotalInputsInvalid(ByVal TotalValue As Double) MsgBox "The total value of all inputs must equal 1. The current total is " & Round(TotalValue, 2) & ". Please adjust the inputs accordingly." End Sub 

Прежде всего, я определил одну переменную для входных значений. Главное преимущество этого заключается в том, что ваш код чище и имеет больше смысла. Наличие таких переменных, как Foo1, Foo2, Foo3 и т. Д., Делает ваш код немного более беспорядочным. Массив может облегчить этот процесс, особенно если это приложение должно масштабироваться для размещения большего количества текстовых полей.

Также обратите внимание, что, по предложению YowE3k, я объявил массив как массив double s, а также с Total . Double s разрешает точность с плавающей запятой, тогда как Long s и Integer s допускают только целые числа (поделитесь этим, никогда не используйте Integer . Получайте привычку использовать Longs только для чего-то, что вы использовали бы для Int).

Затем я определил функцию, которая получает чистый ввод из текстового поля. Это хорошая привычка. Имейте в виду, что скопировать-вставку теперь неизбежно означает дополнительное время отладки / исправления позже. Есть редкие случаи, когда это несколько неизбежно для текущих обстоятельств, но чаще, чем функция или Суб, творят чудеса.

В случае функции, которую я определил, она сначала проверяет числовой ввод (исключая ошибку несоответствия типа), а затем проверяет, чтобы значение не превышало 1. Если оба этих условия успешно, то оно возвращает значение (округленное ко второму знаку после запятой), иначе он ничего не возвращает.

Я использую эту функцию для получения всех трех значений, а затем проверяю правильность всех трех значений в том же блоке If / ElseIf. Это гарантирует, что все три значения действительны до выполнения окончательной проверки.

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

Процесс здесь – использовать функции для возврата значений, а затем использовать логику для обработки ошибок. Это намного эффективнее, чем блоки GoTo, и делает код отладки намного проще (по крайней мере, в моем опыте).

Если у вас есть какие либо вопросы, пожалуйста спрашивайте. Удачи!

EDIT: Изменено объявление входов от Double to Variant. Тип Double автоматически устанавливает базовые значения равными 0 в зависимости от разрешения Empty . Это, в свою очередь, предотвращает проверку недопустимых значений по сравнению с нулями. Тип Variant фиксирует это.

  • VBA Как проверить, существуют ли значения пользовательской формы combobox в базе данных
  • Приложение Lauch внутри пользовательской формы
  • Флажки пользовательской формы Excel: null
  • Назначение обработчиков событий для элементов управления в пользовательской форме, созданных динамически в VBA, в подпункте
  • Ошибка выполнения VBA Excel VBA -2147319767 (80028029)
  • excel vba userforms: пользовательский тип не определен
  • Вызов массива по пользовательской форме Завершение / закрытие VBA
  • Выбор и удаление листов Excel с помощью пользовательской формы
  • Автоматическое открытие нескольких пользовательских форм
  • Пользовательские формы Excel: таинственное поведение событий мыши
  • Excel Userform - Обратный фокус на ComboBox после нажатия кнопки ввода
  • Interesting Posts

    Проверка орфографии и получение предлагаемого списка в следующей ячейке

    Попытка объединить содержимое нескольких текстовых файлов в виде ячейки, каждая в электронной таблице

    Как использовать INDEX MATCH для возврата нескольких значений?

    Excel Добавить в отладку

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

    Необычная синяя коробка смерти – Visual Basic – Excel

    Таблица сводной таблицы Excel 2010 – преобразование текста в данные

    C # После сохранения CSV в Excel, как мне его открыть?

    Выделите определенные годы (по оси x) на графике

    Необходима реализация функции индекса excel

    Ошибка VB Visible Cell Paste 1004

    Microsoft ACE OLE DB 12.0 не зарегистрирован на локальном компьютере. Но это

    Excel VBA Debug: Loop не выполняет поиск по всему диапазону

    Как получить данные из XML в excel с помощью VBA?

    не может импортировать все данные в таблицу excel в sql в C #

    Давайте будем гением компьютера.