rubberduck-vba / Rubberduck

Every programmer needs a rubberduck. COM add-in for the VBA & VB6 IDE (VBE).
https://rubberduckvba.com
GNU General Public License v3.0
1.91k stars 299 forks source link

List all Subs's and Function in all modules with their parameters #5467

Open JCabral2000 opened 4 years ago

JCabral2000 commented 4 years ago

Hi Rubberduck Being new to these vba wanderings, I just use the Rubberduck indentation module, I confess my ignorance but I'm not sure how I can use the other modules to improve my code. I don't even know if Rubberduck, has any module that lists all the Sub's and Functions that exist in each module, identifying them exactly as Sub's or as Functions and listing the parameters of each one when they exist? Is this possible to do?

Description List, in a worksheet, all Subs's and Function in all modules with their parameters

retailcoder commented 4 years ago

Bring up the Code Explorer toolwindow, and click the "Copy to clipboard" button:

image

You can then paste the content into a worksheet, and you'll get a table with all user declarations in the project - including every module, procedure, parameter, ...but also every variable, enum member, line label, ...everything that has a name, basically.

Does that work?

JCabral2000 commented 4 years ago

Hi Rubberduck-Vba/Rubberduck This is not what I wanted to be listed. What I would like to do is select a module and list all the Sub's and Functions that exist in that module and only in that module. It would be a listing of the type:

'--------------------------------------------------------------------------------------- ' Module......: mdDRRGanttBars ' Procedures: 1) - Function GetColumnNoDRR(ByVal Input1 As Date, ByVal Input2 As Date, ByRef Output1 As Long, ByRef Output2 As Long) As Long 2) - Public Sub DeleteShapesInSheetDRR() 3) - Public Sub DrawGanttBarsForDRR(ByVal ws As Worksheet, ByVal cRow As Long, ByVal sCol As Long, ByVal eCol As Long) .) - ....... N) - ....... '---------------------------------------------------------------------------------------

Is that possible in Rubberduck?

Thanks Jorge

Mathieu Guindon notifications@github.com escreveu no dia quarta, 22/04/2020 à(s) 16:20:

Bring up the Code Explorer toolwindow, and click the "Copy to clipboard" button:

[image: image] https://user-images.githubusercontent.com/5751684/80000224-df9a3500-848a-11ea-9cef-fc14fc0204a8.png

You can then paste the content into a worksheet, and you'll get a table with all user declarations in the project - including every module, procedure, parameter, ...but also every variable, enum member, line label, ...everything that has a name, basically.

Does that work?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/rubberduck-vba/Rubberduck/issues/5467#issuecomment-617844838, or unsubscribe https://github.com/notifications/unsubscribe-auth/AL6MMIHTF67FDHFU7MZDKWLRN4DLNANCNFSM4MOIHQ2A .

retailcoder commented 4 years ago

Note that a list of procedure signatures is just plain text, not usable metadata. I invite you to take a closer look at the user declarations table: you can filter by module, by procedure scope, even by custom @Folder. If you filter the declaration type to only include Procedure, Function, and Parameter members, you'll have everything you need to traverse the table and visualize the data any way you like, including by generating a report that lists procedure signatures in a bullet list. Others might prefer a pivot that counts the average number of local variables per procedure scope, or some dashboard that shows the 5 most-common identifier names and the average identifier length in the project... who knows.

It's not the job of an IDE add-in to generate such custom visualizations: we give you the source data, but forcing one specific particular visualization of this data onto our users isn't something that is going to be prioritized.

retailcoder commented 4 years ago

To be fair the parameter indexes are missing, which means regenerating member signatures from the provided metadata isn't reliably possible... that's missing metadata, and adding that would definitely be in-scope.

JCabral2000 commented 4 years ago

Hi Mathieu Guindon

Thank you for your quick response. I will have to look for what I want elsewhere.

Thanks Jorge

