Run time error 1004 placing formula in cell - vba

I have created a formula that works in a spreadsheet but not in VBA. What I have pasted here is only a subset of the entire formula; in total it exceeds 3,000 characters
If I run this, it works
LastRow = Range("a" & Rows.Count).End(xlUp).Row
Range("cI2:cI" & LastRow).Formula = "=CONCATENATE(CONCATENATE(MID(""00"",1,2-LEN(A2)),A2))"
If I run this, I get the run time error
LastRow = Range("a" & Rows.Count).End(xlUp).Row
Range("cI2:cI" & LastRow).Formula = "=CONCATENATE(CONCATENATE(MID(""00"",1,2-LEN(A2)),A2)), " & _
"CONCATENATE(MID(""00000000"",1,8-LEN(B2)),B2),"" "", CONCATENATE(C2,MID("" "",1,12-LEN(C2))),CONCATENATE(MID(""00"",1,2-LEN(D2)),D2) "

Without seeing the rest of the formula, I would suspect that it exceeds some of the internal limits Excel has for function. Possibilities that come to mind are:
Arguments in a function: 255
Nested levels of functions: 64
Length of formula contents: 8,192 characters
You can find more information on the Office support page here.
That said, I'm curious why you would need to build a 3000 character formula to place in the cell. This is what VBA is for - converting the formula into a user defined function is likely going to be the solution.

Related

Excel vba formula string: array formula - how to simulate Ctrl+Shift+Enter press

