How to remove error when there is blanks between cells - arrays

Function ArrayRemoveDups(MyArray As Variant) As Variant
Dim nFirst As Long, nLast As Long, i As Long
Dim item As String
' Hello I am trying to remove duplicates from an array as well as ignore blanks. But when i insert blanks inbetween the cells there will be an error
Dim arrTemp() As String
Dim Coll As New Collection
'Get First and Last Array Positions
nFirst = LBound(MyArray)
nLast = UBound(MyArray)
ReDim arrTemp(nFirst To nLast)
'Convert Array to String
For i = nFirst To nLast
arrTemp(i) = CStr(MyArray(i))
Next i
'Populate Temporary Collection
On Error Resume Next
For i = nFirst To nLast
Coll.Add arrTemp(i), arrTemp(i)
Next i
Err.Clear
On Error GoTo 0
'Resize Array
nLast = Coll.Count + nFirst - 1
ReDim arrTemp(nFirst To nLast)
'Populate Array
For i = nFirst To nLast
arrTemp(i) = Coll(i - nFirst + 1)
Next i
'Output Array
ArrayRemoveDups = arrTemp
End Function
Sub ArrTest()
Dim WorkingWS As Worksheet
Set WorkingWS = ActiveSheet
Dim LastActiveCellColumn As Long
LastActiveCellColumn = WorkingWS.UsedRange.Columns.Count
MsgBox LastActiveCellColumn
Dim WorkingRng As Range
Dim strNames(10000) As String
Dim outputArray() As String
Dim i As Long
Dim item As Variant
Dim a As Long
Dim B As Long
a = 0
For Each WorkingRng In WorkingWS.Range(Cells(1, 1), Cells(1, LastActiveCellColumn))
strNames(a) = WorkingRng
a = a + 1
Next
outputArray = ArrayRemoveDups(strNames)
'Output values to Immediate Window (CTRL + G)
a = 0
Do While a < LastActiveCellColumn
If Not outputArray(a) = "" Then
MsgBox outputArray(a)
'carry out action here
End If
a = a + 1
Loop
End Sub

Related

VBA Dictionary to Array for each item per dictionary key

