Copiare record tra due tabelle

di il
15 risposte

Copiare record tra due tabelle

Buongiorno a tutti,

E' da un pò che ho approcciato Access e sto cercando di realizzare un programmino gestionale.

Ho creato:

una tabella ANAGRAFICHE CLIENTI che raccoglie i seguenti campi: IDCLIENTE (chiave primaria), RAGIONE SOCIALE, VIA,.....etc....)

una tabella PREVENTIVI che raccoglie i seguenti campi: IDPREVENTIVO (chiave primaria), IDCLIENTE, NUMEROPREVENTIVO, RIFERIMENTO,.....etc....)

una tabella DETTAGLIO_PREVENTIVO che raccoglie i seguenti campi: IDDETTAGLIOPREVENTIVO (chiave primaria), IDPREVENTIVO, CODICEARTICOLO, DESCRIZIONE, QUANTITA.....etc....)

Relazione 1-molti tra ID CLIENTE di ANAGRAFICHE CLIENTI e IDCLIENTE di PREVENTIVI

Relazione 1-molti tra IDPREVENTIVO di PREVENTIVI e IDPREVENTIVO di DETTAGLIO-PREVENTIVO

Inserisco i dati per mezzo di una maschera e una sottomaschera.

Esistono le tabelle FATTURE e DETTAGLIO_FATTURA legate dalle stesse relazioni e che hanno in comune molti campi delle tabelle PREVENTIVI e DETTAGLIO_PREVENTIVO.

Analogamente una maschera e una sottomaschera permettono l'inserimento dei dati di fatturazione.

Vorrei creare un pulsante nella maschera dei preventivi che apra la maschera di fatturazione (in modo da generare il nuovo numero fattura) e mi permetta di accodare il preventivo corrente nelle tabelle relative alla fatturazione evitando di dover immettere manualmente tutte le informazioni comuni.

Ho fatto diversi tentativi senza ottenere il risultato sperato.

