Newsgroup: it.comp.appl.access
Titolo: aggiungere giorni lavorativi

Data una data (bel giro di parole...) devo aggiungere n giorni
lavorativi....per arrivare quindi ad una nuova data.
Sul sito comune ho visto la funzione per ricavare i giorni lavorativi tra
due date e l'ho presa come spunto...ma non ce la fo !!!
 
 
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/

 ha scritto nel messaggio 
news:81Z112Z191Z154Y...@usenet.libero.it...

non ce la fai xè sei troppo stanco? ... ovomaltina alla mattina!
se invece ci dici che cosa non riesci a fare, che errore ti viene dato 
ecc... magari qualcuno che ha preso ovomaltina ti aiuterà volentieri!
p.s. se sei nato prima degli anni 80 e non conosci ovomaltina ... allora è 
un'altro problema! 

 due date e l'ho presa come spunto...ma non ce la fo !!!
Se la tua data si chiama DataInizio.
Se i giorni lavorativi si chiamano Giorni.
Memorizza le funzioni pubblicate nella FAQ di cui sopra in un modulo del tuo
database, quindi esegui il seguente codice VBA:
Dim DataFine As Date
DataFine = DataInizio + Giorni
Do Until 1 =2
    If ContaLavorativi(DataInizio, DataFine, True) = Giorni Then
        Exit Do
    End If
    DataFine = DataFine + 1
Loop
Quando esci dal ciclo Do ... Loop in DataFine ci trovi DataInizio + Giorni
lavorativi.
-- 
Roberto
---------------------------------------------
il Sito Comune di it.comp.appl.access:
http://www.sitocomune.com
---------------------------------------------

Innanzitutto Ti ringrazio Roberto, ho provato a fare come dici tu ma...
facendo un pò di prove la cosa non funge...ho legato Giorni ad una casella
di testo come pure per Data inizio... ho inserito i valori ma...da degli
errori...se ci sono dei weekend o delle festività il calcolo è corretto se
non Vi sono fetività aggiunge sempre un giorno in più....
 



 non Vi sono fetività aggiunge sempre un giorno in più....
Quando rispondi scrivi DOPO e non prima del testo dei messaggi precedenti.
E se invece di:
DataFine = DataInizio + Giorni
scrivi:
DataFine = DataInizio
Cosa succede?


 ---------------------------------------------
 
Ho la necessità di usare questa soluzione ma la devo inserire dentro a una maschera continua e quindi di conseguenza richiamare tale routine da un campo della query, ma mi sono ingrippato. Come si fa?
 
 

SELECT *, Contalavorativi(campodatainizio, campodatafine, true)
FROM TuaTabella
 
@Alex


No Alex, io ho la DataInizio e ho i giorni da contare, 
e devo trovare la DataFine


Ho aggiunto nel modulo questo:
 
Public Function DataFine(DataInizio As Date, Giorni As Integer) As Date
DataFine = DataInizio + Giorni
Do Until 1 = 2
    If ContaLavorativi(DataInizio, DataFine, True) = Giorni Then
        Exit Do
    End If
    DataFine = DataFine + 1
Loop
 
End Function
 
Nella query nel campo 'espr1:' come faccio a richiamare DataFine del modulo?
 
 

Te l'ho scritta sopra la sintassi... ma ti devi riscrivere la funzione ;-) perché quella fa altro... o meglio il contrario.
 
@Alex

Ti ringrazio, ma non sono capace di riscrivere la funzione. Posso chiederti (per cortesia e soprattutto per pietà) se puoi dirmi come va riscritta?
 
Grazie infinite.
 
Andrea

 @Alex
 
Ho provato a riscriverla in questo modo, e all'esecuzione della query ottengo i la somma dei giorni di calendario e non quelli lavorativi. Dove ho sbagliato?
 
Public Function ContaLav(DataIniziale As Date, Giorni As Integer) As Date
Dim DataFinale As Date
ContaLav = DataIniziale + Giorni
Do Until 1 = 2
    If ContaLavorativi(DataIniziale, DataFinale, True) = Giorni Then
        Exit Do
    End If
    DataFinale = DataFinale + 1
Loop
End Function
 
Nella query ho inserito questa espressione per ottenere la data finale che mi serve:
 
Espr2: ContaLav([Data_Ordine];[Giorni])
 
Grazie per l'aiuto
 
Andrea


Dim DataInizio As Date, DataFine As Date, nGiorniLavorativiDaContare As Variant, Valore As Variant, k As Variant
DataInizio = Date
nGiorniLavorativiDaContare = 6
'DataFine = Date + nGiorniLavorativiDaContare
k = 0
While Valore <> nGiorniLavorativiDaContare
  k = k + 1: DataFine = Date + k
  Valore = ContaLavorativi(DataInizio, DataFine, True)
  'MsgBox (Valore)
