Come usare Access (Le DDE)

Stampa
( 0 Votes ) 
Valutazione attuale:  / 0
ScarsoOttimo 
Categoria: Informatica
Data pubblicazione
Scritto da Fragger Visite: 3022

Come usare Access

'Le DDE (Dynamic Data Exchange)'  [Ultima Parte]


Generalità dello scambio dei dati
Il DDE (Scambio Dinamico dei dati, Dynamic Data Exchange) è un protocollo per Microsoft Windows che consente a due applicazioni di dialogare tra loro, vale a dire di scambiare dati in modo continuativo e, se lo si desidera, automaticamente.
E' possibile che si desideri utilizzare un programma di comunicazione per scaricare dati periodicamente e memorizzarli nel database oppure fornire i risultati di una query ad un documento di Microsoft Word. Utilizzando il DDE queste operazioni tra appicazioni possono essere eseguite automaticamente.

Conversazioni DDE

Due applicazioni che utilizzano il DDE per scambiare dati, sono coinvolte in una conversazione DDE attraverso un canale che supporta conversazioni bidirezionali. Il codice di Access Basic ma anche quello di Excel e Word, sono in grado di condurre più conversazioni con la stessa applicazione contemporaneamente. Ciascuna conversazione avrà però luogo su un diverso canale. Il codice mantiene aperto molti canali contemporaneamente. L'applicazione che inizia una conversazione prende il nome di applicazione o applicazione client DDE, mentre l'applicazione che risponde all'applicazione client DDE, viene chiamata applicazione di origine o server DDE. Si noti infatti che tutte le applicazioni Windows possono iniziare una conversazione con un'applicazione su un canale e rispondere ad un'altra applicazione su un diverso canale. Una procedura di Access Basic può ed esempio, iniziare una conversazione con Excel per la trasmissione dei dati relative alle vendite. In questo caso Access sarà l'applicazione client ed Excel l'applicazione server ma nello stesso momento Access può rispondere ad altre applicazioni diventando server per altre applicazioni.

Argomenti, elementi e applicazioni
Per iniziare una conversazione DDE, il codice deve contenere due indicazioni.
-Il nome del server DDE, o applicazione di origine,con cui comunicare.
-L'argomento della conversazione.

Quando un'applicazione server riceve una richiesta di conversazione, su un argomento che riconosce, risponde e apre un canale. Una volta avviata la conversazione, non sarà più possibile modificare gli argomenti o le applicazioni. Per inziare una conversazione con un altro server DDE o con la stessa applicazione ma relativamente ad un altro argomento, sarà necessario avviare una nuova conversazione su un canale differente. Questa operazione non influenzerà la conversazione in atto sul primo canale, la quale potra essere terminata o continuata.
Durante la conversazione, le applicazioni si scambiano dei messaggi riguardanti elementi specifici. Un elemento è in genere un riferimento a un dato contenuto nell'argomento. Gli elementi possono variare da argomento ad argomento e ogni applicazione server può riconoscere argomenti diversi.
Un argomento definisce l'oggetto della conversazione DDE e rappresenta dati significativi per il server DDE. La maggior parte delle applicazioni che operano sui file, l'argomento è rappresentato da un nome file.
Per Excel ad esempio è "ORDINI.XLS" per Word ad esempio può essere "RAPPORTO.DOC" e per Access "VENDITE.MDB".
Un argomento speciale che la maggior parte delle applicazioni riconosce è "System". E' possibile usare questo argomento per ottenere informazioni  sugli argomenti che questa applicazione supporta.
In genere, quando un argomento si riferisce ad un file, è necessario che il file sia aperto se si desidere che il server DDE risponda ad una conversazione sull'argomento. Un elemento è un riferimento ad un dato che può essere, un intervallo di celle in un fogli di lavoro di Excel oppure ad un oggetto di database di Access. Un elemento si riferisce ad una parte specifica di un argomento.
Per ultimo è il nome dell'applicazione che prende parte a una conversazione DDE. Il NomeApp di un applicazione di solito è il nome del corrispondente file eseguibile, senza l'estenzione EXE.
Il seguente schema sono riportati i nomi più comuni di applicazioni di Windows.
Applicazione     NomeApp
Word                  WINWORD
Excel                  EXCEL
Access              MSACCESS
PowerPoint       POWERPNT
Per informazioni sul NomeApp di altre applicazioni, consultare la documentazione specifica.


