Primo giorno lavorativo rispetto ad una determinata data

Anonimo
2017-10-11T17:55:12+00:00

Ho provato a fare una qualche ricerca ma non sono riuscito a trovare qualcosa.

Poniamo che ci si trovi di fronte ad una data scadenza che cade in un determinato giorno (ad es. 23/12/2017 sabato).

Che sia previsto che nel caso in cui la scadenza cada in un giorno festivo (sabato, domenica o festività nazionale) la scadenza si intenda spostata al primo giorno lavorativo successivo (in questo caso 27 dicembre in quanto il 24 cade di domenica e il 25 e 26 dicembre sono festività nazionali).

Esiste una funzione VBA che automaticamente calcoli il primo giorno lavorativo successivo ad una determinata data se tale data è "festiva"?

La funzione, ovviamente, nel caso la data  non fosse festiva dovrebbe restituire la data stessa.

Es. se la scadenza cadesse il 11/10/2017 il "primo giorno lavorativo" sarebbe il 11/10/2017 in quanto la scadenza cade in un giorno lavorativo.

Personalmente ho sviluppato questa function (ancora da provare a fondo).Ma magari qualcuno si è già cimentato con risultati sicuri e migliori.

Function PrimoGiornoLavorativo(vData As Variant) As Date

  Dim NewData As Date

  Dim arrDateFestività As Variant

  Dim bFestivo As Boolean

  If Not IsDate(vData) Then Exit Function

  NewData = CDate(vData)

  Do

    Select Case NewData

      Case "01/01/2015", "06/01/2015", "05/04/2015", "06/04/2015", "25/04/2015", "01/05/2015", "02/06/2015", "15/08/2015", "01/11/2015", "08/12/2015", "25/12/2015", "26/12/2015", _

           "01/01/2016", "06/01/2016", "27/03/2016", "28/03/2016", "25/04/2016", "01/05/2016", "02/06/2016", "15/08/2016", "01/11/2016", "08/12/2016", "25/12/2016", "26/12/2016", _

           "01/01/2017", "06/01/2017", "16/04/2017", "17/04/2017", "25/04/2017", "01/05/2017", "02/06/2017", "15/08/2017", "01/11/2017", "08/12/2017", "25/12/2017", "26/12/2017", _

           "01/01/2018", "06/01/2018", "01/04/2018", "02/04/2018", "25/04/2018", "01/05/2018", "02/06/2018", "15/08/2018", "01/11/2018", "08/12/2018", "25/12/2018", "26/12/2018", _

           "01/01/2019", "06/01/2019", "21/04/2019", "22/04/2019", "25/04/2019", "01/05/2019", "02/06/2019", "15/08/2019", "01/11/2019", "08/12/2019", "25/12/2019", "26/12/2019", _

           "01/01/2020", "06/01/2020", "12/04/2020", "13/04/2020", "25/04/2020", "01/05/2020", "02/06/2020", "15/08/2020", "01/11/2020", "08/12/2020", "25/12/2020", "26/12/2020", _

           "01/01/2021", "06/01/2021", "04/04/2021", "05/04/2021", "25/04/2021", "01/05/2021", "02/06/2021", "15/08/2021", "01/11/2021", "08/12/2021", "25/12/2021", "26/12/2021", _

           "01/01/2022", "06/01/2022", "17/04/2022", "18/04/2022", "25/04/2022", "01/05/2022", "02/06/2022", "15/08/2022", "01/11/2022", "08/12/2022", "25/12/2022", "26/12/2022", _

           "01/01/2023", "06/01/2023"

        NewData = NewData + 1

        bFestivo = True

      Case Else

        Select Case DatePart("w", NewData, vbMonday)

          Case 6

            NewData = NewData + 2

            bFestivo = True

          Case 7

            NewData = NewData + 1

            bFestivo = True

          Case Else

            bFestivo = False

        End Select

    End Select

  Loop While bFestivo

  PrimoGiornoLavorativo = NewData

End Function

Se qualcuno avesse spunti o segnalazioni gliene sarei grato :)

Ciao

Microsoft 365 e Office | Excel | Per la casa | Windows

Domanda bloccata. Questa domanda è stata eseguita dalla community del supporto tecnico Microsoft. È possibile votare se è utile, ma non è possibile aggiungere commenti o risposte o seguire la domanda.

0 commenti Nessun commento

4 risposte

