ODBC: collegamento DNS-less

di il
3 risposte

ODBC: collegamento DNS-less

Ciao a tutti.
Come suggeritomi apro un nuovo thread relativo al collegamento ODBC delle tabelle.

Sto cercando di preparare un DB di prova prima di distribuirlo agli utenti, il DB lavora su tabelle collegate con ODBC oracle, per ovviare al problema di installare DSN con lo stesso nome su tutte le macchine, ho optato per una connessione in modalità DNS-less e ho accrochiato il codice qui di seguito, basandomi su qualcosa che ho trovato in rete e su miei lavori precedenti.

Per il momento connetto delle tabelle da una maschera con un pulsante che usa la sub qui sotto, poi la connessione dovrà essere fatta in automatico.

Sub MakeConnection_R2()
On Error GoTo Err_MakeConnection_R2
Dim db As Database
Dim td As TableDef
Dim count As Integer
Dim tabOr As String
Dim tabDe As String
Dim strSQL As String
Dim contTot As Integer
Dim cont As Integer
Set db = CurrentDb
cont = 0 'inizializzo un contatore
strSQL = "SELECT tabOrigine, TabDestinazione, flag FROM elencoTab WHERE (((flag)=True))"

Set rst = CurrentDb.OpenRecordset(strSQL)
contTot = rst.RecordCount
Debug.Print "totale tabelle da collegare: " & contTot
Forms![maschera1].Testo3.Value = "Tabelle: " & contTot

    rst.MoveFirst
    
    Do Until rst.EOF
    cont = cont + 1
        strsourcename = rst.Fields("tabOrigine")
        strlocalname = rst.Fields("TabDestinazione")


Set tdf = db.CreateTableDef(strlocalname)
tdf.Connect = "ODBC;DRIVER={Oracle in OraClient11g_home1};DBQ=nomedb;UID=nomeutente;PWD=password"

tdf.SourceTableName = strsourcename

Forms![maschera1].Testo1.Value = "Sto collegando la tabella: " & strsourcename & " in -> " & strlocalname & " - " & cont & "/" & contTot


db.TableDefs.Append tdf
rst.MoveNext

Loop

Forms![maschera1].Testo1.Value = "Tutte le tabelle sono state collegate"

db.Close
Set db = Nothing

Exit_MakeConnection_R2:
   Exit Sub
Err_MakeConnection_R2:
   If Err.Number = 3010 Then
      Forms![maschera1].Testo1.Value = "Tabella già collegata"
   End If
   Resume Exit_MakeConnection_R2

End Sub
sostanzialmente ho:
  • creato una tabella di appoggio in cui elenco le tabelle da collegare, scelgo se la tabella è da collegare o meno con un campo "flag", come si vede da strSQL;
  • ho creato una maschera con un pulsante che richiama la sub Make_connection_R2;
  • cliccando sul pulsante le tabelle vengono connesse e in un controllo della maschera "dovrei" vedere il progresso dell'operazione.
Il tutto essenzialmente funziona, ma ho i seguenti problemi:
  • anche quando la procedura di collegamento è terminata, non vedo le tabelle nel pannello laterale (lo sto tenendo aperto per controllo, il db per gli utenti non lo avrà visibile);
  • ho impostato la variabile contTot per contare quante tabelle devono essere collegate, ma restituisce sempre il numero 1 (ho inserito per prova 7 tabelle, quindi mi aspetterei questo numero nel contatore). Problema di poco conto visto che poi le tabelle sono realmente collegate;
  • nel controllo non riesco a vedere la scritta: "collegamento della tabella x su y" ed il relativo contatore cont/contTot (anche questo è un problema di poco conto);
  • nel controllo riesco a vedere il messaggio "tutte le tabelle sono collegate". Anche questo mi pare strano perché non riesco a vedere il progresso dell'operazione ma questo messaggio si ... (anche qui poco male).
Come dicevo il problema principale è dovuto al fatto che le tabelle si collegano ma non le vedo (nel pannello) per un bel po' (qualche minuto). Infatti se chiudo il db e lo riapro le tabelle sono visibili. Dopo che la sub ha collegato le tabelle ho provato a creare a mano una query e le tabelle non mi comparivano quando cercavo di selezionarle, quindi temo che se costruisco con questa logica il db, gli utenti non riescano a usufruire dei report, maschere ... e in generale tutti gli oggetti che hanno come base dati le tabelle collegate, se non dopo diversi minuti.
É un problema che altri hanno già avuto?

Il comportamento è simile su diversi sistemi operativi (ho provato win 7 pro 64 bit e win 10 pro 64 bit), con win 10 il tempo di "ritardo" è ancora più lungo.

Spero di essermi spiegato bene.
Grazie in anticipo a tutti per l'aiuto.

