0

I'm creating a program that searches a table (~8,500) rows and gets a corresponding value. To do this, I created a Dictionary that holds the "Key" and its corresponding "Value" for that big table. In another Dictionary, I am storing ~330 keys that I need to find the values of in the big table. I then compare the keys and values of the two dictionaries to set the values of the 330ish keys. The code is below:

'Create new HashMap to store part numbers
 Dim partsDict As New Scripting.Dictionary

Sub Main()

    Dim apparatus As String
    Dim facility As String

    'Get selected Apparatus and facility
     apparatus = getApparatus()
     facility = getFacility()

     'Call method to add part numbers to partsDict
     addPartNumbersToDict

    'Call method to add part counts from database to partsDict
     addCountsFromDatabaseToDict apparatus, facility

End Sub

Function getApparatus() As String

    Sheets("Results").Select
    Range("B2").Select
    getApparatus = ActiveCell.value
    Exit Function

End Function

Function getFacility() As String

    Sheets("Results").Select
    Range("E2").Select
    getFacility = ActiveCell.value
    Exit Function

End Function

Sub addPartNumbersToDict()

    'Stores last row of sheet
    Dim lastRow As Integer
    'Allows key to be null
    Dim key As Variant

    Sheets("Parts").Select
    ActiveSheet.Cells.UnMerge

    'Get last active row number
     lastRow = Cells.SpecialCells(xlCellTypeLastCell).Row

    'Loop Variable
     Dim i As Integer

    'Loop through list
     For i = 2 To lastRow
        'set key to current cell
         key = Cells(i, 2).value
    
        'ignore empty cells
         If (Not (IsEmpty(key))) Then
        
            'if key hasn't been seen before
             If Not partsDict.Exists(key) Then
                'add key to dictionary
                 partsDict.Add key, 1
            End If
        
        End If
    Next

End Sub

Sub addCountsFromDatabaseToDict(apparatus As String, facility As String)

    'Set WorkBook as database and activate it
     Dim wk As Workbook
     Set wk = Workbooks.Open("Path")
     wk.Activate

    'Filter table
     ActiveSheet.ListObjects("Table_BuyDesign_ChannelSales_Query").Range.AutoFilter _
        Field:=1, Criteria1:=apparatus
     ActiveSheet.ListObjects("Table_BuyDesign_ChannelSales_Query").Range.AutoFilter _
        Field:=2, Criteria1:=facility

    'Create worksheet variable and set it to table sheet
     Dim ws As Worksheet
     Set ws = ActiveWorkbook.Sheets("Data")

    'Create new dictionary for all parts in table
     Dim allParts As New Scripting.Dictionary

     'Create range to hold area of search
      Dim partRange As Range
     'This array holds data in partsRange
     Dim currData As Variant

     'Range of filtered data
      Dim filRange As Range
      Set filRange = ws.Range("D2:E:E").SpecialCells(xlCellTypeVisible).SpecialCells(xlCellTypeConstants)

    'Loop through filtered data adding all parts and counts for searching
     For Each partRange In filRange.Areas
         currData = partRange
    
        Dim i As Long
        For i = 1 To UBound(currData, 1)
        
            If Not (allParts.Exists(currData(i, 1))) Then
                 allParts(currData(i, 1)) = currData(i, 2)
            End If
        Next i

    Next partRange

    For Each key In partsDict
         If allParts.Exists(key) Then
             partsDict(key) = allParts(key)
         Else
             partsDict(key) = Empty
         End If
    Next key

End Sub

I know that the Dictionary with all ~8,500 rows has been populated correctly (I printed it out). However, the setting of my keys is not working properly. Less than 10 of the 330 keys have values assigned to them. The rest are empty. Is my element checking wrong?

The main problem subroutine is addCountsFromDatabaseToDict() and more specifically, the last for loop in that subroutine. I added the entire program for clarity. Thank you!

capnation
  • 3
  • 2
  • 1
    Start by getting rid of all your `Select` and `Activate` methods and explicitly referring to your workbooks and sheets. For example, your `getApparatus` function reduces to the single line: `getApparatus = Sheets("Results").Range("B2").Value`. By doing this, you will discover that you never declare an `ActiveSheet` in your problematic subroutine at the beginning. Could this be the problem? Depends on what worksheet gets opened when you open that book. See [How to Avoid Using Select in Excel VBA](https://stackoverflow.com/questions/10714251/how-to-avoid-using-select-in-excel-vba) – Ron Rosenfeld Jul 06 '20 at 19:39
  • This sounds like a job for SQL. – HackSlash Jul 06 '20 at 20:06
  • I'm pretty sure I am looking at the right sheet. When I print out all the rows and do a VLookup for my keys, I get the right values. It's just the Dictionary comparison just doesn't want to work. – capnation Jul 07 '20 at 13:28
  • @RonRosenfeld tag – capnation Jul 07 '20 at 14:06
  • Edit your question with the simplified code after getting rid of all the `Select` and `Activate` methods. Also add some textual data that some one can copy/paste to reproduce your problem. See [How to create a Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve) – Ron Rosenfeld Jul 07 '20 at 14:57

0 Answers0