Здравствуйте. Возможно ли без перебора названий листов через for each и без on error как-то проверить наличие\отсутствие листа в книге? Причина вопроса в том, что on error по каким то причинам иногда на коде типа Set А = Workbooks(B).Worksheets(D) не отрабатывает и код вылетает с ошибкой "9" - Subсkript out of range. (break on unhandles error -стоит опция в редакторе кода)
Это происходит, когда нужного листа в книге нет. Собственно код пишется с целью проверки наличия листа. И далее идет: if A is nothing then собственно ветвление по наличию или отсутствию листа. Есть способ еще как-то проверить присутствие листа в книге?
Глючит эксель иногда. Если сбросить и открыть заново приложение - на том же коде ошибки уже нет. Через какое-то время может появиться. Отловить влияющие причины довольно проблематично. Хочу подстраховаться и обойти этот скользкий момент. потому и ищу альтернативы.
На форуме было - прочитать оглавление файла xls через АПИ(Володя Захаров вроде автор), но если у ТС родное глючит, предлагать лезть в системные функции..
Следующая универсальная функция не замечена в неподобающем поведении:
Код
' Проверяет, есть ли в коллекции Col объект с именем Name. Возвращает True (есть), False (нет)
Function ItemExists(ByVal Col, ByVal Name) As Variant
Dim v As Object
On Error Resume Next
Set v = Col.Item(Name)
ItemExists = (Err.Number = 0)
Set v = Nothing
On Error GoTo 0
End Function
Sub test()
Debug.Print ItemExists(Worksheets, "Лист3")
End Sub
sokol92 написал: Следующая универсальная функция не замечена в неподобающем поведении:
Опять on error... я пробовал вариации на эту тему уже. В том числе обращение к свойству Cells не существующего листа. Глюки... глюки... On error не срабатывает ни так ни эдак, как будто его нет.
Цитата
kuklp написал: На форуме было - прочитать оглавление файла xls через АПИ(Володя Захаров вроде автор),
Да, тема известная. Но с точки зрения быстродействия не айс. Тут тогда уж лучше for each. Меня последний только из-за быстродействия не устраивает. Листов в книге много и процедура к тому же очень много раз вызывается. Хотелось бы, чтобы она пошустрее лётала.
Пример - в студию (с #11). А по быстродействию - миллион проверок за 3 секунды:
Код
Sub test()
Dim t As Double, b As Boolean, i As Long
t = Timer
For i = 1 To 1000000
b = ItemExists(Worksheets, "Лист" & (i Mod 4))
Next i
Debug.Print Timer - t
End Sub
Private Function WorksheetIsExist(iName$) As Boolean
'***********************************************'
' Дата создания 01/01/2005 '
' Автор Климов Павел Юрьевич '
' http://www.msoffice.nm.ru '
'***********************************************'
On Error Resume Next
WorksheetIsExist = IsObject(Worksheets(iName$))
End Function
Private Function WorksheetIsExist(iName$) As Boolean
On Error Resume Next
WorksheetIsExist = (TypeOf Worksheets(iName$) Is Worksheet)
End Function
Private Function WorksheetIsExist(iName$) As Boolean
On Error Resume Next
WorksheetIsExist = (TypeName(Worksheets(iName$)) = "Worksheet")
End Function
Private Function WorksheetIsExist(iName$) As Boolean
On Error Resume Next
WorksheetIsExist = (VarType(Worksheets(iName$)) = vbObject)
End Function
Private Function WorksheetIsExist(iName$) As Boolean
On Error Resume Next
WorksheetIsExist = Len(Worksheets(iName$).Name) > 0
End Function
Private Function WorksheetIsExist(iName$) As Boolean
On Error Resume Next
WorksheetIsExist = Worksheets(iName$).Index > 0
End Function
'Пример вызова любой из вышеопубликованных авторских функций :
Private Sub Test()
MsgBox WorksheetIsExist("Имя_Рабочего_Листа")
End Sub
Нет примера не рабочего кода. Есть пример приложения, в котором on error периодически перестает выполнять свою роль. С приложением в разумный срок разобраться не сможете.
sokol92 написал: А по быстродействию - миллион проверок за 3 секунды:
Ну да, в попугаях мы гораздо длиннее. Нагрузи книгу листами и все уже много печальнее. - 100 тысяч итераций = 16 секунд в моей рабочей книге. Объем обработки в моей задаче предполагает пару миллионов итераций. Это лишние 3 минуты выполнения кода.
Neufazendnik написал: Есть пример приложения, в котором on error периодически перестает выполнять свою роль
Я не программист и не претендую, те отрывочные знания накопленные по необходимости - не так обширны, но вот уж тут они позволяют вспомнить про "Одного в ногу и семь не в ногу в строю" , только в данном случае наоборот. У Вас сбоит что-то общее, что приводит к программному сбою, а Вы ищете метод который будет работать без сбоя, как Вам кажется. Ну сработает метод тут, вылезет проблема в другом, по не устраненной причине. Хорошо, не получается обработать ошибку, чем перебор плох? Долго писать - вроде нет, долго обрабатывать - ну все от количества листов зависит, но не думаю что критично. Ну сделайте словарь, хранимый в памяти и используйте его, только естественно пополнять новыми и удалять ненужные объекты не забывайте.
Так перебором и заткнул дыру пока. Но мало ли, вдруг чего не знаю и есть еще варианты. Потому и задал вопрос. А с причиной сбоя разбираться нет смысла. Так или иначе со временем наверняка и она вылезет. Зацикливаться на ней слишком затратно. Так что принимаю ситуацию как есть и стараюсь сделать код стабильнее.
БМВ написал: ой, как это неправильно, но Вам решать.
Объем работы, необходимый на выявление причины, оцениваю в несколько месяцев. Зачем? Если что критичное, оно вылезет в явной форме со временем. Не вылезет - значит не столь критично. Ситуация то какая. Имеем сутками и неделями работающее приложение. В какой-то момент появляется сбой. От чего? Да фиг знает. Сотни сложных подпрограмм отработали по 100 раз, прежде чем проблема на каком-то этапе образовалась. Логичного механизма отловить этот этап практически не возможно помыслить. Сидеть надеяться на случай - не метод. Задача на мой взгляд из числа неберучек. В лоб решать нет смысла. Нужно ждать появления стабильных закономерностей, после которых появляется сбой. Тогда будет возможность разобраться с его причиной.
Neufazendnik написал: оцениваю в несколько месяцев
Еще одно озарение Я всю систему, со всеми установленными программами, настройками, драйверами переустанавливаю за 5-7 минут. Из записанного образа. Но Вы идете своим, непроторенным доселе путем. Уважаю!
Я о своей системе со своими программами писал. За пару тысяч рублей(вообще-то мало, штук за пять будет нормально) легко установлю на ваш комп свой образ со своими драйверами. Если Вы этого не понимаете, еще плюс сто Вам в карму.
А зачем мне Ваши драйвера? Вы тему явно попутали. И я это хорошо понимаю. Или вы из тех диагностов, что при любой поломке кричат: У вас отвалился задний мост! Давайте я помогу его поменять!
Да угомонитесь уже. Вы по пять раз редактируете свои посты. Зачем? Мне неинтересно. Вы не хотите слушать других: У всех работает код с On error - у Вас нет. А дальше читайте #23. Ради Бога, идите своим путем, меняйте радиостанцию в приемнике, колпачки на шинах, что хотите. Месяцами, годами. Я приветствую Вашу приверженность к упрямству))