Newsgroup: it.comp.appl.access
Titolo: CreateObject e associazioni Tardive

Non ho mai approfondito l'utilizzo di CreateObject per creare "associazioni
tardive".
Ecco il classico esempio dall'help di Access.
' Dichiara una variabile oggetto che conterrà il
' riferimento all'oggetto. La dichiarazione Dim As
' Object causa un'associazione tardiva.
Dim ExcelSheet As Object
Set ExcelSheet = CreateObject("Excel.Sheet")
' Rende visibile Excel tramite l'oggetto Application
ExcelSheet.Application.Visible = True
' Inserisce del testo nella prima cella del foglio
ExcelSheet.Cells(1, 1).Value = "Questa è la colonna A, riga 1"
' Salva il foglio nella directory C:\test.doc
ExcelSheet.SaveAs "C:\ TEST.DOC"
' Chiude Excel applicando il metodo Quit all'oggetto
' Application
ExcelSheet.Application.Quit
' Libera la variabile oggetto
Set ExcelSheet = Nothing
La comodità sta nel poter utilizzare proprietà e metodi dell'applicazione
invocata senza aggiungere librerie nei "Riferimenti" di Access, evitando
così problemi legati a Broken references.
Sintassi:
CreateObject(classe)
classe:   nomeapp.tipooggetto
nomeapp:  Nome dell'applicazione che fornisce l'oggetto.
tipooggetto: Variant (String). Tipo o classe di oggetto da creare.
Vorrei sfruttare sistematicamente l'associazione tardiva, ma non trovo
documentazione sugli oggetti esposti dalle varie applicazioni.
All'atto pratico vorrei sperimentare con le barre degli strumenti (libreria
Server: MSOXX.DLL) ma non ne esco.
Informazioni, suggerimenti, consigli?
Saluti: Damiano

> "Damiano Zorzi" [...]:

    Il modo piu' pratico e' sicuramente sviluppare con l'"associazione
anticipata", quindi togliere i riferimenti e "aggiustare" le dichiarazioni.
Per esempio il codice seguente:
Public Sub x_DamianoZorzi1()
' Dim oMsoCommandBar As Office.CommandBar
  Dim oMsoCommandBar As Object
  For Each oMsoCommandBar In Application.CommandBars
    With oMsoCommandBar
      Debug.Print .Name
    End With
  Next
  Set oMsoCommandBar = Nothing
End Sub
l'ho scritto avendo referenziato nel progetto:
        Library Office
            <...>\mso9.dll
            Microsoft Office 9.0 Object Library
e non commentata la dichiarazione:
        Dim oMsoCommandBar As Office.CommandBar
    Una volta accertatomi che il tutto funziona, ho eliminato i riferimenti,
ho messo il commento a:
        Dim oMsoCommandBar As Office.CommandBar
e l'ho tolto a:
        Dim oMsoCommandBar As Object
    Se la compilazione va a buon fine... tutto ok.
    Il bello e' che, dato che le applicazioni con le quali abbiamo a che
fare hanno tutte l'oggetto "Application" come vertice del modello, il codice
qui sopra funzionera', senza cambiare una virgola, sia con Access che con
Word, Excel, ... E con qualsiasi applicazione e versione della stessa che
implementi un modello degli oggetti con queste caratteristiche.
    Chiaramente, gli esiti dell'esecuzione varieranno a seconda
dell'ambiente in cui gira il codice.
    Percio' se, indipendentemente dall'ambiente, voglio ottenere la lista
dei nomi delle barre di comando di Excel e solo di Excel, sara' oltremodo
imprudente scrivere il codice in questo modo. Perche' non ho *perfettamente
qualificato* l'oggetto Application. Se scrivo ed eseguo solamente in
ambiente Excel non c'e' problema. Ma non dimentichiamo che la legge di
Murphy e' sempre pronta a dimostrare la sua validita': se abbiamo stabilito
che un evento non capitera' mai possiamo essere certi che capitera': nel
momento meno opportuno e producendo il maggior danno possibile.
    Quindi come dovremo operare? Se stiamo scrivendo il codice in Excel non
