Тут я взялся дополировывать макрос для создания в активной книге листа "<<ОГЛАВЛЕНИЕ>>" с гиперссылками на все её листы. При выборе гиперссылки на лист из оглавления выбранный лист и "<<ОГЛАВЛЕНИЕ>>" остаются видимыми, а все другие листы скрываются. При активизации листа "<<ОГЛАВЛЕНИЕ>>" все остальные листы книги скрываются. На листе "<<ОГЛАВЛЕНИЕ>>" добавлен пункт-гиперссылка "Все листы", позволяющий при его активизации сделать видимыми все листы книги.
При необходимости название создаваемого листа "<<ОГЛАВЛЕНИЕ>>" и адрес ячейки начала оглавления на нём вводятся в первых строках кода процедуры СОЗДАТЬ_ОГЛАВЛЕНИЕ
Код может функционировать самостоятельно как надстройка - создавать листы "<<ОГЛАВЛЕНИЕ>>" в любой активной книге.
Вроде, всё работает как надо. Только почему-то приходится два раза запускать макрос СОЗДАТЬ_ОГЛАВЛЕНИЕ для создания оглавления в новой книге: - за первый запуск создаётся лист "<<ОГЛАВЛЕНИЕ>>" и код обработки событий - за второй - прописываются гиперссылки.
НИЧЕГО НЕ ПОНИМАЮ! Пол-дня бьюсь...
Тут я взялся дополировывать макрос для создания в активной книге листа "<<ОГЛАВЛЕНИЕ>>" с гиперссылками на все её листы. При выборе гиперссылки на лист из оглавления выбранный лист и "<<ОГЛАВЛЕНИЕ>>" остаются видимыми, а все другие листы скрываются. При активизации листа "<<ОГЛАВЛЕНИЕ>>" все остальные листы книги скрываются. На листе "<<ОГЛАВЛЕНИЕ>>" добавлен пункт-гиперссылка "Все листы", позволяющий при его активизации сделать видимыми все листы книги.
При необходимости название создаваемого листа "<<ОГЛАВЛЕНИЕ>>" и адрес ячейки начала оглавления на нём вводятся в первых строках кода процедуры СОЗДАТЬ_ОГЛАВЛЕНИЕ
Код может функционировать самостоятельно как надстройка - создавать листы "<<ОГЛАВЛЕНИЕ>>" в любой активной книге.
Вроде, всё работает как надо. Только почему-то приходится два раза запускать макрос СОЗДАТЬ_ОГЛАВЛЕНИЕ для создания оглавления в новой книге: - за первый запуск создаётся лист "<<ОГЛАВЛЕНИЕ>>" и код обработки событий - за второй - прописываются гиперссылки.
Дмитрий (The_Prist) подсказал в чём дело - рановато использовал [vba]
Код
With ActiveWorkbook.Worksheets(shContent)
[/vba], а когда листа не было в книге, то и ячейки не было куда писАть... Переделал код. Не могу проверить - комп заглючил - постоянно Ёксель падает. Перегружался - не помогло... Может кто-нибудь проверить, создаётся ли лист <<ОГЛАВЛЕНИЕ>> и работают ли на нём гиперссылки?
Дмитрий (The_Prist) подсказал в чём дело - рановато использовал [vba]
Код
With ActiveWorkbook.Worksheets(shContent)
[/vba], а когда листа не было в книге, то и ячейки не было куда писАть... Переделал код. Не могу проверить - комп заглючил - постоянно Ёксель падает. Перегружался - не помогло... Может кто-нибудь проверить, создаётся ли лист <<ОГЛАВЛЕНИЕ>> и работают ли на нём гиперссылки?Alex_ST
RAN, лист создаётся с кодами обработки после первого же после открытия файла запуске макроса? Попробуйте в прилагаемом примере (там подработана обработка ошибок по указанию The_Prist) вызвать макрос создаения оглавления. У большинства тестирующих лист с гиперссылками создаётся, но коды обработки событий на него почему-то не прописываются. А если макрос запустить ещё раз, то коды прописыватся и всё начинает работать как надо. Самое интересное, что если лист с оглавлением удалить, книгу сохранить, но не закрывать, а потом вызвать макрос, то лист создастся вместе с кодами с первого запуска макроса... Бред какой-то. Такое впечатление, что состав коллекции Worksheets сразу после Add не обновляется, а при повторном запуске лист уже есть и на него записывается код...
RAN, лист создаётся с кодами обработки после первого же после открытия файла запуске макроса? Попробуйте в прилагаемом примере (там подработана обработка ошибок по указанию The_Prist) вызвать макрос создаения оглавления. У большинства тестирующих лист с гиперссылками создаётся, но коды обработки событий на него почему-то не прописываются. А если макрос запустить ещё раз, то коды прописыватся и всё начинает работать как надо. Самое интересное, что если лист с оглавлением удалить, книгу сохранить, но не закрывать, а потом вызвать макрос, то лист создастся вместе с кодами с первого запуска макроса... Бред какой-то. Такое впечатление, что состав коллекции Worksheets сразу после Add не обновляется, а при повторном запуске лист уже есть и на него записывается код...Alex_ST
Private Sub Worksheet_Activate() Dim iSht As Worksheet On Error Resume Next For Each iSht In ThisWorkbook.Worksheets ' скрываем все листы кроме ActiveSheet iSht.Visible = iSht.Name = ActiveSheet.Name Next End Sub
Private Sub Worksheet_FollowHyperlink(ByVal Target As Hyperlink) Dim sHypAddr$, sParent$, iSht As Worksheet On Error Resume Next Application.ScreenUpdating = False: Application.EnableEvents = False sHypAddr = Target.SubAddress sParent = Replace$(Mid$(sHypAddr, 1, InStr(sHypAddr, "!") - 1), "'", "") For Each iSht In ThisWorkbook.Worksheets iSht.Visible = IIf(Target.TextToDisplay = "Все листы", True, (iSht.Name = sParent) Or (iSht.Name = Target.Range.Parent.Name)) Next Target.Follow Application.EnableEvents = True: Application.ScreenUpdating = True End Sub
[/vba]
Это должно было получиться?
Код листа "Оглавление"
[vba]
Код
Private Sub Worksheet_Activate() Dim iSht As Worksheet On Error Resume Next For Each iSht In ThisWorkbook.Worksheets ' скрываем все листы кроме ActiveSheet iSht.Visible = iSht.Name = ActiveSheet.Name Next End Sub
Private Sub Worksheet_FollowHyperlink(ByVal Target As Hyperlink) Dim sHypAddr$, sParent$, iSht As Worksheet On Error Resume Next Application.ScreenUpdating = False: Application.EnableEvents = False sHypAddr = Target.SubAddress sParent = Replace$(Mid$(sHypAddr, 1, InStr(sHypAddr, "!") - 1), "'", "") For Each iSht In ThisWorkbook.Worksheets iSht.Visible = IIf(Target.TextToDisplay = "Все листы", True, (iSht.Name = sParent) Or (iSht.Name = Target.Range.Parent.Name)) Next Target.Follow Application.EnableEvents = True: Application.ScreenUpdating = True End Sub
Придётся, я так подозреваю, Ёкселю лоботомию делать... У меня срабатывает не при каждом запуске файла. Попробую этот модуль в Персонал засунуть и оттуда кнопочкой вызывать.
Придётся, я так подозреваю, Ёкселю лоботомию делать... У меня срабатывает не при каждом запуске файла. Попробую этот модуль в Персонал засунуть и оттуда кнопочкой вызывать.Alex_ST
Снёс и переустановил на работе MSOffice-2003SP3 с другого дистрибутива - не помогло. Ёксель при попытке записи кода на создаваемый лист умирает и просит послать "прощальное письмо" его "родителям" Тупо внёс задержку в 1 секунду между созданием нового листа и записью на него кода. Дома всё теперь работает. Завтра попробую на работе. А если заработает, то перенесу модуль в Персонал (в надстройках я плаваю, к сожалению).
Снёс и переустановил на работе MSOffice-2003SP3 с другого дистрибутива - не помогло. Ёксель при попытке записи кода на создаваемый лист умирает и просит послать "прощальное письмо" его "родителям" Тупо внёс задержку в 1 секунду между созданием нового листа и записью на него кода. Дома всё теперь работает. Завтра попробую на работе. А если заработает, то перенесу модуль в Персонал (в надстройках я плаваю, к сожалению).Alex_ST
Алекс, попробуйте блок If записать обычным способом: [vba]
Код
If iSht Is Nothing Then ActiveWorkbook.Worksheets.Add ActiveSheet.Name = shContent Call Create_shContent(shContent) End If
[/vba] Сам натыкался - в однострочном If последние операторы, бывает, не срабатывают. Т.е. до Call Create_shContent(shContent) просто не доходит. Ну, вдруг... Хотя у меня работает и так, и так.
Алекс, попробуйте блок If записать обычным способом: [vba]
Код
If iSht Is Nothing Then ActiveWorkbook.Worksheets.Add ActiveSheet.Name = shContent Call Create_shContent(shContent) End If
[/vba] Сам натыкался - в однострочном If последние операторы, бывает, не срабатывают. Т.е. до Call Create_shContent(shContent) просто не доходит. Ну, вдруг... Хотя у меня работает и так, и так.nilem
Яндекс.Деньги 4100159601573
Сообщение отредактировал nilem - Среда, 08.06.2011, 23:27
На работе Ёксель при запуске макроса всё равно гибнет... При этом именно при выполнении oSh.CodeModule.InsertLines Пытался сделать тупо: сначала удалить весь код с листа: [vba]
[/vba] Это сработало. А когда на следующей строке (проходил в построчном режиме) встретилось [vba]
Код
oSh.CodeModule.InsertLines 1, sCode
[/vba] тут он и помер >:(
Порылся в и-нете. Оказывается, CodeModule.InsertLines у многих глючит - не всегда прописывает код. На одном буржуйском форуме предлагают вставить перед этим в код после создания страницы DoEvents. Попробовал. Не помогло. Вспомнил, что надо ещё подключить ссылку на Microsoft Visual Basic for Applications Extensibility 5.3. Подключил (после переустановки Офиса старая ссылка слетела). Не помогло.
Пошёл ещё дальше - начал определять переменные прямо "от печки" (подсмотрел на Programming The VBA Editor ): [vba]
Код
Dim VBProj As VBIDE.VBProject Dim VBComp As VBIDE.VBComponent Dim CodeMod As VBIDE.CodeModule Dim sCodeName$, lFirstProcLine& sCodeName = ActiveSheet.CodeName Set VBProj = Application.ActiveWorkbook.VBProject Set VBComp = VBProj.VBComponents(sCodeName) Set CodeMod = VBComp.CodeModule lFirstProcLine = CodeMod.CountOfDeclarationLines + 1 CodeMod.InsertLines lFirstProcLine, sCode
[/vba] Всё равно вылетает, зараза, на строке с InsertLines Решил, что накопились глюки в VBE (бывает и такое). Скопировал код в "Блокнот". Закрыл Ёксель. Открыл. Создал новую книгу. В ней - модуль. В него - текст кода из "Блокнота". ВЫЛЕТАЕТ! Вот совсем новый файл.
На работе Ёксель при запуске макроса всё равно гибнет... При этом именно при выполнении oSh.CodeModule.InsertLines Пытался сделать тупо: сначала удалить весь код с листа: [vba]
[/vba] Это сработало. А когда на следующей строке (проходил в построчном режиме) встретилось [vba]
Код
oSh.CodeModule.InsertLines 1, sCode
[/vba] тут он и помер >:(
Порылся в и-нете. Оказывается, CodeModule.InsertLines у многих глючит - не всегда прописывает код. На одном буржуйском форуме предлагают вставить перед этим в код после создания страницы DoEvents. Попробовал. Не помогло. Вспомнил, что надо ещё подключить ссылку на Microsoft Visual Basic for Applications Extensibility 5.3. Подключил (после переустановки Офиса старая ссылка слетела). Не помогло.
Пошёл ещё дальше - начал определять переменные прямо "от печки" (подсмотрел на Programming The VBA Editor ): [vba]
Код
Dim VBProj As VBIDE.VBProject Dim VBComp As VBIDE.VBComponent Dim CodeMod As VBIDE.CodeModule Dim sCodeName$, lFirstProcLine& sCodeName = ActiveSheet.CodeName Set VBProj = Application.ActiveWorkbook.VBProject Set VBComp = VBProj.VBComponents(sCodeName) Set CodeMod = VBComp.CodeModule lFirstProcLine = CodeMod.CountOfDeclarationLines + 1 CodeMod.InsertLines lFirstProcLine, sCode
[/vba] Всё равно вылетает, зараза, на строке с InsertLines Решил, что накопились глюки в VBE (бывает и такое). Скопировал код в "Блокнот". Закрыл Ёксель. Открыл. Создал новую книгу. В ней - модуль. В него - текст кода из "Блокнота". ВЫЛЕТАЕТ! Вот совсем новый файл.Alex_ST
От безысходности попытался с нуля постепенно, проверяя каждый шаг, создать файл. Выяснил, что "собака-то порылась" вовсе не в InsertLines , а в попытке обращения к созданному листу уже после прописывания на него кода обработки событий. Посмотрите, пожалуйста. В приложенном примере после нажатия на кнопочку СОЗДАТЬ_ОГЛАВЛЕНИЕ лист оглавления и код на нём создаются. А следующие шаги - перемещение этого листа на первое место и операции с его ячейками (стирание диапазона, прописка в ячейки гиперссылок) заремарены. Если ремарку с чего-нибудь внутри блока With oWbk.Sheets(shName) … End With снять (ну, хотя бы с .Move Before:=oWbk.Sheets(1) ) , то при выполнении макроса Ёксель вылетит.
От безысходности попытался с нуля постепенно, проверяя каждый шаг, создать файл. Выяснил, что "собака-то порылась" вовсе не в InsertLines , а в попытке обращения к созданному листу уже после прописывания на него кода обработки событий. Посмотрите, пожалуйста. В приложенном примере после нажатия на кнопочку СОЗДАТЬ_ОГЛАВЛЕНИЕ лист оглавления и код на нём создаются. А следующие шаги - перемещение этого листа на первое место и операции с его ячейками (стирание диапазона, прописка в ячейки гиперссылок) заремарены. Если ремарку с чего-нибудь внутри блока With oWbk.Sheets(shName) … End With снять (ну, хотя бы с .Move Before:=oWbk.Sheets(1) ) , то при выполнении макроса Ёксель вылетит.Alex_ST
Так и не победил "умирания" Ёкселя на работе, но сделал так, что у меня тоже функционирует, но только после второго прохода макроса. Самое обидное, что у всех вокруг мой макрос работает нормально, а у меня нет...
Ссылки на сильно скрытые листы теперь не создаются (сделано специально, но не трудно и убрать). Вместо таких листов - пропуск в оглавлении В данном примере сильно спрятан Лист3
Если у кого-то Excel всё-таки будет "умирать" при запуске макроса (это иногда бывает на некоторых релизах Офиса), то надо снять ремарку с указанной строки кода. Тогда полностью функционирующее оглавление будет создаваться за два прохода макроса.
Так и не победил "умирания" Ёкселя на работе, но сделал так, что у меня тоже функционирует, но только после второго прохода макроса. Самое обидное, что у всех вокруг мой макрос работает нормально, а у меня нет...
Ссылки на сильно скрытые листы теперь не создаются (сделано специально, но не трудно и убрать). Вместо таких листов - пропуск в оглавлении В данном примере сильно спрятан Лист3
Если у кого-то Excel всё-таки будет "умирать" при запуске макроса (это иногда бывает на некоторых релизах Офиса), то надо снять ремарку с указанной строки кода. Тогда полностью функционирующее оглавление будет создаваться за два прохода макроса.Alex_ST
Гы-Гы А вот этот файл уже не работает! Перестарался! Т.е. лист с гиперссылками и кодом создается, лист1 прячется, и прЮвет! - переход по гиперссылкам не работает.
Гы-Гы А вот этот файл уже не работает! Перестарался! Т.е. лист с гиперссылками и кодом создается, лист1 прячется, и прЮвет! - переход по гиперссылкам не работает.RAN