Esporre la funzionalità VSTO a VBA senza admin locale
Domanda
Quale sarebbe il modo migliore per esporre determinate funzionalità in un componente aggiuntivo Dotnet VSTO Excel a VBA, senza richiedere all'utente di essere un amministratore locale (ovvero nessuna registrazione COM, no HttpListener )? Sarebbe possibile utilizzare Microsoft Message Queues da VBA?
Soluzione
Se posso interpretare la tua domanda in modo ampio come " Come posso esporre la funzionalità in un assembly .Net ad Excel senza registrazione COM " allora un'ottima soluzione è usare l'interfaccia XLL di Excel. Fondamentalmente si distribuisce uno spessore xll e una dll .Net associata. Quando la xll viene caricata, si riflette sulla dll ed espone le funzioni in essa contenute in Excel.
Un'implementazione open source è disponibile qui http: //exceldna.typepad .com / blog / 2006/01 / introducing_exc.html
Uno commerciale, di origine chiusa, ma più ricco di funzionalità qui http://www.managedxll.com/
Altri suggerimenti
Non puoi semplicemente istanziarli come oggetti COM, poiché VSTO non sarà in esecuzione nel dominio dell'applicazione predefinito.
Ecco come l'ho fatto, che è certamente un po 'contorto. Questo avveniva con una cartella di lavoro VSTO salvata come file XLA, che per certi versi è più flessibile di un semplice componente aggiuntivo VSTO.
-
Devi generare una libreria di tipi usando regasm.exe a cui farà riferimento il tuo codice VBA.
-
Crea una classe factory radice nel tuo modello di oggetti .NET, che è in grado di creare un'istanza di una delle classi che vuoi consumare in VBA (qualcosa come la classe "Applicazione" nei modelli di oggetti di Office).
-
È quindi necessario trovare un modo per passare un riferimento a un'istanza di questa classe di fabbrica a VBA. Una volta che VBA ha un riferimento a un'istanza di questa classe factory, può chiamare i suoi metodi per creare un'istanza di qualsiasi altro oggetto nel modello a oggetti .NET.
-
Per passare un'istanza a VBA, definisci una macro nel tuo codice VBA come segue
Codice di esempio:
Private m_objMyFactory As Object
Public Sub RegisterFactory(MyFactory As Object)
On Error GoTo ErrHandler
Set m_objMyFactory = MyFactory
Exit Sub
ErrHandler:
MsgBox "An unexpected error occurred when registering the Factory component: " & Err.Description
Exit Sub
End Sub
- Ora aggiungi il codice al gestore eventi VSTO ThisWorkbook_Open, che crea un'istanza dell'oggetto factory e chiama la macro sopra passando un riferimento all'oggetto factory.
Codice di esempio:
void ThisWorkbook_Open()
{
try
{
ThisApplication.Run("RegisterFactory",
new MyNamespace.MyFactory(),
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing);
}
catch (Exception ex)
{
MessageBox.Show("Load error: " + ex.ToString());
}
}
Ci sono alcuni altri problemi da considerare per farlo funzionare in modo efficace - se sei interessato a seguirlo fammelo sapere e posterò maggiori dettagli.
Potresti essere interessato a Excel4Net (è simile a ExcelDNA e ManagedXll, ma più facile da usare):
sito web: http://www.excel4net.com
Solo come riferimento per i futuri lettori: potresti anche dare un'occhiata a questa domanda:
Accesso a un'applicazione VSTO-tipi di componenti aggiuntivi da VBA (Excel )
e, in particolare, al blog a cui si fa riferimento lì:
Componenti aggiuntivi VSTO, COMAddIns e RequestComAddInAutomationService
Sovrascrivendo RequestComAddInAutomationService () è possibile esporre qualsiasi funzionalità desiderata, definendo una classe Facade che fornisce punti di ingresso per tutte quelle funzionalità ed esponendo tale classe a VBA.