Reputation: 13
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
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