Newsgroup: it.comp.appl.access
Titolo: Aggiornamento Tabelle non Collegate al BE-

Salve,
sono sempre io con il solito problema.
Ho ottenuto da Antonio Biso il seguente codice per il modulo da inserire nel
DB:
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'                   AggiornaCollegamentiTabelle                '
'                                                              '
' Questo modulo contiene funzioni che aggiornano i collegamenti'
'     alle tabelle di Northwind se non sono disponibili.       '
'                                                              '
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Option Explicit           ' Richiede la dichiarazione delle variabili da
utilizzare.
Option Compare Database   ' Utilizza il tipo di ordinamento del database per
confrontare le stringhe.
Declare Function LeggiApriNomeFile Lib "comdlg32.dll" Alias
"GetOpenFileNameA" (pApriNomeFile As APRINOMEFILE) As Boolean
Declare Function LeggiSalvaNomeFile Lib "comdlg32.dll" Alias
"GetSaveFileNameA" (pApriNomeFile As APRINOMEFILE) As Boolean
Type MSA_APRINOMEFILE
    ' Filtro utilizzato nella finestra Apri file.
    ' Utilizza MSA_CreaStringaFiltro() per crearlo.
    ' Predefinito = Tutti i file, *.*
    strFiltro As String
    ' Filtro iniziale da visualizzare.
    ' Predefinito = 1.
    lngIndiceFiltro As Long
    ' Cartella iniziale di apertura della finestra.
    ' Predefinito = Cartella di lavoro corrente.
    strCartellaIniziale As String
    ' Nome file iniziale per riempire la finestra.
    ' Predefinito = "".
    strFileIniziale As String
    strTitoloFinestra As String
    ' Estensione predefinita da aggiungere al file se non è stata già
specificata.
    ' Predefinito = Valori di sistema (Apri file, Salva file).
    strEstensionePredefinita As String
    ' Flag da utilizzare (vedere l'elenco delle costanti).
    ' Predefinito = no flag.
    lngFlag As Long
    ' Percorso completo del file selezionato. Durante l'apertura del file,
se è stato selezionato un file
    ' non esistente, restituisce solo il testo nella casella "Nome file".
    strPercorsoCompletoRestituito As String
    ' Percorso completo del file selezionato.
    strNomeFileRestituito As String
    ' Offset nel percorso completo (strPercorsoCompletoRestituito)
all'inizio del nome di file
    ' (strNomeFileRestituito).
    intOffsetFile As Integer
    ' Offset nel percorso completo (strPercorsoCompletoRestituito)
all'inizio dell'estensione del file.
    intEstensioneFile As Integer
End Type
Const OGNIFILE = "Tutti i file"
Type APRINOMEFILE
    lDimensioneStruttura As Long
    hwndProprietario As Long
    hIstanza As Long
    lpstrFiltro As String
    lpstrFiltroPersonalizzato As Long
    nMaxFiltroPersonalizzato As Long
    nIndiceFiltro As Long
    lpstrFile As String
    nMaxFile As Long
    lpstrTitoloFile As String
    nMaxTitoloFile As Long
    lpstrCartellaIniziale As String
    lpstrTitolo As String
    FLAG As Long
    nOffsetFile As Integer
    nEstensioneFile As Integer
    lpstrDefinizioneEstensione As String
    lDatiPersonalizzati As Long
    lpfnHook As Long
    lpNomeModello As Long
End Type
Const ANF_PERMETTESELEZIONEMULTIPLA = &H200
Const ANF_CREAPROMPT = &H2000
Const ANF_EXPLORER = &H80000
Const ANF_FILEDEVEESISTERE = &H1000
Const ANF_NASCONDESOLALETTURA = &H4
Const ANF_NONCAMBIACARTELLA = &H8
Const ANF_NESSUNRIFERIMENTOCOLLEGAMENTI = &H100000
Const ANF_NESSUNPULSANTEDIRETE = &H20000
Const ANF_NONRESTITUISCESOLALETTURA = &H8000
Const ANF_NESSUNACONVALIDA = &H100
Const ANF_SOVRASCRIVEPROMPT = &H2
Const ANF_PERCORSODEVEESISTERE = &H800
Const ANF_SOLALETTURA = &H1
Const ANF_MOSTRAGUIDA = &H10
'
****************************************************************************
' Visualizza la finestra di dialogo per l'apertura del database BackEnd dove
' sono contenute le tabelle utilizzate dal tool
' Restituisce il percorso completo del database collegato.
'
****************************************************************************
Function TrovaDatabase(strCercaPercorso, caso As Integer) As String
    Dim msaaf As MSA_APRINOMEFILE
    If caso = 1 Then 'caso tabelle importazione
        msaaf.strTitoloFinestra = "Collegamento tabelle importazione"
        msaaf.strCartellaIniziale = strCercaPercorso
        msaaf.strFileIniziale = "EsportaSIM.mdb"
        msaaf.strFiltro = MSA_CreaStringaFiltro("Database intermedio",
"EsportaSIM.mdb")
    ElseIf caso = 2 Then 'caso tabelle backend
        msaaf.strTitoloFinestra = "Collegamento tabelle BackEnd"
        msaaf.strCartellaIniziale = strCercaPercorso
        msaaf.strFileIniziale = "Back.mdb"
        msaaf.strFiltro = MSA_CreaStringaFiltro("Tabelle Backend",
"back.mdb")
    End If
    ' Chiama la routine associata alla finestra di dialogo per l'apertura
del file.
    MSA_LeggiApriNomeFile msaaf
    ' Restituisce il percorso e il nome di file.
    TrovaDatabase = Trim(msaaf.strPercorsoCompletoRestituito)
End Function
Function MSA_CreaStringaFiltro(ParamArray varFilt() As Variant) As String
' Crea la stringa filtro dagli argomenti forniti.
' Restituisce "" se non è stato fornito alcun argomento.
' Il numero atteso di argomenti deve essere pari (nome filtro, estensione);
' se dispari, aggiunge *.*
    Dim strFiltro As String
    Dim intRet As Integer
    Dim intNum As Integer
    intNum = UBound(varFilt)
    If (intNum <> -1) Then
        For intRet = 0 To intNum
            strFiltro = strFiltro & varFilt(intRet) & Chr$(0)
        Next
        If intNum Mod 2 = 0 Then
            strFiltro = strFiltro & "*.*" & Chr$(0)
        End If
        strFiltro = strFiltro & Chr$(0)
    Else
        strFiltro = ""
    End If
    MSA_CreaStringaFiltro = strFiltro
End Function
Function MSA_ConvertiStringaFiltro(strFiltroIn As String) As String
' Crea una stringa filtro da una stringa separata da una barra ("|").
' La stringa dovrebbe accoppiare le stringhe filtro|estensione, per esempio:
"Access Database|*.mdb|Tutti i file|*.*"
' Se l'ultima stringa non ha estensione, aggiunge *.*.
' Ignora le stringhe vuote, per esempio: doppia barra "||".
' Restituisce "" se la stringa fornita è vuota.
    Dim strFiltro As String
    Dim intNum As Integer, intPos As Integer, intUltimaPos As Integer
    strFiltro = ""
    intNum = 0
    intPos = 1
    intUltimaPos = 1
    ' Aggiunge stringhe fino a quando non trova una barra.
    ' Ignora tutte le stringhe vuote (non consentito).
    Do
        intPos = InStr(intUltimaPos, strFiltroIn, "|")
        If (intPos > intUltimaPos) Then
            strFiltro = strFiltro & Mid$(strFiltroIn, intUltimaPos, intPos -
intUltimaPos) & Chr$(0)
            intNum = intNum + 1
            intUltimaPos = intPos + 1
        ElseIf (intPos = intUltimaPos) Then
            intUltimaPos = intPos + 1
        End If
    Loop Until (intPos = 0)
    ' Legge l'ultima stringa esistente (ipotizzando che strFiltroIn non
abbia come ultimo termine la barra).
    intPos = Len(strFiltroIn)
    If (intPos >= intUltimaPos) Then
        strFiltro = strFiltro & Mid$(strFiltroIn, intUltimaPos, intPos -
intUltimaPos + 1) & Chr$(0)
        intNum = intNum + 1
    End If
    ' Aggiunge *.* se l'ultima stringa non ha estensione.
    If intNum Mod 2 = 1 Then
        strFiltro = strFiltro & "*.*" & Chr$(0)
    End If
    ' Aggiunge il terminatore NULL se è presente un filtro.
    If strFiltro <> "" Then
        strFiltro = strFiltro & Chr$(0)
    End If
    MSA_ConvertiStringaFiltro = strFiltro
