Forms sequence--design question

  • Thread starter Thread starter Gary Schuldt
  • Start date Start date
G

Gary Schuldt

"Everything was going along fine, and then . . . !"

I am not sure what the *best* way is to handle this problem--*best* meaning
high maintainability, high reuse, straightforward coding.

============================

I have a normal sequence of forms:

Seq#1: frmA --> frmB -->> frmC.

frmA is a search form (to isolate the frmB record), and from frmB you can
get to many frmC records (master -->> detail sort of pattern). A user would
normally start with the search frmA and go from there. From frmB you can
either just look at or even add C's via frmC.

==========================

Enter the spoiler, frmX!

frmX is sort of an "Xpress receiving" form, allowing you to (temporarily)
log in a bunch of C's without knowing precisely which B they are related to
.. . . something you'll determine later when you have time.

It's this "later", when you reprocess frmX data, that I'm not sure what to
do. You see, frmX has some stuff on it that needs to be carried over into
frmC (pushed to it or pulled by frmC). (This stuff is contained partly on
frmX and partly on a subfrmC within frmX.)

During this "reprocessing", the sequence is:

Seq#2: frmX.subfrmC --> frmA --> frmB -->frmC

Right now, in frmC OnOpen, I test to see if frmX IsLoaded, and, if so, pull
the stuff from it I need.

==================================

It works . . . but I see a flaw: Just because frmX IsLoaded doesn't mean I
got to frmC via Seq#2!

Instead, this could've happened:

