简体   繁体   中英

Excel VBA: can't paste my function into a cell

I'm trying to paste

=IF(AND(C4-C3<($I$1/1000),A4=A3),"OOOO","-----")

into a cell, which I do via

 Range("I3").Select
 ActiveCell.FormulaR1C1 = "=IF(AND(C4-C3<($I$1/1000),A4=A3)," & Chr(34) & "OOOO" & Chr(34) & "," & Chr(34) & "-----" & Chr(34) & ")"
 Range("I3").Select

That returns Run time error '1004' Application-defined or object-defined error

I already tried double quotes and saw the & Chr(34) & workaround and tried that too. Nothing works. Furthermore, something as simple as

 ActiveCell.FormulaR1C1 = "=IF("

doesn't work, but

 ActiveCell.FormulaR1C1 = "=IF" 

does.

Strangely, this works in the code

Range("C3").Select
ActiveCell.FormulaR1C1 = "=MID(B3,1,2)*3600+MID(B3,4,2)*60+MID(B3,7,9)"
Range("C3").Select

which I do earlier. If I paste "=MID(B3,1,2)*3600+MID(B3,4,2)*60+MID(B3,7,9)" (instead of the string I'm trying to use), into the problem code while debugging and hit Continue, it will paste that line, so its not anything that happens in between the two statements. What happens between there is just some selection and copy/pasting but I'll include it here anyway if you want to look

    Range("C3").Select
  ActiveCell.FormulaR1C1 = "=MID(B3,1,2)*3600+MID(B3,4,2)*60+MID(B3,7,9)"
Range("C3").Select
Selection.Copy
Range("D3").Select
Selection.End(xlDown).Select
ActiveSheet.Paste
Range("K3:Z4").Select
Application.CutCopyMode = False
Selection.Copy
Range("K1").Select
ActiveSheet.Paste
Columns("H:H").Select
Application.CutCopyMode = False
Selection.Cut
Columns("M:M").Select
ActiveSheet.Paste
Columns("I:I").Select
Selection.Cut
Columns("H:H").Select
ActiveSheet.Paste
Range("I3").Select
ActiveCell.FormulaR1C1 = "=IF(AND(C4-C3<($I$1/1000),A4=A3)," & Chr(34) & "OOOO" & Chr(34) & "," & Chr(34) & "-----" & Chr(34) & ")"
Range("I3").Select

Quick answer:

You need to change either your formula to R1C1 style - or even simpler, assigned the formula to the .Formula instead of .FormulaR1C1 property.

Longer explanation:

Excel has two ways of referencing cells:

  1. The default A1 notation, where you refer to a cell by providing the column letter and the row number - and fix it to either row or column by prefixing a $ .
  2. The R1C1 notation where you refer to a cell by specifying it row with R and the row number and the column with C and the column number. If the number is provided in [] brackets, the reference is relative, without brackets it absolute. To use this notation, you need to set it in the Excel options (under Formulas)

The advantage of the R1C1 notation is that relative references do not change when applied to multiple cells! For example the A1 formula =A1+B1 entered in C1 would be =RC[-2]+RC[-1] . If the formula is now copied down column C, the row number will change in each row in A1 style (eg =A2+B2 , =A3+B3 , etc.). In R1C1 notation, it is exactly the same formula without any change.

In the normal Excel UI, this doesn't matter too much and is simply a matter of preference, as Excel automatically takes care of adjusting the formulas as long as you fix the absolute reference properly with the $ .*

However, it becomes much more useful in macros and if you want to search&replace references! Imagine in the above example, you want to change the formula from =A1+B1 to =A1+A2 - everywhere that this formula is used. In A1 , you cannot simply search&replace B1 with A2, as B1 will become B2, B3, and so forth. However, in R1C1 , you simply reaplce RC[-1] with R[1]C and you're done.

For that reason, the Excel Macro Recorder also records the formulas in R1C1 - it is simply the same formula, no matter where you apply it to! However, every Range has a .Formula and a FormulaR1C1 property that you can set - and the other property will be updated accordingly. Therefore, use whatever style is suited be for your need.

In your case, the R1C1 formula would make sense, if you plan to use it also with other cells than I3.

A1 :

Range("I3").Formula = "=IF(AND(C4-C3<($I$1/1000),A4=A3),""OOOO"",""-----"")"
Range("J4").Formula = "=IF(AND(D5-D4<($I$1/1000),B5=B4),""OOOO"",""-----"")"

R1C1 :

strFormula = "=IF(AND(R[1]C[-6]-RC[-6]<(R1C9/1000),R[1]C[-8]=RC[-8]),""OOOO"",""-----"")"
Range("I3").FormulaR1C1 = strFormula
Range("J4").FormulaR1C1 = strFormula

HTH!

( * Interesting side node: in the first version of Excel, Microsoft used the R1C1 as the default notation, as it is superior to A1 in multiple ways. However, as Lotus 1-2-3 was the standard by then and A1 already accepted as the norm, it reverted this notation in later versions.)

your issue is using .FormulaR1C1 and not using an R1C1 style of formula.

If you look at your spreadsheet, you will see that C3 contains

=MID('B3',1,2)*3600+MID('B3',4,2)*60+MID('B3',7,9)

as it's translated your reference to strings, and the reeor refers to it's attempt to reference a cell with a formula it doesn't understand.

To use B3 (and C3, and the rest) you need to use .Formula instead:

ActiveCell.Formula = "=MID(B3,1,2)*3600+MID(B3,4,2)*60+MID(B3,7,9)"
ActiveCell.Formula = "=IF(AND(C4-C3<($I$1/1000),A4=A3)," & Chr(34) & "OOOO" & Chr(34) & "," & Chr(34) & "-----" & Chr(34) & ")"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM