Condensing Excel data with overlapping index/repetitive word occurrence - database

I have an excel sheet that is formatted like so:
I would like to format it to be something like this:
It is about 40,000 cells of information, so is there any way to do this that isn't manually?

You could probably use =SUMIF to achieve this, since you appear to have numbers as values.
Create a new sheet, copy column A from your data sheet to your new sheet and remove duplicates. Copy row 1 from your data sheet to your new sheet.
Use this formula in sheet 2 cell B2:
=SUMIF(Sheet1!$A:$A;Sheet2!$A2;Sheet1!B:B)
Drag the formula to the right, then down.

I am by no means an excel expert, and this is going to be my first answer ever. Take this into account please.
I've checked it and it works.
I've add a command button in Sheet1 (where the original data is), and when clicked this code writes formatted data into Sheet2.
No need to manually remove duplicates!
Dim dU1 As Object, cU1 As Variant, iU1 As Long, lrU As Long
Dim MyArray() As Variant
Dim i As Integer
Dim j As Integer
Dim k As Integer
Dim h As Integer
Private Sub CommandButton1_Click()
'Get unique indexes
Set dU1 = CreateObject("Scripting.Dictionary")
lrU = Cells(Rows.Count, 1).End(xlUp).Row 'number of rows
cU1 = Range("A2:A" & lrU) 'Assuming your data starts in A2
For iU1 = 1 To UBound(cU1, 1)
dU1(cU1(iU1, 1)) = 1
Next iU1
'Now dU1 contains indexes as unique values (about, absence, etc.)
For i = 0 To dU1.Count - 1 'for each index
ReDim MyArray(1 To 1) As Variant 'starts a "new" array
For j = 2 To 9 'each of the columns with values (D1-D8)
a = 0
For k = 2 To lrU 'all rows
If (Worksheets("Sheet1").Cells(k, 1).Value = dU1.keys()(i) And Worksheets("Sheet1").Cells(k, j).Value <> "") Then
MyArray(UBound(MyArray)) = Worksheets("Sheet1").Cells(k, j).Value 'add value to array
ReDim Preserve MyArray(1 To UBound(MyArray) + 1) As Variant 'resize array (now is 1 element longer)
a = a + 1
End If
Next
If a = 0 Then 'if no value found, add an element to array anyway
MyArray(UBound(MyArray)) = "" 'add value to array
ReDim Preserve MyArray(1 To UBound(MyArray) + 1) As Variant 'resize array (now is 1 element longer)
End If
Next
Worksheets("Sheet2").Cells(i + 2, 1) = dU1.keys()(i) 'write indexes in another sheet
For h = 2 To UBound(MyArray)
Worksheets("Sheet2").Cells(i + 2, h) = MyArray(h - 1)
Next
Next
End Sub

Related

Storing data to array from worksheet

