VBA: replacing array elements - arrays

Edit: based on the comments, I'm providing more details on the code.
The idea of the code is:
There are strings stored in a range B6:E6 (e.g. B6 = "Actual Sales", C6 = "SOP11 (2015)", D6 = "SOP12 (2015)", E6 = "SOP10 (2015)").
I calculate the integer by using "Mid" function if the string is not "Actual Sales".
When that's done, the calculated integers are sorted using BubbleSort in array.
Afterwards, I would like to link the sorted integers (SOP_key_B6, SOP_key_C6, SOP_key_D6, SOP_key_E6) with the original string (cell_b6, cell_c6, cell_d6, cell_e6). In other words, there's a one-to-one correspondence between SOP_key_B6 and cell_b6, etc.)
I want to do the above, because I need to input to the range L30:O30 the sorted array with strings based on the sorted integers.
I hope this makes the idea clear as it's not very complicated, but the approach itself & code makes it a bit frustrating (probably because I'm still learning the VB coding).
Here's the code:
Sub Worksheet_Delta_Update()
'Variables
Dim wb As Workbook, ws_wk_dlt As Worksheet, ws_dash As Worksheet, cell_B6 As Variant, _
cell_C6 As Variant, cell_D6 As Variant, cell_E6 As Variant, SOP_key_B6 As Variant, _
SOP_key_C6 As Variant, SOP_key_D6 As Variant, SOP_key_E6 As Variant
'Referencing
Set wb = ThisWorkbook
Set ws_wk_dlt = wb.Worksheets("t")
Set ws_dash = wb.Worksheets("x")
'Values from pivot stored
cell_B6 = ws_wk_dlt.Range("B6").Value
cell_C6 = ws_wk_dlt.Range("C6").Value
cell_D6 = ws_wk_dlt.Range("D6").Value
cell_E6 = ws_wk_dlt.Range("E6").Value
'If len certain amount of characters then do option 1, or option 2
If cell_B6 <> "" Then
If Len(cell_B6) = 12 And cell_B6 <> "Actual Sales" Then
SOP_key_B6 = CInt(Mid(cell_B6, 4, 2)) + CInt(Mid(cell_B6, 8, 4))
ElseIf Len(cell_B6) = 11 And cell_B6 <> "Actual Sales" Then
SOP_key_B6 = CInt(Mid(cell_B6, 4, 2)) + CInt(Mid(cell_B6, 7, 4))
End If
End If
If cell_C6 <> "" Then
If Len(cell_C6) = 12 And cell_C6 <> "Actual Sales" Then
SOP_key_C6 = CInt(Mid(cell_C6, 4, 2)) + CInt(Mid(cell_C6, 8, 4))
ElseIf Len(cell_C6) = 11 And cell_C6 <> "Actual Sales" Then
SOP_key_C6 = CInt(Mid(cell_C6, 4, 2)) + CInt(Mid(cell_C6, 7, 4))
End If
End If
If cell_D6 <> "" Then
If Len(cell_D6) = 12 And cell_D6 <> "Actual Sales" Then
SOP_key_D6 = CInt(Mid(cell_D6, 4, 2)) + CInt(Mid(cell_D6, 8, 4))
ElseIf Len(cell_D6) = 11 And cell_D6 <> "Actual Sales" Then
SOP_key_D6 = CInt(Mid(cell_D6, 4, 2)) + CInt(Mid(cell_D6, 7, 4))
End If
End If
If cell_E6 <> "" Then
If Len(cell_E6) = 12 And cell_E6 <> "Actual Sales" Then
SOP_key_E6 = CInt(Mid(cell_E6, 4, 2)) + CInt(Mid(cell_E6, 8, 4))
ElseIf Len(cell_E6) = 11 And cell_E6 <> "Actual Sales" Then
SOP_key_E6 = CInt(Mid(cell_E6, 4, 2)) + CInt(Mid(cell_E6, 7, 4))
End If
End If
'Finding the Actual Sales and putting into L30
If cell_B6 = "Actual Sales" Then
ws_dash.Range("L31").Value = cell_B6
ElseIf cell_C6 = "Actual Sales" Then
ws_dash.Range("L31").Value = cell_C6
ElseIf cell_D6 = "Actual Sales" Then
ws_dash.Range("L31").Value = cell_D6
ElseIf cell_E6 = "Actual Sales" Then
ws_dash.Range("L31").Value = cell_E6
End If
'BubbleSort in Descending order
Dim ArrayToSort(0 To 4) As Variant
ArrayToSort(0) = SOP_key_B6
ArrayToSort(1) = SOP_key_C6
ArrayToSort(2) = SOP_key_D6
ArrayToSort(3) = SOP_key_E6
'Moving upwards because of -1
For j = UBound(ArrayToSort) - 1 To LBound(ArrayToSort) Step -1
'Starting at lowest
For i = LBound(ArrayToSort) To j
If ArrayToSort(i) > ArrayToSort(i + 1) Then
vTemp = ArrayToSort(i)
ArrayToSort(i) = ArrayToSort(i + 1)
ArrayToSort(i + 1) = vTemp
End If
Next i
Next j
'Put sorted array into the range
'But how to put the values linked to integers?
'E.g. SOP_key_B6 = cell_B6
ws_dash.Range("L30:O30").Value = ArrayToSort
End Sub
Most probably the solution is with replacing the array elements with the correct ones (i.e. SOP_key_B6 = cell_B6, etc.)?

