简体   繁体   English

VBA Excel自动填充事件

[英]VBA Excel Autofill event

I need to be able to either execute some code when user tries to autofill a column or be able to detect that it is an autofill during the execution of Worksheet_Change. 我需要能够在用户尝试自动填充列时执行一些代码,或者能够在执行Worksheet_Change期间检测到它是自动填充。 I have some code that changes the values of the autofilled cells. 我有一些代码可以更改自动填充单元格的值。 The problem is that this code fires every time I edit several cells at once. 问题在于,每次我一次编辑多个单元格时都会触发此代码。

Private Sub Worksheet_Change(ByVal Target As range)
    If Target.Rows.count > 1 Then

AFAIK and I could be wrong but there is no easy way where you can trap the Autofill event. AFAIK和我可能是错的,但是没有简单的方法可以捕获Autofill事件。

The Target.Rows.count is an unreliable way of checking if it was an autofill as Target.Rows.count will be greater than 1 for many scenarios. Target.Rows.count是检查其是否为自动填充的不可靠方法,因为在许多情况下, Target.Rows.count将大于1。 For example 例如

  1. User pasted in multiple cells 用户粘贴到多个单元格中
  2. User deleted multiple cells 用户删除了多个单元格
  3. User pressed CTRL + Z ( Undo ) which changed multiple cells etc etc... 用户按下CTRL + Z撤消 )更改了多个单元格等...

If you seriously want to trap the Autofill then you have to handle all the above cases and eliminate the possibilities to narrow down to ascertain that it is indeed an Autofill event. 如果您真的想捕获自动填充,则必须处理以上所有情况,并消除缩小范围以确保确实是自动填充事件的可能性。

Private Sub Worksheet_Change(ByVal Target As Range)
    If Target.Count > 1 Or Target.Column <> 1 Then Exit Sub
    MsgBox Target.Address ' your code goes here
End Sub

So if more than one cell is changed the code will not activate or if it does not happen in column A 因此,如果更改了多个单元格,则该代码将不会激活,或者在列A中未发生

You have 2 area's during a change event and for the most part the size of the selected area matches the size of the area being changed. 在更改事件期间,您有2个区域,并且大多数情况下,所选区域的大小与要更改的区域的大小匹配。 During a DragFill operation the selection area completely contains the area being changed but also contains the area which is the source of the drag fill. 在DragFill操作期间,选择区域完全包含要更改的区域,但也包含作为拖动填充源的区域。 The source also fills one edge of the selected area. 源也将填充选定区域的一个边缘。

    Application.SheetChange += Sheet_Change;

    private void Sheet_Change(object Sh, Range Target)
    {
        //See if the size of the target matches the size of the current selection.
        //Selection size must be greater that one cell
        //Changed cells must be in the same dimension as the unchanged cells. e.g. unchanged area must fill one edge of the rectangle

        var selection = (Application.Selection as Range);

        Rect selectionArea = new Rect(selection.Column, selection.Row, selection.Columns.Count, selection.Rows.Count);
        Rect changedArea = new Rect(Target.Column, Target.Row, Target.Columns.Count, Target.Rows.Count);

        var isDragFill = false;
        if (selectionArea.Contains(changedArea)
            && (selectionArea.Width > 1 || selectionArea.Height > 1)
            && (selectionArea.Width == changedArea.Width || selectionArea.Height == changedArea.Height)
            && selectionArea != changedArea)
            isDragFill = true;

        if (!blockNextChange)
        {
            if (isDragFill)
            {
                //Re-entrancy check in the case the value changes in this block
                blockChanges = true;
                bool isHorizontal = selectionArea.Height == changedArea.Height;
                {                       
                    if (isHorizontal)
                    {
                        DragFillHorizontal(Target, selection, selectionArea, changedArea);
                    }
                    else
                    {
                        DragFillVertical(Target, selection, selectionArea, changedArea);
                    }
                }
                blockChanges = false;
            }
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM