Estaba tratando de crear un botón de Excel en una hoja a partir de un código de C# , utilizando un controlador de eventos de C# para el botón, por lo que no tengo que involucrar VBA ni secuencias de comandos de texto; y encontré esta gran solución de @Dummy yoyo que funciona pero "solo por un tiempo".
La solución es simple: agregue una forma, consígala como un objeto ole, obtenga el ole como un botón y agregue un evento de clic:
int i = 1; private void CreateButton() { Microsoft.Office.Interop.Excel.Worksheet sheet = #get a sheet from Excel sheet.Shapes.AddOLEObject("Forms.CommandButton.1", Type.Missing, false, false, Type.Missing, Type.Missing, Type.Missing, 10, 10, 100, 30); Microsoft.Office.Interop.Excel.OLEObject oleShape = sheet.OLEObjects(1); Microsoft.Vbe.Interop.Forms.CommandButton button = oleShape.Object; button.Caption = "Custom Buttom" + i; button.Click += Button_Click; i++; //for future use, see below } private void Button_Click() { MessageBox.Show("It works!"); }Ahora, la primera vez que hago clic en el botón de la hoja, ¡funciona! La segunda vez "podría" funcionar. Cuantos más clics, menos posibilidades de que funcione. Inevitablemente, el botón "pierde" el evento de clic y simplemente no hace nada . No puedo entender por qué, qué puede estar causando esto.
Incluso traté de recrear el botón cada clic con:
private void Button_Click() { MessageBox.Show("It Works!"); sheet.Shapes.Item(1).Delete(); CreateButton(); } Puedo ver que el botón se está recreando debido al i++ que se muestra en el título del botón. Aunque, algunos clics más tarde, incluso el botón recién creado simplemente no hace nada cuando se hace clic.
¿Qué puede estar pasando? ¿Como puedo resolver esto?
Editar:
Se encontró una solución parcial, como sugirió @Hans Passant : si mantengo la forma, el objeto ole y el botón como miembros estáticos fuera del método, el recolector de basura no los elimina. Sin embargo, me gustaría guardar, cerrar y volver a abrir la hoja y seguir obteniendo los eventos.
Grandes soluciones podrían ser:
Algunos detalles más:
Globals.Factory , aunque me encantaría poder obtener una instancia de esta fábrica y probar los métodos de Microsoft.Office.Tools.Worksheet para agregar controles.