Mathieu Guindon notifications@github.com escreveu no dia quarta, 22/04/2020 à(s) 17:52:

Note that a list of procedure signatures is just plain text, not usable metadata. I invite you to take a closer look at the user declarations table: you can filter by module, by procedure scope, even by custom @Folder. If you filter the declaration type to only include Procedure, Function, and Parameter members, you'll have everything you need to traverse the table and visualize the data any way you like, including by generating a report that lists procedure signatures in a bullet list. Others might prefer a pivot that counts the average number of local variables per procedure scope, or some dashboard that shows the 5 most-common identifier names and the average identifier length in the project... who knows.

It's not the job of an IDE add-in to generate such custom visualizations: we give you the source data, but forcing one specific particular visualization of this data onto our users isn't something that is going to be prioritized.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/rubberduck-vba/Rubberduck/issues/5467#issuecomment-617900589, or unsubscribe https://github.com/notifications/unsubscribe-auth/AL6MMID6222J5XEMXXHMUILRN4OFJANCNFSM4MOIHQ2A .

retailcoder commented 4 years ago

If all you need is member signatures, you can get that from the VBIDE API with a few lines of code. Assuming all member signatures are on a single physical line of code (i.e. no line continuations), then this would be a start:

Dim c As VBComponent
For Each c In ThisWorkbook.VBProject.VBComponents
    Debug.Print "Module:", c.Name
    Debug.Print "Members:"

    Dim ln As Long
    For ln = 1 To c.CodeModule.CountOfLines
        Dim lineOfCode As String
        lineOfCode = c.CodeModule.GetLines(ln, 1)
        Dim memberIndex As Long
        If Left(lineOfCode, 4) <> "End " And (InStr(lineOfCode, "Sub ") > 0 Or InStr(lineOfCode, "Function ") > 0) Then
            memberIndex = memberIndex + 1
            Debug.Print vbTab & memberIndex & ")" & vbTab & lineOfCode
        End If
    Next

    Debug.Print vbNewLine
Next

