Excel 将数组公式转换为正则公式

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))

大家好,通过使用数组公式计算(在上面的示例中):

统计仅购买了少于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))
=总和(如果频率(如果($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])