I have been doing a lot of reading up on n-tier stuff - User services, Business services, data services etc. My Question is :
It is fine to talk about GUI -> Business Layer/service -> Data Service,and it can be implemneted - but has anybody implemented a regular commercial app where the Reporting also goes thru 'Business Service' ( Which i equate to Bizobjs ) ?
Curious to know !
Prakash R Bhat
prb@giasmd01.vsnl.net.in
Hi Prakash:
<I><FONT COLOR="#663300">I have been doing a lot of reading up on n-tier stuff - User services, Business services, data services etc. My Question is :
It is fine to talk about GUI -> Business Layer/service -> Data Service,and it can be implemneted - but has anybody implemented a regular commercial app where the Reporting also goes thru 'Business Service' ( Which i equate to Bizobjs ) ?
</I>
There is a class library in SAVI Codebook named cSAVIPrt.VCX. It contains one class named SAVIPrintingForm. This class, coupled with the event object can accomplish exactly what you are looking for. Define the required business objects as participant objects of the event. In the execute event method of the event, requery the business objects to obtain the data you require (any amount of pre-processing can be attached here that accepts parameters from users etc.) This, in effect, is how I set up the printing environment ... it is a more dynamic way of reporting that using the Codebook standard. The SAVIPrintingForm accepts the name of the .FRX file and a title to display when printing the report. This form allows the user to preview, print with dialog, print without dialog or print to a file.
Let me know if you have any questions. I believe that you have the version of SAVI Codebook that contains aforementioned .VCX.
Take care,
CTBlankenship
mailto:ctb@savvysolutions.com
Flash Creative Management, Inc. (FLASH)
ctb@flashcreative.com
tomandanna@erols.com
Prakash,
What you're asking seems out of reach with the present state of VFP
report writer. But we may try to tend to it. Here is what I am doing
right now.
Since VFP reports are not object oriented, I prepare one template report
per project.
In the BeforeOpenTables(), I create the report session environment:
goApp.oReportSessionEnvironment=CREATEOBJECT("cReportSessionEnvironment")
Its purpose is to SET all the fixed settings I'll need with all reports.
Code follows at the end of the message.
In the init(), I do the following:
LOCAL loDataEnvironment
*-- instantiate the Data Environment
*-- this will load all cursors needed for the report.
*-- Because the environment object is local, it will be
*-- destroyed when the object goes out of scope (when the
*-- init() method is exited). Since AutoCloseTables is set
*-- to .F., the cursors will stay open.
loDataEnvironment = CREATEOBJECT("<DataEnvironment>")
RETURN TYPE("loDataEnvironment") == "O"
and in the destroy I release the report session environment object
goApp.oReportSessionEnvironment = .NULL.:
You can make what you want in the init(). By example, if you use a
parameterized view, you could call a form to obtain the view parameters.
After trying out many things, I've found that the most convenient way is
to create a cursor with as many fields as the view parameters, and insert
a blank record. I pass the datasession as a parameter to the model form,
make sure that it shares the same datasession as the report, obtain the
view parameters, save them in the cursor. Once back in the Init() of the
report I can requery the view and proceed with the report.
**************************************************
*-- Class: creportsessionenvironment
(c:cdbk30common30libscenviron.vcx)
*-- ParentClass: cenvironment (c:cdbk30common30libscenviron.vcx)
*-- BaseClass: container
*
#INCLUDE "c:cdbk30common30includeframincl.h"
*
DEFINE CLASS creportsessionenvironment AS cenvironment
lsaveoldsettings = .F.
Name = "creportsessionenvironment"
PROCEDURE set
SET DELETED ON
SET TALK OFF
SET SAFETY ON
SET POINT TO ","
SET SEPARATOR TO "."
SET DATE FRENCH
SET CURRENCY TO "F"
SET CURRENCY RIGHT
SET CENTURY ON
ENDPROC
ENDDEFINE
*
*-- EndDefine: creportsessionenvironment
**************************************************
JosÃ
œ
I want to create a user-interface like Outlook's for my phone numbers. The one described in the November FPA won't do because phones are normalized out of the main contact table in my application and not in his. So the textbox portion of the container will have to have a distinct view because each phone number will be looking at a different record in the same table. Is there a reasonable way to design the middle tier of this so that one phone business object can handle mutilple controls or is the only reasonable design to have a separate phone business object for each phone control container on the form? It seems like an awful lot of overhead for a little phone number.
:-) Pamela
pamela@eagle-crest.com
<I><FONT COLOR="#663300">I want to create a user-interface like Outlook's for my phone numbers. The one described in the November FPA won't do because phones are normalized out of the main contact table in my application and not in his. So the textbox portion of the container will have to have a distinct view because each phone number will be looking at a different record in the same table. Is there a reasonable way to design the middle tier of this so that one phone business object can handle mutilple controls or is the only reasonable design to have a separate phone business object for each phone control container on the form? It seems like an awful lot of overhead for a little phone number.</FONT></I>
Pamela
What we have decided to do is to have collections of addresses and phones so we have one child bizobj for each collection and one grandchild object for the item in the collection. in other words, we have a bizob child to obizobj that displays a combobox of the phone types associated with this bizobj instance <view param>, this object has a child object that dispays this phone number of this type for this "customer" same with addresses
HTH
Allan Lindgren
akl@morningstar-healing.com
Author: Michael Babcock
Posted: 2001-06-04 13:38:57 Link
Someone mentioned earlier about "why would you hardcode a controlsource" when
designing an n-tier system=2E Now I can see the non-grid objects (txt,lbl,cbo,
etc=2E) having a custom form property for a control source, but what would you
do about 1:many items like grids? My guess is that you'd use a custom form
property ARRAY to hold the values?
Is anyone doing this now? (I'm guessing CharlieGC since he's using
SCATTER/GATHER a lot instead of buffering=2E=2E=2E) ???
=20=
=20=
=20=
=20=
=20=
=20=
=20=
=20=
*****************************************************
Michael Babcock
KePRO, Inc
Tel: 717-564-8288
Fax: 717-564-4188
Internet Address: mbabcock@kepro=2Eorg
Home Page: http://www=2Ekepro=2Eorg
*****************************************************
Author: A Hilton
Posted: 2001-06-04 14:00:37 Link
The mountain is, indeed, there ... but it only has to be climbed once.
You're talking n-tier here... ease has nothing to do with it. <g> Throw your
boots away after the first climb and make or buy a class that handles these
disconnected cursor retrieving/updating/deleting tasks for you. Personally,
I choose "make it" but that's just the way I am.
Yes. You should manage the updates manually and you *should* have a UID
(Unique ID) for each record. This allows you to go straight to the record(s)
you need without having to depend on recno(). Depending on your data store,
you have options as to how you do the actual updating. I've seen developers
swear by just deleting the original record(s) and inserting new ones
all_the_time. I usually just swear at that one. <g> Others never insert new
records if there's records marked for deletion ... just reusing them if
available. Do it however you wish but you'll still have to manage the
updating/insertion of records yourself.
As for buffering, I usually use a technique I call "Optimistic Realism". For
the actual locks, I setup the data store as optimistic (physically locking
at the time of update/insertion = "Optimistic") but I use a class & fields
that store who/when/why the record/table was starting to be edited. This
allows some flexibility in managing "locks" on my data.Of course, it's not
used or even appropriate in all cases or even all apps of mine but it has
worked well for 1-tier, C/S, and n-tier work. But I think that was more than
you wanted to know. Sorry. I ramble.
- AHilton
>
> You would then have to code the updates manually, however, as
> they would be no
> physical tie to the real table (like in a view), right? You
> could still use
> the buffering I suppose with GETNEXTMODIFIED to determine what record to
> update, and then dynamically generate the UPDATE SQL assuming the
> record has a
> unique identifier for it. Seems like a lot of work, however. Perhaps I'm
> making a mountain out of a mole-hill?
Author: Michael Babcock
Posted: 2001-06-04 14:20:28 Link
You would then have to code the updates manually, however, as they would be no
physical tie to the real table (like in a view), right? You could still use
the buffering I suppose with GETNEXTMODIFIED to determine what record to
update, and then dynamically generate the UPDATE SQL assuming the record has a
unique identifier for it=2E Seems like a lot of work, however=2E Perhaps I'm
making a mountain out of a mole-hill?
>>> "ahilton@usexpr=2Ecom" 06/04/01 02:11PM >>>
You can just use a temp cursor retrieving them as needed from your
upper-tier=2E
- AHilton
> Someone mentioned earlier about "why would you hardcode a
> controlsource" when
> designing an n-tier system=2E Now I can see the non-grid objects
> (txt,lbl,cbo,
> etc=2E) having a custom form property for a control source, but
> what would you
> do about 1:many items like grids? My guess is that you'd use a
> custom form
> property ARRAY to hold the values?
>
> Is anyone doing this now? (I'm guessing CharlieGC since he's using
> SCATTER/GATHER a lot instead of buffering=2E=2E=2E) ???
>
=20=
=20=
=20=
=20=
=20=
=20=
=20=
=20=
=20=
=20=
=20=
=20=
=20=
=20=
=20=
=20=
*****************************************************
Michael Babcock
KePRO, Inc
Tel: 717-564-8288
Fax: 717-564-4188
Internet Address: mbabcock@kepro=2Eorg
Home Page: http://www=2Ekepro=2Eorg
*****************************************************
Author: Michael Babcock
Posted: 2001-06-04 16:26:04 Link
Ramble away---I appreciated your viewpoints! In some of the ASP code (where
an update is required), I've seen code more/less like the following: UPDATE
MyTABLE Set MyField1=3DlcField1, MyField2=3DlcField2, <etc=2E> WHERE UID=3DlcUID=20=
=20=
so if only 1 field is really changed, the entire record contents get changed,
not just the changed field=2E They dynamically build the SQL statement composed
of all the fields, not just the updated one, stepping through the Fields
collection=2E Not very efficient IMO, but perhaps it's easier to code it that
way than to write all the conditional logic to build the UPDATE SQL for only
the field that has updated=2E I haven't personally coded anything web-related
yet (via ASP), so I can't speak from experience=2E I've got samples from folks
on the list but have had limited time to explore them in depth=2E "So much to
do; so little time in which to do it=2E"
>>> "ahilton@usexpr=2Ecom" 06/04/01 03:09PM >>>
The mountain is, indeed, there =2E=2E=2E but it only has to be climbed once=2E
You're talking n-tier here=2E=2E=2E ease has nothing to do with it=2E <g> Throw y=
our
boots away after the first climb and make or buy a class that handles these
disconnected cursor retrieving/updating/deleting tasks for you=2E Personally,
I choose "make it" but that's just the way I am=2E
Yes=2E You should manage the updates manually and you *should* have a UID
(Unique ID) for each record=2E This allows you to go straight to the record(s)
you need without having to depend on recno()=2E Depending on your data store,
you have options as to how you do the actual updating=2E I've seen developers
swear by just deleting the original record(s) and inserting new ones
all_the_time=2E I usually just swear at that one=2E <g> Others never insert new
records if there's records marked for deletion =2E=2E=2E just reusing them if
available=2E Do it however you wish but you'll still have to manage the
updating/insertion of records yourself=2E
As for buffering, I usually use a technique I call "Optimistic Realism"=2E For
the actual locks, I setup the data store as optimistic (physically locking
at the time of update/insertion =3D "Optimistic") but I use a class & fields
that store who/when/why the record/table was starting to be edited=2E This
allows some flexibility in managing "locks" on my data=2EOf course, it's not
used or even appropriate in all cases or even all apps of mine but it has
worked well for 1-tier, C/S, and n-tier work=2E But I think that was more than
you wanted to know=2E Sorry=2E I ramble=2E
- AHilton
=20=
=20=
=20=
=20=
=20=
=20=
=20=
=20=
=20=
=20=
=20=
=20=
=20=
=20=
=20=
=20=
=20=
=20=
=20=
=20=
*****************************************************
Michael Babcock
KePRO, Inc
Tel: 717-564-8288
Fax: 717-564-4188
Internet Address: mbabcock@kepro=2Eorg
Home Page: http://www=2Ekepro=2Eorg
*****************************************************
Author: A Hilton
Posted: 2001-06-05 11:59:07 Link
I have options for passing back numeric values, straight text, delimited
text, HTML, File path pointer (Pre-made HTML file, picture, ...), Arrays,
ADO and XML. These options are simply passed into the VFP COM server method
as a parameter. Again, it depends on the situation as to what I use but at
least those options are there.
Yes, VFP is very efficient in constructing and spitting back HTML strings. I
tend to let VFP handle that instead of the ASP page when I can. What's neat
(to me anyway) is when you are working on a project with actual "Web
Designers" and they want to enforce all of these visual design features,
elements and rules. You give them a few tables and a frontend to those
tables where they can store and manage their 'art of design' whereby you can
access those tables from your VFP COM server and spit back that stuff on the
fly. So, IOW, you have easy access to their web design (stored and updated
by them at anytime in the tables).
- AHilton
> So your ASP pages are simply passing HTML back and forth that is generated
> in/from your VFP COM objects? That should be more efficient anyway. That
> also sounds easier to control/code.
>