General

6.18 Aggiornare le applicazioni distribuite.
  AntoGal
Quando viene distribuita un'applicazione, suddivisa in front-end e back-end, per aggiornare il programma, basta sostituire il FE che si collegherà ai dati già esistenti. Spesso però ci si trova nelle condizioni di dover aggiornare la struttura del DB (aggiungere nuovi campi, tabelle, indici...), e sarebbe impensabile di andare da tutti i clienti per aggiornare la struttura manualmente, per preservare i dati che nel frattempo sono stati inseriti. In questo caso non sarebbe consigliabile usare le "repliche", perchè i clienti potrebbero essere molti, dall'altra parte del mondo, ed a nessuno interessa dei dati dell'altro.

A questo punto si possono seguire diverse strade:

1) Scrivere un bel po' di codice che confronta i 2 BE e li allinea, cioè riporta le modifiche anche in quello con i dati del cliente (soluzione meno facile). Questo si fa ciclando tra gli insiemi Tables, Fields, Relazioni ecc...

2) Tenere un numero di versione e le relative modifiche per passare da una all'altra. Per es. dalla ver. 1.2 alla 1.3 aggiungere X campi e Y tabelle.
Ad ogni avvio, il FE confronta il numero attuale e, se non corrisponde all'ultima versione, applica sequenzialmente tutte le modifiche per ottenere l'upgrade. Ovviamente bisogna tenere da qualche parte la lista con tutte le correzioni alla struttura necessarie.
Potrebbe essere utile la funzione presente sul sito comune:
T&T, "Modificare la struttura dati del BE via codice, direttamente dal FE.", Enrico Oemi

3) (più semplice) Installare dal cliente il nuovo programma, ed importare nel BE aggiornato i dati presenti nel BE più vecchio, magari prevedendo una voce di menù "Importa archivi esterni". In pratica si importano nelle nuove tabelle vuote i valori dei campi corrispondenti. Se ci sono campi in più, o nuove tabelle, resteranno vuoti fino all'inserimento manuale dei dati.
Per importare il contenuto delle tabelle, si deve rispettare una sequenza che non violi l'integrità referenziale, ad esempio prima di importare le righe di una fattura, si deve importare l'intestazione della fattura stessa, quindi prima il lato 1, poi il lato molti.
Un esempio pratico, dove l'ordine di importazione NON è considerato:

'IMPORTA I DATI DI TUTTE LE TABELLE ESTERNE, NEL DB CORRENTE
'RESTRIZIONI: non si possono ELIMINARE o RINOMINARE campi nel nuovo DB,
'mentre si possono avere i campi in ordine diverso e si possono aggiungere
'nuovi campi nel nuovo DB

 Set dbsExt = OpenDatabase("VecchioBE.mdb")
 For Each tdf In dbsExt.TableDefs
  If (tdf.Attributes And dbSystemObject) = False And (tdf.Attributes And dbHiddenObject) = False Then
   If EsisteTabella(tdf.Name) Then
    DoCmd.RunSQL "INSERT INTO " & tdf.Name & " SELECT * FROM " & tdf.Name & " IN " & "VecchioBE.mdb"
   End If
  End If
  Next tdf
 End If
 Set dbsExt = Nothing
Naturalmente prima di questo va fatto scegliere all'utente il percorso dove
risiede il vecchio BE, insieme a tutti i controlli necessari.

Se invece dobbiamo considerare l'ordine di importazione, una soluzione
potrebbe essere:
 Dim TabelleOrd(100) As String
 Dim NumTab As Integer, TotTabelle As Integer
 TabelleOrd(1) = "TblCausaliFatture"
 TabelleOrd(2) = "TblModalPagamFatture"
 TabelleOrd(3) = "TblFatture"
 TabelleOrd(4) = "TblDatiFattura"
 [...]
 TotTabelle = 4
 'se la tabella esiste nel DB corrente e nel DB da importare, importa i campi in comune
 For NumTab = 1 To TotTabelle
  If EsisteTabella(TabelleOrd(NumTab)) And EsisteTabella(TabelleOrd(NumTab), "VecchioBE.mdb") Then
   DoCmd.RunSQL "INSERT INTO " & TabelleOrd(NumTab) & " SELECT * FROM " & TabelleOrd(NumTab) & " IN " & "VecchioBE.mdb"
  End If
 Next NumTab
dove la funzione EsisteTabella è:
 Public Function EsisteTabella(NomeTab As String, Optional NomeDbs) As Boolean
  'restituisce True se la tabella NomeTab del database NomeDbs (opzionale) esiste
  Dim dbs As Database, tdf As TableDef
  If IsMissing(NomeDbs) Then
   Set dbs = CurrentDb
  Else
   Set dbs = OpenDatabase(NomeDbs)
  End If
  EsisteTabella = False
  For Each tdf In dbs.TableDefs
   If tdf.Name = NomeTab Then
    EsisteTabella = True
    Exit For
   End If
  Next tdf
  Set dbs = Nothing
 End Function
Personalmente uso quest'ultima soluzione da diversi anni e non ha mai dato problemi.


Se pensate di avere del materiale freeware interessante e volete pubblicarlo, allora leggete qui.