Tuesday, November 20, 2018   
  Search  
 
Register  Login  
Projects » .NET » VS2010 - Early-Late Binding in VB.NET + Excel  
   Download Minimize  
     
  
   Early-Late Binding with Excel (VB.NET/C#) - VS2017 Minimize  

ENGLISH

In developing applications that interfere with Office applications, the programmer has always been confronted with the classic versioning problem.

So the dilemma was: I use late-binding or early-binding?

Let's see what differences involve the use of one or the other approach:

Comparison late binding vs early binding
  Late Early
Advantages Work with any version Intellisense available
Disadvantages Intellisense not available Work only with referenced version
     

 As we can see, neither of them fully meets the developer, who is in any case forced to choose Late-binding (using CreateObject() API function), to make sure that his programs, once deployed, will works with any version of Office installed.

Unfortunately, because of this, it is forced to give up the functionality of the intellisense, which would be very useful for quickly accessing the object model made available from the referenced Office Library (Excel, Word, and so on).

Often (too often) are found in the web solutions that mix both binding methods (which obviously do not work or work badly) and this tends to confuse even more the ideas of those who approach for the first time to these problems.

In this article, I will explain how it is possible to use both modes when needed.
That is: use the Early-Binding when working in the integrated environment of VB.NET (IDE), but that once compiled, and without any modification to the project, the program uses the Late-Binding, which means that it will work with any version of Excel.

In practice this means getting the two advantages and eliminating the disadvantages of both methods. I would say it's not bad.

The trick (if we want to call it that) is to exploit a feature of VB.NET that is found in the Advanced Compiler Settings accessible from the homonymous property button of the project and called Compilation constants.

The image below shows how to.
Sorry, I have italian version of Visual Studio, but you should be able to understand how to in your IDE.

Advanced compilation options

Compilation constants are really useful because they allow you to compile certain instructions only based on their value. This is made possible thanks to the directives:

#If ... Then ... #Else

Looking at the image above you notice that I defined the Custom Constant:

EarlyBinding = 1

in this way I can decide which instructions will be used depending on the value of EarlyBinding, and in this specific case I will be able to use the directives like this:

 

Public Class Form1

#If EarlyBinding = 1 Then
    Dim excelApp As Microsoft.Office.Interop.Excel.Application
    Dim excelWorkbook As Microsoft.Office.Interop.Excel.Workbook
    Dim excelWorksheet As Microsoft.Office.Interop.Excel.Worksheet
    Dim excelRange As Microsoft.Office.Interop.Excel.Range
#Else
    Dim excelApp As Object
    Dim excelWorkbook As Object
    Dim excelWorksheet As Object
    Dim excelRange As Object
#End If


#If EarlyBinding = 1 Then
    excelApp = New Microsoft.Office.Interop.Excel.
Application
#Else
   
excelApp = CreateObject("Excel.Application")
#End If

 

You will notice that in the ID of VB.NET the code of one of the two parts will be displayed in gray depending on the mode set, DEBUG or RELEASE demonstrating which instructions will be executed.

Observing the code, it is clear that EarlyBinding cutom constant can contain the value 1 only when I will run the project in the IDE of VB.NET or in DEBUG mode, while once the project is completed in RELEASE mode, since there is no more IDE that set it, will always contain the value 0.

This will ensure that by executing the project in the IDE of VB.NET (or in Debug) the typed declarations will be used, while once the executable is compiled (Release) the other declarations 'As Object' will be used.

To confirm of this, I have included in the Load () event of sample project a message that displays the execution mode:


#If EarlyBinding = 1 Then
    MessageBox.Show("EarlyBinding=1 - We are in Debug mode")
#Else
   
MessageBox.Show("EarlyBinding=0 - We are in Release mode")
#End If

 

Alternating the mode from Debug to Release (thanks to the convenient combobox on the VS2010 toolbar) you will see a different message appear.

As I stated above, in addition to the advantage of being able to continue to exploit the intellisense in the IDE there will no longer be the problem of versioning because thanks to the statements 'As Object' there is no control over the version of Office.

 

Issues

However, this highlights two issues that must not be neglected:

1) The first concerns the fact that by not using typed declarations the code can not be considered completely safe as there is no certainty that the methods and properties used are present in the installed version of Office.
This forces us to make sure we use methods and properties that are available in all versions.
But, usually, at least in the vast majority of cases it is so.
However, if you want, you can always check which version of the Office application is running on your computer and decide what to do depending on this information.