Wend
MsgBox (DataFine)

Andrea, devi fare un ciclo da DataInizio finchè iCount=Giorni.
Il Contatore di giorni iCount lo devi incrementare solo se il giorno in analisi è Lavorativo, ovvero se NON è festivo.
 
Quindi una roba simile:
 
Dim iCount As integer
Dim iTot   As Integer
Dim dtAct  As Date
 
dtAct=DataInizio
iCount=0
iTot=0
 
Do until iCount=TotaleGiorni
   If Not Festivo(dtAct) Then iCount=iCount+1
   iTot=iTot+1
Loop
 
DataFinale=DateAdd("d",iCount,DataIniziale)
 
 
La funzione Festivo io ho la mia... vedi tu se nel tuo demo hai già una funzione che restituisce TRUE/FALSE in caso di Festivo.
 
@Alex 
 
Saluti
@Alex


Grazie infinite Alex, sul tuo insegnamento ho scritto in questo modo la funzione pubblica, ma sarebbe stato troppo bello se avesse funzionato al primo colpo:
 
Public Function ContaLav(Data_Ordine As Date, Giorni As Integer) As Date
 
Dim iCount As Integer
Dim iTot   As Integer
Dim dtAct  As Date
 
dtAct = Data_Ordine
iCount = 0
iTot = 0
 
Do Until iCount = Giorni
   If Not Festivo(dtAct) Then iCount = iCount + 1
   iTot = iTot + 1
Loop
 
ContaLav = DateAdd("d", iCount, Data_Ordine)
 
End Function
 
Ora ti devo anche dire cosa ho inserito di mio spiegando i campi in questione:
Data_Ordine è un campo che si trova nella query;
Giorni è un campo che si trova nella query (che indica il numero intero dei giorni lavorativi da sommare alla data_Ordine);
Festivo ce l'ho anche io in questa funzione pubblica:
Public Function Festivo(D As Date) As Boolean
   'Autore: Silvio Mazzetto
   'Accetta: una data
   'Restituisce: True se è un giorno festivo
   'Eventualmente inserire anche il Santo Patrono della città
   'Modificato da Roberto
   Dim Anno As Integer, DayMax As Date, DayMin As Date
   Anno = Year(D)
   If Weekday(D) = 1 Then
      Festivo = True
      Exit Function
   End If
   If Day(D) = 1 And (Month(D) = 1 Or Month(D) = 5 Or Month(D) = 11) Or _
         Day(D) = 6 And Month(D) = 1 Or Day(D) = 25 And (Month(D) = 4 Or _
         Month(D) = 12) Or Day(D) = 15 And Month(D) = 8 Or (Day(D) = 8 Or _
         Day(D) = 26) And Month(D) = 12 Then
      Festivo = True
      Exit Function
   End If
   'intervallo in cui può cadere il Lunedì di Pasqua
   DayMax = DateValue("21/4/" & Anno)
   DayMin = DateValue("20/3/" & Anno)
   If Weekday(D) = 2 And D <= DayMax And D >= DayMin Then
      If D = (Pasqua(Anno) + 1) Then
         Festivo = True
         Exit Function
      End If
   End If
   Festivo = False
End Function
 
E nella query ho messo questa espressione:
Espr2: ContaLav([Data_Ordine];[Giorni])
 
Grazie @Alex per il tuo aiuto sulla sistemazione di quanto ho fatto.
 
Andrea
 
 

Scusami Alex, forse non hai capito su mio post precedente che non sono ancora riuscito nel mio intento e chiedevo ancora aiuto a te. Puoi vedere su quanto ho scritto nel codice e dove sbaglio? Grazie:
 
Public Function ContaLav(Data_Ordine As Date, Giorni As Integer) As Date
 
Dim iCount As Integer
Dim iTot   As Integer
Dim dtAct  As Date
 

Espr2: ContaLav([Data_Ordine];[Giorni])
 


Andrea, mi era scappato il POST, prima di terminarlo...
 
Sono certo tu capisca che il tempo da dedicare al FORUM non sempre è IMMEDIATO, soprattutto in questo periodo che, per qualcuno è di arresto forzato... ma per altri è il contrario.
 
In ogni caso non avevo tempo di capire dove sbagliavi, ho fatto prima a riscrivere la Funzione da zero, in 10 minuti...
 
Il DEBUG è satato un po superficiale, ma spero funzioni tutto.
 
