Страницы: 1
RSS
Как макросом составить готовый список: КОМБИНАЦИЯ КЛАВИШ – НАЗВАНИЕ МАКРОСА ?
 
У меня есть надстройка. В нём много кодов. Многим из этих кодов я назначил комбинации клавиш.  
Теперь появилась потребность сделать такой готовый список:  
КОМБИНАЦИЯ КЛАВИШ НАЗВАНИЕ МАКРОСА  
Ctrl+Shift+Q Подготовить_месячный_отчёт  
Ctrl+E Подготовить_и_распечатать_ежедневные_данные  
Ctrl+Shift+J Сделать_формат_с_разделителями_и_покрасить_фон_на_желтый  
… …  
… …  
ВОПРОС – Можно ли это сделать макросом? (Чтобы долго и скучно не писать вручную)  
В поиске я нашёл вот эту тему – http://www.planetaexcel.ru/forum.php?thread_id=12742  
В ней знатоки пишут, что наверняка эту задачу не решить макросом, и что скорее всего надо будет делать список вручную.  
НО:  
Шаг 1  
Вот таким макросом:  
Sub ExportAllVBComponents()  
   iTempPath$ = Environ("Temp") & "\" 'укажите свою папку  
   For Each iVBComponent In ThisWorkbook.VBProject.VBComponents  
       Select Case iVBComponent.type  
           Case 1: iType$ = ".txt"  
           Case 3: iType$ = ".frm"  
           Case 2, 100: iType$ = ".cls"  
       End Select  
       iVBComponent.Export _  
       Filename:=iTempPath$ & iVBComponent.Name & iType$  
   Next  
End Sub  
можно все макросы экспортировать в текстовые файлы (.txt) в нужную папку.
 
Шаг 2  
В этой папке выделить все текстовые файлы, нажать F2, написать 1 и нажать Ctrl+Enter  
Все файлы переименуются на 1 (1).txt, 1 (2).txt, 1 (3).txt, 1 (4).txt, 1 (5).txt, … и т.д.  
 
Шаг 3  
Вот таким макросом:  
Sub qwer()  
Dim TextLine  
For s = 1 To 31  
i = 1  
Open "d:\1\й (" & s & ").txt" For Input As #1  
Do While Not EOF(1)  
Line Input #1, TextLine  
ThisWorkbook.Worksheets("лист1l").Cells(i, s).Value = TextLine  
i = i + 1  
Loop  
Close #1  
Next  
End Sub  
можно импортировать тексты этих самих текстовых файлов в книгу ЭКСЕЛЬ на один лист. При этом, текст 1-го макроса запишется на 1-й столбец, текст 2-го на 2-й, и так далее.  
 
НЬЮАНС в том, что в тексте каждого макроса (если он Sub, и если ему была назначена клавиша) есть такая строка:  
Attribute Видимые_ячейки.VB_ProcData.VB_Invoke_Func = "е\n14"  
Или например:  
Attribute Налево.VB_ProcData.VB_Invoke_Func = "Д\n14"  
Это значит, что макросу ”Видимые_ячейки“ была назначена комбоклавиш Ctrl+е ,  
а макросу ”Налево “ была назначена комбоклавиш Ctrl+Shift+д (поэтому буква Д написана там большими буквами)  
 
Теперь наверно нетрудно написать макрос, который исходя из этой связи (то есть, имеется название макроса и чуть ниже есть назначенная к ней комбоклавиш) сможет составить ГОТОВЫЙ СПИСОК, который был описан в самом начале вопроса.  
 
ПОСТСКРИПТУМ.  
Извиняюсь, что изложил вопрос так сложно. Дело в том, что я в VBA ещё не очень силён.  
Просто в других темах было написано, что сделать требуемый список придётся только вручную. А то что я изложил, ЕСЛИ НЕ ОШИБАЮСЬ, указывает на то, что всё таки можно поставленную задачу решить МАКРОСОМ.  
Я наверно шёл долгим путём, когда есть наиболее короткие пути, а именно:  
- может VB_ProcData.VB_Invoke_Func является каким-то свойством макроса, и необязательно заниматься экспорт-импортом  
- может после экспорта на .txt, необязательно импортировать тексты макросов на эксель, (то есть можно нужную информацию просто взять из .txt не ползуясь импортом)  
- может вообще не нужно переименовать текстовые файлы (макрос сам будет перебирать их по одному)  
 
