Код VBA для создания и обновления баланса в поле на форме и в таблице - PullRequest
0 голосов
/ 16 ноября 2011

Я надеюсь, что вы можете мне помочь.Я использую MS Access 2003 и создал таблицу с следующими полями RefNo, TransactionDate, Detail, Debit, Credit и balance.Даты сделок индексируются в табл.Я создал форму, в которой я ввел дату и сумму в поле дебет или кредит, и он рассчитает остаток.Моя проблема в том, что все в порядке, если это делается в последовательном порядке, но если мне нужно ввести одну недостающую транзакцию в середине для старой даты, необходимо просмотреть последний остаток на эту дату и добавить или вычесть соответствующую сумму кредита или дебета, и следуетТакже отрегулируйте последующий баланс. Может кто-нибудь помочь мне написать код?Заранее спасибо.

1 Ответ

0 голосов
/ 21 ноября 2011

Это то, что я придумал. Требуется неуникальный составной индекс 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].

Надеюсь, это поможет

...