Reputation: 415
I am getting issues in using a dictionary in VBA. I want to add values from a sheet to a dictionary. If I use simple lists, there is no error in the code. Like this.
Function Account(Place As String) As String
Dim cities(500)
Dim accounts(500)
For i = 2 To 500
cities(i) = Worksheets("Sheet2").Cells(i, 2).Value
accounts(i) = Worksheets("Sheet2").Cells(i, 3).Value
Next i
placeName = StrConv(Place, vbProperCase)
Account = placeName
End Function
This code does not give an issue but if I add the code for the dictionary, there is some issue.
Function Account(Place As String) As String
Dim cities(500)
Dim accounts(500)
Dim dict
Set dict = CreateObject(Scripting.Dictionary)
For i = 2 To 500
cities(i) = Worksheets("Sheet2").Cells(i, 2).Value
accounts(i) = Worksheets("Sheet2").Cells(i, 3).Value
dict(cities(i)) = accounts(i)
Next i
placeName = StrConv(Place, vbProperCase)
Account = placeName
dict = Nothing
End Function
Can someone point out the error. I am new to vba so I dont know much about it.
Upvotes: 1
Views: 1456
Reputation: 682
One possible area of concern, brought to mind by one of your comments, lies in the use of "Sheet1" and "Sheet2". In Excel VBA, there are two different ways to refer to a worksheet. The is the Name of the worksheet, which is what the user sees on the tabs in Excel, and the user can change at will. Thtese default to names like "Sheet1", "Sheet2", etc.
There is also the "Codename" for each worksheet. In the Visual Basic Editor, the project explorer window will list all the worksheets under "Microsoft Excel Objects". There you'll see the Codename for each worksheet, with the Name of the worksheet in parentheses.
When you use Worksheets("Sheet1"), the "Sheet1" refers to the Name, not the Codename. It's possible to end up with a worksheet with the Name "Sheet1" and the codename "Sheet2".
As far as your functions are concerned, I note that in both cases you declare local variables -- the arrays 'cities' and 'accounts' in the first, and those two plus the dictionary 'dict' in the second. You have code to fill those local variables, but then do nothing with them. The return value of the function is not dependent on any of those local variables.
Once the function code completes, those local variables lose their values. VBA returns the memory it used to store those variables to its pool of available memory, to be reused for other purposes.
Try commenting-out the entire for...next loop, and you'll see that the value return from the function is unchanged.
I'm not certain what you intend to accomplish in these functions. It would be helpful for you to explain that.
Upvotes: 0
Reputation:
The folowing UDF loads a dictionary object with places as keys (unique) and associated accounts as items. After the dictionary has been loaded, it looks up the Place parameter passed into the function and returns the account if found.
Option Explicit
Function Account(Place As String) As String
Static d As Long, dict As Object
If dict Is Nothing Then
Set dict = CreateObject("Scripting.Dictionary")
dict.comparemode = vbTextCompare
Else
dict.RemoveAll
End If
With Worksheets("Sheet2")
For d = 2 To .Cells(.Rows.Count, "B").End(xlUp).Row
dict.Item(.Cells(d, "B").Value2) = .Cells(d, "C").Value2
Next d
End With
If dict.exists(Place) Then
Account = dict.Item(Place)
Else
Account = "not found"
End If
End Function
Note that beyond other corrections, the code to instantiate the dictionary object is CreateObject("Scripting.Dictionary")
not CreateObject(Scripting.Dictionary)
.
Upvotes: 3