Форум программистов, компьютерный форум, киберфорум
VBA
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.63/315: Рейтинг темы: голосов - 315, средняя оценка - 4.63
1018 / 122 / 2
Регистрация: 26.08.2011
Сообщений: 1,177
Записей в блоге: 2
1

Определить, есть ли лист в книге с заданным именем

28.06.2012, 18:03. Показов 62980. Ответов 13
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Нужно программно спросить есть ли лист в книге Excel с таким именем
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
28.06.2012, 18:03
Ответы с готовыми решениями:

Есть ли лист с определенным именем в книге?
Коллеги, подскажите, как определить это? Спасибо!

Определить существует ли лист в книге
Привет всем. Подскажите пожалуйста как определить существует ли лист в книге имя которого...

Проверить есть ли файл с заданным именем в папке
Здравствуйте. Мне необходимо проверить есть ли файл с таким именем в папке, и если есть, то...

Как создать новый лист в книге со ссылкой на предыдущий лист?
Добрый день. Есть реестр учета спецтехники. Его заполняет диспетчер каждый день. т.е. каждый день...

13
призрак
3263 / 891 / 119
Регистрация: 11.05.2012
Сообщений: 1,702
Записей в блоге: 2
28.06.2012, 18:08 2
Лучший ответ Сообщение было отмечено как решение

Решение

AndreA SN, я, конечно, рискую, но ради Вас готов разок получить по шее.
Вы задаёте так много интересных вопросов по Excel'ю, ответы на которые давным-давно лежат в сети.

а у меня к Вам один вопрос: Вы в курсе, что существуют поисковые системы?
3
здесь больше нет...
3374 / 1672 / 184
Регистрация: 03.02.2010
Сообщений: 1,219
28.06.2012, 18:09 3
Visual Basic
1
2
3
4
5
6
7
8
9
10
Function bSheetExist(sName As String) As Boolean
    Dim wksSh As Worksheet
    For Each wksSh In Sheets
        If sName = wksSh.Name Then
            bSheetExist = True
            Exit Function
        End If
    Next wksSh
    bSheetExist = False
End Function
1
6172 / 937 / 310
Регистрация: 25.02.2011
Сообщений: 1,367
Записей в блоге: 1
28.06.2012, 18:18 4
Лучший ответ Сообщение было отмечено как решение

Решение

Не мое:
Visual Basic
1
2
3
4
5
6
7
8
9
Private Function WorksheetIsExist(iName$) As Boolean
'***********************************************'
' Дата создания 01/01/2005 '
' Автор Климов Павел Юрьевич '
' [url]http://www.msoffice.nm.ru[/url] '
'***********************************************' 
On Error Resume Next
WorksheetIsExist = IsObject(Worksheets(iName$))
End Function
Visual Basic
1
2
3
4
Private Function WorksheetIsExist(iName$) As Boolean
On Error Resume Next
WorksheetIsExist = (TypeOf Worksheets(iName$) Is Worksheet)
End Function
Visual Basic
1
2
3
4
Private Function WorksheetIsExist(iName$) As Boolean
On Error Resume Next
WorksheetIsExist = (TypeName(Worksheets(iName$)) = "Worksheet")
End Function
Visual Basic
1
2
3
4
Private Function WorksheetIsExist(iName$) As Boolean
On Error Resume Next
WorksheetIsExist = (VarType(Worksheets(iName$)) = vbObject)
End Function
Visual Basic
1
2
3
4
Private Function WorksheetIsExist(iName$) As Boolean
On Error Resume Next
WorksheetIsExist = Len(Worksheets(iName$).Name) > 0
End Function
Visual Basic
1
2
3
4
Private Function WorksheetIsExist(iName$) As Boolean
On Error Resume Next
WorksheetIsExist = Worksheets(iName$).Index > 0
End Function
Пример вызова любой из вышеопубликованных авторских функций :
Visual Basic
1
2
3
Private Sub Test()
MsgBox WorksheetIsExist("Имя_Рабочего_Листа")
End Sub
9
Эксперт MS Access
26812 / 14491 / 3192
Регистрация: 28.04.2012
Сообщений: 15,782
28.06.2012, 19:04 5
Лучший ответ Сообщение было отмечено как решение

Решение

Ну и мои 5 копеек...

Можно использовать ADODB-соединение к книге екселя, открыть рекордсет для OpenSchema с параметром adSchemaTables. Проход по рекордсету даст все листы книги. Поиск по рекордсету позволит найти заданное имя. Метод удобен для поиска листов из внешнего файла.
4
1018 / 122 / 2
Регистрация: 26.08.2011
Сообщений: 1,177
Записей в блоге: 2
29.06.2012, 02:04  [ТС] 6
да в курсе я))) но такого количества толковых ответов да еще сконцентрированных в одном месте Вы там не найдете))) Поисковая система для профи))) а я, слава Богу, вопросы пока учусь задавать. При этом решаю свои насущные задачки. Вот что гарантированно могу сказать - то не деньги я Вашими ответами зарабатываю)))
А вообще по моему профилю я не считаю, сколько раз мне задают один и тот же вопрос. Я просто отвечаю. А программирование - совсем не мой профиль)))
а если серьезно - пока тут висит один мой вопрос - я занимаюсь другими. На расшифровку поисковика нет совсем времени... И английский плохо знаю опять же... Вообщем благодарствую сказал...

