Excel это не сложно
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
23.04.2024, 18:06:03

Войти
Интересные и полезные статьи по работе с Excel и VBA можно найти в разделе ХИТРОСТИ
33 242 Сообщений в 5 457 Тем от 6 758 Пользователей
Последний пользователь: Сергей2662
*
Перейти на сайт Хитрости Надстройка MulTEx Обучающие тренинги Наша группа ВКонтакте
Правила форума Начало Помощь Поиск Календарь Войти Регистрация Выйти
+  Excel это не сложно
|-+  Основные форумы
| |-+  Полезные решения
| | |-+  Показать только лист, выбранный в оглавлении, остальные скрыть.
Страниц: 1 [2]  Все   Вниз
Печать
Автор Тема: Показать только лист, выбранный в оглавлении, остальные скрыть.  (Прочитано 46056 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Alex_ST
Постоялец
***

Репутация: +13/-0
Офлайн Офлайн

Сообщений: 156


Просмотр профиля
« Ответ #15 : 08.06.2011, 16:17:13 »

В общем, как ни бился, даже полностью Офис с другого дистрибутива переставил, а Ёксель как помирал на "исправленном" примере, так и помирает.

Тогда взял и сделал тупо - взял свой пример от 07.06.2011, 15:28:35 и сделал два раза подряд вызов процедуры:
Код:
Sub duplet()
   СОЗДАТЬ_ОГЛАВЛЕНИЕ :СОЗДАТЬ_ОГЛАВЛЕНИЕ
End Sub
ПОМЕР ЁКСЕЛЬ ОПЯТЬ! А ведь при ручном повторном вызове всё работало (см. мой пост 07.06.2011, 15:15 )
Тупо ввёл задержку в 1 секунду:
Код:
Sub duplet()
   СОЗДАТЬ_ОГЛАВЛЕНИЕ
   Application.OnTime Now + TimeValue("00:00:01"), "СОЗДАТЬ_ОГЛАВЛЕНИЕ"
End Sub
ЗАРАБОТАЛО!
Записан

С уважением, Алексей
Alex_ST
Постоялец
***

Репутация: +13/-0
Офлайн Офлайн

Сообщений: 156


Просмотр профиля
« Ответ #16 : 08.06.2011, 20:15:56 »

Вот посмотрите, пожалуйста последний исправленный вариант: я просто добавил перед записью кода на созданный лист задержку в 1 секунду.
Дома всё теперь работает. Завтра попробую на работе. А если заработает, то перенесу модуль в Персонал (в надстройках я плаваю, к сожалению).
Записан

С уважением, Алексей
Дмитрий Щербаков(The_Prist)
Администратор
Ветеран
*****

Репутация: +485/-0
Офлайн Офлайн

Сообщений: 5 831



Просмотр профиля WWW
« Ответ #17 : 08.06.2011, 20:38:54 »

Алексей, а если попробовать убрать задержку, но добавить:
   
Код:
Dim lCntDeclrLines As Long
    sCodeName = ActiveSheet.CodeName
    sCode = sProc1 & vbLf & vbLf & sProc2
    Set oSh = ActiveWorkbook.VBProject.VBComponents(sCodeName)
    lCntDeclrLines = oSh.CodeModule.CountOfDeclarationLines + 1
    oSh.CodeModule.InsertLines lCntDeclrLines, sCode
Записан

Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
Пункты приёма Спасибов:    -41001332272872  -R298726502453
Alex_ST
Постоялец
***

Репутация: +13/-0
Офлайн Офлайн

Сообщений: 156


Просмотр профиля
« Ответ #18 : 08.06.2011, 21:07:05 »

Дмитрий, к сожалению дома на 100% проверить не могу - здесь и так почти всегда работает.
Но, честно говоря, вряд ли глюк идёт из-за того, что параметр CountOfDeclarationLines мы указываем прямо в инструкции добавления линий кода процедур. Ведь в этих линиях деклараций нет, поэтому и CountOfDeclarationLines из-за их добавления "на лету" не меняется.
Но, как говорил Лаврентий Павлович: "Попытка - не пытка". Дома сейчас сработало. А на работе - будем завтра посмотреть.
Записан

С уважением, Алексей
Alex_ST
Постоялец
***

Репутация: +13/-0
Офлайн Офлайн

Сообщений: 156


Просмотр профиля
« Ответ #19 : 08.06.2011, 21:16:00 »

Нет, не работает. Но не совсем:
- после открытия файла "от кнопки" создаётся лист с гиперссылками, но код на него прописывается с вероятностью ~50%
- после открытия файла и запуска макроса из VBE лист с гиперссылками тоже создаётся, но код на него прописывается практически всегда
Записан

С уважением, Алексей
Дмитрий Щербаков(The_Prist)
Администратор
Ветеран
*****

Репутация: +485/-0
Офлайн Офлайн

Сообщений: 5 831



Просмотр профиля WWW
« Ответ #20 : 08.06.2011, 21:20:24 »

вряд ли глюк идёт из-за того, что параметр CountOfDeclarationLines мы указываем прямо в инструкции добавления линий кода процедур. Ведь в этих линиях деклараций нет, поэтому и CountOfDeclarationLines из-за их добавления "на лету" не меняется.
Дело вовсе не в этом, а в том, что обращение к компонентам VBA весьма тонкая штука и почти всегда требуется каждое отдельное свойство использовать через переменную. Если пытаться экономить, то можно как раз напороться именно на вылет из Excel
Записан

Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
Пункты приёма Спасибов:    -41001332272872  -R298726502453
Alex_ST
Постоялец
***

Репутация: +13/-0
Офлайн Офлайн

Сообщений: 156


Просмотр профиля
« Ответ #21 : 08.06.2011, 21:36:30 »

Надо будет на CitForum поковыряться в Меню Visual Basic
там очень много всего разного, но есть и про команды для работы с VBProject. В том числе и про CountOfDeclarationLines
Но к сожалению это не учебник, а справочник.
Нет ли у вас ссылки на русскоязычный учебник по работе с VBProject? (или стандартный ответ - Уокенбах?)
Записан

С уважением, Алексей
Alex_ST
Постоялец
***

Репутация: +13/-0
Офлайн Офлайн

Сообщений: 156


Просмотр профиля
« Ответ #22 : 09.06.2011, 09:13:15 »

На работе Ёксель при запуске макроса гибнет...
При этом именно при выполнении oSh.CodeModule.InsertLines
Пытался сделать тупо: сначала удалить весь код с листа:
Код:
   Set oSh = ActiveWorkbook.VBProject.VBComponents(sCodeName)
   Debug.Print "CountOfLines = " & oSh.CodeModule.CountOfLines
   lCountOfLines = oSh.CodeModule.CountOfLines
   oSh.CodeModule.DeleteLines 1, lCountOfLines
   Debug.Print "CountOfLines = " & oSh.CodeModule.CountOfLines
Это сработало. А когда на следующей строке (проходил в построчном режиме) встретилось
Код:
   oSh.CodeModule.InsertLines 1, sCode
тут он и помер Злой

Порылся в и-нете. Оказывается, CodeModule.InsertLines у многих глючит - не всегда прописывает код.
На одном буржуйском форуме предлагают вставить перед этим в код после создания страницы DoEvents. Попробовал. Не помогло.
Вспомнил, что надо ещё подключить ссылку на Microsoft Visual Basic for Applications Extensibility 5.3. Подключил (после переустановки Офиса старая ссылка слетела). Не помогло.
Записан

С уважением, Алексей
Дмитрий Щербаков(The_Prist)
Администратор
Ветеран
*****

Репутация: +485/-0
Офлайн Офлайн

Сообщений: 5 831



Просмотр профиля WWW
« Ответ #23 : 09.06.2011, 09:20:55 »

Алексей, давай пошаманим. Как я и говорил - надо теперь разбить каждый элемент проекта на переменые.
Код:
Dim objVBPrj as object, oSh as object
Dim lCntDeclrLines As Long
sCodeName = ActiveSheet.CodeName
sCode = sProc1 & vbLf & vbLf & sProc2
Set objVBPrj = ActiveWorkbook.VBProject
Set oSh = objVBPrj.VBComponents(sCodeName)
lCntDeclrLines = oSh.CodeModule.CountOfDeclarationLines + 1
oSh.CodeModule.InsertLines lCntDeclrLines, sCode
Записан

Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
Пункты приёма Спасибов:    -41001332272872  -R298726502453
Alex_ST
Постоялец
***

Репутация: +13/-0
Офлайн Офлайн

Сообщений: 156


Просмотр профиля
« Ответ #24 : 09.06.2011, 11:49:17 »

Пошёл ещё дальше - начал определять переменные прямо "от печки" (подсмотрел на Programming The VBA Editor ):  
Код:
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
Всё равно вылетает, зараза, на строке с InsertLines
« Последнее редактирование: 09.06.2011, 11:51:21 от Alex_ST » Записан

С уважением, Алексей
Alex_ST
Постоялец
***

Репутация: +13/-0
Офлайн Офлайн

Сообщений: 156


Просмотр профиля
« Ответ #25 : 09.06.2011, 14:40:22 »

От безысходности попытался с нуля постепенно, проверяя каждый шаг, создать файл.
Выяснил, что "собака-то порылась" вовсе не в InsertLines , а в попытке обращения к созданному листу уже после прописывания на него кода обработки событий.
Посмотрите, пожалуйста.
В приложенном примере после нажатия на кнопочку СОЗДАТЬ_ОГЛАВЛЕНИЕ лист оглавления и код на нём создаются. А следующие шаги - перемещение этого листа на первое место и операции с его ячейками (стирание диапазона, прописка в ячейки гиперссылок) заремарены.
Если ремарку с чего-нибудь внутри блока With oWbk.Sheets(shName) … End With снять (ну, хотя бы с .Move Before:=oWbk.Sheets(1) ) , то при выполнении макроса Ёксель вылетит.
Записан

С уважением, Алексей
Alex_ST
Постоялец
***

Репутация: +13/-0
Офлайн Офлайн

Сообщений: 156


Просмотр профиля
« Ответ #26 : 10.06.2011, 14:56:41 »

Так и не победил "умирания" Ёкселя на работе, но сделал так, что у меня тоже функционирует, но только после второго прохода макроса.
Самое обидное, что у всех вокруг мой макрос работает нормально, а у меня нет...

Ссылки на сильно скрытые листы теперь не создаются (сделано специально, но не трудно и убрать). Вместо таких листов - пропуск в оглавлении
В данном примере сильно спрятан Лист3

Если у кого-то Excel всё-таки будет "умирать" при запуске макроса (это иногда бывает на некоторых релизах Офиса), то надо снять ремарку с указанной строки кода. Тогда полностью функционирующее оглавление будет создаваться за два прохода макроса.

Записан

С уважением, Алексей
solmir
Пользователь
**

Репутация: +2/-0
Офлайн Офлайн

Сообщений: 68


Просмотр профиля E-mail
« Ответ #27 : 16.06.2011, 20:23:08 »

На самом деле, на 2 разных машинах абсолютно разные настройки, сам недавно убедился... The_Prist можно ли тебе код высыть?  Я думал это платно... Плачущий
Записан
Страниц: 1 [2]  Все   Вверх
Печать
Перейти в:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2006-2011, Simple Machines Valid XHTML 1.0! Valid CSS!
Яндекс.Метрика Рейтинг@Mail.ru