UserThread 1: frmX . . . (incomplete Seq#2 that never opens frmC)

UserThread 2: Seq#1, ending up in frmC, which OnOpen finds out frmX is
loaded . . . but the context is probably wrong for pulling the data from
frmX into frmC.

================================

Potential Solution: OK, I could make "duplicates" of frms A, B and C--say
frmAx, frmBx, and frmCx--which would have basically the same functionality
as frms A, B, and C, except they would only run in Seq#2--i.e., initiated
starting with frmX.

That doesn't seem too smart, since I have essentially two copies of each of
three form modules, so, if for example I modify frmB I also probably have to
make the same modification to frmBx, and so on.

Or, I suppose I could devise enough globals and/or hidden unbound fields
that would communicate to frmC whether it was in the same UserThread as
frmX, but that seems really complex design. Anyway, I don't immediately see
how to do it!

====================

Appeal for help: Anyone have an elegant design solution to this problem? I
realize the problem statement is somewhat lengthy, but . . . nothing
ventured nothing gained!

Thanks.

Gary
 
Appeal for help: Anyone have an elegant design solution to this problem? I
realize the problem statement is somewhat lengthy, but . . . nothing
ventured nothing gained!

Well, it's worse than you think.

You're apparently totally focused on Forms. Forms don't contain any
data; Tables do. The user could have opened frmX; entered a dozen
records into its table; and closed frmX, before opening frmC at all.

What's wrong with making frmC a Subform of frmB, so that it
automatically maintains the link, and doing away with frmX altogether?
It would strike me as very risky to create unlinked TableC records,
without maintaining relational integrity, and then somehow hoping to
repair the orphan records later!
 
John,

First, thanks for having the patience to tackle my problem. I appreciate
it.
You're apparently totally focused on Forms. Forms don't contain any
data; Tables do.

Yes, I understand that. I made a choice not to introduce the tables into my
description of the problem, just in the interest of simplicity. But, behind
frmB there is a tB, and the same for frmC.
The user could have opened frmX; entered a dozen
records into its table; and closed frmX, before opening frmC at all.

And that would be a common scenario. frmX has a master/detail relationship
with its subfrmC, but the records in the table that underlies subfrmC aren't
full-fledged C records, they are "preliminary" (and as yet unlinked to tB)
descriptions which will only later end up as fully linked C-records.

In fact, that's the whole purpose of the frmX and its subfrmC: To give the
user the ability to quickly record some information known at that time
without burdening them with the full A-B-C sequence (which they will have to
do later on to get the info "officially" into the database). Think of frmX
as a scratchpad or a "to-do" list.
What's wrong with making frmC a Subform of frmB, so that it
automatically maintains the link, and doing away with frmX altogether?

In fact, frmC is functionally a subform of frmB, since you can't create an
instance of a C-record without first establishing its parent B-record.
That is reflected in both Seq#1 and Seq#2 that I described in my original
message.

This application has the same structure as cataloging and acquisitions in a
library system, except instead of books we have plants. FrmB is based on
tB, which represents the botanical data (genus / species /variety and other
characteristics of interest, such as growth rate, bloom time, leaf
retention, lifecycle, form). FrmC represents tC, which contains info about
specific physical plants, such as date acquired, where acquired from (FK to
tSource), price, container size, as well as eventual planting info (where,
when, etc.).

FrmX gives the user a place to record a Batch Acquisition of plants--namely,
a buncha plants gotten from one specific source (e.g., nursery, plant swap)
(a link to tSource) on a specific date and intended for a specific
OwnerGarden (link to tGarden).

Each line-item (subfrmC-data) contains a "best guess" at the genus / species
/ variety (without having to research books and / or web references or the
database itself to make sure it's authoritative); a quantity purchased, a
unit price, and the container size (gallon, 4"-pot, ball-and-burlap, etc.).
All that is info you tend to have immediately at hand as you unload the
plants, and you want to record that as quickly as possible, for various
reasons.

So FrmX supports a "receiving" function--just logging in what you brought in
in that one shopping spree (the batch). It's just that there's no order or
"invoice" (maybe just a cash register receipt) to check off the stuff
against, only the physical plants themselves and hopefully some tag on them.
The point is to record what info there IS (say on a laptop) while unloading,
when the info is fresh, rather than writing it down on paper and carrying it
indoors to make the formal, proper entry into the Plant Database.

What's labor-saving about the Batch Acquisition (frmX) is that later on one
can bring it up, double-click a line item, and the "best-guess" prefills the
cmbox search window in frmA, which goes against the botanical info tB to
either isolate an existing botanical record or, if you can't find one, add a
new one using frmB. You may have to tweak the "best-guess" prefill, but
you'd have to do that anyway (BatchAcq or not), maybe do some reference
searching for the proper name, etc.

After you're finished entering any botanical data (if necessary) via frmB,
you click cmdAddPlant go to frmC to record acquisition information for a
specific physical plant (the tC data). At that point a tC record is created
and linked to its parent tB record.

It's at that point where the data from frmX & subfrmC get carried over so
you don't have to retype the same acq. date, same source, same garden for a
batch of 12 plants . . . AND the quantity, price, and size that you entered
earlier also get carried over (together with a default planted-location of
"pot").

But you may not always be operating in a BatchAcquisition situation. You
might be describing physical plants that are already in the garden (planted
before the system came into operation). You still have to identify genus /
species / variety (the REAL WORK in this whole retrospective entry
operation!), create a new tB record if necessary, and then record the
physical plant info in tC. In this case, however, you cannot do any
prefills of info as described above, since frmX doesn't apply. You have to
type in your best acquisition guesses for each plant, or leave the fields
blank. (And, if it's already in the garden, its location is probably not
"pot".)

Now we are back to the original problem: When frmC is opened, how does it
know whether or not to "pull" the prefills? The code I have now uses
IsLoaded(frmX) to make the decision, but, for reasons already discussed,
that's not totally reliable. I thought additionally of putting a
cmdPullBatchAcqInfo? on frmC (of course made visible only if frmX is
loaded), but the user could always make a mistake, too.

In fact, the process, as currently designed, works ONLY if the current
record in frmX.subfrmC corresponds to the info you want to be recorded via
frmC in tC. It will fail if, at any point in the process after frmX.subfrmC
line item was double-clicked and before frmC was opened, you give focus to a
different subfrmC record.

So my goal is to make the system more robust without duplicating
functionality. I am thinking that the problem boils down to this: When
frmC opens, can it correctly know whether to pull info from frmX and subfrmC
or not . . . and, if so, how can it determine that? If it can't, am I
forced to create separate (but equal) chain of forms initiated by a frmX,
thereby duplicating a lot of code that already exists for the forms A, B and
C?

[BTW, if anyone out there needs a GardenPlantDatabase that has over 1000
botanical descriptions, complete with web text references and photos and
that can print labels (but designed by an obvious amateur), let me know!
This is just my hobby.]

Gary
 
Note 100% sure I follow the exact sequence. But two things come to mind.

First, make your forms model. That means when you close formc, you must
return to formB, and then when you close frmB, you must return to frmA.

Thus, model forms control the sequence you must follow.


Second:
You are allow to have multiple instances of the same form. So, you might
have a general search form called frmA, but the tables, and even the form
that is opened AFTER frmA does not necessary have to be frmb.

in other words, each instance of the SAME form can have its own records etc,
and not impact, or nor interfere with other forms.

So, in theory, you could have 3 or 4 or 5 instances of frmA opened all at
the same time...

So, you can have more then one copy of frmc opened. And, you can pass some
pars to the frmC, or in the case of multiple instances...simply make some
custom methods of that form...and set that...

So, just make that frmX open frmC (or a another instance) of frmc. And, you
can always pass parms, or have the calling form (fmbB, or frmX) setup values
and run procedures in the formC as you wish...
 
Albert,

(sorry for the delay in replying!)

Thanks for the helpful ideas! I haven't used modal forms much, so I will
have to experiment with them to see how they behave. I know they involve
some constraints on other open forms and whether they can get focus.

What I'm not sure about is, if frmB has been opened modally, then can some
CBF in frmB open another frmC (modally or not)?

I'll check my reference works!

Gary
 
Gary Schuldt said:
Albert,

(sorry for the delay in replying!)

Thanks for the helpful ideas! I haven't used modal forms much, so I will
have to experiment with them to see how they behave. I know they involve
some constraints on other open forms and whether they can get focus.

What I'm not sure about is, if frmB has been opened modally, then can some
CBF in frmB open another frmC (modally or not)?

yes....
 
Back
Top