Just query the property: excelApp.Version

2) The second question is inherent to the intrinsic constants of the specific application (Excel, Outlook, Word, and so on ...) that obviously will no longer be available in the version compiled in Release mode, so we will have to pay attention to explicitly declare all the constants used in our project, otherwise running in Release will report an error every time it fails to resolve the value:

Const xlCenter = -4108  ' Member of Excel.Constants
Const xlJustify = -4130
Const xlLeft = -4131
Const xlRight = -4152


Personally I strongly discourage the use of numbers instead of constants.


Conclusion

This technique is very powerful and can also be applied to other libraries, so not only to Office applications, as long as they expose an accessible object model.

To conclude, it is useful to know that the sample project does a rather simple job: through an OpenFileDialog it allows the user to open any Excel file and load the contents of the first sheet in a DataGridView and then close the Excel instance.

The peculiarity is that in the project I show how you can open Excel files of any version including those of Office 2007/2010.
For those who do not have Office 2007/2010 but want to open Excel file of this version will have to install the appropriate driver:

2007 Office System Driver: Data Connectivity Components
http://www.microsoft.com/downloads/details.aspx?displaylang=it&FamilyID=7554f536-8c28-4598-9b72-ef94e038c891

 

 


     
  
   VS2010 - Early-Late Binding in VB.NET con Excel Minimize  

 

ITALIANO

Nello sviluppo di applicazioni che si interfacciano con gli applicativi Office il programmatore si è sempre trovato davanti al classico dubbio: usare l'Early-Binding (associazione preventiva) oppure il Late-binding (associazione tardiva)?

Il problema, arci noto, è che se si usa il Late-Binding, ovvero usando la funzione CreateObject(), si perde la caratteristica dell'Intellisense (che non è poca cosa), ma si ha il vantaggio che il programma distribuito funzionerà su qualsiasi computer indipendentemente da quale versione di Office sia installata.

Al contrario, se si usa l'Early-Binding, si avrà a disposizione l'intellisense, ma il programma funzionerà solo quando la versione di Office installata è la stessa con cui è stato progettata l'applicazione.

Spesso (troppo spesso) si trovano nei forum le classiche (anche quelle) castronate in cui vengono mescolate entrambe le modalità di binding (che ovviamente non funzionano o funzionano male) e ciò tende ad confondere ancor più le idee di chi si approccia per la prima volta a queste problematiche.

In questo articolo spiegherò allora come sia possibile fare in modo di poter entrambe le modalità quando servono!
Cioè: usare l'Early-Binding quando si lavora nell'ambiente integrato di VB.NET (IDE), ma che una volta compilato, e senza alcuna modifica al progetto, il programma utilizzi il Late-Binding.

Tutto questo, in pratica, significa ottenere i due vantaggi ed eliminare gli svantaggi di entrambi i metodi.
Direi non male...

Passiamo al 'sodo'.

Il trucco (se vogliamo chiamarlo così) sta nello sfruttare una caratteristica di VB.NET che si trova nelle
Opzioni di compilazione avanzate accessibili dall'omonimo pulsante delle Proprietà del progetto e che si chiama
Costanti di compilazione:

 

Le costanti di compilazione sono davvero utili perchè consentono di compilare determinate istruzioni solo in base al valore di tali costanti. Ciò è reso possibile grazie alle direttive:

#If ... Then ... #Else

Osservando l'immagine sopra si nota che ho definito la costante condizionale:

EarlyBinding = 1

in questo modo posso decidere quali istruzioni saranno utilizzate a seconda del valore di EarlyBinding, e nel caso speciifico potrò utilizzare le direttive così:

Public Class Form1