Your code is bloated in places, for example:
Dim ArrayToSort(0 To 4) As Variant
ArrayToSort(0) = SOP_key_B6
ArrayToSort(1) = SOP_key_C6
ArrayToSort(2) = SOP_key_D6
ArrayToSort(3) = SOP_key_E6
can be replaced by
Dim ArrayToSort As Variant 'note lack of ()
ArrayToSort = Array(SOP_key_B6, SOP_key_C6, SOP_key_D6, SOP_key_E6)
As far as your question goes, it seems that you need to use a collection. Assuming that there is a one-to-one correspondence between the SOP-key_ values and the cell_ values (otherwise, calling them "keys" is misleading), you could do the following:
Dim C As New Collection
C.Add cell_B6, CStr(SOP_key_B6)
C.Add cell_C6, CStr(SOP_key_C6)
C.Add cell_D6, CStr(SOP_key_D6)
C.Add cell_E6, CStr(SOP_key_E6)
then, after sorting ArrayToSort, have a loop like:
For i = 0 to 3
Range("L30").Offset(0,i).Value = C(CStr(ArrayToSort(i)))
Next i
I think this is what you are looking for -- but the code seems on the convoluted side so it might not be a bad idea to streamline it a bit.
On Edit:
You are getting duplicate keys due to the way you are constructing the keys by adding note that SOP11(2015) differs from SOP10(2016) but 11+2015 = 10 + 2016 (both equal to 2026). Instead -- juxtapose: 112015 isn't 102016.
Furthermore, it makes sense to split the key creation into its own function (so you don't repeat essentially the same code 4 times:
Function ExtractKey(s As Variant) As Long
Dim v As Variant, n As Long
v = Trim(s)
If v Like "*(*)" Then
n = Len(v)
v = Mid(v, n - 7, 7)
v = Replace(v, "(", "")
ExtractKey = CLng(v)
Else
ExtractKey = 0
End If
End Function
Note that the return type is Long -- Integer variables overflow too easily to be useful in VBA.
Then -- something like this should work:
Sub Worksheet_Delta_Update()
Dim SourceRange As Range, TargetRange As Range
Dim i As Long, j As Long, minKey As Long, minAt As Long
Dim v As Variant
Dim C As New Collection
Set SourceRange = Worksheets("t").Range("B6:E6")
Set TargetRange = Worksheets("t").Range("L30:O30")
For i = 1 To 4
v = SourceRange.Cells(1, i).Value
C.Add Array(ExtractKey(v), v)
Next i
'transfer data
For i = 1 To 4
minAt = -1
For j = 1 To C.Count
If minAt = -1 Or C(j)(0) < minKey Then
minKey = C(j)(0)
minAt = j
End If
Next j
TargetRange.Cells(1, i).Value = C(minAt)(1)
C.Remove minAt
Next i
End Sub

On fixed the Type mismatch error with the following modificaton:
Function ExtractKey(s As Variant) As Long
Dim v As Variant, n As Long
v = Trim(s) 'remove spaces leave only spaces between words
If v Like "*(*)" Then 'if it's SOPXX (YYYY) then
n = Len(v) 'find number of the characters
If n = 11 Then
v = Mid(v, n - 7, 7) 'find the number of SOP + year in bracket
ElseIf n = 12 Then
v = Mid(v, n - 8, 8)
End If
v = Replace(v, "(", "") 'replace the brackets with nothing
v = Replace(v, " ", "")
ExtractKey = CLng(v) 'error WAS here
Else
ExtractKey = 0
End If
End Function
Edit:
Added another few lines
If n = 11 Then
v = Right(v, 4) + Left(v, 1)
ElseIf n = 12 Then
v = Right(v, 4) + Left(v, 2)
End If
The above switch year and number (e.g. SOP12 (2015) = 122015 and after switch 201512). This is because SOP12 (2014) was placed after SOP10 (2015) despite the fact it should go before as its dated year 2014. Now working like charm :)

