View Single Post
  #14   Report Post  
Posted to microsoft.public.excel.programming
Ronald R. Dodge, Jr.[_2_] Ronald R. Dodge, Jr.[_2_] is offline
external usenet poster
 
Posts: 134
Default Nothing Keyword Destories Objects rather than just resetting the variable to an empty variable

Maybe it's unclear as to what intrinsic means within the programming world,
but from what I had gathered, any object or other value tied to the
application or some other referenced library (early or late binding, though
normally see it more readily with early binding), those are the items that's
intrinsic and therefore can't really be changed.

Yes, I am very critical as I have learned early on not to assume anything
unless I have no realistic choice. That is cause when one start going on
assuming things, they are taking on a much greater risk of getting
inaccurate results, which then can either get them into a lot of problems or
can make it rather tough to resolve. Some people may hate me for that fact,
but it's one of those day to day rules that has kept me out of trouble.
Therefore, without knowing what the ObjPtr did or seeing the code for it
(Not to mention someone could have made up their own UDF with that name,
though wouldn't think you would purposely do that, but nonetheless, there's
that assumption thing again), I couldn't really trust your example. That is
why I have rules like prequalify variables, don't rely on active objects,
use a proper naming convention, and use explicit coding only, as just a few
examples, unless of course, there is no realistic choice to break one of
those rules. That should be very rare to have such an exception and if it
does happen, it better be for a very good reason.

The only thing is, there must be a starting point, and documentations was
basically my starting point. If I attempted to prove every little thing
before using them, I wouldn't be nearly as far along as I am with my
programs. Yes, there has been times when documentations has proven to be
either incorrect or misleading, such as in this example, at the minimal,
very much so misleading. Another example, Excel specification states the
only limit to defined names is the amount of ram when in fact it's limited
to 65,536 defined names within a single workbook due to the fact the names
collection seems to have a 2 byte field for the index. Not only that, but
even after exceeding 32,768 defined names within a single workbook, the
workbook may become unstable. If a single workbook has in it more than
65,536 defined names in it at the time it's saved then closed out, the next
time it opens up, it goes into repair mode and the only items left in it are
the text/formula entries into the cells and maybe a few other minor stuff.
Pretty much everything else is gone like formats, charts, other worksheet
settings, and what not.

--
Thanks,

Ronald R. Dodge, Jr.
Production Statistician
Master MOUS 2000
"Peter T" <peter_t@discussions wrote in message
...
I thought Chip's example was clear but I guess we all see things different
ways.

In my example use of ObjPtr was to demonstrate that all the references,
the original, the ByRef & ByVal all pointed to the same intrinsic object
and therefore no copy of the object was created. I posted this early in
the thread when you were disinclined to accept that was how it worked.

The example also showed, that as far as the intrinsic object is concerned,
there is no difference between using ByVal or ByRef. However there most
certainly is a difference in what may or may not happen to the object
variables depending on how they are passed.

I fully accept there are always better ways of explaining things, but that
does not mean either of the examples were not valid.


However, note, there is nothing in the documentations to make this point
dealing with *NON* intrinsic objects.


I don't follow "non". I used the term "intrinsic" to refer to the object
"thing", as distinct from an object variable which stores the address that
"points" to the block of memory where the object currently exists
(simplified).

Does that mean the other sources are incorrect?


I haven't read anything that is technically incorrect but I agree there is
not much in the way of explanation on this particular aspect.


I still don't follow your objective and problem. Why not post a simplified
example.

Regards,
Peter T


"Ronald Dodge" wrote in message
...
Maybe, but it was more so the method that he used that worked out the
same under both scenarios, so that didn't prove anything to me. What did
prove it to me was when I changed the code inside of the ByVal method to
change the property of the local object and then print all 3 object
variable's Text property to the immediate window while still in the
method and after changing the Text property of the local object variable.

However, note, there is nothing in the documentations to make this point
dealing with *NON* intrinsic objects.

Does that mean the other sources are incorrect?