#If EarlyBinding = 1 Then
    Dim excelApp As Microsoft.Office.Interop.Excel.Application
    Dim excelWorkbook As Microsoft.Office.Interop.Excel.Workbook
    Dim excelWorksheet As Microsoft.Office.Interop.Excel.Worksheet
    Dim excelRange As Microsoft.Office.Interop.Excel.Range
#Else
    Dim excelApp As Object
    Dim excelWorkbook As Object
    Dim excelWorksheet As Object
    Dim excelRange As Object
#End If


#If EarlyBinding = 1 Then
    excelApp = New Microsoft.Office.Interop.Excel.
Application
#Else
   
excelApp = CreateObject("Excel.Application")
#End If

Noterete che nell'IDE di VB.NET il codice di una delle due parti sarà visualizzato in grigio a seconda della modalità impostata, Debug o Release a dimostrazione di quali istruzioni saranno eseguite. 

Osservando il codice, è lampante che EarlyBinding potrà contenere il valore 1 solo quando eseguirò il progetto nell'IDE di VB.NET oppure in modalità di Debug, mentre una volta compilato il progetto in modalità Release, dato che non c'è più l'IDE che la valorizza, conterrà sempre il valore 0.

Questo farà sì che eseguendo il progetto nell'IDE di VB.NET (o in Debug) saranno usate le dichiarazioni tipizzate, mentre una volta compilato l'eseguibile (Release) saranno usate le altre dichiarazioni 'As Object'.

A conferma di ciò, ho previsto nell'evento Load() del progetto di esempio un messaggio che visualizza la modalità di esecuzione:  

#If EarlyBinding = 1 Then
    MessageBox.Show("EarlyBinding=1 - Siamo in Debug")
#Else
   
MessageBox.Show("EarlyBinding=0 - Siamo in Release")
#End If

Alternando la modalità da Debug a Release (grazie al comodo combobox sulla toolbar di VS2010) si vedrà apparire un messaggio differente.

Come affermavo più sopra, oltre al vantaggio di poter continuare a sfruttare l'intellisense nell'IDE non vi sarà più il problema di versioning perchè proprio grazie alle dichiarazioni 'As Object' non esiste alcun controllo sulla versione di Office.

Questo però pone in evidenza due questioni che non bisogna assolutamente trascurare:

1) La prima riguarda il fatto che non usando dichiarazioni tipizzate il codice non può essere considerato completamente safe in quanto non esiste certezza che metodi e proprietà utilizzati siano presenti nella versione installata di Office.
Ciò costringe ad assicurarci di utilizzare metodi e proprietà che siano disponibili in tutte le versioni.
Ma, di solito, almeno nella stragrande maggioranza dei casi è così.
Comunque, volendo, è sempre possibile verificare quale versione dell'applicazione Office è in esecuzione sul computer e decidere il da farsi a seconda di questa informazione.

excelApp.Version

2) La seconda questione è inerente alle costanti intrinseche dell'applicazione specifica (Excel, Outlook, Word, e così via...) che ovviamente non saranno più disponibili nella versione compilata in modalità Release, quindi dovremo prestare attenzione a dichiarare esplicitamente tutte le costanti utilizzate nel nostro progetto, in caso contrario l'esecuzione in Release segnalerà un'errore ogni volta che non riesce a risolvere il valore.
Personalmente sconsiglio vivamente l'uso dei numeri al posto delle costanti.

Per concludere è utile sapere che il progetto di esempio fa un lavoro piuttosto semplice: tramite una OpenFileDialog consente all'utente di aprire un qualunque file Excel e di caricare il contenuto del primo foglio in un DataGridView e poi chiude l'istanza di Excel.

La particolarità è che nel progetto mostro come sia possibile aprire file Excel di qualunque versione inclusi quelli di Office 2007/2010.
Per chi non possiede Office 2007/2010 ma vuole aprire file Excel di questa versione dovrà installare il driver apposito:

Driver di Office System 2007: Data Connectivity Components
http://www.microsoft.com/downloads/details.aspx?displaylang=it&FamilyID=7554f536-8c28-4598-9b72-ef94e038c891

 

 

 

 

     
  
DotNetNuke® is copyright 2002-2018 by DotNetNuke Corporation