Now that we saw how macros, queries, forms, reports and tables are persisted in templates, we can ask: what about embedded macros?

 

Since embedded macros live in the event properties of form, reports and controls, they are persisted along with the object that contains them. For example, let’s say that a form has a control which OnClick event has an embedded macro. If we look at how the form is persisted, the embedded macro will be clear. See below in red:

 

Version =20

VersionRequired =20

Checksum =1875235619

Begin Form

    DividingLines = NotDefault

    AllowDesignChanges = NotDefault

    DefaultView =0

    TabularCharSet =204

    PictureAlignment =2

    DatasheetGridlinesBehavior =3

    GridX =24

    GridY =24

    Width =8884

    DatasheetFontHeight =11

    ItemSuffix =1

    Right =7755

    Bottom =7860

    RecSrcDt = Begin

        0x5e1d77333303e340

    End

    GUID = Begin

        0x215548c7105bb74f9c5a62a34852d43e

    End

    NameMap = Begin

        0x0acc0e5500000000000000000000000000000000000000000c00000004000000 ,

        0x0000000000000000000000000000

    End

    DatasheetFontName ="Arial"

    FilterOnLoad =0

    DatasheetBackColor12 =16777215

    ShowPageMargins =0

    DisplayOnSharePointSite =1

    DatasheetAlternateBackColor =16053492

    DatasheetGridlinesColor12 =16765357

    FitToScreen =1

    Begin

        Begin CommandButton

            FontSize =11

            FontWeight =400

            ForeColor =-2147483630

            FontName ="Calibri"

            LeftPadding =30

            TopPadding =30

            RightPadding =30

            BottomPadding =30

            GridlineStyleLeft =0

            GridlineStyleTop =0

            GridlineStyleRight =0

            GridlineStyleBottom =0

            GridlineWidthLeft =1

            GridlineWidthTop =1

            GridlineWidthRight =1

            GridlineWidthBottom =1

        End

        Begin Section

            Height =7560

            Name ="Detail"

            GUID = Begin

                0x074cc32161de494c80853bffa393c314

            End

            AutoHeight =1

            Begin

                Begin CommandButton

                    OverlapFlags =85

                    Left =2820

                    Top =300

                    Width =1800

                    Height =1560

                    Name ="Command0"

                    Caption ="Command0."

                    GUID = Begin

                        0x57ec04af6fab7346a743706d495ed583

                    End

                    OnClickEmMacro = Begin

                        Version =196611

                        ColumnsShown =8

                        Begin

                            Action ="MsgBox"

                            Argument ="foo"

                            Argument ="-1"

                            Argument ="0"

                        End

                    End

                    LayoutCachedLeft =2820

                    LayoutCachedTop =300

                    LayoutCachedWidth =4620

                    LayoutCachedHeight =1860

                End

            End

        End

    End

End

 

The reality is that this persistence representation of the object and the embedded macro shows some implementation details about embedded macros. The key is in the “OnClickEmMacro” property name used above.

 

Embedded macros actually are not store in the event property themselves (say, On Click), because those only hold things like “[Event Procedure]”, “Macro1”, “=Foo(1+2)” and such. Embedded macros are actually store in hidden properties that exist corresponding to every single event property. We call them “shadow” properties.  These shadow properties are actually exposed through the OM, but also in a hidden manner. You will notice that for every event property OM (e.g. Control.OnClick) there is a corresponding shadow property (e.g. Control.OnClickMacro).

 

Even further, if you create an embedded macro and open the immediate window in the VBE editor and query for the shadow property (such as: “? Form(0).Controls(“foo”).OnClickMacro”), you will see an output that looks something like this:

 

Version =196611

ColumnsShown =8

               Begin

                   Action ="MsgBox"

                   Argument ="foo"

                   Argument ="-1"

                   Argument ="0"

               End

 

Doesn’t it look familiar? Well, it is the same output as it was saved in the form above for templates. You see, you can read (and write!) to these shadow properties using the SaveAsText/LoadFromText format for plain macros.

 

Do I smell an embedded macro to standalone macro converter add-in? How about an embedded macro reporter and analyzer for databases? The world is the limit here…