VBA Excel自动填充事件

VBA Excel自动填充事件,vba,excel,Vba,Excel,我需要能够在用户尝试自动填充列时执行一些代码,或者能够在执行工作表更改期间检测到它是自动填充。我有一些更改自动填充单元格值的代码。问题是,每次我同时编辑几个单元格时,都会触发此代码 Private Sub Worksheet_Change(ByVal Target As range) If Target.Rows.count > 1 Then Private子工作表\u更改(ByVal目标作为范围) 如果Target.Count>1或Target.Column 1,则退出Sub

我需要能够在用户尝试自动填充列时执行一些代码,或者能够在执行工作表更改期间检测到它是自动填充。我有一些更改自动填充单元格值的代码。问题是,每次我同时编辑几个单元格时,都会触发此代码

Private Sub Worksheet_Change(ByVal Target As range)
    If Target.Rows.count > 1 Then
Private子工作表\u更改(ByVal目标作为范围)
如果Target.Count>1或Target.Column 1,则退出Sub
MsgBox Target.Address'您的代码位于此处
端接头

因此,如果更改了多个单元格,代码将不会激活,或者如果代码没有发生在A列中,AFAIK和I可能是错误的,但是没有简单的方法可以捕获自动填充事件

Target.Rows.count
是一种不可靠的方法,用于检查它是否是自动填充,因为在许多情况下,
Target.Rows.count
将大于1。比如说

  • 用户粘贴在多个单元格中
  • 用户删除了多个单元格
  • 用户按CTRL+Z(撤消)可更改多个单元格等

  • 如果您真的想捕获自动填充,那么您必须处理上述所有情况,并消除缩小范围的可能性,以确定它确实是一个自动填充事件。

    在更改事件期间,您有两个区域,并且在大多数情况下,所选区域的大小与正在更改的区域的大小相匹配。在拖动填充操作期间,选择区域完全包含正在更改的区域,但也包含作为拖动填充源的区域。源还会填充选定区域的一条边

        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;
                }
            }
        }
    

    在我的例子中,没有附加公式,现在的基本场景是用户拖动标题(这是一些字符串)。我只是检查是否有一列、几行和所有行都有相同的值。没有必要只在有公式的情况下自动填充才起作用。试试这个…在单元格A1到A15中键入一些内容。现在在单元格B1中键入一些内容,并在光标变为
    +
    符号时双击单元格右下角;)
        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;
                }
            }
        }