I have a worksheet with data and some columns which I fill with formulas via vba. The formula I struggle with is an array formula that looks like this:
Workbooks(job_file).Worksheets(1).Cells(h + b, 195).Formula = _
"{=IF(MAX(IF(B2:M2>$FY" & currentRow & ",$B$1:$M$1))=0,0," & _
"MAX(IF(sheet1!B2:M2>$FY" & currentRow & "," & _
"sheet1!$B$1:$M$1)))+1}"
It's supposed to be an array formula, so that's why I put {} there. However, when run it simply display the formula's text in a cell, without calculating it. I have to manually remove the brackets, and then press Ctrl+Shift+Enter myself.
Is there any way to avoid it? I have a great many rows and I can't ctrlshiftenter each.
I tried running it without brackets, it works, but gives a #VALUE! error, which can also be fixed by applying Ctrl+Shift+Enter.
To create an array formula with a simulated ctrl+shift+enter (aka CSE), use the Range.FormulaArray Property instead of the Range.Formula Property and let Excel add the 'curly braces'.
with Workbooks(job_file).Worksheets(1)
.Cells(h + b, 195).FormulaArray = _
"=IF(MAX(IF(B2:M2>$FY" & currentRow & ",$B$1:$M$1))=0,0," & _
"MAX(IF(sheet1!B2:M2>$FY" & currentRow & ", sheet1!$B$1:$M$1)))+1"
end with
I noticed in your formula that you use B2:M2 and sheet1!B2:M2. Shouldn't they both be sheet1!B2:M2?
There are some considerations.
Runtime Error: 1004 - Too long. There is a reduced character limit of 255 for FormulaArray but there are work-arounds.
Runtime Error: 1004 - Broken String. Remember that all quotes within a quoted string must be doubled up. This is easily one of the most common causes of errors when trying to write a formula into a cell through VBA. Hint: TEXT(,) can be used instead of "" so you don't have to type """" for a zero-length string.
FormulaArray accepts both xlR1C1 and xlA1 style formulas. If you can wrap your head around xlR1C1 style formula syntax, it is generally easier to construct a concatenated formula string in xlR1C1 since you can use digits to represent column numbers instead of trying to convert column ordinals to a column letter. However, do not try to mix-and-match xlA1 and xlR1C1 range references in the same formula; they must all be one style or the other.
If you are having trouble formulating a string that will be accepted as a formula, put a tick (e.g. ' ) in front of the first equals sign then run the code and return to the worksheet to see what was put in. Make modifications on the worksheet until you have a working formula then transfer those modifications to the VBA code.
As a note, it looks like this can be done without an array formula, like so:
Workbooks(job_file).Worksheets(1).Cells(h + b, 195).Formula = _
"=IF($FY" & currentRow & ">MAX(B2:M2),0," & _
"MAX(INDEX((B2:M2>$FY" & currentRow & ")*$B$1:$M$1,)))+1"

Syntax error for INDEX formula using Macro

I'm getting a syntax error when I try to insert a formula in a cell using Macro. I can't seem to figure out what am I doing wrong? The formula works fine when I manually enter it. Here's my code:
ws3.Range("F2:F" & lastRow3).Formula = "=INDEX($L$1:INDEX(L:L,MATCH("ZZZ",D:D)),AGGREGATE(15,6,ROW($K$1:INDEX(K:K,MATCH("ZZZ",D:D)))/($K$1:INDEX(K:K,MATCH("ZZZ",D:D))=D2),COUNTIF($D$1:$D2,D2)))"
ws3 is the worksheet, and lastRow3 is just to autofill the contents by comparing to a column to the left. Any ideas why this is giving an error?
FYI: This formula is finding values in one column from another column and giving the adjacent entries.
When filling a full range it is best to use R1C1 format.
Also with using vba to set the last row there is no reason for all the INDEX(L:L,MATCH("ZZZ",D:D)) to find the last row, since the code itself can set it directly.
Use this:
ws3.Range("F2:F" & lastRow3).FormulaR1C1 = _
"=INDEX(R1C12:R" & lastrow & "C12,AGGREGATE(15,6,ROW(R1C11:R" & lastrow & "C11)/(R1C11:R" & lastrow & "C11=RC[-2]),COUNTIF(R1C4:RC4,RC[-2])))"

Long nested IF statement creates runtime error 1004 in Excel VBA

I have a formula that works perfectly well in a spreadsheet, but when I try to automate the creation of the formula using VBA, I get the 1004 run time error.
I have a 3 stage process, each with a start and finish date (so 6 separate date columns). This formula looks at the series dates and calculates the time lost between each stage using the NETWORKDAYS function.
I thought the simple way to overcome this problem was to record a macro of me pasting this formula into a cell, which would generate the required VBA code that I could then adapt, but even using this method causes the 1004 error.
I'm wondering whether it's the length of the formula that's the problem? I've tried replacing the double quotation marks with & Chr(34) & Chr(34) & and I've tried assigning the formula to a variable. I can get it to work if I add it as text using .value instead of .formulaR1C1, or if I add an apostrophe to the start of the formula string. It appears to be the fact that its a formula that causes the problem. Any help is greatly appreciated.
The formula from the cell in the spreadsheet:
=IF(AND(I2="",J2="",K2="",L2=""),"",IF(AND(G2="",H2="",K2="",L2=""),"",IF(AND(G2="",H2="",I2="",J2=""),"",IF(AND(H2<>"",I2<>"",J2<>"",K2<>""),IF(NETWORKDAYS(H2,I2)-2+NETWORKDAYS(J2,K2)-2<1,"",NETWORKDAYS(H2,I2)-2+NETWORKDAYS(J2,K2)-2),IF(AND(H2<>"",I2<>""),IF(NETWORKDAYS(H2,I2)-2<1,"",NETWORKDAYS(H2,I2)-2),IF(AND(H2<>"",K2<>""),IF(NETWORKDAYS(H2,K2)-2<1,"",NETWORKDAYS(H2,K2)-2),IF(AND(J2<>"",K2<>""),IF(NETWORKDAYS(J2,K2)-2<1,"",NETWORKDAYS(J2,K2)-2),"")))))))
The code that the macro records when I enter the formula into the cell:
ActiveCell.FormulaR1C1 = _
"=IF(AND(RC[-10]="""",RC[-9]="""",RC[-8]="""",RC[-7]=""""),"""",IF(AND(RC[-12]="""",RC[-11]="""",RC[-8]="""",RC[-7]=""""),"""",IF(AND(RC[-12]="""",RC[-11]="""",RC[-10]="""",RC[-9]=""""),"""",IF(AND(RC[-11]<>"""",RC[-10]<>"""",RC[-9]<>"""",RC[-8]<>""""),IF(NETWORKDAYS(RC[-11],RC[-10])-2+NETWORKDAYS(RC[-9],RC[-8])-2<1,"""",NETWORKDAYS(RC[-11],RC[-10])-2+NETWORKDAYS(RC[" & _
"8])-2),IF(AND(RC[-11]<>"""",RC[-10]<>""""),IF(NETWORKDAYS(RC[-11],RC[-10])-2<1,"""",NETWORKDAYS(RC[-11],RC[-10])-2),IF(AND(RC[-11]<>"""",RC[-8]<>""""),IF(NETWORKDAYS(RC[-11],RC[-8])-2<1,"""",NETWORKDAYS(RC[-11],RC[-8])-2),IF(AND(RC[-9]<>"""",RC[-8]<>""""),IF(NETWORKDAYS(RC[-9],RC[-8])-2<1,"""",NETWORKDAYS(RC[-9],RC[-8])-2),"""")))))))"
Consider:
Sub EvilFormula()
Dim st As String, DQ As String
DQ = Chr(34) & Chr(34)
st = "=IF(AND(I2=~,J2=~,K2=~,L2=~),~,IF(AND(G2=~,H2=~,K2=~,L2=~),~,IF(AND(G2=~,H2=~,I2=~,J2=~),~,IF(AND(H2<>~,I2<>~,J2<>~,K2<>~),IF(NETWORKDAYS(H2,I2)-2+NETWORKDAYS(J2,K2)-2<1,~,NETWORKDAYS(H2,I2)-2+NETWORKDAYS(J2,K2)-2),IF(AND(H2<>~,I2<>~),IF(NETWORKDAYS(H2,I2)-2<1,~,NETWORKDAYS(H2,I2)-2),IF(AND(H2<>~,K2<>~),IF(NETWORKDAYS(H2,K2)-2<1,~,NETWORKDAYS(H2,K2)-2),IF(AND(J2<>~,K2<>~),IF(NETWORKDAYS(J2,K2)-2<1,~,NETWORKDAYS(J2,K2)-2),~)))))))"
st = Replace(st, "~", DQ)
ActiveCell.Formula = st
End Sub
Here we first construct a String that represents the formula, but uses tildas in place of pairs of double-quotes. We replace the tildas and deposit the formula.I use this to avoid migraine headaches.

Summing cells from another sheet using offset

I'm trying to get this code to work for summing cells:
Worksheets("Sheet2").Range("C3").Offset(i, j).Formula = "=Sum("
&Worksheets("Sheet1").Range("A3").Offset(2*i,j).Address & ":" &
Worksheets("Sheet1").Range("A7").Offset(2*i,j).Address & ")"
It keeps giving me the right cells but from the wrong sheet. So for the first iteration I get sum(A3:A7) in cell C3 of Sheet2 but the A3:A7 stays referenced to Sheet2 not Sheet1.
Thanks!
You need to specify the name of the sheet in the formula too. Your code will work if you write it like this:
Worksheets("Sheet2").Range("C3").Offset(i, j).Formula = "=Sum(Sheet1!" & _
Worksheets("Sheet1").Range("A3").Offset(2 * i, j).Address & ":" & _
Worksheets("Sheet1").Range("A7").Offset(2 * i, j).Address & ")"
Try this code - it uses the External:=True parameter of .Addressto retrieve the full address. While this also includes the workbook name, Excel will remove this automatically so you end up with Sheet1!A3. Also note that I used the range A3:A7 as source as .Address can handle multi-cell ranges and you don't need to take care of it manually:
Sheets("Sheet2").Range("C3").Offset(i, j).Formula = "=SUM(" & _
Sheets("Sheet1").Range("A3:A7").Offset(2 * i, j).Address(External:=True) & ")"
Be aware that hard coding references such as A3 can lead to bugs in the long run, as the user (or even the developer at some stage) might modify the sheet structure. It is best practice to use named ranges, i.e. create a named range for each cell/range you refer to and then access it in VBA with SheetX.Range("rngStartCell") or similar!

VBA VLOOKUP Convert to Values Gives #N/A

I'm having some trouble with VLOOKUP in my VBA. Here's an example of the code I'm using:
Sub Macro15()
'
' Macro15 Macro
Dim LR As Long
LR = Cells(Rows.Count, "A").End(xlUp).Row
Range("B1:B" & LR).FormulaR1C1 = _
"=VLOOKUP(RC[-1],'https://internal_sharepoint_address
/[Vendor_Information.xlsx]Sheet1'!R3C3:R150C18,4,FALSE)"
Range("C1:C" & LR).FormulaR1C1 = _
"=VLOOKUP(RC[-2],'https://internal_sharepoint_address
/[Vendor_Information.xlsx]Sheet1'!R3C3:R150C18,5,FALSE)"
With Range("B1:C" & LR)
.Value = .Value
End With
End Sub
The problem is that the values in Columns B & C (the VLOOKUP formulas) return a value of #N/A.
However, if I stop the code before converting the formula to values (the "With Range("B1:C" & LR)" line), the VLOOKUP formula returns the correct values.
Also strange - if I clear the contents of Columns B & C and re-run the above code, the values return fine. If I try to add a second cycle to the VBA, however, it does NOT work.
Any wisdom that anyone can provide would be a huge help. I've been stuck on this for a long time, and I'm just at my wit's end.
Thanks all,
David
You'll probably need to add in a step that runs a calculation cycle before you try to replace with the value:
Application.Calculate
Edit from comment: I would imagine that retrieving lookup data from a linked workbook on a Sharepoint site would take awhile. Maybe add some delay loops? Can you make two separate macros (one ending with the formulas, and a second one starting at the Paste Values), and run them separately with a pause in between?