Avvio di una conversazione DDE
Per avviare una conversazione DDE con un'altra applicazione, utilizzare la funzione:
    DDEInitiate(NomeApp, argomento)
Per iniziare, ad esempio, una conversazione con Excel sull'argomento "System":
   nCanale = DDEInitiate("EXCEL", "System")
Se DDEInitiate riesce ad avviare la conversazione con l'applicazione specificata, restituirà un numero che indica il canale aperto.
E' possibile utilizzare il numero di canale come argomento in altre istruzioni e funzioni DDE per mantenere più conversazioni contemporaneamente ed eseguire operazioni differenti in ognuno di essi. Se l'appicazione non è già in eseguzione o se lo è ma non riconosce l'argomento, si verificherà un errore intercettabile. Si consiglia sempre di aggiungere un codice di rilevamneto errori e che lo avvii in caso contrario.
Per avviare l'applicazione, di solito si usa la funzione Shell:
  Temp = Shell(NomeApp,6)     'Apre l'applicazione ridotta ad icona.
 
Invio di comandi ad altre applicazioni
Per inviare una stringa di comendo ad un'altra applicazione, viene utilizzata l'istruzione DDEExecute:
    DDEExecute nCanale, comando
dove:     nCanale  -  è il numero di canale aperto con l'istruzione DDEInitialize
             comando  -  è il comando da inviare all'altra appicazione che funge da server
.
     
E' possibile, ad esempio inviare a Excel un comando per aprire un foglio di lavoro:
   DDEExcute nCanale, "[Open(""ORDINI.XLS"")]"  
L'uso di parentesi quadre per racchiudere il comando macro è una convenzione di Excel che viene utilizzata anche da Word.
Altre applicazioni potrebbero utilizzare altre convenzioni. Conviene pertanto consultare la documentazione dell'applicazione. Le virgolette doppie sono necessarie per racchiudere le virgolette della stringa, come richieste da Excel.

Trasferimento dei dati ad altre applicazioni
Dopo aver iniziato la conversazione con un'altra applicazione, è possibile inviare dati con l'istruzione DDEPoke:
   DDEPoke nCanale, elemento, dati
dove:     nCanale  -  è il numero di canale aperto con l'istruzione DDEInitialize
             elemento e dati  -  sono l'argomento.

         
Ad esempio è stata avviata una conversazione con Excel utilizzando un foglio di lavoro come argomento, sarà possibile inserire un nuovo valore, ad esempio 100, nella cella superiore sinistra del foglio di lavoro.
   DDEPoke nCanale, "R1C1", "100"
E' opportuno sottolineare che i dati devono sempre essere di tipo Stringa o Variant. Sarà compito dell'altra applicazione interpretare i dati correttamente.

Chiusura di conversazione DDE
Una volta terminato lo scambio di dati con un'altra applicazione, è necessario chiudere la conversazione:
    DDETerminate nCanale
Quando si chiude Access, vengono terminate automaticamente tutte le conversazioni DDE attive. Potrebbe essere necessario chiudere tutte le conversazioni attive senza chiudere Access. A tal fine è possibile utilizzare l'istruzine:
   DDETerminateAll
A meno che non si esca da Access, i canali DDE non vengono mai chiusi automaticamente. Se si utilizza una variabile locale per memorizzare il numero di canale e non si chiude il canale al termine della procedura, il canale resterà aperto senza alcuna possibilità di chiuderlo in seguito. Quindi chiudere sempre i canali aperti quando non sono più necessari, dal momemto che ogni canale utilizza delle risorse di sistema.

Esempi di codice utilizzando Access come client ed Excel come server





