Calcolo automatico scadenze pagamento fatture

di il
5 risposte

Calcolo automatico scadenze pagamento fatture

Buonasera a tutti,

ho creato questo codice per eseguire il calcolo automatico della scadenza di pagamento fatture in funzione della tipologia impostata e caricare poi le scadenze in tabella.

Nella form principale dove inserisco i dati della fattura, ho inserito questa funzione su un evento afterupdate di un controllo. La funzione utilizza la data della fattura a cui vengono aggiunti eventuali giorni oltre i mesi di pagamento, i mesi di pagamento, il fine mese ed infine eventuali ulteriori giorni dopo il fine mese.

Alcune tipologie di pagamento "piu' complesse" possono essere : 165 giorni fine mese, 30/60/90 gg fine mese, 120/150 gg fine mese, ecc.

Quindi ho in alcuni casi piu' date di pagamento: quindi l'importo viene splittato in base alla percentuale delle scadenze di pagamento.

Nella tblCPcalcolopagamento ho i seguenti campi: mesi, giornioltreimesi, finemese, ulteriorigiorni, percentualepagamento

Il codice funziona parzialmente perche non so come inserire un flag sull'ultima tranche di pagamento (che sarebbe il campo rst1.fields(6))

Public Function CalcoloDataPagamento(intTipoPagamento As Integer, pdatafattura As Date, pidfattura As Integer, pimporto As Currency)
On Error GoTo Err_handler

    Dim dt As Date
    Dim rst As DAO.Recordset
    Dim rst1 As DAO.Recordset
    
    Set rst = DBEngine(0)(0).OpenRecordset("SELECT * FROM TblCPcalcolopagamento WHERE NUMtabCPIDtabTPid= " & intTipoPagamento & " ORDER BY IDtabCPid ASC", dbOpenSnapshot, dbReadOnly)
    'apro un recordset con i dati per il calcolo del pagamento fattura
    
    Set rst1 = DBEngine(0)(0).OpenRecordset("tblPApagamentofornitori", dbOpenDynaset)
    'apro un recordset nuovo nella tabella con le scadenze di pagamento
    
    rst.MoveFirst
    Do While Not rst.EOF()
    
        dt = DateAdd("d", rst.Fields(3), pdatafattura)    'Aggiungo i giorni(3)
        dt = DateAdd("m", rst.Fields(2), dt)                'Aggiungo i mesi(2)

        If rst.Fields(4) Then
            dt = DateSerial(Year(dt), Month(dt) + 1, 0)  'Calcolo il fine mese(4)
        End If
       
        dt = DateAdd("d", rst.Fields(5), dt)            'Aggiungo gli ulteriori giorni(5)
    
        rst1.AddNew
        rst1.Fields(1) = pidfattura
        rst1.Fields(2) = dt
        rst1.Fields(3) = pimporto * rst.Fields(6)
        rst1.Update
        
    rst.MoveNext
    Loop
    

    rst.Close
    rst1.Close
    Set rst = Nothing
    Set rst1 = Nothing
    
    
Exit_Err_handler:
    Exit Function

Err_handler:
    MsgBox Err.Number & " " & Err.Description
    Resume Exit_Err_handler

End Function

La funzione e' inserita in un modulo generico e richiamata nella form di inserimento fatture, passandogli i parametri necessari.

Qualche consiglio?

grazie in anticipo

