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