09/08/2023 - By65Franco ha scritto:
Come accennato in precedenza i tuoi problemi nascono per una errata progettazione del database, tabelle e relazioni. Ma sicuramente migliorerai sotto questo aspetto.
Riepilogando:
- Stai lavorando con campi descrittivi e non con gli Id Chiave e questo ti crea il problema nel reperire la corretta corrispondenza tra Accertamento e Tabella Accertamenti/Anagrafica/etc…
- Non ti scombussolo nulla di quello che hai già realizzato e pur sapendo che non va bene ti propongo una soluzione molto criticabile e non ortodossa visto la natura delle colonne definite nelle tabelle e loro relazioni
Nel particolare:
- quando crei l'appuntamento non hai una chiave nella combo box accertamenti che tu possa successivamente utilizzare per implementare la tabella Piano Sanitario
- hai solo una descrizione dell' Accertamento e questo dato in modo ridontante lo porti dietro su altre tabelle (questo non si fa)
- vista la natura della tabella Appuntamenti e della tabella Piano Sanitario, le due non si legano tramite degli Id ma solo in modo descrittivo (questo non si fa)
- per andare avanti con questo approccio devi continuare ad utilizzare tali descrizioni (anche questo non si fa) ;-)
- da Appuntamenti per passare il record al Piano Sanitario devi simulare ciò che faresti manualmente nel Piano Sanitario
- per simulare tali inserimenti è necessario reperire le informazioni che ti occorrono passando nuovamente dall'Anagrafica dalla tabella Rischi e attraverso le Mansioni alla tabella Accertamenti. Per fare questo devi crearti una query (stringa sql nel nostro caso) per poter risalire al Numero Mesi legato a tale accertamento. Per esempio:
strSql = "SELECT T_Anagrafica.ID, Accertamenti_T.Accertamenti, Accertamenti_T.Periodicità " & _
"FROM (T_Rischio INNER JOIN T_Anagrafica ON T_Rischio.ID = T_Anagrafica.IDMansione.Value) INNER JOIN Accertamenti_T ON T_Rischio.ID = Accertamenti_T.IDRischio " & _
"WHERE T_Anagrafica.ID=" & Me.IDAnagrafica & " AND Accertamenti_T.Accertamenti='" & Me.Accertamento & "';"
- se va a buon fine tale istruzione sql, otterrai il Numero Mesi che dovrai controllare se per quel Tipo di Accertamento è ammasso dal quell'Id Anagrafica… pertanto se non esiste tale legame il Numero Mesi sarà = 0
- questa ipotesi devi intercettarla e gestire il da farsi. Per Esempio:
If intMesi = 0 Then
MsgBox "Type of assessment not foreseen", vbCritical, "Error"
Me.Eseguito = "NO"
Exit Sub
End If
- se invece il Tipo di Accertamento è legato a quella Anagrafica, allora puoi procedere all'inserimento del nuovo record nel Piano Sanitari. Il mio approccio è quello che ti presentavo nei post precedenti utilizzando l'Execute di DBEngine (sempre di Dao si parla, vedi documentazione che ti avevo passato). Pertanto dovrai controllare di avere tutte le informazioni e che siano corrette per procedere all'inserimento del record. Per esempio una traccia sarà di questo tipo:
' insert new records in the PianoSanitarioT table
DBEngine(0)(0).Execute "INSERT INTO PianoSanitarioT (IdAnagrafica, Accertamenti, Periodicità, DataUltima, ProssimaVisita) " & _
"VALUES (" & _
Me.IDAnagrafica & ", '" & _
Me.Accertamento & "', " & _
intMesi & ", " & _
CStr(CLng(Me.SelData)) & ", " & _
CStr(CLng(DateAdd("m", intMesi, Me.SelData))) & ");"
- dovranno essere anche eseguiti dei controlli preliminari prima di procedere. A tal fine ti lascio un esempio di questo tipo:
Private Sub Eseguito_Click()
' check only selected = "SI"
If Me.Eseguito = "NO" Then Exit Sub
' confirm message
If MsgBox("Confirming the inclusion in the Health Plan?", vbExclamation + vbYesNo, "Confirm") = vbNo Then
Me.Eseguito = "NO"
Exit Sub
End If
- Come giustamente avevi segnalato userai la ComboBox Eseguito
- una correzione che dovrai fare è quella di impostare il valore di Default per tale colonna della tabella e la imposterai con il valore “NO” altrimenti hai un valore null che a tale scopo non ti serve. Quindi i valori possibili saranno esclusivamente NO oppure SI
- Per esempio su evento Click della combo box puoi creare "Routine Evento" e da codice Vba ti ritrovi la Sub dove inserire i tuoi controlli e esecuzione dell'Inserimento new record
- Se sulla combo box scegli NO allora non esegui il codice e esci subito dalla Routine
- Se hai scelto SI puoi per esempio far apparire un messaggio di conferma se si vuole effettivamente passare le informazioni al Piano Sanitario
- se al messaggio di conferma selezioni NO allora devi impostare a NO la combo box Esegito e esci direttamente dalla Routine
Se adesso provi a mettere insieme questi passsaggi otterrai una cosa di questo tipo:
Esempio:
' INSERT PIANO SANITARIO
Private Sub Eseguito_Click()
' check only selected = "SI"
If Me.Eseguito = "NO" Then Exit Sub
' confirm message
If MsgBox("Confirming the inclusion in the Health Plan?", vbExclamation + vbYesNo, "Confirm") = vbNo Then
Me.Eseguito = "NO"
Exit Sub
End If
' set sql string
Dim strSql As String
strSql = "SELECT T_Anagrafica.ID, Accertamenti_T.Accertamenti, Accertamenti_T.Periodicità " & _
"FROM (T_Rischio INNER JOIN T_Anagrafica ON T_Rischio.ID = T_Anagrafica.IDMansione.Value) INNER JOIN Accertamenti_T ON T_Rischio.ID = Accertamenti_T.IDRischio " & _
"WHERE T_Anagrafica.ID=" & Me.IDAnagrafica & " AND Accertamenti_T.Accertamenti='" & Me.Accertamento & "';"
' open recordset
Dim rs As DAO.Recordset
Set rs = DBEngine(0)(0).OpenRecordset(strSql, dbOpenSnapshot)
' if exist - value save
Dim intMesi As Integer
If Not rs.EOF Then intMesi = rs.Fields("Accertamenti_T.Periodicità").Value Else intMesi = 0
' close
rs.Close
Set rs = Nothing
' check Accertmento type
If intMesi = 0 Then
MsgBox "Type of assessment not foreseen", vbCritical, "Error"
Me.Eseguito = "NO"
Exit Sub
End If
' insert new records in the PianoSanitarioT table
DBEngine(0)(0).Execute "INSERT INTO PianoSanitarioT (IdAnagrafica, Accertamenti, Periodicità, DataUltima, ProssimaVisita) " & _
"VALUES (" & _
Me.IDAnagrafica & ", '" & _
Me.Accertamento & "', " & _
intMesi & ", " & _
CStr(CLng(Me.SelData)) & ", " & _
CStr(CLng(DateAdd("m", intMesi, Me.SelData))) & ");"
End Sub
Se noti possiamo utilizzare lo stesso metodo, DBEngine per aprire un recordset della Query di cui si parlava all'inizio, quella che permetterà di risalire ai mesi di quell'Accertamento per quella Mazione di quel Rischio legato all'Anagrafica dove hai aperto un appuntamento da accodare al Piano Sanitario.
E' solo una traccia in quanto non sappiamo se e come vorrai agire in caso di ripetuti invii al Piano Sanitario dello stesso Appuntamento… qui dovrai decider, per esempio se quell'Appuntamento viene Eseguito (combo box Eseguito = SI) , potresti bloccare la ComboBox in modo che non possa più essere scelto un valore diverso. Quindi una volta Impostato Eseguito = SI a quel punto blocchi o la combobox oppure inserisci un ulteriore controllo nell' evento click dove puoi risalire al valore precedente della combo box (old value), confrontarlo con il valore attualmente modificato e se era già stato impostato SI eseguirai direttamente un Exit Sub per uscire subito dalla Routine.
Valuta se può essere la soluzione che cercavi e se l'approccio risulta corretto.
A disposizione per qualsiasi ed ulteriori chiarimenti.
Fai sapere… ;-))
Super!
Grazie mille, ho letto tutto e domani mi metto a studiare tutto quello che mi hai girato. E lo faccio funzionare con le indicazioni
Però volevo fare una domanda sulla progettazione, se dovessi creare un programma parallelo, questa volta, come mi stai consigliando, ho avuto questo problema che magari se avessi conosciuto il forum prima avrei risparmiato guai :)
Praticamente, ogni dipendente ha un rischio, che viene definita dalla manzione (praticamente è il campo multi IDmanzione) da cui parte il piano sanitario.
Perciò es.
Io dipendente lavoro al 50% su officina mecanica e 50% in ufficio (sono i valori che vengono definiti dalla tabella rischio e caricato nella maschera sorveglianza sanitaria)
Questo, che può sembrare una caz..ta, ma non riuscivo a individuare la relazione giusta per poter far saltar fuori gli accertamenti (che è la globalizzazione di tutti i rischi possibili delle varie mansioni svolte da un dipendente , con la minima tempistica, ovvero, se una mansione prevede la visita optometrica a 24 mesi e l'altra a 12 mesi, nel piano sanitario mi deve riportare che la visita optometrica la dovrà fare a 12 mesi)
In questo caso, se mi posso approfittare ancora della tua esperienza, come potrei ripartire da zero?
Io avevo trovato la risposta nel multifunzione, ma mi ha riportato tutta la carrellata di errori e errorini che mi hai fatto notare