Короче, вроде бы обнаруженный мною :-) НЬЮАНС, состоит в том, что после шага №1, когда мы экспортировали тексты макросов на .txt, на этих текстовых файлах появились такие строки  
Attribute Налево.VB_ProcData.VB_Invoke_Func = "Д\n14"  
которые подсказывают назначенную к макросу комбоклавиш и которые дают СВЯЗЬ между именем макроса и комбоклавишами.  
А это уже даёт мысль о том, что поставленную задачу все таки можно решить МАКРОСОМ.  
 
Если получится осуществить эту идею, прошу ответы писать сюда или на    
3061916@mail.ru  
 
Заранее выражаю благодарность всем, кто этим заинтересуется и потратит время на изучение.  
 
P.S. №2  Если в одном модуле имеется несколько макросов, то они экспортируются на один файл .txt, но каждый Sub имеет свою строчку Attribute...  
 
P.S. №3  Если получится, то вещь конечно очень удобная и нужная  
 
СПАСИБО
 
И впрямь - можно в этот же код дописать чтение полученного текста, выборка строк вида  
Attribute DelDuplicates.VB_ProcData.VB_Invoke_Func = "l\n14"  
и из них фрагментов между "Attribute " и точкой, и "VB_Invoke_Func = " и "\n14".  
Всё это собираем в массив, выгружаем на лист (или сразу на лист, что проще - а скорость тут не нужна).  
Но конечно лучше бы вообще без экспорта обойтись - но я не знаю как...
 
суть того, что вы хотите сказать я могу понять прочитав ваше сообщение ещё раз :-)  
но на то, чтобы осуществить это у меня уйдёт слишком много времени (на чтение разных справок, на метод проб и ошибок, да и в конечном результате наверно получится очень большой код)  
причина - я ешё не силён в VBA  
 
и вообще догадываюсь, что поставленная мною же задача именно для меня СЛОЖНОВАТА  
 
просто в итоге хотелось получить универсальный готовый макрос. :-)  
 
Ну что ж, завтра сяду на осуществление предоженного вами варианта (если сегодня кто-то не даст полностью готовый ответ) :-)
 
