FormulaArray Producing Runtime 1004 Error - arrays

I am trying to run the following procedure that entails placing an array formula in a range ("CA2010") on a sheet ("Slate Data").
I've tested the the array formula many times and it produces the desired results.
The sub below gets
run-time '1004' error: Unable to set the FormulaArray property of the Range class.
Sub countuniqueBINs()
Dim placementoutlook As Workbook
Set placementoutlook = Excel.Workbooks("Placement Outlook")
Dim sdws As Worksheet
Set sdws = placementoutlook.Sheets("Slate Data")
sdws.Range("CA2010").NumberFormat = "general"
sdws.Range("CA2010").FormulaArray = "=SUM(IF(FREQUENCY(IF(SUBTOTAL(3,OFFSET(E2:E2000,ROW(E2:E2000)-ROW(E2),0,1)),MATCH(""~""&E2:E2000,E2:E2000&"""",0)),ROW(E2:E2000)-ROW(E2)+1),1))"
End Sub
I tried breaking the array formula into two parts based on some guidance out there, but it still did not resolve the issue.

The reason for the error is that the R1C1 format version of your formula exceeds 255 characters (even though the A1 style version is much shorter than that) due to the relative references. If you use absolute references, the formula is short enough to be entered using FormulaArray; if you can't do that, you'll need to use the workaround of splitting the formula into sections so that you can use the Range.Replace method after entering a shorter version.

Related

Type mismatch error when creating a vba array

I'm trying to drop a range of cells straight into an array to run some calculations. The range will always be A8:E?, but I never know how many total rows there will be. One of the columns contains string values that I need for determining conditions. I set a variable to find the last row (and no, this data never has any blanks so the method to set it works just fine). This is what I have"
Sub use_arr()
Dim rw As Integer
rw = Worksheets("Sheet1").Range("A8").End(xlDown).Row
Dim myArr()
myArr = Worksheets("Sheet1").Range("A8:E" & rw)
End Sub
But it keeps throwing a "Run_time error '13'" at me.
Arrays are still new to me, someone suggested using them instead of looping through cells for faster execution. So I'm still figuring this out.
Either declare myArr just as a Variant, not an array, or specify the Value property of the range:
myArr = Worksheets("Sheet1").Range("A8:E" & rw).Value

Converting Index Match Formula with Dynamic Range to VBA

My Original formula is as follows:
=INDEX(MIR!$A:$A,MATCH(1,(MIR!$H:$H=TRI!$W2)*(MIR!$I:$I=TRI!$L2),0))
I created the following VBA Code for this and while the code does add the formula to the appropriate range, the formula does NOT work. It's as if the Array portion is not being applied. I've looked everywhere to figure this out but I obviously am not looking in the right spot. Please advise.
Range("B2").Select
Selection.FormulaArray = _
"=INDEX(MIR!C1,MATCH(1,(MIR!C8=TRI!RC23)*(MIR!C9=TRI!RC12),0))"
Range("B2", "B" & Cells(Rows.Count, 1).End(xlUp).Row).FillDown
End Sub
You are using xlR1C1 notation but VBA is reading it as xlA1 notation. MIR!C1 is not MIR!A:A, it is first row, third column on the MIR worksheet (e.g. MIR!C1). The formula is put on the worksheet as,
=INDEX(MIR!C1,MATCH(1,(MIR!C8=TRI!RC23)*(MIR!C9=TRI!RC12),0))
Use a formula in xlA1 notation.
Range("B2").FormulaArray = "=INDEX(MIR!$A:$A,MATCH(1,(MIR!$H:$H=TRI!$W2)*(MIR!$I:$I=TRI!$L2),0))"
Btw, you should really cut those full column references in the MATCH down to the used data range.

Looking to read the .text of cells into an array

I'm building a simple report compare macro in Excel VBA to compare all sorts of different reports in our system. Since it's so much faster I'm pulling both spreadsheets into arrays and running a compare on them then pasting the results into a different workbook.
The issue is that both spreadsheets have long underlying values in some cells (interest rates and things like 3.27823202), but all I care about is the displayed value in the cell (3.28). I know I can easily pull the .values into an array with
Dim ReportParams() as variant
Dim SH1 as Worksheet
set SH1= activeworkbook.sheets("Sheet1")
ReportParams= SH1.range(cells(1,1),cells(5,5)).Value
But when I attempt the same using .Text instead of .Value it gives me a Run-Time error '13': Type Mismatch.
Is there any effecient way to bring in all the visible values for the cells into an array?

Using array instead of ranges in VBA

I've only been using VBA for a couple of weeks now so bear with me.
I'm trying to change a macro so that it reads from an array instead of a range. One of the sections I need to change uses .formulaR1C1 to run a vlookup, but im having a hard time trying to work out how this can be done with the array.
An example of this is the below line:
.Range("M2:L" & lastrow).FormulaR1C1 = "=VLOOKUP(RC[-1], Sheet2!R1C1:R4C10, 3, 0)"
I'm not too sure on whether I can set the value of an array to a formula, as I've done above, or if I have to maybe store the value as a String and then edit the value of the cell later when printing the column back on to the worksheet.
What I have so far is below:
For i = 2 To lastrow
arr(i, 13).FormulaR1C1 = "=VLOOKUP(RC[-1],Sheet2!R1C1:R4C10,3,0)"
Next
Thanks in advance!
Storing the value as a string would certainly be a valid option. Simply write the formula in your array, presuming it is of Variant / String type, and when you put the data back into a worksheet you can use .FormulaR1C1 on a Cell (Range) object to apply it as a formula.
arr(i, 13) = "=VLOOKUP(RC[-1],WMSPAM!R1C1:R4C10,3,0)"
...
Range("M2").FormulaR1C1 = Arr(1,13)
I believe this approach is likely the most effective and most easily maintained for you. As you are learning and appear to be curious of what is possible, here are a couple more examples of how you could approach this, with some further explanation.
.FormulaR1C1 is a Range object method and so the only way it could be called on an Array item would be if that item was a Range object.
Dim arr(0 To 10) As Range
Set arr(0) = Range("A1")
arr(0).FormulaR1C1 = "=2+2"
Note that as Ranges are an Object (of reference type), this operation will directly effect the Range specified in the array. In the above example, the formula "=2+2" will be placed into cell A1. You can learn more about the difference between Reference and Value types here.
If your array contains only values, the other way to achieve what you need is to use the WorksheetFunction object. With this object you can access the formula functions, that you would use in worksheet, within VBA.
WorksheetFunction.VLookup(Arg1, Arg2, Arg3, Arg4)
As with anything in writing code the WorksheetFunction methods take some trial and error to get them to work how you would expect, but in my experience these specifically can be a tricky to implement, there are though some cases where they can be very useful!
You can read more about the VLookup method here.
You may try to use .Offset():
Sub Test()
lastrow = 11
With Sheets(1)
Set Rng = .Range("M2:L" & lastrow)
End With
For i = 0 To Rng.Rows.Count - 1
Rng.Offset(i, 12).FormulaR1C1 = "=VLOOKUP(RC[-1],Sheet2!R1C1:R4C10,3,0)"
Next
End Sub
I'm not sure what you are asking. Your first code line writes a formula to a two-column range in the most efficient way there is already, your second snippet shows the less efficient way of doing it one cell at the time. If the goal is to use the vlookup to fill cells and then dispose of the formula, one efficient way is this:
.Range("M2:L" & lastrow).FormulaR1C1 = "=VLOOKUP(RC[-1], Sheet2!R1C1:R4C10, 3, 0)"
.Range("M2:L" & lastrow).Value2 = .Range("M2:L" & lastrow).Value2

Excel vba and arrayformula

I'm trying to get the values from an array formula into VBA as an array. Simple example: I have a cell (let's say D1) which has an array formula in it such as
=A1:A10*B1:B10
when I highlight this on the spreadsheet and press F9 I'll get an array of 10 numbers, say, ={5;12;15;24;25;24;42;40;54;70}
I want to be able to store these values in a VBA array: a(0)=5, a(1)=12, a(3)=15 etc; you get the idea.
Tried hunting for an answer on this one, but can't find anything relevant even on MSFT. Lots of answers about how to go the other way from VBA to the worksheet range (I know that one) but not this way. Looked at trying to do it via a ParamArray (the number of elements won't be fixed), by assigning directly to a undimensioned array and via EVALUATE(range) but I can't get any of these to work. I feel I must be missing something obvious.
Not sure what you have tried already. But Evaluate should work.
If I have the following:
The code:
Sub getArrayFormulaResult()
sFormula = Range("D1").FormulaArray
aResult = Evaluate(sFormula)
MsgBox Join(Application.Transpose(aResult), ",")
End Sub
will result in:
try this
Dim var as variant
var=Worksheets("MySheet").Evaluate(Worksheets("MySheet").Range("D1").formula)
Note you should use Worksheet.Evaluate to ensure this works when Mysheet is not the active sheet. The result will always be a 2_D array (with one column for your example array formula)

Resources