OLE object controls such as Command button, Checkbox, etc., allow us to call VBA code behind using OnAction property. However, when a situation arises that we have to call .Net code behind, we cannot use OnAction property, because this property requires a VBA macro to be assigned. In such situations, the option that we can immediately think of is to have VBA macro to call the .Net code, which is possible.
There are scenarios such as one where you want to upgrade your VBA add-in (XLA) to .Net COM/Automation add-in (with no VBA layer in between), which does not allow us to use OnAction property, then this blog post can help you. Because this option does not require us to have VBA layer in between and we can call C#.Net code directly.
I have illustrated this idea using an Excel COM add-in that inserts an OLE command button control on Application start up and I will use it to call its button click event written in C# code behind. To know how to build an Office COM add-in by using Visual C# .NET, please refer to the article, http://support.microsoft.com/kb/302901
Here are the steps:
using System; using Extensibility; using System.Runtime.InteropServices; using Excel = Microsoft.Office.Interop.Excel; using Office = Microsoft.Office.Core; using MSForms = Microsoft.Vbe.Interop.Forms; using Microsoft.VisualBasic.CompilerServices;
public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode, object addInInst, ref System.Array custom) { try { xlApp = (Excel.Application)application; wbs = xlApp.Workbooks; //Get the Workbooks collection wbs.Add(Type.Missing); //Add a new workbook wb = xlApp.ActiveWorkbook; wsht = (Excel.Worksheet)wb.ActiveSheet; //To insert an OLE Object which of type "CommandButton". We need to use the ProgID for the command button, which is "Forms.CommandButton.1" cmdButton = (Excel.Shape)wsht.Shapes.AddOLEObject("Forms.CommandButton.1", Type.Missing, false, false, Type.Missing, Type.Missing, Type.Missing, 200, 100, 100, 100); //We name the command button, we will use it later cmdButton.Name = "btnClick"; //In order to access the Command button object, we are using NewLateBinding class as below CmdBtn = (MSForms.CommandButton)NewLateBinding.LateGet((Excel.Worksheet)xlApp.ActiveSheet, null, "btnClick", new object[0], null, null, null); //Set the required properties for the command button CmdBtn.FontSize = 10; CmdBtn.FontBold = true; CmdBtn.Caption = "Click Me"; //Wiring up the Click event CmdBtn.Click += new Microsoft.Vbe.Interop.Forms.CommandButtonEvents_ClickEventHandler(CmdBtn_Click); } catch (Exception ex) { System.Windows.Forms.MessageBox.Show(ex.Message); } }
void CmdBtn_Click() { //Adding the event code System.Windows.Forms.MessageBox.Show("I am called from C# COM add-in"); wsht.get_Range("A1", "A10").Value2 = "I am called from C# Add-in"; }
(Note: on machines with Vista or later, you will need to launch Visual Studio in Administrator mode (To do that, right click Visual Studio Icon-->Run as Administrator), as Vista or later would not allow a program to modify registry entries, when UAC is turned on)