I'm trying to analyze some data from a worksheet, the first step was to find the last row, which I managed. Then I need to store the data in an array for each column to simplify further analysis.
My data looks like this:
I'm trying to store let's say the B column in an array but starting at B6:
Sub List_Rem_stock()
Dim array_Rem_Batch(1 To last_row_Rem_stock - 5) As Integer
For i = 1 To last_row_Rem_stock - 5
array_Rem_Batch(i) = Worksheets("Rem stock").Range(Bi)
Next i
Debug.Print array_Rem_Index
End Sub
last_row_Rem_stock represents the last row of the table.
Am I doing this properly?
Almost, try the code below (find explanation inside code's comments):
Option Explicit
Sub List_Rem_stock()
Dim last_row_Rem_stock As Long, i As Long
Dim array_Rem_Batch() As Long
With Worksheets("Rem stock")
last_row_Rem_stock = .Cells(.Rows.Count, "B").End(xlUp).Row ' get last row with value in colum B
ReDim array_Rem_Batch(1 To last_row_Rem_stock - 5) ' redim array size
For i = 1 To last_row_Rem_stock - 5
array_Rem_Batch(i) = .Range("B" & i).Value
Next i
End With
End Sub
You can allocate a range to an array (2D) as such:
Dim arrData as variant: arrData = Range("B1:B" & lastrow).
You can also put the array back on the spreadsheet the same way:
Range("B1:B" & lastrow) = arrData
Simple, easy and fast, without the need of iterating through data.
In your example, you would probably do it like this.
Sub List_Rem_stock()
Dim i As Long, last_row_Rem_stock As Long
Dim array_Rem_Batch As Variant
With Worksheets("Rem stock")
last_row_Rem_stock = .Cells(.Rows.Count, "B").End(xlUp).Row 'get last row in B
array_Rem_Batch = .Range("B1:B" & last_row_Rem_stock)
End With
For i = 6 To last_row_Rem_stock
Debug.Print array_Rem_Batch(i, 1)
Next i
End Sub
To note that arrays allocated this way will always start at 1, not 0.
EDIT:
I'm allocating the data starting at row 1, and not at row 6, purely for the nice 1:1 relation between array index and sheet rows. Is my prefered way, wherever the situation allows.
If array_Rem_Batch(i, 1) = Range("B" & i) Then ....
Can always allocate the data from any row you want:
array_Rem_Batch = Worksheets("Rem stock").Range("B6:B100") 'now the array has 95 rows.
In this case, array index 1, will corespond to row 6 in the sheet, and will have to manage this in the code if you need to something like this:
If array_Rem_Batch(i, 1) = Range("B" & i + 5) Then ....

Passing text from one worksheet to another using an array

I'm trying to pass data from sheet 3 to sheet 4 based on a criterion (*). With numbers results but with text the program fails.
How to overcome this situation when instead of a number I have text.
Public Sub TestArray3()
'Array to copy data from Sheet3 to Sheet4 Based on criterion "in this case*"
Dim tempVar As Integer, anotherIteration As Boolean, i As Integer
Dim J As Integer, ArraySize As Integer, myArray() As Integer
Dim newArray() As Integer, FinalRow As Integer, linha As Integer
Dim counter As Integer, cel1 As Range
Sheets("Folha3").Select
FinalRow = Cells(Rows.Count, 1).End(xlUp).Row ' Find the last row of data
ArraySize = FinalRow 'Get Array Size
ReDim myArray(ArraySize - 1)
For linha = 1 To FinalRow
Set cel1 = Cells(linha, 1)
If cel1 = "*" Then
myArray(linha - 1) = Val(Cells(linha, "B").Value) 'Populate de Array
End If
Next linha
ReDim newArray(LBound(myArray) To UBound(myArray)) 'Avoid zeros in Array
For i = LBound(myArray) To UBound(myArray)
If myArray(i) <> "0" Then
J = J + 1
newArray(J) = myArray(i)
End If
Next i
ReDim Preserve newArray(LBound(myArray) To J)
ArraySize = J
Sheets("Folha4").Select 'Write data to Sheet 4 column A
Range("A1").Resize(J - LBound(newArray) + 1)=Application.Transpose(newArray)
End Sub
I'm not clear on where you're actually trying to paste from/to, but here's one [of several] ways to move data between worksheets, including both with and without transposing
Hopefully this example should clear up the steps:
Sub copyRangeToOtherSheet()
Dim lastRow As Long, lastCol As Long, rgSrc As Range, rgDest As Range, arr() As Variant
With ThisWorkbook.Sheets("Sheet1") 'set source worksheet
lastRow = .Cells(Rows.Count, "A").End(xlUp).Row 'find last row of Col A
lastCol = .Cells(1, Columns.Count).End(xlToLeft).Column 'find last col of Row 1
Set rgSrc = Range(.Range("A1"), .Cells(lastRow, lastCol)) 'create range (from A1)
End With
arr = rgSrc 'dump range into array
With ThisWorkbook.Sheets("Sheet2") 'set destination sheet
'OPTION #1: Populate destination in "original" orientation
Set rgDest = .Range("A1") 'set destination top-left corner
Set rgDest = rgDest.Resize(UBound(arr, 1), UBound(arr, 2)) 'fit to array rows/col's
rgDest = arr 'dump array to worksheet range
'OPTION #2: Populate destination in "transposed" orientation
Set rgDest = .Range("D1") 'set destination top-left corner
Set rgDest = rgDest.Resize(UBound(arr, 2), UBound(arr, 1)) 'fit to array col's/rows
rgDest = WorksheetFunction.Transpose(arr) 'dump transposed array to worksheet range
End With
End Sub
Note that it's easiest if you don't set the size of the array in advance — Excel will size it automatically as long as the array isn't already dimensioned (which is why it's declared only as arr() As Variant).
On the destination end, we can pick one cell as the top-left of the range, then ReSize the range based on the arrays' upper bounds (UBound).
If we are going to Transpose the cells, we must swap the number of rows/columns in the destination range.
More Information:
One resource I've found very helpful is Chip Pearson's VBA Arrays And Worksheet Ranges.
String vs Integer
It is a little unclear what is happening here, but I have noticed that you have declared all your arrays as integer so you cannot pass strings to them. Try to find out which array you're trying to pass strings to and declare it as variant or implement some 'conditional' code like:
If Not IsNumeric(Cells("A1").Value) then
Variable = 0
End If
Read ashleedawg's guidelines.
You don't have to select a worksheet to do stuff to it (referring to Select). You can write
FinalRow = Sheets("Folha3").Cells(Rows.Count, 1).End(xlUp).Row
or
Sheets("Folha4").Range("A1").Resize(J - LBound(newArray) + 1) _
= Application.Transpose(newArray)
and save a line but more importantly, not jump around in the workboook. Even better is using With:
With Sheets("Folha3")
FinalRow = .Cells(Rows.Count, 1).End(xlUp).Row ' Find the last row of data
ArraySize = FinalRow 'Get Array Size
ReDim myArray(ArraySize - 1)
For linha = 1 To FinalRow
Set cel1 = .Cells(linha, 1)
If cel1 = "*" Then
myArray(linha - 1) = Val(.Cells(linha, "B").Value) 'Populate de Array
End If
Next linha
End With
Notice the '.' in front of each cells (.cells), it is referring to the sheet object.
Try using variables for objects. When you write
Sheets("folha3").
nothing happens you have to remember what it can do. But if you assign it to a variable the intelliSense is activated and you can see the properties and methods of objects e.g.
Dim oWb as Workbook
Dim oWs as Worksheet
Set oWb = Activeworkbook
Set oWs = oWb.Sheets("Folha3")
Now when you write:
oWs.
the IntelliSense shows you the properties and methods of the worksheet object e.g. Activate, Cells, Copy, Delete, Paste etc.
With a few more lines of code you will learn much more.

