gpt4 book ai didi

excel - 有没有办法以编程方式确定是否在 VBA 中打开了错误处理?

转载 作者:行者123 更新时间:2023-12-03 07:46:29 26 4
gpt4 key购买 nike

背景
你好呀!我被困在试图在效率和稳健性之间做出决定。这是Excel中的VBA问题。
我有一个函数,GetTable (如下),它接受一个表名并在我的工作簿中返回相应的 ListObject。我更喜欢这种方法显式调用 ThisWorkbook.Worksheet.ListObjects("strTableName")因为如果表格移动到不同的工作表中,它提供了编码灵 active 。
最初,这是通过遍历每个 Worksheet 并检查每个 ListObject 是否具有与提供的输入匹配的名称来完成的。这是Option 1下面的代码。这种方法效果很好,虽然它不是特别有效,并且如果您有一个包含许多工作表和表格的大型工作簿,并且您在宏中抓取多个表格,它可能会减慢速度。
为了提高效率我改为Option 2 ,它显式调用每张纸上的表格。如果该表不存在,则它会引发错误,并且错误处理允许它直接移动到下一个工作表。当打开错误处理时,这非常适合正常使用工作簿。但是,当在调试期间关闭错误处理时,这会变得很痛苦,因为代码总是会卡在这里。
问题

  • 有没有一种方法可以以编程方式判断错误处理是打开还是关闭,以便函数可以根据情况在这两种方法之间切换?我意识到这可能会有风险,因为它会在调试期间运行不同的代码,但我仍然想知道这是否可能。
  • 如果没有,是否有另一种方法可以完成与选项 #2 类似的方法(或者如果您有想法,可以使用更有效的方法!)而不会引发错误?

  • 我知道对于这个函数,除非你有大量可笑的表,否则效率的提高通常并不重要,但我将它作为一个更大的函数库的一部分分享给更少精通代码的同事,因此他们可能无法有效地使用它并将其包含在大范围内循环。此外,找到正确的方法可能会在应用于其他功能时派上用场。
    在此先感谢您,祝您 body 健康!
    代码
    Function GetTable(strTableName As String) As ListObject
    'This function searches the workbook for a table with the exact name strTableName
    'Returns the table object
    'If nothing found then display message
    On Error Resume Next

    Dim sht As Worksheet
    Dim tbl As ListObject

    '#Option 1: Slower but doesn't throw errors
    'For Each sht In ThisWorkbook.Worksheets
    ' For Each tbl In sht.ListObjects
    ' 'Debug.Print sht.Name & " " & tbl.Name 'uncomment to print all table names
    '
    ' If LCase(tbl.Name) = LCase(strTableName) Then
    ' Set GetTable = tbl
    ' Exit Function
    ' End If
    ' Next tbl
    'Next sht

    '#Option 2: More efficient but causes problems when debugging
    For Each sht In ThisWorkbook.Worksheets

    Set GetTable = sht.ListObjects(strTableName) 'Generates runtime error 9 if table doesn't exist on sheet

    If Err.Number = 0 Then Exit Function 'No error means we've found the answer

    Err.Clear

    Next sht

    'If the code reaches this point it means the table wasn't found.
    'This may have negative implications depending on where this function is called.
    'This message gives the user an out
    Dim ans As Byte
    ans = MsgBox("Could not find table with name '" & strTableName & "'." & vbNewLine & vbNewLine & _
    "Would you like to abort code?", vbCritical + vbYesNo, "Table not found")

    If ans = vbYes Then End

    'Set GetTable = Nothing '#This is redundant

    End Function

    最佳答案

    这就是我所说的缓存:

    Function GetTable(ByVal strTableName As String, _
    Optional reset As Boolean = False) As ListObject
    Static dict As Object 'Static, so persists between calls
    Dim sht As Worksheet
    Dim tbl As ListObject, nm
    If reset Then Set dict = Nothing '<< clear the cache
    If dict Is Nothing Then
    Set dict = CreateObject("scripting.dictionary")
    For Each sht In ThisWorkbook.Worksheets
    For Each tbl In sht.ListObjects
    nm = LCase(tbl.Name)
    If Not dict.exists(nm) Then dict.Add nm, tbl
    Next tbl
    Next sht
    End If
    strTableName = LCase(strTableName)
    If dict.exists(strTableName) Then Set GetTable = dict(strTableName)
    End Function

    第一次调用它时,它会扫描所有列表对象,但之后它将使用字典作为查找。

    您需要注意何时可能需要清除缓存,以考虑添加或删除的列表对象。

    关于excel - 有没有办法以编程方式确定是否在 VBA 中打开了错误处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60888317/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com