Excel 将数组公式转换为正则公式
大家好,通过使用数组公式计算(在上面的示例中): 统计仅购买了少于5台产品1且区号仅与相邻D单元匹配的唯一客户 我在E11中使用以下数组公式:Excel 将数组公式转换为正则公式,excel,Excel,大家好,通过使用数组公式计算(在上面的示例中): 统计仅购买了少于5台产品1且区号仅与相邻D单元匹配的唯一客户 我在E11中使用以下数组公式: =SUM(IF(FREQUENCY(IF($G$2:$G$7=D11, IF($I$2:$I$7="Product 1",IF($J$2:$J$7<5,IF($E$2:$E$7<>"", MATCH($E$2:$E$7,$E$2:$E$7,0))))),ROW($E$2:$E$7)-ROW(G2)+1),1))
=SUM(IF(FREQUENCY(IF($G$2:$G$7=D11,
IF($I$2:$I$7="Product 1",IF($J$2:$J$7<5,IF($E$2:$E$7<>"",
MATCH($E$2:$E$7,$E$2:$E$7,0))))),ROW($E$2:$E$7)-ROW(G2)+1),1))
=总和(如果频率(如果($G$2:$G$7=D11,
IF($I$2:$I$7=“Product 1”,IF($J$2:$J$7好的,我不确定我是否理解所有条件和累积,但我认为这里有一个VBA函数可以完成它
首先,从Excel Developer菜单打开VBA。然后在VBA中,从插入菜单创建一个新模块(只需将其设置为Module1)。然后将以下两个函数粘贴到VBA模块中
Public Function AreaUniqueCustomersLessThan(ReportAreaRange, AreaRange, ProductRange, SalesRange, CustomerRange)
On Error GoTo Err1
Dim RptAreas() As Variant
Dim Areas() As Variant, Products() As Variant, Sales() As Variant, Customers As Variant
RptAreas = ArrayFromRange(ReportAreaRange)
Areas = ArrayFromRange(AreaRange)
Products = ArrayFromRange(ProductRange)
Sales = ArrayFromRange(SalesRange)
Customers = ArrayFromRange(CustomerRange)
Dim r As Long, s As Long 'report and source rows indexes
Dim mxr As Long, mxs As Long
mxr = UBound(RptAreas, 1)
mxs = UBound(Areas, 1)
'encode the ReportAreasList into accumulation array indexes
Dim AreaCustomers() As Collection
Dim i As Long, j As Long
Dim colAreas As New Collection
ReDim AreaCustomers(1 To mxr)
For r = 1 To mxr
On Error Resume Next
'Do we have the area already?
j = colAreas(RptAreas(r, 1))
If Err.Number <> 0 Then
'Add a new area to the collection and array
i = i + 1
colAreas.Add i, RptAreas(r, 1)
Set AreaCustomers(i) = New Collection
j = i
End If
Next r
'now scan the source rows, accumulating distinct customers
' for any ReportAreas
For s = 1 To mxs
'is this row's Arera in the report Area list?
i = 0
On Error Resume Next
i = colAreas(Areas(s, 1))
On Error GoTo Err1
If i > 0 Then
'this is a report Area code, so check the conditions
If Products(s, 1) = "Product 1" Then
If Sales(s, 1) < 5 Then
On Error Resume Next 'just ignore any duplicate errors
AreaCustomers(i).Add Customers(s, 1), Customers(s, 1)
On Error GoTo Err1
End If
End If
End If
Next s
'finally, return to the report area codes, returning the distinct count
' of customers
Dim count() As Variant
ReDim count(1 To mxr, 1 To 1)
For r = 1 To mxr
count(r, 1) = AreaCustomers(colAreas(RptAreas(r, 1))).count
Next r
AreaUniqueCustomersLessThan = count ' "foo"
Exit Function
Err1:
AreaUniqueCustomersLessThan = "%ERR(" & Str(Err.Number) & ")%" & Err.Description
Exit Function
Resume
End Function
'handle all of the cases, checking and conversions to convert
' a variant range into an array of Variant(1 to n, 1 to 1)
' (we do this because it makes data access very fast)
Function ArrayFromRange(varRange As Variant)
Dim rng As Range
Dim A() As Variant
Set rng = varRange
'Check for degenerate cases
If rng Is Nothing Then
'do nothing
ElseIf rng.count = 0 Then
'do nothing
ElseIf rng.count = 1 Then
ReDim A(1 To 1, 1 To 1)
A(1, 1) = rng.Value
Else
A = rng.Value
End If
ArrayFromRange = A
End Function
Public Function area uniquecustomerslessthan(ReportAreaRange、AreaRange、ProductRange、SalesRange、CustomerRange)
错误转到错误1
Dim rptaries()作为变量
变光区域()为变型,产品()为变型,销售()为变型,客户为变型
RptAreas=ArrayFromRange(ReportAreaRange)
面积=阵列范围(面积范围)
Products=ArrayFromRange(ProductRange)
Sales=ArrayFromRange(SalesRange)
Customers=ArrayFromRange(CustomerRange)
Dim r As Long,s As Long报告和源行索引
将mxr变长,mxs变长
mxr=UBound(1个区域)
mxs=UBound(区域,1)
'将ReportAreaList编码为累加数组索引
Dim Area Customers()作为集合
我和我一样长,我和我一样长
将这些区域作为新集合
重拨区域客户(1至mxr)
对于r=1到mxr
出错时继续下一步
“我们已经有这个区域了吗?
j=colAreas(Rtpareas(r,1))
如果错误号为0,则
'将新区域添加到集合和数组中
i=i+1
colAreas.添加i,RPT区域(r,1)
设置区域客户(i)=新集合
j=i
如果结束
下一个r
'现在扫描源行,积累不同的客户
“对于任何报告区域
对于s=1到mxs
'这一行的Arera是否在报告区域列表中?
i=0
出错时继续下一步
i=面积(面积(s,1))
错误转到错误1
如果i>0,那么
'这是一个报告区号,请检查条件
如果产品(s,1)=“产品1”,则
如果销售额小于5,则
“错误时继续下一步”忽略任何重复错误
区域客户(i).添加客户(s,1),客户(s,1)
错误转到错误1
如果结束
如果结束
如果结束
下一个s
'最后,返回报告区号,返回不同的计数
"顾客",
Dim count()作为变量
重拨计数(1对mxr,1对1)
对于r=1到mxr
计数(r,1)=区域客户(colAreas(r,1))。计数
下一个r
AreaUniqueCustomersLessThan=计数“foo”
退出功能
错误1:
AreaUniqueCustomersLessThan=“%ERR”(&Str(ERR.Number)&”)%”和ERR.Description
退出功能
简历
端函数
'处理所有情况,检查和转换以转换
'将变量范围转换为变量数组(1到n,1到1)
(我们这样做是因为它使数据访问速度非常快)
函数数组FromRange(变量为varRange)
变暗rng As范围
Dim A()作为变量
设置rng=varRange
"查退化病例",
如果rng不算什么,那么
“什么也不做
ElseIf rng.count=0,则
“什么也不做
ElseIf rng.count=1,则
重拨A(1对1,1对1)
A(1,1)=平均值
其他的
A=平均值
如果结束
ArrayFromRange=A
端函数
最后,转到您的数组公式区域,并将以下数组公式粘贴到“Sales<5”列表中:{=AreaUniqueCustomersLessThan(D$11:D$16,G$2:G$7,I$2:I$7,J$2:J$7,E$2:E$7)}
注意,第一个范围必须与数组公式范围本身长度相同。另外四个范围(源数据范围)应该都是相同的长度(它们不必与第一个范围的长度相同)。好的,我不确定我是否理解了所有的条件和累加,但我认为这里有一个VBA函数可以实现
首先,从Excel Developer菜单打开VBA。然后在VBA中,从插入菜单创建一个新模块(只需将其设置为Module1)。然后将以下两个函数粘贴到VBA模块中
Public Function AreaUniqueCustomersLessThan(ReportAreaRange, AreaRange, ProductRange, SalesRange, CustomerRange)
On Error GoTo Err1
Dim RptAreas() As Variant
Dim Areas() As Variant, Products() As Variant, Sales() As Variant, Customers As Variant
RptAreas = ArrayFromRange(ReportAreaRange)
Areas = ArrayFromRange(AreaRange)
Products = ArrayFromRange(ProductRange)
Sales = ArrayFromRange(SalesRange)
Customers = ArrayFromRange(CustomerRange)
Dim r As Long, s As Long 'report and source rows indexes
Dim mxr As Long, mxs As Long
mxr = UBound(RptAreas, 1)
mxs = UBound(Areas, 1)
'encode the ReportAreasList into accumulation array indexes
Dim AreaCustomers() As Collection
Dim i As Long, j As Long
Dim colAreas As New Collection
ReDim AreaCustomers(1 To mxr)
For r = 1 To mxr
On Error Resume Next
'Do we have the area already?
j = colAreas(RptAreas(r, 1))
If Err.Number <> 0 Then
'Add a new area to the collection and array
i = i + 1
colAreas.Add i, RptAreas(r, 1)
Set AreaCustomers(i) = New Collection
j = i
End If
Next r
'now scan the source rows, accumulating distinct customers
' for any ReportAreas
For s = 1 To mxs
'is this row's Arera in the report Area list?
i = 0
On Error Resume Next
i = colAreas(Areas(s, 1))
On Error GoTo Err1
If i > 0 Then
'this is a report Area code, so check the conditions
If Products(s, 1) = "Product 1" Then
If Sales(s, 1) < 5 Then
On Error Resume Next 'just ignore any duplicate errors
AreaCustomers(i).Add Customers(s, 1), Customers(s, 1)
On Error GoTo Err1
End If
End If
End If
Next s
'finally, return to the report area codes, returning the distinct count
' of customers
Dim count() As Variant
ReDim count(1 To mxr, 1 To 1)
For r = 1 To mxr
count(r, 1) = AreaCustomers(colAreas(RptAreas(r, 1))).count
Next r
AreaUniqueCustomersLessThan = count ' "foo"
Exit Function
Err1:
AreaUniqueCustomersLessThan = "%ERR(" & Str(Err.Number) & ")%" & Err.Description
Exit Function
Resume
End Function
'handle all of the cases, checking and conversions to convert
' a variant range into an array of Variant(1 to n, 1 to 1)
' (we do this because it makes data access very fast)
Function ArrayFromRange(varRange As Variant)
Dim rng As Range
Dim A() As Variant
Set rng = varRange
'Check for degenerate cases
If rng Is Nothing Then
'do nothing
ElseIf rng.count = 0 Then
'do nothing
ElseIf rng.count = 1 Then
ReDim A(1 To 1, 1 To 1)
A(1, 1) = rng.Value
Else
A = rng.Value
End If
ArrayFromRange = A
End Function
Public Function area uniquecustomerslessthan(ReportAreaRange、AreaRange、ProductRange、SalesRange、CustomerRange)
错误转到错误1
Dim rptaries()作为变量
变光区域()为变型,产品()为变型,销售()为变型,客户为变型
RptAreas=ArrayFromRange(ReportAreaRange)
面积=阵列范围(面积范围)
Products=ArrayFromRange(ProductRange)
Sales=ArrayFromRange(SalesRange)
Customers=ArrayFromRange(CustomerRange)
Dim r As Long,s As Long报告和源行索引
将mxr变长,mxs变长
mxr=UBound(1个区域)
mxs=UBound(区域,1)
'将ReportAreaList编码为累加数组索引
Dim Area Customers()作为集合
我和我一样长,我和我一样长
将这些区域作为新集合
重拨区域客户(1至mxr)
对于r=1到mxr
出错时继续下一步
“我们已经有这个区域了吗?
j=colAreas(Rtpareas(r,1))
如果错误号为0,则
'将新区域添加到集合和数组中
i=i+1
colAreas.添加i,RPT区域(r,1)
设置区域客户(i)=新集合
j=i
如果结束
下一个r
'现在扫描源行,积累不同的客户
“对于任何报告区域
对于s=1到mxs
'这一行的Arera是否在报告区域列表中?
i=0
出错时继续下一步
i=面积(面积(s,1))
错误转到错误1
如果i>0,那么
'这是一个报告区域c
=getCounts(D11:D15,G2:G7,E2:E7,I2:I7,J2:J7)
getCounts(AreaStr,AreaRng,CustomerRng,ProductRng,SalesRng,[ProductName],[lessThan])