Navigation: ABC Library Reference > ViewManager >====== ViewManager Overview ====== | |
The ViewManager class manages a VIEW. The ViewManager gives you easy, reliable access to all the sophisticated power and speed of VIEWs, through its proven objects. So you get this speed and power without reinventing any wheels.
ViewManager Concepts
The management provided by the ViewManager includes defining and applying multiple sort orders, range limits (key based filters), and filters (non-key based) to the VIEW result set. It also includes opening, buffering, reading, and closing the VIEW. Finally, it includes priming and validating the view's primary file record buffer in anticipation of adding or updating records.
All these services provided by the ViewManager are applied to a VIEW–not a FILE. A VIEW may encompass some or all of the fields in one or more related FILEs. The VIEW concept is extremely powerful and perhaps essential in a client-server environment with normalized data. The VIEW lets you access data from several different FILEs as though from a single file, and it does so very efficiently. See VIEW in the Language Reference for more information.
In addition, the ViewManager supports buffering (some file drivers do not support buffering) which allows the performance of “browse” type procedures to be virtually instantaneous when displaying pages of records already read. Buffering (see BUFFER in the Language Reference) can also optimize performance when the file driver is a Client/Server back-end database engine (usually SQL-based), since the file driver can then optimize the calls made to the back-end database for minimum network traffic.
ViewManager Relationship to Other Application Builder Classes
The ViewManager relies on the FieldPairsClass and the RelationManager to do much of its work. Therefore, if your program instantiates the ViewManager it must also instantiate these other classes. Much of this is automatic when you INCLUDE the ViewManager header (ABFILE.INC) in your program's data section. See Field Pairs Classes and Relation Manager Class for more information. Also, see the Conceptual Example.
Perhaps more significantly, the ViewManager serves as the foundation of the BrowseClass and the ProcessClass. That is, both the BrowseClass and the ProcessClass are derived from the ViewManager.
BrowseClass–An Interactive VIEW
The BrowseClass implements an interactive VIEW that includes a visual display of records with scrolling, sorting, searching, and updating capabilities. See Browse Classes for more information.
ProcessClass–A Non-Interactive VIEW
The ProcessClass implements a batch (non-interactive) VIEW with sorting and updating capability, but no visual display and therefore no scrolling or searching capability. See Process Class for more information.
ViewManager ABC Template Implementation
The ViewManager serves as the foundation to the Browse procedure template, the Report procedure template, and the Process procedure template, because all these templates rely on VIEWs.
The BrowseClass and the ProcessClass are derived from the ViewManager, and the ABC Templates instantiate these derived classes; that is, the templates do not instantiate the ViewManager independently of the BrowseClass or ProcessClass. The Browse procedure template instantiates the BrowseClass, and the Process and Report procedure templates instantiate the ProcessClass.
ViewManager Source Files
The ViewManager source code is installed by default to ..\LIBSRC. The specific ViewManager files and their respective components are:
ABFILE.INC | ViewManager declarations | |
ABFILE.CLW | ViewManager method definitions |
ViewManager Conceptual Example
The following example shows a typical sequence of statements to declare, instantiate, initialize, use, and terminate a ViewManager object. This example simply establishes a VIEW with a particular sort order, range limit and filter, then processes the result set that fits the range and filter criteria.
PROGRAM
INCLUDE('ABFILE.INC') !declare ViewManager class
MAP !program map
END
GlobalErrors ErrorClass !declare GlobalErrors object
View:Customer ViewManager !declare View:Customer object
Access:CUSTOMER CLASS(FileManager) !declare Access:Customer object
Init PROCEDURE
END
Relate:CUSTOMER CLASS(RelationManager)!declare Relate:Customer object
Init PROCEDURE
END
CUSTOMER FILE,DRIVER('TOPSPEED'),PRE(CUS),THREAD,BINDABLE
BYNUMBER KEY(CUS:CUSTNO),NOCASE,OPT,PRIMARY
Record RECORD,PRE()
CUSTNO LONG
NAME STRING(30)
ZIP DECIMAL(5)
END
END
Customer:View VIEW(CUSTOMER) !declare Customer VIEW
END
Low LONG !low end of range limit
High LONG(1000) !high end of range limit
ProgressMsg STRING(60)
ProgressWindow WINDOW('Processing…'),AT(,,215,60),GRAY,TIMER(100)
STRING(@S60),AT(1,21,210,10),USE(ProgressMsg),CENTER
BUTTON('Cancel'),AT(87,37,45,14),USE(?Cancel)
END
CODE
GlobalErrors.Init !initialize GlobalErrors object
Relate:CUSTOMER.Init !initialize Relate:Customer object
View:Customer.Init(Customer:View,Relate:CUSTOMER) !initialize View:Customer object
View:Customer.AddSortOrder( CUS:BYNUMBER ) !add sort BYNUMBER
View:Customer.AppendOrder( 'CUS:Name,CUS:ZIP' ) !add secondary sorts
View:Customer.AddRange(CUS:CUSTNO,Low,High)!add a range limit
View:Customer.SetFilter( 'CUS:ZIP=33066','1') !add filter #1
Relate:CUSTOMER.Open !open customer & related files
OPEN(ProgressWindow) !open the window
ProgressMsg='Processing…'
ACCEPT
CASE EVENT()
OF Event:OpenWindow
View:Customer.Reset(1) !open view, apply range & filter
OF Event:Timer
CASE View:Customer.Next() !get next view record
OF Level:Notify !if end of file, stop
POST(EVENT:CloseWindow)
BREAK
OF Level:Fatal !if fatal error, stop
POST(EVENT:CloseWindow)
BREAK
END
CUS:ZIP=33065 !process the record
IF Relate:CUSTOMER.Update() !update customer & related files
BREAK
ELSE
ProgressMsg = CLIP(CUS:Name)&' zip changed to '&CUS:ZIP
DISPLAY(ProgressMsg)
END
END
IF FIELD() = ?Cancel !if user cancelled, stop
IF EVENT() = Event:Accepted
POST(Event:CloseWindow)
END
END
END
Relate:CUSTOMER.Close !close customer & related files
View:CUSTOMER.Kill !shut down View:Customer object
Relate:CUSTOMER.Kill !shut down Relate:Customer object
GlobalErrors.Kill !shut down GlobalErrors object
Access:CUSTOMER.Init PROCEDURE
CODE
PARENT.Init(Customer,GlobalErrors)
SELF.FileNameValue = 'CUSTOMER.TPS'
SELF.Buffer &= CUS:Record
SELF.AddKey(CUS:BYNUMBER,'CUS:BYNUMBER',1)
SELF.LazyOpen = False
Relate:CUSTOMER.Init PROCEDURE
CODE
Access:CUSTOMER.Init
PARENT.Init(Access:CUSTOMER,1)