Ну вот такое получилось из Вашего примера - первые (ну или как получится, смотря где этот код) две строки брак - они тянутся из текста этого же макроса :(  
Как-то можно шлифануть, но думаю их легко вручную удалить.  
Попробуйте (у меня горячих нет, так что попробовать особо не на чем, одному макросу для теста задал - вытянуло):  
 
 
Sub ExportAllVBComponents()  
   Dim sh As Worksheet, x As Long  
   x = 1  
   Set sh = Workbooks.Add(xlWBATWorksheet).Sheets(1)  
   On Error Resume Next  
   iTempPath$ = Environ("Temp") & "\"    'укажите свою папку  
   For Each iVBComponent In ThisWorkbook.VBProject.VBComponents  
       Select Case iVBComponent.Type  
       Case 1: iType$ = ".txt"  
       Case 3: iType$ = ".frm"  
       Case 2, 100: iType$ = ".cls"  
       End Select  
       iVBComponent.Export _  
               Filename:=iTempPath$ & iVBComponent.Name & iType$  
 
       Dim a, i&, tmp  
       a = Split(CreateObject("Scripting.FileSystemObject").Getfile(iTempPath$ & iVBComponent.Name & iType$).OpenasTextStream(1).readall, vbNewLine)  
       ReDim b(1 To UBound(a), 1 To 2)  
       ii = 0  
       For i = 0 To UBound(a)  
           If InStr(a(i), "VB_ProcData.VB_Invoke_Func =") Then  
               ii = ii + 1  
               b(ii, 1) = a(i - 1)  
               b(ii, 2) = "Ctrl + " & Split(Split(a(i), "VB_Invoke_Func = ")(1), "\")(0)  
           End If  
       Next  
       sh.Cells(x, 1).Resize(ii, 2) = b  
       x = x + ii  
   Next  
End Sub
 
Упс, кавычки лишние тянет:  
 
Ctrl + "l  
 
Нужно их заменой убрать...
 
Вернее, можно позже заменой, а можно вот так эту "сложную" строку изменить (что-то сразу не придумалось):  
 
 
               b(ii, 2) = "Ctrl + " & Split(Split(a(i), "VB_Invoke_Func = " & """")(1), "\")(0)
 
Исправленный вариант, без лишних строк в результатах (обманул :) ) и без кавычек (предыдущие варианты можно убрать):  
 
Sub ExportAllVBComponents()  
   Dim sh As Worksheet, x As Long  
   x = 1  
   Set sh = Workbooks.Add(xlWBATWorksheet).Sheets(1)  
   On Error Resume Next  
   iTempPath$ = Environ("Temp") & "\"    'укажите свою папку  
   For Each iVBComponent In ThisWorkbook.VBProject.VBComponents  
       Select Case iVBComponent.Type  
       Case 1: iType$ = ".txt"  
       Case 3: iType$ = ".frm"  
       Case 2, 100: iType$ = ".cls"  
       End Select  
       iVBComponent.Export _  
               Filename:=iTempPath$ & iVBComponent.Name & iType$  
 
       Dim a, i&, tmp  
       a = Split(CreateObject("Scripting.FileSystemObject").Getfile(iTempPath$ & iVBComponent.Name & iType$).OpenasTextStream(1).readall, vbNewLine)  
       ReDim b(1 To UBound(a), 1 To 2)  
       ii = 0  
       For i = 0 To UBound(a)  
           If InStr(a(i), "VB_ProcData.VB_Invoke_Func =") Then  
               If InStr(a(i), "Then") = 0 Then  
                   ii = ii + 1  
                   b(ii, 1) = a(i - 1)  
                   b(ii, 2) = "Ctrl + " & Split(Split(a(i), "VB_Invoke_Func = " & """")(1), "\")(0)  
               End If  
           End If  
       Next  
       sh.Cells(x, 1).Resize(ii, 2) = b  
       x = x + ii  
   Next  
End Sub
 
спасибо большое попробую сегодня если успею, если нет то завтра и отпишусь обязательно
 
Хм, так теперь и ошибки можно не подавлять - в этом варианте у меня их нет:  
 
Sub ExportAllVBComponents()  
   Dim sh As Worksheet, x As Long  
   x = 1  
   Set sh = Workbooks.Add(xlWBATWorksheet).Sheets(1)  
   iTempPath$ = Environ("Temp") & "\"    'укажите свою папку  
   For Each iVBComponent In ThisWorkbook.VBProject.VBComponents  
       Select Case iVBComponent.Type  
       Case 1: iType$ = ".txt"  
       Case 3: iType$ = ".frm"  
       Case 2, 100: iType$ = ".cls"  
       End Select  
       iVBComponent.Export _  
               Filename:=iTempPath$ & iVBComponent.Name & iType$  
 
       Dim a, i&, tmp  
       a = Split(CreateObject("Scripting.FileSystemObject").Getfile(iTempPath$ & iVBComponent.Name & iType$).OpenasTextStream(1).readall, vbNewLine)  
       ReDim b(1 To UBound(a), 1 To 2)  
       ii = 0  
       For i = 0 To UBound(a)  
           If InStr(a(i), "VB_ProcData.VB_Invoke_Func =") Then  
               If InStr(a(i), "Then") = 0 Then  
                   ii = ii + 1  
                   b(ii, 1) = a(i - 1)  
                   b(ii, 2) = "Ctrl + " & Split(Split(a(i), "VB_Invoke_Func = " & """")(1), "\")(0)  
               End If  
           End If  
       Next  
       If ii <> 0 Then sh.Cells(x, 1).Resize(ii, 2) = b  
       x = x + ii  
   Next  
End Sub
 
ОГРОМНОЕ СПАСИБО !!!  
 
не стал читать результат от начала до конца (у меня там больше 25-ти назначенных к макросам клавиш)  
 
но вроде ТО, ЧТО НАДО  
 
ну там разделить на отдельные столбцы имя макроса и примечание к макросу я могу и сам  
 
если возникнут вопросы завтра отпишусь  
 
где-то здесь если есть ALEX ST то, думаю он тоже бдует вам очень благодарен (если до сегодняшнего дня не нашёл ответов на свои вопросы)  
 
вообще нужно поискать похожие темы и дать ссылку на эту тему  
 
МОДЕРАТОРАМ - ОЧЕНЬ ПРОШУ, если можно в копилку.  
 
HUGO - слов нет выразить благодарность
 
Б А Х Т И Ё Р, основная работа тут Ваша - я лишь технически текст отпарсил :)  
Главное - идея, алгоритм, а это Ваше.
 
{quote}{login= Б А Х Т И Ё Р}{date=21.03.2012 09:45}{thema=HUGO}{post}МОДЕРАТОРАМ - ОЧЕНЬ ПРОШУ, если можно в копилку.{/post}{/quote}В "Копилку" попадает то, что нужно сотням людей. А если туда помещать решения, которые нужны 2-3 посетителям - "Копилка" превратится в ТАКОЙ сборник, что найти там что-то нужное будет проосто невозможно. Кто мешает Вам создать свой файл-копилку?
 
иметь всегда под рукой макрос, который быстро сформирует готовый список: Название макроса - Описание макроса - Назначенная клавиша, нужно ИМХО многим.  
Особенно, кто назначил много клавиш к своим макросам, и кто эти макросы будет распостранять среди других пользователей.  
Но - решать Вам.  
 
HUGO  
протестировал, всё нормально. Спасибо ещё раз
 
Не всё нормально - мне стыдно, но т.к. я горячими клавишами не пользуюсь, то я не учёл, что горячие клавиши могут быть не только Ctr+буква, но и Ctrl+Shift+буква.  
Нужно в код добавить анализ этих сочетаний, а не тупо делать  
b(ii, 2) = "Ctrl + " & Split(...  
Т.к. "кошки" для тренировки нет, а делать неохота - кода тоже нет...
 
Б А Х Т И Ё Р навёл меня на эту интересную тему.  
Сейчас на работе затишье. Разбираюсь в работе Игоря.  
Нашёл ещё одну гадкую не учтённую фенечку: в отличие от Sub, текст экспортированной Function в любом случае сопровождается стрингом-признаком назначения хоткеев "VB_ProcData.VB_Invoke_Func = ", но только там написано VB_ProcData.VB_Invoke_Func = " \n14" , т.е. хоткей вроде бы есть, но он не назначается.  
Надо убрать и доработать для хоткеев с Ctrl+Shift  
Тут бы, конечно, проще всего было бы RegExp использовать, но я их очень слабо знаю :(  
Ну, а пока покручу по-простому Мидами и Инстрингами  
Через часок, надеюсь, что-нибудь выложу.
С уважением, Алексей (ИМХО: Excel-2003 - THE BEST!!!)
 
Ну, вот примерно так (оптимизировать лень, но, вроде, все нюансы учтены)  
Sub ReadHotKeyes() 'считать и вывести на новый лист все программно назначенные горячие клавиши  
  Dim iTempPath$, iType$  
  Dim iVBComponent As VBComponent  
  Dim WB As Workbook, SH As Worksheet  
     
  Dim x&: x = 1  
  Set SH = ThisWorkbook.Sheets.Add(After:=Sheets(Sheets.Count))  
  iTempPath$ = Environ("Temp") & "\"   ' или укажите свою папку  
  'iTempPath$ = "C:\Temp\"  
  For Each WB In Application.Workbooks  
  If WB.Name <> ThisWorkbook.Name Then  
     For Each iVBComponent In WB.VBProject.VBComponents  
        Select Case iVBComponent.Type  
           Case 1: iType$ = ".txt"  
           Case 3: iType$ = ".frm"  
           Case 2, 100: iType$ = ".cls"  
        End Select  
        iVBComponent.Export Filename:=iTempPath$ & iVBComponent.Name & iType$  
 
        Dim A, B, i&, ii&, s$  
        A = Split(CreateObject("Scripting.FileSystemObject").Getfile(iTempPath$ & iVBComponent.Name & iType$).OpenasTextStream(1).ReadAll, vbNewLine)  
        ReDim B(1 To UBound(A), 1 To 5)  
        ii = 0  
        For i = 0 To UBound(A)  
           If InStr(A(i), "VB_ProcData.VB_Invoke_Func =") Then  
              If InStr(A(i), "VB_ProcData.VB_Invoke_Func = "" \n14""") = 0 Then  
                 ii = ii + 1  
                 B(ii, 1) = WB.Name  
                 B(ii, 2) = iVBComponent.Name  
                 B(ii, 3) = Split(Mid(A(i), Len("Attribute ") + 1), ".")(0)   ' считать имя макроса после "Attribute "  
                 B(ii, 4) = Replace(Split(A(i - 1), """")(1), "\r\n", Chr(10))  ' из предыдущей строки считать Description макроса  
                 B(ii, 5) = "Ctrl + " & Split(Split(A(i), "VB_Invoke_Func = """)(1), "\")(0)  
                 s = Split(Split(A(i), "VB_Invoke_Func = """)(1), "\")(0)  
                 B(ii, 5) = "Ctrl + " & IIf(LCase(s) = s, "", "Shift + ") & s  
              End If  
           End If  
        Next  
        If ii <> 0 Then SH.Cells(x, 1).Resize(UBound(B, 1), UBound(B, 2)) = B  
        x = x + ii  
     Next iVBComponent  
     End If  
  Next WB  
End Sub  
 
 
У меня всего пара хоткеев назначена и та только через Ctrl+буква, но отработка Ctrl+Shift+буква тоже должна работать.
С уважением, Алексей (ИМХО: Excel-2003 - THE BEST!!!)
 
Alex_ST - спасибо, попробую и чуть позже отпишусь
 
Останавливается на строчке:  
Dim iVBComponent As VBComponent  
и выдаёт ошибку (скрин прилагаю)
 
А как на счёт того, чтобы заглянуть в Tools-References и увидеть там, что не подключена библиотека Microsoft Visual Basic for Applications Extensibility 5.3 ? :)  
Вообще-то, это не обязательно, но удобнее работать если её подключить.  
 
А я пока обедал (да ещё и "Планета" висела) малость причесал процедурку: прошерстил и перевёл на Dictionary - из него удобнее выводить на лист.
С уважением, Алексей (ИМХО: Excel-2003 - THE BEST!!!)
 
Да, ещё доработка - уборка за собой в темпах, а то раньше там мусора после каждого запуска накапливалась гора.
С уважением, Алексей (ИМХО: Excel-2003 - THE BEST!!!)
 
Останавливается на строке:  
sDescr = Replace(Split(Arr(i - 1), """")(1), "\r\n", vbLf)   ' предыдущую строку разбить в массив "по кавычкам" и во втором элементе (1) заменить \r\n на перевод строки в Description макроса  
 
и даёт ошибку (скрин прилагаю)  
 
-28820-
 
Это произошло скорее всего из-за того, что при задании хоткеев не было задано описание (Description) макроса  
поставьте перед началом всех циклов OnError Resume Next и программа будет игнорировать ошибки.
С уважением, Алексей (ИМХО: Excel-2003 - THE BEST!!!)
 
попробую и отпишусь
 
{quote}{login=Alex_ST}{date=15.06.2012 09:45}{thema=}{post}...поставьте перед началом всех циклов OnError Resume Next и программа будет игнорировать ошибки...{/post}{/quote} спасибо, теперь всё работает нормально
 
Как макросы писать разобрался, а вот переназначить горячие кнопки могу только созданием нового и копированием. Есть более простой способ?
 
Есть: Alt+F8, выбираем нужный макрос и жмём кнопкочку "Параметры".
 
Ненене!  
Андрей, вот это работает:  
 
Sub SetSubShortcut() ' назначение сочетания клавиш для макроса  
   Application.MacroOptions macro:="Sumari", _  
   HasShortcutKey:=True, ShortcutKey:="q"  
   ' строчная для Ctrl+, заглавная для Ctrl+Shift+  
End Sub  
 
Запустить из редактора VBA (F5) и сразу после – Ctrl+S.  
Я все макросы вытащил в .xla, теперь их по Alt+F8 не видно, к свойствам иначе не докопаться.  
Ну есть ещё один способ, с ескпортом/импортом .bas, но это извратъ.
Страницы: 1
Читают тему
Наверх