3

我已经在这个问题上绞尽脑汁三天了,也许你可以帮助我解决这个问题。

所以,我有3张桌子。

一个称为项目价格,其中包含某些项目在给定时间内的价格。

基本上该表如下所示:

ItemName | Startdate  | Enddate    | Price
-------------------------------------------
Watch    | 01/01/2012 | 04/08/2012 | 180€
Watch    | 05/08/2012 | 31/12/2012 | 150€
Watch    | 01/01/2013 | 31/12/2013 | 200€

另一个表名为Sales,其中包含每个月已售出的商品数量。

该表如下所示:

ItemName | SaleMonth  | Number
-----------------------------
Watch    | 01/01/2012 | 93
  .             .        .
  .             .        .
  .             .        .
Watch    | 01/05/2013 | 59
Watch    | 01/06/2013 | 74

最后一个称为汇率,即每月从欧元到英镑的汇率。

ExchangeMonth | Rate  |
-----------------------
 01/01/2013   | 1.225 | 
 01/02/2013   | 1.166 |

为了计算我在一个月内获得了多少,我使用这个公式:

Gain_month_i = (ItemPrice_month_i-1 * ItemsSold_month_i-1)/ExchangeRate_month_i

我想计算在给定期间我获得了多少。

但是,如果我选择的时间段与我的项目价格表中的不同时间段重叠,我无法找到获得正确结果的方法(例如,如果我想查看从 01/02/2012 到2014 年 1 月 1 日)

4

1 回答 1

1

您的问题的本质是您的 [Sales] 数字是按月汇总的,但商品的价格可能在月初和月底之间发生了变化。所以,如果你在 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 中运行查询,将 [Sales] 表中每一行的销售数量、平均价格和汇率汇总在一起:

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

如果将该查询保存在 Access 中,则可以在其他查​​询中使用它(就像使用表一样)来执行其余的计算。

于 2013-10-21T13:43:26.567 回答