I have a dict made up of multiple items (dates) per key, looks like this
Key Items dates()
23359720 03/12/2020 , 04/12/2020, 05/12/2020
23293711 26/01/2021
How can I transfer each key & item into an array (including repeating keys for multiple items)? so that array:
23359720 03/12/2020
23359720 04/12/2020
... ....
This is the code I have:
Sub Test_Dates()
'
Dim TESTWB As Workbook
Dim TESTWS As Worksheet
Set TESTWB = ThisWorkbook
Set TESTWS = TESTWB.Worksheets("TEST")
Dim Dict As New Scripting.Dictionary
For i = 2 To TESTWS.Cells(1, 1).End(xlDown).Row
Dict.Add TESTWS.Cells(i, 1).Value, getDates(TESTWS.Cells(i, 2), TESTWS.Cells(i, 3))
Next i
For i = 0 To Dict.Count - 1
Dim DateItem As Variant
For Each DateItem In Dict.Items(i)
Debug.Print Dict.Keys(i), DateItem
Next DateItem
Next i
'Dict to Array
Dim PricingDatesArr As Variant
PricingDatesArr = Dict.Keys
PricingDatesArr = Dict.Items
End Sub
This is to get dates between 2 sets of dates (i,2) (i,3) in the code
Function getDates(ByVal StartDate As Date, ByVal EndDate As Date) As Variant
Dim varDates() As Date
Dim lngDateCounter As Long
ReDim varDates(0 To CLng(EndDate) - CLng(StartDate))
For lngDateCounter = LBound(varDates) To UBound(varDates)
varDates(lngDateCounter) = CDate(StartDate)
StartDate = CDate(CDbl(StartDate) + 1)
Next lngDateCounter
getDates = varDates
End Function
This is the third question you have posted in as many days regarding Dictionaries. You might want to take a little time out a read up on Dictionary data structures a bit more.
The code below will return a 1 to n,by 1 to 2 array from a dictionary with arrays of dates.
Option Explicit
Public Function UnpackDictionaryOfArrays(ByRef ipDict As Scripting.DIctionary) As Variant
Dim myKeys As Collection
Set myKeys = New Collection
Dim myItems As Collection
Set myItems = New Collection
Dim myKey As Variant
Dim myItem As Variant
For Each myKey In ipDict
myItem = ipDict(myKey)
If IsArray(myItem) Then
Dim myElement As Variant
For Each myElement In myItems
myKeys.Add myKey
myItems.Add myElement
Next
Else
myKeys.Add myKey
myItems.Add myItem
End If
Next
' Now compile into a single array
Dim myKeyItem As Variant
ReDim myKeyItem(1 To myKeys.Count, 1 To 2)
Dim myIndex As Long
For myIndex = 1 To myKeys.Count
myKeyItem(myIndex, 1) = myKeys(myIndex)
myKeyItem(myIndex, 2) = myItems(myIndex)
Next
UnpackDictionaryOfArrays = myKeyIndex
End Function
Dictionary With Arrays to 2D One-Based Array
' Dict to Array
' Count the number of dates.
Dim Arr As Variant
Dim pCount As Long
For Each Arr In Dict.Items
pCount = pCount + UBound(Arr) - LBound(Arr) + 1
Next Arr
' Resize the array to the number of dates.
Dim PricingDatesArr As Variant: ReDim PricingDatesArr(1 To pCount, 1 To 2)
' Write the data to the array.
Dim Key As Variant
Dim n As Long, r As Long
For Each Key In Dict.Keys
For n = LBound(Dict(Key)) To UBound(Dict(Key))
r = r + 1
PricingDatesArr(r, 1) = Key
PricingDatesArr(r, 2) = Dict(Key)(n)
Next n
Next Key
' Print the elements of the array.
For r = 1 To pCount
Debug.Print PricingDatesArr(r, 1), PricingDatesArr(r, 2)
Next r
' Copy to a range.
'SheetX.Range("A1").Resize(pCount, 2).Value = PricingDatesArr
EDIT: The Function Edition
Usage in Your Code
' Dict to Array
Dim PricingDatesArr As Variant
PricingDatesArr = UnpivotDictionaryArrays(dict)
If IsEmpty(PricingDatesArr) Then Exit Sub
' Print the elements of the array.
For r = 1 To pCount
Debug.Print PricingDatesArr(r, 1), PricingDatesArr(r, 2)
Next r
' Copy to a range.
'SheetX.Range("A1").Resize(pCount, 2).Value = PricingDatesArr
The Function
Function UnpivotDictionaryArrays( _
ByVal dict As Object) _
As Variant
Const ProcName As String = "UnpivotDictionaryArrays"
On Error GoTo ClearError
' Count the items of the source (dictionary) arrays.
Dim Item As Variant
Dim n As Long
For Each Item In dict.Items
n = n + UBound(Item) - LBound(Item) + 1
Next Item
' Write the values from the dictionary to the destination array.
Dim Data As Variant: ReDim Data(1 To n, 1 To 2)
Dim r As Long
For Each Item In dict.Keys
For n = LBound(dict(Item)) To UBound(dict(Item))
r = r + 1: Data(r, 1) = Item: Data(r, 2) = dict(Item)(n)
Next n
Next Item
UnpivotDictionaryArrays = Data
ProcExit:
Exit Function
ClearError:
Debug.Print "'" & ProcName & "' Run-time error '" _
& Err.Number & "':" & vbLf & " " & Err.Description
Resume ProcExit
End Function

Find duplicates in 2D arrays in VBA

