Solved

Problem retrieving second level from dictionary of dictionaries (VBA in Excel 2007)

Posted on 2010-11-07
2
641 Views
Last Modified: 2012-05-10
I'm trying to employ the dictionary of dictionaries techniques mentioned in a reply to a recent question about storing information where the number of items to be held is unpredictable.  I'm having trouble retrieving the second level dictionary.

To diagnose what was going on I've set up the following code.

Sub TestingDictionaries()

    Dim Phrases As Scripting.Dictionary         '   Dictionary of Phrases
    Dim WordsInPhrase As Scripting.Dictionary   '   Dictionary of the non trivial words in each phrase
    Dim vPhrases As Variant
    Dim vWords As Variant

    Dim iPhrase As Integer, iWord As Integer
    
    Dim wsPhrases As Worksheet
                
    Worksheets.Add(After:=Worksheets(Worksheets.Count)).Name = "Phrases"
    Set wsPhrases = Worksheets("Phrases") ' List of extracted words
    
    Set Phrases = New Scripting.Dictionary
    Phrases.CompareMode = vbTextCompare

    Set WordsInPhrase = New Scripting.Dictionary
    WordsInPhrase.CompareMode = vbTextCompare
    
'   Load dummy contents

    For iPhrase = 1 To 10
    
        For iWord = 1 To 5
        
            WordsInPhrase.Add iWord, "Word #" & iWord & " in phrase #" & iPhrase
            
        Next iWord
        
'   Dump WordsInPhrase back out to test that it loaded
        
        For iWord = 1 To WordsInPhrase.Count
        
            wsPhrases.Cells(15 + iPhrase + 1, iWord + 2).Value = WordsInPhrase.Item(iWord)
        
        Next iWord
                   
        Phrases.Add "Dummy phrase #" & iPhrase, WordsInPhrase
        WordsInPhrase.RemoveAll
            
    Next iPhrase
    
'   ALL OK TO HERE -------------------------------------------------------

    vPhrases = Phrases.Keys
    
    For iPhrase = 0 To UBound(vPhrases)
    
        wsPhrases.Cells(iPhrase + 1, 1).Value = vPhrases(iPhrase)
        
        Set WordsInPhrase = Phrases.Item(vPhrases(iPhrase))
        
        For iWord = 1 To WordsInPhrase.Count
        
            wsPhrases.Cells(iPhrase + 1, iWord + 2).Value = WordsInPhrase.Item(iWord)
        
        Next iWord
                    
    Next iPhrase

End Sub

Open in new window


Down to the comment "ALL OK TO HERE" it behaves as expected.

The variant vPhrases retrieves the keys to the Phrases dictionary fine and the loop For iPhrase/Next iPhrase behaves as it should but the subsidiary dictionary WordsInPhrase is not retrieved by the line

Set WordsInPhrase = Phrases.Item(vPhrases(iPhrase))

The value of WordsInPhrase.Count is zero

I presume It's a simple error on my part but I'm having trouble tracking it down and any assistance will be most welcome.
0
Comment
Question by:sjgrey
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
2 Comments
 
LVL 37

Accepted Solution

by:
TommySzalapski earned 500 total points
ID: 34082054
Here is your problem. When you add an item like a scripting dictionary to a dictionary, it doesn't copy the item, it simply adds a reference (or pointer if you're a c programmer). So when you do WordsInPhrase.RemoveAll it removes all the words from both WordsInPhrase and Phrases since it didn't actually copy them in.

See the following code. All I did was change WordsInPhrase to an array and did not clear them. Now it works as expected.
Option Explicit
Private Sub CommandButton1_Click()

    Dim Phrases As Scripting.Dictionary         '   Dictionary of Phrases
    Dim WordsInPhrase(10) As Scripting.Dictionary   '   Dictionary of the non trivial words in each phrase
    Dim vPhrases As Variant
    Dim vWords As Variant

    Dim iPhrase As Integer, iWord As Integer
    
    Dim wsPhrases As Worksheet
                
    Worksheets.Add(After:=Worksheets(Worksheets.Count)).Name = "Phrases"
    Set wsPhrases = Worksheets("Phrases") ' List of extracted words
    
    Set Phrases = New Scripting.Dictionary
    Phrases.CompareMode = vbTextCompare

'   Load dummy contents

    For iPhrase = 1 To 10
    
        Set WordsInPhrase(iPhrase) = New Scripting.Dictionary
        WordsInPhrase(iPhrase).CompareMode = vbTextCompare
    
        For iWord = 1 To 5
        
            WordsInPhrase(iPhrase).Add iWord + iPhrase, "Word #" & iWord & " in phrase #" & iPhrase
            
        Next iWord
        
'   Dump WordsInPhrase back out to test that it loaded
        
        For iWord = 1 To WordsInPhrase(iPhrase).Count
        
            wsPhrases.Cells(15 + iPhrase + 1, iWord + 2).Value = WordsInPhrase(iPhrase).Item(iWord)
        
        Next iWord
                   
        Phrases.Add "Dummy phrase #" & iPhrase, WordsInPhrase(iPhrase)
        'WordsInPhrase.RemoveAll
            
    Next iPhrase
    
'   ALL OK TO HERE -------------------------------------------------------

    vPhrases = Phrases.Keys
    
    For iPhrase = 0 To UBound(vPhrases)
    
        wsPhrases.Cells(iPhrase + 1, 1).Value = vPhrases(iPhrase)
        
        Set WordsInPhrase(iPhrase) = Phrases.Item(vPhrases(iPhrase))
        
        For iWord = 1 To WordsInPhrase(iPhrase).Count
        
            wsPhrases.Cells(iPhrase + 1, iWord + 2).Value = WordsInPhrase(iPhrase).Item(iWord)
        
        Next iWord
                    
    Next iPhrase

End Sub

Open in new window

0
 
LVL 1

Author Closing Comment

by:sjgrey
ID: 34082121
Great - thanks very much

To maintain the open ended scale of the store, I used Redim Preserve to build the WordsInPhrase array for each new phrase and I think that will solve the problem.
0

Featured Post

To Patch or not to Patch? That is the question!

Don't get caught out like thousands of others around the world in the recent Ransomware Fiasco!
Discuss..
- Why it's not a good idea to wait before Patching
- Sensible approaches to Patching discussed
- Add your feedback, comments and suggestions

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
How to fix this UDF to handle blank cells? 8 44
Office 2016 Pro Plus MSI Version 4 47
Pull data from a another spreadsheet tab 3 29
Zip Codes Excel Spreadsheet 4 20
Freeze panes is an option within all variants of Excel to enable parts of a sheet to remain stationary when the cursor is in another part of the sheet. This is a very useful feature which is overlooked or under used.
I was prompted to write this article after the recent World-Wide Ransomware outbreak. For years now, System Administrators around the world have used the excuse of "Waiting a Bit" before applying Security Patch Updates. This type of reasoning to me …
Graphs within dashboards are meant to be dynamic, representing data from a period of time that will change each time the dashboard is updated with new data. Rather than update each graph to point to a different set within a static set of data, t…
This Micro Tutorial demonstrates how to create Excel charts: column, area, line, bar, and scatter charts. Formatting tips are provided as well.

739 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question