End Function
Private Function MSA_LeggiSalvaNomeFile(msaaf As MSA_APRINOMEFILE) As
Integer
' Apre la finestra di dialogo per l'apertura del file.
    Dim af As APRINOMEFILE
    Dim intRet As Integer
    MSAAF_in_AF msaaf, af
    af.FLAG = af.FLAG Or ANF_NASCONDESOLALETTURA
    intRet = LeggiSalvaNomeFile(af)
    If intRet Then
        AF_in_MSAAF af, msaaf
    End If
    MSA_LeggiSalvaNomeFile = intRet
End Function
Function MSA_SempliceLeggiSalvaNomeFile() As String
' Apre la finestra di dialogo per il salvataggio del file con i valori
predefiniti.
    Dim msaaf As MSA_APRINOMEFILE
    Dim intRet As Integer
    Dim strRet As String
    intRet = MSA_LeggiSalvaNomeFile(msaaf)
    If intRet Then
        strRet = msaaf.strPercorsoCompletoRestituito
    End If
    MSA_SempliceLeggiSalvaNomeFile = strRet
End Function
Private Function MSA_LeggiApriNomeFile(msaaf As MSA_APRINOMEFILE) As Integer
' Apre la finestra di dialogo per l'apertura del file.
    Dim af As APRINOMEFILE
    Dim intRet As Integer
    MSAAF_in_AF msaaf, af
    intRet = LeggiApriNomeFile(af)
    If intRet Then
        AF_in_MSAAF af, msaaf
    End If
    MSA_LeggiApriNomeFile = intRet
End Function
Function MSA_SempliceLeggiApriNomeFile() As String
' Apre la finestra di dialogo per l'apertura del file con i valori
predefiniti.
    Dim msaaf As MSA_APRINOMEFILE
    Dim intRet As Integer
    Dim strRet As String
    intRet = MSA_LeggiApriNomeFile(msaaf)
    If intRet Then
        strRet = msaaf.strPercorsoCompletoRestituito
    End If
    MSA_SempliceLeggiApriNomeFile = strRet
End Function
Public Function ControllaCollegamenti() As Boolean
' Controlla i collegamenti al database Northwind; restituisce True se i
collegamenti funzionano.
    Dim dbs As Database, rst As Recordset
    Set dbs = CurrentDb()
    ' Apre una tabella collegata per controllare che le informazioni sulla
connessione siano corrette.
    On Error Resume Next
    Set rst = dbs.OpenRecordset("Clienti")
    ' Se non si riscontra alcun errore, restituisce True.
    If Err = 0 Then
        ControllaCollegamenti = True
    Else
        ControllaCollegamenti = False
    End If
End Function
Private Sub AF_in_MSAAF(af As APRINOMEFILE, msaaf As MSA_APRINOMEFILE)
' Sub che converte la struttura di win32 nella struttura di MSAccess.
    msaaf.strPercorsoCompletoRestituito = Left$(af.lpstrFile,
InStr(af.lpstrFile, vbNullChar) - 1)
    msaaf.strNomeFileRestituito = af.lpstrTitoloFile
    msaaf.intOffsetFile = af.nOffsetFile
    msaaf.intEstensioneFile = af.nEstensioneFile
