How to handle events from embedded Excel.OleObjects or Excel.Shapes
Have you tried using NewLateBinding.LateGet?
using MSForms = Microsoft.Vbe.Interop.Forms;using Microsoft.VisualBasic.CompilerServices;...MSForms.CommandButton CommandButton1 = (MSForms.CommandButton)NewLateBinding.LateGet(Globals.ThisWorkbook.Worksheets(1), null, "CommandButton1", new object[0], null, null, null); CommandButton1.Click += new Microsoft.Vbe.Interop.Forms.CommandButtonEvents_ClickEventHandler(CommandButton1_Click);
It's referenced on MSDN in the VSTO forums and in an old blog post.
Solution Type: VSTO Document-Level
Scenario:
1.) Excel.Worksheet created at run-time. (not a Worksheet Host Item)
2.) Add a button on the Worksheet at run-time that triggers C# code when clicked.
Assembly References:
Microsoft.Vbe.Interop (Microsoft.Vbe.Interop.dll)
Microsoft.Vbe.Interop.Forms (Microsoft.Vbe.Interop.Forms.dll)
Microsoft.VisualBasic (Microsoft.VisualBasic.dll)
Tested / Working Code:
using MSForms = Microsoft.Vbe.Interop.Forms;using System.Windows.Forms;...Microsoft.Vbe.Interop.Forms.CommandButton CmdBtn;private void CreateOLEButton(){ Excel.Worksheet ws = Globals.ThisWorkbook.Application.Sheets["MyWorksheet"]; // insert button shape Excel.Shape cmdButton = ws.Shapes.AddOLEObject("Forms.CommandButton.1", Type.Missing, false, false, Type.Missing, Type.Missing, Type.Missing, 500, 5, 100, 60); cmdButton.Name = "btnButton"; // bind it and wire it up CmdBtn = (Microsoft.Vbe.Interop.Forms.CommandButton)Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateGet(ws, null, "btnButton", new object[0], null, null, null); CmdBtn.Caption = "Click me!"; CmdBtn.Click += new MSForms.CommandButtonEvents_ClickEventHandler(ExecuteCmd_Click);}private void ExecuteCmd_Click(){ MessageBox.Show("Click");}
Can you programmatically add code to a CodeModule in the Workbook, like this?
Private Sub CommonButton_Click(ByVal buttonName As String) MsgBox "You clicked button [" & buttonName & "]"End SubPrivate Sub CreateEventHandler(ByVal buttonName As String) Dim VBComp As VBIDE.VBComponent Dim CodeMod As VBIDE.CodeModule Dim codeText As String Dim LineNum As Long Set VBComp = ThisWorkbook.VBProject.VBComponents(Me.CodeName) Set CodeMod = VBComp.CodeModule LineNum = CodeMod.CountOfLines + 1 codeText = codeText & "Private Sub " & buttonName & "_Click()" & vbCrLf codeText = codeText & " Dim buttonName As String" & vbCrLf codeText = codeText & " buttonName = """ & buttonName & "" & vbCrLf codeText = codeText & " CommonButton_Click buttonName" & vbCrLf codeText = codeText & "End Sub" CodeMod.InsertLines LineNum, codeTextEnd Sub