找到单元格块中最后使用的单元格

时间:2017-06-09 21:44:18

标签: excel excel-formula

我需要一个公式来定位块中最后使用的单元格。最后使用的单元格我的意思是:

  1. 找到包含非空数据的最后一列(最右侧)
  2. 找到该列中包含非空数据的最低单元格
  3. 返回该单元格的地址
  4. 例如,在块 B2:I16

    Spreadsheet

    该功能应返回: I15 而不是 D16 。我已经有一个我想要替换的VBA UDF:

    Public Function FindLast(r As Range) As String
        Dim nLastRow As Long, nLastColumn As Long
        Dim nFirstRow As Long, nFirstColumn As Long
        Dim i As Long, j As Long
    
        nLastRow = r.Rows.Count + r.Row - 1
        nLastColumn = r.Columns.Count + r.Column - 1
        nFirstRow = r.Row
        nFirstColumn = r.Column
    
        For i = nLastColumn To nFirstColumn Step -1
            For j = nLastRow To nFirstRow Step -1
                If Len(r(j, i)) > 0 Then
                    FindLast = r(j, i).Address(0, 0)
                    Exit Function
                End If
            Next j
        Next i
    End Function
    

    由于工作表必须在无宏环境中工作。

3 个答案:

答案 0 :(得分:3)

这个{数组公式}有效:

=ADDRESS(MAX(ROW(L1:P5)*(LEN(L1:P5)>0)*(COLUMN(L1:P5)=
   MAX(COLUMN(L1:P5)*(LEN(L1:P5)>0)))),
   MAX(COLUMN(L1:P5)*(LEN(L1:P5)>0)), 4)

Ctrl + Shift + Enter

显然,第二个术语捕获了正确的列(这是容易的部分)。第一个术语包括第二个术语,以便在该列中搜索最后一个填充的行。

在下图中,它已应用于L1:P5范围,并产生了正确的结果O4

enter image description here

我到目前为止发现的唯一缺点是,如果范围包含错误单元格,它将会出错,但是从读取OP的UDF看,这似乎不是问题。如果是这样,一些额外的IFERROR将解决它:

=ADDRESS(MAX(ROW(L1:P5)*IFERROR(LEN(L1:P5)>0, 0)*(COLUMN(L1:P5)=
  MAX(COLUMN(L1:P5)*IFERROR(LEN(L1:P5)>0,0)))),
  MAX(COLUMN(L1:P5)*IFERROR(LEN(L1:P5)>0, 0)), 4)

Ctrl + Shift + Enter

编辑:在4功能中添加了参数ADDRESS,以便从结果中删除$。我修改后的测试结果与OP的UDF相匹配,用r(j, i)替换r.Parent.Cells(j, i)

答案 1 :(得分:3)

这是一个非CSE版本:

<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.98.1/js/materialize.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.98.1/css/materialize.min.css" rel="stylesheet"/>
<a class="waves-effect waves-light btn view" data-target="modal1">View Scores</a>
<!-- Modal Structure -->
<div id="modal1" class="modal">
  <div class="modal-content">
    <h4>Modal Header</h4>
    <p>A bunch of text</p>
  </div>
  <div class="modal-footer">
    <a href="#!" class=" modal-action modal-close waves-effect waves-green btn-flat">Agree</a>
  </div>
</div>

enter image description here

答案 2 :(得分:1)

我的第一种方法类似于@ ScottCraner's。

=ADDRESS(MOD(AGGREGATE(14,6,(ROW(L1:P5)+COLUMN(L1:P5)*10^7)*(L1:P5<>""),1),10^7),AGGREGATE(14,6,COLUMN(L1:P5)*(L1:P5<>""),1),4)

此处第一个AGGREGATE用于计算最大值:
COL_NUM*10^7+ROW_NUM 对于非空单元格(乘以10 ^ 7确保列优先级)。所以这个函数在技术上返回两个坐标(例如P4它是160000004 - 第16列和第4行)。 MOD提取行号。

但如果一个AGGREGATE可以返回两个坐标(作为一个数字),则下一步是尝试查找公式,仅使用AGGREGATE一次返回地址。这是我能想到的最好的:

=BASE(AGGREGATE(14,6,(DECIMAL(ROW(L1:P5),36)+36^6*(DECIMAL(ADDRESS(1,COLUMN(L1:P5),4),36)-1)*(L1:P5<>"")),1),36)

这个公式:

  1. 解码Base36中的列字母(向左移6位)到 十进制
  2. 将行号(!)从Base36解码为十进制
  3. 计算非空单元格的最大值
  4. 将结果编码为Base36
  5. 缺点:

    1. BASE在Excel2013中引入
    2. 公式返回P000004而不是P4 - 但它仍然是有效的单元格地址 - 可以与INDIRECT一起使用
    3. 执行大量计算 - 仅尝试使用一个AGGREGATE来解决问题。
相关问题