I want a cod that will find duplicates and return it in separate array.
So I found a code that would be perfect for me, but the thing is that this code is removing duplicates. I thought that it will be a simple job to change it, but somehow I cannot manage to do it....
I was thinking that it will be in this part of code If Err.Number <> 0 Then coll.Remove txt but have no idea how to change it. I have tried changing <> with = but it seems not to work.
Can someone tell me where and how should I change the code to get duplicates from 2 arrays.
Sub test()
Dim arr1 As Variant
Dim arr2 As Variant
Dim arr3 As Variant
Dim coll As Collection
Dim I As Long, j As Long, ii As Long, txt As String, x
With Worksheets("Sheet1")
LastRowColumnA = .Cells(.Rows.Count, 1).End(xlUp).Row
arr1 = .Range("A2:C" & LastRowColumnA).Value
End With
With Worksheets("Sheet2")
LastRowColumnA = .Cells(.Rows.Count, 1).End(xlUp).Row
arr2 = .Range("A2:C" & LastRowColumnA).Value
End With
Set coll = New Collection
On Error Resume Next
For I = LBound(arr1, 1) To UBound(arr1, 1)
txt = Join(Array(arr1(I, 1), arr1(I, 2), arr1(I, 3)), Chr(2))
coll.Add txt, txt
Next I
For I = LBound(arr2, 1) To UBound(arr2, 1)
txt = Join(Array(arr2(I, 1), arr2(I, 2), arr2(I, 3)), Chr(2))
Err.Clear
coll.Add txt, txt
If Err.Number <> 0 Then coll.Remove txt
Next I
ReDim arr3(1 To coll.Count, 1 To 3)
For I = 1 To coll.Count
x = Split(coll(I), Chr(2))
For ii = 0 To 2
arr3(I, ii + 1) = x(ii)
Next
Next I
Worksheets("test").Range("A2").Resize(UBound(arr3, 1), 3).Value = arr3
Columns("A:C").EntireColumn.AutoFit
End Sub
Regards,
Timonek
Extract Duplicates
If you set CountSameWorksheetDuplicates to True, it will return the duplicates of each worksheet even if they are not found in the other worksheet.
Option Explicit
Sub ExtractDuplicates()
Const sName1 As String = "Sheet1"
Const sCols1 As String = "A:C"
Const sfRow1 As Long = 2
Const sName2 As String = "Sheet2"
Const sCols2 As String = "A:C"
Const sfRow2 As Long = 2
Const dName As String = "Test"
Const dfCellAddress As String = "A2"
Const CountSameWorksheetDuplicates As Boolean = False
Dim Delimiter As String: Delimiter = Chr(2)
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim sData As Variant
sData = RefColumns(wb.Worksheets(sName1).Rows(sfRow1).Columns(sCols1))
Dim cCount As Long: cCount = UBound(sData, 2)
Dim dict As Object: Set dict = CreateObject("Scripting.Dictionary")
dict.CompareMode = vbTextCompare
Dim r As Long
Dim sKey As Variant
For r = 1 To UBound(sData, 1)
sKey = StrJoinedDataRow(sData, r, Delimiter)
If CountSameWorksheetDuplicates Then
DictAddCount dict, sKey
Else
DictAdd dict, sKey, 1
End If
Next r
sData = RefColumns(wb.Worksheets(sName2).Rows(sfRow2).Columns(sCols2))
If CountSameWorksheetDuplicates Then
For r = 1 To UBound(sData, 1)
sKey = StrJoinedDataRow(sData, r, Delimiter)
DictAddCount dict, sKey
Next r
Else
Dim dict2 As Object: Set dict2 = CreateObject("Scripting.Dictionary")
dict2.CompareMode = vbTextCompare
For r = 1 To UBound(sData, 1)
sKey = StrJoinedDataRow(sData, r, Delimiter)
DictAdd dict2, sKey
Next r
For Each sKey In dict2.Keys
DictAddCount dict, sKey
Next sKey
Set dict2 = Nothing
End If
Erase sData
For Each sKey In dict.Keys
If dict(sKey) = 1 Then dict.Remove sKey
Next sKey
Dim drCount As Long: drCount = dict.Count
If drCount = 0 Then Exit Sub
Dim dData As Variant: ReDim dData(1 To drCount, 1 To cCount)
r = 0
Dim c As Long
For Each sKey In dict.Keys
sData = Split(sKey, Delimiter)
r = r + 1
For c = 1 To cCount
dData(r, c) = sData(c - 1)
Next c
Next sKey
Dim drg As Range
Set drg = wb.Worksheets(dName).Range(dfCellAddress).Resize(drCount, cCount)
drg.Value = dData
drg.Resize(drg.Worksheet.Rows.Count - drg.Row - drCount + 1) _
.Offset(drCount).Clear ' clear below
drg.EntireColumn.AutoFit
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Creates a reference to the range from the first row of a range
' ('FirstRowRange') to the row range containing
' the bottom-most non-empty cell in the row's columns.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function RefColumns( _
ByVal FirstRowRange As Range) _
As Range
If FirstRowRange Is Nothing Then Exit Function
With FirstRowRange.Rows(1)
Dim lCell As Range
Set lCell = .Resize(.Worksheet.Rows.Count - .Row + 1) _
.Find("*", , xlFormulas, , xlByRows, xlPrevious)
If lCell Is Nothing Then Exit Function ' empty range
Set RefColumns = .Resize(lCell.Row - .Row + 1)
End With
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Returns the values of a row of a 2D array in a delimited string.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function StrJoinedDataRow( _
ByVal Data As Variant, _
ByVal RowIndex As Long, _
Optional ByVal Delimiter As String = " ") _
As String
Const ProcName As String = "StrJoinedDataRow"
On Error GoTo ClearError
Dim c As Long
Dim cString As String
For c = LBound(Data, 2) To UBound(Data, 2)
cString = cString & CStr(Data(RowIndex, c)) & Delimiter
Next c
StrJoinedDataRow = Left(cString, Len(cString) - Len(Delimiter))
ProcExit:
Exit Function
ClearError:
Debug.Print "'" & ProcName & "' Run-time error '" _
& Err.Number & "':" & vbLf & " " & Err.Description
Resume ProcExit
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Adds a value ('Key') to a key of an existing ('ByRef')
' dictionary ('dict') adding another value ('Item')
' to the key's associated item.
' Remarks: Error and blank values are excluded.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub DictAdd( _
ByRef dict As Object, _
ByVal Key As Variant, _
Optional ByVal Item As Variant = Empty)
If Not IsError(Key) Then
If Len(Key) > 0 Then
dict(Key) = Item
End If
End If
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Adds a value ('Key') to a key of an existing ('ByRef')
' dictionary ('dict') increasing its count being held
' in the key's associated item.
' Remarks: Error and blank values are excluded.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub DictAddCount( _
ByRef dict As Object, _
ByVal Key As Variant)
If Not IsError(Key) Then
If Len(Key) > 0 Then
dict(Key) = dict(Key) + 1
End If
End If
End Sub
Dim Dict as Object
Dict = CreateObject("Scripting.Dictionary")
Dim Line As Object
For Each line in MyArray
On Error Resume Next
Dict.Add(Line, "")
On Error Goto 0
Next
Dictionaries don't allow duplicate keys. We are only setting keys and ignoring the value by not setting it. The dictionary raises an error if the key exists.

