【问题标题】:Range saving the result of a validity check possible?可以保存有效性检查结果的范围吗?
【发布时间】:2021-09-24 10:57:40
【问题描述】:

我正在编写几个UDF,它们都以Range 作为输入。因为我需要检查用户输入是否有效,所以我构建了另一个Function 来检查IsNumericIsEmpty 等内容。每次检查完成时,如果检测到一些问题,就会有一个MsgBox。我想保留这个MsgBox,但是因为有不同的UDF 将用于同一个Range 我想问我是否可以减少弹出窗口的数量?如果有办法“保存”另一个Function 已经完成对这个Range 的有效性检查的事实?无法提前知道函数将被调用多少次。

我的代码太长,还有其他问题,但这是基本思路:

Public Const maxn As Long = 10

Function Check(myRange As Range, p As Long, n As Long) As Boolean
    Dim i As Long, k As Long, x As Long
    Dim emptyCell As String, noNum As String, emptyRow As String 
    Dim empty(1 To maxn) As Long 

    For i = 1 To p
        For k = 1 To n
            If IsEmpty(myRange.Cells(i, k).Value) Then
                x = x + 1
                empty(k) = 1
                If x = n Then
                    emptyRow = emptyRow & vbLf & CStr(myRange.Row + i - 1)
                End If
            ElseIf Not IsNumeric(myRange.Cells(i, k).Value) Then
                noNum = noNum & vbLf & ColNo2ColLet(myRange.Column + k - 1) & CStr(myRange.Row + i - 1)
            End If
            If k = n And x > 0 And x <> n Then
                For x = 1 To n
                    If empty(x) = 1 Then emptyCell = emptyCell & vbLf & ColNo2ColLet(myRange.Column + x - 1) & CStr(myRange.Row + i - 1)
                Next x
            End If
        Next k
    Next i
    
    If emptyRow <> "" Then
        emptyRow = "Following rows are empty and will not be considered:" & emptyRow
        MsgBox (emptyRow)
    End If
    If emptyCell <> "" Then
        emptyCell = "Following cells are empty and will not be considered:" & emptyCell
        MsgBox (emptyCell)
    End If
    If noNum <> "" Then
        noNum = "Following cells contain nonnumeric values:" & noNum
        MsgBox (noNum)
        Check = CVErr(xlErrValue)
        Exit Function
    End If
    Check = True
End Function

Function ColNo2ColLet(x as Long) as String
'returns the Letters corresponding to the Column number provided by myRange.Column
End Function

Function sr(myRange As Range) as Double
    ' p, n get defined and checked
    Call Check(myRange, p, n)
    ' other calculations
End Function

Function Q(myRange As Range) as Double
    ' p, n get defined and checked
    Call Check(myRange, p, n)
    ' other calculations
End Function

【问题讨论】:

  • 您是否将Check 称为工作表中的公式?然后我强烈建议不要使用MsgBox,每次重新计算工作表时都会出现所有这些弹出窗口,这一定会让人感到困惑。 UDF 应该只返回一个值或一个值数组(如果您想返回多个值)。
  • 不,我只从其他公式中调用 Check.. 所以我只在 Qsr 中调用它。
  • 那么Qsr 是否用作表格中的公式?这仍然会触发重新计算的所有框。那会变得非常混乱。
  • 是的。我知道,但我需要它,因为我需要知道一行何时为空,并且我想避免遍历整个表格试图找出 2..5 而不是 2.5 的错字所在的位置。
  • 我认为您在此处提出问题 X,而您的实际问题是 Y。请参阅 What is the X/Y-Problem。如果您在这里提出正确的问题,请重新考虑。

标签: excel vba range


【解决方案1】:

这就是我所做的。我声明一个变量来存储消息,然后在其中“收集”消息。最后,我只在最后显示 1 个消息框,其中包含所有消息。

Option Explicit

Dim msg As String

Sub Sample()
    Dim Ret As Variant
    msg = ""

    Ret = SomeFunctionA(1)
    Ret = SomeFunctionB(1)
    
    If msg <> "" Then MsgBox msg
End Sub

Function SomeFunctionA(x As Long) As String
    '
    '~~> Some code
    '
    If msg = "" Then msg = "Error A" Else msg = msg & vbNewLine & "Error A"
End Function

Function SomeFunctionB(x As Long) As String
    '
    '~~> Some code
    ' 
    If msg = "" Then msg = "Error B" Else msg = msg & vbNewLine & "Error B"
End Function

如果您不想一遍又一遍地输入If msg = "" Then msg = ...,另一种方法

Option Explicit

Dim msg As String

Sub Sample()
    Dim Ret As Variant
    msg = ""
    
    Ret = SomeFunctionA(1)
    Ret = SomeFunctionB(1)
    
    If msg <> "" Then MsgBox msg
End Sub

Function SomeFunctionA(x As Long) As String
    '
    '~~> Some code
    '
    StoreMessage "Error A"
End Function

Function SomeFunctionB(x As Long) As String
    '
    '~~> Some code
    '
    StoreMessage "Error B"
End Function

Private Sub StoreMessage(s As String)
    If msg = "" Then msg = s Else msg = msg & vbNewLine & s
End Sub

【讨论】:

  • 听起来不错,但在这种情况下,如果我在 A4 和 B15 中有一个空单元格,并且在工作表中我调用 sr("A1:C31")Q("A1:C31"),那么我会收到消息:A4、B15、A4 ,B15..有没有办法只得到A4,B15?
  • 如果您收到重复消息,那么请使用 unique collection 代替字符串。
猜你喜欢
  • 2015-11-11
  • 2015-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-03
  • 1970-01-01
相关资源
最近更新 更多