2010-10-13 6 views
6

Tengo el siguiente código en VBA (que reside en un libro de Excel 2007):¿Acceso a valor de retorno desde la función VBA en .NET?

Public Function Multiply(a As Double, b As Double) As Double 
    Multiply = a * b 
End Function 

Si invoco Multiplicar en otro código VBA, devuelve el valor correcto. Sin embargo, cuando llamo Multiplicar en C#:

var excel = new Application {Visible = true}; 
excel.Workbooks.Open(filename); 
var returned = excel.Run("Sheet1.Multiply", (Double) a, (Double) b); 

... la multiplicación se lleva a cabo (puedo verificar esto mediante la adición de rastreo para la función Multiplicar en VBA), pero el valor devuelto no está disponible en mi código C# ; returned es siempre null.

¿Podría alguien decirme cómo obtener el valor de retorno de Multiply de mi código C#?

+0

He podido evitar esto modificando Multiply() para establecer el valor de una celda en el valor de retorno y leyendo el valor de esa celda desde C#. Feo, pero funciona. –

+0

¿Alguna idea de por qué funciona desde un módulo pero no desde la hoja? – anakic

+0

Ninguno Tengo miedo. De hecho, no he hecho ningún trabajo significativo en Microsoft desde 2011, por lo que probablemente no responda a menos que alguien más pueda ayudar ... –

Respuesta

4

Ha intentado mover su función a un módulo regular en Excel (no es un módulo de hoja)?

+0

Creé un nuevo módulo, moví la función a eso y cambié "Sheet1.Multiply" a "MyModule.Multiply". Funcionó a la perfección, gracias :-) Solo una pregunta: ¿fue esta una idea que obtuviste a través de la experiencia o está documentada en alguna parte? La información en MSDN, etc. es bastante escasa para llamar a VBA. interoperacion –

+0

@DuncanBayne 'Sheet1' es un * objeto *, una * instancia * de una clase' Worksheet'. Para llamar a miembros de una clase, necesita una instancia, y la instancia 'Sheet1' solo vive en el tiempo de ejecución de VBA, .net no la ve. Los módulos estándar son solo eso: módulos de procedimientos que exponen código ejecutable a través de miembros públicos; no necesita (no podría de todos modos) * instanciarlo para llamar a sus miembros. Es por eso que funciona en 'Module1' y no en' Sheet1'. –

-4

Intente modificar su función Multiply para ser como el código de abajo:

Public Function Multiply(a As Double, b As Double) As Double 
    return a * b 
End Function 
+0

Eso ni siquiera es válido VBA. Consulte: http://office.microsoft.com/en-in/excel-help/create-custom-functions-in-excel-2007-HA010218996.aspx –

+1

No puede usar la palabra clave return en VBA; necesita establecer el valor de retorno para el nombre de la función, por ejemplo Multiplicar = a * b, que estaba en la pregunta original. – Jazza

+0

Esto es VB.Net, no VBA. – Icemanind

0

Un ejemplo sencillo:

La prueba spreadsheet.xlsm tiene Module1 que contiene:

Public Function test() As String 
    test = "hello 1234" 
End Function 

Con objExcel ya establecido en la hoja de cálculo ...

Dim result = objExcel.Run("Module1.test") 
MsgBox(result) 

... produce hello 1234 en el mensaje emergente.

Porque había probado inicialmente con este ? module1.test()(con éxito) en la ventana Inmediato VBA, que estaba inicialmente tratando de conseguir objExcel.Run("Module1.test()") para trabajar - pero que estaba recibiendo un error: Cannot run the macro .... The macro may not be available in this workbook or all macros may be disabled. - eliminación de los corchetes resolvieron el problema.

Cuestiones relacionadas