Loop through cells in column, store specific value in array

Hey I am a trainee as an IT-Specialist and my trainer gave me a task to complete a macro for excel. (I don't know anything about VBA)
I have to check the cells in a column for the value 1. If there is a 1 I need to store that value in a array.
That's what I did till now.
Sub test()
Dim sht As Worksheet
Dim LastColumn As Long
Dim LastRow As Long
Dim MyArray() As Single
Set sht = ThisWorkbook.Worksheets("Tabelle1")
LastRow = sht.Cells.SpecialCells(xlCellTypeLastCell).Row
MsgBox LastRow
MsgBox Join(MyArray)
End Sub
Sub createArray(x As Variant)
Dim sht As Worksheet
Dim LastRow As Long
Dim tempArray() As String
Dim rowVal As String
Dim MyArray() As Single
Dim i As Integer
Dim j As Integer
Dim rang As Range
Dim arrayEntry As String
Set sht = ThisWorkbook.Worksheets("Tabelle1")
Set rang = sht.Range("A:A") ' // SET RANGE TO LOOK FOR VALUES
LastRow = rang.SpecialCells(xlCellTypeLastCell).Row
arrayEntry = ""
For i = 1 To LastRow
If sht.Cells(i, 1).Value = x Then ' // (i, 1) <---- '1' references column A -
change to numerical column that you want to loop through
If arrayEntry = "" Then
arrayEntry = x
rowVal = i
Else
arrayEntry = arrayEntry & "," & x
rowVal = rowVal & "," & i
End If
End If
Next i
tempArray = Split(arrayEntry, ",")
ReDim MyArray(UBound(tempArray))
For j = 0 To UBound(tempArray)
MyArray(j) = CInt(tempArray(j))
Next j
Erase tempArray
MsgBox LastRow
MsgBox arrayEntry
MsgBox rowVal
MsgBox (UBound(MyArray) + 1)
End Sub
I am unsure if you wanted the value '1' in the array or the row it appears on, swap x with i if you wanted the row number.
Sub TESTFORMULA()
createArray (1)
End Sub

Finding Cells in which all values of fixed array are present

I have an array with fixed values. How can I find cells in Column B that contain all the 'String' values present in array?
Here is my code
With Worksheets("Data")
Dim kwrSets As Variant
.Activate
kwrSets = .Range("B2:B" & Application.WorksheetFunction.Max(2, .Range("A100000").End(xlUp).Row)).Value
For k = LBound(kwrSets) To UBound(kwrSets)
For i = LBound(arr) To UBound(arr)
Delete entire row if all values of arr not found in kwrSets
Next i
Next k
End With
Following is the updated code based on the answer below but it is giving error "Subscript out of range" in inStr line.
Sub Extractor()
Dim ws As Worksheet, wsd As Worksheet
Dim cell As Variant
Dim tmp As Variant
Dim blnFound As Boolean
Dim j As Long, i As Long
Dim kwrSets() As Variant
Dim arr() As String
Set ws = Worksheets("Sheet1")
With ws
.Activate
For Each cell In .Range("A1:A" & .Cells(.Rows.Count, "B").End(xlUp).Row)
If (cell.Offset(0, 2) = 1) Then
tmp = tmp & cell & "|"
End If
Next cell
If Len(tmp) > 0 Then tmp = Left(tmp, Len(tmp) - 1)
arr = Split(tmp, "|")
End With
Set wsd = Worksheets("Data")
With wsd
.Activate
kwrSets = .Range("B2:B" & Application.WorksheetFunction.Max(2, .Range("A100000").End(xlUp).Row)).Value
For k = LBound(kwrSets) To UBound(kwrSets)
blnFound = True
For i = LBound(arr) To UBound(arr)
If InStr(kwrSets(j, 1), arr(i)) = 0 Then
blnFound = False
Exit For
End If
Next i
Next k
End With
End Sub
Below is some VBA code that gets all of the data in column B into an array, then loops this array checking for the existence of each of the elements in the search array. If any of the search elements are not found, then it exits that loop. If all elements are found then it highlights the cell.
Sub sFindArray()
Dim ws As Worksheet
Dim aSearch() As Variant
Dim aData() As Variant
Dim lngLoop1 As Long
Dim lngLoop2 As Long
Dim lngFirstRow As Long
Dim lngLastRow As Long
Dim lngLBound As Long
Dim lngUBound As Long
Dim blnFound As Boolean
aSearch = Array("a", "b", "c")
lngLBound = LBound(aSearch)
lngUBound = UBound(aSearch)
Set ws = Worksheets("Sheet1")
lngLastRow = ws.Cells(ws.Rows.Count, "B").End(xlUp).Row
aData() = ws.Range("B1:B" & lngLastRow)
lngFirstRow = LBound(aData, 1)
lngLastRow = UBound(aData, 1)
For lngLoop1 = lngFirstRow To lngLastRow
blnFound = True
For lngLoop2 = lngLBound To lngUBound
If InStr(aData(lngLoop1, 1), aSearch(lngLoop2)) = 0 Then
blnFound = False
Exit For
End If
Next lngLoop2
If blnFound = True Then
ws.Cells(lngLoop1, 2).Interior.Color = vbRed
End If
Next lngLoop1
End Sub
Regards,

How to extract data from Array in Dictionary?

I'm trying to get a grasp of the VBA Dictionary.
I believe I have succeeded into storing the text of multiple cells into an array into the dictionary. But I can't find any way to get it out of there.
End goal is the ability to add multiple sources into 1 dictionary and then extract them by key or item or all at once into a new tab.
Here is the code I'm working on:
Sub tutorial_dictionary_Select()
'Must add reference to Tools > References > Microsoft Scripting Runtime
Dim dict As New Dictionary
dict.CompareMode = CompareMethod.TextCompare
Dim source As Worksheet
Set source = ActiveSheet
Dim last_row As Long
last_row = Cells(Rows.Count, 1).End(xlUp).Row
Dim last_col As Long
last_col = ActiveSheet.UsedRange.Columns.Count
Dim i As Long, n As Long
Dim hasHeader As Boolean
Dim arr(0 To 99) As Variant
If IsNumeric(Range("B1").Value) Or IsNumeric(Range("C1").Value) Then
i = 0
Else
hasHeader = True
i = 1
n = 1
For Each rngCell In Range(Cells(1, 2), Cells(1, last_col))
arr(n) = rngCell.Text
'MsgBox arr(n)
Range("I" & n) = arr(n)
Range("J" & n) = n
n = n + 1
Next rngCell
End If
Dim strVal As String
Dim Item(0 To 99) As Variant
Dim header As Range
Dim rng As Range
Dim rngTemp As Range
For Each rngCell In Range(Cells(1 + i, 1), Cells(last_row, 1))
i = i + 1
strVal = rngCell.Text
If Not dict.Exists(strVal) Then
n = 0
For Each headerCell In Range(Cells(i, 2), Cells(i, last_col))
n = n + 1
Item(n) = headerCell.Text
MsgBox headerCell.Text
Next headerCell
dict(strVal) = Item
Else
MsgBox "already exists"
End If
Next rngCell
sFruit = InputBox("Check value of key")
MsgBox "The value of " & sFruit & " is " & dict(sFruit)
The message box gives a type mismatch and I feel like I've tried everything to get those values either put in a cell or debugged and I'm clueless.
As you can see, the code it totally flexible checking for height and width (and a header). And it generates the correct items and their position in the array on the right:
https://i.imgur.com/5Ba6jaN.png
Yes!! That did the trick! I've been stuck on this for days, thank you so much.
Could you maybe elaborate what this code does? The script will run without the first line, but not without the second.
ar = Array()
ReDim ar(lastCol)
In case a key already exists, I want to add the amounts of the 2nd entry to what was already stored in the dictionary. I was able to figure this out myself:
Dim ws As Worksheet
Set ws = ActiveSheet
Dim dict As New Dictionary
Set dict = New Dictionary
dict.CompareMode = TextCompare
Dim lastRow As Long
lastRow = ws.Cells(Rows.Count, 1).End(xlUp).Row
Dim lastCol As Long
lastCol = ws.UsedRange.Columns.Count
Dim i As Integer
Dim startRow As Long
startRow = 2
Dim ar As Variant
Dim sKey As String
For iRow = startRow To lastRow
sKey = ws.Cells(iRow, 1).Text
If Not dict.Exists(sKey) Then
ar = Array()
ReDim ar(lastCol)
For i = 2 To lastCol
ar(i) = ws.Cells(iRow, i)
Next
dict(sKey) = ar
Else
ar = dict(sKey)
For i = 2 To lastCol
ar(i) = ar(i) + ws.Cells(iRow, i)
Next
End If
Next
Is this the right way to do it? I expected to do something like dict(sKey)(3) = dict(sKey)(3) + ws.Cells(iRow, 3) but that didn't work.
You can't assign the same array to every key in the dictionary, you have to create a new one each time.
Sub tutorial_dictionary_Select()
'Must add reference to Tools > References > Microsoft Scripting Runtime
Dim dict As New Dictionary
dict.CompareMode = CompareMethod.TextCompare
Dim wb As Workbook, ws As Worksheet
Set wb = ThisWorkbook
Set ws = wb.ActiveSheet
Dim last_row As Long, last_col As Long, start_row As Long
Dim hasHeader As Boolean, i As Integer, iRow As Long
last_row = ws.Cells(Rows.Count, 1).End(xlUp).Row
last_col = ws.Range("A1").CurrentRegion.Columns.Count
Debug.Print "last_col", last_col
' check for header
hasHeader = True
start_row = 2
For i = 2 To last_col
If IsNumeric(ws.Cells(1, i)) Then
hasHeader = False
start_row = 1
End If
Next
Dim ar As Variant, sKey As String
For iRow = start_row To last_row
sKey = ws.Cells(iRow, 1).Text
If Not dict.Exists(sKey) Then
ar = Array()
ReDim ar(last_col)
For i = 2 To last_col
ar(i) = ws.Cells(iRow, i)
Next
dict(sKey) = ar
End If
Next
Dim sFruit As String
sFruit = InputBox("Check value of key")
MsgBox "The value of " & sFruit & " is " & dict(sFruit)(3)
End Sub
Okay I've been trying to store my item + properties into an array and then multiple items in an array in a dictionary if that makes sense.
Dim ws As Worksheet
Set ws = ActiveSheet
Dim dict As New Dictionary
Set dict = New Dictionary
dict.CompareMode = TextCompare
Dim lastRow As Long
lastRow = ws.Cells(Rows.Count, 1).End(xlUp).Row
Dim lastCol As Long
lastCol = ws.UsedRange.Columns.Count
Dim i As Long, u As Long
Dim startRow As Long
startRow = 2
Dim ar As Variant, items As Variant, item As Variant
Dim sKey As String
Dim itemAdded As Boolean
For iRow = startRow To lastRow
sKey = ws.Cells(iRow, 1).Text
item = ws.Cells(iRow, 2).Text
If Not dict.Exists(sKey) Then
MsgBox "adding new customer"
items = Array()
ReDim items(99)
ar = Array()
ReDim ar(lastCol)
'--------------------
For i = 2 To lastCol
ar(i) = ws.Cells(iRow, i)
Next
items(0) = ar
dict(sKey) = items
Else
MsgBox "customer already exists"
items = dict(sKey)
For u = LBound(items) To UBound(items)
If item = items(u)(2) Then
MsgBox "item already exists"
ar = items(u)
For i = 3 To lastCol
ar(i) = ar(i) + ws.Cells(iRow, i)
Next
items(u) = ar
dict(sKey) = items
itemAdded = True
End If
Next
If Not itemAdded = True Then
MsgBox "adding new item"
For i = 2 To lastCol
ar(i) = ws.Cells(iRow, i)
Next
items(u) = ar
dict(sKey) = items
End If
End If
Next
What is working is that I can recall Items(u)(2) and see the name of an item. But the If item = items(u)(2) Then statement is giving me a type mismatch even though it passes as true on the first loop, why? I tried declaring as String and as Variant but neither combination is working.
https://imgur.com/4eKak8q

Resources