I am writing a reusable VBA routine to copy data and formulas from one Excel workbook to another. I am working with large amounts of data and formulas and have found that copying by assigning values (Range2.Value2 = Range1.Value2 vs. Cut/Paste) has better performance. However, I can't figure out how to do this to copy formulas. I believe copying using the R1C1 reference notation should do this correctly (e.g., Range2.FormulaR1C1 = Range1.FormulaR1C1), as using the straight Range2.Formula = Range1.Formula method does not increment the cell references in the copied formulas. Does anybody know why the .FormulaR1C1 method increments rows and columns by 2??!!!? I am using the latest Office 365. The below example illustrates the issue:
Am I doing something wrong? Any help or insights on this would be much appreciated!!!
VBA Code:
Option Explicit
Sub TestAssignFormulaR1C1_Click()
Range("A1:E5").Clear
' Place formula in a single cell
Range("A1").Formula = "=ADDRESS(ROW(A1), COLUMN(A1))"
' Copy formula to the right
Dim source_range As Range: Set source_range = Range("A1")
Dim target_range As Range: Set target_range = Range("B1:E1")
target_range.FormulaR1C1 = source_range.FormulaR1C1
' Copy formulas from top row down
Set source_range = Range("A1:E1")
Set target_range = Range("A2:E5")
target_range.FormulaR1C1 = source_range.FormulaR1C1
' This gives an incorrect result starting at row 3:
' A B C D E
' ------------------------------
' 1 | $A$1 $B$1 $C$1 $D$1 $E$1
' 2 | $A$2 $B$2 $C$2 $D$2 $E$2
' 3 | $A$4 $B$4 $C$4 $D$4 $E$4
' 4 | $A$6 $B$6 $C$6 $D$6 $E$6
' 5 | $A$8 $B$8 $C$8 $D$8 $E$8
MsgBox "Row 1 formulas copied down via assignment .FormulaR1C1 = .FormulaR1C1." & _
vbCrLf & vbCrLf & "Notice the rows are off starting at row 3!", vbCritical
' Alternative method which uses clipboard BUT is slower:
source_range.Copy
target_range.PasteSpecial xlPasteFormulas
' Of course gives the expected result:
' A B C D E
' ------------------------------
' 1 | $A$1 $B$1 $C$1 $D$1 $E$1
' 2 | $A$2 $B$2 $C$2 $D$2 $E$2
' 3 | $A$3 $B$3 $C$3 $D$3 $E$3
' 4 | $A$4 $B$4 $C$4 $D$4 $E$4
' 5 | $A$5 $B$5 $C$5 $D$5 $E$5
MsgBox "The standard Copy with PasteSpecial works as expected.", vbInformation
' Now try the same thing but copying a single column of data
Range("A1:E5").Clear
Range("A1").Formula = "=ADDRESS(ROW(A1), COLUMN(A1))"
' Copy formula down
Set source_range = Range("A1")
Set target_range = Range("A2:A5")
target_range.FormulaR1C1 = source_range.FormulaR1C1
' Copy formulas from left column over
Set source_range = Range("A1:A5")
Set target_range = Range("B1:E5")
target_range.FormulaR1C1 = source_range.FormulaR1C1
' This gives an incorrect result starting at column C:
' A B C D E
' ------------------------------
' 1 | $A$1 $B$1 $D$1 $F$1 $H$1
' 2 | $A$2 $B$2 $D$2 $F$2 $H$2
' 3 | $A$3 $B$3 $D$3 $F$3 $H$3
' 4 | $A$4 $B$4 $D$4 $F$4 $H$4
' 4 | $A$5 $B$5 $D$5 $F$5 $H$5
MsgBox "Column A formulas copied to right via assignment .FormulaR1C1 = .FormulaR1C1." & _
vbCrLf & vbCrLf & "Notice the columns are off starting at column C!", vbCritical
End Sub
Am I doing something wrong? Any help or insights on this would be much appreciated!!!