Добавлено через 3 минуты
Кстати, о невеждах, ikki)))

Слепой иногда пройдет там, где зрячий оступится)))
0
1301 / 403 / 22
Регистрация: 21.10.2011
Сообщений: 1,285
29.06.2012, 11:41 7
Не вижу здравого смысла в сообщении #4: это засорение интернета ненужной информацией по данному вопросу и усложнение для непрограммистов, которым просто нужно написать макрос.

Всё это заменяется вот этим:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Sub Procedure_1()
    
    'Создаём переменную, в которую поместим имя листа.
    Dim sName As String
    
    'Создаём переменную, с помощью которой будем обращаться к нужному листу.
    Dim oSheet As Excel.Worksheet
    
    'Помещаем в переменную имя листа.
    sName = "Имя листа"
    
    'On Error Resume Next - используется, чтобы код продолжил
    'выполняться и при возникновниии ошибки.
    On Error Resume Next
    
        'Присваиваем листу имя oSheet.
        'Если листа нет, то будет ошибка.
        Set oSheet = Worksheets(sName)
        
        'Если будет ошибка, то это выражение Err.Number не будет равно нулю.
        If Err.Number <> 0 Then
            MsgBox "Листа не существует.", vbCritical
        End If
    
    'On Error GoTo 0 - отменяет действие On Error Resume Next
    On Error GoTo 0
    
End Sub
Или, чтобы не использовать ошибку, то нужно использовать код в сообщении #3, хотя и там код усложнён тем, что представлен в виде функции, что непрограммисту может показаться очень сложным и непонятным.
3
15147 / 6420 / 1731
Регистрация: 24.09.2011
Сообщений: 9,999
29.06.2012, 13:37 8
Busine2012,
собсно, достаточно такой конструкции:
Visual Basic
1
2
3
4
5
6
On Error Resume Next
If Worksheets(sName) Is Nothing Then
    'действия, если листа нет
Else
    'действия, если лист есть 
End If
Если лист есть, то выражение Worksheets(sName) Is Nothing ложно и управление переходит на Else. Если листа нет, то выражение Worksheets(sName) вызывает ошибку и, в буквальном соответствии с инструкцией On Error Resume Next управление передается следующему оператору, т.е. после Then! Это интересная фича (или баг) в бейсике, разбирали на Планете.
Попробуй
Visual Basic
1
2
3
4
5
6
7
8
Sub bb()
On Error Resume Next
If 1 / 0 = 5 Then
    Debug.Print "вот так!"
Else
    Debug.Print "другое"
End If
End Sub
6
1301 / 403 / 22
Регистрация: 21.10.2011
Сообщений: 1,285
29.06.2012, 13:58 9
Казанский,
буду иметь ввиду.
0
6172 / 937 / 310
Регистрация: 25.02.2011
Сообщений: 1,367
Записей в блоге: 1
29.06.2012, 15:51 10
Цитата Сообщение от Busine2012 Посмотреть сообщение
Не вижу здравого смысла в сообщении #4
А в чем собственно проблема?
Когда искал для себя аналогичное решение данного вопроса, оно достаточно быстро нашлось в поисковике на Планете.

Для меня это хороший пример, как шестью разными вариантами можно определить наличие листа.
При том, что я практически не знаю объектной модели Excel, для меня примеры понятны.

И то что определение сделано через функцию тоже плюс, не нужно в коде каждый раз награмождать конструкции, если делаются регулярные проверки.

PS: для себя взял шестой вариант через Index, как наиболее понятный.
0
0 / 0 / 0
Регистрация: 11.11.2017
Сообщений: 5
11.02.2019, 01:28 11
Дабы не создавать новую тему,

В моей книге есть макросы, имеющие в своем составе формулы со ссылками на другие листы этой книги. При запуске макросов необходимо проверить книгу на соответствие имен листов (не изменил ли кто случайно). если все ОК, то запускаем другой макрос, если нет, то сообщение, какой лист нужно проверить.

воспользовался примером Busine2012, и Казанский, написал код:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
   Sub ttt()
    
    'Создаём переменную, в которую поместим имя листа.
    Dim sName As String
    Dim aName As String
    
    'Создаём переменную, с помощью которой будем обращаться к нужному листу.
    Dim oSheet As Excel.Worksheet
    'Помещаем в переменные имена листов.
    sName = "ДАННЫЕ"
    aName = "РЕЗУЛЬТАТЫ"
    bName = "ИТОГИ
 
    On Error Resume Next
    
        'Присваиваем листу имя oSheet.
Set oSheet = Worksheets(sName)
  
    
        If Worksheets(sName) Is Nothing Then
            MsgBox "Проверь имя листа ДАННЫЕ.", vbCritical
   Else
    
