Problemi derilanti con le date!!!

di il
5 risposte

Problemi derilanti con le date!!!

Ciao a tutti.
Premesso che ho cercato ovunque una soluzione senza venirne a capo, posto questa situazione a dir poco delirante.
Sto lavorando in VBA su una form che contiene una query che deve aggiornare i campi di una tabella; sono numerosi campi di tipo diverso e la query è costruita a partire da variabili che si alimentano a seconda di cosa l'utente fa sulla form.
Il problema mi sorge sulle date, vi posto il codice completo sotto.
La prima cosa strana succede quando digito in VBA: assegnando un valore ora ad una variabile, mi cambia automaticamente il formato dell'ora, ossia: io scrivo
PlanOraIn1 = #13:00:00#
e VBA corregge in
PlanOraIn1 = #9:00:00 AM#
Non so perché e non so come modificare la cosa, ma questo mi ha ovviamente insospettito. Dopo di che, valorizzo il campo data; nella finestra immediata, la data è SEMPRE in formato "italiano", ma quando la query inserisce i dati nel database, modifica il formato e scrive in formato "inglese".
Questo però succede SOLO finché la data non è sbagliata per il formato, in quel caso il sistema AUTOMATICAMENTE (senza il mio intervento da codice) lascia, ad esempio, che il 13 giugno (13/06/2015) sia il 13/06/2015, mentre il primo giugno (01/06/2015) diventa 6 gennaio (06/01/2015).
Giacché il campo "data", manco a farlo apposta, è fondamentale per la mia pianificazione, come posso ovviare? DI seguito il codice. Le query interessate sono le stringhe "StringaCreaPlan".
Grazie a chi ha pazienza

DoCmd.OpenForm "Attendere", acNormal, , , acFormReadOnly

Dim ToPlanDB As dao.Database
Dim ToPlanRS As dao.Recordset
Dim ToPlanST As String

Dim NumGiorni, NumTurni
Dim PlanDateIn, PlanDateEnd, PlanOraIn1, PlanOraIn2, PlanOraEnd1, PlanOraEnd2 As Date
Dim PlanZone, PlanAct, PlanWeekDay, PlanTurno1, PlanTurno2, PlanMate As String
Dim PlanQuant As Integer

NumGiorni = DataEndIst - DataStartIst + 1

If Me.SelezioneTurni = 1 Then
    NumTurni = NumGiorni
    PlanOraIn1 = #9:00:00 AM#
    PlanOraEnd1 = #1:00:00 PM#
    PlanTurno1 = "Mattina"
End If

If Me.SelezioneTurni = 2 Then
    NumTurni = NumGiorni
    PlanOraIn1 = #2:00:00 PM#
    PlanOraEnd1 = #6:00:00 PM#
    PlanTurno1 = "Pomeriggio"
End If

If Me.SelezioneTurni = 3 Then
    PlanOraIn1 = #9:00:00 AM#
    PlanOraEnd1 = #6:00:00 PM#
    NumTurni = NumGiorni
    PlanTurno1 = "Giornata intera"
End If

If Me.SelezioneTurni = 4 Then
    NumTurni = NumGiorni * 2
    PlanOraIn1 = #9:00:00 AM#
    PlanOraEnd1 = #1:00:00 PM#
    PlanOraIn2 = #2:00:00 PM#
    PlanOraEnd2 = #6:00:00 PM#
    PlanTurno1 = "Mattina"
    PlanTurno2 = "Pomeriggio"
End If

i = 1

Dim DataPlan
DataPlan = Me.DataStartIst
PlanWeekDay = StrConv(WeekdayName((Weekday(DataPlan, vbMonday)), False, vbMonday), vbProperCase)

Dim StringaCreaPlan, StringaCreaPlan1, StringaCreaPlan2 As String

DoCmd.SetWarnings (False)

