Excel VBA: Extract custom class from dictionary - class

I am having a problem with VBA Excel 2010. I've made a custom Class called 'Enclosure', created an instance of this and added it to a dictonary.
I can then loop through the keys to ensure it has been added.
I'm having trouble then extracting my enclosure class. Here's my code for the extraction sub:
Sub AddEnclosureItem(sItemToAdd As String, ByRef rdEnclosures As Scripting.Dictionary, dDebug As Boolean)
Dim TempEnclosure As Enclosure ' hold enclosure we pull
TempEnclosure = rdEnclosures(1)
End Sub
When I try to compile I get the 'Object Variable or With block variable not set'
Any idea's on how to proceed? I've read somewhere you can declare a dictionary stating the items are of a certain object but I can't get it to work in 2010. That's all I can guess at. OR a way to cast the enclosure item as it comes out.

When you assign an object to a variable, you have to use the Set keyword. The opposite of Set is Let, which is used to assign a value (not an object) to a variable. The Let keyword is optional and almost nobody uses it anymore.
The reason there's a Set and Let is because most objects have a default property - meaning that if you reference an option without a property, it will return the value stored in the default property. The Value property is a common default property. This
x = Range("A1")
is the same as this
x = Range("A1").Value
is the same as this
Let x = Range("A1").Value
Any is acceptable (although I prefer the second one). That's great if x is a Double or String, but if x is a Range object variable, you need use Set
Set x = Range("A1")
If you omit the Set keyword, VBA assumes you wanted Let and tries to assign the (default) Value property to x. That gives the 'Object variable or with block not set' error because it's trying to assign a Double or String to a Range object variable.
Your custom class module probably doesn't have a default value, so none of this should matter. But it does. Even if there is no default value, you have to use Set to reference the object.

Related

Why can't we pass const values by reference to inout functions in swift?

In C, although we declare a value as const int a = 5;, we can pass &a to a function declared as void someFun(const int *);.
As a rule of thumb, in C, when the original value is need not to be changed, i) if the size of object is less than or equal to size of pointer, we pass it by value, ii) otherwise we pass it by const reference copying the entire value to a function would take more resources.
But in swift, even though an inout parameter is not modified in a function, we can't pass a value declared as let a = 5 to function declared as someFun(_ z: inout Int) -> (). Hence we have to mark z in the function as let. This will copy the entire value to the function. This may cost more if the size of the type of a is big. Is there a workaround to this?
As to my understanding,
The 'inout' in swift does not actually send the reference of
the property to the function. When you change the value of the
property passed as 'inout', the swift on its own end checks if you
have changed the value and then performs that change to the actual
property on its own. So the only thing 'inout' does in swift is
changing the value of the actual property. So even if it allows you to send a constant as
'inout', you still won't be able to make any use of it, because of the very nature of the 'constant'. You just cant change the value of a 'constant', because its immutable.
Reference Link: https://docs.swift.org/swift-book/LanguageGuide/Functions.html
Edit:
As mentioned by #SouravKannanthaB in the comment above, swift can automatically optimize the inout by mimicking the behavior of pass by reference, but i don't believe one can force the optimization to take place.

Is it valid to set the value of changing control property equal to a constant in swift?

I apologize for the rather basic question, there is a lot of documentation out there but this is not particularly clear to me.
Swift keeps giving me warnings that suggest changing variables to constants so my question is this: if I set a constant equal to a control property (a label text value for instance) and the value of that control property changes, will the value of the constant change? The definition of that "constant" will always be equal to the control property.
Example from my code:
let MELLandingPenalty: Int = Int(lblMELLandingDist.text!)!
Constants behave in two different ways:
If the assigned object is value type then the value is a copy of the right side and will never change.
If the assigned object is reference type then the reference will never change but its variable properties are mutable.
In your example value type MELLandingPenalty will never change – by the way variable names are supposed to start with a lowercase letter and don't annotate types the compiler can infer.
Trust the compiler and resolve the warnings by changing var to let.

Stopping reference variables changing the value of the original variable

