2010-10-13 8 views
6

Ho il seguente codice VBA (che risiede in una cartella di lavoro di Excel 2007):Valore di ritorno di accesso dalla funzione VBA in .NET?

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

Se invoco Moltiplicare da altro codice VBA, restituisce il valore corretto. Tuttavia, quando chiamo Moltiplicare da C#:

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

... la moltiplicazione avviene (posso verificare questo con l'aggiunta di analisi per la funzione Multiply in VBA), ma il valore restituito non è disponibile nel mio codice C# ; returned è sempre null.

Qualcuno potrebbe dirmi come ottenere il valore restituito di Multiply dal mio codice C#?

+0

Sono stato in grado di aggirare questo problema modificando Multiply() per impostare il valore di una cella sul valore restituito e leggendo il valore di tale cella da C#. Brutto ma funziona. –

+0

Qualche idea sul perché funzioni da un modulo ma non dal foglio? – anakic

+0

Nessuno, ho paura. In realtà, non ho fatto alcun lavoro significativo su Microsoft dal 2011, quindi probabilmente questo non avrà una risposta a meno che qualcun altro là fuori possa aiutare ... –

risposta

4

Hai provato spostando la funzione di un modulo regolare in Excel (non un modulo foglio)?

+0

Ho creato un nuovo modulo, spostato la funzione e modificato "Sheet1.Multiply" in "MyModule.Multiply". Ha funzionato perfettamente, grazie :-) Solo una domanda: è stata un'idea che hai acquisito attraverso l'esperienza, o è effettivamente documentata da qualche parte? Le informazioni su MSDN ecc. Sono piuttosto scarse per chiamare VBA via. Interop. –

+0

@DuncanBayne 'Sheet1' è un * oggetto *, un * istanza * di una classe' Worksheet'. Per chiamare i membri di una classe, hai bisogno di un'istanza - e l'istanza di 'Sheet1' vive solo nel runtime VBA, .net non la vede. I moduli standard sono proprio questo: moduli procedurali che espongono il codice eseguibile attraverso membri pubblici; non hai bisogno (non puoi comunque) di * istanziare * per chiamare i suoi membri. Ecco perché funziona in 'Module1' e non in' Sheet1'. –

-4

Provate a modificare la funzione Multiply di essere come il codice qui sotto:

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

Non è nemmeno un VBA valido. Vedi: http://office.microsoft.com/en-in/excel-help/create-custom-functions-in-excel-2007-HA010218996.aspx –

+1

Non è possibile utilizzare la parola chiave return in VBA - è necessario imposta il valore di ritorno sul nome della funzione es Moltiplicare = a * b, che era nella domanda originale. – Jazza

+0

Questo è VB.Net, non VBA. – Icemanind

0

Un semplice esempio:

Il test spreadsheet.xlsm ha Module1 contenente:

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

Con objExcel già impostato sul foglio ...

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

... produce hello 1234 nel messaggio pop-up.

Perché avevo inizialmente provato questo con ? module1.test()(con successo) nella finestra Immediata VBA, stavo cercando di ottenere inizialmente objExcel.Run("Module1.test()") al lavoro - ma mi è stato sempre un errore: Cannot run the macro .... The macro may not be available in this workbook or all macros may be disabled. - rimuovere le staffe fatto il trucco.