Loop to replicate values into an array

I’m in a situation where I need to reproduce something in VBA and a bit stuck given my lack of understanding of object oriented language and VBA in general.
Problem:
I need to produce an array or vector based on a 2 column table.
The first range (column) contains unit counts.
The second range (column) contains numeric values.
I need to replicate the value based on the number of units.
For example,
if the first row contains 3 units with a value of $100
I need the array to contain $100, $100, $100.
This will need to be looped thru each row containing units.
So if row 2 contains 2 units with a value of $50
I need to complete array to be $100, $100, $100, $50, $50, and so on.
I understand this situation will require ReDim the array based on the total values. My struggle is I’ve been unable to figure out the nested for loops.
I get how to replicate the value based on the number of “units” like the below...
ReDim arr(0 To x - 1)
For i = 0 To x - 1
arr(i) = rng.Offset(0, 1).Value
Next
What is the best way to loop thru each row and replicate the values for each row in the range based on the unit count?
If anyone is familiar with R, I'm essentially looking for something that achieves the rep() function (e.g., rep(df$b, df$a)) and return the values in a single array.
Any help is greatly appreciated. Thanks
Or a one liner which uses the REPT function as you would have used in r :)
This assumes your data is in A1:B10 - the length can be made variable
s = Split(Join(Application.Transpose(Evaluate("=INDEx(REPT(B1:B10&"","",A1:A10),,1)"))), ",")
An an example, to dump the new to array to C1
s = Split(Join(Application.Transpose(Evaluate("=INDEx(REPT(B1:B10&"","",A1:A10),,1)"))), ",")
[c1].Resize(UBound(s), 1) = Application.Transpose(s)
When you say Row contains 3 units, do you mean the cell has value 3 or 3 Units? If it is 3 then you may not have to Redim the array in the loop. Simply find the sum of values in Col A which has units and Redim it in one go as shown below.
Sub Sample()
Dim ws As Worksheet
Dim Ar() As String
Dim n As Long, i As Long, lRow As Long
'~~> Change this to the relevant sheet
Set ws = Sheet6
With ws
n = Application.WorksheetFunction.Sum(.Columns(1))
ReDim Ar(t To n)
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
n = 1
For i = 1 To lRow
If Len(Trim(.Range("A" & i).Value)) <> 0 Then
For j = 1 To .Range("A" & i).Value
Ar(n) = .Range("B" & i).Value
n = n + 1
Next j
End If
Next i
For i = LBound(Ar) To UBound(Ar)
Debug.Print Ar(i)
Next i
End With
End Sub
Screenshot
And if the cell has 3 Units then you will have to store the values of Col A in an array, do a replace on Unit/Units, find the sum and finally use the above code. Here is an example
Sub Sample()
Dim ws As Worksheet
Dim Ar() As String, tmpAr As Variant
Dim n As Long, i As Long, j As Long, k As Long, lRow As Long
'~~> Change this to the relevant sheet
Set ws = Sheet6
With ws
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
tmpAr = .Range("A1:A" & lRow).Value
For i = LBound(tmpAr) To UBound(tmpAr)
tmpAr(i, 1) = Replace(tmpAr(i, 1), "Units", "")
tmpAr(i, 1) = Trim(Replace(tmpAr(i, 1), "Unit", ""))
n = n + Val(tmpAr(i, 1))
Next i
ReDim Ar(t To n)
n = 1
For i = 1 To lRow
If Len(Trim(.Range("A" & i).Value)) <> 0 Then
k = Val(Trim(Replace(Replace(.Range("A" & i).Value, "Units", ""), "Unit", "")))
For j = 1 To k
Ar(n) = .Range("B" & i).Value
n = n + 1
Next j
End If
Next i
For i = 1 To UBound(Ar)
Debug.Print Ar(i)
Next i
End With
End Sub
Screenshot
if your data is already in an array then ReDim'ing will delete it's contents. You can ReDim Preserve but it's an expensive operation, better to create a new array to put the results into.
I have assumed the data is contained within a Named Range called "Data" with Units being the first column and Values being the second column.
if your data changes regularly you can create a dynamic range using the OFFSET function i.e. =OFFSET(Sheet1!$A$1,0,0,COUNTA(Sheet1!$A:$A),2) assuming your data starts in cell A1 and there is no header row.
Sub ProcessData()
Dim DataArr() As Variant
Dim QtyColArr() As Variant
Dim ResultArr() As Variant
Dim TotalQty As Long
Dim i As Long, j As Long, k As Long
'store data into array
DataArr = Range("Data") 'assume data stored in named range called "Data"
'store Qty col into 1D array
QtyColArr = Range("Data").Resize(, 1)
'sum all qty vals
TotalQty = Application.Sum(QtyColArr)
're-size ResultsArray
ReDim ResultArr(1 To TotalQty)
'Initialize ResultsArr counter
k = LBound(ResultArr)
'loop DataArr
For i = LBound(DataArr) To UBound(DataArr)
'loop qty for current row
For j = 1 To DataArr(i, 1)
'copy value
ResultArr(k) = DataArr(i, 2)
'iterate ResultsArr counter
k = k + 1
Next j
Next i
'output to intermediate window
Debug.Print "{" & Join(ResultArr) & "}"
End Sub

