How to get Excel Row as 1D object array into VB.net - arrays

I am trying to pull a row of data from an excel spreadsheet that I already have open, in order to compare it with an existing 1D array of values. As far as I can tell, when I try to pull a range such as
Dim excelArray(49) as object
excelArray = sheet1.Range("B3", "AY3").Value
it returns a 2d array, even though it only has a single row. This line in my code errors because of this. I need it to compare with another array that is already populated which is actually an array of Singles. The above excel row also contains a row of singles in each cell.
Dim otherArray(49) as object
Is there a way to do this that does not involve the following.
For i As Integer = 2 To 51
indexJ = i - 2
excelArray(indexJ) = sheet1.Cells(3, j).value
Next j
I do not wish to do it the above way because I am doing this with several large arrays, multiple times. The process of doing it cell by cell seems to be taking a long time.

Related

Possible to Run Goal Seek on array elements within VBA, instead of an Excel sheet range?

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

Searching, Sorting, Matching, within Dynamic Multidimensional Array - VBA

Before I begin, I know all of this can be accomplished with a SQL query. Just take my word that currently building an active directory is in the works, but right now this is what i have:
An excel spreadsheet of about 30k rows with about 25 columns with a list of items, using the item # as the level 1 match. Let's call it the "master" sheet.
The item #'s, which are unique identifiers, may appear multiple times, i.e.:
Item # 10000 can appear multiple times in this sheet.
So I created a dynamic array, and inserted the entire master sheet into the array using
Sub Items()
Dim Items() As Variant
Sheets("Master").Activate
Items = Range("A3", "AL" & Range("a1").End(xlDown).Row)
End Sub
The user will be on another sheet within the workbook ("itemlist"), and will enter some items they need like this: Item List
I need all occurrences (whether it be a single or duplicate value) of each of the items in the "Master" to output to individual rows on another sheet.
I'm stuck how to achieve this in VBA. I'm finding it difficult to find examples of this.
Would i want to sort the array first to make finding the duplicates faster? Should I turn the user created list into a single dimensional array and try to find intersecting points with the 2d array? I'm not sure where to start after the creation of the "master" array.
The reason I'm using arrays instead of a bunch of index matching or iterative looping in the "Master" sheet is because the processing power/physical memory available will be inconsistent due to computing environment, so arrays seem to be the most efficient method to avoid some users taking several minutes for return values if it can process at all.
What do you mean 'may appear multiple times'? It sounds like you need xto group and sum, as you would in a database (Access or SQL Server) or do some ranking and pick the highest/lowest element in the array. Or, are you saying you want to copy/paste certain element in your array to a new sheet???
Let's say you want to copy items in column B, which have a value of 'x', and paste them into another sheet, well, just run the script below.
Sub CopyData10()
Dim Rng As Range, cell As Range
Dim rw As Long
Set Rng = Worksheets("Sheet1").Range("B1:B10")
rw = 1
For Each cell In Rng
If LCase(cell.Value) = "x" Then
Worksheets("Sheet2").Cells(rw, "A") = cell.Offset(0, -1)
rw = rw + 1
End If
Next
End Sub

What is the Best Method for Storing Data

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 cre­at­ing two dimen­sional dynamic array in excel, fol­low the steps below:
◾Declare the two dimen­sional Array
◾Resize the array
◾Store val­ues in array
◾Retrieve val­ues 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

SpecialCells(xlCellTypeVisible) not returning all values to array (Excel 2013)

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.

Populating an Array in VBA from different parts of a spreadsheet

I am trying to populate different portions of an array based on different locations within a spreadsheet.
For example
Dim prices(50) as double
prices(0, 1, 2) = Range("i35", "i38")
prices(3,4,5,6,7,8) = Range("b7","b12")
I'm getting a wrong number of dimensions error, because I'm assuming you have to populate the whole thing at once. Is there another syntax to do this better, or is it just a limitation of VBA?
Possibly a for each loop? But that doesn't really help since there are a lot of different ranges.
Thanks for your help
It looks like you are trying to tell VBA that the list of numbers in the parenthesis of the array are positions within an array that will receive multiple items.
That's not what it is. Instead, you can only do one at a time. For example:
Dim prices(50) as double
' My range syntax might be wrong here.
prices(0) = Range("i35", "i35")
prices(1) = Range("i36", "i36")
prices(2) = Range("i37", "i37")
prices(3) = Range("i38", "i38")
..etc. Or, if you're new to programming, you'll find this really cool:
for CounterVariable = 0 to 3
prices(CounterVariable) = Range("i" & 35 + CounterVariable)
next CounterVariable
To Wit ...
an array defined like Dim prices(50) will have one 'dimension', like a straight line.
Picture one row in a spreadsheet, 50 columns long.
If you said Dim prices(50,60) you would have a 2-dimensional array, like a cartesian plane (x,y) or a 50x60 cell spreadsheet where the first number is like the letters, the second, like the numbered rows.
Some languages support 3-dimensional arrays - VariableName(x,y,z). Don't know if VBA does
Therefore, using commas in parenthesis after an array is supported by VBA
BUT it means something completely different than you were hoping (and you can't change that): the values for the dimensions.
So your last line of code is looking for some value in a 6-dimensional universe! So we've got, height, width, depth, time, tesseract, and uh, you've beat me there!!!

Resources