Acquista i nostri libri consigliati su Amazon.it
+ Rispondi al messaggio
Visualizzazione dei risultati da 1 a 8 su 8

Tabelle Prestazioni e DettaglioPrestazioni e loro relazioni

  1. #1
    L'avatar di RaoulDuke
    RaoulDuke non è in linea Scolaretto
    Post
    141
    Like Inviati  
    3
    Like Ricevuti  
    0
    Sto avendo dei problemi nella gestione delle maschere relative a due tabelle in relazione uno a molti. Dei problemi ne sto parlando in questo 3D ma la discussione è andata abbondantemente off topic, per cui continuo qui.

    Tali problemi mi fanno sorgere il dubbio che ci sia un errore di base nelle relazioni tra le tabelle, quindi vorrei gentilmente chiedere il vostro parere a tal proposito.

    Tabelle:
    - tabPrestazioni (LATO UNO): IDPrestazione (PK), IDCliente, Data, Sconto, ecc
    - tabDettagliPrestazioni (LATO MOLTI): IDDettagliPrestazione (PK), IDPrestazione(FK), IDPaziente, IDProdotto, Descrizione, PrezzoUnitarioDef, Quantità, SubTotale, Sconto

    La tabPrestazioni rappresenta in sostanza la testata della fattura, mentre la tabDettagliPrestazioni le singole righe.
    Si tratta di prestazioni generate da un ambulatorio veterinario e questo complica leggermente le cose, dato che l'intestazione fattura fa riferimento al Cliente (il proprietario dell'animale), mentre i dettagli al Paziente (l'animale, ragione per la quale compare IDPaziente nella tabDettagliPrestazioni).

    Il problema nasce al momento in cui l'utente vuole immettere nuove prestazioni, creando record nelle rispettive tabelle.
    Ho creato un classico sistema Form - SubForm.
    Quindi l'utente dovrà immettere nuovi record nel Form (una nuova testata) e al contempo nuovi record nel subfrom (le singole righe).

    Se uso un sistema di immissione dati con controlli associati nella form e nella subform l'inserimento procede senza problemi.
    Vorrei invece poter utilizzare un pulsante nella form che crei un nuovo record nella subform (nel suo recordset) dopo aver raccolto i dati da controlli non associati. In questo caso ottengo diversi errori.

    Ho provato con il metodo

    Recordset.AddNew
    ...
    ...
    ...
    RecordSet.Update
    
    Se agisco solo sul recordset della tabella figlia, non mi fa fare l'update e ricevo come messaggio di errore

    Impoossibile aggiungere o modificare il record. Nella tabella tabPrestazioni è necessario un record correlato.
    Questo, credo io, perchè la tabelle sono collegate da una relazione che utilizza la chiave primaria della tabella madre, che al momento dell'interazione del pulsante nella maschera non è ancora stata immessa in tabella.

    Ho perciò provato a inserire prima un nuovo record nel Recordset della tabella tabPrestazioni, recuperare l'IDPrestazione così generato e inserire poi il record nel Recordset della tabella figlia:

    Private Sub cmdInserisci_Click()
        'Ricava Descrizione Prodotto
        Dim DescrizioneProdotto As String
            DescrizioneProdotto = DLookup("Descrizione", "tabProdotti", "IDProdotto = " & Me.cboIDProdotto)
            
        'Ricava IDListino
        Dim Listino As Integer
            Listino = DLookup("IDListino", "tabClienti", "IDCliente =" & Me.cboIDCliente)
        
        'Ricava Prezzo Unitario
        Dim Prezzo As Double
            Prezzo = retrieveIdPrezzoUnitario(Me.cboIDProdotto, Listino, Me.Data)
               
        
        
        Dim wrk As DAO.Workspace
        Dim dbs As DAO.Database
        Dim rst As DAO.Recordset
        Dim rst2 As DAO.Recordset
        Dim Prestazione As Long
       
        Set wrk = DBEngine.Workspaces(0)
        Set dbs = CurrentDb
        Set rst = dbs.OpenRecordset("tabDettagliPrestazioni")
        Set rst2 = dbs.OpenRecordset("tabPrestazioni")
    
            'Tabella Prestazioni
            rst2.AddNew
            rst2![IDCliente] = Me.cboIDCliente
            rst2![Data] = Me.Data
            rst2.Update
            rst2.Bookmark = rst2.LastModified
            Prestazione = rst2!IDPrestazione
            
            'Tabella Dettagli Prestazioni
            rst.AddNew
            rst![PrezzoUnitarioDef] = Prezzo
            rst![IDPrestazione] = Prestazione
            rst![IDPaziente] = Me.cboIDPaziente
            rst![IDProdotto] = Me.cboIDProdotto
            rst![Quantità] = Me.txtQuantita
            rst![Descrizione] = DescrizioneProdotto
            rst![SubTotale] = Round(rst![PrezzoUnitarioDef] * rst![Quantità], 1)
            rst.Update
            
            Me.frmDettaglioPrestazioniProva.Form.Requery
        
            rst.Close
            dbs.Close
            wrk.Close
       
        Set rst = Nothing
        Set dbs = Nothing
        Set wrk = Nothing
           
    Exit Sub
    End Sub
    
    In questo modo i record vengono correttamente aggiornati nelle tabelle, ma il requery finale della subform non mi mostra i nuovi record.
    Questa è la ragione che mi fa sospettare un problema di base nelle relazioni tra le due tabelle, ma dopo molto tempo passato a ragionare mi sono perso.

    Avrei bisogno del vostro aiuto.

    Grazie a chiunque voglia leggere il romanzo e darmi una mano.

  2. #2
    OsvaldoLaviosa non è in linea Topo di biblioteca
    Post
    3,072
    Like Inviati  
    0
    Like Ricevuti  
    0
    Quote Originariamente inviato da RoulDuke
    Tabelle:
    - tabPrestazioni (LATO UNO): IDPrestazione (PK), IDCliente, Data, Sconto, ecc
    - tabDettagliPrestazioni (LATO MOLTI): IDDettagliPrestazione (PK), IDPrestazione(FK), IDPaziente, IDProdotto, Descrizione, PrezzoUnitarioDef, Quantità, SubTotale, Sconto
    La tabPrestazioni rappresenta in sostanza la testata della fattura, mentre la tabDettagliPrestazioni le singole righe.
    OK dal punto di vista relazionale. Abbi cura di nominare i campi sempre al SINGOLARE, quindi direi IDDettaglioPrestazione.

    Quote Originariamente inviato da RoulDuke
    Ho creato un classico sistema Form - SubForm.
    Quindi l'utente dovrà immettere nuovi record nel Form (una nuova testata) e al contempo nuovi record nel subfrom (le singole righe).
    Se uso un sistema di immissione dati con controlli associati nella form e nella subform l'inserimento procede senza problemi.
    OK. Mi sembra tutto normale.

    Quote Originariamente inviato da RoulDuke
    Vorrei invece poter utilizzare un pulsante nella form che crei un nuovo record nella subform (nel suo recordset) dopo aver raccolto i dati da controlli non associati.
    Non capisco. Perchè? Puoi spiegare meglio, magari con un esempio?
    ℹ️ Leggi di più su OsvaldoLaviosa ...

  3. #3
    L'avatar di RaoulDuke
    RaoulDuke non è in linea Scolaretto
    Post
    141
    Like Inviati  
    3
    Like Ricevuti  
    0
    Ciao Osvaldo e grazie per la risposta.
    I campi sono al singolare, ho sbagliato a scrivere.

    Ecco un'immagine della situazione che vorrei avere:



    Già questa configurazione mi dava problemi.
    Comunque in sostanza vorrei avere due caselle combinate, una per la scelta del Prodotto ed una per la scelta della quantità. Poi al click del pulsante creare il necessario record nella tabella figlia e farlo comparire nella subform.

    Perché questa impostazione?
    Il discorso è un po' complesso, provo a spiegartelo.
    La combobox del Prodotto ha come origine dati, due campi della tabProdotti (IDProdotto e Descrizione). Ho bisogno di intercettare l'IDProdotto da memorizzare nella riga della fattura, ma al contempo avere la possibilità di modificare la Descrizione.
    Questo perché in catalogo ho prodotti generici (tipo "intervento chirurgico" o "iniezione") che avrò bisogno di alterare nella riga della fattura ("intervento di splenectomia" o "iniezione duplocillina").

    Con una impostazione classica, dove vado ad immettere il record agendo direttamente nella sottomaschera, ho incontrato alcuni problemi di carattere pratico.

    Non so come gestire due cose che devono funzionare contemporaneamente:
    - la possibilità di digitare una stringa per la ricerca del prodotto direttamente nella combobox
    - la possibilità di modificare la descrizione del prodotto senza alterare l'IDProdotto

    L'unica soluzione che ho trovato è immettere una combobox per la scelta dell'IDProdotto (con menu in cui compaiano ovviamente anche le descrizioni dei prodotti) e poi una casella Descrizione che si popola con la descrizione del Prodotto, eventualmente da editare. Funziona. Ma nella combobox non posso digitare la stringa per la ricerca del prodotto (perché è associata all'IDProdotto e non alla descrizione) e mi ritrovo con un controllo nella subform per il quale non vi è necessità di visualizzazione.

    Per intenderci, una cosa così:



    La versione con il pulsante nella maschera mi permetterebbe invece di popolare la subform con un controllo descrizione editabile e di non dover mostrare il controllo IDProdotto
    Spero di essermi fatto capire

  4. #4
    OsvaldoLaviosa non è in linea Topo di biblioteca
    Post
    3,072
    Like Inviati  
    0
    Like Ricevuti  
    0
    Correggimi se sbaglio. Il campo Descrizione mi sembra sia STRETTAMENTE legato al IDProdotto. Per tanto deve comparire nella tabella Prodotti e non in DettagliPrestazioni.
    In sottomaschera DettagliPrestazioni predisponi una casella combinata che SCEGLIE IDProdotto, ma MOSTRI un campo testuale di Prodotto (non conosciamo tutti i campi di tabella Prodotti...non ho capito se si tratta proprio di Descrizione).
    ℹ️ Leggi di più su OsvaldoLaviosa ...

  5. #5
    L'avatar di RaoulDuke
    RaoulDuke non è in linea Scolaretto
    Post
    141
    Like Inviati  
    3
    Like Ricevuti  
    0
    Il campo descrizione Prodotto è legato all'IDProdotto esclusivamente nella tabella tabProdotti.
    La tabella tabDettagliPrestazioni non è collegata ad altre tabelle.
    È un discorso ampio e articolato, se ne era discusso un anno fa con gibra in questo 3D.

    Ecco le sue parole, per farti capire:

    Nel momento in cui compili un documento 'fiscale' quello diventa parte di uno storico quindi NON è più relazionabile con alcuna tabella.
    Sappiamo che un documento fiscale è gestito tramite due sole tabelle: TESTATE e RIGHE per cui i documenti fiscali (in quanto storico) devono essere relazionati solamente tra 'padre' (TESTATE) e 'figlio' (RIGHE).

    Ovvio che sia nelle TESTATE che nelle RIGHE continuo a memorizzare gli 'ID' relativi, ma non devono essere vincolanti, saranno utili solo per una eventuale analisi storica dei dati.
    I dati storici non devono dipendere da nessun'altra tabella se non da sé stessi!

    Questo permette al'utente di poter modificare i dati 'al volo' di qualsiasi informazione senza inficiare o compromettere i dati nelle tabelle 'anagrafiche'.
    La tabella tabProdotti fa unicamente da stampo per copiare la descrizione del prodotto che viene poi eventualmente adattata nella tabDettagliPrestazioni.
    Lo stesso vale per i prezzi. Prelevo il prezzo dalla tabPrezzi, ma poi lo posso modificare perché il dato nella tabDettagliPrestazioni non è collegato a quello della tabPrezzi.

    Quindi:
    Se io uso una combobox per la scelta dell'IDProdotto, che mostri, come dici tu, il campo Descrizione, non avrò la possibilità di modificare la stringa descrizione, perché non apparterrà all'origine dati della combobox.

    Ecco perchè devo prelevare il dato dalla tabProdotti (attraverso la combobox), ma poi trasferirlo sul controllo associato alla tabDettagliPrestazioni, dove potrà essere modificato.

  6. #6
    OsvaldoLaviosa non è in linea Topo di biblioteca
    Post
    3,072
    Like Inviati  
    0
    Like Ricevuti  
    0
    Ignoro la discussione con gibra di cui parli. Io, se non mi fornisci almeno una decina di valori, non riesco a capire nemmeno di cosa stiamo parlando.
    ℹ️ Leggi di più su OsvaldoLaviosa ...

  7. #7
    L'avatar di RaoulDuke
    RaoulDuke non è in linea Scolaretto
    Post
    141
    Like Inviati  
    3
    Like Ricevuti  
    0
    Ti ringrazio per lo sforzo.

    La discussione con gibra è linkata sopra e spiega perché le tabelle devono essere costruite in questo modo.
    Da cui la necessità, di cui parlavo sopra, di copiare i dati contenuti nelle tabelle tabPrezzi e tabProdotti e riportarli nella tabella tabDettaglioPrestazioni che sarà quella che contiene lo storico di tutte le transazioni effettuate e dove potranno essere modificati.

    Non riesco a spiegare meglio di quanto non abbia già fatto, il discorso purtroppo è articolato. Se leggi la discussione linkata, capirai senz'altro meglio.

    Ma lo scopo del mio thread era un altro.
    - capire se ho commesso errori nelle relazioni tra tabelle, cosa che tendo ad escludere
    - capire perché sebbene io riesca ad inserire i record nelle due tabelle (agendo sui recordset DAO come ho mostrato nel codice postato prima) non riesca a vederli nella subform dopo il requery di quest'ultima.

    Questo è il punto su cui vorrei focalizzarmi, perché altrimenti devo rispiegare tutto da capo e riprendere le discussioni avute un anno fa.

    Grazie mille!

  8. #8
    L'avatar di RaoulDuke
    RaoulDuke non è in linea Scolaretto
    Post
    141
    Like Inviati  
    3
    Like Ricevuti  
    0
    Alla fine credo di aver risolto.
    I punti critici erano due.

    - C'è la necessità di forzare l'immissione del record nella tabella madre, questo per evitare il messaggio di errore quando si prova a creare un nuovo record nella tabella figlia. L'ho fatto facendo perdere il focus alla form madre e passandolo ad un controllo della SubForm

    - Il metodo che utilizzavo per il requery era sbagliato.

    Private Sub cmdInserisci_Click()
        'Ricava Descrizione Prodotto
        Dim DescrizioneProdotto As String
            DescrizioneProdotto = DLookup("Descrizione", "tabProdotti", "IDProdotto = " & Me.cboIDProdotto)
            
        'Ricava IDListino
        Dim Listino As Integer
            Listino = DLookup("IDListino", "tabClienti", "IDCliente =" & Me.cboIDCliente)
        
        'Ricava Prezzo Unitario
        Dim Prezzo As Double
            Prezzo = retrieveIdPrezzoUnitario(Me.cboIDProdotto, Listino, Me.Data)
            
        'Ricava SubTotale
        Dim SubToto As Double
            SubToto = Round(Prezzo * Me.txtQuantita, 1)
               
        Dim wrk As DAO.Workspace
        Dim dbs As DAO.Database
        Dim rst As DAO.Recordset
        Dim Prestazione As Long
       
        Set wrk = DBEngine.Workspaces(0)
        Set dbs = CurrentDb
        Set rst = dbs.OpenRecordset("tabDettagliPrestazioni")
    
    
            'QUI BISOGNA CERCARE DI FORZARE L'IMMISSIONE IN tabPrestazioni
            
            Me.SubForm.SetFocus
            Me.SubForm.Form!IDProdotto.SetFocus
            
            'Creo il nuovo record in Tabella Dettagli Prestazioni
            rst.AddNew
            rst![PrezzoUnitarioDef] = Prezzo
            rst![IDPrestazione] = Me.IDPrestazione
            rst![IDPaziente] = Me.cboIDPaziente
            rst![IDProdotto] = Me.cboIDProdotto
            rst![Quantita] = Me.txtQuantita
            rst![Descrizione] = DescrizioneProdotto
            rst![SubTotale] = SubToto
            rst.Update
            
            Me.SubForm.SetFocus
            Me.SubForm.Form.Requery
        
            rst.Close
            dbs.Close
            wrk.Close
       
        Set rst = Nothing
        Set dbs = Nothing
        Set wrk = Nothing
           
    Exit Sub
    End Sub
    

+ Rispondi al messaggio

Potrebbero interessarti anche ...

  1. Prestazioni Tabelle vs Query
    Da Sains90 nel forum Microsoft Access
    Risposte: 9
    Ultimo Post: 26-06-2017, 15:39
  2. Relazioni tra tabelle
    Da Thoth nel forum Microsoft Access
    Risposte: 10
    Ultimo Post: 22-08-2016, 15:52
  3. Access relazioni tabelle
    Da Elisa Grandi nel forum Microsoft Access
    Risposte: 33
    Ultimo Post: 29-11-2008, 19:41
  4. Access - relazioni tabelle
    Da edirama nel forum Microsoft Access
    Risposte: 4
    Ultimo Post: 28-10-2006, 23:32
  5. Relazioni Tabelle Access e VB6
    Da Sonnyland nel forum Visual Basic 6
    Risposte: 1
    Ultimo Post: 28-02-2006, 04:05