vba - Add dict to dict [duplicate] - excel

I want to set a dictionary as dictionary value?
But it throws an error like
'Wrong number of arguments or invalid property assignment'.
How to fix this issue?
sub test()
Dim Dict As Scripting.Dictionary
Set Dict = New Scripting.Dictionary
Dim rows As Scripting.Dictionary
Set rows = New Scripting.Dictionary
dict("name") = "Sarah"
dict("surname") = "Jones"
rows(dict("name")) = dict
end sub

Dictionary is an object type, with a default member.
rows(dict("name")) = dict
The RHS of this assignment is really a call to dict.Item, but invoked without any parameters... but the Key parameter is required - hence the error.
The Set keyword disambiguates default member calls from "yes I really mean the object reference itself"
Set rows(dict("name")) = dict

Related

Excel VBA throws "Run-time error '91': Object variable or With block variable not set" when setting a range [duplicate]

Pardon me as am a newbie in VBA.
Sometimes I use
Dim r as Range
r = Range("A1")
Other times I use
Set r = Range("A1")
What is the difference? And when should I use what?
There's no reason to use set unless referring to an object reference. It's good practice to only use it in that context. For all other simple data types, just use an assignment operator. It's a good idea to dim (dimension) ALL variables however:
Examples of simple data types would be integer, long, boolean, string. These are just data types and do not have their own methods and properties.
Dim i as Integer
i = 5
Dim myWord as String
myWord = "Whatever I want"
An example of an object would be a Range, a Worksheet, or a Workbook. These have their own methods and properties.
Dim myRange as Range
Set myRange = Sheet1.Range("A1")
If you try to use the last line without Set, VB will throw an error. Now that you have an object declared you can access its properties and methods.
myString = myRange.Value
Dim declares the variable.
Dim r As Range
Set sets the variable to an object reference.
Set r = Range("A1")
However, I don't think this is what you're really asking.
Sometimes I use:
Dim r as Range
r = Range("A1")
This will never work. Without Set you will receive runtime error #91 Object variable or With block variable not set. This is because you must use Set to assign a variables value to an object reference. Then the code above will work.
I think the code below illustrates what you're really asking about. Let's suppose we don't declare a type and let r be a Variant type instead.
Public Sub test()
Dim r
debug.print TypeName(r)
Set r = Range("A1")
debug.print TypeName(r)
r = Range("A1")
debug.print TypeName(r)
End Sub
So, let's break down what happens here.
r is declared as a Variant
`Dim r` ' TypeName(r) returns "Empty", which is the value for an uninitialized variant
r is set to the Range containing cell "A1"
Set r = Range("A1") ' TypeName(r) returns "Range"
r is set to the value of the default property of Range("A1").
r = Range("A1") ' TypeName(r) returns "String"
In this case, the default property of a Range is .Value, so the following two lines of code are equivalent.
r = Range("A1")
r = Range("A1").Value
For more about default object properties, please see Chip Pearson's "Default Member of a Class".
As for your Set example:
Other times I use
Set r = Range("A1")
This wouldn't work without first declaring that r is a Range or Variant object... using the Dim statement - unless you don't have Option Explicit enabled, which you should. Always. Otherwise, you're using identifiers that you haven't declared and they are all implicitly declared as Variants.
Dim: you are defining a variable (here: r is a variable of type Range)
Set: you are setting the property (here: set the value of r to Range("A1") - this is not a type, but a value).
You have to use set with objects, if r were a simple type (e.g. int, string), then you would just write:
Dim r As Integer
r=5
Dim simply declares the value and the type.
Set assigns a value to the variable.
If a variable is defined as an object e.g. Dim myfldr As Folder, it is assigned a value by using the keyword, "Set".
Dim is short for Dimension and is used in VBA and VB6 to declare local variables.
Set on the other hand, has nothing to do with variable declarations. The Set keyword is used to assign an object variable to a new object.
Hope that clarifies the difference for you.
According to VBA help on SET statement it sets a reference to an object.so if you change a property the actual object will also changes.
Dim newObj as Object
Set var1=Object1(same type as Object)
Set var2=Object1(same type as Object)
Set var3=Object1(same type as Object)
Set var4=Object1(same type as Object)
Var1.property1=NewPropertyValue
the other Vars properties also changes,so:
Var1.property1=Var2.property1=Var3.property1=Var4.property1=Object1.Property1=NewpropertyValue`
actualy all vars are the same!

How do I pass an Object to VBA Class Get Property Method without receiving an 'Object not Defined' Error?

When passing a Worksheet to a Class Object Method, I receive:
Error 91: Object Variable or With Block variable not set.
The problem is, I do not know where it is I have not set an object.
Dim WS As Worksheet
Set WS = oExport.ExportSheet(oExport.WB)
Dim testint As Integer
Dim oAsset As clsAsset
testint = oAsset.AssetIDCol(WS)
I have checked, and the worksheet object is correctly set in Line 2 of the code. The error occurs when assigning a value to the 'testint' variable. Here is the .AssetIDCol() property from my clsAsset property:
Option Explicit
Private priv_asset_id_col As Integer
Public Static Property Get AssetIDCol(WS As Worksheet) As Integer
If Not priv_asset_id_col = Null Then
AssetIDCol = priv_asset_id_col
Exit Property
End If
Dim rngX As Range
Dim Val As Variant
Dim i As Integer
Set rngX = WS.UsedRange '.Rows(1) '.Find(SearchVal, LookAt:=xlWhole)
For i = 1 To rngX.Columns.Count
If InStr(priv_asset_id_col_name, rngX.Cells(1, i).Value) > 0 Then
AssetIDCol = i
priv_asset_id_col = i
Exit Property
End If
Next i
AssetIDCol = 0
End Property
How do I fix this error? The Get property returns an integer, so I am not sure where I am failing to use Set in creating an instance.
The error appears, because oAsset is declared, but not initialized.
The easiest way to fix it is to write Dim oAsset As New clsAsset instead of Dim oAsset As clsAsset. This way you are referring to a new object upon declaration.
Another way is to set the new object explicitly with a new line, after declaring it:
Dim oAsset As clsAsset
Set oAsset = New clsAsset

How to set Dictionary as Dictionary value in Excel VBA?

I want to set a dictionary as dictionary value?
But it throws an error like
'Wrong number of arguments or invalid property assignment'.
How to fix this issue?
sub test()
Dim Dict As Scripting.Dictionary
Set Dict = New Scripting.Dictionary
Dim rows As Scripting.Dictionary
Set rows = New Scripting.Dictionary
dict("name") = "Sarah"
dict("surname") = "Jones"
rows(dict("name")) = dict
end sub
Dictionary is an object type, with a default member.
rows(dict("name")) = dict
The RHS of this assignment is really a call to dict.Item, but invoked without any parameters... but the Key parameter is required - hence the error.
The Set keyword disambiguates default member calls from "yes I really mean the object reference itself"
Set rows(dict("name")) = dict

dictionarys and functions: User-defined type not defined

I have typed the following code in Excel VBA:
The function should create a dictionary acording to unique values in a certain column part.
Function CreateDictForFactors(xcord As Integer, ycord As Integer, length As Integer) As Dictionary
Dim Dict As Dictionary
Set Dict = New Dictionary
Dim i As Integer
For i = 0 To length - 1
If Not Dict.Exists(Cells(xcord + i, ycord)) Then
Dict.Add Cells(xcord + i, ycord), 0
End If
Next i
Set CreateDictForFactors = Dict
End Function
Sub test2()
Dim dict1 As Dictionary
Set dict1 = CreateDictForFactors(7, 6, 12)
End Sub
I found this code as an excample for dictionaries and functions:
Sub mySub()
dim myDict as Dictionary
set myDict = myFunc()
End Sub
Function myFunc() as Dictionary
dim myDict2 as Dictionary
set myDict2 = new Dictionary
'some code that does things and adds to myDict2'
set myFunc=myDict2
End Function
However when I try to run the makro test2 it gives the error message:
User-defined type not defined
Can anyone tell where I made a mistake?
Thank you in advance
G'day,
Did you add "Microsoft Scripting Runtime" as a reference to your project?
Once you've done that, declare dict as a Scripting.Dictionary like this:
Dim dict As Scripting.Dictionary
You can create the object as follows:
Set dict = New Scripting.Dictionary
This is a good website describing the use of a dictionary:
https://excelmacromastery.com/vba-dictionary/
Hope this helps.
You can also late bind the code like this:
Function CreateDictForFactors(xcord As Integer, ycord As Integer, length As Integer) As Dictionary
Dim Dict As Object
Set Dict = CreateObject("Scripting.Dictionary")
Dim i As Integer
For i = 0 To length - 1
If Not Dict.Exists(Cells(xcord + i, ycord)) Then
Dict.Add Cells(xcord + i, ycord), 0
End If
Next i
Set CreateDictForFactors = Dict
End Function
Sub test2()
Dim dict1 As Object
Set dict1 = CreateDictForFactors(7, 6, 12)
End Sub
Note that neither method will work on a Mac.

What is the difference between dim and set in vba

Pardon me as am a newbie in VBA.
Sometimes I use
Dim r as Range
r = Range("A1")
Other times I use
Set r = Range("A1")
What is the difference? And when should I use what?
There's no reason to use set unless referring to an object reference. It's good practice to only use it in that context. For all other simple data types, just use an assignment operator. It's a good idea to dim (dimension) ALL variables however:
Examples of simple data types would be integer, long, boolean, string. These are just data types and do not have their own methods and properties.
Dim i as Integer
i = 5
Dim myWord as String
myWord = "Whatever I want"
An example of an object would be a Range, a Worksheet, or a Workbook. These have their own methods and properties.
Dim myRange as Range
Set myRange = Sheet1.Range("A1")
If you try to use the last line without Set, VB will throw an error. Now that you have an object declared you can access its properties and methods.
myString = myRange.Value
Dim declares the variable.
Dim r As Range
Set sets the variable to an object reference.
Set r = Range("A1")
However, I don't think this is what you're really asking.
Sometimes I use:
Dim r as Range
r = Range("A1")
This will never work. Without Set you will receive runtime error #91 Object variable or With block variable not set. This is because you must use Set to assign a variables value to an object reference. Then the code above will work.
I think the code below illustrates what you're really asking about. Let's suppose we don't declare a type and let r be a Variant type instead.
Public Sub test()
Dim r
debug.print TypeName(r)
Set r = Range("A1")
debug.print TypeName(r)
r = Range("A1")
debug.print TypeName(r)
End Sub
So, let's break down what happens here.
r is declared as a Variant
`Dim r` ' TypeName(r) returns "Empty", which is the value for an uninitialized variant
r is set to the Range containing cell "A1"
Set r = Range("A1") ' TypeName(r) returns "Range"
r is set to the value of the default property of Range("A1").
r = Range("A1") ' TypeName(r) returns "String"
In this case, the default property of a Range is .Value, so the following two lines of code are equivalent.
r = Range("A1")
r = Range("A1").Value
For more about default object properties, please see Chip Pearson's "Default Member of a Class".
As for your Set example:
Other times I use
Set r = Range("A1")
This wouldn't work without first declaring that r is a Range or Variant object... using the Dim statement - unless you don't have Option Explicit enabled, which you should. Always. Otherwise, you're using identifiers that you haven't declared and they are all implicitly declared as Variants.
Dim: you are defining a variable (here: r is a variable of type Range)
Set: you are setting the property (here: set the value of r to Range("A1") - this is not a type, but a value).
You have to use set with objects, if r were a simple type (e.g. int, string), then you would just write:
Dim r As Integer
r=5
Dim simply declares the value and the type.
Set assigns a value to the variable.
If a variable is defined as an object e.g. Dim myfldr As Folder, it is assigned a value by using the keyword, "Set".
Dim is short for Dimension and is used in VBA and VB6 to declare local variables.
Set on the other hand, has nothing to do with variable declarations. The Set keyword is used to assign an object variable to a new object.
Hope that clarifies the difference for you.
According to VBA help on SET statement it sets a reference to an object.so if you change a property the actual object will also changes.
Dim newObj as Object
Set var1=Object1(same type as Object)
Set var2=Object1(same type as Object)
Set var3=Object1(same type as Object)
Set var4=Object1(same type as Object)
Var1.property1=NewPropertyValue
the other Vars properties also changes,so:
Var1.property1=Var2.property1=Var3.property1=Var4.property1=Object1.Property1=NewpropertyValue`
actualy all vars are the same!

Resources