Ordina per: Più utili
  1. Anonimo
    2017-10-13T21:10:53+00:00

    Ciao!

    Lo sai che io corro in formula (1 o 2 o 3 a seconda dei casi).

    Poiché vuoi che il riconteggio della scadenza parta dalla scadenza effettiva non puoi usare GIORNO.LAVORATIVO perché questa funzione ti toglie dal conteggio tutti i sabati e le domeniche intermedi falsando il risultato.

    Per esempio se la data iniziale fosse il 1/12/2017 (venerdì) e tu aggiungessi 9 gg. la funzione restituirebbe 14/12  (giovedì) e non 10/12 (domenica). Data ultima sulla quale verificare poi se è festivo.

    La cosa migliore pertanto, secondo me, è procedere per gradi. Si potrebbe anche fare con un'unica funzione SE con tanti SE annidati ma la formula finale diventerebbe un obbrobrio.

    Io, quindi, avrei pensato, ma si può senz'altro fare meglio, una cosa del genere che tenga conto di tutte le possibili code festive come per esempio accade dal prossimo 23/12/2017 che cumula ben 4 giorni (sabato compreso) di feste.

    Innanzitutto, in un foglio Festività elencherei tutte le feste dal 2017 al 2019 (la Pasquetta è calcolata con una formula) e attribuirei il nome Feste ad un intervallo dinamico (si possono quindi aggiungere impunemente ulteriori annualità di feste fino alla riga 1000) con questa formula:

    =SCARTO(Festivita!$A$1;1;;CONTA.SE(Festivita!$A$1:$A$1000;">0"))

    Nel Foglio1:

    in A2: la data iniziale

    in B2: il numero di giorni da aggiungere

    in C2: la formula =Festivita!I2

    Nel Foglio Festività:

    in E2: =Foglio1!A2+Foglio1!B2

    in F2: =SE((GIORNO.SETTIMANA(E2;2)<6)*(CONTA.SE(Feste;E2)=0);E2;E2+1)

    in G2: =SE((GIORNO.SETTIMANA(F2;2)<6)*(CONTA.SE(Feste;F2)=0);F2;F2+1)

    in H2: =SE((GIORNO.SETTIMANA(G2;2)<6)*(CONTA.SE(Feste;G2)=0);G2;G2+1)

    in I2: =SE((GIORNO.SETTIMANA(H2;2)<6)*(CONTA.SE(Feste;H2)=0);H2;H2+1)

    in I2 il risultato finale che viene poi richiamato in C2 del Foglio1.

    Poi è ovvio che si potrebbe fare meglio, chi lo nega :-)

    PS: lo so che tu preferisci scrivere codice ma mi hai coinvolto richiamando la funzione GIORNO.LAVORATIVO. Peggio per te ;-)

    Se poi sei interessato alla gestione delle date con formule, tempo fa ho scritto il seguente articolo che, forse, potrebbe solleticarti. Chissà......

    QUI comunque ho salvato il file Data Scad Feriale.xlsx

    La risposta è stata utile?

    1 persona ha trovato utile questa risposta.
    0 commenti Nessun commento
  2. Anonimo
    2017-10-14T07:32:54+00:00

    ....

    mi sono limitato al 2099 .... perché credo che a 132 anni, anche dovessi arrivarci, non credo avrò interesse a calcolare le date delle Pasque future :D :D :D :D :D

    Sull'argomento ci risentiamo a quella data :-) Auguri!!

    La risposta è stata utile?

    0 commenti Nessun commento
  3. Anonimo
    2017-10-13T23:39:38+00:00

    Ciao Paolo,

    intanto grazie per l'intervento.

    Ho già salvato il tuo articolo tra la mia collezione nel "segnalibri" Excel del browser :)

    E lo leggerò con calma perché la gestione delle date in Excel è sempre un po' "delicata" :)

    Per quanto riguarda l'eventuale utilizzo della funzione GIORNO.LAVORATIVO, come dici, non potrei partire da una data, aggiungere l'intervallo di tempo per determinare la scadenza.

    Al massimo, una volta trovata la scadenza, dato un determinato intervallo di tempo a partire da una data iniziale, potrei utilizzarla assegnando la data precedente e "avanzando" di un giorno.

    Infatti, per quello che è il mio scopo, che è "data una scadenza se la stessa cade in un giorno festivo spostarsi al primo lavorativo successivo", dovrei prima individuare la scadenza, eventualmente aggiungendo ad una data iniziale il numero di giorni, settimane, mesi anni senza tenere conto di "festivi intermedi", verificare se questa data di scadenza è una festività e, nel caso, verificare qual è il giorno lavorativo successivo.

    Ad esempio, ipotetico, poniamo che la scadenza sia "pagamento fine mese da data fattura",

    Data fattura 10/09/2017. Fine mese 30/09/2017 che cade di sabato. Il pagamento cade al primo giorno lavorativo che è il lunedì 02/10/2017.

    Se utilizzassi la funzione GIORNO.LAVORATIVO tra gli argomenti dovrei indicare ("29/09/2017";1;Feste)

    Questo perché la funzione richiede che ci sia almento un giorno di "avanzamento" per fare il sul lavoro.

    Quindi determinata una scadenza devo indicare come data il giorno precedente e avanzare di 1 giorno.

    A questo punto la funzione legge se il "giorno avanzato" è festivo o meno e se è festivo si sposta al primo non festivo altrimenti restituisce lo stesso giorno "avanzato"

    Nel mio caso cercavo una funzione da utilzzare via codice per effettuare calcoli sempre via codice per poi riportare i risultati, in maniera "dinamica", su di un foglio di lavoro. Il tutto senza utilizzare altri fogli di "appoggio" per le date delle festività ma indicando via codice le date delle festività.

    Il tutto per rendere più "leggera" e "snella" la cartella di lavoro. Da qui la soluzione di una FDU.

    Avrei potuto anche sfruttare via codice la funzione GIORNO.LAVORATIVO (nella sua versione WorsheetFunction) ma richiede la conversione in numero seriale delle date e quindi ogni data indicata con Clng(Cdate("01/01/2017")). Non che non avrei potuto crearmi stringhe di testo in un foglio, cosa che ho fatto anche per le date in formato "01/01/2017", ma avrebbe occupato molto più codice :-).

    Comunque ho provato un po' la funzione è mi sembra che restituisca sempre valori corretti.

    La logica della funzione è quella di effettuare un "ciclo perpetuo" fino a che una data è festiva e dove per prima cosa viene verificato se la data rientra tra quelle indicate tra le festività. Se rientra in una di queste date la data viene aumentata di 1 e viene indicato che si è trattata di una data festiva.

    Il ciclo quindi viene ripetuto per verificare se la nuova data è comunque ancora festiva (es. 25/12 diventerebbe 26/12 e quindi ancora festivo). Se la nuova data non rientra tra quelle festive allora viene verificato se cade di sabato o di domenica. Nel caso si verifichi questa evenienza la nuova data viene aumentata di 2 o 1 e sempre considerata festiva. Quindi il ciclo riparte per verificare che questa nuova data non ricada eventualmente nel gruppo delle festività.

    Solo quando la data non rientra in una delle festività e non cade di sabato o di domenica viene "marcata" come non festiva (bFestivo = False) e quindi il ciclo viene interrotto.

    Se vuoi per curiosità verificarne il funzionamento qui trovi un file di esempio per l'anno 2017

    File Esempio

    ciao

    p.s. nell'esempio la funzione può gestire tre annualità dal 2017 al 2019.

    p.p.s per determinare la Pasqua, prendendo spunto da Metodo artimentico di Gauss utilizzo questa FDU (manco a dirlo :D)

    Function DataPasqua1900_2099(Y As Long) As Date

      Dim a, b, c, d, e, tot_de

      Dim Giorno As Long

      Dim Mese As Long

      Const M As Long = 24

      Const N As Long = 5

        a = Y Mod 19

        b = Y Mod 4

        c = Y Mod 7

        d = (19 * a + M) Mod 30

        e = (2 * b + 4 * c + 6 * d + N) Mod 7

        tot_de = d + e

        If tot_de < 10 Then

          Giorno = (d + e + 22)

          Mese = 3

        Else

          Giorno = (d + e - 9)

          Select Case Giorno

            Case 25

              If d = 28 And e = 6 And a > 10 Then Giorno = 18

            Case 26

              Giorno = 19

          End Select

          Mese = 4

        End If

        DataPasqua1900_2099 = CDate(Giorno & "/" & Format(Mese, "00") & "/" & Y)

    End Function

    mi sono limitato al 2099 .... perché credo che a 132 anni, anche dovessi arrivarci, non credo avrò interesse a calcolare le date delle Pasque future :D :D :D :D :D

    La risposta è stata utile?

    0 commenti Nessun commento
  4. Anonimo
    2017-10-11T18:10:57+00:00

    Aggiungo che a livello di formula excel nel foglio si potrebbe utilizzare GIORNO.LAVORATIVO indicando come data il giorno precedente alla data di interesse e riportando tutte le festività nazionali nell'argomento "Vacanze".

    La risposta è stata utile?

    0 commenti Nessun commento