Creating and Transposing Array in VBA - arrays

I'm hoping to load values in a range to an array and transpose that array to another location (different workbook)
I am using the below forum post to get an idea of how to do it:
http://www.mrexcel.com/forum/excel-questions/629320-application-transpose-visual-basic-applications-array.html
Below is the code I am working with now, and I'm getting the 1004 object defined error. Can anyone spot what I am doing wrong?
I did find that the code works if I do not Set tRangeArray and instead do Sheets("sheet1").Range("C12:C19).Value = Application.Transpose(MyArray), but I'm not sure why that's different from my code.
Sub copy_data()
Dim cRange As Range, aRange As Range, tRange1 As Range, wbk1 As Workbook, wbk2 As
Workbook
Dim MyArray() As Variant, tRangeArray As Range
Set wbk1 = ThisWorkbook
MyArray = Range("E12:L12")
Set tRangeArray = wbk1.Sheets("sheet1").Range("C12:C19")
Sheets("sheet1").Range(tRangeArray).Value = Application.Transpose(MyArray)

As I mentioned in comments, just use:
tRangeArray.Value = Application.Transpose(MyArray)
Sheets("sheet1").Range(tRangeArray).Value not working, because Range accepts either single parameter - string with range address (not range itself): Range(addr), either two parameters - top left and bottom right cells: Range(cell_1,cell_2)

Similar, but using Resize and Ubound:
Dim myarray As Variant
myarray = Array(1, 2, 3, 4, 5)
Sheets("sheet1").Range("A1").Resize(UBound(myarray), 1).Value = Application.Transpose(myarray)

Related

Create a VBA Array from Column Headers?

I have a an export "NewExport" that always randomizes the columns of data I receive. I need these columns to align with the order of columns in "TheOrder", so this code will help to re-organize the export to align with the column headers I've already built.
I have 132 columns that need re-alignment, and while I can type it all out, there must be an easier way to align with the column headers I've already created. It should be noted that the below code is shamelessly copy/pasted from another StackOverflow answer.
Sub OrderColumns(ByVal NewExport As Workbook, ByVal TheOrder As Worksheet)
Dim correctOrder() As Variant
Dim lastCol As Long
Dim headerRng As Range, cel As Range
Dim mainWS As Worksheet
Set mainWS = NewExport.Worksheets("Sheet1")
'Need to figure out how to make this an array based on a Range
correctOrder() = Array(TheOrder.Range("A1:A132").Value)
With mainWS
lastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
Set headerRng = .Range(.Cells(1, 1), .Cells(1, lastCol))
End With
Dim newWS As Worksheet
Set newWS = Ninja.Sheets.Add
newWS.Name = "Rearranged Sheet"
Dim col As Long
With newWS
For col = 1 To lastCol
For Each cel In headerRng
If cel.Value = correctOrder(col - 1) Then
mainWS.Columns(cel.Column).Copy .Columns(col)
Exit For
End If
Next cel
Next col
End With
End Sub
While it's not as automated as I would have liked (and requires one piece of hard-coding), I was able to find a solution as such:
Dim correctOrder(132) As Variant
'132 will need to be changed if there's ever any more/less columns added/excluded
For i = 1 To 132
correctOrder(i - 1) = TheOrder.Range("A" & i).Value
Next
This solution gave me the array I was looking for for use later on.
I recently wrote a 'column finder' function for a project of mine.
I've modified it to suit your requirements below.
The function requires you pass the workbook your correct ordered headings are in to capture. You could modify this to require your TargetWorksheet instead so it's a bit more dynamic.
The function returns a single dimension Array.
The function finds the last used Column in the Target Worksheet allowing for changes in the number of column headings (as mentioned in your own answer which has the column number hard coded).
Public Function CorrectOrderHeadingsArrayFunction(ByRef TargetWorkbook As Workbook) As Variant()
With TargetWorkbook.Sheets(1) 'Change this to target your correct sheet
Dim LastColumn As Long
LastColumn = .Cells(1, .Columns.Count).End(xlToLeft).Column
CorrectOrderHeadingsArrayFunction= Application.Transpose(Application.Transpose(.Range(.Cells(1, 1), .Cells(1, LastColumn)).Value)) 'This returns the array as single dimension rather than 2D
End With
End Function
As an example, below is some sample 'Test' code to show the concept of using this function .
You could call it like so, and loop through each element perhaps comparing another arrays elements to the correct order elements and do something when the correct order value is found.
Sub TestSub()
Dim CorrectOrderArray As Variant
Dim TargetCorrectOrderElement As Variant
Dim RandomOrderArray As Variant
Dim TargetRandomOrderElement As Variant
CorrectOrderArray = CorrectOrderHeadingsArrayFunction(Workbooks("Export (4).csv")) 'Change this to target your correct workbook
RandomOrderArray = Sheet1.Range("A1:AZ1000") 'Change this to target the correct range for your data.
For Each TargetCorrectOrderElement In CorrectOrderArray
For TargetRandomOrderElement = LBound(RandomOrderArray) To UBound(RandomOrderArray)
If RandomOrderArray(TargetRandomOrderElement) = TargetCorrectorderValue Then
'Do some code to write that column to your worksheet
Exit For 'Leaves the current iteration of the random order array loop to go to the next iteration of the correct order array
End If
Next TargetRandomOrderElement
Next TargetCorrectOrderElement
End Sub

Store element from excel into array VBA

I have some data in terms of a column that I want to store into an array using VBA. After storing it, I will reference the element in the array and make a comparison.
Dim tRange As Range
Set tRange = wb.Sheets("wbname").Range("A1:A5")
Lets say I want to store column A with 5 row into the array in VBA. May I know the way?
Here is one way:
Sub Dave()
Dim tRange As Range, wb As Workbook, cell As Range
Dim i As Long
Set wb = ThisWorkbook
Set tRange = wb.Sheets("wbname").Range("A1:A5")
ReDim arr(1 To tRange.Count)
i = 1
For Each cell In tRange
arr(i) = cell.Value
i = i + 1
Next cell
End Sub
NOTE:
This technique does not depend on the "shape" of the range. It will work if the range is a piece of a column, or a piece of a row, or a rectangle of cells, or even a disjoint set of cells.
You can just declare a Variant data type and make it equal to the range.
Dim DirArray As Variant
DirArray = Range("a1:a5").Value
This was answered in a previous question by #vacip coincidentally for exactly the same range!
Creating an Array from a Range in VBA

Transferring an array to multiple ranges

I have become stuck trying to solve a piece of code I thought would be very simple.
I have defined a range (2 rows, 150 columns) and transferred it to an array. I then want to use the defined array in multiple ranges (same size of 2 rows and 150 columns). I have written the following code:
Dim LocalArray As Variant
LocalArray = .Range("FD6781:KW6782").Value2
.Range("FD6839:KW6840,FD6955:KW6956,FD7013:KW7014,FD7071:KW7072").Value2 = LocalArray
The issue is that every second range defined in .range("FD6839:KW6840,FD6955:KW6956...") shows up as N/A. Hence range FD6839:KW6840 is correct while range FD6955:KW6956 is wrong.
What have I done wrong in the above code?
Thank you!
You could loop. Otherwise, it does seem to be related to the number of columns causing the issue. Seems odd.
Option Explicit
Public Sub test()
Dim localArray(), rng As Range, ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet3")
localArray = ws.Range("FD6781:KW6782").Value2
For Each rng In ws.Range("FD6839, FD6955, FD7013, FD7071")
rng.Resize(UBound(localArray, 1), UBound(localArray, 2)) = localArray
Next
End Sub

Using VBA to assign range of cell values to array of variables

I'm very new to VBA, to bear with me here.
I want to assign a set of variables the value of a set of ranges ie. run a brief code to simplify the following
Dim Sample 1 as string
Sample1 = activeworksheet.range("C17").value
Dim Sample 2 as string
Sample2 = activeworksheet.range("C18").value}
and so on
Following an excelfunctions.net tutorial, I know that I can shorten the declaration to
Dim Sample(1 to 20) as a string
But the tutorial drops it there(because it's a tutorial about names), suggesting I populate it as follows
sample(1)=activesheet.range("C7").value
sample(2)=activesheet.range("C7").value
and so on
I found the discussion below to be on the right track to answer my quest, but I am having trouble applying it to my situation. (Excel VBA Array Ranges for a loop)
As a follow up note, I am ultimately trying to assign values to these variables for use in the following procedures, rather than declaring and assigning them each time.
Thanks!
Try something like this:
Sub test()
Dim sampleArr(1 To 20) As String
Dim i As Integer
Dim rng As Range, cel As Range
i = 1
Set rng = Range("C1:C20")
For Each cel In rng
sampleArr(i) = cel.Value
i = i + 1
Next cel
For i = LBound(sampleArr) To UBound(sampleArr)
Debug.Print sampleArr(i)
Next i
Also, if you know the range you want to put into an array, you can simply set an array to that range:
Sub test()
Dim sampleArr() As Variant
Dim i As Integer
Dim rng As Range, cel As Range
i = 1
Set rng = Range("C1:C20") ' Note, this creates a 2 Dimensional array
sampleArr = rng ' Right here, this sets the values in the range to this array.
For i = LBound(sampleArr) To UBound(sampleArr)
Debug.Print sampleArr(i, 1) ' you need the ",1" since this is 2D.
Next i
End Sub
You should :
Define the range you want to retrieve data
For each cell of the range, retrieve your datas
dim tab() As string, cell as range, i as integer
i = 0
redim tab(0)
for each cell in ActiveWorksheet.Range("C1:C20")
tab(i) = cell
i = i + 1
redim preserve tab(i)
next
edit : I indent the code to display it correctly
Additional way to the above you can only use:
Arr = ActiveWorksheet.Range("C1:C20").Value
Then you can directly use:
Arr(i,1) where i is C1 to C20 range!

VBA Application.Index with array causes type mismatch error 13

My macro throws a type mismatch error when I use
Myarr= Application.Index(arr,0,1)
I have tried adding option explicit and defining the variables as variants but nothing seems to work.
The arr array is created from a CSV file and that contains 100000 rows and 11 columns. The arr looks fine when I check it in the watch window (I can see the values for each row and column)
Here is the code:
Sub ArrTest()
Dim Myarr
Dim Arr
Dim wb As Workbook
Set wb = Workbooks.Open("F:\People.csv")
Arr = wb.Sheets(1).Range("A1").CurrentRegion.Value
Myarr = Application.Index(Arr, 0, 2)
End Sub
Can anyone suggest what I am doing wrong?
Many of the worksheet functions have a limit of just over 65k or so when it comes to the upper bound of input arrays, so you may be hitting that. Works for me with 65k, fails with 66k rows.
Sub ArrTest()
Dim Myarr
Dim Arr
Arr = Range("a1:C65000").Value
Myarr = Application.Index(Arr, 0, 1) '<<< OK
Arr = Range("a1:C66000").Value
Myarr = Application.Index(Arr, 0, 1) '<<<fails
End Sub
If you want to be able to handle more than 65k upper bound, then you will need to use a loop to populate your array "slice"

Resources