Set oSheet = Worksheets(aName)
    
    If Worksheets(aName) Is Nothing Then
            MsgBox "проверь имя листа РЕЗУЛЬТАТЫ.", vbCritical
    Else
Set oSheet = Worksheets(bName)
    
    If Worksheets(bName) Is Nothing Then
            MsgBox "проверь имя листа ИТОГИ.", vbCritical
               Else
            MsgBox "Работа разрешена.", vbCritical  ' работа макроса
    End If
 End If
 End If
    
End Sub


Макрос работает.

Вопрос: можно ли упростить код для проверки имен листов, если число проверяемых листов на правильность имени будет больше 10 (без ухудшения производительности)?

Было бы конечно лучше, если макрос сам переименовывал неправильные названия без участия пользователя..


Заранее спасибо.

Добавлено через 25 минут
Цитата Сообщение от dmb2 Посмотреть сообщение
Было бы конечно лучше, если макрос сам переименовывал неправильные названия без участия пользователя..
Visual Basic
1
Лист1.Name="Данные"
Добавлено через 5 минут
Но код проверяет (соответственно и переименовывает неправильные листы) по одному за работу всего цикла. Хотелось бы чтобы сразу все листы проверил, и все исправил.

Добавлено через 5 минут
Возникла мысль, хотелось бы узнать мнение о целесообразности,

Может обойтись без проверки листов и сразу все листы переименовать?
0
15147 / 6420 / 1731
Регистрация: 24.09.2011
Сообщений: 9,999
11.02.2019, 15:33 12
dmb2,
Visual Basic
1
2
3
4
5
6
7
8
Sub ttt()
Dim vName, sMsg
  On Error Resume Next
  For Each vName In Array("ДАННЫЕ", "РЕЗУЛЬТАТЫ", "ИТОГИ") 'список можно продолжить
    If Worksheets(vName) Is Nothing Then sMsg = sMsg & vbLf & vName
  Next
  If Len(sMsg) Then MsgBox "Нет листов:" & sMsg, vbCritical
End Sub
А переименовывать - надо знать, какому листу дать какое имя. VBA может работать с листами по CodeName, которое не может изменить пользователь - оно идет первым а панели Project, например Лист1 (ДАННЫЕ) - Лист1 это Codename. Но лучше изменить CodeName в панели Properties на латинские буквы.
0
0 / 0 / 0
Регистрация: 11.11.2017
Сообщений: 5
11.02.2019, 19:29 13
Казанский, спасибо!
Код действительно очень упростился ! (Правда пока не проверял работу кода. нет доступа к компу)..а можно ли к этому коду брбавить изменение имен листов по codename без сообщения, или нужно весь код менять?

Codename у меня уже изменены, правда на кириллице. Никак не могу сообразить что стабильнее и быстрей, проверить на названия листы и при ошибке переименовывать, или сразу присваивать имена листов по Codename каждого листа.
0
0 / 0 / 0
Регистрация: 11.11.2017
Сообщений: 5
21.02.2019, 21:11 14
Нашел ответ на вопрос как лучше сделать, проверять все листы на соответствие имени или сразу менять названия.
Пришел к алгоритму: сначала проверить имена, и если какое-нибудь имя не совпадает,то тогда переименовать все листы заново. В самом распространенном случае, когда все имена листов правильные, переименование не происходит и за счет этого макрос быстрее отрабатывает (примерно на 0,03 сек).Мелочь, а приятно.
Казанский, спасибо за код.

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Sub ForReName()
Dim iName
  On Error Resume Next
  For Each iName In Array("Данные", "Итоги", "Результаты", "ПромежИтог1", "ПромежИтог2", "ПромежИтог3", "ПромежИтог4") 
    If Worksheets(iName) Is Nothing Then ReName
  Next
  MsgBox "Работа макроса.", vbCritical
End Sub
 
Sub ReName()
    Лист21.Name = "Данные"
    Лист22.Name = "Итоги"
    Лист23.Name = "Результаты"
    Лист24.Name = "ПромежИтог1"
    Лист25.Name = "ПромежИтог2"
    Лист26.Name = "ПромежИтог3"
    Лист27.Name = "ПромежИтог4"
End Sub
0
21.02.2019, 21:11
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
21.02.2019, 21:11
Помогаю со студенческими работами здесь

Проверить есть ли в папке файл с заданным именем; если нет такого, то открыть другой
Когда открываю форму она загружает в два picturebox 2 картинки, необходимо проверить есть ли в...

Перенести на новый лист строки с определенным именем, и переименовать лист
Приветствую уважаемых форумчан! У меня есть книга в excel (питание в университетской столовой),...

Можно ли как то определить что компонент с заданным именем присутствует в коллекции
Можно ли как то определить что компонент с заданным именем присутствует в коллекции не перебирая...

Можно ли как то определить что компонент с заданным именем присутствует в коллекции
Можно ли как то определить что компонент с заданным именем присутствует в коллекции не перебирая...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru