【问题标题】:How do I make IsNumeric check the whole string/variable instead of just the first character?如何让 IsNumeric 检查整个字符串/变量而不仅仅是第一个字符?
【发布时间】:2020-05-06 05:09:22
【问题描述】:

我正在使用IsNumeric 检查变量的一部分是否为数字。不幸的是,它似乎只检查字符串部分的第一个字符而不是整个位。

它目前接受即 Q123 1234567 和 QWER 1QWERTYR(以及其他变体)。虽然我需要前 4 个字符都是字母,其他字符都是数字。

我不知道我还缺少什么。如果可能的话,请添加额外的 cmets,我对 vba 的理解仍然低于基本。

Dim ConNr As String
Dim Space As String
Dim Four As String
Dim Six As String
Dim One As String
Dim Container As String

ConNr = Me.txtContainer.Value
Space = " "
Four = Left(Me.txtContainer.Value, 4)
Four = UCase(Four)
Six = Mid(Me.txtContainer.Value, 5, 6)
One = Right(Me.txtContainer.Value, 1)

'Check if all 4 are letters
If IsNumeric(Four) = True Then
    MsgBox "First 4 need to be letters."
    Me.txtContainer.SetFocus
    Exit Sub
Else
    'MsgBox "Four Letters " + Four

'Check if 6 characters are numbers
If IsNumeric(Six) = False Then
    MsgBox "4 Letters followed by 6 numbers."
    'MsgBox "These Six " + Six
    Me.txtContainer.SetFocus
    Exit Sub
Else
    'MsgBox "Six Numbers " + Six

'Last number is number
If IsNumeric(One) = False Then
    MsgBox "Last character needs to be a number."
    Me.txtContainer.SetFocus
    Exit Sub
Else
    'MsgBox "Last Number " + One
    ConNr = Four & Space & Six & Space & One
    Container = ConNr
End If
End If
End If

基于 JvdV 编辑

当我尝试"[A-Za-z][A-Za-z][A-Za-z][A-Za-z] ###### #" 时,输出为空。

我不想强迫用户使用正确的格式。 (大写、空格。)但 4 个字母/7 个数字是必需的。


Dim ConNr As String: ConNr = Me.txtContainer.Value


If ConNr Like "[A-Za-z][A-Za-z][A-Za-z][A-Za-z]#######" Then ‘Without spaces, else it doesn’t post.
Container = UCase(ConNr)
    Else
    MsgBox "YOU FAILED."
    Me.txtContainer.SetFocus
    Exit Sub

End If

‘Output should become ASDF 123456 7. Currently gives me ASDF1234567.

【问题讨论】:

  • 我建议使用Regular Expressions 执行此操作:您可以使用类似^[A-Za-z]{4} [0-9]+$ 的模式来验证您的字符串。问题是isNumeric 只能判断整个(子)字符串是否为数字。它无法判断它是否包含数字。 • 如果您不想使用RegEx,那么您需要检查每个字符是否为数字,或者使用instr 来测试字符串是否包含0-9
  • 根据@Pᴇʜ,RegEx 是检查这些内容的绝佳方式,但Like 运算符有一个内置替代方案。
  • @Pᴇʜ 谢谢,在找到最近的神之前,仔细阅读了这篇文章并进行了一些诚实的尝试。我发现Like 选项对我来说更容易理解,因为我有点理解代码中发生了什么以及为什么。

标签: excel vba variables split isnumeric


【解决方案1】:

根据我的评论,特此提供一个简单的示例代码来演示Like 运算符的使用:

Sub Test()

Dim str As String: str = "QWER 1234567"
Dim arr As Variant: arr = Split(str, " ")

If arr(0) Like "[A-Z][A-Z][A-Z][A-Z]" And IsNumeric(arr(1)) Then
    Debug.Print str & " is passed!"
End If

End Sub

顺便说一句,如果你想允许大小写,你可以使用:[A-Za-z][A-Za-z][A-Za-z][A-Za-z]


编辑

如果您要寻找 4 个字母字符、空格、6 位数字的模式,您甚至可以做一些更简单的事情:

Sub Test()

Dim str As String: str = "QWER 123456"

If str Like "[A-Z][A-Z][A-Z][A-Z] ######" Then
    Debug.Print str & " is passed!"
End If

End Sub

如果您想包含另一个空格/数字,请扩展表达式。你在说:

“ConNr = 四 & 空格 & 六 & 空格 & 一”