3 Risposte

  • Re: ODBC: collegamento DNS-less

    oierpa ha scritto:


    ...
    • anche quando la procedura di collegamento è terminata, non vedo le tabelle nel pannello laterale (lo sto tenendo aperto per controllo, il db per gli utenti non lo avrà visibile);
    Application.RefreshDatabaseWindow

    oierpa ha scritto:


    ...
    [*]ho impostato la variabile contTot per contare quante tabelle devono essere collegate, ma restituisce sempre il numero 1
    Perché il recordcount di un recorset non OpenTable contiene il totale dei record a cui c'è stato l'accesso. Per avere la certezza che contenga il numero totale dei record devi prima fare un MoveLast (ed eventualmente riportarlo all'inizio con MoveFirst se devi farne il ciclo dall'inizio)

    oierpa ha scritto:


    [*]nel controllo non riesco a vedere la scritta: "collegamento della tabella x su y" ed il relativo contatore cont/contTot
    Forse devi mettere un DoEvents ad ogni ciclo, per permettere alla maschera di aggiornarsi.
  • Re: ODBC: collegamento DNS-less

    Beh, che dire ....
    GRAZIE 1000!!!!
    Funziona alla perfezione.
    Anche se funziona, non ho capito come agisce "Doevent", ma ora lo cerco.
  • Re: ODBC: collegamento DNS-less

    Un'ultima nota.
    Ho modificato uno dei database che devo distribuire.
    Questo ha una maschera che viene caricata all'avvio, ho messo su evento di caricamento maschera (si chiama "main") il controllo della presenza delle tabelle collegate. Se non sono collegate cerco di collegarle. Finchè il controllo non è finito però non vedo la maschera, passano alcuni secondi che per gli utenti possono essere drammatici.
    Riporto un po' di codice.
    Codice della Form:
    
    Private sub Form_Load()
    'spengo dei controlli per evitare che gli utenti clicchino anche se le tabelle non sono collegate
    me.controllo1.visible=false
    me.controllo2.visible=false
    me.casellatesto.value="Sto caricando le tabelle"
    ....
    Call ControllaTabCollegate
    'riaccendo i controlli spenti prima
    me.controllo1.visible=true
    me.controllo2.visible=true
    ....
    End Sub
    
    Codice sub ControllaTabCollegate:
    
    Sub ControllaTabCollegate
    Dim .... dichiarazioni di variabili
    
    cont=0      'contatore per sapere che numero di tabella sto collegando 
    contNo=0  'contatore per tenere il conto delle tabelle non collegate
    contSi=0   'contatore per tenere il conto delle tabelle collegate
    
    Set db = CurrentDb
    
    strSQL = "SELECT NomeTabRemota, NomeTabLocale, flag FROM tblLinkSeme WHERE (((flag)=True))"
    
    Set rst = CurrentDb.OpenRecordset(strSQL)
    rst.MoveLast
    contTot = rst.RecordCount     'conto le tabelle da collegare
    
     rst.MoveFirst
        
        Do Until rst.EOF
        cont = cont + 1
            strsourcename = rst.Fields("NomeTabRemota")
            strlocalname = rst.Fields("NomeTabLocale")
    If TableExists(strlocalname) = False Then
    'se la tabella non è collegata prova a collegarla
       contNo = contNo + 1
       Call connTab(strsourcename, strlocalname)
       Forms![main].ctlAvvisi.value = "Sto collegando la tabella: " & strsourcename & " in -> " & strlocalname & " - " & cont & "/" & contTot
       DoEvents
          If TableExists(NomeTabLocale) = True Then
             contNo = contNo - 1
          End If
    Else
       contSi = contSi + 1
    End If
    
    rst.MoveNext
    
    Loop
    
    If contSi = contTot Then
       Forms![main].ctlAvvisi.value = "Tutte le tabelle sono state collegate"
       DoEvents
    
    End If
    
    db.Close
    Set db = Nothing
    Application.RefreshDatabaseWindow
    
    'varie righe per la gestione errori
    end sub
    
    Sub connTab(nomeTabellaRemota As String, nomeTabellaLocale As String)
    Dim db As Database
    Dim td As TableDef
    
    Set db = CurrentDb
    
    Set tdf = db.CreateTableDef(nomeTabellaLocale)
    tdf.Connect = "ODBC;DRIVER={Oracle in OraClient11g_home1};DBQ=nomeDB;UID=user;PWD=password"
    
    tdf.SourceTableName = nomeTabellaRemota
    
    db.TableDefs.Append tdf
    db.Close
    Set db = Nothing
    Application.RefreshDatabaseWindow
    
    End Sub
    
    Come dicevo il codice funziona, è da ottimizzare un po'. Ma non vedo la tabella in caricamento finché non ha finito di collegare le tabelle. Pensavo di risolvere con una maschera di avvio diversa da quella standard dove appare un messaggio, quando ha finito di collegare le tabelle la maschera apre la maschera principale (quella che ora uso all'avvio) e poi si chiude in automantico. Però mi sembra un po' artificioso ed inelegante.

    Grazie in anticipo per l'aiuto.
Devi accedere o registrarti per scrivere nel forum
3 risposte