Страницы: 1 2 След.
RSS
"Метод 'ProcCountLines' объекта '_CodeModule' не выполнен"
 
Для доводки идеи Hugo о создании специальной книги с UDF и формы в ней с вызовом "любимых" Function и Sub ( http://www.planetaexcel.ru/forum.php?thread_id=18463&thread_id=18463&page_forum=lastpage&allnum_forum=84#post150776 ) пишу на досуге макрос, выводящий имена и размещение процедур в открытых книгах:  
 
Sub Find_Sub()  
Debug.Print "============   Sub's   ============="  
  Call FindProc("Sub")  
End Sub  
Sub Find_Func()  
Debug.Print "============   Function's   ============="  
  Call FindProc("Function")  
End Sub  
 
Sub FindProc(Proc$)  
  Dim iWbk As Workbook, iVBComp As Object, i&  
  On Error GoTo ErrExit  
  For Each iWbk In Workbooks   ' для каждой из открытых книг  
     For Each iVBComp In iWbk.VBProject.VBComponents  ' для каждого модуля проекта  
        i = 1   'начиная с первой строки кода  
        With iVBComp.CodeModule  
           Do Until Not .Find(Proc & " ", i, 1, .CountOfLines, 1, , True)   ' ищем в тексте модуля требуемый тип процедуры ("Sub " или "Function ")  
Debug.Print iWbk.Name & vbTab & iVBComp.Name & vbTab & .ProcOfLine(i, 0)  
              i = i + .ProcCountLines(.ProcOfLine(i, 0), 0)  ' переходим к следующей после конца процедуры строке кода  
           Loop  
        End With  
     Next iVBComp  
  Next iWbk  
ErrExit:  
  If Err Then Debug.Print Err.Description  
End Sub  
Чушь какая-то получается!  
Function ищет безошибочно и везде, а при попытке найти Sub выводит только из двух модулей Personal.xls, а потом вываливается в ошибку    
Метод 'ProcCountLines' объекта '_CodeModule' не выполнен
С уважением, Алексей (ИМХО: Excel-2003 - THE BEST!!!)
 
Развиваешь дальше - молодец!  
У меня отработало без сбоев - вывело все функции и все макросы.
 
Долго не мог понять, почему к функциям Sub FindProc(Proc$) зачислило... :)  
 
Нашёл - замени строку на такую - чтоб где не надо не находило :)  
' ищем в тексте модуля требуемый тип процедуры ("Sub_" или "Function_")
 
Привет, Игорь!  
А у меня, видишь, что-то глючит...  
А вообще-то идейка-то твоя очень интересная была. Только вылизывать её ещё долго.  
Там бы на форме сделать мультипэйдж с избранными фукнциями и макросами и кнопочку для вызова опять же мультипэйдж-формы с мультиселект-листбоксами, на которых должны быть перечислены доступные функции и макросы. А после пометки их должны формироваться листы со списками, в которых уже и прописываещь пояснения... А по "ОК" листы скрываются...  
В общем дел с получающейся книгой формул ещё невпроворот... и, наверное, я её-таки не доведу в ближайшее время...  
Хотя, как видишь, сдвиги есть.
С уважением, Алексей (ИМХО: Excel-2003 - THE BEST!!!)
 
{quote}{login=Hugo}{date=07.09.2010 03:37}{thema=}{post}Долго не мог понять, почему к функциям Sub FindProc(Proc$) зачислило... :)  
 
Нашёл - замени строку на такую - чтоб где не надо не находило :)  
' ищем в тексте модуля требуемый тип процедуры ("Sub_" или "Function_"){/post}{/quote}  
так, вроде, эти строки с комментариями должно пропускать:  
i = i + .ProcCountLines(.ProcOfLine(i, 0), 0)  ' переходим к следующей после конца процедуры строке кода  
Хотя... VB в чистом виде очень от меня далёк... С трудом разбираюсь в чужих функциях.
С уважением, Алексей (ИМХО: Excel-2003 - THE BEST!!!)
 
