Dictionary value of key from another array - arrays

This has been answered... have to wait 2 days to accept own answer
Background:
I have an array ("arr") generated from a dataset in Excel; I use that array to populate another array ("zrr"), where one aspect of that population is to use a Dictionary ("dcdept").
The dictionary was populated appropriately (tested via debug.print dcdept(ActualKey); was populated such that dcdept(4000)="Value" and tested debug.print dcdept(4000) printed the word "Value" in the immediate window.
I was originally using the source dataset via .cells(i,) references, but with several hundred thousand lines, I tried to keep activities in VBA to speed it up.
There are no errors/alerts generated from my code.
Issue:
When attempting to populate an element in zrr (zrr(i-1,3)) using the dictionary key from arr (dcdept(arr(i-2,16))), I get no value output.
Question:
Does anyone have any suggestions/solutions to resolve the issue with the given data?
Code in question:
Public arr As Variant, brr As Variant, crr As Variant, drr As Variant, lrs As Long
Private Sub changes()
Dim i As Long, x As Long, y As String, z As String, dcdept As Scripting.Dictionary, zrr As Variant, a As Long
'set-up dictionary for department
Set dcdept = New Scripting.Dictionary
dcdept(4000) = "Value"
'generate array to store new values
With Sheets("Conversion")
.Columns(16).NumberFormat = "0"
lrs = .Cells(.Rows.Count, 1).End(xlUp).Row
arr = .Range(.Cells(2, 1), .Cells(lrs, 17)).Value '17 = Q
ReDim zrr(lrs, 4)
For i = 2 To lrs
ReDim Preserve zrr(lrs, 4)
Select Case Left(arr(i - 1, 17), 3)
Case "QTE"
x = 7
Case "ZNA"
x = 5
End Select
zrr(i - 2, 0) = Right(arr(i - 1, 17), x)
If InStr(arr(i - 1, 9), " Milestone ") Then
y = Left(arr(i - 1, 9), 2) & " " & arr(i - 1, 10)
Else
y = arr(i - 1, 9) & " " & arr(i - 1, 10)
End If
zrr(i - 2, 1) = y
If IsEmpty(arr(i - 1, 14)) Then
zrr(i - 2, 2) = "N"
Else
zrr(i - 2, 2) = "Y"
End If
a = Val(arr(i - 1, 16))
z = dcdept(a)
zrr(i - 2, 3) = z
Debug.Print a
Debug.Print z
Next i
'append data to sheet
.Cells(2, "R").Resize(lrs, 3).Value = zrr 'SHOULD BE Resize(lrs,4), per answer
End With
End Sub

OK this is not an answer, but an illustration of my comment. I didn't expect this to happen. I set up a simple scenario which I hope is similar to yours:
Sub x()
Dim oDic As Object, v1(1 To 2), v2(1 To 2), v, i As Long
Set oDic = CreateObject("Scripting.Dictionary")
v1(1) = "Fred"
v1(2) = 1000
oDic(1) = v1(1) 'key 1, item "Fred
oDic(2) = v1(2) 'key 2, item 1000
The locals window after this looks like this
Then add this line
v2(1) = oDic(v1(1))
and the immediate window reads thus:
Add this line
v2(2) = oDic(v1(2))
and the immediate window reads thus:

I'm an idiot...
.Cells(2, "R").Resize(lrs, 3).Value = zrr
should be
.Cells(2, "R").Resize(lrs, 4).Value = zrr
Can't accept my own answer for 2 days; pardon the "unanswered" question in the meantime.

Related

Pasting Formula from an Array in VBA into an excel table

So I am trying to make a VBA scripts that changes all indirect formula in a selection into direct reference, aim is to improve performance of my excel workbook. Below is the code:
Call manual
Dim continue As Integer
continue = MsgBox("This cannot be undone. Continue anyway?", vbOKCancel)
If continue <> vbOK Then Exit Sub
Dim formula_array() As Variant
row_cnt = Selection.Rows.count
col_cnt = Selection.Columns.count
ReDim formula_array(1 To row_cnt, 1 To col_cnt)
If row_cnt = 1 And col_cnt = 1 Then
formula_array(1, 1) = Selection.formula
Else
formula_array = Selection.formula
End If
'for some reason formula_array = Selection.formula gives an error when I select only one cell
count = 0
Dim i As Integer, y As Integer
For i = 1 To row_cnt
For y = 1 To col_cnt
frmula = formula_array(i, y)
oldfunc = find_full_formula(frmula, "indirect(")
Do While (oldfunc <> "")
newfunc = Application.Evaluate(oldfunc)
If IsError(newfunc) Then
newfunc = ""
End If
oldfunc = "indirect(" & oldfunc & ")"
formula_array(i, y) = Replace(formula_array(i, y), oldfunc, newfunc, 1, -1, vbTextCompare)
frmula = formula_array(i, y)
oldfunc = find_full_formula(frmula, "indirect(")
count = count + 1
Loop
Next y
Next i
Dim temp As String
Selection.formula = formula_array
MsgBox count
Call auto
Here the find_full_formula function gives arguments of any function, input is the start of that function and the whole formula. So if you have a formula"Indirect("A1:B2")" then the result of this function would be "A1:B2".
The whole script works very well for normal ranges except when I try to run in on a column of an excel table where the selection also includes the first cell of the column (first cell of data, so not the header) then the result is that all cells in that column have the same formula as the first cell. What is also interesting is that if I select all cells of a column of the table except the first one then the result is fine but only when the first cell is also involved then the problem arises. It obviously looks like some auto-fill feature but I have turned off all such settings that I could find and still this issue isn't solved.
okay, I am adding below a much simpler version of VBA code to highlight my problem:
Dim arr(1 To 4, 1 To 1) As Variant
arr(1, 1) = "2+2"
arr(2, 1) = "=3+2"
arr(3, 1) = "=4+2"
arr(4, 1) = "=5+2"
Range("A2:A5").Formula = arr
this code above works just fine, however the one below results in "=2+2" as formula for each cell of my table.
Dim arr(1 To 4, 1 To 1) As Variant
arr(1, 1) = "=2+2"
arr(2, 1) = "=3+2"
arr(3, 1) = "=4+2"
arr(4, 1) = "=5+2"
Range("A2:A5").Formula = arr
Table in excel looks something like this:
Excel Table
I found a solution that works in all cases I checked out, but it's not beautiful - consider it as a workaround:
set Application.AutoCorrect.AutoFillFormulasInLists = False
set formula to cells by looping them (one by one)
None of these alone sets the formulas as expected if selection matches a ListObject.DataBodyRange.
Sub Test()
' select a range that fits
' the following arrays dimensions
Dim arr(1 To 4, 1 To 2) As Variant
arr(1, 1) = "=2+2": arr(1, 2) = "=12+2"
arr(2, 1) = "=3+2": arr(2, 2) = "=13+2"
arr(3, 1) = "=4+2": arr(3, 2) = "=14+2"
arr(4, 1) = "=5+2": arr(4, 2) = "=15+2"
' deactivate AutoFillFormulasInLists; store setting to restore
Dim bAutoFill As Boolean
bAutoFill = Application.AutoCorrect.AutoFillFormulasInLists
Application.AutoCorrect.AutoFillFormulasInLists = False
Selection.ClearContents
' `Selection.FormulaR1C1 = arr` does NOT work in case of
' Selection = ListObject.DataBodyRange
' => loop cells (slower and more lines of code)
Dim i As Long, j As Long
For i = 1 To UBound(arr, 1)
For j = 1 To UBound(arr, 2)
Selection(i, j).FormulaR1C1 = arr(i, j)
Next j
Next i
Application.AutoCorrect.AutoFillFormulasInLists = bAutoFill
End Sub
Hopefully somebody else will paste a more straightforward solution!

CountIF within an Array VBA

This should be easy and I think I am almost there. I would like to count how many times an entry repeats itself within a certain array. The array will be populated from a range. Eventually if the number of the count is more than 4, I would like to insert "Excess", otherwise if less than 4, I would like to insert "Insufficient", else is "complete". Unfortunately, even though I have learnt to do these calculations without using Arrays, I find some difficulties when switching to Arrays.
How the code should look like
Sub test()
Dim MyArray() As Variant, Countarrays() As Variant, Result() As Variant
Dim r As Range
Dim rows As Integer
Worksheets("Sheet1").Activate
Set r = Range("B2", Range("B1").End(xlDown))
MyArray = Range("B2", Range("B1").End(xlDown))
rows = Range("B2", Range("B1").End(xlDown)).Count
For i = 0 To rows
For j = 0 To rows
Countarrays(i, 1) = WorksheetFunction.CountIf(r, MyArray(i))
If (Countarrays(i, 1).value) > 4 Then Result(j, 1) = "Excess"
ElseIf (Countarrays(i, 1).value) < 4 Then Result(j, 1) = "Insufficient"
ElseIf (Countarrays(i, 1).value) = 4 Then Result(j, 1) = "Complete"
Next j
Next i
End Sub
This should do the trick:
Option Explicit
Sub Test()
Dim MyArray, DictDuplicates As New Scripting.Dictionary, i As Long
With ThisWorkbook.Sheets("Sheet1") 'change if needed
MyArray = .Range(.Cells(2, 1), .Cells(2, 2).End(xlDown))
For i = LBound(MyArray) To UBound(MyArray) 'loop to store all the items and how many times do they repeat
If Not DictDuplicates.Exists(MyArray(i, 2)) Then 'if doesn't exists will store it
DictDuplicates.Add MyArray(i, 2), 1
Else 'if it does exists will increment its item value
DictDuplicates(MyArray(i, 2)) = DictDuplicates(MyArray(i, 2)) + 1
End If
Next i
For i = LBound(MyArray) To UBound(MyArray) 'loop to give back the result
Select Case DictDuplicates(MyArray(i, 2))
Case Is > 4
MyArray(i, 1) = "Excess"
Case Is = 4
MyArray(i, 1) = "Complete"
Case Is < 4
MyArray(i, 1) = "Insufficient"
End Select
Next i
.Range(.Cells(2, 1), .Cells(2, 2).End(xlDown)) = MyArray
End With
End Sub
Note that for the DictDuplicates to work, you need to check the Microsoft Scripting Runtime library.

vba multiD array to range

I'm having an issue with writing an 4D Array to a range in Excel.
My Array Looks like this:
varArray(0)
- varArray(0)(0) "test01"
- varArray(0)(1) "test02"
- varArray(0)(2) "test03"
- varArray(0)(3) "test04"
varArray(1)
- varArray(1)(0) "test11"
- varArray(1)(1) "test12"
- varArray(1)(2) "test13"
- varArray(1)(3) "test14"
There will be more than only 2 "Items" in the Array in the end but for understanding I displayded 2 of them.
I tried it with transpose but I coudl not Access the subitems
Range("A" & CellIndex) = Application.Transpose(varArray(0,1))
does not work :S
Output should look like this(write in to a range):
A B C D
1 test01 test02 test03 test04
2 test11 test12 test13 test14
Can anyone assist me on this?
You can use Application.Transpose twice. This will output to the worksheet in columns A:D
Sub CreateArray()
Dim varArray As Variant
varArray = Array(Array(1, 2, 3, 4), Array(11, 12, 13, 14))
For i = 0 To 1
ThisWorkbook.Worksheets("Sheet1").Range("A1:D1").Offset(i, 0).Value = Application.Transpose(Application.Transpose(varArray(i)))
Next i
End Sub
Try:
Dim varArray(0 To 1, 0 To 3) As String
varArray(0, 0) = "test01"
varArray(0, 1) = "test02"
varArray(0, 2) = "test03"
varArray(0, 3) = "test04"
varArray(1, 0) = "test11"
varArray(1, 1) = "test12"
varArray(1, 2) = "test13"
varArray(1, 3) = "test14"
Range("A1:D2") = varArray()
Range("F1:G4") = Application.Transpose(varArray())
I think the output you want is simply your array, not your transposed array. However I put the two outputs on the code. Feel free to change the adresses...
Do you want something like this:
Option Explicit
Public Sub TestMe()
Dim varArray As Variant
Dim lCounter As Long
Dim lCounter2 As Long
Dim rngCell As Range
varArray = Array(Array(1, 2, 3, 4), Array(11, 12, 13, 14))
Set rngCell = Cells(1, 1)
For lCounter = LBound(varArray) To UBound(varArray)
For lCounter2 = LBound(varArray(lCounter)) To UBound(varArray(lCounter))
Debug.Print varArray(lCounter)(lCounter2)
rngCell = varArray(lCounter)(lCounter2)
Set rngCell = rngCell.Offset(0, 1)
Next lCounter2
Debug.Print "-----------"
Set rngCell = Cells(rngCell.Row + 1, 1)
Next lCounter
End Sub
The result in the immediate window is this one:
1
2
3
4
-----------
11
12
13
14
-----------
From this output, you can easily come to your desired one.
You're trying to transpose a single item in the array:
Application.Transpose(varArray(0,1))
Also, this array isn't indexed in such a manner. You could have varArray(0)(1), but you don't have varArray(0,1).
Try this:
Dim x as Long
For x = LBound(varArray) To UBound(varArray)
Range("A1").Resize(1, UBound(varArray(x)) + 1).Offset(x) = Application.Transpose(Application.Transpose(varArray(x)))
Next

Why is this locking up? Loop through all rows, perform function on duplicate, delete duplicate row

The code works when I bite off a couple hundred rows at a time, but always hangs somewhere in the middle when I try to run it on 10,000.
What the code does: Looks for duplicate entries in column A, adds the values in columns c, d and e between the two rows, then deletes the original row.
Can anybody think of a more stable way to do this, or point me towards why it might be locking up?
Sub combineDelete ()
Const TEST_COLUMN As String = "A"
Dim i As Long
Dim iLastRow As Long
With ActiveSheet
iLastRow = .Cells(.Rows.Count, TEST_COLUMN).End(xlUp).Row
For i = iLastRow To 2 Step -1
If Cells(i, 1) = Cells(i - 1, 1) Then
s = Cells(i, 3).Value
t = Cells(i - 1, 3).Value
Cells(i - 1, 3) = s + t
u = Cells(i, 4).Value
v = Cells(i - 1, 4).Value
Cells(i - 1, 4) = u + v
w = Cells(i, 5).Value
y = Cells(i - 1, 5).Value
Cells(i - 1, 5) = w + y
Cells(i, 1).EntireRow.Delete
End If
Next i
End With
End Sub
Edit: Here's a link to a sample subset of the data.
Post-edit: Every one of these ideas is effective. Ron Rosenberg's solution below manages to handle it orders of magnitude faster than any solution I tinkered with. Thanks!
Start with this and let us know how things are going afterwards:
Option Explicit
Sub combineDelete()
Const TEST_COLUMN As String = "A"
Dim i As Long
Dim iLastRow As Long
Dim s As Double, t As Double, u As Double
Dim v As Double, w As Double, y As Double
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
.EnableEvents = False
End With
With ActiveSheet
iLastRow = .Cells(.Rows.Count, TEST_COLUMN).End(xlUp).Row
For i = iLastRow To 2 Step -1
If .Cells(i, 1).Value2 = .Cells(i - 1, 1).Value2 Then
s = .Cells(i, 3).Value2
t = .Cells(i - 1, 3).Value2
.Cells(i - 1, 3).Value2 = s + t
u = .Cells(i, 4).Value2
v = .Cells(i - 1, 4).Value2
.Cells(i - 1, 4).Value2 = u + v
w = .Cells(i, 5).Value2
y = .Cells(i - 1, 5).Value2
.Cells(i - 1, 5).Value2 = w + y
.Rows(i).EntireRow.Delete
End If
Next i
End With
With Application
.EnableEvents = True
.Calculation = xlCalculationAutomatic
.ScreenUpdating = True
End With
End Sub
Notes:
Disable screenupdating, calculations and events
Use .Value2 instead of .Value
Explicit coding
Missing references to ActiveSheet added by adding dots .
Dim all variables to avoid variants
Here is a routine that should run quite rapidly. You will note near the top of the code where to change the source and results worksheets if you want.
The work is done within VBA arrays, which will be much faster than working on the worksheet.
I create a User defined object whose properties are the contents of the TestColumn; the Maximum amount in Column B; and an array of the Sum of Columns C, D and E.
These are placed into a Collection object with the Key being the TestColumn. If there is a duplicate, the Collection object will return a 457 error, which we test for and use to combine the rows.
Finally, we write the collection object back to an array, and write that array to the worksheet.
You will use both a Class Module and a Regular Module
The original data does not need to be sorted, but you can if you want, either before or after running this macro.
Enjoy.
Class Module
Be sure to rename this module cCombo after inserting it
Rename this module **cCombo**
Option Explicit
Private pTestColumn As String
Private pMaxColumn As Double
Private pSumColumns(3 To 5) As Variant
Public Property Get TestColumn() As String
TestColumn = pTestColumn
End Property
Public Property Let TestColumn(Value As String)
pTestColumn = Value
End Property
Public Property Get MaxColumn() As Double
MaxColumn = pMaxColumn
End Property
Public Property Let MaxColumn(Value As Double)
pMaxColumn = IIf(pMaxColumn > Value, pMaxColumn, Value)
End Property
Public Property Get SumColumns() As Variant
SumColumns = pSumColumns
End Property
Public Property Let SumColumns(Value As Variant)
Dim I As Long
For I = LBound(Value) To UBound(Value)
pSumColumns(I) = pSumColumns(I) + Value(I)
Next I
End Property
Regular Module
Option Explicit
Sub combineDelete()
Const TEST_COLUMN As String = "A"
Dim vSrc As Variant, vRes As Variant, rRes As Range
Dim wsSrc As Worksheet, wsRes As Worksheet
Dim cC As cCombo, colC As Collection
Dim I As Long, J As Long, V As Variant, S As String
Set wsSrc = Worksheets("sheet1")
Set wsRes = Worksheets("sheet2") 'could be same sheet if you want to overwrite
Set rRes = wsRes.Cells(2, 1)
'Get original data
With wsSrc
vSrc = Range(.Cells(2, TEST_COLUMN), .Cells(.Rows.Count, TEST_COLUMN).End(xlUp)).Resize(columnsize:=5)
End With
ReDim V(3 To UBound(vSrc, 2)) 'for storing rows
'Collect the data, eliminating duplicates
Set colC = New Collection
On Error Resume Next
For I = 1 To UBound(vSrc, 1)
Set cC = New cCombo
With cC
.TestColumn = vSrc(I, 1)
.MaxColumn = vSrc(I, 2)
For J = 3 To UBound(vSrc, 2)
V(J) = vSrc(I, J)
Next J
.SumColumns = V
colC.Add Item:=cC, Key:=.TestColumn
Select Case Err.Number
Case 457
Err.Clear
colC(.TestColumn).MaxColumn = .MaxColumn
colC(.TestColumn).SumColumns = .SumColumns
Case Is <> 0
Debug.Print Err.Number, Err.Description
Stop
End Select
End With
Next I
On Error GoTo 0
'Create results array
ReDim vRes(1 To colC.Count, 1 To 5)
For I = 1 To colC.Count
With colC(I)
vRes(I, 1) = .TestColumn
vRes(I, 2) = .MaxColumn
V = .SumColumns
For J = LBound(V) To UBound(V)
vRes(I, J) = V(J)
Next J
End With
Next I
'Write the results
Set rRes = rRes.Resize(UBound(vRes, 1), UBound(vRes, 2))
With rRes
.EntireColumn.Clear
.Value = vRes
.EntireColumn.ColumnWidth = 5
End With
End Sub
Working with ~10K rows would benefit immensely from a variant array but you can also make significant improvements by deleting all of the rows at once. While you could gather a Union of the rows to delete, a Range.RemoveDuplicates method is also appropriate in this case.
It is unclear on whether your data is sorted on a primary key of column A. Your current code depends upon this but I've changed the criteria check to the Excel Application object's MATCH function to accommodate unsorted data.
Your code appears to avoid text column header labels in row 1. I've used the Range.CurrentRegion property to localize the cells to be processed.
Sub combineDelete()
Const TEST_COLUMN As String = "A"
Dim i As Long, mtch As Long
'appTGGL bTGGL:=False 'uncomment this line once you have completed debugging
With ActiveSheet
With .Cells(1, 1).CurrentRegion
For i = .Rows.Count To 2 Step -1
mtch = Application.Match(.Cells(i, 1).Value, .Columns(1), 0)
If mtch < i Then
.Cells(mtch, 3) = Application.Sum(.Cells(mtch, 3), .Cells(i, 3))
.Cells(mtch, 4) = Application.Sum(.Cells(mtch, 4), .Cells(i, 4))
.Cells(mtch, 5) = Application.Sum(.Cells(mtch, 5), .Cells(i, 5))
End If
Next i
.RemoveDuplicates Columns:=1, Header:=xlYes
End With
End With
appTGGL
End Sub
Public Sub appTGGL(Optional bTGGL As Boolean = True)
With Application
.ScreenUpdating = bTGGL
.EnableEvents = bTGGL
.DisplayAlerts = bTGGL
.Calculation = IIf(bTGGL, xlCalculationAutomatic, xlCalculationManual)
.StatusBar = vbNullString
End With
Debug.Print Timer
End Sub
The use of Application.Sum(..., ...) is a trifle slower than straight addition but it has the benefit of providing error control over text values. This may or may not be a desired behavior; i.e. you might want to know when you are trying to add text to a number instead of skipping over it.
There were many places inside your With ... End With statement where you used Cells(i, 3) and not .Cells(i, 3) (note the prefix . ). If you are going to take the time to reference the Range.Parent property (and you should always do so!) then it seems a shame not to use it.
I've included a reusable 'helper' sub that 'turns off' many application environment states but left it commented. Uncomment it once you havew completed debugging for additional speed and stability.
Addendum for lookup strings with length > 255
Sub combineDelete()
Dim i As Long, mtch As Long
Dim vCOLAs As Variant, dCOLAs As Object
'appTGGL bTGGL:=False 'uncomment this line once you have completed debugging
Set dCOLAs = CreateObject("Scripting.Dictionary")
dCOLAs.CompareMode = vbTextCompare
With ActiveSheet
With .Cells(1, 1).CurrentRegion
'strings in column A may exceed 255 chars; build array and and a dictionary from array
vCOLAs = .Resize(.Rows.Count, 1).Value2
For i = UBound(vCOLAs, 1) To LBound(vCOLAs, 1) Step -1
'fast overwrite method
dCOLAs.Item(vCOLAs(i, 1)) = i
Next i
For i = .Rows.Count To 2 Step -1
mtch = dCOLAs.Item(vCOLAs(i, 1))
If mtch < i Then
.Cells(mtch, 3) = Application.Sum(.Cells(mtch, 3), .Cells(i, 3))
.Cells(mtch, 4) = Application.Sum(.Cells(mtch, 4), .Cells(i, 4))
.Cells(mtch, 5) = Application.Sum(.Cells(mtch, 5), .Cells(i, 5))
End If
Next i
.RemoveDuplicates Columns:=1, Header:=xlYes
End With
End With
Erase vCOLAs
dCOLAs.RemoveAll: Set dCOLAs = Nothing
appTGGL
End Sub
A dictionary object provides lightning fast lookups due to its unique keys. Since these are a variant type, there is no 255 character limit.

Specific referenc on one Array-element in an 2D-Array in VBA

i wanna have a reference on one element in a 2 dimensional Array like this:
dim ary(5,5) as String
ary(1) = "Michael, Thomas, Bill, Mike, Pascal"
ary(2) = "Iphone,HTCOne,SGS4,SGS3"
'... and so on
can i write sth like this:?
For i = 0 To UBound(ary)
activMan = ary(i)
Sheets("Example").Cells(1,1) = activMan(i)
'activMan is now Michael
' so i dont have to use two variables...
End If
Next i
' in the next round activMan is going to be HTCOne
Now activMan should be a reference on ary(i) in the first Dimension and i have access on all the elements in the second dimension.
Is that possilbe or completly wrong?
EDIT:
I'il give out:
1.: Mike -> arr(0,0)
2.: Ipod -> arr(1,1)
3.: .... -> arr(2,2)
But i realized it's possible with only one variable...^^
That is completely wrong :p
Analyse this bud :)
Option Explicit
Sub build2DArray()
' 2D 5 element array
' elements 1st 2nd 3rd 4th 5th
' index 0 [0, 0][1, 0][2, 0][3, 0][4, 0]
' index 1 [0, 1][1, 1][2, 1][3, 1][4, 1]
Dim arr(0 To 5, 0 To 1) as String ' same as Dim arr(5, 1)
arr(0, 0) = "Mike"
arr(1, 0) = "Tom"
arr(2, 0) = "Bill"
arr(3, 0) = "Michael"
arr(4, 0) = "Pascal"
arr(0, 1) = "IPhone"
arr(1, 1) = "Ipod"
arr(2, 1) = "Mac"
arr(3, 1) = "ITunes"
arr(4, 1) = "IArray"
Dim i As Long, j As Long
Dim activeMan As String
For i = LBound(arr) To UBound(arr) - 1
activeMan = arr(i, 0)
Debug.Print "loop no. " & i & " activeMan: " & activeMan
Cells(i + 1, 1).Value = activeMan
Cells(i + 1, 2).Value = arr(i, 1)
Next i
End Sub
Edit: its possible to use types and a custom function to achieve the same result, have a look
Private Type yourType
tName As String
tPhone As String
End Type
Sub example()
Dim yType(3) As yourType
yType(0).tName = "Michael"
yType(0).tPhone = "iPhone"
yType(1).tName = "Tom"
yType(1).tPhone = "Blackberry"
yType(2).tName = "Dave"
yType(2).tPhone = "Samsung"
Dim i&
For i = LBound(yType) To UBound(yType)
Debug.Print get_yType(yType, i)
Next i
End Sub
Private Function get_yType(arr() As yourType, i&) As String
get_yType = arr(i).tName & " " & arr(i).tPhone
End Function

Resources