[VB6] Gestione specifiche import-export di database Access

Per il mio lavoro, spesso ho la necessità di gestire l’importazione e l’esportazione di file di dati (tipicamente file di testo con record a lunghezza fissa) da Microsoft Access. Per queste attività ho sempre utilizzato la gestione delle specifiche di importazione/esportazione nativa di Access, ma è una funzionalità che non mi ha mai soddisfatto completamente.

Per esempio ci sono stati dei casi in cui non sono riuscito a modificare una specifica già esistente e ho dovuto ricrearla da zero, senza contare il problema di inserire un campo all’interno di una specifica già esistente: in questo caso è necessario ricalcolare manualmente il carattere di partenza di ciascun campo successivo. Anche lo spostamento di un campo in una diversa posizione è un’attività che può diventare un’atroce perdita di tempo.

Ecco quindi che, diverso tempo fa, ho pensato di creare un progetto in Visual Basic 6.0 (download di 153 kb). Anzi, i progetti sono più di uno:

  • un progetto che comprende l’interfaccia principale (ImportExport.vbp)
  • un progetto che comprende l’interfaccia per la gestione delle specifiche (Specifiche.vbp)
  • un progetto per gestire le attività di importazione (Import.vbp)
  • un progetto per gestire le attività di esportazione (Export.vbp). 

Con il link sopra riportato potete scaricare tutti questi progetti, con anche gli eseguibili già compilati, un database di prova e alcuni file di testo, con qualche specifica di importazione/esportazione già caricata.

Le specifiche, infatti, vengono caricate in una tabella di Access. E’ possibile estrarre anche le specifiche da un database già esistente e salvarle in questa tabella speciale, così da centralizzare tutte le attività di importazione/esportazione.

Non è tutto: considerato che potrebbe essere necessario eseguire un’importazione/esportazione anche direttamente da un programma VBA scritto all’interno di Access (o di un altro prodotto Office) o perfino in un proprio programma scritto in qualsiasi altro linguaggio (perfino VB.NET), ho pensato di gestire i parametri della riga di comando utilizzati per avviare i programmi Import.exe e Export.exe.

In questo modo è possibile avviare, per esempio, Import.exe passandogli già i parametri necessari per eseguire l’importazione senza nemmeno aprire la sua interfaccia grafica! Il trucco sta tutto nell’evento Load del form Import.frm:

Private Sub Form_Load() 
    ReDim argv(5) As String 
    Dim i As Integer 
    
    Dim sNomeFile 
    Dim sNomeSpecifica 
    Dim sNomeDB 
    Dim sNomeTabella 
      

    ' legge la riga di comando: 
    argv = GetCommandLine(argv) 
    
    If argv(1) <> "" Then 
        ' i parametri vengono passati secondo quest'ordine: 
        sNomeFile = argv(1) 
        sNomeSpecifica = argv(2) 
        sNomeDB = argv(3) 
        sNomeTabella = argv(4) 
        sFlagDelete = argv(5) 
        
        If argv(5) = 1 Then 
            Call DeleteTable(sNomeDB, sNomeTabella) 
        End If 
        
        If argv(1) <> "" Then 
            Call ImportaFile(sNomeFile, sNomeSpecifica, sNomeDB, sNomeTabella) 
        End If 
        
        ' annulla il caricamento del form: 
        Unload Me 
        Exit Sub 
    End If 
    
    ReDim arraySpecifiche(1) 
    arraySpecifiche = ElencaSpecifiche() 
    
    Me.txtNomeSpecifica.Clear 
    For i = 1 To arraySpecifiche(0) 
        Me.txtNomeSpecifica.AddItem arraySpecifiche(i) 
    Next i 
        
End Sub

Per ultima, una piccola precisazione: questo programma l’ho scritto qualche anno fa, ma non l’avevo mai pubblicato prima, quindi è una soluzione assolutamente inedita.

Può sembrare anacronistico un progetto scritto in VB6 come nuova soluzione, visto che ormai .NET è diventata la piattaforma di sviluppo prevalente, ma c’è una considerazione da tenere presente: tra i file forniti con il file compresso c’è anche un report dell’analisi eseguita con Code Advisor per verificare la compatibilità dei progetti con VB.NET. L’esito è assolutamente confortante, dato che viene segnalato solo un piccolo problema relativo a Option Explicit, facilmente eliminabile.

