VBA触发单元格值更改的宏

时间:2013-08-29 00:46:33

标签: excel vba excel-vba event-handling

这应该很简单。当单元格的值发生变化时,我想触发一些VBA代码。单元格(D3)是来自另外两个单元格=B3*C3的计算。我尝试了两种方法:

Private Sub Worksheet_Change(ByVal Target As Range)
  If Target.Column = 4 And Target.Row = 3 Then
    MsgBox "There was a change in cell D3"
  End If
End Sub

由于单元格是计算,因此在值更改时不会触发,因为计算保持不变。我也尝试过:

Private Sub Worksheet_Calculate()
  MsgBox "There was a calculation"
End Sub

但是我在工作表上有多个计算,它会多次触发。有没有办法可以确定哪个计算在计算事件中发生了变化?还是有另一种方法可以跟踪D3何时发生变化?

4 个答案:

答案 0 :(得分:5)

你可以试试这样的吗?将公式更改为=D3AlertOnChange(B3*C3)

Private D3OldVal As Variant

Public Function D3AlertOnChange(val)
    If val <> D3OldVal Then MsgBox "Value changed!"
    D3OldVal = val
    D3AlertOnChange = val
End Function

答案 1 :(得分:3)

或尝试

Private Sub Worksheet_Change(ByVal Target As Range)
Dim numdependences As Integer
On Error Resume Next
HasDependents = Target.Dependents.Count
If Err = 0 Then
    If InStr(Target.Dependents.Address, "$D$3") <> 0 Then
        MsgBox "change"
    End If
End If
On Error GoTo 0
End Sub

如果您更改了没有依赖的单元格,则需要使用错误控制。

答案 2 :(得分:1)

试试这个:

1                                                          The SAS System                              11:12 Wednesday, May 13, 2015

1          ;*';*";*/;quit;run;
2          OPTIONS PAGENO=MIN;
3          %LET _CLIENTTASKLABEL='Program';
4          %LET _CLIENTPROJECTPATH='';
5          %LET _CLIENTPROJECTNAME='';
6          %LET _SASPROGRAMFILE=;
7          
8          ODS _ALL_ CLOSE;
9          OPTIONS DEV=ACTIVEX;
10         GOPTIONS XPIXELS=0 YPIXELS=0;
11         FILENAME EGSR TEMP;
12         ODS tagsets.sasreport13(ID=EGSR) FILE=EGSR STYLE=HtmlBlue
12       ! STYLESHEET=(URL="file:///C:/Program%20Files/SASHome/SASEnterpriseGuide/5.1/Styles/HtmlBlue.css") NOGTITLE NOGFOOTNOTE
12       ! GPATH=&sasworklocation ENCODING=UTF8 options(rolap="on");
NOTE: Writing TAGSETS.SASREPORT13(EGSR) Body file: EGSR
13         
14         GOPTIONS ACCESSIBLE;


15         data _null_;
16         run;

NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds


17         
18         GOPTIONS NOACCESSIBLE;
19         %LET _CLIENTTASKLABEL=;
20         %LET _CLIENTPROJECTPATH=;
21         %LET _CLIENTPROJECTNAME=;
22         %LET _SASPROGRAMFILE=;
23         
24         ;*';*";*/;quit;run;
25         ODS _ALL_ CLOSE;
26         
27         
28         QUIT; RUN;
29         

查找单元格B1的值的变化,然后执行&#34;宏&#34;

答案 3 :(得分:0)

如果您只查看Worksheet_Change,那么即使它与之前的值相同,它也会对输入的任何内容进行更改。为了解决这个问题,我使用Public变量来捕获起始值并进行比较。

这是我执行此操作的代码。它还允许您省略工作表的某些部分,或者您可以使用它来评估工作表中的每个单元格。

将此代码放在工作表中。

Public TargetVal As String 'This is the value of a cell when it is selected


Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Cells.CountLarge > 1 Then 'If more then one cell is selected do not save TargetVal. CountLarge is used to protect from overflow if all cells are selected.
    GoTo EXITNOW
Else
    TargetVal = Target 'This sets the value of the TargetVal variable when a cell is selected
End If
EXITNOW:
End Sub

 Sub Worksheet_Change(ByVal Target As Range)
'When a cell is modified this will evaluate if the value in the cell value has changed.
'For example if a cell is entered and enter is pressed the value is still evaluated
'We don't want to count it as a change if the value hasn't actually changed

Dim ColumnNumber As Integer
Dim RowNumber As Integer
Dim ColumnLetter As String

'---------------------
'GET CURRENT CELL INFO
'---------------------
    ColumnNumber = Target.Column
    RowNumber = Target.Row
    ColumnLetter = Split(Target.Address, "$")(1)

'---------------------
'DEFINE NO ACTION PARAMETERS
'   IF CELL CHANGED IS IN NO ACTION RANGE, EXIT CODE NOW FOR PERFORMANCE IMPROVEMENT OR TO NOT TAKE ACTION
'---------------------
    If ColumnNumber <> 4 Then 'This would exempt anything not in Column 4
        GoTo EXITNOW
    ElseIf RowNumber <> 3 Then 'This would exempt anything not in Row 3
        GoTo EXITNOW
    'Add Attional ElseIf statements as needed
    'ElseIf ColumnNumber > 25 Then
        'GoTo EXITNOW
    End If

'---------------------
'EVALUATE IF CELL VALUE HAS CHANGED
'---------------------
Debug.Print "---------------------------------------------------------"
Debug.Print "Cell: " & ColumnLetter & RowNumber & " Starting Value: " & TargetVal & " | New Value: " & Target

    If Target = TargetVal Then
        Debug.Print " No Change"
        'CALL MACRO, FUNCTION, or ADD CODE HERE TO DO SOMETHING IF NOT CHANGED
    Else
        Debug.Print " Cell Value has Changed"
        'CALL MACRO, FUNCTION, or ADD CODE HERE TO DO SOMETHING IF CHANGED
    End If
Debug.Print "---------------------------------------------------------"

EXITNOW:
 End Sub