我的两个宏“冲突”,即它们不能同时运行

时间:2019-05-17 15:45:32

标签: excel vba

背景

我的一个工作表中有2个宏,它们使 i)从彭博网站的收盘价直接进入工作表[通过按钮触发](单元格H3:向下)和 ii)如果此新值导致位于单元格K3:downwards中的公式发生更改,则另一个将注册时间戳记。然后,如果有任何更改,更改发生的时间将记录在H列的右列。

我的问题在于,当我按下按钮启动宏i)时,调试器弹出“运行时错误1004。对象'_application的方法'undo'失败”,导致宏ii)停止工作(即停止在感兴趣的栏中记录价值发生变化的时间)。调试器突出显示的代码行是“ Application.undo”

说实话,我对过程有点迷茫。

这是代码

免责声明:那里的大多数注释都可以使我了解代码的实际工作方式。非常感谢为这两个小组做出贡献的所有人。

Private Sub Worksheet_Calculate()

    Dim rMonitored As Range
    Dim MonitoredCell As Range
    Dim vSelected As Variant
    Dim aNewValues As Variant
    Dim ixFormulaCell As Long

    On Error Resume Next
    Set rMonitored = Me.Columns("K").SpecialCells(xlCellTypeFormulas)
    On Error GoTo 0
    If rMonitored Is Nothing Then Exit Sub  'No formula cells in column K

    Application.EnableEvents = False    'Disable events to prevent infinite calc loop
    Set vSelected = Selection           'Remember current selection (it may not be a range)

    'Prepare the array that will store the new values, the cells those values are in, and whether or not there was a change
    ReDim aNewValues(1 To rMonitored.Cells.Count, 1 To 3)
        'Column1 = new value
        'Column2 = cell address
        'Column3 = did value change?

    'Get the new value for each formula in column K
    ixFormulaCell = 0
    For Each MonitoredCell In rMonitored.Cells  'The formula cells may not be in a contiguous range
        ixFormulaCell = ixFormulaCell + 1
        aNewValues(ixFormulaCell, 1) = MonitoredCell.Value  'Store the new value
        Set aNewValues(ixFormulaCell, 2) = MonitoredCell    'Store the cell address
    Next MonitoredCell

    Application.Undo    'This will undo the most recent change, which allows us to compare the new vs old to check for formula updates

    ixFormulaCell = 0
    For Each MonitoredCell In rMonitored.Cells
        ixFormulaCell = ixFormulaCell + 1
        'Check if the formula result is different
        If MonitoredCell.Value <> aNewValues(ixFormulaCell, 1) Then
            'Formula result found to be different, record that
            'We can't put the timestamp in now because we still have to redo the most recent change
            aNewValues(ixFormulaCell, 3) = True
        End If
    Next MonitoredCell

    Application.Undo    'Redo the most recent change to put worksheet back in the new state
    '--> THE LINE OF CODE ABOVE IS WHAT THE DEBUGGER POINTS TO

    'Now that we've completed our comparison and have re-done the most recent change, check what did change and put in a timestamp in the next empty cell in same row
    For ixFormulaCell = LBound(aNewValues, 1) To UBound(aNewValues, 1)
        'Check for formula result change
        If aNewValues(ixFormulaCell, 3) Then
            'Formula result change found, get next empty cell in same row
            With Me.Cells(aNewValues(ixFormulaCell, 2).Row, Me.Columns.Count).End(xlToLeft).Offset(, 1)
                'Next empty cell found, put in the current datetime stamp and format it
                .Value = Now
                .NumberFormat = "dd-mm-yyyy, hh:mm:ss"
                .HorizontalAlignment = xlGeneral
                .VerticalAlignment = xlCenter
            End With
        End If
    Next ixFormulaCell

    vSelected.Select                'Re-select the remembered selection so that this operation is invisible to users
    Application.EnableEvents = True 'Re-enable events so that the next calculation can be monitored for formula changes in cells of interest

End Sub
Public Sub test()

    Dim re As Object, pairs(), ws As Worksheet, i As Long, s As String
    Set ws = ThisWorkbook.Worksheets("Sheet1")
    Set re = CreateObject("VBScript.RegExp")

    With ws
        pairs = Application.Transpose(.Range("G3:G" & .Cells(.Rows.Count, "G").End(xlUp).Row).Value) ' assumes pairs start in row 3
    End With

    Dim results()
    ReDim results(1 To UBound(pairs))

    With CreateObject("MSXML2.XMLHTTP")
        For i = LBound(pairs) To UBound(pairs)
            .Open "GET", "https://www.bloomberg.com/quote/" & pairs(i) & ":CUR", False
            .send
            s = .responseText
            results(i) = GetCloseValue(re, s, "previousClosingPriceOneTradingDayAgo%22%3A(.*?)%2")
        Next
    End With

    ws.Cells(3, "I").Resize(UBound(results), 1) = Application.Transpose(results)

End Sub
Public Function GetCloseValue(ByVal re As Object, inputString As String, ByVal pattern As String) As String 'https://regex101.com/r/OAyq30/1

    With re
        .Global = True
        .MultiLine = True
        .IgnoreCase = False
        .pattern = pattern

        If .test(inputString) Then
            GetCloseValue = .Execute(inputString)(0).SubMatches(0)
        Else
            GetCloseValue = "Not found"
        End If

    End With

End Function

预期输出

我希望两个宏同时工作。

0 个答案:

没有答案