Friday, May 18, 2012   
  Search  
 
Register  Login  
Articoli » VB 6.0 » Early-Late Binding  
   Download Minimize  
     
  
   Early-Late Binding - esempio con Outlook Minimize  

Early-Late Binding con Outlook

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)?

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) e ciò tende ad confondere ancor più le idee del neofita.

Per chi non ha ben presente l'argomento suggerisco la lettura di un breve ma conciso articolo sulle differenze tra le due modalità di associazione ad opera di @Alex: http://forum.masterdrive.it/vba-tutorials-and-how-to-37/latebinding-vs-earlybinding-46733/
Anche se lui si riferisce al solo VBA, il concetto è esattamente uguale. Solo che VB6, come vedremo, mette a disposizione un qualcosa in poù che consente di risolvere il problema in modo elegante.

In questo articolo, invece, spiegherò come sia possibile fare in modo di poter usare l'Early-Binding quando si lavora nell'ambiente integrato di VB6 (IDE), ma nello stesso tempo, senza alcuna modifica al progetto, venga poi eseguito a run-time utilizzando il Late-Binding.

Come esempio, prenderemo l'automazione con Outlook, ma il concetto vale per qualsiasi altra applicazione di Office che esponga il relativo modello ad oggetti.

Prima di tutto, assicuriamoci di aggiungere il riferimento alla libreria di Outlook al nostro progetto. Nel mio caso, avendo Office 2007, sarà la versione 12.0

Nota importante: non importa quale versione usiate voi, e non importa quale versione ha l'utente finale.
Non importa semplicemente perchè tale libreria sarà utilizzata solo all'interno dell'IDE di VB6. Quando il programma sarà eseguito sul computer dell'utente, userà quella presente.

Infatti, come vedremo tra poco, il programma utilizzerà l'Early-Binding quando è eseguito nell'IDE, mentre quando sarà eseguito nella versione compilata userà automaticamente il Late-Binding.

Il bello è che ciò sarà possibile senza che lo sviluppatore debba modificare il proprio progetto!

Ricordo infatti che di solito si usa(va) utilizzare l'Early-Binding in fase di sviluppo con il vantaggio di avere disponibile il modello ad oggetti esposto dall'applicativo Office, intellisense incluso, ma poi al momento della compilazione si dovevano commentare le righe delle dichiarazioni che si riferivano direttamente alla libreria referenziata, rimuovere il riferimento alla libreria stessa, ed utilizzare CreateObject(...); poi si doveva rimettere tutto a posto per eventuali sviluppi futuri del progetto.
Tutt'altro che piacevole...

Ora dobbiamo predisporre il progetto affinchè possa distinguere la modalità di esecuzione sfruttando un argomento di compilazione condizionale.
Apriamo le Proprietà del progetto e nella scheda Crea inseriamo l'assegnazione EarlyBinding = 1 come mostrato in figura:

  

Bene, adesso iniziamo a scrivere il codice in modo da sfruttare l'argomento di compilazione condizionale.
Apriamo la finestra del codice del nostro form, e nella sezione delle Dichiarazioni inseriamo il codice

Rem ------------------------------------------------------------
Rem Dichiarazione condizionale degli oggetti in funzione di come
Rem sarà eseguito il programma (dall'IDE di VB o dall'EXE)
Rem ------------------------------------------------------------
#If EarlyBinding = 1 Then
    Rem VB IDE

    Rem OUTLOOK
    Dim myOlApp         As Outlook.Application
    Dim myNameSpace     As Outlook.NameSpace

    Rem CONTACT
    Dim myContacts      As Outlook.Items
    Dim myItem          As Outlook.ContactItem

    Rem APPOINTMENT
    Dim myAppointments  As Outlook.Items
    Dim myRestrictItems As Outlook.Items
    Dim myAppItem       As Outlook.AppointmentItem

    Rem Used both for CONTACTS and APPOINTMENTS
    Dim objItems        As Outlook.ItemProperties
    Dim objItem         As Outlook.ItemProperty
#Else
    Rem EXE stand alone

    Rem OUTLOOK
    Dim myOlApp         As Object 'Outlook.Application
    Dim myNameSpace     As Object 'Outlook.NameSpace

    Rem CONTACT
    Dim myContacts      As Object 'Outlook.Items
    Dim myItem          As Object 'Outlook.ContactItem

    Rem APPOINTMENT
    Dim myAppointments  As Object 'Outlook.Items
    Dim myRestrictItems As Object 'Outlook.Items
    Dim myAppItem       As Object 'Outlook.AppointmentItem

    Rem Used both for CONTACTS and APPOINTMENTS
    Dim objItems        As Object 'Outlook.ItemProperties
    Dim objItem         As Object 'Outlook.ItemProperty
