<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Wizards of Smart &#187; VBA</title>
	<atom:link href="http://wizardsofsmart.net/tag/vba/feed/" rel="self" type="application/rss+xml" />
	<link>http://wizardsofsmart.net</link>
	<description>.NET Design Patterns</description>
	<lastBuildDate>Thu, 29 Jul 2010 16:40:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1-alpha</generator>
		<item>
		<title>Future-proofing Office 2003 Custom Menu Development</title>
		<link>http://wizardsofsmart.net/samples/future-proofing-office-2003-custom-menu-development/</link>
		<comments>http://wizardsofsmart.net/samples/future-proofing-office-2003-custom-menu-development/#comments</comments>
		<pubDate>Thu, 05 Jun 2008 12:30:56 +0000</pubDate>
		<dc:creator>panesofglass</dc:creator>
				<category><![CDATA[Samples]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[Office]]></category>
		<category><![CDATA[Ron de Bruin]]></category>
		<category><![CDATA[VBA]]></category>
		<category><![CDATA[Worksheet Menu Bar]]></category>

		<guid isPermaLink="false">http://panesofglass.com/?p=32</guid>
		<description><![CDATA[More and more companies are slowly rolling out Windows Vista as they bring on new machines. However, if you&#8217;ve tried upgrading an Office 2003 document that uses custom menus, you will have noticed that those custom menus don&#8217;t appear in Office 2007&#8242;s new Ribbon. Well, that&#8217;s not entirely true; they do appear in the Add-Ins [...]]]></description>
			<content:encoded><![CDATA[<p>More and more companies are slowly rolling out Windows Vista as they bring on new machines. However, if you&#8217;ve tried upgrading an Office 2003 document that uses custom menus, you will have noticed that those custom menus don&#8217;t appear in Office 2007&#8242;s new Ribbon. Well, that&#8217;s not entirely true; they do appear in the Add-Ins tab. However, leaving users to figure that out for themselves is not a little unkind.</p>
<p>You might think your only option is to create two files&#8211;one for Office 2003 and previous and another for Office 2007. You would be wrong. Instead, you can use an Excel 2007 Add-In to extend the ribbon when the file is opened in Office 2007 and open the file as normal in Office 2003. <a href="http://www.rondebruin.nl/" onclick="urchinTracker('/outgoing/www.rondebruin.nl/?referer=');">Ron de Bruin</a> explains how to do this in his post &#8220;<a href="http://www.rondebruin.nl/compatiblemenu.htm" onclick="urchinTracker('/outgoing/www.rondebruin.nl/compatiblemenu.htm?referer=');">Dealing with Ribbons and Menus &#8211; Avoiding Two Versions</a>.&#8221;</p>
<p>To make this work, you&#8217;ll need the <a href="http://openxmldeveloper.org/articles/customuieditor.aspx" onclick="urchinTracker('/outgoing/openxmldeveloper.org/articles/customuieditor.aspx?referer=');">CustomUIEditor</a> from <a href="http://openxmldeveloper.org/" onclick="urchinTracker('/outgoing/openxmldeveloper.org/?referer=');">OpenXMLDeveloper.org</a>. Also, I&#8217;ve always been a big fan of class modules, so I have attempted to roll all this up into one class module, following Ron&#8217;s second example.</p>
<p>Here&#8217;s the code for the CustomMenu.cls class:</p>
<pre class="brush: vb">VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  &#039;True
END
Attribute VB_Name = &quot;CustomMenu&quot;
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
&#039;******************************************
&#039; Class:        CustomMenu
&#039;
&#039; Created by:   Ryan Riley (Catapult Systems)
&#039; Created on:   5/22/2008
&#039;
&#039; Description:  This class allows menus and menu items to be added
&#039;               to assist the user with additional reporting options.
&#039;
&#039; Dependencies: None
&#039;******************************************

Option Explicit

&#039;******************************************
&#039; Private Members
&#039;******************************************
Private mstrName As String            &#039; Use an &#039;&amp;amp;&#039; to assign a shortcut key.
Private mstrRibbonxPath As String     &#039; Store the Excel 2007 Add-in path.
Private mstrRibbonxName As String     &#039; Store the Excel 2007 Add-in filename.
Private mcolMenuItems As Collection
Private mcbc As CommandBarControl

&#039;******************************************
&#039; Class C&#039;tors and D&#039;tors
&#039;******************************************
Private Sub Class_Initialize()
    &#039; Initialize the Name property.
    mstrName = &quot;My Menu&quot;
    mstrRibbonxPath = ThisWorkbook.Path
    mstrRibbonxName = &quot;RibbonxAddin.xlam&quot;
    Set mcolMenuItems = New Collection
End Sub

Private Sub Class_Terminate()
    &#039; Destroy the menu item collection object.
    Set mcolMenuItems = Nothing

    &#039; Destroy the CommandBarControl object.
    Set mcbc = Nothing
End Sub

&#039;******************************************
&#039; Public Properties
&#039;******************************************
Public Property Get Name() As String
    Name = mstrName
End Property

Public Property Let Name(ByVal value As String)
    mstrName = value
End Property

Public Property Get RibbonxPath() As String
    RibbonxPath = mstrRibbonxPath
End Property

Public Property Let RibbonxPath(ByVal value As String)
    mstrRibbonxPath = value
End Property

Public Property Get RibbonxName() As String
    RibbonxName = mstrRibbonxName
End Property

Public Property Let RibbonxName(ByVal value As String)
    mstrRibbonxName = value
End Property

&#039;******************************************
&#039; Public Methods
&#039;******************************************
&#039; Add a menu to the document.
Public Function Attach( _
  Optional Before As Integer = 0) As Boolean
    &#039; Initialize the function return value.
    Attach = False
   
    If Val(Application.Version) &amp;gt; 11 Then
        If (Dir(mstrRibbonxPath &amp;amp; &quot;\&quot; &amp;amp; mstrRibbonxName) &amp;lt;&amp;gt; &quot;&quot;) Then
            Workbooks.Open mstrRibbonxPath &amp;amp; &quot;\&quot; &amp;amp; mstrRibbonxName
        Else
            MsgBox &quot;The RibbonX add-in (&quot; &amp;amp; mstrRibbonxName &amp;amp; &quot;) could not be found.&quot;
        End If
    Else
        AddMenu Before
    End If

    &#039; If all has gone well, return true.
    Attach = True
End Function

Public Function Detach()
    Detach = False

    If Val(Application.Version) &amp;gt; 11 Then
        On Error Resume Next
        Workbooks(mstrRibbonxName).Close False
    Else
        DeleteMenu
    End If

    Detach = True
End Function

&#039; Add menu items to the menu. Call this for each menu
&#039; item you wish to add to the menu.
Public Function AddItem( _
  ByVal Name As String, _
  ByVal Macro As String) As Boolean
    AddItem = False
   
    If (Val(Application.Version) &amp;gt; 11) Then
        &#039; Add the menu item to the private collection.
        mcolMenuItems.Add Macro, Name
    Else
        &#039; Add a menu item to our new menu, give it a caption,
        &#039; and tell it which macro to run (OnAction).
        With mcbc.Controls.Add(Type:=msoControlButton)
            .Caption = Name
            .OnAction = Macro
        End With
    End If

    AddItem = True
End Function

&#039; Define the function for all Ribbon controls to call when executed.
&#039; This method execute the button that matches the format:
&#039; &quot;buttonName&quot; where Name is the Menu Item name.
Public Function OnActionCall(MenuItem As Variant) As Boolean
    Dim RibbonItem As IRibbonControl

    &#039; Initialize the return value.
    OnActionCall = False

    &#039; Set the MenuItem to the RibbonItem as an implementation
    &#039; of the IRibbonControl.
    Set RibbonItem = MenuItem

    &#039; Run the macro that matches that stored in the collection.
    Application.Run mcolMenuItems(Mid(RibbonItem.ID, 7))

    &#039; If all goes well, return true.
    OnActionCall = True
End Function

&#039;******************************************
&#039; Private Methods
&#039;******************************************
Private Function AddMenu( _
  Optional Before As Integer = 0) As Boolean
    Dim cbMainMenu As CommandBar
    Dim intBeforeIndex As Integer

    &#039; Initialize the function return value.
    AddMenu = False

    &#039; Delete any existing menus with the same name.
    &#039; We must use On Error Resume next in case it does not exist.
    On Error Resume Next
    Application.CommandBars(&quot;Worksheet Menu Bar&quot;).Controls(mstrName).Delete
    On Error GoTo 0
   
    &#039; Set a CommandBar variable to use for the Worksheet menu bar
    Set cbMainMenu = Application.CommandBars(&quot;Worksheet Menu Bar&quot;)
   
    &#039; If the Before Index is &amp;gt; 0, set the Before Index to the passed
    &#039; in index; otherwise set it to the index for the last menu.
    If (Before &amp;gt; 0 And Before &amp;lt;= cbMainMenu.Controls.Count) Then
        intBeforeIndex = Before
    Else
        intBeforeIndex = cbMainMenu.Controls.Count
    End If

    &#039; Add &quot;My Menu&quot; to the Main Menu CommandBar, just before the last menu.
    &#039; Set a CommandBarControl variable to it
    Set mcbc = cbMainMenu.Controls.Add( _
        Type:=msoControlPopup, Before:=intBeforeIndex)
                     
    &#039; Set the menu control&#039;s caption to the provided name.
    mcbc.Caption = mstrName

    &#039; If all has gone well, return True
    AddMenu = True
End Function

Private Function DeleteMenu() As Boolean
    On Error Resume Next
   
    &#039; Initialize the function return value.
    DeleteMenu = False
   
    &#039; Remove the menu added earlier.
    Application.CommandBars(&quot;Worksheet Menu Bar&quot;).Controls(mstrName).Delete

    DeleteMenu = True
End Function</pre>
<p>As for the implementation, you could do something like this to get the same affect as Ron&#8217;s Example 2 (above):</p>
<pre class="brush: vb">Option Explicit

Const RibbonxAddin As String = &quot;HasRibbonX.xlam&quot;
Private menu As CustomMenu

Private Sub Workbook_Open()

    Set menu = New CustomMenu

    menu.Name = &quot;Test Tab&quot;
    menu.RibbonxPath = ThisWorkbook.Path    &#039; Default
    menu.RibbonxName = RibbonxAddin
    menu.Attach
    menu.AddItem &quot;A&quot;, &quot;BtnA&quot;
    menu.AddItem &quot;B&quot;, &quot;BtnB&quot;
    menu.AddItem &quot;C&quot;, &quot;BtnC&quot;
End Sub

Private Sub Workbook_BeforeClose(Cancel As Boolean)
    menu.Detach
   
    Set menu = Nothing
End Sub

Sub OnActionCall(MenuItem As Variant)
    menu.OnActionCall MenuItem
End Sub</pre>
<p>Using this approach, you&#8217;ll be able to add in your custom menu/ribbon for all users of your custom Office development.</p>
]]></content:encoded>
			<wfw:commentRss>http://wizardsofsmart.net/samples/future-proofing-office-2003-custom-menu-development/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