Related

Print multi dimensional array onto excel sheet VBA

I'm trying to have a for loop that takes my weeks and then another for loop that looks at my product to calculate the sales for this year, last year and then the difference. I am getting 0's for all of the weeks except for the current week, any idea what is wrong with my code? Thanks
Sub Weekly_Recap()
Dim h, d As Worksheet
Dim myarray(), answers() As Variant
'Dim week, datarange As Range
Dim D1, i As Long
Set h = Worksheets("Helper")
Set d = Worksheets("Data")
myarray = d.Range("P2:P51")
D1 = UBound(myarray, 1)
ReDim answers(1 To D1, 1 To 3)
For i = 1 To D1
If myarray(i, 1) <= h.Range("A1") Then
For j = 1 To 17
answers(i, 1) = Application.WorksheetFunction.SumIfs(d.Range("G:G"), d.Range("B:B"), myarray(i, 1), d.Range("F:F"), h.Cells(j, 4))
answers(i, 2) = Application.WorksheetFunction.SumIfs(d.Range("H:H"), d.Range("B:B"), myarray(i, 1), d.Range("F:F"), h.Cells(j, 4))
answers(i, 3) = (answers(i, 1) - answers(1, 2)) / answers(i, 2)
If h.Cells(j, 4) = "FLAVORED/FUNCTIONAL WATER" Then
h.Range(h.Range("F2"), h.Range("F2").Offset(D1, 2)).Value = answers
ElseIf h.Cells(j, 4) = "SALTY BAGGED/CANISTER SNACKS" Then
h.Range(h.Range("K2"), h.Range("K2").Offset(D1, 2)).Value = answers
End If
Next j
End If
Next i
End Sub
Kinda hard to understand what you are trying to do. When I tried to run your code in debug mode I noticed that line with offset is overwriting data in previous lines, and that is where you are getting all 0's. In lets say loop i = 1 and j = 1 you get some value, but in i = 1 and j = 2 you don't (sumif returns 0) and then you overwrite it in variable answers and then paste it in worksheet, at the end only last one has not been overwritten.
You need swap the loops to calculate all the weeks for each product in turn otherwise the figure for week1/product1 will be overwritten by week1/product2 then week1/product3 etc.
Option Explicit
Sub Sales()
Dim arWeeks, NoOfWeeks As Long, iLastWeek As Long
Dim rngSales1 As Range, rngSales2 As Range
Dim rngWeek As Range, rngProduct As Range
Dim iWeek As Long, sProduct As String
Dim h As Worksheet, d As Worksheet
Dim j As Long, i As Long
Set h = Worksheets("Helper")
Set d = Worksheets("Data")
Set rngSales1 = d.Range("G:G")
Set rngSales2 = d.Range("H:H")
Set rngWeek = d.Range("B:B")
Set rngProduct = d.Range("F:F")
arWeeks = d.Range("P2:P51")
iLastWeek = h.Range("A1").Value
NoOfWeeks = UBound(arWeeks)
ReDim answers(1 To NoOfWeeks, 1 To 3) 'yr1,yr2,diff
For j = 1 To 17 ' products
sProduct = h.Cells(j, 4)
For i = 1 To NoOfWeeks ' weeks
iWeek = arWeeks(i, 1)
If iWeek <= iLastWeek Then
With Application.WorksheetFunction
answers(i, 1) = .SumIfs(rngSales1, rngWeek, iWeek, rngProduct, sProduct)
answers(i, 2) = .SumIfs(rngSales2, rngWeek, iWeek, rngProduct, sProduct)
End With
If answers(i, 2) <> 0 Then
answers(i, 3) = (answers(i, 1) - answers(1, 2)) / answers(i, 2)
End If
End If
Next i
If sProduct = "FLAVORED/FUNCTIONAL WATER" Then
h.Range("F2").Resize(NoOfWeeks, 3).Value = answers
ElseIf sProduct = "SALTY BAGGED/CANISTER SNACKS" Then
h.Range("k2").Resize(NoOfWeeks, 3).Value = answers
End If
Next j
MsgBox "Done ", vbInformation
End Sub

