我设计了一个UDF来获得没有促销期的产品的平均销售额。
它应该如何工作,它将促销期间的销售价值替换为""
,然后获得销售的平均值。
需要注意的是:同一产品可能有一个或多个促销期
它在VBA或MsgBox中调用时效果很好,但在工作表中返回#Value
Public Function promless(itemcode As Range, daterange As Range, salesvalues As Range) As Double
Application.Volatile
'find promotion rows
Dim porrange1 As Range
Dim pormotionrow() As Long
ReDim pormotionrow(1 To 10)
Dim code As String
code = itemcode.Value
Set porrange1 = Sheets("por").Range("a:a").Find(code)
pormotionrow(1) = porrange1.Row
If Not pormotionrow(1) = 0 Then
For n = 2 To 10
pormotionrow(n) = Sheets("por").Range("a:a").FindNext(porrange1).Row
If pormotionrow(n) = pormotionrow(n - 1) Then
pormotionrow(n) = 0
Exit For
End If
Next
End If
Size = n - 1
ReDim Preserve pormotionrow(1 To Size)
'-------------------------------------------------------------------------------------
'put sart and end of promotions
Dim porstart(), porend() As Variant
ReDim porstart(1 To Size)
ReDim porend(1 To Size)
For n = 1 To Size
porstart(n) = Sheets("por").Range("c" & pormotionrow(n)).Value
Next
For n = 1 To Size
porend(n) = Sheets("por").Range("d" & pormotionrow(n)).Value
Next
'--------------------------------------------------------------
'get data range date and apply pormotion conditions
Dim daterangearr As Variant
daterangearr = daterange.Value
For n = 1 To daterange.Columns.Count
For i = 1 To Size
If daterangearr(1, n) >= porstart(i) And daterangearr(1, n) <= porend(i) Then
daterangearr(1, n) = "por"
End If
Next
Next
'----------------------------------------------------------------
'get sales values
Dim salesvaluesarr As Variant
salesvaluesarr = salesvalues.Value
'check if the date range is the same size of sales values
If salesvalues.Columns.Count <> daterange.Columns.Count Then
MsgBox ("date range must be same number of sales values")
End If
'empty sales values that are in pormotion
For n = 1 To salesvalues.Columns.Count
If daterangearr(1, n) = "por" Then salesvaluesarr(1, n) = Empty
Next
promless = Application.WorksheetFunction.Average(salesvaluesarr)
End Function
在我获得促销信息的工作表中:
并且原始工作表包含销售数据: