Adding a button and Click event at run-time

Many developers recognize the need to disable certain controls in their application to either keep from confusing users as to which button to click or to keep users from clicking buttons at an inappropriate time. Usually this is done by programmatically enabling/disabling the button. However there is another way. At run-time, you can create a button or subroutine that does its own thing and then, before it is finished, creates another button and adds an event procedure to the button just created.

The following steps help you create a Word macro that will add a control to a document and assign that control’s Click event at run-time. Although the steps below are for Word, you can apply the same concepts to programmatically manipulate controls in Microsoft Excel workbooks.

Steps to Create Sample

1. Start a new document in Word.

2. Press Alt+F11 to go to the Visual Basic Editor.

3. Click Tools and then References and select the reference for
   “Microsoft Visual Basic for Applications Extensibility”.

4. Insert a new module and add the following code:

Sub Test()
    ‘Add a command button to a new document.
    Dim doc As Word.Document
    Dim shp As Word.InlineShape
    Set doc = Documents.Add
    Set shp =        doc.Content.InlineShapes.AddOLEControl(ClassType:=”Forms.CommandButton.1″)
    shp.OLEFormat.Object.Caption = “Click Here”
    ‘Add a procedure for the click event of the inlineshape
    ‘Note: The click event ends up residing in the ThisDocument module.
    Dim sCode As String
    sCode = “Private Sub ” & shp.OLEFormat.Object.Name & “_Click()” & vbCrLf & _
       ”   MsgBox “”You Clicked the CommandButton””” & vbCrLf & _
       “End Sub”
    doc.VBProject.VBComponents(“ThisDocument”).CodeModule.AddFromString sCode
End Sub

5. Run the macro “Test”.

6. Once the macro “Test” finishes running, you will see a new
   CommandButton control on a new document. When you click the
   CommandButton, it’s Click Event fires.

Note: If you receive the following error:

“Programmatic Access to Visual Basic Project is not trusted.”

Office XP and Office 2003 add a security option to deliberately lock out programmatic access to the VBA object model from any Automation client unless a user chooses to permit such access. This is a per user and per application setting, and denies access by default. To turn on the access, do the following:

1. Open the Office application in question. On the Tools menu, click
   Macro, and then click Security to open the Macro Security dialog box.

2. On the Trusted Sources tab, click to select the Trust access to
   Visual Basic Project
check box to turn on access.

3. Click OK to apply the setting. You may need to restart the
   application for the code to run properly if you automate from a
   Component Object Model (COM) add-in or template.



Comments (9)

  1. Sam says:

    I don’t understand why this is any better than:

    btnMyButton.enabled = False.

  2. frice says:

    Thanks for the feedback. To me, it’s cleaner because you don’t have grayed out buttons on the form or document. You only have a button on the form when you need it. For example, you could set up a conditional statement that would allow you to create the button and assign the event procedure only if a certain condition was true(false).

  3. Sam says:

    Or you could make the button invisible until you need it. To me its cleaner to have a button invisible and then a one line:

    btnMyButton.visible = true

    Rather than the 200 lines you’ve posted above.

    am I missing something special about what you’ve done?

  4. Lena says:

    HI There,

    Could somebody help me to do the same thing with excel ….

    It does nto work

    Thank you

  5. Frice says:

    I’m not familiar with RSS feeds. Sorry.

  6. d says:

    The 200 lines above can be used if you want a more flexible interface than something that is pre-programmed. If, for example you are implementing an interface to a database you can pull information from it and use that to decide how many buttons, text fields, etc. you need.

    Or you may be trying to develop a way for a user with less/no VB experience to develop something based on a few questions/parameters.

    In any case, it is always better to learn different ways to do things. If you want to use the simple way because that works best for what you’re doing, go ahead. But it doesn’t hurt to know there’s another way to do it.

    If you don’t want to learn more and improve your skills, don’t.

  7. Frank…. been a while since you blogged. Keep it coming.

  8. KH says:

    Thanks a lot for this code – I have been able to create a PowerPoint toolbar button to automatically add a button to a slide that will print the current slide when clicked during a show. Your code worked with just a little tweeking for PowerPoint.

  9. frice says:

    Thanks for the feedback! I’m sure that my code was only 40% of your solution and your tweaking was the other 60%. Thanks again.