Press "Enter" to skip to content

Creare una Dll .Net utilizzabile dal VBA di Excel

Un post in risposta ad un quesito posto sul Forum Microsoft in cui un Temerario che ha la necessità di utilizzare delle funzioni .Net da dentro Excel chiedeva come mai non riusciva a vedere una libreria .Net da dentro a Excel.

Credo che l’ultima volta che ho usato questa cosa sia stato il 2005, poi, per mia fortuna ho potuto evitare l’interoperabilità, anche perché sono sempre maggiori i paletti inseriti all’interno degli strumenti office per paura della creazione di virus che possano danneggiare i computer.

Ad ogni modo, ho creato una libreria esempio, seguendo quanto esposto da chi ha fatto la domanda e ho verificato tutti gli step necessari a poterla utilizzare dentro al VBA di Excel.

solution_01

La DLL in .Net

Ho creato una soluzione di tipo Class Library, che ho chiamato ExcelVisible, non perché renda Excel visibile ma perché è visibile da Excel.

Al suo interno c’è una classe, che ho chiamato Helper che è la classe che utilizzeremo da VBA.

Ho poi creato una cartella excel con le macro, attivando la modalità Sviluppatore dalle opzioni di Excel e l’ho copiata nella cartella del progetto includendola utilizzando la funzione che mostra tutti i file della cartella di progetto e l’opzione include in project.

Una volta fatto, per fare in modo che il mio foglio di excel sia copiato nella cartella bin\Debug, ho modificato le property del file in questo modo:

excel_properties

Per fare in modo che la Dll prodotta dalla mia soluzione sia utilizzabile in interoperabilità COM ho fatto le seguenti cose:

signing

Per prima cosa ho firmato la DLL con un file a chiave doppia, che utilizzo anche per firmare tutti i progetti dotnetwork. Se non ne avete uno, la combobox dove si può sceglierlo è in grado di produrne uno utilizzando la funzione New come da immagine seguente:

createsnk

Ho modificato l’AssemblyInfo (dal Tab Application delle property di progetto) nel seguente modo.

assemblyinfo

In questo modo, l’assembly prodotto dal progetto, quindi la DLL è visibile da COM e oltre alla DLL sarà prodotto un file .TLB che sarà quello che useremo per referenziare la DLL dal VBA

L’ultima operazione da fare è fare in modo che l’assembly sia registrato per l’interoperabilità.

registerforcom

A questo punto la nostra DLL è pronta ad essere utilizzata, perciò scriviamo un po’ di codice:

namespace ExcelVisible
{
public class Helper
{


private int mLeftAddend;


internal int LeftAddend
{
get
{
return mLeftAddend;
}
set
{
mLeftAddend = value;
}
}



public const string FLD_RightAddend = "RightAddend";


private int mRightAddend;


internal int RightAddend
{
get
{
return mRightAddend;
}
set
{
mRightAddend = value;
}
}



public void SetLeftAddend(int Value)
{
LeftAddend = Value;
}

public void SetRightAddend(int Value)
{
RightAddend = Value;
}

public int SumValues()
{
return LeftAddend + RightAddend;
}

}
}

Ho creato 3 metodi pubblici, che saranno visibili da VBA, mentre le property sono Internal e non saranno visibili da VBA.

I tre metodi inseriscono dei dati nella classe e poi li usano per una somma restituendo un valore. Molto banale ma funzionante.

Ora se Compilando questa libreria vi venisse sollevato un messaggio di errore che dice “Can’t register assembly for com interop” o qualcosa di simile, vuol dire che come me state lavorando su Windows 10 e pure essendo Administrator della vostra macchina locale, avete lo UAC attivo, pertanto in realtà non siete Administrator di un bel niente.

Per fare in modo che la cosa funzioni, basta che lanciate visual studio come Administrator realmente. Trovate il link per farlo sullo start menu nella cartella di visual studio oppure, facendo tasto destro sulla Tile di Visual Studio nello Start menu trovate l’opzione sotto il menu “More” oppure se usate come me la toolbar del desktop facendo Tasto destro sul bottone di Visual Studio nel menu contestuale fate ancora tasto destro su Visual Studio 2015 (senza aprire una soluzione già mappata) e potete usare il Run as Administrator.

runasadmin

Dopo aver detto di si alla richiesta di conferma dello UAC, il vostro visual studio girerà effettivamente con utente Administrator e quindi sarà in grado di registrare la DLL per l’interoperabilità COM dopo la sua compilazione.

vsadministrator

Il vostro Visual Studio vi mostrerà di essere eseguito come Administrator scrivendolo sul titolo.

Il foglio di Excel

Ho aperto il la cartella di lavoro di Excel vuota che avevo creato prima e per prima cosa ho inserito nel foglio 1 della cartella un Active X Button.

activexbutton

Ho poi fatto doppio click sul Button e automaticamente mi è stata generata una Sub VBA che sarà eseguita sul click del button:

vba_onsheetone

Ho scritto una Function, Prova, che utilizza la nostra DLL .Net, ma per fare in modo di poterla usare, la prima cosa che ho dovuto fare è stata referenziarla nel progetto:

Questo si fa dal menu strumenti della finestra di VBA

referencedll

Utilizzando sfoglia per andare a cercare la cartella del nostro progetto e selezionare il file TLB, attenzione il TLB non la DLL perché il file TLB è quello che fa la magia di collegare .Net a Com.

Ora analizziamo il codice VBA:

Public Function Prova() As String


Dim test As New ExcelVisible.Helper
Dim result As Integer
Dim message As String

test.SetLeftAddend(10)

test.SetRightAddend (20)


result = test.SumValues()

message = "the value is " & result

MsgBox message

End Function

La cosa più importante da ricordarsi, per usare una classe .NET in un progetto COM è che la classe deve essere istanziata, pertanto dobbiamo utilizzare la New per creare il nostro oggetto di tipo Helper.

A questo punto i suoi metodi saranno visibili nell’intellisense ed il gioco è fatto.

Riepilogo

Cosa abbiamo visto in questo post:

  • Come si crea una Class Library in C#
  • Come si fa a renderla visibile all’interoperabilità COM
  • Come creare una semplice classe di test
  • Come eseguire Visual Studio come Administrator
  • Come creare un foglio Excel con l’attivazione delle macro VBA
  • Come creare un Button su un foglio di Excel
  • Come utilizzare una classe della nostra DLL .Net dentro ad una function VBA

 

Potete scaricare il progetto esempio dal link qui indicato:

Per qualsiasi domanda, osservazione, commento, approfondimento, o per segnalare un errore, potete usare il link alla form di contatto in cima alla pagina.