Per provarla:
?WorkingDays(#14/03/2020#,10)
27/03/2020 
 
I giorni che esclude sono commenatti nella Funzione sotto...
 
Option Compare Database
Option Explicit
 
Function WorkingDays(DateIni As Date, vEnd As Variant) As Variant
    Dim dtINI       As Date
    Dim dtTMP       As Date
    Dim vDays       As Variant
 
    dtINI = DateIni
 
    dtTMP = dtINI
    Do Until vEnd <= vDays
        If Not Holiday(dtTMP) Then
            vDays = vDays + 1
        End If
        dtTMP = dtTMP + 1
    Loop
 
    WorkingDays = dtTMP - 1
End Function
 
Public Function Holiday(ByVal DateIsHoliday As Date) As Boolean
    Dim YearOfDate As Integer
    Dim NotWorkingDay(1 To 12) As Date
    Dim i As Integer
 
    If Weekday(DateIsHoliday, vbMonday) < 6 Then
 
        YearOfDate = Year(DateIsHoliday)
 
        NotWorkingDay(1) = DateSerial(YearOfDate, 1, 1)     ' 1 GENNAIO CAPODANNO
        NotWorkingDay(2) = DateSerial(YearOfDate, 1, 6)     ' 6 GENNAIO BEFANA
        NotWorkingDay(3) = DateSerial(YearOfDate, 5, 1)     ' 1 MAGGIO BEFANA
        NotWorkingDay(4) = DateSerial(YearOfDate, 6, 2)     ' 2 GIUGNO (Repubblica)
        NotWorkingDay(5) = DateSerial(YearOfDate, 8, 15)    ' 15 AGOSTO Ferragosto
        NotWorkingDay(6) = DateSerial(YearOfDate, 11, 1)    ' 1 NOVEMBRE SANTI
        NotWorkingDay(7) = DateSerial(YearOfDate, 12, 25)   ' 25 DICEMBRE NATALE
        NotWorkingDay(8) = DateSerial(YearOfDate, 12, 26)   ' 26 DICEMBRE S.Steefano
        NotWorkingDay(9) = EasterMonday(YearOfDate)         ' PASQUA
        NotWorkingDay(10) = NotWorkingDay(9) + 38           ' Ascensione = lundi de Paques + 38
        NotWorkingDay(11) = NotWorkingDay(9) + 49           ' Lundi Pentecoste = lundi de Paques + 49 (questo in Italia forse non è festa)
 
'        NotWorkingDay(9) = DateSerial(YearOfDate, 8, 10) ' Patrono 10 AGOSTO
 
 
        For i = 1 To UBound(NotWorkingDay()) - 1
            If Fix(DateIsHoliday) = NotWorkingDay(i) Then
                Holiday = True
                Exit For
            End If
        Next
 
    Else
        Holiday = True
    End If
 
End Function
 
Public Function EasterMonday(ByVal Iyear As Integer) As Date
        'Adapté de +ieurs scripts...
        Dim L(6) As Long, Lj As Long, Lm As Long
 
        L(1) = Iyear Mod 19: L(2) = Iyear Mod 4: L(3) = Iyear Mod 7
        L(4) = (19 * L(1) + 24) Mod 30
        L(5) = ((2 * L(2)) + (4 * L(3)) + (6 * L(4)) + 5) Mod 7
        L(6) = 22 + L(4) + L(5)
 
        If L(6) > 31 Then
                Lj = L(6) - 31
                Lm = 4
        Else
                Lj = L(6)
                Lm = 3
        End If
 
        ' Lundi de Pâques = Paques + 1 jour
        EasterMonday = DateAdd("d", 1, (Lj & "/" & Lm & "/" & Iyear))
 
End Function
 
@Alex


Ti ringrazio infinitamente @Alex, e capisco benissimo. Ho visto infatti che avevi risposto ad altri post, senza rispondere al mio e avevo capito che non ti eri accorto, per questo mi sono permesso di ripostare per attirare la tua attenzione. Ho corretto solo un paio di cose sul codice che hai scritto (e sono riuscito a farlo funzionare alla grande, per merito tuo).
 
Function WorkingDays(DateIni As Date, vEnd As Variant) As Variant
che ho corretto con
Public Function WorkingDays(DateIni As Date, vEnd As Variant) As Date
 
Per ora con i giorni lavorativi senza le festività fa tutto giusto, e sono sicuro che sarà tutto giusto anche quando arriveranno le feste comandate, del resto lo ha scritto il grande @Alex!!!
 
Non mi stancherò mai di dirti GRAZIE, GRAZIE, GRAZIE.
 
Andrea