panmor
panmor

Reputation: 13

VBA code to create and update balance in field on form and table

I hope you can help me. I am using MS access 2003 and have created a table with folloing fields RefNo,TransactionDate,Detail,Debit,Credit and balance. Transaction dates are indexed in table. I have created a form where i enter the date and amount in either debit or credit field and it will calculate the balance. My problem is it is fine if done in sequential order but if i need to enter one missing transaction in the middle for old date it needs to look at the last balance for that date and add or substract accorting to the credit or debit amount and should also adjust the subsequent balance.Can anyone help me to write the code? Thank you in advance.

Upvotes: 0

Views: 4983

Answers (1)

MrP
MrP

Reputation: 346

This is what I came up with. It requires a non unique composite index of RefNo, TransactionDate, Debit and Credit (all Ascending) on your table (referred to as Transactions in my example)

Sample data looks like this

Id  RefNo  TransactionDate  Detail           Debit   Credit     Balance
--  -----  ---------------  ---------------  ------  ---------  -------
1   1      31/12/2010       Brought Forward                     £502.79
2   1      01/01/2011       Debit Item 1     £11.40     
3   1      01/01/2011       Debit Item 2     £11.40     
4   1      01/01/2011       Debit Item 3     £11.40     
5   1      02/01/2011       Debit Item 1     £50.00     
6   1      02/01/2011       Crebit Item 1            £72.20 
7   1      03/01/2011       Debit Item 1     £11.40     
8   1      03/01/2011       Debit Item 2     £11.40     
9   1      03/01/2011       Credit Item 1            £1,200.00  
11  2      01/01/2011       Debit Item 1     £120.00        
12  2      01/01/2011       Credit Item 1            £800.00    
13  2      02/01/2011       Debit Item 1     £10.00

VBA code

Public Sub CalculateBalance(refNo As Long, transactionDate As Date)

Dim db As DAO.Database
Set db = CurrentDb

Dim transactions As DAO.Recordset
Set transactions = db.OpenRecordset("transactions")
transactions.Index = "RefNo_TransactionDate_Debit_Credit"

Dim balance As Currency

Dim previousBalanceBookmark As Variant

If Not (transactions.BOF And transactions.EOF) Then

    transactions.Seek ">=", refNo, transactionDate, Null, Null

    ' Find the previous balance
    Do While transactions.Fields("RefNo").Value = refNo

        If Not IsNull(transactions.Fields("Balance").Value) Then
            previousBalanceBookmark = transactions.Bookmark
            If transactions.Fields("TransactionDate").Value < transactionDate Then
                Exit Do
            End If
        End If

        transactions.MovePrevious
        If transactions.BOF Then Exit Do
    Loop

    If IsEmpty(previousBalanceBookmark) Then

        ' Create an opening balance
        transactions.AddNew
        transactions.Fields("RefNo").Value = refNo
        transactions.Fields("TransactionDate").Value = transactionDate - 1
        transactions.Fields("Detail").Value = "Brought Forward"
        transactions.Fields("Balance").Value = 0
        transactions.Update

        ' bookmark the balance
        previousBalanceBookmark = transactions.LastModified

    End If

    ' Re-calculate balance from the bookmarked record onwards
    transactions.Bookmark = previousBalanceBookmark
    balance = transactions.Fields("Balance").Value
    Dim previousDate As Date
    previousDate = transactions.Fields("TransactionDate").Value
    transactions.MoveNext

    Do Until transactions.Fields("RefNo") <> refNo

        ' Update the balance of previous days last record
        If transactions.Fields("TransactionDate").Value > previousDate Then
            transactions.MovePrevious
            transactions.Edit
            transactions.Fields("Balance").Value = balance
            transactions.Update
            transactions.MoveNext
        End If

        ' Clear any existing balances
        If Not IsNull(transactions.Fields("Balance").Value) Then
            transactions.Edit
            transactions.Fields("Balance").Value = Null
            transactions.Update
        End If

        balance = balance - Nz(transactions.Fields("Debit").Value, 0)
        balance = balance + Nz(transactions.Fields("Credit").Value, 0)

        previousDate = transactions.Fields("TransactionDate").Value

        transactions.MoveNext
        If transactions.EOF Then Exit Do
    Loop

    ' Update the last record
    transactions.MovePrevious
    transactions.Edit
    transactions.Fields("Balance").Value = balance
    transactions.Update

End If

transactions.Close
Set db = Nothing

End Sub

Call this routine when you save a new transaction record supplying Refno and Transaction date and it will recalculate the daily balances from the most recent date prior to the current transaction date onwards. If no previous balance can be found a zero balance is created based on the current transaction date minus 1 day.

Additional:

The VBA code should be pasted into a seperate module i.e. not in the form code behind.

On your form you should have a save button. You need to add some code to the button's On Click event to save the record and then run the CalculateBalance code. Here's an example

Private Sub SaveRecord_Click()

Application.RunCommand acCmdSave

Call CalculateBalance(Forms!transactions!RefNo, Forms!transactions!TransactionDate)

End Sub

Note that when you add command buttons and use the wizard to configure the button action Access creates a Macro rather than inserting code behind the form. You will need to change the button's On Click property from [Embedded Macro] to [Event Procedure].

Hope this helps

Upvotes: 0

Related Questions