所以[A-Z][A-Z][A-Z][A-Z] ###### # 在这种情况下会为你工作。


根据您的评论,您不希望对用户强制使用特定格式,只要他们的字符串中有 4 个字母和 7 个数字字符。任何形式。 所以我想,既然有这么多地方可以放置空间,最好使用Application.Substitute 摆脱它们。您的代码可能如下所示:

If Application.Substitute(Me.txtContainer.Value, " ", "") Like "[A-Za-z][A-Za-z][A-Za-z][A-Za-z]#######" Then
    Debug.Print str & " is passed!"
End If

如果您不想预测大写但仍想返回它,那么请使用UCase 函数一次对整个字符串进行封盖!

Debug.Print UCase(Application.Substitute(Me.txtContainer.Value, " ", ""))

很难掩饰这与RegEx 非常相似。

【讨论】:

  • 嗯,很好,我不知道Like 运算符接受基本的RegEx,如[A-Z] 之类的语法。很高兴知道和简单的检查可能比 RegEx 更容易实现。
  • 相当令人惊讶的权利! @Pᴇʜ。 Here 是一些很好的例子。然而它并没有告诉你,你可以组合这些范围。所以即使[A-Za-z0-9] 也可以工作(以及像[A-Ca-d3-7] 这样的变体)。
  • 测试了这些。他们工作!但是当我在[A-Z] 之后或# 之间添加空格时,字符串不会发布。当我删除这些时,数字确实会打印到工作表上,但作为 QWER1234567 而不是 QWER 123456 7。
  • @Davey,你能编辑你原来的问题并举一些例子吗?听起来您需要Application.Trim 才能进行比较。如果可以有任意数量的空格,请使用我帖子中的第一个解决方案,但要遍历返回的数组。
  • @JvdV 我编辑了这个问题,我希望这就是你的意思。恐怕我还不明白如何自己创建循环。
【解决方案2】:

在此解决方案中,合同编号格式的批准由一个函数提供,如果数字正确则返回 True,否则返回 False。如果数字不好,该函数会告诉它有什么问题。如果发现可接受,则调用程序继续执行该程序。请注意,该函数可容纳缺失或多余的空格,并将小写字母转换为大写字母。

Option Explicit

Private Sub TestConNumber()

    Dim ConNr As String

'    ConNr = Me.txtContainer.Value
    ConNr = "QAAK 781234 x"
    If GetConNumber(ConNr) Then
        MsgBox "The Contract number is " & ConNr
    End If
End Sub

Private Function GetConNumber(ConNr As String) As Boolean
    ' return Not True if incorrect

    Dim Fun As Boolean                     ' function return value
    Dim Nr As String
    Dim Msg As String
    Dim Arr(1 To 3) As String

    Nr = UCase(Replace(ConNr, " ", ""))
    If Len(Nr) = 11 Then
        Arr(1) = Left(Nr, 4)
        If Arr(1) Like "[A-Z][A-Z][A-Z][A-Z]" Then
            If IsNumeric(Right(Nr, 7)) Then
                Arr(2) = Mid(Nr, 2, 6)
                Arr(3) = Right(Nr, 1)
                ConNr = Join(Arr)
                Fun = True
            Else
                Msg = "The last 7 digits must be numbers."
            End If
        Else
            Msg = "The first 4 characters must be non-numeric"
        End If
    Else
        Msg = "Input must have 11 characters"
    End If

    If Not Fun Then
        MsgBox Msg, vbExclamation, "Wrong input"
    End If

    GetConNumber = Fun
End Function

【讨论】:

  • 我试过这个,但我得到一个编译错误'评论只允许在End SubEnd FunctionEnd Property 之后'。 (Option Explicit 被突出显示。)我还要将此代码添加到表单中还是需要将其添加到单独的模块中?
  • Option Explicit 必须位于代码表的最顶部,高于任何过程声明。函数调用应该在您现有的过程中: If GetConNumber(ConNr) Then 在顶部和 End If 在过程结束之前(避免使用 退出子s)。 GetConNumber 函数应该在调用过程的下方,但您也可以将它放在标准代码模块中。如果它与调用过程不在同一个模块中,则从其声明中删除单词“Private”以使其成为Public
猜你喜欢
  • 2018-11-21
  • 1970-01-01
  • 2019-11-05
  • 2021-12-31
  • 1970-01-01
  • 1970-01-01
  • 2015-11-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多