или я тебя не понял?  
С функциями у меня работает отлично. Не задваивает и находит, вроде, все...
С уважением, Алексей (ИМХО: Excel-2003 - THE BEST!!!)
 
Да, а я так пока использую, даже без кнопки открытия скрытого листа.  
А по поводу Function_ - оно ищет и находит в тексте макроса слово "Function "  и заносит эту поцедуру к функциям. У тебя не так?
 
Нет. У меня с функциями всё ОК.  
А вот с сабами - облом.  
В моём Персонал - кроме ThisWorkbook ещё 3 модуля:  
Common_Module, Examples_Module и UDF_Module  
В модуле UDF_Module кроме собственно UDF есть ещё и макросы для их вызова (как мы разобрались в той теме).  
Так вот:  
Sub Find_Func находит функции во всех модулях PERSONAL.XLS и в о всех открытых книгах.  
Sub Find_Sub находит все макросы в ThisWorkbook,Common_Module и Examples_Module PERSONAL.XLS, а вот при попытке прочитать UDF_Module успевает вывести на экран при i=1 iWbk.Name & vbTab & iVBComp.Name & vbTab и затыкается, похоже, на попытке найти .ProcOfLine(i, 0)    
Т.е. в окне я получаю такие последние строки:  
PERSONAL.XLS   UDF_Module    
Метод 'ProcCountLines' объекта '_CodeModule' не выполнен
С уважением, Алексей (ИМХО: Excel-2003 - THE BEST!!!)
 