Some of them are (primarily the ones in the help files, though they are
so vague anyhow, they don't do much good), while others not really so as
they mainly used simple data type variables to make their point, and then
used intrinsic objects to show that it doesn't work that way for those
objects. However, there's nothing stated anywhere that I saw dealing with
custom objects.

Maybe lesson learned by all 3 of us. For me, it was realizing that the
documentations were misleading or incorrect (which ever may have been the
case) while for the 2 of you, using a proper example that shows a clear
distinction without using something that could end up returning the same
result (In Chip's case) and don't use an example that has something in it
that has an unknown in it like what your example had with the ObjPtr
Function.


"Peter T" <peter_t@discussions wrote in message
...
You have misinterpreted Chip's example.

In the ByRef example the object variable C1 is in effect is re-assigned
to point to the C2 instance, at which moment the C1 class is destroyed
as the C1 pointer was the sole reference to the class object. That did
not occur with the ByVal example. Totally predictable and consistent
with what I have been trying to explain, without success.

Is there a reason you do not want to try the example I had posted, maybe
if you do things will become clearer.

Regards,
Peter T


"Ronald Dodge" wrote in message
...
Take a look at Chip Pearson's response, then my response right back
using his own code example and debug print out.

Yes, an object variable is a pointer to an object, but that is the only
way how a programmer can interact with an object. However, there is a
pretty big difference difference between ByRef and ByVal, and you seem
to be missing it, just like Chip also missed it.

If ByVal and ByRef both merely had a pointer to the original object, C1
in lines 2 and 4 would both be stating "222", not "111" in Line 2 and
"222" in Line 4. Study carefully the difference between Line # 2 and
Line # 4 in his example.


"Peter T" <peter_t@discussions wrote in message
...
There is nothing there that says anything about creating a replica
object for ByVal. The closest to what you have in mind is this -

When you pass arguments by value, Visual Basic makes a temporary copy
of the variable and passes the copy rather than the original. When
the procedure ends, Visual Basic throws the copy away--and changes
are discarded.

But you are missing the point. An object variable is a pointer to an
object. Sending an object ByVal makes a copy of the pointer as a new
object variable. Both original and new variables both point to the
same object. This bit - "and changes are discarded" as relates to an
object ByVal refers to any reassignment or destruction of the object
variable, but not to any changed properties of the actual object which
will persist.

I take it you didn't try the example I gave that demonstrates.

Regards,
Peter T


"Ronald R. Dodge, Jr." wrote in message
...
But that still doesn't answer the question to how to deal with the
original issue with *NON* intrinsic objects.


As to answer your question, even within the VBA help file under
"Statements", then any one of the items listed below:

Function Statement
Property Get Statement
Property Let Statement
Property Set Statement
Sub Statement

When you look up the ByVal, it states:

---START QUOTE---

Optional. Indicates that the argument is passed by value.

---END QUOTE---

If you click on the link of "by value", it further states:

---START QUOTE---

by value

A way of passing the value of an argument to a procedure instead of
passing the address. This allows the procedure to access a copy of
the variable. As a result, the variable's actual value can't be
changed by the procedure to which it is passed.

---END QUOTE---

Also as stated in other sources such as in Access 2002 VBA Handbook
by Susann Novalis and Dana Jones on page 367:

---START QUOTE---

When you send a copy of the variable's value, VBA creates a copy in
another temporary storage location in memory and sends the copy. The
called procedure can use the copy and may even change it's values,
but because the called procedure is working with a copy, the variable
itself is not affected. Sending a copy of the variable is called
passing the variable by value.

---END QUOTE---

While this is VBA with Excel, regardless if it's within Excel or
Access, it's still the same VBA language and structure, just with a
different set of objects and variables pertinent to the application.
Okay, here's one from "Using Excel Visual Basic For Applications,
Second Edition" by Jeff Webb on page 52:

---START QUOTE---

Besides data types, you can also specify how Visual Basic passes
arguments to a procedure. By default, Visual Basic passes a
reference to the argument. Any changes to the argument are reflected
in the variable that was passed in as the argument.

---END QUOTE---

This is stating that, using ByRef, or the omission of using either
one of the 2 key words, any changes done to the object is reflected
both inside and outside of the called procedure.

Now, go to page 53 of the same book, but only for the ByVal keyword:

---START QUOTE---

When you pass arguments by value, Visual Basic makes a temporary copy
of the variable and passes the copy rather than the original. When
the procedure ends, Visual Basic throws the copy away--and changes
are discarded.

---END QUOTE---

Though I'm dealing with passing arguments onto properties as opposed
to methods, it's the same deal. That very last one quoted pretty
much spelt it out.

You wanted my sources for my understanding of these 2 keywords, you
got them.


However, there's one exception to this rule, and you relied on this
one exception.

Variable/Object names that are global to the application, those names
can't be used for anything else, so when you attempt to use the ByVal
with such variables or variable types, they won't react the same way
as described in the help files. For that reason, these global
variables/objects are known as intrinsic to the application, which is
why they have a different behavior as compared to any other
variable/object that's not considered as global at the application
level.
--
Thanks,

Ronald R. Dodge, Jr.
Production Statistician
Master MOUS 2000
"Peter T" <peter_t@discussions wrote in message
...
Strange, I didn't see this when I followed up to your earlier
message. Anyway I trust the example in the follow-up clarifies.

Regards,
Peter T


"Ronald R. Dodge, Jr." wrote in message
...
As far as I can tell, what you are saying only works with intrinsic
objects.

Given my custom objects are within a project, not part of the
application itself, but the very definition of intrinsic objects,
my custom objects are NOT intrinsic objects, thus your argument for
how the ByVal works would not work out.

--
Thanks,

Ronald R. Dodge, Jr.
Production Statistician
Master MOUS 2000
"Peter T" <peter_t@discussions wrote in message
...
ByVal - Creates a whole new replica of the object with all of the
same settings as the object that is being passed onto it

No it doesn't. It creates a new (temporary) pointer to the
original intrinsic object.

As far as the original object's properties are concerned there is
no difference between using ByRef and ByVal.

Regards,
Peter T


"Ronald R. Dodge, Jr." wrote in message
...
The way I understood the ByRef and ByVal are the following:

ByRef - References to the object, and any changes done to the
object is done for any variable referencing to that object,
rather it be done in the original code or in the code referencing
to the object.

ByVal - Creates a whole new replica of the object with all of the
same settings as the object that is being passed onto it, but any
changes done to the original object is not reflects in the new
object, just like any changes done in the new object is not
reflected in the original object.

Though I haven't fully tested it to be sure with object
variables, but simple data type variables does work like this.

--
Thanks,

Ronald R. Dodge, Jr.
Production Statistician
Master MOUS 2000
"Peter T" <peter_t@discussions wrote in message
...
Afraid I don't follow most of that, maybe a simple example might
help.

One thing though, I think you are misunderstanding the
difference of passing an object byref & byval. Either way, any
changes to the object's properties will persist.

The only difference is with byval a new pointer to the original
object is created and passed. This means even if you destroy or
reassign the byval object within the procedure, the original
object variable will continue point to the same object.

Regards,
Peter T



"Ronald R. Dodge, Jr." wrote in
message ...
Office XP, SP3 (VBA 6.0)
WIN XP, SP2


I have read over the text dealing with custom objects

According to the text that I have read online from MS
themselves, the keyword "NOTHING" should only destroy the
object when there is no other variable refering to that object.
However, as I have learned the hard way, that is not the case.
Any time any variable is set to NOTHING, the object is
destroyed, so any object variable referencing to that object is
then also set to NOTHING.

Example:

PayCode collection has a set of objects containing properties.
One of those PayCode objects is passed onto an Employee Object.
It's passed into the employee object via a property with the
object using the ByRef within the signature line, so if there's
any changes to the PayCode object, it's not only changed within
the PayCodes collection, but also within the Employee's PayCode
reference to it.

However, if the Employee Object is set to be destroyed, via the
clean up code, the code should be to set the object variable
within the Employee Object to NOTHING. However, doing that not
only does that, but also set's that particular object within
the PayCodes collection to NOTHING as if the object itself has
been destroyed.

How do I resolve this issue, so as I can have it reset only the
variable, not destroy the actual object, but yet, also allow
for changes to carry into the variable when they are done into
the main object?

--
Thanks,

Ronald R. Dodge, Jr.
Production Statistician
Master MOUS 2000