End Sub
Private Sub MSAAF_in_AF(msaaf As MSA_APRINOMEFILE, af As APRINOMEFILE)
' Sub che converte la struttura di MSAccess nella struttura di win32.
    Dim strFile As String * 512
    ' Inizializza alcune parti della struttura.
    af.hwndProprietario = Application.hWndAccessApp
    af.hIstanza = 0
    af.lpstrFiltroPersonalizzato = 0
    af.nMaxFiltroPersonalizzato = 0
    af.lpfnHook = 0
    af.lpNomeModello = 0
    af.lDatiPersonalizzati = 0
    If msaaf.strFiltro = "" Then
        af.lpstrFiltro = MSA_CreaStringaFiltro(OGNIFILE)
    Else
        af.lpstrFiltro = msaaf.strFiltro
    End If
    af.nIndiceFiltro = msaaf.lngIndiceFiltro
    af.lpstrFile = msaaf.strFileIniziale & String$(512 -
Len(msaaf.strFileIniziale), 0)
    af.nMaxFile = 511
    af.lpstrTitoloFile = String$(512, 0)
    af.nMaxTitoloFile = 511
    af.lpstrTitolo = msaaf.strTitoloFinestra
    af.lpstrCartellaIniziale = msaaf.strCartellaIniziale
    af.lpstrDefinizioneEstensione = msaaf.strEstensionePredefinita
    af.FLAG = msaaf.lngFlag
    af.lDimensioneStruttura = Len(af)
End Sub
Public Function RiallegaTabelle(nome_tabella As String) As String
' Aggiorna i collegamenti al database a cui ci si collega.
' Le tabelle che dovranno essere riallegate sono elencate nella tabella
passata
' come parametro
' Restituisce True se funziona correttamente.
    Const conMaxTabelle = 8
    Dim strCercaPercorso As String
    Dim strNomeFile As String
    Dim intErrore As Integer
    Dim strErrore As String
    Dim mioset As Recordset
    Dim tdf As TableDef
    Dim msg As String
    Dim miodb As Database
    Dim caso As Integer
    ' directory da presentare nella finestra di dialogo
        strCercaPercorso = "C:\programmi\database riello"
    ' Cerca il database di cui si vogliono riallegare le tabelle.
    caso = IIf(right(nome_tabella, 5) = "zione", 1, 2)
    strNomeFile = TrovaDatabase(strCercaPercorso, caso)
    If strNomeFile = "" Then  ' L'utente ha premuto Annulla.
        MsgBox "Database non connesso", vbInformation, "OPERAZIONE
ANNULLATA!!!"
        RiallegaTabelle = "NOK"
        Exit Function
    End If
    ' Risolve i problemi di collegamento.
    On Error GoTo gest_err_riallega
    Set mioset = CurrentDb.OpenRecordset(nome_tabella)
    Set miodb = CurrentDb()
    mioset.MoveFirst
    Do Until mioset.EOF
        Set tdf = miodb.TableDefs(mioset.Fields(0).Value)
        tdf.Connect = ";DATABASE=" & strNomeFile
        tdf.RefreshLink         ' Riallega le tabelle.
        mioset.MoveNext
    Loop
    GoTo fine_riallega_ok
gest_err_riallega:
    ' Se non funziona, visualizza un messaggio di errore.
    Select Case Err
    Case 3011, 3078
        msg = "Rilevata anomalia nella connessione!@"
        msg = msg & "La tabella allegata " & tdf.Name & ", necessaria "
        msg = msg & "all'elaborazione, non è stata trovata nel database
remoto"
        msg = msg & vbCrLf & strNomeFile & vbCrLf
        msg = msg & "al quale ci si è connessi.@"
        msg = msg & "Contattare supporto informatico."
    Case Err = 3265
        msg = "Rilevata anomalia nella connessione!@"
        msg = msg & "La tabella allegata " & mioset.Fields(0).Value & ",
necessaria "
        msg = msg & "all'elaborazione, non è stata trovata nel presente
database.@"
        msg = msg & "Contattare supporto informatico."
    Case Err = 3049
        msg = "Rilevata anomalia nella connessione!@"
        msg = msg & "Il file scelto" & vbCrLf & strNomeFile & vbCrLf
        msg = msg & "è un database danneggiato o non è un database Access."