I am assigning the value of a custom class to another variable. Updating the value of the new variable is affecting the value of the original variable. However, I need to stop the reference variable from updating the original variable.
Here's a basic representation of what's happening:
var originalVariable = CustomClass()
originalVariable.myProperty = originalValue
var referenceVariable = originalVariable
referenceVariable.myProperty = updatedValue
print("\(originalVariable.myProperty)") //this prints the ->updatedValue<- and not the ->originalValue<-
I've tried wrapping the referenceVariable in a struct to make it a value type but it hasn't solved the problem.
I've found information regarding value and reference types but I haven't been able to find a solution.
My question in a nutshell: How do I stop an update to a reference variable from updating the original variable that it got its value assigned from?
Thanks in advance.
The whole point of reference semantics (as used by classes) is that all variables point to the same (i.e., they reference the same) object in memory. If you don't want that behaviour, you should use value types (Struct, Enum, Array...) or create copies of your object.
If CustomClass implements the NSCopying protocol you can do:
var referenceVariable = originalVariable.copy()
If it doesn't, you'll have to find some other way to copy it or implement the protocol yourself.
Wrapping the class in a struct will just make two different structs each containing a different reference to the same object.

Swift. When should you define an Object / Value with specific data type

As I started developing with Swift and searching through different tutorials and documentations about the language, I'm not sure about one thing.
You can declare an object / value with a specific data type like this:
var aString:String = "Test"
var anObject:SKScene = ASceneClass()
Or you can just do it like this:
var aString = "Test"
var anObject = ASceneClass()
The result will be exactly the same (ASceneClass inherits from SKScene of course)
As everyone is doing it different I wonder if there's a logical reason behind it or you do it for readability ?
Declaring type right after variable name is called Type Annotation
When you don't do that, you have to provide initial value
var aString = "Test"
Often value is not known at that moment, or you are not even sure if it's going to be not nil value, then you can declare it as optional
var aString:String?
If you would like to declare variable without any initiaization but you are sure it's not going to evaluate to nil, you force unwrap it
var aString:String!
This is the definition. In practice, it's always better to use type annotations even when you initialize variable with value, because later in your program you will notice anytime you mess something with the type of the variable.
Also, When you declare an array or dictionary, usually nested ones, Xcode might expect them to have type annotations since it might have some issues with writing values when the type is not known in advance.
To recap
You will want to use type annotations whenever you can, which means whenever you are sure about the variable's type in advance
Recommended/Documented way to declare a variable in swift is as follow:
var <variable name>: <type> = <initial value/expression>
Note: Given form declares a stored variable or stored variable property. Its used when you are clear about type annotation of it.
Though its valid to declare variable without its Type.
var variableName = <initial value>
Note: When you don't know type annotation its mandatory to assign 'Initial value' to that variable.
Refer Swift Documentation on Declaration for more details.

Why is constant instance of a value type can NOT change its properties while constant instance of a reference type can?

I'm new to Swift and is trying to learn the concept of Property. I saw the statements and code below from "swift programming language 2.1".
struct FixedLengthRange {
var firstvalue: Int
let length: Int
}
let rangeOfFourItems = FixedLengthRange(firstvalue: 0, length: 4)
rangeOfFourItems.firstvalue = 8 //error: cannot assign to property: rangeOfFourItems is a "let" constant
And the book provided the following explanation for the error:
This behavior is due to structures being value types. When an instance
of a value type is marked as a constant, so are all of its properties.
The same is not true for classes, which are reference types. If you
assign an instance of a reference type to a constant, you can still
change that instance’s variable properties.
Why is constant instance of a value type can NOT change its properties while constant instance of a reference type can? What is the reason behind it? The book did say how but failed to explain why. I think it is good practice to understand the reasons behind how things the way they are. Could someone please kindly explain it to me?
why is constant instance of a value type can NOT change its properties
Because value type is treated as an indivisible unit: it gets copied on assignment, passing it as a parameter behaves like a copy, and so using const-ness locks down the entire struct. In a sense, rangeOfFourItems variable represents the structure itself, not a pointer or a reference to it.
while constant instance of a reference type can?
This is not entirely correct to say that declaring a const variable of reference type makes the instance constant as well. Only the reference is constant, not the instance.
If you think about it, that is the only way this could be meaningfully implemented, because multiple variables can reference the same by-reference instance. If one of these variables is constant and the other one is not constant, assigning a non-const reference to a constant variable could not possibly lock down the referenced object, which would lock out the non-const reference as well:
var a = ByRefType()
let b = a; // b is a constant reference to the same instance as "a"
a.property = newValue; // Prohibiting this assignment would be inconsistent
Of course the constant variable itself (e.g. b above) could not be re-assigned, unlike the non-constant variable a.