如何将多个宏和Excel函数组合成一个按钮单击执行的宏?

时间:2017-07-25 12:27:18

标签: excel vba excel-vba excel-formula

我需要将多个宏组合到按钮单击时执行的单个宏。如果我写错了什么,请原谅我,因为我对excel宏和vb完全不熟悉。

以下是该方案。

步骤:

  1. 计算总数
  2. 提取参考
  3. 比较匹配参考的总字段值,并将其标记为“完成”如果匹配参考的总和总和计算为。
  4. (适用解释...) 的 首先,我计算一个名为total的新列的借方和贷方金额,为此,我最初使用了SUM函数。之后,我尝试使用按钮单击

    上执行的宏

    (旧宏)

    Private Sub getTotal_Click()
        With ActiveSheet
           lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
        End With
    For i = 5 To lastRow
        Range("K" & i).Value = Range("F" & i).Value + Range("G" & i).Value
    Next i
    End Sub
    

    与使用公式(以分钟结束时)相比,耗时(在75k记录上执行约2小时)非常耗时。我仍然无法理解这个原因。无论如何修改Dy.Lee的答案,只需几秒钟就可以计算总数。

    (根据Dy.Lee的回答修改)

    Private Sub getTotal_Click()
        Dim vDB As Variant, vR() As Variant
        Dim i As Long, n As Long, lastRow As Long
    
        With ActiveSheet
           lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
           vDB = .Range("R5", "S" & lastRow)
           n = UBound(vDB, 1)
           ReDim vR(1 To n, 1 To 1)
           For i = 1 To n
               vR(i, 1) = vDB(i, 1) + vDB(i, 2)
           Next i
          .Range("AL5").Resize(n) = vR
        End With
    
    End Sub
    

    现在转到我用来从D和E列中的字符串中提取模式的第二个宏。

    Function extractReference(cid_No As String, pm_source As String)
    Dim regExp As Object, findMatches As Object, match As Object
    Dim init_result As String: init_result = ""
    
    Set regExp = CreateObject("vbscript.regexp")
    With regExp
        .Global = True
        .MultiLine = False
        .Pattern = "(?:^|\D)(\d{5,6})(?!\d)"
    End With
    
    
    Set findMatches = regExp.Execute(pm_source)
    For Each match In findMatches
        init_result = init_result + match.SubMatches.Item(0)
    Next
    
    If init_result <> "" Then
        extractReference = cid_No & " | " & init_result
    Else
        extractReference = ""
    End If
    End Function
    

    这个宏工作正常。

    最后,在将提取的参考和总计复制到新工作表并为其创建数据表之后,我使用了以下函数

    =IF(ISBLANK([@Reference]), "", (IF((ROUND(SUMIFS([Total],[Reference],[@Reference]),2)=0), "complete", "")))

    这也很好。

    现在我真正想要的是我需要避免创建任何新的数据表或工作表,并在单击按钮的情况下在当前工作表中预先形成所有这些。无论如何可以在不使宏成为耗时的过程的情况下完成吗?非常感谢您的帮助!

    先谢谢

2 个答案:

答案 0 :(得分:1)

第一部分尝试:

Private Sub getTotal_Click()
Dim lastRow As Long
Dim sumRange As Range

    With ActiveSheet
       lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
    End With
    Set sumRange = Range(Range("K5"), Range("K" & lastRow))
    sumRange.FormulaR1C1 = "=RC[-5]+RC[-4]"
    sumRange.Copy
    sumRange.PasteSpecial Paste:=xlPasteValues
    Application.CutCopyMode = False
End Sub

另外,如果你仍然想循环注意调用像.Cells(1, 1)这样的单元格比Range("A1")更快

答案 1 :(得分:1)

您需要使用Variant Array。它更快。

Private Sub getTotal_Click()
    Dim vDB As Variant, vR() As Variant
    Dim i As Long, n As Long, lastRow As Long

    With ActiveSheet
       lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
       vDB = .Range("f5", "g" & lastRow)
        n = UBound(vDB, 1)
        ReDim vR(1 To n, 1 To 1)
        For i = 1 To n
            vR(i, 1) = vDB(i, 1) + vDB(i, 2)
        Next i
       .Range("k5").Resize(n) = vR
    End With

End Sub