#End If

Come vedete abbiamo inserito delle doppie dichiarazioni che saranno utilizzate, le une o le altre, a seconda della valore indicato alla riga
#If EarlyBinding = 1 Then

Ora, dato che noi abbiamo impostato questo valore su 1 (figura 1) sarà utilizzata la modalità Early-Binding.
Ciò ci permetterà di sfruttare comodamente l'intellisense di VB6 quindi avere sotto mano tutti gli oggetti e metodi di Outlook e relativa sintassi digitando il punto dopo la nostra variabile oggetto myOlApp:

myOlApp.

Probabilmente avete già capito: quando il progetto sarà compilato ed eseguito stand-alone il valore di EarlyBinding sarà sempre 0 (perchè non c'è più l'IDE di VB6 a valorizzarla in automatico) per cui le variabili oggetto dichiarate saranno quelle As Object.

Addesso occorre un secondo passo: dopo averle dichiarate occorre istanziarle in modo corretto. per cui nell'evento Form_Load() faremo più o meno la stessa cosa, ma questa volta useremo una proprietà dell'oggetto Application: App.LogMode

Private Sub Form_Load()

    If App.LogMode = 1 Then ' sta eseguendo l'EXE (compilato)
        ' uso il Late-Binding

        Set myOlApp = CreateObject("Outlook.Application")
    Else ' sta eseguendo il progetto nell'IDE
        ' uso l'Early-Binding

        Set myOlApp = Outlook.Application
    End If

    ' se sul computer non esiste Outlook avvio la chiusura del form
    If myOlApp Is Nothing Then
        GoTo OUTLOOK_NOT_FOUND
    End If

    ' Outlook esiste, per cui posso istanziare anche gli altri oggetti.
    Set myNameSpace = myOlApp.GetNamespace("MAPI")

    Set myAppointments = myNameSpace.GetDefaultFolder(olFolderCalendar).Items
    Set myContacts = myNameSpace.GetDefaultFolder(olFolderContacts).Items


    Exit Sub

OUTLOOK_NOT_FOUND:
    Timer1.Enabled = False ' Esce dall'applicazione
End Sub

Come vedete, non è poi così difficile.

Il vantaggio di non dover modificare niente per 'commutare' tra le due modalità (early e late) non è di poco conto per lo sviluppatore che in pratica non deve curarsi di nulla, se non quella di migliorare la propria applicazione.

A questo punto può essere spontaneo domandarsi se lasciare attivo il riferimento alla libreria di Outlook 2007 (v.12.0) non crei problemi nel caso si esegua il programma su un computer in cui è installata una versione diversa.
No, non crea alcun problema per il semplice fatto che nell'eseguibile l'oggetto Outlook.Application non sarà né dichiarato, né istanziato direttamente ma sempre e solo tramite la CreateObject().

Ultima nota importante: le costanti esposte da Outlook.
Quando il programma sarà compilato (EXE) le costanti di Outlook non sono più visibili perchè esse sono legate direttamente all'oggetto referenziato della libreria nel progetto. 
Ovviamente, non essendoci più un riferimento esplicito a tale libreria il programma eseguibile non è in grado di accedervi, per cui è assolutamente necessario dichiarare nel progetto tutte le costanti utilizzate. Esempio:

Rem Outlook constants:
Public Const olMailItem = 0
Public Const olAppointmentItem = 1
Public Const olContactItem = 2
Public Const olTaskItem = 3
Public Const olJournalItem = 4
Public Const olNoteItem = 5
Public Const olPostItem = 6
Public Const olDistributionListItem = 7
Public Const olFolderDeletedItems = 3
Public Const olFolderOutbox = 4
Public Const olFolderSentMail = 5
Public Const olFolderInbox = 6
Public Const olFolderCalendar = 9
Public Const olFolderContacts = 10
Public Const olFolderJournal = 11
Public Const olFolderNotes = 12
Public Const olFolderTasks = 13
Public Const olFolderDrafts = 16

Sarebbe superfluo farlo, ma ricordo che le costanti devono essere sempre accessibili (scope) quindi consiglio di dichiararle Public in un modulo BAS, oppure impostare un enumerazione, oppure creare una classe, fate voi;
l'importante è che siano sempre accessibili altrimenti quando eseguite il programma compilato i risultati saranno inaspettati.

 

 

     
  
DotNetNuke® is copyright 2002-2012 by DotNetNuke Corporation