简体   繁体   中英

Dynamic Calculated Field in VBA Access

I'm trying to add a field into an existing table. The field is calculated using two variables 'myPrice', which is the price of a record at a certain date, and 'previousPrice', which is the price of the same part from the first record, only a from the month previous. I'm using a loop to iterate through the entire recordset of prices, thereby altering the two variables each time. My code is as follows:

Function priceDifference()

Dim currentPrice As Currency
Dim previousPrice As Currency
Dim recordDate As Date
Dim previousDate As Date
Dim dbsASSP As DAO.Database
Dim priceTable As DAO.TableDef
Dim diffFld As DAO.Field2
Dim rstCurrentPrice As DAO.Recordset
Dim rstPreviousPrice As DAO.Recordset
Dim PN As String

Set dbsASSP = CurrentDb
strSQL = "SELECT * FROM qryPrice"
Set rstCurrentPrice = dbsASSP.OpenRecordset(strSQL, dbOpenDynaset)

Set priceTable = dbsASSP.TableDefs("tblPrice")
Set diffFld = priceTable.CreateField("Difference", dbCurrency)

If Not (rstCurrentPrice.EOF) Then
    rstCurrentPrice.MoveFirst
    Do Until rstCurrentPrice.EOF = True
        PN = rstCurrentPrice![P/N]
        recordDate = rstCurrentPrice![myDate]
        previousDate = Format(DateAdd("m", -1, recordDate), "M 1 YYYY")
        myPrice = rstCurrentPrice!Price
        strPreviousSQL = "SELECT * FROM qryPrice WHERE [MyDate] = #" & previousDate & "# AND [Type] = 'Net Price' AND [P/N] = " & PN & ""
        Set rstPreviousPrice = dbsASSP.OpenRecordset(strPreviousSQL, dbOpenDynaset)
        myCodeName = rstCurrentPrice!CodeName
        If DCount("[P/N]", "qryPrice", "[MyDate] = #" & previousDate & "# And [P/N] = " & PN) <> 0 Then
            previousPrice = rstPreviousPrice!Price
        Else
            previousPrice = myPrice
        End If

    rstCurrentPrice.MoveNext
    Loop
Else
    MsgBox "Finished looping through records."
End If

diffFld.Expression = myPrice - previousPrice

rstCurrentPrice.Close
rstPreviousPrice.Close

priceTable.Fields.Append diffFld

End Function

Syntactically, it works. The calculated field, however, does not give me the correct values and I cannot figure out why, although I imagine it has something to do with the dynamic formula.

Any help is appreciated. Thanks!!

Your code can't work as you append a number to the field instead of a formula, but you should avoid calculated fields

Use a query:

SELECT 
    nPrice.[P/N], 
    nPrice.Price,  
    nPrice.MyDate,
    oPrice.MyDate,
    nPrice.Price-Nz(oPrice.Price,nPrice.Price) AS diff
FROM (
   SELECT 
       [P/N],
       Price, 
       MyDate, 
       Format(DateAdd("m",-1,MyDate),"yyyymm") as previousMonthYear
   FROM 
       tblPrice) AS nPrice 
LEFT JOIN (
    SELECT 
        [P/N], 
        Price, 
        MyDate,
        Format(MyDate,"yyyymm") AS monthYear 
    FROM 
        tblPrice)  AS oPrice 
ON 
    nPrice.[P/N] = oPrice.[P/N] 
    AND nPrice.previousMonthYear = oPrice.monthYear

This calculates the difference dynamic and you don't need to store it.

I assume there is max one price per month, otherwise you need to filter the subqueries or just calculate the difference to the last price before. If the query is too slow ([P/N] and MyDate need an index) , you can still use it to update a field the table tblPrice , but this has to be updated every time a price is updated or inserted in tblPrice

I think you can avoid your code loop by using this query

SELECT A.qryPrice, A.MyDate, B.qryPrice, B.MyDate
FROM qryPrice A LEFT OUTER JOIN qryPrice B 
ON A.[P/N] = B.[P/N] 
AND B.MyDate = DATEADD(month, -1, A.MyDate)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM