如何避免在VBA中使用goto命令?

3
我多次阅读到代码中应避免使用GoTo,然而我经常需要创建循环,如果一个项目给我错误,代码就会停止。

在下面的情况中,我必须比较单元格的值,但如果单元格中有字符串,我会得到一个错误。

您有任何其他选项来避免下面代码中的GoTo吗?

谢谢!

Sub Conditional()

        Dim x As Integer



        For x = 1 To 31



            On Error GoTo na


            If Sheets("Sheet1").Cells(8 + x, 5) >= 0.95 Then

                Sheets("Sheet2").Shapes("Shape " & x).Fill.ForeColor.RGB = RGB(0, 176, 80)

            ElseIf Sheets("Sheet1").Cells(8 + x, 5) < 0.95 Then

                Sheets("Sheet2").Shapes("Shape " & x).Fill.ForeColor.RGB = RGB(255, 0, 0)

            End If

            GoTo nextx

na:

            Sheets("Sheet2").Shapes("Shape " & x).Fill.ForeColor.RGB = RGB(0, 0, 0)
            On Error GoTo -1

nextx:
        Next x

End Sub

适当的错误捕获/处理可能是最佳选择。 - Skip Intro
2个回答

4
在这种情况下,如果您想检查单元格中的字符串,可以使用以下代码:
Sub Conditional()

    Dim x As Long

    For x = 1 To 31
        If IsNumeric(Sheets("Sheets1").Cells(8 + x, 5)) Then
            If Sheets("Sheet1").Cells(8 + x, 5) >= 0.95 Then

                Sheets("Sheet2").Shapes("Shape " & x).Fill.ForeColor.RGB = RGB(0, 176, 80)

            ElseIf Sheets("Sheet1").Cells(8 + x, 5) < 0.95 Then

                Sheets("Sheet2").Shapes("Shape " & x).Fill.ForeColor.RGB = RGB(255, 0, 0)

            End If
        End If
    Next x
End Sub

通常情况下,goto应该只用于错误捕获,例如On Error GoTo ErrorHandler,不应该有任何例外。


IsNumeric()在某些情况下可能会失败并返回“True”(即“它是一个数字”),而实际上它不是数字。例如,IsNumeric("1..23")将返回True。 而 SpecialCells(.., xlNumbers) 将返回 真正的 数字。 请参见我的下面的答案。 - user3598756
你能试一下 ?isnumeric(range("A3")) 并告诉我当你在单元格中输入 1..23 时得到什么吗? - Vityata
它返回 True - user3598756
@user3598756 我能看到那个的截图吗?麻烦了。这是我的:https://postimg.org/image/aitkcx4e1/ - Vityata
你尝试过将参数提交为范围或像这样给出它IsNumeric("1..23")吗?结果是不同的。 - Vityata
显示剩余3条评论

1

由于您要根据单元格的类型文本数字)进行一些格式设置,因此您可以使用Range对象的SpecialCells()方法,并输入以下函数:

Function GetCells(rng As Range, cellType As XlCellType, cellValues As XlSpecialCellsValue, outputRng As Range) As Boolean
    On Error Resume Next '<--| ignore subsequent errors, if any
    Set outputRng = rng.SpecialCells(cellType, cellValues) '<--| get a sub-range out of passed range as filtered by passed arguments
    GetCells = Not outputRng Is Nothing '<--| returns 'True' if range has been properly set
End Function

并按以下方式利用它:
Sub Conditional()
    Dim myCells As Range, cell As Range

    With Sheets("Sheet  1").Range("E9:E39") '<--| reference your sheet relevant range        
        If GetCells(.Cells, xlCellTypeConstants, xlNumbers, myCells) Then '<--| if any cells whose value is a "constant" "number" in your range
            For Each cell In myCells '<--| loop through those filtered cells
                Sheets("Sheet2").Shapes("Shape " & cell.row - 8).Fill.ForeColor.RGB = IIf(cell.Value >= 0.95, RGB(0, 176, 80), RGB(255, 0, 0)) '<--| format your shapes as per corresponding current cell
            Next cell
        End If

        If GetCells(.Cells, xlCellTypeConstants, xlTextValues, myCells) Then '<--| if any cells whose value is a "constant" "text" in your range
            Sheets("Sheet2").Shapes("Shape " & cell.row - 8).Fill.ForeColor.RGB = RGB(0, 0, 0) '<--| format your shapes as per corresponding current cell
        End If
    End With
End Sub

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接