For i = 1 To NumTurni

    If NumTurni = NumGiorni Then
        
        PlanZone = DLookup("Zona", "Zonecontrattosel", "IDContratto = " & Me.IDContratto)
        PlanAct = "Affissione"
        PlanMate = "Locandine"

        StringaCreaPlan = "INSERT INTO [Planning] ([IDContratto], [IDIstanza], [Data], [GiornoSettimana], [Turno], [InizioTurno], " & _
                    "[FineTurno], [Attivita], [Zona], [Materiale], [Quantita]) VALUES " & _
                    "(" & Me.IDContratto & ", " & Me.IdIstanza & ", #" & DataPlan & "#, '" & PlanWeekDay & _
                    "', '" & PlanTurno1 & "', #" & PlanOraIn1 & "#, #" & PlanOraEnd1 & "#, '" & PlanAct & _
                    "', '" & PlanZone & "', '" & PlanMate & "', 5);"
                
        DoCmd.RunSQL (StringaCreaPlan)
        DataPlan = DataPlan + 1
        PlanWeekDay = StrConv(WeekdayName((Weekday(DataPlan, vbMonday)), False, vbMonday), vbProperCase)
        
    Else
        
        PlanZone = DLookup("Zona", "Zonecontrattosel", "IDContratto = " & Me.IDContratto)
        PlanAct = "Affissione"
        PlanMate = "Locandine"

        StringaCreaPlan1 = "INSERT INTO [Planning] ([IDContratto], [IDIstanza], [Data], [GiornoSettimana], [Turno], [InizioTurno], " & _
                    "[FineTurno], [Attivita], [Zona], [Materiale], [Quantita]) VALUES " & _
                    "(" & Me.IDContratto & ", " & Me.IdIstanza & ", #" & DataPlan & "#, '" & PlanWeekDay & _
                    "', '" & PlanTurno1 & "', #" & PlanOraIn1 & "#, #" & PlanOraEnd1 & "#, '" & PlanAct & _
                    "', '" & PlanZone & "', '" & PlanMate & "', 5);"
        StringaCreaPlan2 = "INSERT INTO [Planning] ([IDContratto], [IDIstanza], [Data], [GiornoSettimana], [Turno], [InizioTurno], " & _
                    "[FineTurno], [Attivita], [Zona], [Materiale], [Quantita]) VALUES " & _
                    "(" & Me.IDContratto & ", " & Me.IdIstanza & ", #" & DataPlan & "#, '" & PlanWeekDay & _
                    "', '" & PlanTurno2 & "', #" & PlanOraIn2 & "#, #" & PlanOraEnd2 & "#, '" & PlanAct & _
                    "', '" & PlanZone & "', '" & PlanMate & "', 5);"
        
       
        DoCmd.RunSQL (StringaCreaPlan1)
        DoCmd.RunSQL (StringaCreaPlan2)
        
        DataPlan = DataPlan + 1
        PlanWeekDay = StrConv(WeekdayName((Weekday(DataPlan, vbMonday)), False, vbMonday), vbProperCase)

    End If

Next i