Speeding up Loop / Match - Code runs very slow

I have a code that matches a cell value in Column C on Sheet1 to a pivot table on Sheet3 and then copies certain columns over.
Code will check how many entries there are on Sheet1 that need to be checked
Loop 2: For every value in Column C/Sheet1 with a match in Column A on Sheet 2 it will then copy over the corresponding data from Column B,C,D,E.
Since there are multiple matches possible by value/Sheet I am limiting the data pull to three matches (three loops in the code). To achieve that I am increasing i +1 or i+2 to get the next row in the pivot table.
The table on Sheet 2 is sometimes 10,000+ rows and excel crashes.
Does anyone have an idea how to speed up the loop codes (Loop2,3,4 are the same) to make it less work intensive e.g. array possibly? They are causing the lock up since I think the code keeps running up and down column A.
Set sheet3 = Sheets("OrbitPivotTable")
CellChanged = Sheet1.Range("A1").Value + 1
LastRow = sheet3.Cells(Rows.Count, "A").End(xlUp).Row
LastData = Sheet1.Cells(Rows.Count, "C").End(xlUp).Row
'Loop1
For i = 1 To LastRow
If Sheet1.Range("C" & CellChanged).Value = "" Then GoTo Nextstep2
If Sheet1.Range("C" & CellChanged).Value = sheet3.Range("A" & i) Then
Sheet1.Range("H" & CellChanged).Value = sheet3.Range("B" & i).Value 'Customer
Sheet1.Range("I" & CellChanged).Value = sheet3.Range("C" & i).Value 'Rate Val start
Sheet1.Range("J" & CellChanged).Value = sheet3.Range("D" & i).Value 'ATA All in
Sheet1.Range("K" & CellChanged).Value = sheet3.Range("E" & i).Value 'Special Remarks
Found = True
End If
If Found = True Or i = LastRow Then
If CellChanged = LastData Then
Exit For
End If
If Found = True Then
Found = False
Nextstep2:
CellChanged = CellChanged + 1
End If
i = 0
End If
Next i
'Loop2
etc....
Excel File
I might have misunderstood the process in the file you shared, but this should be faster (and much less code overall).
I put the pivot table lookup in a loop, switched to Match(), and reduced the number of read/writes using arrays where possible.
EDITED to fix an embarrassing bug where I forgot to adjust the Match() result m to account for the starting row of the range I run match() against...
Sub HB_IPT_Rate_Check()
Dim wsReport As Worksheet, wsCPK As Worksheet, wsOrbitPivot As Worksheet
Dim c As Range, rwReport As Range, lastPivotRow As Long
Dim ata, m, numMatches As Long, matchFrom As Long, matchRow As Long
Set wsReport = ThisWorkbook.Worksheets("Comparison Report")
Set wsCPK = ThisWorkbook.Worksheets("CPK")
Set wsOrbitPivot = ThisWorkbook.Worksheets("OrbitPivotTable")
'loop over the rows in the report sheet
For Each c In wsReport.Range("C3", wsReport.Cells(Rows.Count, "C").End(xlUp)).Cells
ata = c.Value 'read this once....
Set rwReport = c.EntireRow
'1st Database Match "CPK"
m = Application.Match(ata, wsCPK.Columns("A"), 0)
If Not IsError(m) Then
With wsCPK.Rows(m)
rwReport.Columns("D").Resize(1, 4).Value = _
Array(.Columns("B").Value, .Columns("C").Value, _
.Columns("F").Value, .Columns("H").Value)
'Sum of HB CWGT (KG),Sum of MB CWGT (KG),Achiev CPK,Density
End With
Else
'no match...
End If
'2nd Database Match "Orbit"
lastPivotRow = wsOrbitPivot.Cells(Rows.Count, "A").End(xlUp).Row
numMatches = 0 'reset match count
matchFrom = 2
m = Application.Match(ata, wsOrbitPivot.Range("A" & matchFrom & ":A" & lastPivotRow), 0)
'keep going while we still have a match and we've not reached the max result count
Do While Not IsError(m) And numMatches < 3
numMatches = numMatches + 1
matchRow = matchFrom + (m - 1) 'adjust the matched row index according to where we started looking...
'sanity check
Debug.Print "Matched " & ata & " on row " & matchRow
rwReport.Columns("H").Offset(0, (numMatches - 1) * 4).Resize(1, 4).Value = _
wsOrbitPivot.Cells(matchRow, "B").Resize(1, 4).Value
'find the next match if any, starting below the last match
matchFrom = matchRow + 1
m = Application.Match(ata, wsOrbitPivot.Range("A" & matchFrom & ":A" & lastPivotRow), 0)
Loop
Next c 'next report row
End Sub
Use Dictionary to set row and column number.
Data is assigned to fit rows and columns in a virtual array.
Sub test()
Dim Ws(1 To 4) As Worksheet
Dim DicR As Object ' Dictionary
Dim DicC As Object ' Dictionary
Dim vDB, arr()
Dim s As String
Dim i As Long, n As Long, j As Integer
Dim r As Long, c As Integer
Set Ws(1) = Sheets("Comparison Report")
Set Ws(2) = Sheets("CPK")
Set Ws(3) = Sheets("OrbitPivotTable")
Set Ws(4) = Sheets("Orbit")
'Row index dictionary
Set DicR = CreateObject("Scripting.Dictionary") 'New Scripting.Dictionary
'Column index dictionary
Set DicC = CreateObject("Scripting.Dictionary") ' New Scripting.Dictionary
vDB = Ws(1).UsedRange
For i = 3 To UBound(vDB, 1)
s = vDB(i, 3)
If s <> "" Then
If DicR.Exists(s) Then
'DicC(s) = DicC(s) + 1
Else
n = n + 1
DicR.Add s, n 'row index
DicC.Add s, 0 'column index
End If
End If
Next i
'Create an array of virtual tables based on the number of dictionaries.
'Since the number of columns cannot be predicted, a specific number of 1000 was entered.
'in my test, number 100 is too small
ReDim arr(1 To DicR.Count, 1 To 1000)
For j = 2 To 4
vDB = Ws(j).Range("a1").CurrentRegion
For i = 2 To UBound(vDB, 1)
s = vDB(i, 1)
If DicR.Exists(s) Then
r = DicR(s)
c = DicC(s) * 4 + 1
DicC(s) = DicC(s) + 1
arr(r, c) = vDB(i, 2)
arr(r, c + 1) = vDB(i, 3)
arr(r, c + 2) = vDB(i, 4)
arr(r, c + 3) = vDB(i, 5)
End If
Next i
Next j
With Ws(1)
.Range("d3").Resize(UBound(arr, 1), UBound(arr, 2)) = arr
End With
End Sub
Result image

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.

