5

I am trying to have my spreadsheet automatically take the previous rows format and formulas when a new row is inserted.

I read where you can set up your sheet to automatically run the code if a change is made, but I am having a hard time getting the code to work.

I have tried the following and every time I insert a new row it keeps adding a row until it gets an error and I have to force quit:

Private Sub Worksheet_Change(ByVal Target As Range)
    If Target.Range("A1:D25") = ActiveCell.EntireRow.Insert Then
        Cells(1, 2).Value = 10
    End If 
End Sub

I added the Cell Value = 10 to see if it would work. It was just a test, but it still fails.

Does anyone know a possible solution?

1
  • It's one of those things that looks like it should work but breaks in a funny way. I'm not 100% sure what it is doing in that If statement... When you say "Insert a new row" do you mean you're appending some data on a new line, further down the sheet, or are you actually rightclick-inserting a new row? In either case if the last row with data is shifting down, you can put an event that checks the last row after every worksheet_change, and appends it to / checks against a value in a hidden sheet containing the prev. max row, then run if it's a higher value Commented Aug 29, 2014 at 21:38

3 Answers 3

6

There are two main issues in your code

  1. You are causing an Event Cascade. Ie your Change event is triggering further change events
  2. .Insert doesn't do what you seem to think it does. It doesn't detect inserted rows, it Inserts rows.

I am assuming by "... insert a new row ..." you mean Insert a whole row

This demo avoids the cascade with .EnableEvents = False and uses Copy, pasteSpecial to copy formats and formulas.

Option Explicit

Dim RowsCount As Long ' Variable to track number of rows used in sheet

Private Sub Worksheet_Activate()
    RowsCount = Me.UsedRange.Rows.Count
End Sub

Private Sub Worksheet_Change(ByVal Target As Range)
    On Error GoTo EH
    ' Detect whole row changed
    If Target.Columns.Count = Me.Columns.Count Then
        ' Detect Extra Row
        If RowsCount = Me.UsedRange.Rows.Count - 1 Then
            ' Copy Formulas and Format new row
            Application.EnableEvents = False
            If Target.Row > 1 Then
                Target.Offset(-1, 0).Copy
                Target.PasteSpecial xlPasteFormulas, xlPasteSpecialOperationNone, False, False
                Target.PasteSpecial xlPasteFormats, xlPasteSpecialOperationNone, False, False
                Application.CutCopyMode = False
            End If
        End If
        RowsCount = Me.UsedRange.Rows.Count
    End If

EH:
    Application.EnableEvents = True
End Sub
Sign up to request clarification or add additional context in comments.

1 Comment

When I use this code, it doesn't run on the first insertion. Also, on the second insertion onwards, it is copying values of the cells that don't contain formulas.
0

It looks like you are attached to the wrong event. You have attached your code to the "Worksheet_Change" event, but your code is also causing a change to the worksheet

Cells(1, 2).Value = 10

Which turns right around and invokes the "Worksheet_Change" event.

As for the right event to attach to, it looks like there is no native event for "New Row Inserted".

There is a discussion of this over on this page which might be an answer to your problem...

Comments

0

Like @laughsloudly said, what your code is doing now is once you make a change anywhere in the range A1:D25 it will start inserting rows until Excel runs out of rows, it's an open loop.

The code:

If Target.Range("A1:D25") = ActiveCell.EntireRow.Insert Then

Is meant to check whether the action taken is within the range you want to be monitored. You don't want to be performing an action in this line. Rather, you want something more like:

If Target.Range("A1:D25") = ActiveCell Then

This will allow you to run code based on actions in your sheet. However, your statement "I am trying to have my spreadsheet automatically take the previous rows format and formulas when a new row is inserted." isn't entirely logical. I presume that you mean to copy all formats from the above row and only formulas from certain cells, correct? So, let's say if you have rows that all have formulas relative to column A, you don't want to copy all of the row, because you will overwrite A. Furthermore, in this case, you only want to monitor column A.

So let's say you have formulas in columns B through K that rely on column A, then you only want changes to column A to affect the spreadsheet. Then your code would look something like this:

Private Sub Worksheet_Change(ByVal Target As Range)

    If Target.Column = ActiveCell.Column Then
        refRow = Target.Row - 1
        thisRow = Target.Row
        Range("B" & refRow & ":K" & refRow).Copy Range("B" & thisRow & ":K" & thisRow)
    End If

End Sub

This copies down everything but column A when you make a change to A. And, as alluded to previously, you don't want the code making any changes to column A (in this case) without something to break it out of that recursive loop. Best just to apply conditional formatting to any column that you are assigning as the target.

Hope that helps,

n8

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.