Оказывается, нифига не ОК с функциями...  
При нескольких открытых книгах тоже начинает капризничать...  
Я уж, почитав справку на ЦитФоруме ( http://citforum.ru/programming/vbhelp/ ), ещё подправил чтобы точно попадать в поиске на кусок кода после окончания искомой процедуры (не зацепить случайно End Sub или End Function):  
Sub FindProc(Proc$)  
  Dim iWbk As Workbook, iVBComp As Object, iProcName$, iCodeLine&  
  On Error GoTo ErrExit  
  For Each iWbk In Workbooks   ' для каждой из открытых книг  
     For Each iVBComp In iWbk.VBProject.VBComponents  ' для каждого модуля проекта  
        iCodeLine = 1   'начиная с первой строки кода  
        With iVBComp.CodeModule  
           Do Until Not .Find(Proc & " ", iCodeLine, 1, .CountOfLines, 1, , True)   ' ищем в тексте модуля требуемый тип процедуры ("Sub_" или "Function_")  
              iProcName = .ProcOfLine(iCodeLine, 0)  
Debug.Print iWbk.Name & vbTab & iVBComp.Name & vbTab & iProcName  
              iCodeLine = .ProcStartLine(iProcName, 0) + .ProcCountLines(iProcName, 0) ' переходим к следующей после конца процедуры строке кода  
           Loop  
        End With  
     Next iVBComp  
  Next iWbk  
ErrExit:  
  If Err Then Debug.Print Err.Description  
End Sub  
и всё равно вылетает...  
Что-то, наверное, в цикле Do Until Not .Find(Proc & " ", iCodeLine, 1, .CountOfLines, 1, , True)... Loop не правильно.  
Я сам циклы Do Until ... Loop никогда не использую, а метод Find VB использую в первый раз в жизни (просто взял из другого примера на http://www.msoffice.nm.ru/faq/macros/module.htm#faq549 и чуть адаптировал)...  
Может, кто из гуру сможет подсказать, как надо делать?
С уважением, Алексей (ИМХО: Excel-2003 - THE BEST!!!)
 
Теперь, правда, вылетать стал с другим диагнозом: "Процедура Sub или Function не определена", но в той же строке iCodeLine = .ProcStartLine(iProcName, 0) + .ProcCountLines(iProcName, 0), отработав спокойненько несколько таких циклов по разным книгам.
С уважением, Алексей (ИМХО: Excel-2003 - THE BEST!!!)
 
Я тут тоже не помощник - никогда такого не делал. Подождём гуру...
 
Делал однажды что-то подобное: http://excelvba.ru/code/print_all_code_of_VBA_project <BR>Ну и, конечно, всё необходимое можно найти здесь: http://www.cpearson.com/excel/VBE.aspx
 
Дома из-под Висты решил свой макрос попробовать...  
Фиг вам! Ещё лучше: "Программный доступ к проекту Visual Basic не является доверенным"  
А как его доверить-то? Под ХРюшей с абсолютно тем же Офисом на старом компе и на работе таких заморочек не было...
С уважением, Алексей (ИМХО: Excel-2003 - THE BEST!!!)
 
Алекс, с этим постом выше твой аватар вааще отлично смотрится :)  
 
Слушай, а как ты планировал пояснения к формулам и кодам добавлять? Я понимаю, названия для запуска вынуть можно, и в строки прописать, чтоб в форме доступ был, но где и как брать описания? Надо ведь тогда и это тоже автоматизировать, или вручную добавлять особо непонятным кодам?
 
EducatedFool,  
мало того, что меня не пускают:"Программный доступ к проекту Visual Basic не является доверенным", о чём я писал в предыдущем посте, так ещё и компилятор отказывается понимать назначение FSO As FileSystemObject... Ругается, что якобы "User-Defined Type not defined".  
Завтра попробую на работе на ХРюше.  
Но вообще-то, если в моём макросе убрать перебор всех открытых книг в цикле, а оставить только одну ThisWorkbook, то всё прекрасно работает...  
 
Ваш код подробно не разбирал, но на первый взгляд кажется, Вы там просто в тексте ищете "Sub ", "End Sub", "Function ", "End Function" и т.п.?  
А если вдруг эти "волшебные слова" встретятся в тексте выводимого программно стринга или в комментариях?  
ИМХО, корректнее было бы искать первое не закоментированное вхождение нужного слова на листе кода, а потом уже, вычислив для этой строки имя процедуры iProcName = .ProcOfLine(iCodeLine, 0),  искать следующее вхождение уже после окончания этой процедуры. Т.е. начиная со строки  
iCodeLine = .ProcStartLine(iProcName, 0) + .ProcCountLines(iProcName, 0) как сделано в последнем приведенном мною варианте.  
Надо бы попробовать скрестить Ваш метод с методом моего примера: первую процедуру на листе кода искать как у Вас - по InStr(...), а следующее - как у меня - после окончания процедуры (через .ProcCountLines строк после начала процедуры).  
Только не знаю, хватит ли для этого моего знания ВБА...
С уважением, Алексей (ИМХО: Excel-2003 - THE BEST!!!)
 
Дмитрий, спасибо. Что-то я не помню, правда, чтобы я туда когда-либо лазил на других рабочих машинах... Но помогло.  
К сожалению, и дома на новой машине под Вистой макрос также глючит как и на работе на старой под ХРюшей. Ищет Сабы только на части модулей Персонала...  
А среди функций почему-то затесался и макрос от EducatedFool, в котором встречаются "волшебные слова" "Function ". Значит "перескок" поиска на конец процедуры у меня не работает...
С уважением, Алексей (ИМХО: Excel-2003 - THE BEST!!!)
 
Игорь,  
описания, естественно, писать придётся ручками на листе в колонке рядом с именем функции или макроса.  
Именно они будут выводиться на твою волшебную форму. Но можно сделать и добавочный прикол: прописать эти описания ещё и в Description чтобы они выводились при выборе ЮДФ обычным путём из "Определённые пользователем..."  
Т.е. если сейчас я делаю так:    
по событию Workbook_Open вызываю  
Sub Set_UDF_notes()  
'   On Error Resume Next  
   Const UDF_cat = "Определенные пользователем"  
   With Application  
       .MacroOptions Macro:="Substring", _  
                     Description:="Выделяет из текста n-ный субстринг, ориентируясь по символам-разделителям", _  
                     Category:=UDF_cat  
       .MacroOptions Macro:="СКЛЕИТЬ", _  
                     Description:="Склеивает тексты из выделенных ячеек с возможностью переноса строк", _  
                     Category:=UDF_cat  
   End With  
End Sub  
то в твоей форме можно будет эти дескрипшены считать с листа.
С уважением, Алексей (ИМХО: Excel-2003 - THE BEST!!!)
 
Прошу прощения. Зовут вернуться в лоно семьи из интернета... Ухожу.  
Всем до завтра. Спасибо за советы.
С уважением, Алексей (ИМХО: Excel-2003 - THE BEST!!!)
 
{quote}{login=Alex_ST}{date=07.09.2010 11:05}{thema=}{post}А среди функций почему-то затесался и макрос от EducatedFool, в котором встречаются "волшебные слова" "Function ". Значит "перескок" поиска на конец процедуры у меня не работает...{/post}{/quote}  
Так это то, что я заметил, когда на работе тестировал - среди функций появился твой макрос Sub FindProc(Proc$) - именно потому, что там в комментариях есть "Function ", что я и предложил заменить на "Function_".  
Я думаю, перескок тут нипричём - код нашёл процедуру, которая вроде как в его понимании функция. Он ведь ищет по всему тексту? Может искать только в первой строке?
 
{quote}{login=Hugo}{date=08.09.2010 12:02}{thema=Re: }...среди функций появился твой макрос Sub FindProc(Proc$) - именно потому, что там в комментариях есть "Function ", что я и предложил заменить на "Function_".  
Я думаю, перескок тут не причём - код нашёл процедуру, которая вроде как в его понимании функция. Он ведь ищет по всему тексту? Может искать только в первой строке?{/post}{/quote}  
Именно об этом я и писал вчера 07.09.2010 в 22:54.  
Т.е. нужно сделать цикл поиска по строкам кода с неравномерным шагом:  
1. Поиск со строки iCodeLine=1 до первого нахождения незакомментированного "волшебного слова" (с пробелом после него, естественно). Таким образом находим имя процедуры iProcName = .ProcOfLine(iCodeLine, 0)  
2. После нахождения строки с iProcName продолжать поиск уже через количество строк найденной процедуры. Т.е. через .ProcCountLines(iProcName, 0)  
 
Надо бы попробовать, но я боюсь запутаться с неравномерным циклом...
С уважением, Алексей (ИМХО: Excel-2003 - THE BEST!!!)
 
Мне кажется, надо именно в первой строке только смотреть. Если нет, берём следующую процедуру. А то ведь может быть в тексте макроса и незакоментированное что-то типа Msgbox "This Function Not Allowed!!!"
 
{quote}{login=Hugo}{date=08.09.2010 09:10}{thema=}{post}Мне кажется, надо именно в первой строке только смотреть. Если нет, берём следующую процедуру. А то ведь может быть в тексте макроса и незакоментированное что-то типа Msgbox "This Function Not Allowed!!!"{/post}{/quote}  
Быть-то, конечно, может, НО мы же не будем "шерстить" все строки подряд, а, найдя начало процедуры, продолжаем поиск со строк кода уже после её конца (т.е. через ProcCountLines от начала процедуры).  
Т.обр. все вхождения в код "волшебных слов" кроме как в названиях процедур будут (должны быть по крайней мере :-)) пропущены.  
 