& vbCrLf
        msg = msg & "Controllare di aver selezionato il file giusto o
tentare di "
        msg = msg & "recuperarlo chiudendo il presente database e
selezionando il "
        msg = msg & "menu Strumenti-Utilità Database-Ripristina database.@"
        msg = msg & "In caso di ulteriore insuccesso contattare il supporto
informatico."
    Case Else
        msg = "Errore non prevedibile N°." & Err & "@"
        msg = msg & """" & Err.Description & """"
        msg = msg & vbCrLf & "@Contattare supporto informatico."
    End Select
    MsgBox msg, vbCritical, "ELABORAZIONE INTERROTTA!!!"
    RiallegaTabelle = "NOK"
    Exit Function
fine_riallega_ok:
    RiallegaTabelle = strNomeFile
End Function
**************
Ora la mia domanda è : come faccio ad usare questo codice nel mio db ?
Ho capito che all'apertura del DB dovrò fare il controllo se le tabelle sono
collegate, ma che cosa devo scrivere nella mia maschera principale (avvio) ?
Che codice devo scrivere per fare in modo che mi richiami la funzione di
controllo tabelle collegate ?
E poi se ho ben capito occorre creare una tabella con l'elenco delle tabelle
da collegare.
Come devo strutturare questa tabella e come faccio a passare il parametro al
comando che ripristina i collegamenti delle tabelle ?
Insomma io ho capito più o meno il funzionamento, ma non esattamente cosa
scrivere e dove per far si' che il controllo venga fatto tutte le volte che
apro il db e che il controllo restituisca "falso" per quanto riguarda le
tabelle collegate.
Per favore qualcuno mi aiuti. Non è difficile ma mi serve qualche dritta.
Please....
Grazie cmq in anticipo.


Il codice che hai riportato lo puoi trovare nel database di esempio
Soluzioni.mdb fornito con Access.
Molte delle stringhe presenti nel codice vanno opportunamente modificate
secondo le tue esigenze. Per esempio:
Const conMaxTabelle = 8 (metti il numero delle tabelle allegate)
strCercaPercorso = "C:\programmi\database riello" (imposta il tuo percorso
di inizio ricerca del db)
msaaf.strFileIniziale = "EsportaSIM.mdb" (il nome del BE da ricercare)
msaaf.strFiltro = MSA_CreaStringaFiltro("Database intermedio",
"EsportaSIM.mdb")
msaaf.strFileIniziale = "Back.mdb"
Set rst = dbs.OpenRecordset("Clienti") (il nome della prima tabella da
ricercare)
ecc.
Fatte le opportune modifiche sull'evento "Apertura" o "Caricamento" della
maschera iniziale puoi scrivere: ControllaCollegamenti
Questa istruzione farà partire l'omonima funzione. Se vuoi vedere il
funzionamento passo passo, metti un punto di interruzione sulla funzione e
segui, con F8, i vari passaggi del codice.
Dimenticavo: il codice non funziona in Access 2002
Ciao, Carlo

 comando che ripristina i collegamenti delle tabelle ?
Ufff... è già tutto previsto e ti avevo già detto che la tabella ha un unico
campo.
E non importa il nome visto che viene usato mioset.Fields(0).Value
Antonio


Scusami Antonio,
ma in quale post me lo hai scritto ?
Sai non voglio rompere le p....e ma un suggerimento non capito non mi è
utile, oppure utile fino ad un certo punto.
Non ho trovato alcun post tuo dove spieghi come fare esattamente cio' che mi
occorre.
Oltretutto io uso Access 2002.
Comunque ti ringrazio dell'interesse ma ho bisogno di suggerimenti più
chiari in quanto mi è difficile capire come stilare il codice.
Grazie a tutti.
Ciao.

 Oltretutto io uso Access 2002.
Eeehh...
male...
mi sa che la parte dialogo non funziona allora...
Antonio