occorre ovviamente aggiungere i riferimenti, altrimenti li aggiungeremo
quindi scriveremo:
Public Sub x_DamianoZorzi2()
 'Dim oXlApp As Excel.Application
  Dim oXlApp As Object
 'Dim oMsoCommandBar As Office.CommandBar
  Dim oMsoCommandBar As Object
 'Set oXlApp = New Excel.Application
  Set oXlApp = CreateObject("Excel.Application")
  With oXlApp
    For Each oMsoCommandBar In .CommandBars
      With oMsoCommandBar
        Debug.Print .Name
      End With
    Next
    .Quit
  End With
  Set oMsoCommandBar = Nothing
  Set oXlApp = Nothing
End Sub
    E per ora mi fermo qui.
--
Ciao :-)
Maurizio
--------
?SPQR(C)
 X
--------

 anticipata", quindi togliere i riferimenti e "aggiustare" le
dichiarazioni.
Sono ... sbalordito e incredulo: sembra funzionare perfettamente!
Ma com'č possibile ciň?
Mi hai fatto creare un'associazione tardiva senza "CreateObject"; senza
riferirmi a una classe astratta dell'applicazione Server, e il tutto
funziona (ho eseguito del codice che disabilita pulsanti di una barra, e non
fa una piega anche su un PC diverso da quello usato per lo sviluppo).
Si tratta di un bug di Office, hai indagato sui perchč di sta cosa?
E ancora, hai testato associazioni IPER-anticipate :-))  di questo tipo
anche con altre librerie (magari .OCX) che espongano oggetti?
Grazie Mille!
CIAO: Damiano

 > "Maurizio Borrelli" [...]:

    No, piano... Un attimo, prego. ;-)
    Andiamo a vedere come stanno realmente le cose:
        Property CommandBars As CommandBars
            sola lettura
            Membro di Access.Application
        Property CommandBars As CommandBars
            sola lettura
            Membro di Word.Application
        Property CommandBars As CommandBars
            sola lettura
            Membro di Excel.Application
e mi fermo qui ma potrei andare avanti con PowerPoint, AutoCAD (?), ...
    Come vedi tutti questi oggetti Application possiedono una proprieta'
CommandBars, di tipo (Classe) CommandBars , ma tale classe non e' una classe
di Access, Word o Excel. Fanno tutti riferimento alla:
        Class CommandBars
            Membro di Office
tanto e' vero che in un progetto Visual Basic di Access (o Excel, Word,
...), se tentiamo di riferirci a tale classe, per esempio come abbiamo fatto
nel mio precedente post:
        Dim oMsoCommandBar As Office.CommandBar
senza avere il riferimento alla:
        Library Office
            <...>\msoX.dll
            Microsoft Office X.X Object Library
otteniamo ovviamente un errore. Mentre se "lasciamo fare" agli oggetti
(detto in poverissime parole) saranno questi che "si incaricheranno" di
recuperare i riferimenti. Tutto questo, come sai, ha un costo perche' si
allungano i tempi di esecuzione del programma ma, d'altro canto, si evitano
i problemi della rigidita' dei riferimenti, non occorre ricompilare, ecc.
    Nota anche un'altra cosa. Prova, in un progetto che ha fra i riferimenti
la library Office, a scrivere:
        set o = new
    Dopo che hai battuto lo spazio seguente la parola "new" compare
l'"Elenco membri", nel quale non trovi "Office". Perche? Perche' gli oggetti
della libreria Office non sono raggiungibili direttamente ma solo attraverso
il riferimento a questi fatto dagli oggetti Application che li usano. Ecco
il perche' dell'inutilita' di CreateObject.


"Maurizio Borrelli" <

Sei stato chiarissimo: ora i conti mi tornano perfettamente.
Naturalmente sono conscio del fatto che l'associazione tardiva implichi dei
costi aggiuntivi, ma visti i vantaggi non č un problema.
Piuttosto, non riesco a trovare nell'help delle applicazioni i rispettivi
modelli a oggetti (anche DAO e ADO): č perchč non cerco bene oppure si trova
qualcosa sul web?
Ti ringrazio ancora per la preziosa dritta :-)
Damiano

 qualcosa sul web?
Trovato: m'interessava il modello a oggetti generico di Office e ADO.
Ciao: Damiano