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?
Related
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)
Possible to Run Goal Seek on array elements within VBA, instead of an Excel sheet range?
I have an array that takes initial values from an excel input sheet, does many calculations, and prints values back into a report region on an excel sheet; the output is roughly 200 rows x 28 columns of calculated values. I used to do this with formulas in every cell, but it was very, very slow. I converted to an all-vba Sub that does the calculations quickly and pastes the finished values into the report range in excel.
The problem is that I also need to run Goal Seek on various cells and Excel can't do it on a cell that just has a value, it needs a cell with a formula. With my fancy, efficient array, I can't goal seek anymore!!!!!
Is there a way to run some version of Goal Seek NOT on excel sheet ranges but on array members, like on MyArray(107,23) by testing an input value that is actually on the excel sheet, like Range("B2")? What would that code look like?
The first subroutine uses Range while the second uses Array instead. The goal here is 0.
First subroutine :
Sub GoalSeekWithRange()
Dim i As Long
For i = 1 To 10
Range("C" & i).GoalSeek Goal:=0, ChangingCell:=Range("A" & i)
Next
End Sub
Second subroutine :
Sub GoalSeekWithArray()
Dim arGoal As Variant
Dim arChanging As Variant
With ThisWorkbook.Sheets("MySheet")
Set arGoal = .Range("C1:C10")
Set arChanging = .Range("A1:A10")
End With
Dim i As Long
For i = 1 To 10
arGoal(i, 1).GoalSeek Goal:=0, ChangingCell:=arChanging(i, 1)
Next
End Sub
To avoid headaches, remember an array of range has two dimensions
Probably, you will have to adapt these codes to fit your specific need
sort of a newbie with VBA and I was wondering how you can create a dynamic 2D array which will be the size of the selected data in excel (Not knowing how big the data is) . I am unfamiliar with the VBA syntax and most of the questions I saw dealt with static data where the person knows the size of the excel table.
I have already created a function which automatically selects the data in the excel sheet. Now I wish to know how I can place all these data into a 2D Array.
Sorry if this is a common question, I am more familiar with 2D arrays with other languages, however I am getting mixed up with people using Range, Array and others in VBA
Also the data is strings in each element of the table. Please also advise how I will pull this data out :) Thank you
This code will put into array for you ..
Sub SelectionToArray()
Dim arrSelection() As String
Dim i As Integer
i = 0
ReDim arrSelection(i)
For Each c In Selection
arrSelection(i) = c.Value
i = i + 1
ReDim Preserve arrSelection(i)
Next c
End Sub
I am creating a Word userform using VBA. I store several configuration using array in the program code, such as the following:
Public arrConfiguration[2, 3] as Integer
where index 2 represent type 0 to 2, and index 3 represent properties 0 to 3 for each type.
However, I planned to modify the program for larger amount of data (such as for 100 different types of data and 50 properties for each data).
My question is,
should I keep storing the data using array in the program, so that it will be
Public arrConfiguration[99, 49] as Integer
or store it in an Excel file, and make the program open the Excel file and access the cells repeatedly? Which one is better?
Thank you.
Please prefer excel. Sample example data image is appended here-under.
For creating two dimensional dynamic array in excel, follow the steps below:
◾Declare the two dimensional Array
◾Resize the array
◾Store values in array
◾Retrieve values from array
Sub FnTwoDimentionDynamic()
Dim arrTwoD()
Dim intRows
Dim intCols
intRows = Sheet1.UsedRange.Rows.Count
intCols = Sheet1.UsedRange.Columns.Count
ReDim Preserve arrTwoD(1 To intRows, 1 To intCols)
For i = 1 To UBound(arrTwoD, 1)
For j = 1 To UBound(arrTwoD, 2)
arrTwoD(i, j) = Sheet1.Cells(i, j)
Next
Next
MsgBox "The value is B5 is " & arrTwoD(5, 2)
End Sub
In the Message Box you will get the following output.
Further To visualize a two dimensional array we could picture a row of CD racks. To make things easier, we can imagine that each CD rack could be for a different artist. Like the CDs, the racks would be identifiable by number. Below we'll define a two dimensional array representing a row of CD racks. The strings inside of the array will represent album titles.
For multidimensional arrays it should be noted that only the last dimension can be resized. That means that given our example above, once we created the array with two CD racks, we would not be able to add more racks, we would only be able to change the number of CDs each rack held.
You can simplify #skkakkar code:
dim x as variant
x = range("A1").CurrentRegion
No Redim, no loops.
Depending on how you see things evolving, you might want to consider accessing your Excel data via ADO, rather than OLE Automation. That way, if you decide to change your storage system to Access, SQL Server or something else, you will have less work to do.
How To Use ADO with Excel Data from Visual Basic or VBA (Microsoft)
https://support.microsoft.com/en-gb/kb/257819
Read and Write Excel Documents Using OLEDB (Codeproject)
http://www.codeproject.com/Tips/705470/Read-and-Write-Excel-Documents-Using-OLEDB
I have a range with 170000 rows in it. I'm filtering column A for a single value and returning the corresponding values in column B.
I want these values to dump into an array so I can quickly toss them into a dictionary (with the key being the value I filtered column A with).
The problem is that SpecialCells(xlCellTypeVisible) is acting inconsistent.
If I do the same test on a smaller range, the values dump into the array just fine. But with a range as large as mine, it only returns the first value in the range. Also, I can use the same line to copy to another sheet. I just can't get it to populate the array.
foo = ws1.Range(tbl1Name & "[ID]").SpecialCells(xlCellTypeVisible)
Works with small ranges, but returns only the first result in a range as large as mine (less than 50 results.) foo becomes an array containing all the variables.
ws1.Range(tbl1Name & "[ID]").SpecialCells(xlCellTypeVisible).Copy ws2.Range("A1")
Works with the large range and copies all the relevant data successfully.
So my question: How do I populate the array without the extra step of copying to a blank worksheet when autofiltering a large table range? (Excel 2013)
EDIT: requires a reference to "Microsoft Forms 2.0 Object Library" (should be near the top of the list of available references). Or add a userform to your project and that will auto-add the reference (you can then remove the form...)
This should work for a single column:
Sub Tester()
Dim rng, txt As String, cb As New DataObject, arr
Set rng = ActiveSheet.Range("A2:A28").SpecialCells(xlCellTypeVisible)
rng.Copy
DoEvents
cb.GetFromClipboard
txt = cb.GetText
arr = Split(txt, vbCrLf)
Debug.Print LBound(arr), UBound(arr)
End Sub
If you had multiple columns you'd need to loop over each element of arr (splitting its value on tab) and transfer the values to a 2-d array.