А незакомментированное что-то типа Msgbox "This Function Not Allowed!!!" в листе кода без начинающего процедуру Sub или Function и завершающего её End Sub  или End Function (т.е. вне какой-либо процедуры) существовать не может!
С уважением, Алексей (ИМХО: Excel-2003 - THE BEST!!!)
 
Правда, в предыдущем посте я был не в 100% случаев прав...  
Ведь в модуле может быть и продекларирована какая-нибудь текстовая константа, содержащая "волшебные слова"...  
Но, ИМХО, для конкретных наших целей возможностью существования такого варианта можно пренебречь.  
Но конечно, если задаться целью написать универсальный макрос, который во всех случаях будет правильно "вытягивать" из кода все сабы и функции, то нужно будет ещё подполировать поиск.
С уважением, Алексей (ИМХО: Excel-2003 - THE BEST!!!)
 
{quote}{login=The_Prist}{date=08.09.2010 09:22}{thema=}{post}...не проще ли экспортировать модуль во временную папку, обработать его как TXT ...{/post}{/quote}  
ИМХО, не проще, т.к. для ТХТ нет свойств, позволяющих поиску после нахождения начала процедуры "перепрыгивать" на строку после её окончания. А это очень облегчает поиск, т.к. наверняка будут автоматически проигнорированы "волшебные слова", имеющиеся где-то в теле процедуры (в составе текстовых строк, в комментариях, ...)
С уважением, Алексей (ИМХО: Excel-2003 - THE BEST!!!)
 
