Module cReportDS.pkg
1//****************************************************************************//
2// //
3// $File name : cReportDS.PKG //
4// $File title : cReportDS class //
5// $Author : John Tuohy //
6// //
7// Confidential Trade Secret. //
8// Copyright 1991-1999 Data Access Corporation, Miami FL, USA //
9// All Rights reserved //
10// DataFlex is a registered trademark of Data Access Corporation. //
11// //
12// //
13//****************************************************************************//
14
15//************************************************************************
16// ReportDS.Pkg
17// Version: 1.1
18// Wed 11-25-1992 Created
19//
20// Author: John J. Tuohy
21//
22//************************************************************************
23// 10/19/97 JJT - changed find_init to send clear to srvr when DD used.
24// Otherwise parent is not cleared and it is attached in for
25// a find first.
26// 06/09/97 JJT - made mods for DD support. Request_Save in RO now sends
27
28//************************************************************************
29
30//
31// Report_Ds - Report class that can optionally use data_sets.
32//
33// If Data_sets are used the report can support batch updates where files
34// are saved and deleted (via request_save and request_delete).
35//
36// IMPORTANT: All constraints including "relates to" constraints MUST be
37// handled by the data_set and not the report object (when in Rome do as the
38// Romans). Also, the report's relate_main_file, No_Constrained_Find_State and
39// No_relate_state are ignored - these same properties in the data_set are used
40// instead.
41//
42// This class can be used as a non-data_set class (just don't set the server).
43//
44// New Syntax:
45//
46// To hook into a Data_set, three syntaxes
47// Object Order_Rpt is a Report_ds Using DATA_SET_NAME
48//
49// <or> Object Order_Rpt is a Report_ds
50// Report_Data_Set DATA_SET_NAME
51//
52// <or> Object Order_Rpt is a Report_ds
53// Set Server to DATA_SET_NAME
54//
55// New Public Interface:
56//
57// PROPERTY: Server
58// This is the object ID of the data_set. If 0, the report will behave
59// exactly like a non_ds report. This is usually only set once and
60// usually when the object is created. This can be done with the USING
61// object command line parameter, the SET SERVER TO command, or the
62// RPT_DATA_SET command.
63//
64// PROPERTY: Deferred_State (Default=TRUE)
65// This determines if accesses to the data_set causes refresh messages
66// to get sent to other objects using this data_set. Setting this TRUE
67// reduces traffic a bit. This can be set FALSE but you should know what
68// you are doing.
69//
70// PROCEDURE: Request_Save
71// If sent, will save the current record. Usually sent in OnBody section.
72// Use Entry_Update message to make the changes during the save process.
73// All parent files are properly modified. This is M/U solid.
74//
75// PROCEDURE: Request_Delete
76// If sent (usually in the body) this will delete the current record thru
77// the data_set. After delete the record remains unchanged in the buffer
78// (including the recnum). All parent files are properly updated and
79// all multi-user requirements are met.
80//
81// PROCEDURE Entry_Update
82// Does nothing. This is the user hook that you fill out to make changes
83// the record you are saving. If this were a DEO this would get called
84// when you need to update from the forms to the database. This is a
85// manual version of this.
86//
87// PROCEDURE Refresh
88// This is normally a stub that does nothing. A clever data_set expert
89// might be able to make use of this.
90//
91
92use cReport.pkg
93use DataDict.pkg
94
95
96{ ClassLibrary=WebApp ClassType=Abstract }
97{ HelpTopic=cReportDS }
98Class cReportDS is a cReport
99
100 Procedure Construct_Object // Integer Img#
101 Forward Send Construct_Object // Img#
102
103
104 { DesignTime=False }
105 Property Integer Server 0 // data_set
106 // When used with DDs, deferred_state will really not work properly and
107 // should therefore be avoided.
108 { Visibility=Private }
109 { PropertyType=Boolean }
110 Property Integer Deferred_State False // makes less traffic
111 { Visibility=Private }
112 { PropertyType=Boolean }
113 Property Integer Auto_Fill_State False // Required not used
114 End_Procedure // Construct_Object
115
116 { MethodType=Event Visibility=Private }
117 Procedure Refresh // Display - required
118 End_Procedure
119
120 { Visibility=Private }
121 Procedure Entry_Update // Update from report to datafile.
122 End_Procedure // User hook routine.
123
124 { Visibility=Private }
125 Function Validate_items integer fg returns integer // called during request_validate to DDO
126 End_Function
127
128 Procedure Request_Delete // Supports deletes. Should be called in body
129 Integer Srvr# iRec // procedure.
130 integer iFile iStat
131 Boolean bSupportRecnum
132 Get Server to Srvr#
133 If Srvr# Begin
134 if (Deferred_State(self)) ;
135 send Request_Assign to srvr# 0 //0 means main_file of Server
136 // when deleted the record number is lost. Remember this number
137 // and restore it so that findings will work properly.
138 Get main_file of srvr# to iFile
139 Move (IsRecnumTable(self,iFile)) to bSupportRecnum
140 If bSupportRecnum Begin
141 Get_Field_value iFile 0 to iRec // compatibility w/ recnum
142 end
143 Send Request_Delete to Srvr#
144 If bSupportRecnum Begin
145 // now move rec back into file if a delete really occured
146 Get_Attribute DF_FILE_STATUS of iFile to iStat
147 If (iStat=DF_FILE_INACTIVE) Begin
148 Set_Field_value iFile 0 to iRec // compatibility w/ recnum
149 end
150 end
151 End
152 End_Procedure
153
154 Procedure Request_Save // supports saves
155 Integer Srvr# // entry_update should handle updating.
156 Integer NotOK
157 Get Server to Srvr#
158 If Srvr# Begin
159 if (Deferred_State(self)) ;
160 send Request_Assign to srvr# 0 //0 means main_file of Server
161 Set Changed_state of Srvr# to TRUE
162 Get Request_Validate of Srvr# to NotOK
163 If NotOk Procedure_return
164 Send Request_Save to Srvr# // note: returns ERR if error occurred
165 End
166 End_Procedure
167
168 // See notes in DoRunReport. Added in 11.1 Attaches all reports to all DDs just once in outer report
169 { Visibility=Private }
170 Procedure AddReportsToServer
171 Handle hoDD
172 Boolean bHasChildren
173 Get pbHasChildReports to bHasChildren
174 get Server to hoDD
175 If hoDD Begin
176 Send Add_User_Interface of hoDD self
177 end
178 if bHasChildren Begin
179 Broadcast Send AddReportsToServer
180 end
181 end_Procedure
182
183 // See notes in DoRunReport. Added in 11.1 detaches all reports from all DDs just once in outer report
184 { Visibility=Private }
185 Procedure RemoveReportsFromServer
186 Handle hoDD
187 Boolean bHasChildren
188 Get pbHasChildReports to bHasChildren
189 get Server to hoDD
190 // remove in childmost order. This is what the old behavior did, so just keep using it
191 if bHasChildren begin
192 Broadcast Send RemoveReportsFromServer
193 end
194 If hoDD Begin
195 Send Remove_User_Interface of hoDD self
196 end
197 end_Procedure
198 //
199 // Augmented to add this object from the Data_set's user interface
200 //
201 { NoDoc=True }
202 Function DoRunReport returns integer
203 Integer Retval
204 // 11.1 change. The outer report will attach all child reports to their DDs at the start of the
205 // report and not every time a child starts (this slowed down reports). This connection is only needed
206 // if you are sending request_save from your report and you are counting on using entry_update to update
207 // your fields. This is an old technique and is not recommended. It would be better to interact directly
208 // with the DD using the DD interface. All of this extra work of attaching and detaching is only provided
209 // for backwards compatibility. Also, this might make more sense in Starting_main_report, but we are keeping
210 // it here for compatibility reasons. Otherwise, we'd just remove all of the attaching/detaching completely.
211 // All of the above appliues to End_report.
212 If (not(pbChildReport(self))) begin
213 Send AddReportsToServer
214 end
215 forward get DoRunReport to retval
216 Function_Return retval
217 End_Function // DoRunReport
218
219 //
220 // Augmented to remove this object from the Data_set's user interface
221 //
222 { NoDoc=True }
223 // See notes in DoRunReport about 11.1 change
224 Function End_Report integer rpt_Status returns integer
225 Integer Retval
226 forward get end_report rpt_status to retval
227 If (not(pbChildReport(self))) begin
228 Send RemoveReportsFromServer
229 end
230 Function_Return retval
231 End_Function
232
233 //
234 // Procedure: Find_Init
235 // set up this file for finding... This clears the needed buffers
236 //
237 { Visibility=Private }
238 Procedure Find_Init
239 Integer Srvr# Mode file# ndx#
240 Get Server to Srvr#
241 If Srvr# eq 0 Forward send Find_init
242 Else begin
243 Move (if(pbFindDown(self),1,3)) to Mode // LE or GE
244 Get main_file of srvr# to File#
245 Get piOrdering to Ndx#
246 // 9/7/98 JJT - we do not need to set the DDO
247 // ordering
248 //Set Ordering of Srvr# to Ndx#
249 Send Rebuild_Constraints to Srvr#
250 // we only want to clear parents of the outer report. This was changed in 11.1. The Clear
251 // message is not needed with child reports and it can really slows things down because it
252 // adds a lot of DD messages (even when deferred). This clear is only needed at the top report
253 // level where a buffer may contain unknown parent data. With child reports this is controlled.
254 If Not (pbChildReport(self)) begin
255 Send Clear to Srvr# // this will clear needed parents as well
256 End
257 Constrained_Clear Mode File# BY Ndx#
258 Send establish_find_direction to srvr# mode file# Ndx#
259 end
260 End_Procedure
261
262 //
263 // Augment to find record in Data_set if Server exists
264 //
265 { Visibility=Private }
266 Function Find_Rec Returns Integer
267 Integer srvr# rval
268 Integer File# Ndx# Dfrd
269 integer iRec
270 Get server to srvr#
271 if srvr# eq 0 begin // if no server do
272 forward get find_rec to rval // standard finding
273 function_return rval // behavior
274 end
275 //
276 // Server exists. Channel the Find through the data_set
277 //
278 Get main_file to File#
279 Get piOrdering to Ndx#
280 Get Deferred_State to Dfrd
281 // if not deferred find next record and notify all other DEOs
282 // if deferred just find the record
283 If Dfrd eq 0 Send Request_Find to Srvr# Next_record file# Ndx#
284 Else Send Locate_Next to Srvr#
285 If (Found) Begin // set priFoundRec
286 Set priFoundRec to (GetRowId(File#))
287 // for compatibility sake.
288 If (IsRecnumTable(self,File#)) begin
289 Get_field_value File# 0 to iRec // compatibility w/ recnum
290 Set Found_Rec to iRec
291 end
292 Function_Return RPT_OK
293 End
294 Function_return RPT_END
295 End_Function
296
297 { Visibility=Private NoDoc=True }
298 Procedure ReadByRowId RowId riRec
299 Handle hoDD
300 integer iFile eStat
301 rowId riCrnt riDDO
302 Boolean bSameRec
303
304 // optimized for 11.1: If no find is needed, don't find. If DD is up to date, leave it alone
305 // We will not find if rec if active and is the same RowId. If DDOs and not-deferred, CurrentRowId must also match
306
307 Get Server to hoDD
308 Get Main_File of (if(hoDD,hoDD,self)) to iFile // main-file from Object or DDO (if ddo)
309
310 // if no main file we cannot find
311 If (iFile=0) Begin
312 indicate Found False
313 Procedure_Return
314 End
315
316 Get_Attribute DF_FILE_STATUS of iFile to eStat
317 Move (eStat<>DF_FILE_INACTIVE) to bSameRec
318 If bSameRec begin
319 Move (GetRowID(iFile)) to riCrnt
320 Move (IsSameRowId(riRec,riCrnt)) to bSameRec
321 Indicate Found True // you should not rely on this - but just in case.
322 End
323
324 If not hoDD begin
325 If not bSameRec Begin
326 Forward send ReadByRowId riRec
327 end
328 end
329 Else Begin
330 If (Deferred_state(self)) begin
331 If not bSameRec begin
332 Send ReadbyRowId of hoDD iFile riRec // if deferred
333 End
334 end
335 Else Begin
336 Get CurrentRowId of hoDD to riDDO
337 If ( Not(bSameRec) or Not(IsSameRowId(riRec,riDDO)) ) begin
338 Send FindByRowId of hoDD iFile riRec // if not deferred
339 End
340 end
341 End
342 End_procedure
343// Procedure ReadByRowId RowId riRec
344// Handle hoDD
345// integer iFile
346// Get Server to hoDD
347// If not hoDD begin
348// Forward send ReadByRowId riRec
349// end
350// Else Begin
351// Get Main_File of hoDD to iFile
352// If (Deferred_state(self)) begin
353// Send ReadbyRowId of hoDD iFile riRec // if deferred
354// end
355// Else Begin
356// Send FindByRowId of hoDD iFile riRec // if not deferred
357// end
358// End
359// End_procedure
360
361
362// //
363// // Procedure : Read_By_RecNum
364// // Augmented to direct read to server
365// //
366// //Doc/ Visibility=Private
367// Procedure Read_by_RecNum Integer Rec#
368// Integer srvr# File#
369// Get Server to Srvr#
370// If Srvr# eq 0 Forward send Read_by_Recnum Rec#
371// Else Begin
372// Get Main_File of Srvr# to File#
373// If (Deferred_state(self)) ;
374// Send Read_by_Recnum to srvr# File# rec# // if deferred
375// Else Send Find_by_Recnum to srvr# File# rec# // if not deferred
376// End
377// End_procedure
378
379 //**Procedure rebuild_constraints
380 //** Integer srvr#
381 //** Get server to srvr#
382 //** if srvr# eq 0 forward send rebuild_constraints
383 //** Else Begin
384 //** send rebuild_constraints to srvr#
385 //** if (Constrain_by_Report_State(self)) Send constrain
386 //** End
387 //**End_procedure
388 //**
389 //**Procedure constrain
390 //** integer srvr# file# Prnt_srvr#
391 //** Get server to srvr#
392 //** If Srvr# eq 0 Forward send constrain // this'll set object relates to constraint
393 //** else begin
394 //** if (pbChildReport(self)) begin
395 //** delegate get Server to Prnt_srvr#
396 //** CONSTRAIN (Main_File(srvr#)) RELATES TO ;
397 //** (if(prnt_srvr#=0,;
398 //** Main_File(Parent(self)), Main_file(Prnt_Srvr#)))
399 //** end
400 //** end
401 //**End_Procedure
402
403 //
404 // Augment to set Report Object's main_file if server exists
405 //
406 Procedure End_Construct_Object
407 Integer Srvr# File#
408 Get Server to Srvr#
409 If Srvr# Begin
410 Get Main_file of Srvr# to File#
411 Set Main_File to File#
412 End
413 Forward Send End_Construct_Object
414 End_Procedure
415
416
417End_Class
418
419
420//
421// Set a report's dataset
422//
423#COMMAND Report_Data_Set R .
424 #IFDEF !1
425 set Server to !1
426 #ELSE
427 set Server to !1.obj
428 #ENDIF
429#ENDCOMMAND
430