传递函数范围,相邻单元格和返回和

时间:2014-12-06 01:24:58

标签: vba excel-vba excel

我有以下Excel表格:

Sample Image

我想将第一列作为字符串传递,确定名为' LNA'的单元格的地址。和' LCAMP'并将相邻的单元格相加在'之间。那两个地址。我失败的代码:

Function LNAtoLCAMP(ComponentList) As Single

Dim i As Integer
Dim LBoundAddress As Variant, UBoundAddress As Variant

For i = LBound(ComponentList) To UBound(ComponentList)
    If ComponentList(i, 1).Value = "LNA" Then
        LBoundAddress = ComponentList(i, 1).Address.Offset(0, 1)
    End If
    If ComponentList(i, 1).Value = "LCAMP" Then
        UBoundAddress = ComponentList(i, 1).Address.Offset(0, 1)
    End If
Next

LNAtoLCAMP = Application.WorksheetFunction.Sum(LBoundAddress, ":", UBoundAddress)

End Function

也许有更好的方法?

3 个答案:

答案 0 :(得分:4)

试试这个:

Function LNAtoLCAMP() As Single
   Dim LNA As Range, LCAMP As Range

   With Sheets("Sheet1")
       Set LNA = .Range("B:B").Find("LNA").Offset(0, 1)
       Set LCAMP = .Range("B:B").Find("LCAMP").Offset(0, 1)
       If Not LNA Is Nothing And Not LCAMP Is Nothing Then _
           LNAtoLCAMP = Evaluate("SUM(" & .Range(LNA, LCAMP).Address & ")")
   End With
End Function

Edit2:满足您的动态需求。

Function CONSUM(rng As Range, str1 As String, str2 As String, _
        Optional idx As Long = 1) As Variant
    Application.Volatile '<~~ autoupdate on cell change, remove otherwise
    Dim r1 As Range, r2 As Range
    Set r1 = rng.Find(str1, rng(1), , xlWhole)
    Set r2 = rng.Find(str2, rng(1), , xlWhole, , xlPrevious)
    If Not r1 Is Nothing And Not r2 Is Nothing Then _
        CONSUM = Application.Sum(rng.Parent.Range(r1.Offset(0, idx), _
        r2.Offset(0, idx))) Else CONSUM = CVErr(xlErrValue)
End Function

在第二个功能中,您可以选择搜索范围并指定要搜索的字符串。
如果找不到您指定的字符串,则会返回#VALUE!错误。 HTH。

对于 Edit2 ,偏移也是动态的(默认为1)。此外,这将把第一个字符串的第一个实例与由chrisneilsen提出的第二个实例相加。

<强>结果:

enter image description here

答案 1 :(得分:3)

根据您的评论,您将该功能称为

=LNAtoLCAMP(B16:B61)

这是不是传递一个数组,它正在传递一个range(这是一件好事)

您的功能,已修改:

Function LNAtoLCAMP(ComponentList As Range) As Variant
    Dim i As Long
    Dim dat As Variant
    Dim Sum As Double

    Dim LBoundAddress As Long, UBoundAddress As Long

    dat = ComponentList.Value
    For i = LBound(dat, 1) To UBound(dat, 1)
        Select Case dat(i, 1)
            Case "LNA", "LCAMP"
                If LBoundAddress = 0 Then
                    LBoundAddress = i
                End If
                If i > UBoundAddress Then
                    UBoundAddress = i
                End If
        End Select
    Next

    For i = LBoundAddress To UBoundAddress
        Sum = Sum + dat(i, 2)
    Next
    LNAtoLCAMP = Sum
End Function

使用范围

中的两个列进行调用
=LNAtoLCAMP(B16:C61)

注意:

  1. 我假设你想在总和中包含隐藏的行,而“Between”包括LNA和LCAMP所在的行。如果需要,这两个假设都很容易修改。

  2. 我还假设您要将 字符串。如果需要,也可以轻松修改。

  3. 您还可以传入搜索字符串,使其更具灵活性。

  4. 您应该添加错误处理,例如,如果其中一个搜索字符串不在列表中

答案 2 :(得分:0)

如果您坚持使用ApplicationFunction,则需要引号。

另外我认为它应该是.offset().address(需要翻转)

测试工作:

Function LNAtoLCAMP(ByVal ComponentList As Range) As Single
    Dim LBoundAddress As Range, UBoundAddress As Range
    Dim cel As Range
    For Each cel In ComponentList
        If cel.Value = "LNA" Then
            Set LBoundAddress = cel.Offset(0, 1)
        End If
        If cel.Value = "LCAMP" Then
            Set UBoundAddress = cel.Offset(0, 1)
        End If
    Next cel
    LNAtoLCAMP = Application.WorksheetFunction.Sum(Range(LBoundAddress, UBoundAddress))
End Function