5 Risposte

  • Re: Calcolo automatico scadenze pagamento fatture

    Si dice che la notte porti consigli ed infatti questa mattina ho modificato il codice come segue e funziona anche per il flag.

    Grazie comunque e accetto consigli per eventuali miglioramenti del codice.

    Public Function CalcoloDataPagamento(intTipoPagamento As Integer, pdatafattura As Date, pidfattura As Integer, pimporto As Currency)
    On Error GoTo Err_handler
    
        Dim dt As Date
        Dim rst As DAO.Recordset
        Dim rst1 As DAO.Recordset
        Dim i As Integer
        Set rst = DBEngine(0)(0).OpenRecordset("SELECT * FROM TblCPcalcolopagamento WHERE NUMtabCPIDtabTPid= " & intTipoPagamento & " ORDER BY IDtabCPid ASC", dbOpenSnapshot, dbReadOnly)
        'apro un recordset con i dati per il calcolo del pagamento fattura
        
        Set rst1 = DBEngine(0)(0).OpenRecordset("tblPApagamentofornitori", dbOpenDynaset)
        'apro un recordset nuovo nella tabella con le scadenze di pagamento
        
        rst.MoveLast
        rst.MoveFirst
        For i = 1 To rst.RecordCount
        
            dt = DateAdd("d", rst.Fields(3), pdatafattura)    'Aggiungo i giorni(3)
            dt = DateAdd("m", rst.Fields(2), dt)                'Aggiungo i mesi(2)
    
            If rst.Fields(4) Then
                dt = DateSerial(Year(dt), Month(dt) + 1, 0)  'Calcolo il fine mese(4)
            End If
           
            dt = DateAdd("d", rst.Fields(5), dt)            'Aggiungo gli ulteriori giorni(5)
        
            rst1.AddNew                                     'aggiungo nuovo record al recordset
            rst1.Fields(1) = pidfattura                     'compilo il campo con ID fattura
            rst1.Fields(2) = dt                             'compilo il campo con la data scadenza fattura
            rst1.Fields(3) = pimporto * rst.Fields(6)       'calcolo e compilo il campo dell'importo in scadenza
            
            If i = rst.RecordCount Then
                rst1.Fields(6) = True                       'compilo il flag per evasione ultimo pagamento
            End If
                
            rst1.Update
            rst.MoveNext
        Next i
        
        rst.Close
        rst1.Close
        Set rst = Nothing
        Set rst1 = Nothing
        
        
    Exit_Err_handler:
        Exit Function
    
    Err_handler:
        MsgBox Err.Number & " " & Err.Description
        Resume Exit_Err_handler
    
    End Function
    
  • Re: Calcolo automatico scadenze pagamento fatture

    Metodipagamento{idmetodo(pk), descrizione}

    scadenzepagamenti{idscapag(pk), idmetodo(fk), giorni, finemese, percentuale}

    scadenziario{idscadenziario(pk), iddocumento(fk), tiposcadenza(fornitori/clienti), datascadenza, importodare, importoavere}

    se a vista
    giorni 0 finemese false percentuale 100

    se a fine mese
    giorni 0 finemese true percentuale 100

    se 60 gg
    giorni 60 finemese false percentuale 100

    se 30/60 gg
    giorni 30 finemese false percentuale 50
    giorni 60 finemese false percentuale 50

    inserito il metodo di pagamento configuri la detail relativa come sopra

    in fase di carico apri la tabella scadenzepagamenti in base al pagamento scelto
    1) o usi il record count 
     for x to recordcount
       scadenziario.iddocumento=fatura.idfattura
       bla bla....
       se fattura scadenziario.importoavere=fattura.totalefattura*scadenziariopercentuale/100
       se notacredito scadenziario.importodare=fattura.totalefattura*scadenziariopercentuale/100
       (fai un controllo se siamo all'ultima rata e non ci sono residui che altrimenti vanno sommati alla rata)
       datascadenza.date=fattura.datafattura+giorni
       se finemese (qui esegui una funzione che controlla se il mese della scadenza è 28/29/30 o 31 gg)
       datascadenza.data=return della funzione
     finito.
    2) o te ne freghi e usi 
      while.... idem + o - come sopra

    nell'esempio ho preso in esame una fattura fornitori in caso di clienti fattura va in dare nota credito in avere

    altrimenti per come sei abituato a gestire lo scadenziario (che non dovrebbe essere prima nota).

    p.s. ovviamente alle tabelle puoi aggiungere tutti i campi che ritieni opportuni, idem per i nomi tabelle e campi

  • Re: Calcolo automatico scadenze pagamento fatture

    Grazie Andrea per gli spunti: diciamo che sostanzialmente il DB e' strutturato come hai indicato tu; 

    05/11/2025 - sihsandrea ha scritto:

    scadenzepagamenti{idscapag(pk), idmetodo(fk), giorni, finemese, percentuale}

    Io ho aggiunto un ulteriore campo con ulteriori giorni oltre il fine mese perche', come saprai le forme di pagamento sono "la qualsiasi" per cui ho fornitori che hanno 60/90 gg FM +5 gg: quindi incassano sempre il 5 del mese successivo; altri hanno addirittura + 10 gg.

    Per quanto riguarda la parte dello scadenziario, non essendo un DB di contabilita' ma solo di produzione, non e' implementato perche' non mi serve.

    Grazie ancora

  • Re: Calcolo automatico scadenze pagamento fatture

    Buongiorno, mi sono accorto che la funzione di cui sopra manca della parte che riguarda la gestione degli errori di digitazione o inserimento: per esempio una data o un metodo di pagamento sbagliati oppure un importo differente. Dopo aver eseguito la funzione di cui sopra, l'eventuale correzione sarebbe da fare manualmente. Vorrei quindi implementare la funzione con una select case in base a quanti records sono presenti nella tabella dei pagamenti aventi lo stesso ID fattura.

    Ma mi sono subito arenato con il seguente codice che dovrebbe contare il numero di records:

    Public Function CalcoloDataPagamento(intTipoPagamento As Integer, pdatafattura As Date, pidfattura As Integer, pimporto As Currency, ByVal nometabella As String)
        ...
        
        Set rst1 = DBEngine(0)(0).OpenRecordset(nometabella, dbOpenDynaset)
        'apro un recordset nuovo, nella tabella passata come parametro, con le scadenze di pagamento o incasso
        
        rst1.MoveLast   								'mi sposto sull'ultimo record per scorrere tutto il recordset
        rst1.Filter = rst1.Fields(1) = pidfattura   	'filtro il recordset sul campo 1 in base al valore pssato alla funzione
        Set rst2 = rst1.clone							'apro un nuovo recordset filtrato dal recordset precedente
        rst2.MoveLast 									'mi sposto sull'ultimo record per scorrere tutto il recordset
        Debug.Print rst2.RecordCount

    Va in errore nella riga selezionata con: errore 3061 parametri insufficienti previsto 2

    La mia intenzione e' verificare se e quanti records ci sono nel rst1 che hanno valori nel campo 1 uguali al parametro pidfattura. 

    La function e' pubblica perche' viene usata in due forms differenti (fatture clienti e fatture fornitori)  e relative tabelle con scadenze incassi e scadenze pagamenti. 

    Grazie in anticipo per suggerimenti

  • Re: Calcolo automatico scadenze pagamento fatture

    Dopo una giornata di tentativi, ho finalmente trovato una soluzione funzionante, che posto qui di seguito. E' sicuramente migliorabile, ma la mia conoscenza di VBA, per ora, arriva fino a qui...

    Public Function CalcoloDataPagamento(intTipoPagamento As Integer, pdatafattura As Date, pidfattura As Integer, pimporto As Currency, nometabella As String, nomecampo As String)
        'Parametri da passare in ordine:ID tipo pagamento, Data fattura, ID fattura, Importo fattura, nome tabella pagamenti tra doppi apici, nome campo id fattura tra doppi apici
    On Error GoTo Err_handler
    
        Dim dt As Date
        Dim rst As DAO.Recordset
        Dim rst1 As DAO.Recordset
        Dim rst2 As DAO.Recordset
        Dim aint As Integer
        Dim bint As Integer
        Dim i As Integer
        Dim dint As Integer
        
        Set rst = DBEngine(0)(0).OpenRecordset("SELECT * FROM TblCPcalcolopagamento WHERE NUMtabCPIDtabTPid= " & intTipoPagamento & " ORDER BY IDtabCPid ASC", dbOpenSnapshot, dbReadOnly)
        'apro un recordset con i dati per il calcolo del pagamento fattura
        
        rst.MoveLast
        bint = rst.RecordCount  'valorizzo la variabile con il numero di scadenze per il metodo di pagamento corrente
       
        Set rst1 = DBEngine(0)(0).OpenRecordset(nometabella, dbOpenDynaset)
    		'apro un recordset nuovo nella tabella delle scadenze
        
        Set rst2 = DBEngine(0)(0).OpenRecordset("SELECT * FROM " & nometabella & " WHERE " & nomecampo & "= " & pidfattura, dbOpenDynaset)
        'apro un recordset filtrato per verificare se sono presenti records nella tabella scadenze con id fattura corrente
        
        If Not rst2.EOF Then    'se il recordset non e' vuoto
            rst2.MoveLast       'scorro il recordset
            aint = rst2.RecordCount 'associo il numero di records alla variabile
        Else
            aint = 0    'valorizzo la variabile se recordset vuoto
        End If
        Select Case True
            Case aint = 0   'caso con nessun record in tabella scadenze
                rst.MoveFirst
                For i = 1 To bint
        
                    dt = DateAdd("d", rst.Fields(3), pdatafattura)    'Aggiungo i giorni(3)
                    dt = DateAdd("m", rst.Fields(2), dt)                'Aggiungo i mesi(2)
    
                    If rst.Fields(4) Then
                        dt = DateSerial(Year(dt), Month(dt) + 1, 0)  'Calcolo il fine mese(4)
                    End If
           
                    dt = DateAdd("d", rst.Fields(5), dt)            'Aggiungo gli ulteriori giorni(5)
        
                    rst1.AddNew                                     'aggiungo nuovo record al recordset
                    rst1.Fields(1) = pidfattura                     'compilo il campo con ID fattura
                    rst1.Fields(2) = dt                             'compilo il campo con la data scadenza fattura
                    rst1.Fields(3) = pimporto * rst.Fields(6)       'calcolo e compilo il campo dell'importo in scadenza
            
                    If i = bint Then                                'se e' l'ultima scadenza
                        rst1.Fields(4) = True                       'compilo il flag per evasione ultimo pagamento
                    Else
                        rst1.Fields(4) = False
                    End If
                    rst1.Update
                    rst.MoveNext
                Next i
                
            Case aint > 0 And bint = aint       'caso in cui sono presenti records nella tabella scadenze ed il numero di scadenze e' uguale
                rst.MoveFirst                   'mi muovo al primo record
                rst2.MoveFirst                  'mi muovo al primo record
                For i = 1 To bint
        
                    dt = DateAdd("d", rst.Fields(3), pdatafattura)    'Aggiungo i giorni(3)
                    dt = DateAdd("m", rst.Fields(2), dt)                'Aggiungo i mesi(2)
    
                    If rst.Fields(4) Then
                        dt = DateSerial(Year(dt), Month(dt) + 1, 0)  'Calcolo il fine mese(4)
                    End If
           
                    dt = DateAdd("d", rst.Fields(5), dt)            'Aggiungo gli ulteriori giorni(5)
                    
                    rst2.Edit                                       'modifico record corrente
                    rst2.Fields(1) = pidfattura                     'compilo il campo con ID fattura
                    rst2.Fields(2) = dt                             'compilo il campo con la data scadenza fattura
                    rst2.Fields(3) = pimporto * rst.Fields(6)       'calcolo e compilo il campo dell'importo in scadenza
        
                    If i = bint Then
                        rst2.Fields(4) = True                       'compilo il flag per evasione ultimo pagamento
                    Else
                        rst2.Fields(4) = False
                    End If
                    rst2.Update
                    rst2.MoveNext
                    rst.MoveNext
                Next i
                
            Case aint > 0 And bint > aint       'caso in cui sono presenti records nella tabella scadenze ma il numero di scadenze e' maggiore
                rst.MoveFirst
                rst2.MoveFirst
                For i = 1 To bint
                    If i <= aint Then                                       'correggo i records esistenti
                        dt = DateAdd("d", rst.Fields(3), pdatafattura)    'Aggiungo i giorni(3)
                        dt = DateAdd("m", rst.Fields(2), dt)                'Aggiungo i mesi(2)
    
                        If rst.Fields(4) Then
                            dt = DateSerial(Year(dt), Month(dt) + 1, 0)  'Calcolo il fine mese(4)
                        End If
           
                        dt = DateAdd("d", rst.Fields(5), dt)            'Aggiungo gli ulteriori giorni(5)
                        
                        rst2.Edit                                       'modifico record corrente
                        rst2.Fields(1) = pidfattura                     'compilo il campo con ID fattura
                        rst2.Fields(2) = dt                             'compilo il campo con la data scadenza fattura
                        rst2.Fields(3) = pimporto * rst.Fields(6)       'calcolo e compilo il campo dell'importo in scadenza
                        rst2.Fields(4) = False                          'rimuovo il flag di ultimo pagamento qualora fosse attivo
                        rst2.Update
                        If Not rst2.EOF Then
                            rst2.MoveNext
                        End If
                    Else                                                   'aggiungo gli ulteriori records non presenti
                        dt = DateAdd("d", rst.Fields(3), pdatafattura)    'Aggiungo i giorni(3)
                        dt = DateAdd("m", rst.Fields(2), dt)                'Aggiungo i mesi(2)
    
                        If rst.Fields(4) Then
                            dt = DateSerial(Year(dt), Month(dt) + 1, 0)  'Calcolo il fine mese(4)
                        End If
           
                        dt = DateAdd("d", rst.Fields(5), dt)            'Aggiungo gli ulteriori giorni(5)
                        
                        rst1.AddNew                                     'aggiungo un nuovo record
                        rst1.Fields(1) = pidfattura                     'compilo il campo con ID fattura
                        rst1.Fields(2) = dt                             'compilo il campo con la data scadenza fattura
                        rst1.Fields(3) = pimporto * rst.Fields(6)       'calcolo e compilo il campo dell'importo in scadenza
                        If i = bint Then
                            rst1.Fields(4) = True                       'compilo il flag per evasione ultimo pagamento
                        Else
                            rst1.Fields(4) = False
                        End If
                        rst1.Update
                    End If
                    rst.MoveNext
                Next i
                
            Case aint > 0 And bint < aint                   'caso in cui sono presenti records nella tabella scadenze ma il numero di scadenze e' minore
                rst.MoveFirst
                rst2.MoveFirst
                For i = 1 To aint
                    If i <= bint Then                                   'correggo i records esistenti
                        dt = DateAdd("d", rst.Fields(3), pdatafattura)    'Aggiungo i giorni(3)
                        dt = DateAdd("m", rst.Fields(2), dt)                'Aggiungo i mesi(2)
    
                        If rst.Fields(4) Then
                            dt = DateSerial(Year(dt), Month(dt) + 1, 0)  'Calcolo il fine mese(4)
                        End If
           
                        dt = DateAdd("d", rst.Fields(5), dt)            'Aggiungo gli ulteriori giorni(5)
                        
                        rst2.Edit                                       'correggo il record corrente
                        rst2.Fields(1) = pidfattura                     'compilo il campo con ID fattura
                        rst2.Fields(2) = dt                             'compilo il campo con la data scadenza fattura
                        rst2.Fields(3) = pimporto * rst.Fields(6)       'calcolo e compilo il campo dell'importo in scadenza
                        If i = bint Then
                            rst2.Fields(4) = True                       'compilo il flag per evasione ultimo pagamento
                        Else
                            rst2.Fields(4) = False
                        End If
                        rst2.Update
                        rst2.MoveNext
                    Else
                        rst2.Delete                                     'cancello i records non piu' necessari dalla tabella delle scadenze
                        rst2.MoveNext
                    End If
                    If Not rst.EOF Then
                        rst.MoveNext
                    End If
                Next i
        End Select
            
    Exit_Err_handler:
        rst.Close
        rst1.Close
        rst2.Close
        Set rst = Nothing
        Set rst1 = Nothing
        Set rst2 = Nothing
        Exit Function
    
    Err_handler:
        MsgBox Err.Number & " " & Err.Description
        Resume Exit_Err_handler
    
    End Function
    
Devi accedere o registrarti per scrivere nel forum
5 risposte