【问题标题】:How can I insert a dynamic last row into a formula?如何在公式中插入动态最后一行?
【发布时间】:2021-07-24 06:11:03
【问题描述】:

我正在使用一张干净的表格,我在其中粘贴一列具有不同行数的日期。我的目标是显示每个日期出现了多少次。但是,每次到达最后一行时,我都会不断收到运行时错误“1004”应用程序定义或对象定义错误。

这是我的代码:

Dim lastrow As Long
    Set ws = ActiveSheet
    Set startcell = Range("A1")
    lastrow = ws.Cells(Rows.Count, "A").End(xlUp).Row
    Range("B2").Formula = "=countif(A1:" & lastrow & ")"

提前致谢!!

【问题讨论】:

  • 您的 COUNTIF 公式缺少结束单元格的列规范,可能是 "=countif(A1:A" & lastrow & ")"

标签: vba excel-formula


【解决方案1】:

COUNTIF 函数采用 2 个参数 (https://support.microsoft.com/en-us/office/countif-function-e0de10c6-f885-4e71-abb4-1f464816df34),而不是您的代码中的一个。也错过了范围内的列字母。如果要处理 N 个日期,则必须使 N 个公式为 COUNTIF。 试试这个代码(A1 中 A 列中的日期,B 列中的公式):

Sub times()
    With ActiveSheet
        Intersect(.Columns(1), .UsedRange).Offset(0, 1).FormulaR1C1 = "=COUNTIF(C[-1],RC[-1])"
    End With
End Sub

结果:

【讨论】:

    【解决方案2】:

    已解决! 4 种方式

    高级

    • Countif 公式不正确(缺少:col 标签 A + 条件)
    • Outlook:快速修复,但所有日期都需要循环
    • 对于大型列表,当前方法可能会占用大量 CPU/时间

    解决方案 A-D:

    见下文(链接部分),用于 4 个解决方案(3 个基于宏 + 1 个无宏但动态解决方案)的 google 表格(带有完整的宏代码、描述)。简要说明:

    • A:输出并修正您的代码
    • B:与 A 一样,部署了 for 循环
    • C:用于更快实现 for 循环/.Function 代码的 VB 代码
    • D:无宏变体(建议/首选)

    截图


    比较表


    链接:


    VB 代码(A-C)

    为了完整性(可以在链接的 Google 表格中找到相同的内容,键入 - 所以无宏/安全工作簿):

    Sub Macro_A():
      
        
        lastrow = ActiveSheet.Cells(Rows.Count, "A").End(xlUp).Row
        cell = Range("a4").Address
        Range("B4").Value = "=countif(A1:" & "A" & lastrow & "," & cell & ")"
    '    For i = 1 To lastrow - Range(cell).Row + 1
    '        Range("B4").Offset(i - 1).Formula = "=countif(A1:" & "A" & lastrow & "," & Range(cell).Offset(i - 1).Address & ")"
    '    Next
    End Sub
    
    
    Sub Macro_B():
        Application.Calculation = xlCalculationManual
        start_time = Timer
        lastrow = ActiveSheet.Cells(Rows.Count, "A").End(xlUp).Row
        cell = Range("a4").Address
    '    Range("B4").Value = "=countif(A1:" & "A" & lastrow & "," & cell & ")"
        For i = 1 To lastrow - Range(cell).Row + 1
            Range("c4").Offset(i - 1).Formula = "=countif(A1:" & "A" & lastrow & "," & Range(cell).Offset(i - 1).Address & ")"
        Next
        Application.Calculation = xlCalculationAutomatic
        Range("c3").End(xlDown).Offset(2).Value = Round(Timer - start_time, 2)
        
        
    End Sub
    
    Sub Macro_C():
        start_time = Timer
        Set Rng = Range("A4", Range("A4").End(xlDown))
        For Each cell In Rng
            cell.Offset(0, 3) = WorksheetFunction.CountIf(Rng, cell.Value)
        Next
        Range("d3").End(xlDown).Offset(2).Value = Round(Timer - start_time, 2)
    End Sub
    

    无宏观溶液 (D)

    1. 转到公式(功能区),名称管理器:

    2. 在出现的名称管理器窗口中,单击“新建...”

    3. 根据要求填充对话框。 (根据要求修改工作表名称和 $A$4 起始单元格。)

    4. 通过点击右下角的向上箭头来测试您的新动态范围(应该选择 A 列中的日期,如下图所示)

    1. 在输出范围的第一个单元格(此处为单元格 D4)中输入单个公式*:

    公式(为方便起见):

    • range_countif

      =Sheet1!$A$4:OFFSET(Sheet1!$A$4,COUNTA(Sheet1!$A:$A)-2,0,1,1)

    • 在 D4 单元格中输入

      =COUNTIF(range_countif,range_countif)

    *注意:“溢出效应”需要 Office 360​​(输入为数组公式,否则使用“ctrl”+“shift”+“enter”)。

    如果您还有其他问题,请告诉我。祝您的 Excel 电子表格好运!

    【讨论】:

      【解决方案3】:

      有很多方法可以实现。我使用这个公式来获取行数

      =ArrayFormula(MAX(IF(L2s!A2:A1009<>"",ROW(2:1011))))
      

      然后我用它构建一个字符串

      ="L2s!A2:E"&D3
      

      我喜欢命名范围,所以我用构建的字符串 DynamicRangeL2s 命名单元格

      这是我在公式中使用动态范围的方式(denormalize() 是我编写的自定义函数,但可以是任何函数)使用 INDIRECT() 函数

      =denormalize(INDIRECT(DynamicRangeL2s),INDIRECT(DynamicRangeSchedule),2,2,"right")
      

      这是一篇关于动态范围的精彩文章

      https://www.benlcollins.com/formula-examples/dynamic-named-ranges/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多