Это то, что я придумал. Требуется неуникальный составной индекс
RefNo, TransactionDate, Debit и Credit (все по возрастанию) на вашей таблице (в моем примере это называется транзакции)
Пример данных выглядит так
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
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
Вызывайте эту процедуру, когда вы сохраняете новую запись транзакции с указанием даты Рефно и Транзакции, и она будет пересчитывать ежедневные остатки с самой последней даты до текущей даты транзакции и далее. Если предыдущий баланс не найден, создается нулевой баланс на основе текущей даты транзакции минус 1 день.
Дополнительно:
Код VBA должен быть вставлен в отдельный модуль, т. Е. Не в коде формы позади.
В вашей форме должна быть кнопка сохранения. Вам нужно добавить некоторый код в событие кнопки «Нажать», чтобы сохранить запись, а затем запустить код CalculateBalance. Вот пример
Private Sub SaveRecord_Click()
Application.RunCommand acCmdSave
Call CalculateBalance(Forms!transactions!RefNo, Forms!transactions!TransactionDate)
End Sub
Обратите внимание, что при добавлении командных кнопок и использовании мастера для настройки действия кнопки Access создает макрос, а не вставляет код за формой. Вам нужно изменить свойство кнопки при нажатии с [Embedded Macro]
на [Event Procedure]
.
Надеюсь, это поможет