David Vo
David Vo

Reputation: 65

Excel VBA formula's not updating row

So my code is to insert a row, copy its format from the previous row, and then insert the formulas that I have preset on a different row. So lets say I insert a new row, row 11, the formula should copy row 10's formats and insert the formulas from row 44 (which I designated as my formula row).

Now, the formulas will all reference row 10 instead of row 11. I'm not sure why that is.

Here is my code:

Dim i As Integer

'loop through position sheets and insert blank rows
For i = 1 To 4
    Sheets(i).Select
    Rows(row_to_insert).EntireRow.Select
    Selection.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
Next i

'loop through sheets and copy/paste formulas into new rows
For i = 1 To 4
    Sheets(i).Select
    Rows(blank_row_to_use + 1).EntireRow.Select
    Selection.Copy
    Rows(row_to_insert).EntireRow.Select
    ActiveSheet.Paste
Next I

End Sub

This worked fine until I added a new sheet, and expanded from For i = 1 To 3 to For i = 1 to 4.

Any ideas why it suddenly stopped working?

Upvotes: 0

Views: 707

Answers (2)

DisplayName
DisplayName

Reputation: 13386

the issue lays in those relative references to another sheet that don't get updated by any rows shifts taking place in the sheet where they are used

while they'd get updated if you shifted rows in the sheet they are referencing

so you have to play a little bit with relative /absolute references to mimic some referenced sheet rows shifting, but without doing it!

for instance you could use a Function that converts some range formulas to absolute or relative reference type, like the following:

Sub Convert(rng As Range, toReferenceType As XlReferenceType)
    Dim cell As Range

    For Each cell In rng.SpecialCells(XlCellType.xlCellTypeFormulas) ' loop thorugh passed range relevant cells (i.e. those containing formulas)
        If InStr(cell.Formula, "!") > 0 Then cell.Formula = Application.ConvertFormula(cell.Formula, xlA1, xlA1, toReferenceType) ' if current cell has an explicit sheet reference, then convert its formula to the passed reference type
    Next
End Sub

and the use it in your code

For i = 1 To 1
    With ThisWorkbook.Sheets(i)
        .Rows(blank_row_to_use).Copy .Rows(blank_row_to_use + 1) ' copy formulas "template" row one "helper" row below
        Convert .Rows(blank_row_to_use + 1), xlAbsolute ' convert "helper" row formulas with some explicit sheet reference to absolute type so they don't get updated by any subsequent row shift
        .Rows(blank_row_to_use + 1).Copy .Rows(blank_row_to_use) ' copy "helper" row converted formulas and paste them back to formula "template" row -> now you have a formula with an absolute row reference one below its own row
        .Rows(blank_row_to_use + 1).ClearContents ' clear "helper" row

        .Rows(row_to_insert).Insert Shift:=xlDown, opyOrigin:=xlFormatFromLeftOrAbove ' insert new row -> formulas "template" row references don't get updated and now you have a formula with an absolute row reference to its own row 
        Convert .Rows(blank_row_to_use + 1), xlRelative ' convert formulas "template" row formulas with some explicit sheet reference to relative type so they do get updated by any subsequent row shift

        .Rows(row_to_insert).EntireRow.Formula = .Rows(blank_row_to_use + 1).EntireRow.Formula ' copy formulas "template" row formulas row to the new row and have them updated
    End With
Next

Please note also that

.Rows(row_to_insert).EntireRow.Formula = .Rows(blank_row_to_use + 1).EntireRow.Formula 

is better than any Copy and subsequent PasteSpecial approach in that it doesn't use the clipboard

Upvotes: 1

Shai Rado
Shai Rado

Reputation: 33672

Try the much shorter and cleaner version of what you are trying to achieve.

Note: try to avoid using Select, Selection and ActiveSheet, and use fully qualified Sheet objects.

Modified Code

'loop through position sheets and insert blank rows
For i = 1 To 4
    With ThisWorkbook.Sheets(i)
        .Rows(row_to_insert).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
        .Rows(blank_row_to_use + 1).EntireRow.Copy
        .Rows(row_to_insert).EntireRow.PasteSpecial xlPasteFormulas
    End With
Next i

Upvotes: 0

Related Questions