La maschera a lato è un esempio di Import ed Export dei dati da Access ad Excel e viceversa. Questa maschera si trova del database di Access IntereagireExcel.mdb. Il codice che segue è memorizzato nel modulo della maschera. La Sub EseguiExport_Click  viene eseguita con l'evento Click del primo pulsante della maschera, mentre la Sub  EseguiImport_Click()  è eseguita con il secondo tasto.

Private Sub EseguiExport_Click()
     Dim PathExcel, FileExcel As String
     Dim Rs As Recordset
     Dim nCanale As Long
     Call CaricaVocaboli             'Carica i vocaboli nella Tabella per la prova di esempio
  
 'Nella variabile PathExcel salvo il percorso dove è memorizzato nel mio pc l'EXCEL.EXE
    PathExcel = "D:\MicrosoftOffice\Office12\EXCEL.EXE" 
 'Nella variabile FileExcel salvo il percorso del foglio Excel dal quale prenderò e scriverò i dati
    FileExcel = CurrentProject.Path & "\Test.xls"
    Shell PathExcel, 6                             'Lancia in esecuzione il file Excel ridotto ad icona
  'Apre nCanale di comunicazione con il file Excel. L'argomento System è un argomento standard di tutte le applicazioni per Microsoft Windows. 'Esso fornisce informazioni sugli altri argomenti supportati  dall'applicazione. Per accedere a tali informazioni, è necessario che il codice prima chiami la funzione DDEInitiate, utilizzando:
     nCanale = DDEInitiate("Excel", "System")
  'Se utilizzo questa istruzione per inviare a Microsoft Excel il comando nuovo foglio Access funge da client, 'mentre Excel da applicazione server
     DDEExecute nCanale, "[open(" + Chr$(34) + FileExcel + Chr$(34) + ")]"  
   DDETerminate nCanale                                                                           ' Chiude nCanale
   nCanale = DDEInitiate("Excel", FileExcel)                                             ' Apre il canale con l'oggetto di conversazione DDE
  
   Set Rs = CurrentDb.OpenRecordset("ExportVocaboli")                      ' Apre un Recordset
   Rs.Index = "Parola"                                                                                    ' Apre l'indice della Tabella
   Riga = 0: Colonna = 1: nRec = 0
   'Esegue un ciclo fino alla fine del Recordset EOF(In realtà tratta solo i primi 900 record)
   Do While Not Rs.EOF
        Riga = Riga + 1                                                                                          'Incrementa la Riga in Excel
        DDEPoke nCanale, "r" & Riga & "c" & Colonna & "", Rs!Parola       'Trasferisce in Excel e scrive nella riga e nella colonna la parola
       nRec = nRec + 1                                                                                         'Conta il numero di record
       Rs.MoveNext                                                                                               'Passa al record successico
       If Riga = 100 Then                                                                                     'Dispone le parole su 9 colonne, ogni colonna è formata da 100 parole
          Riga = 0
          Colonna = Colonna + 1                                                                         'Passa alla colonna successiva
      End If
      If nRec = 900 Then Exit Do                                                                        'Esce dal ciclo a 900 Record
   Loop
  
   Set Rs = Nothing                                                                                           'Distrugge il Recordset     
   DDEExecute nCanale, "[save()]"                                                                'Salva il file Excel
   DDETerminate nCanale                                                                             'Chiude nCanale    
   MsgBox "Sono stati Exportati (" & nRec & ") record"                              'Mostra una scheda di dialogo, dei record eleborati
End Sub
______________________________________________________________________________________
Private Sub EseguiImport_Click()
  Dim Appoggio As Variant, PathExcel, FileExcel As String
  Dim nCanale As Long  
 'Nella variabile PathExcel salvo il percorso dove è memorizzato nel mio pc l'EXCEL.EXE
   PathExcel = "D:\MicrosoftOffice\Office12\EXCEL.EXE" 
 'Nella variabile FileExcel salvo il percorso del foglio Excel dal quale prenderò e scriverò i dati
   FileExcel = CurrentProject.Path & "\Test.xls"
   Shell PathExcel, 6                                    'Lancia in esecuzione il file Excel ridotto ad icona
   nCanale = DDEInitiate("Excel", "System")
