VERSIONS: All
SUBJECT: Naming record objects in a tableframe
BY: MARK PAUKER
Could you elaborate a bit more on *HOW* PDOXWIN will behave differently with named vs. unnamed records?
I was hoping you wouldn't ask that < g >. I don't know if you'll run into any "gotchas" if you name record objects, but you will lose certain
abilities. For example, if you name the record object then you will not be able to read values from a non-current record in the tableFrame, whereas
if you don't name it, you will be able to read values from any record object, regardless of which one is current.
Perhaps it would be helpful to go into the issues a bit...
When you run a form and look at a tableFrame (or MRO), every record being displayed is a separate record object. (If you enumerate the
objects on the form using enumUIObjectNames, you will see as many record objects as there are rows in the tableFrame.) The fact that a
tableFrame contains multiple record objects is a surprise to most people because Paradox attempts to hide that fact, treating tableFrames as if they
contain a single record object.
The basic problem stems from the fact that ObjectPAL controls the UI rather then any underlying data objects. From a database perspective,
we are typically interested in the concept of a "current" record, so that's the programming paradigm Borland attempted to give us. As you can
imagine, though, trying to hide the implementation details has given rise to a large number of Paradox's anomalies.
Consider a tableFrame with 3 rows and 2 fields. Although the Paradox object tree would only show 1 record object and 3 field objects, the
"real" object tree would look something like:
myTable --- #Record5 --- LastName
| |
| -- FirstName
|
-- #Record9 --- LastName
| |
| -- FirstName
|
-- #Record13 --- LastName
|
-- FirstName
FYI-- You can attach to any record object by specifying the object name as a string (ui.attach("#Record9")), but you can only attach to the _first_
row using an actual object reference. (ui.attach(#Record9) will not work.)
The first significant anomaly to consider is what happens when you attach a uiObject variable to the LastName field while in the first record
of the tableFrame. You _should_ be attaching to the object named myTable.#Record5.LastName, but is that really what's happening? If you were
to move to the next row after attaching the ui variable and then ask for ui'value, what should be returned? Since you attached the variable to
myTable.#Record5.LastName, you might reasonably assume that the answer would be the value in the LastName field of the first row. Then
again, since Paradox tries to hide the fact that there are multiple record objects, you might assume that it would give you the value of the
LastName field of the current record.
In the above example, Paradox will return the value of the field for the current row. This brings up some interesting questions as to how this
is done. Is there some type of "on demand" binding? Does Paradox simply ignore the full path of the object name in this situation? I'm not sure
what the answer is here, although I recognize that there are different ramifications for each.
Now let's take a moment to look at a slightly different scenario. Let's un-name the LastName field and attach to it by its noise name. In this
case, if you move to the next row and interrogate the value of the uiObject variable, it will contain the value in the previous row.
We can now further complicate things by bringing the built-in uiObject variable "active" into the discussion. If the cursor is in the LastName
field (or rather, the field we used to call LastName before we un-named it) and we attach a ui variable to active, then that variable will operate on
whatever the current row is (like our first example). On the other hand, if we were to attach the ui variable to active'name, then it would refer to
that specific field of that specific row (like our second example).
Am I bringing up all of this anomalous behavior to scare you? No. (Well, maybe a little! < g >) Keep in mind that the anomalies I just
mentioned don't tend to show themselves if the field has been explicitly named. When you attach to a field that is explicitly named, the ui variable
will always refer the the field within the current record.
I think that the reason why explicitly named field objects work without significant anomalies is because 99.9% of all tables are set up that way,
so that's the setup that Borland tried to make the most consistent. (This is also the way Paradox sets up tableFrames when it binds them to tables.)
The point I'm trying to make is that with regard to single- vs. multiple-record object anomalies, things seem to be exacerbated when the setup is
different from the "norm" (Paradox's default).
In the case of record objects, Paradox normally sets them up with noise names. If you were to explicitly name the object then you would end
up with a lot of objects on the form with EXACTLY the same name. (The same fullName, that is.) Although I don't recall personally running into
any issues here, given the anomalies I've already mentioned regarding field objects, the potential for running into problems seems quite
substantial. Thus as a general rule, I tend to recommend not opening this can of worms.
Even recognizing some problems with the approach I use, I still tend to avoid naming record objects where possible. Your case is a tough one,
as there seems to be quite a good reason for you to name the objects. If I were you, I'd probably continue with the approach you're taking
(assuming that there's no obvious way to remove the need to refer to the record object), and simply be aware of the issues so you can easily spot
them if they come up.
Regardless of how you reference an object (using self, active, etc.), the point I was trying to make was that Paradox works differently
when binding to a named field (or record) versus an unnamed field (or record) in some circumstances. Further, I was trying to point out that
attaching a variable to a uiObject does not necessarily bind the variable directly to the object specified. Instead, the binding can change at runtime,
attaching a variable to a uiObject does not necessarily bind the variable directly to the object specified. Instead, the binding can change at runtime,
such that Paradox makes it point to different physical objects at different times.