ReDim Preserve with multidimensional array in Excel VBA

I can get this to work but am not sure if this is the correct or the most efficient way of doing this.
Details: Looping through 151 rows then assigning column A and B only of those rows to a two dimensional array based on criteria in column C. With the criteria only 114 of the 151 rows are needed in the array.
I know that with ReDim Preserve you can only resize the last array dimension and you can't change the number of dimensions at all. So I have sized the rows in the array to be the total 151 rows using the LRow variable but the actual rows I only need in the array is in variable ValidRow so it seems that (151-114) = 37 superfluous rows are in the array as a result of the ReDim Preserve line. I would like to make the array only as big as it needs to be which is 114 rows not 151 but not sure if this is possible see code below and any help much appreciated as I am new to arrays and have spent the best part of two days looking at this. Note: Columns are a constant no issue with them but rows vary.
Sub FillArray2()
Dim Data() As Variant
Dim ValidRow, r, LRow As Integer
Sheets("Contract_BR_CONMaster").Select
LRow = Range("A1").End(xlDown).Row '151 total rows
Erase Data()
For r = 2 To LRow
If Cells(r, 3).Value <> "Bridge From" And Cells(r, 3).Value <> "Bridge To" Then
ValidRow = ValidRow + 1
ReDim Preserve Data(1 To LRow, 1 To 2)
Data(ValidRow, 1) = Range("A" & r).Value 'fills the array with col A
Data(ValidRow, 2) = Range("B" & r).Value 'fills the array with col B
End If
Next r
ActiveWorkbook.Worksheets("Test").Range("A2:B" & ValidRow + 1) = Data() 'assign after loop has run through all data and assessed it
End Sub
I seemed to have got this to work by using transposition where the rows and cols are swapped around and still using ReDim Preserve then transposing at the end when assigning to a range. This way the array is exactly the size it needs to be with no blank cells.
Sub FillArray3() 'Option 3 works using transposition where row and cols are swapped then swapped back at the end upon assignment to the range with no blank cells as array is sized incrementally via the For/Next loop
Dim Data() As Variant
Dim ValidRow, r, LRow As Integer
Sheets("Contract_BR_CONMaster").Select
LRow = Range("A1").End(xlDown).Row '151 total rows
Erase Data()
For r = 2 To LRow
If Cells(r, 3).Value <> "Bridge From" And Cells(r, 3).Value <> "Bridge To" Then
ValidRow = ValidRow + 1
ReDim Preserve Data(1 To 2, 1 To ValidRow) 'can change the size of only the last dimension if you use Preserve so swapped rows and cols around
Data(1, ValidRow) = Range("A" & r).Value 'fills the array with col A
Data(2, ValidRow) = Range("B" & r).Value 'fills the array with col B
End If
Next r
ActiveWorkbook.Worksheets("Test").Range("A2:B" & ValidRow + 1) = Application.Transpose(Data) 'swap rows and cols back
End Sub
Note also that the internal VBA implementation of REDIM is not guaranteeing to release the storage when it is sized down. It would be a common choice in such an implementation to not physically reduce the storage until the size dropped to less than half the input size.
Have you considered creating a type-safe collection class to store this information instead of an array? In it's most basic form (for a storage type of Integer) it would look be a Class Module like this:
Option Explicit
Private mData As Collection
Public Sub Add(Key As String, Data As Integer)
mData.Add Key, Data
End Sub
Public Property Get Count() As Integer
Count = mData.Count
End Property
Public Function Item(Index As Variant) As Integer
Item = mData.Item(Index)
End Function
Public Sub Remove(Item As Integer)
mData.Remove Item
End Sub
Private Sub Class_Initialize()
Set mData = New Collection
End Sub
A particular advantage of this implementation is that the sizing logic is completely removed from the client code, as it should be.
Note that the Data type stored by such a patter can be any type supported by VBA, including an Array or another Class.
Two more ways of doing this.
FillArray4 - Initial array is created too large but second part of code moves this to a new array using a double loop which creates the array to be the exact size it needs to be.
Sub FillArray4()
Dim Data() As Variant, Data2() As Variant
Dim ValidRow As Integer, r As Integer, lRow As Integer
Sheets("Contract_BR_CONMaster").Select
lRow = Range("A1").End(xlDown).Row '151 total rows
'Part I - array is bigger than it has to be
Erase Data()
For r = 2 To lRow
If Cells(r, 3).Value <> "Bridge From" And Cells(r, 3).Value <> "Bridge To" Then
ValidRow = ValidRow + 1 'this is the size the array needs to be 114 rows
ReDim Preserve Data(1 To lRow, 1 To 2) 'but makes array to be 151 rows as based on lrow not ValidRow as cannot dynamically resize 1st dim of array when using preserve
Data(ValidRow, 1) = Range("A" & r).Value 'fills the array with col A
Data(ValidRow, 2) = Range("B" & r).Value 'fills the array with col B
End If
Next r
'Part II
'move data from Data() array that is too big to new array Data2() that is perfectly sized as it uses ValidRow instead of lrow
Erase Data2()
For i = LBound(Data, 1) To UBound(Data, 1) 'Rows
For j = LBound(Data, 2) To UBound(Data, 2) 'Cols
If Not IsEmpty(Data(i, j)) Then
ReDim Preserve Data2(1 To ValidRow, 1 To 2)
Data2(i, j) = Data(i, j) 'fills the new array with data from original array but only non blank dims; Data2(i,j) is not one particular row or col its an intersection in the array
'as opposed to part one where you fill the initial array with data from cols A and B using seperate lines for each col
End If
Next
Next
ActiveWorkbook.Worksheets("Test").Range("A2:B" & ValidRow + 1) = Data2() 'assign data from new array to worksheet
End Sub
Sub FillArray5 - Much simpler and my preferred option as you only create one array. Initial loop determines the size the array needs to be and then second loop uses this to create array and store data. Note only two cols in both cases. Issue I had in this scenario was creating 2D array where rows varied. That's it for me time to go to the tropics for a well earned holiday!
Sub FillArray5()
Dim Data() As Variant
Dim ValidRow As Integer, r As Integer, lRow As Integer, DimCount As Integer, RemSpaceInArr As Integer
Sheets("Contract_BR_CONMaster").Select
lRow = Range("A1").End(xlDown).Row
Erase Data()
For r = 2 To lRow
If Cells(r, 3).Value <> "Bridge From" And Cells(r, 3).Value <> "Bridge To" Then
ValidRow = ValidRow + 1 'this is the size the array needs to be 114 rows
End If
Next r
DimCount = 0 'reset
For r = 2 To lRow
If Cells(r, 3).Value <> "Bridge From" And Cells(r, 3).Value <> "Bridge To" Then
ReDim Preserve Data(1 To ValidRow, 1 To 2) 'makes array exact size 114 rows using ValidRow from first loop above
DimCount = DimCount + 1 'need this otherwise ValidRow starts the dim at 114 but needs to start at 1 and increment to max of ValidRow
Data(DimCount, 1) = Range("A" & r).Value 'fills the array with col A
Data(DimCount, 2) = Range("B" & r).Value 'fills the array with col B
End If
Next r
RemSpaceInArr = ValidRow - DimCount 'just a check it should be 0
ActiveWorkbook.Worksheets("Test").Range("A2:B" & ValidRow + 1) = Data() 'assign data from array to worksheet
End Sub