'Se utilizzo questa istruzione per inviare a Microsoft Excel il comando apri foglio, Access funge da client, mentre Excel da applicazione server
   DDEExecute nCanale, "[open(" + Chr$(34) + FileExcel + Chr$(34) + ")]"  
   DDETerminate nCanale                                                            'Chiude nCanale
   nCanale = DDEInitiate("Excel", FileExcel)
   CurrentDb.Execute "DELETE FROM ImportVocaboli;"       'Cancella tutti gli eventuali record
   Set Rs = CurrentDb.OpenRecordset("ImportVocaboli")
   Riga = 1: Colonna = 1: nRec = 0
  
   Do
      'Memorizzo nella variabile il contenuto della cella di riga r e colonna c di Excel
        Appoggio = DDERequest(nCanale, "r" & Riga & "c" & Colonna & "")       'Richiede i dati
       If Riga = 101 Then                                                      'A fine della riga
         Riga = 1                                                                      'Riposiziono la lettura a riga 1
         Colonna = Colonna + 1                                           'Vado alla colonna successiva
       Else
         Rs.AddNew                                                                'Aggiungo nella tabella il record
         Rs!Parola = Appoggio                                             'Scrivo
         Rs.Update                                                                 'Salvo
         Riga = Riga + 1                                                         'Vado alla riga successiva di Excel
         nRec = nRec + 1                                                      'Conto i record
       End If      
       If nRec = 900 Then Exit Do
    Loop
     
    DDETerminate nCanale                                             'Chiude  nCanale
    Set Rs = Nothing                                                         'Distrugge il recordset
    MsgBox "Sono stati Importati (" & nRec & ") record"
End Sub

________________________________________________________________________________

Public Function PathCorrente() As String
  'Restituisce: il percorso completo del database corrente  Es: x:\.....\....\ con la slant finale
   PathCorrente = Left(CurrentDb.Name, Len(CurrentDb.Name) -  Len(Dir(CurrentDb.Name)))
End Function
_________________________________________________________________________________
Sub CaricaVocaboli()
  Dim Rs As Recordset, Appoggio As String
  Set Rs = CurrentDb.OpenRecordset("ExportVocaboli")                        'Crea un oggetto recordset con origine la Tabella Vocaboli
  CurrentDb.Execute "DELETE FROM ExportVocaboli;"                            'Cancella tutti gli eventuali record della tabella ExportVocaboli
 
 Open PathCorrente() & "Vocaboli.txt" For Input As #1                              'Apre il file per l'input.
  Do While Not EOF(1)                                                                                     'Ripete fino alla fine del file.
      Line Input #1, Appoggio                                                                            'Legge una riga e la assegna alla variabile Appoggio
      Rs.AddNew                                                                                                 'Crea un record vuoto
      Rs!Parola = Appoggio                                                                              'Scrive sul campo Parola la variabile Appoggio
      Rs.Update                                                                                                   'Salva il record
  Loop
  Close #1                                                                                                         'Chiude vocaboli.txt
  Set Rs = Nothing                                                                                           'Distrugge il Recordset
End Sub

__________________________________________________________________________________

Utilizzare Access come server DDE

Sebbene Access non supporti il collegamento automatico, i dati collegati vengono aggiornati manualmente ad intervalli specificati. E' possibile specificare l'intervallo tra i vari aggiornamenti di collegamenti DDE nella finetra Opzioni di Access, si può impostare l'elemento Intervallo aggiornamenti ODBC (sec), Sempre nella stessa finestra l'elemento Attiva aggiornamento DDE, tale caratteristica si può attivare/disattivare  e l'elemento Ignora richieste DDE indica ad Access di ignorare o di accettare le richieste DDE provenienti da altre applicazioni.

Durante la conversazione DDE è possibile utilizzare l'istruzione DDEExecute nell'applicazione client per inviare un comando ad Access come applicazione server il quale riconosce come validi tutti i seguenti comandi:

  -  Il nome di una macro nel database aperto.

  -  Ogni azione eseguibile in Access utilizzando l'istruzione DoCmd.

  -  Le azioni "ApriDatabase" ("OpenDatabase") e "ChiudiDatabase" ("CloseDatabase") e "Esci" ("Quit").