Note that you have to explicitly enable programmatic access to the VBIDE extensibility library (in Excel's macro security settings) for this code to run.

JCabral2000 commented 4 years ago

Hi Mathieu Guindon

Thanks again for your answer, and for your patience

The only thing I need is what appears in the type listing I sent you.

I have enabled "Microsoft Visual Basic for Applications Extensibility 5.3" in Tools \ References, but the code gives me an error at:

lineOfCode = c.CodeModule.GetLines (ln, 1) - Method or data member not found.

Any help?

Thanks Jorge

Mathieu Guindon notifications@github.com escreveu no dia quarta, 22/04/2020 à(s) 18:23:

If all you need is member signatures, you can get that from the VBIDE API with a few lines of code. Assuming all member signatures are on a single physical line of code (i.e. no line continuations), then this would be a start:

Dim c As VBComponentFor Each c In ThisWorkbook.VBProject.VBComponents Debug.Print "Module:", c.Name Debug.Print "Members:"

Dim ln As Long
For ln = 1 To c.CodeModule.CountOfLines
    Dim lineOfCode As String
    lineOfCode = c.CodeModule.GetLines(ln, 1)
    Dim memberIndex As Long
    If Left(lineOfCode, 4) <> "End " And (InStr(lineOfCode, "Sub ") > 0 Or InStr(lineOfCode, "Function ") > 0) Then
        memberIndex = memberIndex + 1
        Debug.Print vbTab & memberIndex & ")" & vbTab & lineOfCode
    End If
Next

Debug.Print vbNewLineNext

Note that you have to explicitly enable programmatic access to the VBIDE extensibility library (in Excel's macro security settings) for this code to run.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/rubberduck-vba/Rubberduck/issues/5467#issuecomment-617917694, or unsubscribe https://github.com/notifications/unsubscribe-auth/AL6MMIE4CSOOLCIE7HWUB7DRN4RY3ANCNFSM4MOIHQ2A .

retailcoder commented 4 years ago

That was untested air-code.. try declaring a CodeModule variable to hold the c.CodeModule reference and have early-bound access to the members - typing the . should then list what members are available for the CodeModule class.

From the COM wrapper source code: https://github.com/rubberduck-vba/Rubberduck/blob/9aa0cd6b5a396dba08f625d1fc5b82350c234831/Rubberduck.VBEditor.VBA/SafeComWrappers/VB/CodeModule.cs#L33-L36

Looks like the member might actually be called get_Lines.

JCabral2000 commented 4 years ago

Hi Mathieu Guindon

It is almost solved, putting "lineOfCode = c.CodeModule.Lines (ln, 1)" no longer gives an error.

The only thing that remains to be resolved is when all member signatures are NOT on a single physical line of code, there for now just list up to "_".

Any tips, to solve this?

For writing to be done directly on a spreadsheet, I think I can make the code.

Thank you so much again Jorge

Mathieu Guindon notifications@github.com escreveu no dia quarta, 22/04/2020 à(s) 18:46:

That was untested air-code.. try declaring a CodeModule variable to hold the c.CodeModule reference and have early-bound access to the members - typing the . should then list what members are available for the CodeModule class.

From the COM wrapper source code:

https://github.com/rubberduck-vba/Rubberduck/blob/9aa0cd6b5a396dba08f625d1fc5b82350c234831/Rubberduck.VBEditor.VBA/SafeComWrappers/VB/CodeModule.cs#L33-L36

Looks like the member might actually be called get_Lines.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/rubberduck-vba/Rubberduck/issues/5467#issuecomment-617930284, or unsubscribe https://github.com/notifications/unsubscribe-auth/AL6MMIGVYZZNC3HZXP6TRNDRN4UPPANCNFSM4MOIHQ2A .

JCabral2000 commented 4 years ago

Hi Mathieu Guindon

With your help and the website http://www.cpearson.com/Excel/MainPage.aspx, I was able to list, in a simple excel sheet, all the subroutines and respective parameters, of each module. I think the code is very complicated and very dense and I can't simplify it, I don't know if you can help me in trying to simplify the code? If possible, say, because I send you the file. What I can't do is write down the list of all subroutines directly on each module. It is possible? I hope you can help me. Thank you

Jorge

Photo GP Photo GP myphotogp@gmail.com escreveu no dia quarta, 22/04/2020 à(s) 19:36:

Hi Mathieu Guindon

It is almost solved, putting "lineOfCode = c.CodeModule.Lines (ln, 1)" no longer gives an error.

The only thing that remains to be resolved is when all member signatures are NOT on a single physical line of code, there for now just list up to "_".

Any tips, to solve this?

For writing to be done directly on a spreadsheet, I think I can make the code.

Thank you so much again Jorge

Mathieu Guindon notifications@github.com escreveu no dia quarta, 22/04/2020 à(s) 18:46:

That was untested air-code.. try declaring a CodeModule variable to hold the c.CodeModule reference and have early-bound access to the members - typing the . should then list what members are available for the CodeModule class.

From the COM wrapper source code:

https://github.com/rubberduck-vba/Rubberduck/blob/9aa0cd6b5a396dba08f625d1fc5b82350c234831/Rubberduck.VBEditor.VBA/SafeComWrappers/VB/CodeModule.cs#L33-L36

Looks like the member might actually be called get_Lines.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/rubberduck-vba/Rubberduck/issues/5467#issuecomment-617930284, or unsubscribe https://github.com/notifications/unsubscribe-auth/AL6MMIGVYZZNC3HZXP6TRNDRN4UPPANCNFSM4MOIHQ2A .

JCabral2000 commented 4 years ago

Hi Mathieu Guindon

Any tip/help?

Thanks Jorge

Photo GP Photo GP myphotogp@gmail.com escreveu no dia domingo, 26/04/2020 à(s) 22:47:

Hi Mathieu Guindon

With your help and the website http://www.cpearson.com/Excel/MainPage.aspx, I was able to list, in a simple excel sheet, all the subroutines and respective parameters, of each module. I think the code is very complicated and very dense and I can't simplify it, I don't know if you can help me in trying to simplify the code? If possible, say, because I send you the file. What I can't do is write down the list of all subroutines directly on each module. It is possible? I hope you can help me. Thank you

Jorge

Photo GP Photo GP myphotogp@gmail.com escreveu no dia quarta, 22/04/2020 à(s) 19:36:

Hi Mathieu Guindon

It is almost solved, putting "lineOfCode = c.CodeModule.Lines (ln, 1)" no longer gives an error.

The only thing that remains to be resolved is when all member signatures are NOT on a single physical line of code, there for now just list up to "_".

Any tips, to solve this?

For writing to be done directly on a spreadsheet, I think I can make the code.

Thank you so much again Jorge

Mathieu Guindon notifications@github.com escreveu no dia quarta, 22/04/2020 à(s) 18:46:

That was untested air-code.. try declaring a CodeModule variable to hold the c.CodeModule reference and have early-bound access to the members - typing the . should then list what members are available for the CodeModule class.

From the COM wrapper source code:

https://github.com/rubberduck-vba/Rubberduck/blob/9aa0cd6b5a396dba08f625d1fc5b82350c234831/Rubberduck.VBEditor.VBA/SafeComWrappers/VB/CodeModule.cs#L33-L36

Looks like the member might actually be called get_Lines.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/rubberduck-vba/Rubberduck/issues/5467#issuecomment-617930284, or unsubscribe https://github.com/notifications/unsubscribe-auth/AL6MMIGVYZZNC3HZXP6TRNDRN4UPPANCNFSM4MOIHQ2A .

retailcoder commented 4 years ago

I think the code is very complicated and very dense and I can't simplify it,

If it works regardless, then consider putting it up for peer review on Code Review Stack Exchange; I'll post feedback there if/when I find the time, and meanwhile others could chip in with their ideas too.

What I can't do is write down the list of all subroutines directly on each module. It is possible?

I'm not sure what that means. You want to output the list of all procedures ...in the same module where these procedures are defined?

JCabral2000 commented 4 years ago

Photo GP Photo GP myphotogp@gmail.com 14:59 (há 0 minutos) para rubberduck-vba/Rubberduck Hi Mathieu

If it works regardless, then consider putting it up for peer review on Code

Review Stack Exchange https://codereview.stackexchange.com/; I'll post feedback there if/when I find the time, and meanwhile others could chip in with their ideas too.

  I don't know exactly what this is and how to do it, but if you don't

find this challenge interesting, I think there will be no one else who might be interested.

I'm not sure what that means. You want to output the list of all procedures

...in the same module where these procedures are defined?

This is it: Procs

Thanks for your help Jorge

Mathieu Guindon notifications@github.com escreveu no dia quinta, 30/04/2020 à(s) 02:13:

I think the code is very complicated and very dense and I can't simplify it,

If it works regardless, then consider putting it up for peer review on Code Review Stack Exchange https://codereview.stackexchange.com; I'll post feedback there if/when I find the time, and meanwhile others could chip in with their ideas too.

What I can't do is write down the list of all subroutines directly on each module. It is possible?

I'm not sure what that means. You want to output the list of all procedures ...in the same module where these procedures are defined?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/rubberduck-vba/Rubberduck/issues/5467#issuecomment-621554285, or unsubscribe https://github.com/notifications/unsubscribe-auth/AL6MMIDOCE6QMWQUZYJ3QNDRPDGFNANCNFSM4MOIHQ2A .

daFreeMan commented 4 years ago

@JCabral2000 CodeReview is a StackExchange web site where people post working code to have it reviewed by others. There are folks from all around the world who will look at your code for potential bugs, inefficiencies, coding standards and other tips and tricks that will make it better.

Make an account there (if you don't already have a StackExchange account, just join CodeReview if you do), read through the help on how to post to CR (it's a bit different that other SE sites), then post your code asking the world at large for the help you requested specifically from Mathieu. Pro-tip: Recognize that doing a good code review can take many hours, so don't get too impatient when you post on CR. You may not see an answer right away, but that doesn't mean that someone hasn't looked at your code and is in the processes of writing up a review.

By posting on CR, anyone can (and, most likely will) be able to help you instead of having to wait on and rely on just one individual. I really don't think that Mathieu's not interested in helping you, it's just that I know he's currently buried 8+ hours per day by his day-job work and, with his other life commitments, just doesn't have time to help you on your time schedule.

Additionally, your picture didn't post here, we simply got a reference to the fact that you included an image. You may want to come directly to this post on GitHub and edit the image into your post. Also, if you include that image in your CR post (which would be a good idea), be sure to follow the instructions there on how to properly embed images so people there can see it.

JCabral2000 commented 4 years ago

Brett Shepard Thank you for your explanations. Let it be clear that I am not saying that Mathieu did not help me. What I managed to do was only with his help.

What I mentioned is that this is not of interest to be incorporated in the development of Rubberduck. There is no problem. Regarding the extra help I need, I will try at the CR. Thank you all. Jorge

daFreeMan commented 4 years ago

Now that we can see your desired result for "in module", it seems that using Rubberduck's Code Explorer (Rubberduck -> Navigate -> Code Explorer) will show you exactly what you're after without having to write self-modifying code.

Once you're looking at the CE you can click to expand a module and it will show you all the methods (Sub, Function) as well as module-level variables and loads of other things. Take a look at that and see if it will meet your needs.

One word of caution - many anti-virus programs will flag self-modifying code (even if all it's doing is writing comments back into itself) as malicious. You could write something that ends up getting flagged by your company's AV installation on your machine as you develop it and on the machine of anyone who tries to use it (even though they'll never see or even execute the self-modifying bits).

Finally, you are correct, there is little interest in incorporating this into RD since the functionality exists in the form of the CE. However, since this issue is here, I'm sure a pull-request that implemented this feature would be happily accepted.

JCabral2000 commented 4 years ago

Hi Brett Shepard Thanks again for your clarification.

"Once you're looking at the CE you can click to expand a module and it will show you all the methods (Sub, Function) as well as module-level variables and loads of other things. Take a look at that and see if it will meet your needs."

Yes, the information is there but I can't copy it, to the top of each module, as shown in the image I attached.

Thank you Jorge

Brett Shepard notifications@github.com escreveu no dia quinta, 30/04/2020 à(s) 16:06:

Now that we can see your desired result for "in module", it seems that using Rubberduck's Code Explorer (Rubberduck -> Navigate -> Code Explorer) will show you exactly what you're after without having to write self-modifying code.

Once you're looking at the CE you can click to expand a module and it will show you all the methods (Sub, Function) as well as module-level variables and loads of other things. Take a look at that and see if it will meet your needs.

One word of caution - many anti-virus programs will flag self-modifying code (even if all it's doing is writing comments back into itself) as malicious. You could write something that ends up getting flagged by your company's AV installation on your machine as you develop it and on the machine of anyone who tries to use it (even though they'll never see or even execute the self-modifying bits).

Finally, you are correct, there is little interest in incorporating this into RD since the functionality exists in the form of the CE. However, since this issue is here, I'm sure a pull-request that implemented this feature would be happily accepted.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/rubberduck-vba/Rubberduck/issues/5467#issuecomment-621913454, or unsubscribe https://github.com/notifications/unsubscribe-auth/AL6MMIBV5UQ47ORIQ2GV2TDRPGHYBANCNFSM4MOIHQ2A .