Дмитрий, а что будет, если внутри тела процедуры встречается в комментах или в стрингах текст "End Sub" или "End Function", а после них внутри той же процедуры "Sub" или "Function"?
С уважением, Алексей (ИМХО: Excel-2003 - THE BEST!!!)
 
"НО мы же не будем "шерстить" все строки подряд, а, найдя начало процедуры, продолжаем поиск со строк кода уже после её конца"  
Погоди, ведь ты не ищешь сразу оба совпадения, ищешь по одному. И когда ишешь "Function " в Sub() - ты проскакиваешь начало до совпадения... Вот если бы совместить - искать оба одновременно, тогда да, сразу попал в любом случае на начало.  
Может тогда через Instr() в первой строке смотреть?
 
К стати, посмотрев рекомендованный уважаемым Йодо (EducatedFool) пример http://excelvba.ru/code/print_all_code_of_VBA_project , я ЧАСТИЧНО нашёл, почему он отказывается работать.  
Там определено:  
Dim FSo As FileSystemObject, ts As TextStream, fil As File  
а ни одного из таких типов ВБА не знает. Их надо сначала определить.  
Например, вот так:  
Dim FSo As Object  
Set FSo = CreateObject("Scripting.FileSystemObject")  
 
а вот как определять и назначать ts As TextStream и fil As File я пока не нашёл...
С уважением, Алексей (ИМХО: Excel-2003 - THE BEST!!!)
 
Игорь, ИМХО, мы с тобой друг друга не понимаем, хотя говорим абсолютно одно и то же.  
Ну, прочти внимательно мой пост от 08.09.2010, 08:30 ...  
 
Дмитрий,    
1.Я бы не стал называть идиотом человека, который внутри процедуры написал такие, например, фразы:  
Msgbox "Exit Function"  
Msgbox "Function"  
а уж в комментариях-то можно писать всё что хочешь...  
2. А как вы собираетесь искать различные варианты объявления (просто взял из Справки):  
[Public | Private | Friend] [Static] Function name [(arglist)] [As type]
С уважением, Алексей (ИМХО: Excel-2003 - THE BEST!!!)
 
Цитирую - 1. Поиск со строки iCodeLine=1 до первого нахождения незакомментированного "волшебного слова"  
Ну и вот, когда ищешь "Function " - находишь это внутри саба, и считаешь, что это функция - прыгаешь на конец этой процедуры, а сам саб - в список функций. Я так понял, почему у меня в функциях твой саб затесался.  
И честно говоря, не вижу, где закоментированное отсекается...
 
Игорь,  
1. В коде этого пока нет. Вот я в 8:30 и писал как его надо подправить...  
2. Найти внутри Sub стринги "Function " или "Sub " по предлагаемому мною алгоритму будет невозможно потому, что найдя саму Sub, поиск продолжишь уже после End Sub.  
3. Комментарии, включающие "волшебные слова" внутри процедуры обходятся по той де причине.  
4. Комментарии вне процедур всегда имеют в начале апостроф. Так их можно будет отсечь. Но, повторяю: в приведённом мною коде этого ещё нет.
С уважением, Алексей (ИМХО: Excel-2003 - THE BEST!!!)
Страницы: 1 2 След.
Читают тему
Наверх