MS Access VBA loop stops without error or apparent cause

I'm trying to compare two arrays of data in MS Access - one is generated from an API GET, and the other is generated from two columns of a table. I'm using a double loop to do the comparison, I suspect this isn't the best way but I'm still learning my way around loops and arrays. The code I'm using is as follows:
Sub ParseList(ResCount As Long)
Dim db As DAO.Database
Dim rstConts As DAO.Recordset
Dim midstr As String, emailstr As String, Fname As String, Lname As String, SubStatus As String, echeck As String, Mecheck As String, ArrEcheck As String, ArrMecheck As String, MSub As String
Dim ArrResp() As String
Dim ArrConts() As Variant
Dim SubStart As Long, SubCount As Long, Fstart As Long, Fcount As Long, Lstart As Long, LCount As Long, Diffcount As Long, c As Long, i As Long, t As Long, y As Long, u As Long, v As Long
Dim IsSub As Boolean
Set db = CurrentDb
Udate = SQLDate(Now)
ReDim ArrResp(1 To ResCount, 1 To 4) As String
'This section parses a JSON response into an array
For i = 1 To ResCount
midstr = ""
emailstr = ""
x = InStr(t + 2, GetListStr, "}}") + 21
y = InStr(x + 1, GetListStr, "}}")
If y = 0 Then
Exit Sub
End If
midstr = Mid(GetListStr, x, y - x)
emailstr = Left(midstr, InStr(midstr, ",") - 2)
SubStart = InStr(midstr, "Status") + 9
SubCount = InStr(InStr(midstr, "Status") + 8, midstr, ",") - SubStart - 1
SubStatus = Replace(Mid(midstr, SubStart, SubCount), "'", "''")
Fstart = InStr(midstr, ":{") + 11
Fcount = InStr(InStr(midstr, ":{") + 11, midstr, ",") - (Fstart + 1)
Fname = Replace(Mid(midstr, Fstart, Fcount), "'", "''")
Lstart = InStr(midstr, "LNAME") + 8
LCount = InStr(InStr(midstr, "LNAME") + 8, midstr, ",") - (Lstart + 1)
Lname = Replace(Mid(midstr, Lstart, LCount), "'", "''")
If SubStatus = "subscribed" Then
MSub = "True"
Else
MSub = "False"
End If
ArrResp(i, 1) = emailstr
ArrResp(i, 2) = MSub
ArrResp(i, 3) = Fname
ArrResp(i, 4) = Lname
t = y
Next i
'This section grabs two columns from a database table and adds them to a second array
Set rstConts = CurrentDb.OpenRecordset("SELECT Primary_Email, EMailings FROM TBLContacts")
rstConts.MoveLast
rstConts.MoveFirst
c = rstConts.RecordCount
ReDim ArrConts(1 To c) As Variant
ArrConts = rstConts.GetRows(c)
'This loops through the JSON response array, and when it finds a matching value in the Table array it checks if a second value in the table array matches or not
For u = 1 To ResCount
Debug.Print u
echeck = ArrResp(u, 1)
Mecheck = ArrResp(u, 2)
For v = 0 To c
If ArrConts(0, v) = "" Then
Else
ArrEcheck = ArrConts(0, v)
ArrMecheck = ArrConts(1, v)
If ArrEcheck = echeck Then
If ArrMecheck = Mecheck Then
Debug.Print echeck & "Match"
Else
Debug.Print echeck & "No Match"
End If
End If
End If
Next v
Next u
MsgBox "Done"
End Sub
The code above simply doesn't complete and the msgbox is never shown. The debug.print line near the end only goes to 1, and I can't figure out why. If I remove the conditions from the second loop section:
If ArrConts(0, v) = "" Then
Else
ArrEcheck = ArrConts(0, v)
ArrMecheck = ArrConts(1, v)
If ArrEcheck = echeck Then
If ArrMecheck = Mecheck Then
Debug.Print echeck & "Match"
Else
Debug.Print echeck & "No Match"
End If
End If
End If
Then I can successfully complete the Main loop, and receive the 'Done' message. But I've been unable to narrow down why the second loop isn't completing properly, and I'm stuck.
Because arrays are zero-indexed, you need to subtract 1 from the upper limit of nested For loop which should have thrown an error on the subsequent If line when loop exceeded the record limit.
For u = 1 To ResCount
Debug.Print u
echeck = ArrResp(u, 1)
Mecheck = ArrResp(u, 2)
For v = 0 To c - 1 ' REDUCE UPPER LIMIT BY 1
If ArrConts(0, v) = "" Then ' LINE NO LONGER SHOULD ERR OUT
...
Next v
Next u
With that said, consider parsing JSON to an MS Access table using the VBA-JSON library. Then use SQL to check values with JOIN and WHERE in set-based processing between table to table. This is much more efficient that looping between arrays.

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

Resources