Ms Excel -> 2 columns into a 2 dimensional array

Im coming from a Unix world where I never had to develop something for Office with VBA, I have to do some now and Im having a hard time! Please help me! :)
So I've got 2 Excel Sheets(lets call them Sheet1 and Sheet2) and 2 forms(Form1 and Form2) to edit/add data.
In Sheet1, the first two columns are MovieId and MovieName. We dont know how many rows they will be in this columns.
Form1 controls data in Sheet1, and Form2... in Sheet2.
At Form2 initialization, I want to create a 2 Dimensional Array that will be like (MovieId1,MovieName1;MovieId2,MovieName2;...,...;MovieIdN,MovieNameN), where this data has been extracted from Sheet1, like a sort of Map in Java if you will...
It would actually be ok for me if it was like: (0,"MovieId0;MovieName0";1,"MovieId1,MovieName1";..,"..";N,"MovieIdN,MovieNameN")
I dont know how to create the array with an variable last row number, since the compiler seems to always want a constant to initialize an Array...
Please enlighten me!
Look at the Value method or Value2 property.
e.g. Range("$A$2:$B$4").Value2(1,1)
or
Range("$A$2:$B$4").Value()(1,1)
Array's lower bound start from 1.
lbound(Range("$A$2:$B$4").Value2, 1) - row element starts from
ubound(Range("$A$2:$B$4").Value2, 2) - row element ends
lbound(Range("$A$2:$B$4").Value2, 2) - column element starts from
ubound(Range("$A$2:$B$4").Value2, 2) - column element ends
EDIT: Code to traverse through the array
Dim myAddress As String
Dim dataArray As Variant
Dim rowStart As Long, rowEnd As Long
Dim colStart As Long, colEnd As Long
Dim rowCtr As Long
Dim colCtr As Long
myAddress = "$A$2:$B$4"
dataArray = Range(myAddress).Value2
rowStart = LBound(dataArray, 1)
rowEnd = UBound(dataArray, 1)
colStart = LBound(dataArray, 2)
colEnd = UBound(dataArray, 2)
For rowCtr = rowStart To rowEnd
For colCtr = colStart To colEnd
Debug.Print rowCtr & ":" & colCtr, vbTab & dataArray(rowCtr, colCtr)
Next
Next
EDIT2: In my example, I have assumed the address to be $A$2:$B$4.
You can prefix it with sheet name. e.g. Sheet1!$A$2:$B$4 or Sheet2!$A$2:$B$4
On a side note, array can be defined dynamic (if it is 1 dimensional).
e.g dim my1DArray() as Integer
For double dimension array, see the following code
Dim myArray
Dim dynamicRows As Integer
dynamicRows = 2
ReDim myArray(0 To dynamicRows, 0 To dynamicRows)
myArray(0, 0) = "hello"
dynamicRows = 20
ReDim myArray(0 To dynamicRows, 0 To dynamicRows)
MsgBox myArray(0, 0)
myArray(0, 0) = "hello"
ReDim Preserve myArray(0 To dynamicRows, 0 To dynamicRows)
MsgBox myArray(0, 0)
Rather use the Range object, with this you can also use the UsedRange from the sheet
Sub Macro1()
Dim sheet As Worksheet
Dim range As range
Dim row As Integer
Set sheet = Worksheets("Sheet1")
Set range = sheet.UsedRange
For row = 1 To range.Rows.Count
Next row
End Sub
assuming the data starts in A1
Dim vArr as variant
vArr=worksheets("Sheet1").range("A1").resize(worksheets("Sheet1").range("A65535").end(xlup).row,2)
Do you mean:
Dim thearray() As Variant
ReDim thearray(1, range.Rows.Count)
You can also use a recordset and GetRows to return an array from a worksheet.
Slight mod to Charles' answer:
Dim vArr as variant
vArr = Worksheets("Sheet1").Range("A1").CurrentRegion.Value
Assuming of course that there isn't any stray data in Sheet1.

Resources