Фон
Привет! Я застрял, пытаясь сделать выбор между эффективностью и надежностью. Это вопрос VBA в Excel.
У меня есть функция GetTable
(ниже), которая берет имя таблицы и возвращает соответствующий объект ListObject в моей книге. Я предпочитаю, чтобы этот метод явно вызывал ThisWorkbook.Worksheet.ListObjects("strTableName")
, потому что он обеспечивает гибкость кодирования, если таблицы перемещаются на разные листы.
Первоначально это было сделано путем циклического просмотра каждого рабочего листа и проверки того, имеет ли каждый объект ListObject совпадающее имя с предоставленный вход. Это Option 1
кода ниже. Этот метод работает достаточно хорошо, хотя он не особенно эффективен и может замедлить работу, если у вас большая рабочая книга со множеством листов и таблиц, и вы захватываете несколько таблиц в своем макросе.
Чтобы повысить эффективность, я изменил на Option 2
, которая явно вызывает таблицу на каждом листе. Если таблица не существует, она выдает ошибку, и обработка ошибок позволяет ей перейти непосредственно к следующему рабочему листу. Это прекрасно работает для обычного использования книги, когда включена обработка ошибок. Однако, когда обработка ошибок отключена во время отладки, это становится проблемой, потому что код всегда будет зависать здесь. включен или выключен, чтобы функция могла переключаться между этими двумя методами в зависимости от случая? Я понимаю, что это может быть рискованно, потому что во время отладки он будет проходить через другой код, но я все же хотел бы знать, возможно ли это.
Если нет, есть ли другой способ, которым я могу выполнить sh a метод, аналогичный варианту № 2 (или более эффективный, если у вас есть идея!) без выдачи ошибки?
Я знаю, что для этой функции повышение эффективности часто не будет иметь значения, если вы не смешны количество таблиц, но я делюсь этим как часть большей библиотеки функций для менее опытных коллег, поэтому они могут не использовать это эффективно и включать в большие циклы. Также поиск правильного подхода может пригодиться для применения к другим функциям.
Заранее спасибо и крепкого здоровья!
Код
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