5 Risposte

  • Re: Problemi derilanti con le date!!!

    La prima cosa che devi fare è imparare a DICHIARARE in modo corretto le VARIABILI, cosa che non fai...
    Riporto il tuo Codice
    
    Dim NumGiorni, NumTurni
    Dim PlanDateIn, PlanDateEnd, PlanOraIn1, PlanOraIn2, PlanOraEnd1, PlanOraEnd2 As Date
    Dim PlanZone, PlanAct, PlanWeekDay, PlanTurno1, PlanTurno2, PlanMate As String
    Secondo te come sono dichiarate queste...?
    Partiamo dalla 1° Riga
    
    Dim NumGiorni, NumTurni
    Queste sono VARIANT è giusto(visto che hai [Num])...?
    Seconda riga...
    
    Dim PlanDateIn, PlanDateEnd, PlanOraIn1, PlanOraIn2, PlanOraEnd1, PlanOraEnd2 As Date
    Sono TUTTE VARIANT ad eccezione di [PlanOraEnd2] che è l'unica dichiarata in modo corretto come Data...
    Terza riga...
    
    Dim PlanZone, PlanAct, PlanWeekDay, PlanTurno1, PlanTurno2, PlanMate As String
    Sono TUTTE VARIANT ad eccezione di [PlanMate ] che è l'unica dichiarata in modo corretto come Stringa...

    Ora fai un RESET e sistema...

    Le date poi hanno realmente un aspetto specifico... quello che ti accade per l'ORA è incomprensibile se non per l'errore di DataType o VarType... ma per la Data serve considerare che JET lavora con l'accezione ANGLOSASSONE... quindi con l'inversione MM/DD, e occorre ingannarlo... solitamente si dovrebbe lavorare in ISO...

    Ti suggerisco di leggere questo TUTORIAL:
    http://forum.masterdrive.it/microsoft-office-access-vba-23/vba-jet-tutorial-uso-campi-data-56461/
  • Re: Problemi derilanti con le date!!!

    Alex, grazie come sempre.
    Preciso alcune cose:
    0) Io non sono un programmatore... quindi mi spiace di non usare linguaggio e metodi ortodossi, ma uso access per determinati precisi scopi e basta. Diciamo che "dove arrivo metto un segno"... e tutto mi serve per imparare.
    1) Perché le variabili sono Variant? A me servono dati precisi, corrispondenti a quello che c'è nei campi della tabella che vado ad aggiornare con la "insert into". Quindi campi testo, campi data e campi numero. Le variabili che chiamo "NUM" sono per ricordarmi a che cosa servono; nella fattispecie, NUMGIORNI contiene il numero di giorni compreso in un periodo e NUMTURNI quanti turni ci sono nel periodo. Possono essere uguali o il doppio di NUMGIORNI.
    2) Il problema delle date anglosassoni non c'è MAI stato. E' comparso improvvisamente e non so come ovviare, leggerò il tutorial. Nelle altre parti del codice, le date si aggiorna(va)no correttamente, adesso dovrò controllare tutto
    3) Per quanto concerne le ore, anche questo è veramente bizzarro. Comincio a pensare che sia un problema di librerie o componenti aggiuntivi... suggerimenti?
    Grazie ancora.
    S.
  • Re: Problemi derilanti con le date!!!

    In aggiunta a quanto indicato da Alex, è determinante specificare due cose:

    - in tutti i database (non solo Access) il formato predefinito delle date è MM/DD/YYYY mentre quello dell'ora è uguale.
    Alcuni database (non tutti) permettono di impostare a monte un formato di data.
    Access non è tra questi ed in visualizzazione (cioè quando apri direttamente il database ed apri un tabella in modalità Visualizzazione dati) usa sempre il formato delle impostazioni internazionali di Windows del pc locale.
    Di norma, per un pc con Windows italiano, è DD/MM/YYYY.

    - l'ora non è prescindibile dalla data perché, in realtà, data e ora sono un numero che identifica l'evento temporale universale.
    Non possono esistere due eventi temporali con Data e Ora uguali, ma sempre uno ed uno soltanto.
    In sostanza, l'ora singolarmente non esiste, così come non esiste la Data singolarmente.

    Ciò significa che impostare l'ora come fai tu è sbagliato. Devi sempre impostare Data e Ora insieme.
    Adesso che sto scrivendo l'orario non è semplicemente 08:46 ma
    06/05/2014 08:46:42
    Non possono esistere due eventi temporali che cadono il 06/05/2014 08:46:42
    (a parte ovviamente i millisecondi, ma non complichiamo ulteriormente la questione, è solo un esempio).

    Che poi tu voglia visualizzare in un controllo solo l'ora, solo la data o entrambe è solo una mera questione di visualizzazione, ma il valore assoluto dell'evento temporale non cambia.

    E' importante conoscere bene questi aspetti, ed i loro comportamenti, soprattutto quando poi si andranno ad eseguire delle query in cui si utilizzano le date come operatori condizionali.

    Ne parlo in un mio articolo qui:
    ADO, Parametri e affini
    http://nuke.vbcorner.net/Articles/VB60/ADOParametrieaffini/tabid/85/language/it-IT/Default.aspx

    Anche se gli esempi di codice sono per il linguaggio VB6, i concetti sono universali.

    Concludo dicendo che per rendersi conto di quanto questi concetti siano importanti e non vanno sottovalutati, proprio di recente negli Stati Uniti è stato messo sotto accusa un 'sistema' che si basava proprio su una differenza minimale degli orari che tramite un 'cartello' permetteva agli operatori di borsa di 'lucrare' milioni di dollari all'insaputa del povero investitore.
    Se uno non ha idea di cosa parlo si guardi il film Entrapment con Sean Connery e Catherine Zeta-Jones:
    http://www.mymovies.it/dizionario/recensione.asp?id=33145
    che compiono un furto di milioni di dollari basandosi proprio su questi concetti.


  • Re: Problemi derilanti con le date!!!

    PiattinoDiSegreti ha scritto:


    Alex, grazie come sempre.
    Preciso alcune cose:
    0) Io non sono un programmatore... quindi mi spiace di non usare linguaggio e metodi ortodossi, ma uso access per determinati precisi scopi e basta. Diciamo che "dove arrivo metto un segno"... e tutto mi serve per imparare.
    Nemmeno io lo sono, ma i sistemi come Access, in realtà tutti i sistemi, per saperli sfruttare e farli funzionare richiedono vengano trattati come da specifica... e risulta impossibile forzarli a comprendere i nostri limiti, siamo noi che dobbiamo evitare che i limiti siano ALIBI.

    PiattinoDiSegreti ha scritto:


    1) Perché le variabili sono Variant? A me servono dati precisi, corrispondenti a quello che c'è nei campi della tabella che vado ad aggiornare con la "insert into". Quindi campi testo, campi data e campi numero. Le variabili che chiamo "NUM" sono per ricordarmi a che cosa servono; nella fattispecie, NUMGIORNI contiene il numero di giorni compreso in un periodo e NUMTURNI quanti turni ci sono nel periodo. Possono essere uguali o il doppio di NUMGIORNI.
    Sono Variant perchè, così come li hai indicati, ovvero non li hai definiti, di default prendono il Tipo VARIANT.
    L'ultimo invece è definito... la definizione dell'ultimo non si applica ai precedenti... e questa è una delle REGOLE di BASE che devi sapere.
    Sapendo come il VBA vuole/richiede vengano definite le varibili sarai poi tu ad usare la sintassi adeguata.

    PiattinoDiSegreti ha scritto:


    2) Il problema delle date anglosassoni non c'è MAI stato. E' comparso improvvisamente e non so come ovviare, leggerò il tutorial. Nelle altre parti del codice, le date si aggiorna(va)no correttamente, adesso dovrò controllare tutto
    Non ci credo, nella mia esperienza, affermazioni come queste vanno di pari passo con l'evoluzione dell'utente.
    Mi spiego, un utente agli esordi che non conosce nulla... utilizza Access con le sole autocomposizioni, che MASCHERANO i problemi tecnici in quanto il sistema introduce correttivi automatici...
    Sicchè quando leggi una query SQL di questo tipo(a me vengono i brividi... perchè è da evitare):
    
    SELECT * FROM T1 WHERE
    CampoData = Forms!NomeForm!NomeTexBoxData
    l'utente non considera che dietro c'è una CONVERSIONE IMPLICITA della data... quando poi nella fase di evoluzione vuole/vorrebbe gestire da VBA il tutto... e non funziona più nulla, allora Access inizia ad essere il NEMICO IMPOSSIBILE...!
    Formattazione ISO...? Cos'è...?
    Formattazione differenziata per campi Data/Testo e Numerci...?
    Di questi esempi ne troviamo a Kg... perchè è innegabile che senza studiare nessuno possa conoscere queste cose...!

    PiattinoDiSegreti ha scritto:


    3) Per quanto concerne le ore, anche questo è veramente bizzarro. Comincio a pensare che sia un problema di librerie o componenti aggiuntivi... suggerimenti?
    Grazie ancora.
    S.
    Credo sia questione di basi tecniche, cerca di chiare bene i concetti di come Access richiede di usare i dati... poi puoi avere la possibilità di fare valutazioni tecniche sostenibili... oggi credo tu possa essere messo facilmente fuori strada da una tua non completa visione del problema.

    Ovviamente se fare un passo evolutivo eccede da quanto ti serve o da quanto ritieni possa servirti, ti rimane la possiblità di far fare tutto alle autocomposizioni e limitarti a quanto risulta gestibile in quel modo...
  • Re: Problemi derilanti con le date!!!

    Per carità, capisco tutto. Resta, per quanto mi riguarda, visto il poco tempo, l'uso strumentale di Access, il che mi impone di "studiare" quando serve.
    Intanto, ho risolto leggendo il tutorial.
    Quello che non mi era chiaro è che quando si assegna un formato ad una data, Access vuole sapere qual è il formato di provenienza e non quello di destinazione. Tanto è vero che la mia soluzione è stata questa, il problema era nella INSERT INTO:
    StringaCreaPlan = "INSERT INTO [Planning] ([IDContratto], [IDIstanza], [Data], [GiornoSettimana], [Turno], [InizioTurno], " & _
                        "[FineTurno], [Attivita], [Zona], [Materiale], [Quantita]) VALUES " & _
                        "(" & Me.IDContratto & ", " & Me.IdIstanza & ", #" & Format(DataPlan, "mm/dd/yyyy", vbMonday) & "#, '" & PlanWeekDay & _
                        "', '" & PlanTurno1 & "', #" & PlanOraIn1 & "#, #" & PlanOraEnd1 & "#, '" & PlanAct & _
                        "', '" & PlanZone & "', '" & PlanMate & "', 5);"
    dove la chiave è proprio il formato data
    #" & Format(DataPlan, "mm/dd/yyyy", vbMonday) & "#
    .

    Ora, nella rappresentazione dei dati successiva alla INSERT INTO, i dati appaiono correttamente (in formato dd/mm/yyyy per capirci).

    Per l'ora, si tratta solo di un problema a livello di codice. Infatti, anche se VBA mi modifica il formato durante la digitazione, comunque nella tabella scrive correttamente l'ora in formato 24H: sia che lasci
        PlanOraEnd1 = #1:00:00 PM#
    sia che forzi il formato in
        PlanOraEnd1 = Format(#1:00:00 PM#, "HH:mm")
    in tabella scrive "13:00".

    Grazie mille a tutti per l'aiuto.
Devi accedere o registrarti per scrivere nel forum
5 risposte