La parte del dialogo funziona !!!
Mi chiede di scegliere il percorso del file ed io lo scelgo, ma eseguo fino
alla fine il codice che
alla fine mi darà un errore 13 e non mi ricollega le tabelle.
Ma secondo me cè qualcosa che non va bene in quel codice.
Per esempio : (la funzione trovadatabase --->> cosè questo database
intermedio ????) (io ho un file back.mdb e uno front.mdb)
(Le voci con ** sono quelle che non capisco)
Function TrovaDatabase(strCercaPercorso, caso As Integer) As String
    Dim msaaf As MSA_APRINOMEFILE
    If caso = 1 Then 'caso tabelle importazione
        msaaf.strTitoloFinestra = "Collegamento tabelle importazione"
        msaaf.strCartellaIniziale = strCercaPercorso
        msaaf.strFileIniziale = "EsportaSIM.mdb"       **
        msaaf.strFiltro = MSA_CreaStringaFiltro("Database intermedio",
"EsportaSIM.mdb")               **
    ElseIf caso = 2 Then 'caso tabelle backend
        msaaf.strTitoloFinestra = "Collegamento tabelle BackEnd"
        msaaf.strCartellaIniziale = strCercaPercorso
        msaaf.strFileIniziale = "SGM Backend.mdb"
        msaaf.strFiltro = MSA_CreaStringaFiltro("Tabelle Backend", "SGM
Backend.mdb")
    End If
----------------------------------------------------------------------------
------------------------------
Public Function RiallegaTabelle(nome_tabella As String) As String
' Aggiorna i collegamenti al database a cui ci si collega.
' Le tabelle che dovranno essere riallegate sono elencate nella tabella
passata
' come parametro
' Restituisce True se funziona correttamente.
    Const conMaxTabelle = 8               **   (devo inserire il numero
delle tabelle collegate  ?? e non devo conteggiare quelle locali del front
?)
    Dim strCercaPercorso As String
    Dim strNomeFile As String
    Dim intErrore As Integer
    Dim strErrore As String
    Dim mioset As Recordset
    Dim tdf As TableDef
    Dim msg As String
    Dim miodb As Database
    Dim caso As Integer
    ' directory da presentare nella finestra di dialogo
        strCercaPercorso = "C:\"
    ' Cerca il database di cui si vogliono riallegare le tabelle.
    caso = IIf(Right(nome_tabella, 5) = "zione", 1, 2)                    **
(cosa vuol dire   ....="zione",1,2)
    strNomeFile = TrovaDatabase(strCercaPercorso, caso)
    If strNomeFile = "" Then  ' L'utente ha premuto Annulla.
        MsgBox "Database non connesso", vbInformation, "OPERAZIONE
ANNULLATA!!!"
        RiallegaTabelle = "NOK"
        Exit Function
    End If
----------------------------------------------------------------------------
-
 ' Risolve i problemi di collegamento.
    On Error GoTo gest_err_riallega
    Set mioset = CurrentDb.OpenRecordset(nome_tabella)             **
(   ....(nome_tabella) ???)
    Set miodb = CurrentDb()
    mioset.MoveFirst
    Do Until mioset.EOF
        Set tdf = miodb.TableDefs(mioset.Fields(0).Value)
        tdf.Connect = ";DATABASE=" & strNomeFile
        tdf.RefreshLink         ' Riallega le tabelle.
        mioset.MoveNext
    Loop
    GoTo fine_riallega_ok
----------------------------------------------------------------------------
--------
    sarei grato se qualcuno mi aiutasse, o mi sugirisse un metodo
alternativo ,che non sia quello di immissione manuale del percorso.....
Oppure qualcuno mi spighi come eseguire il controllo e fare il ricolegamento
delle tabelle tramite immissione manuale del percorso.
Grazie e scusate se rompo, ma mi manca questo e un'altra cazzata per finire.
Ciao a tutti e grazieeeeeeeeeeeee.

 (   ....(nome_tabella) ???)
Nome_tabella è il parametro passato alla riallegatabelle nella chiamata da
maschera principale
(QUESTO C'ERA NELL'ESEMPIO CHE TI AVEVO PROPOSTO L'ALTRA VOLTA!!!"
Se ne hai una sola puoi renderla costante e scriverla direttamente qui
Antonio