Con la funzione INSERT INTO in una query di accodamento ho ottenuto la copia dell'intera tabella.....
Ho anche provato a cercare aiuto nel support.microsoft (Come copiare un Record utilizzando l'insieme di campi e proprietà Value)

Dim MyDB As Database, Tbl1 As Table, Tbl2 As Table
Set MyDB = OpenDatabase("BIBLIO.MDB") ' Open Database.
Set Tbl1 = MyDB.OpenTable("Publishers") ' Open Table.
Set Tbl2 = MyDB.OpenTable("Publishers") ' Open Table.

For i = 0 to Tbl1.Fields.Count - 1
Tbl2(Tbl1.Fields(i).Name).Value = Tbl1.Fields(i).Value
Next

Ma pur avendo creato un DB di prova con le due sole tabelle indicate nell'esempio ricevo un errore di compilazione nella definizione della tabella Tbl1 As Table....

Mi sono proprio arenato.
Qualcuno mi darebbe una mano? Esiste un diverso approccio al problema?

Grazie anticipatamente

15 Risposte

  • Re: Copiare record tra due tabelle

    In che guida hai trovato la definizione di un Oggetto chiamato [Table]...?
    Non esiste... esiste TableDef nella Collection TableDefs... ma nel tuo caso addirittura è un oggetto Recordset appartenente a DAO...!

    Poi nel codice scrivi:
    Dim MyDB As Database, Tbl1 As Table, Tbl2 As Table
    Set MyDB = OpenDatabase("BIBLIO.MDB") ' Open Database.
    Set Tbl1 = MyDB.OpenTable("Publishers") ' Open Table.
    Set Tbl2 = MyDB.OpenTable("Publishers") ' Open Table.
    
    For i = 0 to Tbl1.Fields.Count - 1
    Tbl2(Tbl1.Fields(i).Name).Value = Tbl1.Fields(i).Value
    Next 
    dove Tbl1 e Tbl2 puntano sempre entrambi allo stesso DB ed alla stessa Tabella... quindi cosa vuoi fare...? Duplicarli...?

    Boh... hai valutato una Query di questo tipo
    
    INSERT INTO T1 IN 'C:\MyData.mdb' SELECT * FROM T2;
  • Re: Copiare record tra due tabelle

    @Alex ha scritto:


    In che guida hai trovato la definizione di un Oggetto chiamato [Table]...?

    L'ho trovato qui.... https://support.microsoft.com/en-us/kb/110588/i
    (Come copiare un Record utilizzando l'insieme di campi e proprietà Value)

    Non esiste... esiste TableDef nella Collection TableDefs... ma nel tuo caso addirittura è un oggetto Recordset appartenente a DAO...!

    Poi nel codice scrivi:
    Dim MyDB As Database, Tbl1 As Table, Tbl2 As Table
    Set MyDB = OpenDatabase("BIBLIO.MDB") ' Open Database.
    Set Tbl1 = MyDB.OpenTable("Publishers") ' Open Table.
    Set Tbl2 = MyDB.OpenTable("Publishers") ' Open Table.
    
    For i = 0 to Tbl1.Fields.Count - 1
    Tbl2(Tbl1.Fields(i).Name).Value = Tbl1.Fields(i).Value
    Next 
    dove Tbl1 e Tbl2 puntano sempre entrambi allo stesso DB ed alla stessa Tabella... quindi cosa vuoi fare...? Duplicarli...?
    [/color]
    No, il DB è lo stesso ma le tabelle cambiano. Mi sembrava il codice riportato sopra trasferisse i campi del record dalla Tbl1 alla Tbl2....

    Boh... hai valutato una Query di questo tipo
    
    INSERT INTO T1 IN 'C:\MyData.mdb' SELECT * FROM T2;
    [/color]

    La mia necessità consiste nell'emissione di una fattura a seguito dell'accettazione di un preventivo senza dover copiare manualmente i dati contenuti nei campi interessati.

    Aperta la maschera del preventivo, vorrei che i dati in essa contenuti (nelle relative due tabelle PREVENTIVI e DETTAGLIO_PREVENTIVO) fossero accodati nelle tabelle FATTURE e DETTAGLIO_FATTURA.

    LA query proposta INSERT INTO T1 IN 'C:\MyData.mdb' SELECT * FROM T2;[/code][/quote] credo sia destinata al trasferimento tra due DB distinti. Sbaglio?
    Perdonate la mia ignoranza, sto iniziando ora a sbattere la testa con i codici......
  • Re: Copiare record tra due tabelle

    Credo tu non abbia letto benissimo... ti risulta sia codice per Access...?
    Leggi molto bene...!! In fondo
    
    Le informazioni in questo articolo si applicano a:
    
        Microsoft Visual Basic 3.0 Professional Edition
    Se le Tabelle sono nello stesso DB la cosa è ancora più semplice, anche se il dubbio del perchè devi duplicare dati in 2 Tabelle è molto grande...

    In tutti i casi se tu avessi letto bene l'articolo ti suggeriva il metodo che io ti ho suggerito adatto a 2 DB differenti riferito allo stesso DB
    
    INSERT INTO ToTableName SELECT * FROM FromTableName
  • Re: Copiare record tra due tabelle

    La duplicazione ritengo sia necessaria in quanto i preventivi devono avere una propria numerazione e vanno archiviati.
    Allo stesso modo le fatture hanno una loro numerazione (indipendente da quella dei preventivi) e anch'esse devono essere archiviate.

    Come indicato nel primo post, avevo provato la strada del codice
    INSERT INTO ToTableName SELECT * FROM FromTableName

    Ma senza una condizione WHERE ottenevo la copia dell'intera tabella.

    Attualmente con la query di accodamento QueryPREVENTIVOFATTURA:
    INSERT INTO FATTURE ( IDCLIENTE, RIFERIMENTO, PAGAMENTO, BANCA, IBAN, TRASPORTO, PORTO, VETTORE )
    SELECT IDCLIENTE, RIFERIMENTO, PAGAMENTO, BANCA, IBAN, TRASPORTO, PORTO, VETTORE
    FROM PREVENTIVI
    WHERE NUMEROPREVENTIVO = [Forms]![RICERCA PREVENTIVO]![NUMEROPREVENTIVO];
    Copio il solo record di interesse.

    Le due difficoltà che sto incontrando ora sono:

    1)Nella generazione del nuovo record nella tabella FATTURE, il numero fattura non viene
    incrementato e il campo NUMERO FATTURA resta vuoto.
    Ho creato un pulsante con il seguente codice:
    Private Sub Comando31_Click()
    DoCmd.OpenModule "Progressivo"
    Call GeneraProgressivo
    DoCmd.OpenQuery "QueryPREVENTIVOFATTURA"
    (Il modulo PROGRESSIVO esegue l'incremento del numero fattura)

    2)Non riesco a fare in modo che vengano copiati anche i campi della tabella DETTAGLI_PREVENTIVO nella tabella DETTAGLI_FATTURA.
    Ho provato ad accodare al codice INSERT INTO......, dopo il ; una seconda operazione INSERT INTO ma non va.
    Anche dividendo l'operazione in due query non sono riuscito....
  • Re: Copiare record tra due tabelle

    Essendo un atabella Dettagli, avrai una FK(Chiave Esterna) che lega la Tabella Fattura alla Dettagli... quindi il tuo INSERT ora dovrà avere come WHERE la FK...

    Quindi dopi l'insert devi Recuperare il NUMERO FATTURA(credo sia il campo che lega le 2 Tabelle) e fare il 2° insert...
  • Re: Copiare record tra due tabelle

    Allora, la chiave è IDPREVENTIVO, ho provato questo codice considerando il solo campo CODICEARTICOLO:
    INSERT INTO FATTURE ( IDCLIENTE, RIFERIMENTO, PAGAMENTO, BANCA, IBAN, TRASPORTO, PORTO, VETTORE )
    SELECT IDCLIENTE, RIFERIMENTO, PAGAMENTO, BANCA, IBAN, TRASPORTO, PORTO, VETTORE
    FROM PREVENTIVI
    WHERE NUMEROPREVENTIVO = [Forms]![RICERCA PREVENTIVO]![NUMEROPREVENTIVO];
    
    INSERT INTO DETTAGLIO_FATTURA (CODICEARTICOLO)
    SELECT CODICEARTICOLO
    FROM DETTAGLIO_PREVENTIVO
    WHERE IDPREVENTIVO = IDPREVENTIVO;
    Ma l'errore che ho è un pop up nella chiusura della query che recita "Caratteri non previsti dopo la fine dell'istruzione SQL" e mi evidenzia il secondo INSERT....

    Non capisco poi come nella copia destinata alla fattura i dettagli si leghino alla fattura stessa....
    Come posso fare a risolvere anche l'incremento del numero fattura?
  • Re: Copiare record tra due tabelle

    Access non supporta le query 'accodate' quindi l'errore è dovuto.
    Ma quand'anche lo fossero è comunque sbagliata la logica di implementazione.

    Prima devi generare la fattura, così da ottenere il nuovo IDFattura.
    Poi dovrai inserire i dettagli indicando singolarmente tutti i campi.

    Ovviamente, le due operazioni dovranno essere incluse all'interno di una transazione.

    P. S. Vi sono altre inesattezze ma intanto partiamo da qui

  • Re: Copiare record tra due tabelle

    Ciao,
    Grazie per l'intervento...

    Ho provato a creare un pulsante che apra la tabella FATTURE, crei un nuovo record (in modo da avere un nuovo ID, e lanci il modulo di conteggio fatture per accodare la numerazione.
    Private Sub Comando31_Click()
    DoCmd.OpenTable "FATTURE"
    DoCmd.GoToRecord , , acNewRec
    DoCmd.OpenModule "Progressivo"
    GeneraProgressivo
    Ma ottengo solo l'apertura della tabella, l'apertura del modulo e nessun aggiornamento nella tabella FATTURE.
    Come faccio a dire di copiare il progressivo ottenuto nel relativo campo?

    Per quanto riguarda la transazione, ho cercato qualche informazione... Se non ho capito male dovrebbe permettere l'esecuzione in sequenza di due INSERT consecutivi. E' questo il motivo per cui me la consigli?

    Grazie ancora
  • Re: Copiare record tra due tabelle

    Spiegati meglio:
    cosa intendi quando scrivi 'apra la tabella FATTURE' ?
    Intendi proprio la Tabella oppure la Maschera?
    In realtà non si può aprire una tabella! Caso mai la si interroga (aprendo un recordset, ad es.)

    In un gestionale di fatturazione il numero progressivo del documento è 'temporaneo', fino alla effettiva registrazione del documento.
    Questo perché in multi-utenza se due utenti creano una nuova fattura verrebbero generati due progressivi, ma se poi uno degli utenti rinuncia a salvare la fattura, il relativo progressivo andrebbe perso (ovvero si crea un 'buco').

    Secondo me il metodo GeneraProgressivo dovrebbe essere una Function che restituisce il progressivo del documento (in base ovviamente a determinati parametri, es: Anno).

    Quindi, va bene generare il progressivo al momento della nuova fattura, ma poi in fase di registrazione del odcumento tale progressivo dovrebbe essere rigenerato nuovamente per essere sicuri che sia effettivamente corretto.

    Transazione
    Hai capito male, o meglio non è proprio così.
    Una transazione di assicura che QUALSIASI operazione sui dati (INSERT, UPDATE e DELETE) siano rese effettive solo se tutte le operazioni sono andate a buon fine.
    In caso contrario, se qualcosa va storto, verranno annullate tutte.

    Ovviamente non è una cosa automatica!
    L'implementazione è a carico dello sviluppatore, che dovrà codificare un gestore di errori che intercetti qualsiasi errore possa verificarsi per annullare.

    Oltretutto, dovresti anche registrare nel preventivo e/o nei dettagli (dipende dalla gestione che fai) che quel documento è già stato fatturato, in tutto o in parte (può accadere che il preventivo non venga fatturato completamente).

    Come vedi le operazioni sono molteplici, ecco perché è indispensabile (ma lo è sempre) una transazione, altrimenti potresti correre il rischio che hai generato sì la fattura, ma per colpa di una riga di codice, il preventivo non risulta fatturato, e chi gestisce le fatturazioni in azienda si trova spiazzato.

    Chiaro che molte di queste cose devono essere fatte via codice VBA, MSAccess può darti una mano, ma fino ad un certo punto.

  • Re: Copiare record tra due tabelle

    Con il codice chiedo di visualizzare a schermo il contenuto della tabella FATTURE.... (Pensavo fosse necessario averla "aperta" per potervi inserire i dati su un nuovo ID).... e lo fa, chiedo di creare un nuovo record, poi mi mostra il testo del modulo "Progressivo" che ha definita all'interno la function "GeneraProgressivo" ma non so come gestire il risultato.... non so neanche se lo ha generato....
    Se fosse possibile gestire il tutto dalla maschera collegata alle tabelle FATTURE e DETTAGLIO_FATTURA sarebbe ancora meglio...
    Non so neanche come gestire la doppia generazione del progressivo che mi indichi... Senza particolari accorgimenti non avrei alla fine un ulteriore incremento? Dovrei forse far fare un controllo imponendo che il secondo progressivo debba essere pari al vecchio+1?

    Sono proprio bloccato, potresti mostrarmi, almeno a grandi linee, un codice di esempio che mi permetta di capire quali siano le istruzioni che mi necessitano?
  • Re: Copiare record tra due tabelle

    Mi pare che tu abbia troppe incognite...

    Per gestire queste operazioni è indispensabile avere buone conoscenze di VBA e soprattutto del linguaggio SQL.
  • Re: Copiare record tra due tabelle

    Ok, grazie lo stesso, cercherò altrove almeno uno spunto per capire cosa studiare per risolvere questo problema.
  • Re: Copiare record tra due tabelle

    Luigi9 ha scritto:


    Ok, grazie lo stesso, cercherò altrove almeno uno spunto per capire cosa studiare per risolvere questo problema.
    Mi pare che tu non abbia proprio capito:
    lo spunto te lo l'ho già dato: devi studiare i linguaggi VBA e SLQ.
  • Re: Copiare record tra due tabelle

    Buona sera a tutti,

    Dopo qualche tempo ho avuto modo rimettere mano al mio database.....

    Sono riuscito in un modo che ai più potrà sembrare "maccaronico" (ma funzionante) a risolvere quasi completamente.

    Soddisfacendo la mia massima aspirazione ora l'operazione viene eseguita mediante pulsante lavorando con le maschere piuttosto che con le tabelle.

    Per quanto riguarda le voci delle maschere ho adottato il seguente codice:
    Private Sub Comando31_Click()
    DoCmd.OpenForm ("EMISSIONE FATTURA")
    DoCmd.GoToRecord , , acNewRec
    Forms![EMISSIONE FATTURA]!IDCLIENTE = Forms![RICERCA PREVENTIVO]!IDCLIENTE
    Forms![EMISSIONE FATTURA]!RIFERIMENTO = Forms![RICERCA PREVENTIVO]!RIFERIMENTO
    ............................................................
    ............................................................
    copiando una ad una le voci di interesse.

    Il problema sorge nella copia dei record relativi alle sottomaschere. Purtroppo adottando lo stesso metodo viene trasferito solo il primo record e non tutti quelli elencati nella sottomaschera di partenza ([DETTAGLIO_PREVENTIVO Sottomaschera]).
    Forms![EMISSIONE FATTURA]![DETTAGLIO_FATTURA Sottomaschera]!CODICEARTICOLO = Forms![RICERCA PREVENTIVO]![DETTAGLIO_PREVENTIVO Sottomaschera]!CODICEARTICOLO
    Forms![EMISSIONE FATTURA]![DETTAGLIO_FATTURA Sottomaschera]!DESCRIZIONE = Forms![RICERCA PREVENTIVO]![DETTAGLIO_PREVENTIVO Sottomaschera]!DESCRIZIONE
    ..................................................................................
    ..................................................................................
    
    Ho provato con i comandi DoCmd.GoToRecord , , acNewRec e DoCmd.GoToRecord , , acNext per
    spostarmi ai record successivi della sottomaschera ponendo a monte (come prova) una funzione
    For...Next ipotizzando un massimo di 10 voci senza ottenere risultati.

    C'è qualcuno che mi dia una dritta?

    Grazie mille
Devi accedere o registrarti per scrivere nel forum
15 risposte