Why can't I run a macro in PowerPoint if the procedure contains an object?

I have run into this issue a couple of times now.  For example, I am trying to run the below macro, but when I press F5 in the VBA Editor it is not on the list of available macros; however, if I remove "ByVal Pres As Presentation, ByRef SldTitles As Collection" then press F5 it shows up on the list.

Why is this happening, and how do I work around it?

I'm using Office 2013.

Also, I'm not positive I am using the correct terminology, so please correct me if I am wrong.

Sub CollectSlideTitles(ByVal Pres As Presentation, ByRef SldTitles As Collection)

     Dim Sld  As Slide
     Dim SldTitle  As String

     For Each Sld In Pres.Slides
         SldTitle = ""
         If Sld.Shapes.HasTitle Then
              If Sld.Shapes.Title.HasTextFrame Then
                 If Sld.Shapes.Title.TextFrame.HasText Then
                     SldTitle = Sld.Shapes.Title.TextFrame.TextRange.Text
                 End If
              End If
         End If
         If SldTitle = "" Then
             SldTitle = Sld.Name
         End If
         SldTitles.Add SldTitle
End Sub

Open in new window

Jon BredensteinerProject ManagerAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Because you are (trying) to pass the objects Pres and Slidetitles to the macro. This is impossible from a list of macros.

It's not at all clear what you expect the code to do but if you pass values to a module it will never appear in the list of runnable module. You would need to call the module from another module.
Jamie GarrochSenior Technical Consultant at BrightCarbonCommented:
There are two types of procedures in VBA. A Sub and a Function. Whilst a Function can be designed to return a value, a Sub cannot (unless of course you're using ByRef in the argument declaration). The simpler Sub can exist in its simplest form without arguments, for example:

Sub HelloWord()
  MsgBox "Hello World"
End Sub

Open in new window

You could then write a sub procedure that allows arguments to be passed to it:

Sub ShowMessage(myMessage As String)
  MsgBox myMessage
End Sub

Open in new window

But of course you need to call this Sub from somewhere as you need to pass the argument myMessage to it somehow:

Sub ShowMessageFromUser()
  If (MsgBox "Show Yes or No", vbYesNo, "Make a choice!") = vbYes Then
    ShowMessage "Yes"
    ShowMessage "No"
End Sub

Open in new window

So what is a Macro then? Well, it's a simple procedure of the Sub type, usually without arguments.

The reason you can't run your macro is that you have declared arguments and you have no way to pass those arguments by simply calling the Sub procedure as a macro.

So, to get round this, you need to find a way to pass Pres and SlideTitles from a macro as it looks like your procedure has been designed as an internal procedure, not a macro.

For example:

Sub myMacro()
  Dim oSld as Slide
  Dim myTitles as New Collection
  For Each oSld in ActivePresentation.Slides
    If oSld.Shapes.HasTitle Then myTitles.Add oSld.Shapes.Title.TextFrame.TextRange.Text
  CollectSlideTitles ActivePresentation, myTitles
End Sub

Open in new window

I haven't checked/compiled/run any of the code above but hopefully you get the idea?

There are exceptions to the macro = Sub without arguments concept. For example, you could assign this macro as a mouse click event (Insert / Action / Run Macro):

Sub ShowShapeTitle(oShp as Shape)
  MSgBox oShp.Title
End Sub

Open in new window

But you still won't see it in the 'macro' list using Alt+F8 as the sub definition contains a variable.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
JSRWilson is right. What is it that you want this code to do? At the moment, this bit of code is actually called from another procedure (i.e., the code in your question is expecting some other bit of code to run first).
OWASP: Avoiding Hacker Tricks

Learn to build secure applications from the mindset of the hacker and avoid being exploited.

Jon BredensteinerProject ManagerAuthor Commented:
Thanks to Jamie's great explanation, I believe I now understand that normally when a sub definition contains a variable it means the variable is an output that another procedure will use as an input.

I was trying to get a list of the slide titles in my presentation.  I found the code here Collect Slide Titles

I see now that the code I posted collects the slide titles, and I would need a separate procedure to output the list to Excel, Word, etc...

Thank you guys for your help.  Jamie your explanation really helped me understand some fundamentals about VBA.
Jon BredensteinerProject ManagerAuthor Commented:
Great explanation!
Jamie GarrochSenior Technical Consultant at BrightCarbonCommented:
Coding is like a lot of things in life. None of it makes any sense to begin with and step by step, the pieces fall into place as you enjoy each eureka moment and move on to solve the next challenge. Glad to have helped and good luck with your project.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft PowerPoint

From novice to tech pro — start learning today.