Ovviamente questo progetto può essere utilizzato come prototipo per realizzare una soluzione analoga e più orientata agli oggetti, utilizzando codice VB.NET puro.

In ogni caso spero che possa essere utile a chi, come me, ha avuto problemi nell’utilizzo delle funzionalità native di Access per la gestione delle specifiche di importazione/esportazione.

Annunci

Pubblicato il 15 febbraio 2008, in Articoli vari, Office con tag , . Aggiungi il permalink ai segnalibri. 5 commenti.

  1. Ciao Mario grazie mille per la tua segnalazione sul mio blog! un grosso saluto e buon lavoro

    Andrea

    Mi piace

  2. Giovanni Puglisi

    Ho letto l’articolo e scaricato i file. Premetto che uso Windows Vista e Access2007. Dagli eseguibili, quando clicco sul pulsante “Carica specifica da database” dal form “Specifiche” non succede nulla. La mia necessità è quella d’importare dei files di testo che contengono dati con campi delimitati; le colonne contengono in modo disomogeneo dati che ho necessità d’importare in un’unica tabella già definita. Per essere più chiaro faccio un esempio:
    file1.txt
    data; ora; durata; campo da saltare; chiamante; campo da saltare; chiamato; … campo …;

    file2.txt
    ora; data; campo da saltare; chiamato; chiamante; campo da saltare; … campo …;

    i dati dovrebbero confluire nella tabella con la seguente definizione:
    data ora durata chiamante chiamato.
    Visto che è richiesto un commento non so se sia il posto giusto per la mia richiesta, per il momento ringrazio ugualmente per l’aiuto e per la presenza di siti come questo che tanto supportano i principianti e gli esperti in cerca di spunti utili.
    Grazie.
    Giovanni

    Mi piace

  3. Normalmente l’importazione di file di testo avviene con un “tracciato record” ben definito e quindi anche l’ordine dei campi dovrebbe essere sempre lo stesso.

    Certamente possono essere fatte delle manipolazioni, utilizzando una tabella di appoggio e quindi adattando i dati importati alla tabella di destinazione.

    Se la prima riga del file contiene i nomi dei campi, si potrebbe importare il file in un foglio Excel (magari con l'”automazione di Excel”) e poi da questa importare in una tabella di Access, ma è importante che i nomi dei campi siano sempre uguali, altrimenti bisogna comunque intervenire modificandoli sempre con l’automazione o manualmente.

    La cosa migliore, comunque, è sempre quella di imporre a chi produce i file di mantenere sempre la stessa struttura (tracciato record), perché normalmente lo scambio avviene con un formato definito a priori.

    Per quanto riguarda Access 2007: non l’ho ancora utilizzato ma lo farò tra breve, in quanto ho iniziato un nuovo libro che tratterà argomenti relativi ai database, con alcuni esempi in Visual Basic 2008 (quindi non VB6…).

    Può darsi che Access 2007 abbia una gestione delle specifiche di import/export diversa dalle versioni precedenti. Se così è, vedrò di esaminare anche questa problematica e di pubblicare un articolo per spiegare come si risolve il problema.

    Ultimo commento: se devi risolvere il problema in VB6, temo di deluderti, perché alcuni mesi or sono ho deciso di non supportare più codice VB6, perché ormai è un linguaggio e un ambiente non più supportato dalla stessa Microsoft, quindi senza più alcuna prospettiva di evoluzione e di miglioramento. Infatti in questo blog ho pubblicato, in seguito, solo articoli e notizie su VB.NET e C#, oltre ad altre tecnologie correlate.

    Mi piace

  4. Giovanni Puglisi

    Intanto grazie per la risposta. Riscrivo per far conoscere la soluzione che ho trovato, non utilizzando VBA ma VB.Net, grazie anche al contenuto del Suo libro “Visual Basic 2008 spiegato a mia nonna”. Di seguito riporto il codice:

    Imports System.IO
    Imports System.Collections.ArrayList
    Public Class Form1
    Dim nuovoArray = New ArrayList
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim archivio As String
    Dim i As Integer
    Dim linea As String
    Dim lista = New ArrayList()
    Dim destinazione As String

    archivio = "C:\fileditesto.txt"
    destinazione = "C:\temp.txt"

    'Verifico se il file esiste. Se è vero lo elimino
    If File.Exists(destinazione) Then
    File.Delete(destinazione)
    End If

    FileOpen(1, archivio, OpenMode.Input) 'apro in input il file di testo
    FileOpen(2, destinazione, OpenMode.Output) ' creo un nuovo file di destinazione

    While Not EOF(1) 'ciclo fino alla fine del file
    linea = LineInput(1) 'leggo una riga
    If linea = "" Or linea = Chr(12) Then ' rimuovo tutte le righe vuote e le interruzioni di pagina
    lista.Remove(linea)
    End If
    lista.Add(linea) 'aggiungo all'arraylist la riga
    End While

    Dim testo As String
    testo = ""
    For i = 13 To lista.Count - 58 ' leggo le righe che m'interessano eliminando quelle all'inizio e alla file
    testo = testo & lista(i) & Chr(13)
    Next i

    PrintLine(2, testo) 'scrivo i nuovi risultati nel file di destinazione
    FileClose(1) 'chiudo i files
    FileClose(2)

    Dim destinazione2 As String 'Creo la variabile che conterrà il percorso del file definivo
    destinazione2 = "C:\NuovoFileTesto.txt"

    'Verifico se il file esiste. Se è vero lo elimino
    If File.Exists(destinazione2) Then
    File.Delete(destinazione2)
    End If

    FileOpen(1, destinazione, OpenMode.Input) 'Apro il nuovo file prodotto prima
    FileOpen(2, destinazione2, OpenMode.Output) 'Preparo il file per l'output

    Dim rigo As String
    While Not EOF(1) 'ciclo fino alla fine del file
    rigo = LineInput(1) 'leggo una riga
    If rigo = "" Or rigo = Chr(12) Then 'elimino righe vuote e interruzioni di pagina se esistono
    lista.Remove(rigo)
    End If
    nuovoArray.Add(rigo) 'aggiungo alla lista la riga
    End While
    FileClose(1)

    Dim righeOrdinate As String ' creo una variabile che conterrà tutto il testo della nuova tabella prodotta dal nuovo output con le colonne ordinate come desiderato
    righeOrdinate = ""
    Dim b As Integer
    For b = 1 To nuovoArray.Count - 1
    righeOrdinate = righeOrdinate + OrdinaCampi(destinazione, b, 1, 10) & " " & OrdinaCampi(destinazione, b, 12, 8) & Chr(10) ' richiamo la funzione OrdinaCampi
    Next b
    PrintLine(2, righeOrdinate) ' stampo i risultati
    FileClose(2) ' chiudo il file
    Kill(destinazione) 'elimino il file intermedio

    End Sub
    Function OrdinaCampi(ByVal archivio As String, ByVal nRiga As Integer, ByVal colonna As Integer, ByVal larghezza As Integer) As String

    Dim riga As String
    'Dim nuovoArray As New ArrayList
    Dim campo As String
    FileOpen(1, archivio, OpenMode.Input)

    campo = ""

    While Not EOF(1) 'ciclo fino alla fine del file
    riga = LineInput(1) 'leggo una riga
    nuovoArray.Add(riga) 'aggiungo alla lista la riga
    End While
    If nRiga > 0 Then
    campo = nuovoArray(nRiga - 1)
    If larghezza > 0 Then
    campo = campo.Substring(colonna - 1, larghezza).TrimEnd
    End If
    FileClose(1)
    Return (campo)
    End If

    End Function

    Per arrivare a questo codice mi sono avvalso molto anche di quanto contenuto nella pagina internet:

    Liked by 1 persona

  1. Pingback: problema funzione transfer da access 2003 a access 2007 - Access - Pagina 2

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

%d blogger hanno fatto clic su Mi Piace per questo: