你的问题的实质是,你的[销售]数字按月汇总,但该项目的价格可能会开始和月底之间发生了变化。所以,如果你在2012年8月卖出50块手表,你不知道当价格为180时有多少卖出,有多少是在价格降到150后卖出的。
在我看来,唯一的合理的解决方案是使用平均每月价格,根据各个价格生效月份的天数来计算。你可以做到这一点通过使用VBA函数是这样的:
Option Compare Database
Option Explicit
Public Function AverageMonthlyPrice(ItemName As String, AnyDayInMonth As Date) As Variant
Dim qdf As DAO.QueryDef, rst As DAO.Recordset
Dim FirstDayOfMonth As Date, LastDayOfMonth As Date, NumDaysInMonth As Long
Dim IntervalStart As Date, IntervalEnd As Date
Dim WeightedAveragePrice As Variant
WeightedAveragePrice = Null
FirstDayOfMonth = DateSerial(year(AnyDayInMonth), Month(AnyDayInMonth), 1)
LastDayOfMonth = DateAdd("d", -1, DateSerial(year(AnyDayInMonth), Month(AnyDayInMonth) + 1, 1))
NumDaysInMonth = DateDiff("d", FirstDayOfMonth, LastDayOfMonth) + 1
Set qdf = CurrentDb.CreateQueryDef("", _
"SELECT * FROM [Item Price] " & _
"WHERE ItemName = [pItemName] " & _
"AND Enddate >= [pFirstDay] AND Startdate <= [pLastDay]")
qdf!pItemName = ItemName
qdf!pFirstDay = FirstDayOfMonth
qdf!pLastDay = LastDayOfMonth
Set rst = qdf.OpenRecordset(dbOpenSnapshot)
Do While Not rst.EOF
IntervalStart = IIf(rst!StartDate < FirstDayOfMonth, FirstDayOfMonth, rst!StartDate)
IntervalEnd = IIf(rst!EndDate > LastDayOfMonth, LastDayOfMonth, rst!EndDate)
WeightedAveragePrice = Nz(WeightedAveragePrice, 0) + rst!Price * (DateDiff("d", IntervalStart, IntervalEnd) + 1)/NumDaysInMonth
rst.MoveNext
Loop
rst.Close
Set rst = Nothing
Set qdf = Nothing
If Not IsNull(WeightedAveragePrice) Then
WeightedAveragePrice = CCur(WeightedAveragePrice)
End If
AverageMonthlyPrice = WeightedAveragePrice
End Function
所以现在你可以运行在Access中一个查询,拉在一起销售数量,平均价格,并在[销售汇率的每一行表:
SELECT
Sales.ItemName,
Sales.SaleMonth,
Sales.Number,
AverageMonthlyPrice(Sales.ItemName, Sales.SaleMonth) AS AveragePrice,
[Exchange Rate].Rate AS ExchangeRate
FROM
Sales
INNER JOIN
[Exchange Rate]
ON [Exchange Rate].ExchangeMonth = Sales.SaleMonth
...返回类似:
ItemName SaleMonth Number AveragePrice ExchangeRate
-------- ---------- ------ ------------ ------------
Watch 2012-01-01 93 180 1.225
Watch 2012-08-01 50 153.871 1.166
Watch 2013-06-01 74 200 1.234
Watch 2013-05-01 59 200 1.123
如果您保存在访问该查询,那么你可以使用它(就像你使用一个表)在其他查询执行其余的部分 的计算。
感谢您的回答。 如果我理解的很好,如果在这个月没有价格变化,这个函数会给出正常的价格,或者如果它发生的话,按比例计算。 所以,如果我想用我的公式来执行我计算我只需要做到以下几点: 'SELECT SUM((AverageMonthlyPrice(Sales.ItemName,Sales.SaleMonth)* Sales.Number)/ EXCHANGERATE。价格)AS收益 从销售,[汇率] WHERE Sales.Itemname =“Watch” AND Sales.SaleMonth BETWEEN DATEADD(“m”,-1,01/02/2012)和DATEADD(“m”, - 1,31/12/2013) AND [Exchangerate] .Exchangemonth = DATEADD(“m”,1,Sales.SaleMonth);' 对吗? – Tom
@Tom是的,如果该月没有价格变化,函数应该给出“正常”的价格。至于你的查询,为什么不试着对付你的一小部分数据,看你的结果与你自己“做数学”时得到的结果是否相符? –
我将它标记为很好的答案,因为我认为这是我要这样做的方式,但我只有一个问题。这只是我的问题的一个简单例子,我的表比较复杂一些,例如Sales.Itemname不等于[Item price] .Itemname,但两个表由另一个链接。你的函数中要修改哪些字段来匹配具有不同字段的表,但基本上这些字段包含相同的数据? – Tom