Home » excel » VBA Excel Autofill event

VBA Excel Autofill event

Posted by: admin May 14, 2020 Leave a comment

Questions:

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. 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
How to&Answers:

AFAIK and I could be wrong but there is no easy way where you can trap the Autofill event.

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. 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…

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.

Answer:

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

Answer:

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