Quando si specifica un'azione come un comando DDEExecute, l'azione e tutti gli argomenti seguono la sintassi DoCmd e devono essere racchiusi tra parentesi quadre ([ ]). Le applicazioni che suppurtano il DDE, però non riconoscono le costanti intrinseche nelle operazioni DDE. Inoltre gli argomenti stringa devono essere rachiusi tra virgolette se la stringa contiene una virgola, altrimenti non sono necessarie.

Come server DDE, Access supporta i seguenti argomenti:

  -  L'argomento System

  -  Il nome di un Database

  -  Il nome di una Tabella

  -  Il nome di una Query

  -  Un'istruzione SQL di Access

 L'argomento System supporta i seguenti elementi di Access



Elemento      Restituisce
SysItems Un elenco di argomenti supportati da System
Formats Un elenco di formati che Access piò copiare negli Appunti
Status "Busy" o "Ready"
Topics L'argomento System ed un elenco dei percorsi completi di tutti i database Access aperti
 L'argomento Database supporta i seguenti elementi 

L'argomento database è il nome del file del database di Access esistente. E' possibile specificare solo il nome di base come EXPORTVOCABOLI oppure il percorso completo e l'estensione. Dopo aver avviato una conversazione DDE con il database, è possibile richiedere un elenco degli oggetti in quel database.



Elemento  Restituisce
TableList Un elenco di nomi di Tabelle
QueryList Un elenco di nomi di Query
FormList Un elenco di nomi di Maschera
ReportList Un elenco di nomi di Report
MacroList Un elenco di nomi di Macro
ModuleList Un elenco di nomi di Moduli

 Gli argomenti TABLE nometabella, QUERY nomequery SQL stringasql

 Questi argomenti utilizzano la seguente sintassi:



nomedatabase;TABLE nometabella
nomedatabase;QUERY nomequery
nomedatabase;SQL [stringasql]
 
Argomento       
Descrizione
nomedatabase  Il nome del database a cui appartiene la tabella o la query o a cui si riferisce l'istruzione SQLseguito da un punto e virgola (;). Il nome del database può essere solo il nome di base (InteregireExcel) o il nome completo del percorso e dell'estensione MDB
nometabella  Il nome di una tabella esistente
nomequery  Il nome di una query esistente
stringasql  Un'istruzione SQL valida, composta da max 255 caratteri, che termini con un punto e virgola. Per scambiare più di 255 caratteri, omettere questo argomento e utilizzare invece delle istrizioni DDEPoke successive per generare in'istruzione SQL.
 Nella seguente tabella sono elencati gli elementi validi per gli argomenti TABLE nometabella, QUERY nomequery, SQL stringasql



Elemento  Restituisce
All Tutti i dati nella Tabella, inclusi i nomi di campo
Data Tutte le righe di dati, senza i nomi di campo
FieldNames Un elenco di una sola riga di nomi di campo
FieldNames;T Un elenco di due righe di nomi di campo(prima riga) e dei tipi di dati corrispondenti (seconda riga)
NextRow I dati contenuti nella riga successiva in una tabella o query.Quando si apre un canale per la prima volta, NextRow restituisce i dati contenuti nella prima riga.Se la prima riga corrente è l'ultimo record, un'eventuale richiesta di NextRow non verrà eseguita.
PrewRow I dati contenuti nella riga precedente in una tabella o query.Se PrevRow è la prima richiesta effettuata dopo l'apertura di un nuovo canale, verranno restituiti i dati contenuti nell'ultima riga. Se il primo record è la riga corrente,  un'eventuale richiesta di PrevRow non verrà eseguita.
FirstRow I dati contenuti nella prima riga di una tabella o query
LastRow I dati contenuti nell'ultima riga di una tabella o query
FieldCount Il numero dei campi contenuti in una tabella o query
SQLText Un'istruzione SQL che rappresenta una tabella o una query. Per le tabelle, questo elemento restituisce un'istruzione SQL nella forma "SELECT * FROM nometabella:"
SqlTest;n Un'istruzione SQL in gruppi di n caratteri, che rappresenta una tabella o una query, dove n è un intero fino a 255
 Esempi di codice utilizzando Access come server ed Excel come client

Il codice che segue è memorizzato nel modulo di Excel 'ThisWorkBook'

Sub Import()
   Dim Rs As Variant
   Rs = Array()                                                         'Crea un array vuoto
  Set NewSheet = Worksheets.Add                   'Crea un nuovo foglio
  NewSheet.Name = "Vocaboli"
  nCanale = DDEInitiate("MSAccess", "System")
 'Apre il database Access "IntereagireExcel.mdb"
    DDEExecute nCanale, "[Opendatabase H:\Articoli\DDE\IntereagireExcel.mdb]"
 'Apre il canale con l'oggetto di conversazione DDE. . Apre la Tabella ExportVocaboli
    nCanale1 = DDEInitiate("MSAccess", "IntereagireExcel;TABLE ExportVocaboli")
 Rs = DDERequest(nCanale1, "Data")                'Tutte le righe di dati senza i nomi di campo
 For i = 1 To 300
    Worksheets("Vocaboli").Cells(i, 1).Value = Rs(i, 1)                      'Importa i primi 300 vocaboli

 Next i
 DDEExecute nCanale, "[CloseDatabase]"                                        'Chiude il database
 DDEExecute nCanale, "[Quit]"                                                             'Chiude Access
 DDETerminate All                                                                                  'Chiude tutti i canali
End Sub 

Questa routine apre la tabella ExportVocaboli  in Access ed esegue l'import dei dati. Elenca i primi 300 vocaboli sul nuovo foglio Vocaboli.

 

Sub SQL()
  Dim Rs As Variant
  Rs = Array()                                              'Crea un array vuoto
  Set NewSheet = Worksheets.Add       'Crea un nuovo foglio
  NewSheet.Name = "Vocaboli"
  nCanale = DDEInitiate("MSAccess", "System")
 'Apre il database Access "IntereagireExcel.mdb"
     DDEExecute nCanale, "[Opendatabase H:\Articoli\DDE\IntereagireExcel.mdb]"
 'Apre il canale con l'oggetto di conversazione DDE
 'Apre la Tabella ExportVocaboli esegue l'istruzione SQL selezionando i vocaboli che iniziano"
 ' con la B-> (WHERE Parola Like 'B*')
     nCanale1 = DDEInitiate("MSAccess", "IntereagireExcel;SQL SELECT * FROM ExportVocaboli WHERE Parola Like 'B*';")
   Rs = DDERequest(nCanale1, "Data")        'Tutte le righe di dati senza i nomi di campo
   For i = 1 To 300
       Worksheets("Vocaboli").Cells(i, 1).Value = Rs(i, 1)                 'Importa i primi 300 vocaboli
   Next i
   DDEExecute nCanale, "[CloseDatabase]"                                   'Chiude il database
   DDEExecute nCanale, "[Quit]"                                                         'Chiude Access
   DDETerminate All                                                                              'Chiude tutti i canali
End Sub

Questa routine apre la tabella ExportVocaboli  in Access, con un comando SQL per selezionare i vocaboli che iniziano con la lettera 'B' ed esegue l'import. Elenca i primi 300 vocaboli sul nuovo foglio Vocaboli.

Sub ApriForm()
    Dim Rs As Variant
    nCanale = DDEInitiate("MSAccess", "System")
 'Apre il database Access "IntereagireExcel.mdb"
      DDEExecute nCanale, "[Opendatabase H:\Articoli\DDE\IntereagireExcel.mdb]"
   Rs = DDERequest(nCanale, "FormList")                                              'Richiede un elenco di nomi di maschere
   DDEExecute nCanale, "[OpenForm MascheraExporImport]"           'Apre la Maschera direttamente in Access
   DDETerminate All                                                                                      'Chiude tutti i canali
End Sub

Questa routine Apre la Maschera 'MascheraExporImport' direttamente  in Access.

Con questi esempi di routine ho concluso questo argomento, metto a disposizione tutti i file citati nei codici.

L' unica avvertenza è quella di modificare i percorsi dei file coinvolti. File