1023 lines
56 KiB
Plaintext
1023 lines
56 KiB
Plaintext
Function Set_Record(Data, DictColPos, VirtualOnly, SkipSymbolics, Window)
|
|
|
|
/***********************************************************************************************************************
|
|
|
|
This program is proprietary and is not to be used by or disclosed to others, nor is it to be copied without written
|
|
permission from SRP Computer Solutions, Inc.
|
|
|
|
Name : Set_Record
|
|
|
|
Description : Updates an OpenInsight window's controls with the data being passed in.
|
|
|
|
Notes : The primary purpose of this routine is to make it easier to update the contents of an OpenInsight
|
|
window without having to name the controls. This allows the developer to simulate the AREV method
|
|
which would automatically update the window's fields whenever @RECORD was update. OpenInsight
|
|
makes this more cumbersome by requiring each control to be updated individually using a property
|
|
setting.
|
|
|
|
Set_Record provides a level of automation that simulate AREV's @RECORD support. The developer can
|
|
pass in a specific field position and the data that needs to be updated in that field or the
|
|
developer can pass in the entire record array. Set_Record will automatically query the window's
|
|
controls and update them as needed. Even symbolic fields will be updated accordingly.
|
|
|
|
(NOTE: OpenInsight 7.2 introduced a new property - ATRECORD. This works the same as the RECORD
|
|
property when used in the Get_Property function. However, unlike the RECORD property it will update
|
|
the window's databound controls, including symbolic fields, when used in the Set_Property function.
|
|
This also simulates AREV's @RECORD support. However, it cannot be used to update specific fields at
|
|
a time or to update non-databound controls that need to be associated with database columns such as
|
|
OLE controls.)
|
|
|
|
Simulating @RECORD = RecordVar
|
|
==============================
|
|
|
|
In AREV, the entire data record could be updated at once by setting @RECORD to the new value. As
|
|
an example, if the developer needed to restore the content of the AREV window to the value of
|
|
record as it was read from the disk, the following line of code could be called:
|
|
|
|
@RECORD = WC_OREC% ; * Restore the contents of the original record.
|
|
|
|
To do the equivelent using Set_Record:
|
|
|
|
Set_Record(OrigRecord) ; // Restore the contents of the original record.
|
|
|
|
Simulating @RECORD<FieldVal> = FieldData
|
|
========================================
|
|
|
|
Individual database columns (aka fields) could also be updated by specifing the column number. In
|
|
AREV the code might look like this:
|
|
|
|
@RECORD<5> = 1000 ; * Put the customer number in place.
|
|
|
|
To do the equivelent using Set_Record:
|
|
|
|
Set_Record(1000, 5) ; // Put the customer number in place.
|
|
|
|
Value, subvalue, text, and subtext positions can also be updated by separating each delimiter
|
|
position with a comma. In AREV the code might look like this:
|
|
|
|
@RECORD<10, 2> = "8005552222" ; * Put the contact phone number in the
|
|
* 2nd value position of field 10.
|
|
|
|
To do the equivalent with this routine:
|
|
|
|
Set_Record("8005552222", "10,2") ; // Put the contact phone number in the
|
|
// 2nd value position of field 10.
|
|
|
|
|
|
Virtual Databound Controls
|
|
==========================
|
|
|
|
Sometimes controls that need to display live data are not truly databound to the database column.
|
|
A good example of this is if an ActiveX control is used to display and manage data. The internal
|
|
method OpenInsight uses to populate the window has no knowledge that these controls are connected
|
|
to the database in any way so they just get ignored.
|
|
|
|
Set_Record provides support for this through the use of the user-defined property @POS. This will
|
|
virtually bind the control to a database column (or columns, see below). Use the CREATE event of
|
|
the window to set @POS. For single field controls you would do something like:
|
|
|
|
Set_Property(@Window:".COMBO_1", "@POS", 5)
|
|
|
|
For multi-field controls (e.g. AMV fields) like the SRP OLE EditTable, just separate each database
|
|
column number with @VM. For instance:
|
|
|
|
Set_Property(@Window:".OLE_EDITTABLE1", "@POS", 2:@VM:5:@VM:6:@VM:"":@VM:7)
|
|
|
|
Set_Property(@Window:".OLE_EDITTABLE2", "@POS", 2:@VM:"DESCRIPTION":@VM:6)
|
|
|
|
In the first example, the first command has a null embedded between database columns 6 and 7. This
|
|
is to illusrate how one would handle an EditTable column that is not associated with a database
|
|
column. In the case of the SRP OLE EditTable, this could be a column of buttons or hyperlinks which
|
|
are there for functionality and not data storage.
|
|
|
|
The second example has a word embedded between database columns 2 and 6. This is to illustrate how
|
|
one would handle an EditTable column that is virtually bound to a symbolic (calculated) column. Just
|
|
enter then name of the symbolic column and this routine will recalculate the value and put the data
|
|
into the the appropriate EditTable column.
|
|
|
|
Handling Symbolic (aka Calculated) Columns
|
|
==========================================
|
|
|
|
As noted above in the Virtual Databound Controls section, non-databound controls can be virtually
|
|
bound to a symbolic column by using the @POS user-defined property. Set_Record will compute it using
|
|
the latest content from the data record.
|
|
|
|
By default, controls that are truly databound to symbolic columns will be recalculated after all the
|
|
data fields have been updated. However, sometimes this is not necessary or desirable. Once instance
|
|
would be during the window's WRITE event. Since OpenInsight windows clear all controls during a
|
|
successful database write, there is no need to go through the additional effort to recalculate
|
|
symbolic columns. In these situations set the SkipSymbolic parameter to 1:
|
|
|
|
Set_Record(RecordVar, "", Yes$)
|
|
|
|
Another option for handling symbolics using Set_Record is to update them while leaving all data
|
|
fields alone. This is useful when changes have been made to a virtually databound control and there
|
|
is a need to update the dependent symbolic controls. This is done by passing "SYM" into the
|
|
DictColPos parameter:
|
|
|
|
Set_Record("", "SYM")
|
|
|
|
A Word About Data Conversions
|
|
=============================
|
|
|
|
Native OpenInsight controls have validation and conversion settings which respond to the INVALUE
|
|
property. OLE controls, however, do not have validation and conversion settings that can be
|
|
configured in the Form Designer. Therefore, OLE controls must provide their own way of reporting
|
|
what validation and/or conversion patterns needed to be used. For the SRP OLE EditTable this is done
|
|
through the CellConv property. If a CellConv property has been set, the raw data will be converted
|
|
to this format first before the EditTable is visually updated. Otherwise, only internal data will be
|
|
displayed in the OLE control.
|
|
|
|
Parameters :
|
|
Data [in] -- The data that needs to updated into the controls. If DictColPos is not populated then
|
|
this should be an entire data record. Otherwise, it should only be the field data for
|
|
the indicated data column position.
|
|
DictColPos [in] -- The database column position being updated. If unassigned or null then Data is assumed
|
|
to be the entire data record. Value, subvalue, text, and subtext positions can also be
|
|
updated using commas to separate each delimiter position. See Notes for details.
|
|
VirtualOnly [in] -- Flag to determine if only virtually data databound controls should be updated. This
|
|
would be ideal during a READ event since has already updated the true databound
|
|
controls.
|
|
SkipSymbolics [in] -- Flag to determine if symbolic (calculated) columns should be updated. If unassigned or
|
|
null it will be Yes. This should be set to no if data is being updated during the WRITE
|
|
event. This will speed up the execution of this routine.
|
|
Window [in] -- The window being updated. If unassigned or null it will be @Window.
|
|
Record [out] -- The data record with updated values.
|
|
|
|
History : (Date, Initials, Notes)
|
|
01/27/06 dmb Original programmer
|
|
02/02/06 dmb Add new parameter, VirtualOnly, to indicate that only virtually databound controls (e.g. OLE
|
|
controls) should be updated. Modified the logic so that virtually databound controls will be
|
|
updated even if there are no true databound controls bound to the same data column.
|
|
02/03/06 dmb Add support for value, subvalue, text, and subtext updates to a single field. Fix problem
|
|
where symbolic columns weren't being updated if only a specific field is being updated.
|
|
Improved support for virtually bound controls so virtually bound symbolic columns will be
|
|
updated even if there are no controls that are actually bound to the symbolic column.
|
|
03/24/06 dmb Change EQ to _EQC when checking for SRP OLE EditTable ProgIDs.
|
|
03/24/06 dmb If the entire record is being set then clear SRP OLE EditTables to remove accidental data
|
|
from a previous record.
|
|
02/14/08 dmb New feature: Rows As Columns. This checks the @ROWSASCOLUMNS UDP which populates SRP
|
|
EditTable rows with database column data. Thus, the format is inverted.
|
|
02/15/08 dmb New feature: Cells as Fields. This checks the @CELLSASFIELDS UDP which populates SRP
|
|
EditTable cells with specific single-valued database columns.
|
|
02/17/08 dmb New feature: If DictColPos is set to "SYM" then only symbolic columns will be recalculated
|
|
and displayed.
|
|
02/17/08 dmb Remove Utility("CURSOR") calls. This was causing to many visual distractions.
|
|
03/04/08 dmb Don't use Clear method on SRP EditTables if they are also the control with focus.
|
|
03/18/08 rch Use @CLEARFILL setting if provided to Clear SRP EditTables.
|
|
12/09/10 rch Move 'While Flag' statements after Remove statements to just before Repeat statements so
|
|
the last value in each array gets processed by loop's logic.
|
|
12/01/12 krf Implement SRP FastArray processes to improve performance. Also built reliance upon the
|
|
@EDITTABLES UDP for the current window to store all SRP EditTable controls. Thus, this needs
|
|
to be populated from within the form's CREATE event or from the promoted CREATE event.
|
|
02/26/13 dmb UDPCtrl was not being populated using the SRP_FastArray_Extract so it was getting the
|
|
handle to UDPCtrls rather than the value stored in the hash table. - [SRPFW-8]
|
|
02/28/13 dmb UDP column positions and names were not being properly extracted since the Remove statement
|
|
is unable to handle the two-dimensional array that tracks these. - [SRPFW-10]
|
|
03/02/13 dmb Fix a reference to CellConv by extracting array <2> rather than the whole value. This was
|
|
left out during the last major enhancement conversion. - [SRPFW-10]
|
|
04/01/13 dmb Fix a VNAV issue in Get_Column_Positions gosub. Original code created a For/Next loop setting
|
|
the variable i. This For/Next loop was replaced with a Remove loop, but the variable i was
|
|
not being set. - [SRPFW-10]
|
|
|
|
***********************************************************************************************************************/
|
|
|
|
$insert Logical
|
|
$insert OIWin_Equates
|
|
If Assigned(Window) else Window = @Window
|
|
If Window EQ "" then Window = @Window
|
|
WinId = Window
|
|
$insert OIWin_Comm_Init
|
|
|
|
Declare function Get_property, Utility, OIWin_Compile_Impacts, Calculate, GetTickCount, SRP_FastArray_Create, SRP_FastArray_Extract, SRP_FastArray_GetVariable
|
|
Declare subroutine Set_Property, Utility, Send_Message, Send_Event, SRP_FastArray_Release, SRP_FastArray_Insert
|
|
|
|
Benchmark = ''
|
|
Total = ''
|
|
ProcessCnt = 0
|
|
ProcessDone = No$
|
|
Loop
|
|
ProcessCnt += 1
|
|
Until ProcessCnt GT 7 OR ProcessDone = Yes$
|
|
StartTime = GetTickCount()
|
|
On ProcessCnt GoSub Initialize_Vars, Set_At_Variables, Get_Column_Positions, Update_Window, Update_Record, Update_Symbolics, Clean_Up
|
|
EndTime = GetTickCount()
|
|
Benchmark := "Process ":ProcessCnt:": ":(EndTime - StartTime):"ms|"
|
|
Total += (EndTime - StartTime)
|
|
Repeat
|
|
Benchmark := "|Total ":Total:"ms"
|
|
* Call Msg(@Window, Benchmark)
|
|
|
|
GoSub Restore_At_Variables
|
|
|
|
Return Record
|
|
|
|
Initialize_Vars:
|
|
If Assigned(Data) else Data = ""
|
|
If Assigned(DictColPos) else DictColPos = ""
|
|
Convert " " to "" in DictColPos
|
|
|
|
Begin Case
|
|
Case DictColPos EQ ""
|
|
// DictColPos is null so the whole data record is being updated.
|
|
WholeRecord = Yes$
|
|
|
|
Case DictColPos _EQC "SYM"
|
|
// DictColPos is set to update only symbolics. To do this the WholeRecord flag needs to be set.
|
|
WholeRecord = Yes$
|
|
|
|
Case Num(DictColPos[1, 1])
|
|
// DictColPos is numerical so only a specific column is being updated.
|
|
WholeRecord = No$
|
|
|
|
Case Otherwise$
|
|
// An unrecognized value was sent in. Just assume the whole data record is being updated.
|
|
WholeRecord = Yes$
|
|
|
|
End Case
|
|
|
|
If Assigned(VirtualOnly) else VirtualOnly = No$
|
|
If VirtualOnly EQ "" then VirtualOnly = No$
|
|
If Assigned(SkipSymbolics) else SkipSymbolics = No$
|
|
If SkipSymbolics EQ "" then SkipSymbolics = No$
|
|
|
|
Controls = "" ; // List of OpenInsight controls that will be updated.
|
|
Properties = "" ; // List of OpenInsight properties that will be set. For native OI controls this will be INVALUE. OLE controls will use appropriate properties.
|
|
Values = "" ; // List of values that will be updated to the controls.
|
|
EdtCols = "" ; // EditTable column positions. AMV data is mapped to specific column positions within the EditTable control.
|
|
|
|
RowMaps = RowMaps@ ; // @VM/@SVM common array from OIWin_Comm_Init containing a list of all dictionary column names, their column numbers, and formatting information.
|
|
If RowMaps[-1, 1] = @VM then RowMaps[-1, 1] = ""
|
|
RMCount = Count(RowMaps, @VM) + (RowMaps NE "")
|
|
|
|
// @FM/@VM Common array of control, control type, and other relevant information. Subvalue 4 in each RowMaps entry has an index to this array.
|
|
MasterRowMap = SRP_FastArray_Create(MasterRowMap@)
|
|
MRCount = Count(MasterRowMap@, @FM) + (MasterRowMap@ NE "")
|
|
|
|
FocusControl = Get_Property(Window, "FOCUS") ; // Get the name of the control with focus will need this later.
|
|
|
|
UpdatedOLEEditTables = "" ; // Store the list of OLE EditTables already updated. Refer to this before executing a Clear method.
|
|
return
|
|
|
|
Set_At_Variables:
|
|
If Window NE @Window then
|
|
// Preserve the original values of @ variables in case a different window other than @Window is being updated.
|
|
Transfer @ID to OrigID
|
|
Transfer @RECORD to OrigRecord
|
|
Transfer @DICT to OrigDict
|
|
end
|
|
|
|
TableName = JoinMap@<1, 1>
|
|
If TableName NE "" then
|
|
// Set up @ variables so that symbolic (calculated) columns can be computed after the data record has been
|
|
// updated.
|
|
Dictionary = "DICT.":TableName
|
|
Open Dictionary to @DICT then
|
|
NumKeyCtrls = Count(KeyMap@, @FM) + (KeyMap@ NE "")
|
|
@ID = ""
|
|
For i = 1 to NumKeyCtrls
|
|
@ID := Get_Property(KeyMap@<i, 1>, "INVALUE"):"*"
|
|
Next i
|
|
@ID[-1, 1] = ""
|
|
|
|
Begin Case
|
|
Case WholeRecord EQ Yes$ AND DictColPos _NEC "SYM"
|
|
DelimDepth = 1
|
|
@RECORD = Data
|
|
|
|
Case WholeRecord EQ No$
|
|
GoSub ParseDictColPos
|
|
If DelimDepth GT 1 then GoSub Update_Data_Array
|
|
@RECORD = Get_Property(Window, "RECORD")
|
|
@RECORD<DictColPos> = Data
|
|
|
|
Case Otherwise$
|
|
// Most likely only updating symbolic columns. Make sure @RECORD is current.
|
|
@RECORD = Get_Property(Window, "RECORD")
|
|
|
|
End Case
|
|
|
|
end
|
|
end else
|
|
@RECORD = ""
|
|
end
|
|
return
|
|
|
|
Get_Column_Positions:
|
|
// Get the actual data column positions and the virtual (@POS) data column positions of the current window
|
|
// to set up in look up arrays
|
|
|
|
// Start with the actual data column positions. OpenInsight EditTable controls store data column positions
|
|
// as an @SVM delimited array. This code will flatten this out so each each EditTable column will have its
|
|
// own lookup reference.
|
|
OICtrls = SRP_FastArray_Create()
|
|
OICtrlColPos = SRP_FastArray_Create()
|
|
OICtrlEdtCol = SRP_FastArray_Create()
|
|
OICtrlTypes = SRP_FastArray_Create()
|
|
|
|
// These variables will track symbolic (calculated) column information so that the CALCULATE event or CALCULATE
|
|
// function can be executed as needed.
|
|
NumSymCtrls = 0
|
|
OISymCtrls = SRP_FastArray_Create()
|
|
OISymDepColPos = SRP_FastArray_Create()
|
|
OISymCtrlEdtCol = SRP_FastArray_Create()
|
|
OISymCtrlRowsAsColumns = SRP_FastArray_Create()
|
|
OISymCtrlCellsAsFields = SRP_FastArray_Create()
|
|
OISymCtrlSelPos = SRP_FastArray_Create()
|
|
OISymCtrlTypes = SRP_FastArray_Create()
|
|
OISymCtrlOrigText = SRP_FastArray_Create()
|
|
OISymCtrlColName = SRP_FastArray_Create()
|
|
|
|
OICtrlPos = 1
|
|
ControlSemanticPos = 1
|
|
ControlListItemPos = 1
|
|
Flag = ""
|
|
Unused = ""
|
|
|
|
Loop
|
|
Remove OICtrl from ControlMap@ at OICtrlPos Setting Flag
|
|
ControlSemantic = ControlSemantics@[ControlSemanticPos, @FM] ; ControlSemanticPos = Col2() + 1
|
|
ControlListItem = ControlList@[ControlListItemPos, @FM] ; ControlListItemPos = Col2() + 1
|
|
Unused = ControlSemantic[1, @VM]
|
|
ColName = ControlSemantic[Col2() + 1, @VM]
|
|
ColPos = ControlSemantic[Col2() + 1, @VM]
|
|
OICtrlType = ControlListItem<1, 3>
|
|
NumEdtCols = Count(ColPos, @SVM) + 1 ; // There is always one even if it is null
|
|
EdtColPos = 0 ; // Start the column counter at 0. Increase as each column is retrieved.
|
|
|
|
ColPosFlag = ""
|
|
ColPosPos = 1
|
|
Loop
|
|
Remove CurrColPos from ColPos at ColPosPos setting ColPosFlag
|
|
EdtColPos += 1
|
|
Begin Case
|
|
Case CurrColPos GT 0
|
|
// Regular databound control.
|
|
SRP_FastArray_Insert(OICtrlColPos, -1, 0, 0, CurrColPos)
|
|
SRP_FastArray_Insert(OICtrls, -1, 0, 0, OICtrl)
|
|
SRP_FastArray_Insert(OICtrlEdtCol, -1, 0, 0, EdtColPos)
|
|
SRP_FastArray_Insert(OICtrlTypes, -1, 0, 0, OICtrlType)
|
|
|
|
Case ColName<0, 0, EdtColPos> NE "" AND CurrColPos EQ "" AND OICtrlType NE "WINDOW"
|
|
// Must be a symbolic (calculated) control. If symbolics are not being skipped then collect
|
|
// necessary information for them to be updated later on.
|
|
If Not(SkipSymbolics) then
|
|
DepColPos = ""
|
|
ColNames = ColName<0, 0, EdtColPos>
|
|
ColNameFlag = ""
|
|
ColNamePos = 1
|
|
Loop
|
|
Remove ColName from ColNames at ColNamePos setting ColNameFlag
|
|
If Len(ColName) then
|
|
DepCols = OIWin_Compile_Impacts(TableName, ColName)
|
|
|
|
DepColsFlag = ""
|
|
DepColsPos = 1
|
|
Loop
|
|
Remove DepCol from DepCols at DepColsPos Setting DepColsFlag
|
|
DepCol = Field(DepCol, "*", 2)
|
|
If Num(DepCol) then
|
|
|
|
// This is a database column position. If it hasn't already been identified then
|
|
// append the tracking variables.
|
|
Locate DepCol in DepColPos using @FM setting fPos else
|
|
DepColPos<-1> = DepCol ; // Track columns already found to avoid duplication
|
|
|
|
// Information is being inserted rather than appended so the most independent
|
|
// columns appear first in the list. This way the CALCULATE event is sent to
|
|
// those controls and more dependent columsn will have the most current
|
|
// information available.
|
|
NumSymCtrls += 1
|
|
SRP_FastArray_Insert(OISymCtrls, 1, 0, 0, OICtrl)
|
|
SRP_FastArray_Insert(OISymDepColPos, 1, 0, 0, DepCol)
|
|
SRP_FastArray_Insert(OISymCtrlEdtCol, 1, 0, 0, EdtColPos)
|
|
SRP_FastArray_Insert(OISymCtrlRowsAsColumns, 1, 0, 0, "") ; // Not needed here, but need to keep values synched for the UDP controls.
|
|
SRP_FastArray_Insert(OISymCtrlCellsAsFields, 1, 0, 0, "") ; // Not needed here, but need to keep values synched for the UDP controls.
|
|
SRP_FastArray_Insert(OISymCtrlSelPos, 1, 0, 0, "") ; // Not needed here, but need to keep values synched for the UDP controls.
|
|
SRP_FastArray_Insert(OISymCtrlTypes, 1, 0, 0, OICtrlType)
|
|
SRP_FastArray_Insert(OISymCtrlOrigText, 1, 0, 0, "") ; // Not needed here, but need to keep values synched for the UDP controls.
|
|
SRP_FastArray_Insert(OISymCtrlColName, 1, 0, 0, "") ; // Not needed here, but need to keep values synched for the UDP controls.
|
|
end
|
|
|
|
end else
|
|
// This is another symbolic column. Add it to the list so all dependent database
|
|
// columns are collected.
|
|
ColNames<-1> = DepCol
|
|
end
|
|
While DepColsFlag
|
|
Repeat
|
|
end
|
|
While ColNameFlag
|
|
Repeat
|
|
end
|
|
|
|
End Case
|
|
While ColPosFlag
|
|
Repeat
|
|
While Flag
|
|
Repeat
|
|
|
|
// Now get the virtual (@POS) data column positions. SRP OLE EditTable controls store data column positions
|
|
// as an @VM delimited array. This code will flatten this out so each each SRP OLE EditTable column will have its
|
|
// own lookup reference.
|
|
|
|
ControlMap = Get_Property(Window, "@EDITTABLES")
|
|
Convert @FM to @RM in ControlMap
|
|
UDPColPos = Get_Property(ControlMap, "@POS")
|
|
UDPRowsAsColumns = Get_Property(ControlMap, "@ROWSASCOLUMNS")
|
|
UDPCellsAsFields = Get_Property(ControlMap, "@CELLSASFIELDS")
|
|
UDPTypes = Get_Property(ControlMap, "TYPE")
|
|
UDPOrigTexts = Get_Property(ControlMap, "ORIG_TEXT")
|
|
|
|
UDPCtrls = SRP_FastArray_Create()
|
|
UDPCtrlColPos = SRP_FastArray_Create()
|
|
UDPCtrlRowsAsColumnsList = SRP_FastArray_Create()
|
|
UDPCtrlCellsAsFieldsList = SRP_FastArray_Create()
|
|
UDPCtrlSelPosList = SRP_FastArray_Create()
|
|
* UDPCtrlTypes = SRP_FastArray_Create()
|
|
UDPCtrlEdtCol = SRP_FastArray_Create()
|
|
UDPCtrlOrigText = SRP_FastArray_Create()
|
|
|
|
ControlMapPos = 1
|
|
UDPColPosPos = 1
|
|
UDPRowsAsColumnsPos = 1
|
|
UDPCellsAsFieldsPos = 1
|
|
UDPTypesPos = 1
|
|
UDPOrigTextsPos = 1
|
|
Flag = ""
|
|
Unused = ""
|
|
|
|
Loop
|
|
ColPos = UDPColPos[UDPColPosPos, @RM]
|
|
UDPColPosPos = Col2() + 1
|
|
|
|
Remove UDPCtrl from ControlMap at ControlMapPos Setting Flag
|
|
Remove UDPCtrlRowsAsColumns from UDPRowsAsColumns at UDPRowsAsColumnsPos Setting Unused
|
|
Remove UDPCtrlCellsAsFields from UDPCellsAsFields at UDPCellsAsFieldsPos Setting Unused
|
|
Remove UDPCtrlType from UDPTypes at UDPTypesPos Setting Unused
|
|
Remove UDPOrigText from UDPOrigTexts at UDPOrigTextsPos Setting Unused
|
|
|
|
If ColPos NE "" then
|
|
|
|
If UDPCtrlRowsAsColumns EQ "" then UDPCtrlRowsAsColumns = No$ ; // Make sure something is in place so the <-1> append logic will work.
|
|
If UDPCtrlCellsAsFields EQ "" then UDPCtrlCellsAsFields = No$ ; // Make sure something is in place so the <-1> append logic will work.
|
|
If UDPOrigText EQ "" then UDPOrigText = UDPCtrlType ; // Make sure something is in place so the <-1> append logic will work.
|
|
|
|
NumEdtCols = Count(ColPos, @VM) + (ColPos NE "")
|
|
If UDPCtrlCellsAsFields EQ Yes$ then
|
|
NumEdtRows = Count(ColPos<0, 1>, @SVM) + (ColPos<0, 1> NE "")
|
|
If NumEdtRows GT 1 then NumEdtCols = NumEdtCols * NumEdtRows
|
|
end else
|
|
NumEdtRows = 1
|
|
end
|
|
|
|
ColNameFlag = ""
|
|
ColNamePos = 1
|
|
|
|
For i = 1 to NumEdtCols
|
|
For j = 1 to NumEdtRows
|
|
ColName = ColPos<0, i, j>
|
|
|
|
If ColName NE "" then
|
|
|
|
UDPCtrlSelPos = i:";":j
|
|
|
|
SRP_FastArray_Insert(UDPCtrlColPos, -1, 0, 0, ColName)
|
|
SRP_FastArray_Insert(UDPCtrls, -1, 0, 0, UDPCtrl)
|
|
SRP_FastArray_Insert(UDPCtrlEdtCol, -1, 0, 0, i)
|
|
SRP_FastArray_Insert(UDPCtrlRowsAsColumnsList, -1, 0, 0, UDPCtrlRowsAsColumns)
|
|
SRP_FastArray_Insert(UDPCtrlCellsAsFieldsList, -1, 0, 0, UDPCtrlCellsAsFields)
|
|
SRP_FastArray_Insert(UDPCtrlSelPosList, -1, 0, 0, UDPCtrlSelPos)
|
|
* SRP_FastArray_Insert(UDPCtrlTypes, -1, 0, 0, UDPCtrlType)
|
|
SRP_FastArray_Insert(UDPCtrlOrigText, -1, 0, 0, UDPOrigText)
|
|
|
|
// In case there are no true databound controls on the form, the data column positions that are
|
|
// virtually bound will be added to the RowMaps variable. This way the logic that updates the
|
|
// entire window will catch these virtually bound column positions and update accordingly.
|
|
If Num(ColName) then
|
|
|
|
// This is a data column so put the column position in the dictionary column name and number
|
|
// areas.
|
|
MRIndex = MRCount + 1
|
|
RowMaps := @VM:ColName:@SVM:ColName:@SVM:@SVM:MRIndex
|
|
RMCount += 1
|
|
SRP_FastArray_Insert(MasterRowMap, -1, 0, 0, UDPCtrl:@VM:i:@VM:UDPCtrlType)
|
|
MRCount += 1
|
|
|
|
end else
|
|
|
|
// This is a symbolic column so only put the column name in the dictionary column name area.
|
|
RowMaps := @VM:ColName:@SVM
|
|
RMCount += 1
|
|
DepColPos = ""
|
|
|
|
DepCols = OIWin_Compile_Impacts(TableName, ColName)
|
|
|
|
DepColsFlag = ""
|
|
DepColsPos = 1
|
|
Loop
|
|
Remove DepCol from DepCols at DepColsPos Setting DepColsFlag
|
|
DepCol = Field(DepCol, "*", 2)
|
|
If Num(DepCol) then
|
|
|
|
// This is a database column position. If it hasn't already been identified then
|
|
// append the tracking variables.
|
|
Locate DepCol in DepColPos using @FM setting fPos else
|
|
DepColPos<-1> = DepCol ; // Track columns already found to avoid duplication
|
|
|
|
// Information is being inserted rather than appended so the most independent
|
|
// columns appear first in the list. This way the CALCULATE event is sent to
|
|
// those controls and more dependent columsn will have the most current
|
|
// information available.
|
|
SRP_FastArray_Insert(OISymCtrls, 1, 0, 0, UDPCtrl) ; NumSymCtrls += 1
|
|
SRP_FastArray_Insert(OISymDepColPos, 1, 0, 0, DepCol)
|
|
SRP_FastArray_Insert(OISymCtrlEdtCol, 1, 0, 0, i)
|
|
SRP_FastArray_Insert(OISymCtrlRowsAsColumns, 1, 0, 0, UDPCtrlRowsAsColumns)
|
|
SRP_FastArray_Insert(OISymCtrlCellsAsFields, 1, 0, 0, UDPCtrlCellsAsFields)
|
|
SRP_FastArray_Insert(OISymCtrlSelPos, 1, 0, 0, UDPCtrlSelPos)
|
|
SRP_FastArray_Insert(OISymCtrlTypes, 1, 0, 0, UDPCtrlType)
|
|
SRP_FastArray_Insert(OISymCtrlOrigText, 1, 0, 0, UDPOrigText)
|
|
SRP_FastArray_Insert(OISymCtrlColName, 1, 0, 0, ColName) ; // The name of the symbolic column so it can be calculated later on.
|
|
end
|
|
|
|
end
|
|
While DepColsFlag
|
|
Repeat
|
|
end
|
|
end
|
|
Next j
|
|
Next i
|
|
end
|
|
While Flag
|
|
Repeat
|
|
|
|
// Check the DictColPos for the special keyword "SYM". This means only the symbolic columns should be updated.
|
|
// Reset the ProcessCnt counter accordingly.
|
|
If DictColPos _EQC "SYM" then ProcessCnt += 2
|
|
return
|
|
|
|
Update_Window:
|
|
// Update the control(s) on the window with the data.
|
|
|
|
If WholeRecord EQ No$ then
|
|
// Only one database column is being updated. Add all the controls that are bound to this database column and
|
|
// update them.
|
|
FieldData = Data
|
|
|
|
// Add all the controls that are actually data bound to this database column.
|
|
If Not(VirtualOnly) then GoSub Add_OI_Control_Information
|
|
|
|
// Add all the controls that are virtually data bound to this database column.
|
|
GoSub Add_UDP_Control_Information
|
|
end else
|
|
// The entire data record is being updated. Use the common variables already set up in the OIWin_Comm_Init
|
|
// insert to loop through each control, get the database column bound to it, then update it with the data record
|
|
// column.
|
|
|
|
Loop
|
|
|
|
RowMap = RowMaps[1, @VM]
|
|
RowMaps[1, Col2()] = ""
|
|
|
|
While RowMap GT ""
|
|
|
|
DictColName = RowMap<1, 1, 1>
|
|
DictColPos = RowMap<1, 1, 2>
|
|
|
|
Begin Case
|
|
Case DictColPos GT 0
|
|
// This is a data column.
|
|
FieldData = Data<DictColPos>
|
|
// Add the control indexed to this RowMap.
|
|
If Not(VirtualOnly) then GoSub Add_Native_Control_Information
|
|
// Add all the controls that are virtually data bound to this database column.
|
|
GoSub Add_UDP_Control_Information
|
|
|
|
Case DictColPos EQ ""
|
|
// This is a symbolic (calculated) column but a non-databound control might be virtually bound to
|
|
// it. The symbolic will need to be calculated and the value put into FieldData. However, in order
|
|
// to avoid unnecessary symbolic calculations check first to see if any controls are virtually bound
|
|
Transfer DictColName to DictColPos
|
|
GoSub Add_UDP_Control_Information
|
|
|
|
End Case
|
|
Repeat
|
|
end
|
|
|
|
// Strip off the preceding @RM
|
|
Controls[1, 1] = ""
|
|
Properties[1, 1] = ""
|
|
Values[1, 1] = ""
|
|
EdtCols[1, 1] = ""
|
|
|
|
Set_Property(Controls, Properties, Values, EdtCols)
|
|
|
|
ProgID = Get_Property(FocusControl, "OLE.ProgID") ; // Get the ProgID of the focus control
|
|
If ProgID _EQC "SRP.EditTable.1" then ; // Is the focus control an SRP EditTable?
|
|
Send_Message(FocusControl, "OLE.AbortCellEdit") ; // Because the SRP EditTable can already be in edit mode before the data
|
|
Send_Message(FocusControl, "OLE.EditCell", "") ; // is updated, reset the edit mode so the data is visible in the cell
|
|
end
|
|
return
|
|
|
|
Update_Record:
|
|
If TableName NE "" then
|
|
// Clear out and then update the RECORD property of the window. This will make sure that all related components
|
|
// to the data changes are in synch so symbolic (calculated) columns and the database write work correctly.
|
|
Set_Property(Window, "RECORD", "")
|
|
Set_Property(Window, "RECORD", @RECORD)
|
|
end
|
|
return
|
|
|
|
Update_Symbolics:
|
|
// Symbolics are updated last (and not with the data controls in the Update_Window gosub) because they need to be
|
|
// recalculated after the data controls have been populated.
|
|
If Not(SkipSymbolics) then
|
|
If WholeRecord EQ Yes$ then
|
|
|
|
// Send a CALCULATE event to all controls bound to a symbolic column.
|
|
For fPos = 1 to NumSymCtrls
|
|
GoSub Calculate_And_Display
|
|
Next fPos
|
|
// No longer need OISymDepColPos array since all controls are being recalculated.
|
|
SRP_FastArray_Release(OISymDepColPos)
|
|
|
|
end else
|
|
|
|
// Convert from Fast Array back to normal array
|
|
Handle = OISymDepColPos
|
|
OISymDepColPos = SRP_FastArray_GetVariable(Handle)
|
|
SRP_FastArray_Release(Handle)
|
|
|
|
// Send a CALCULATE event to those controls which are dependent upon the changed database column.
|
|
Match = Yes$
|
|
Loop
|
|
Locate DictColPos in OISymDepColPos using @FM setting fPos then
|
|
OISymDepColPos<fPos> = "" ; // Clear field position so it won't be found again.
|
|
GoSub Calculate_And_Display
|
|
end else
|
|
Match = No$
|
|
end
|
|
Until Not(Match)
|
|
Repeat
|
|
|
|
end
|
|
end
|
|
return
|
|
|
|
Clean_Up:
|
|
|
|
SRP_FastArray_Release(MasterRowMap)
|
|
|
|
SRP_FastArray_Release(OICtrls)
|
|
SRP_FastArray_Release(OICtrlColPos)
|
|
SRP_FastArray_Release(OICtrlEdtCol)
|
|
SRP_FastArray_Release(OICtrlTypes)
|
|
|
|
SRP_FastArray_Release(OISymCtrls)
|
|
SRP_FastArray_Release(OISymCtrlEdtCol)
|
|
SRP_FastArray_Release(OISymCtrlRowsAsColumns)
|
|
SRP_FastArray_Release(OISymCtrlCellsAsFields)
|
|
SRP_FastArray_Release(OISymCtrlSelPos)
|
|
SRP_FastArray_Release(OISymCtrlTypes)
|
|
SRP_FastArray_Release(OISymCtrlOrigText)
|
|
SRP_FastArray_Release(OISymCtrlColName)
|
|
|
|
SRP_FastArray_Release(UDPCtrls)
|
|
SRP_FastArray_Release(UDPCtrlColPos)
|
|
SRP_FastArray_Release(UDPCtrlRowsAsColumnsList)
|
|
SRP_FastArray_Release(UDPCtrlCellsAsFieldsList)
|
|
SRP_FastArray_Release(UDPCtrlSelPosList)
|
|
* SRP_FastArray_Release(UDPCtrlTypes)
|
|
SRP_FastArray_Release(UDPCtrlEdtCol)
|
|
SRP_FastArray_Release(UDPCtrlOrigText)
|
|
|
|
return
|
|
|
|
Calculate_And_Display:
|
|
|
|
SymCtrl = SRP_FastArray_Extract(OISymCtrls, fPos, 0, 0)
|
|
SymCtrlEdtCol = SRP_FastArray_Extract(OISymCtrlEdtCol, fPos, 0, 0)
|
|
SymCtrlRowsAsColumns = SRP_FastArray_Extract(OISymCtrlRowsAsColumns, fPos, 0, 0)
|
|
SymCtrlCellsAsFields = SRP_FastArray_Extract(OISymCtrlCellsAsFields, fPos, 0, 0)
|
|
SymCtrlSelPos = SRP_FastArray_Extract(OISymCtrlSelPos, fPos, 0, 0)
|
|
SymCtrlOrigText = SRP_FastArray_Extract(OISymCtrlOrigText, fPos, 0, 0)
|
|
SymCtrlColName = SRP_FastArray_Extract(OISymCtrlColName, fPos, 0, 0)
|
|
|
|
If SymCtrlColName EQ "" then
|
|
|
|
// This control is bound to an actual symbolic (calculated) column. Use the CALCULATE event to update it.
|
|
Send_Event(SymCtrl, "CALCULATE", SymCtrlEdtCol)
|
|
|
|
end else
|
|
|
|
// This control is virtually bound to a symboic (calculated) column. Use the CALCULATE function to compute its
|
|
// value and update the control's display directly.
|
|
|
|
SymResult = Calculate(SymCtrlColName)
|
|
|
|
If SymCtrlOrigText _EQC "SRP.EditTable.1" then
|
|
|
|
// OLE EditTable controls need to have enough empty rows to display the data being added. Compute the
|
|
// number of additional rows and use the Dimension property to create them.
|
|
If WholeRecord EQ Yes$ then
|
|
Locate SymCtrl in UpdatedOLEEditTables using @FM setting Dummy else
|
|
// This OLE EditTable might have information from a previous record. Therefore, clear the OLE
|
|
// EditTable just in case but track the control so it won't get cleared if other columns are updated
|
|
If DictColPos _NEC "SYM" then
|
|
// If the control with focus is the control being updated then don't call the Clear method.
|
|
// First, the changes that are being made in this control will be cleared. Second, if the
|
|
// current cell is a Combobox type this will crash OpenInsight.
|
|
If SymCtrlRowsAsColumns OR SymCtrlCellsAsFields then
|
|
// Clear data but maintain the original rows
|
|
Send_Message(SymCtrl, "OLE.Clear", 2)
|
|
end else
|
|
// Clear data and rows
|
|
Send_Message(SymCtrl, "OLE.Clear", 0)
|
|
end
|
|
end
|
|
UpdatedOLEEditTables<-1> = SymCtrl ; // Track this OLE EditTable so the Clear method won't be executed again.
|
|
end
|
|
end
|
|
|
|
Dimension = Get_Property(SymCtrl, "OLE.Dimension")
|
|
CurrNumColumns = Dimension[1, @FM]
|
|
CurrNumRows = Dimension[Col2() + 1, @FM]
|
|
|
|
Begin Case
|
|
Case SymCtrlRowsAsColumns EQ Yes$
|
|
// Data in the SRP EditTable is being stored in a LIST format where rows are associated with field
|
|
// data.
|
|
NeededColumns = Count(SymResult, @VM) + (SymResult NE "")
|
|
If NeededColumns GT CurrNumColumns then
|
|
CurrNumColumns = NeededColumns
|
|
Set_Property(SymCtrl, "OLE.Dimension", CurrNumColumns)
|
|
end
|
|
Conv = Get_Property(SymCtrl, "OLE.CellConv[1;":SymCtrlEdtCol:"]")<2>
|
|
If Conv NE "" then SymResult = Oconv(SymResult, Conv)
|
|
Set_Property(SymCtrl, "OLE.RecordData[":SymCtrlEdtCol:"]", SymResult)
|
|
|
|
Case SymCtrlCellsAsFields EQ Yes$
|
|
// Each cell within he SRP EditTable is associated with a specific field data.
|
|
NeededColumns = Trim(SymCtrlSelPos[1, ";"])
|
|
NeededRows = Trim(SymCtrlSelPos[Col2() + 1, ";"])
|
|
If (NeededColumns GT CurrNumColumns) OR (NeededRows GT CurrNumRows) then
|
|
If NeededColumns GT CurrNumColumns then CurrNumColumns = NeededColumns
|
|
If NeededRows GT CurrNumRows then CurrNumRows = NeededRows
|
|
Set_Property(SymCtrl, "OLE.Dimension", CurrNumColumns:@FM:CurrNumRows)
|
|
end
|
|
Conv = Get_Property(SymCtrl, "OLE.CellConv[":SymCtrlSelPos:"]")<2>
|
|
If Conv NE "" then SymResult = Oconv(SymResult, Conv)
|
|
Set_Property(SymCtrl, "OLE.CellText[":SymCtrlSelPos:"]", SymResult)
|
|
|
|
Case Otherwise$
|
|
// Data in the SRP EditTable is being stored in the traditional ARRAY format where columns are
|
|
// associated with field data.
|
|
NeededRows = Count(SymResult, @VM) + (SymResult NE "")
|
|
If NeededRows GT CurrNumRows then
|
|
DCurrNumRows = NeededRows
|
|
Set_Property(SymCtrl, "OLE.Dimension", @FM:CurrNumRows)
|
|
end
|
|
Conv = Get_Property(SymCtrl, "OLE.CellConv[":SymCtrlEdtCol:";1]")<2>
|
|
If Conv NE "" then SymResult = Oconv(SymResult, Conv)
|
|
Set_Property(SymCtrl, "OLE.ColumnData[":SymCtrlEdtCol:"]", SymResult)
|
|
|
|
End Case
|
|
|
|
end else
|
|
// Data is being updated in a standard OpenInsight control. Use the INVALUE property to make sure the data
|
|
// is being converted correctly.
|
|
Set_Property(SymCtrl, "INVALUE", SymResult, SymCtrlEdtCol)
|
|
end
|
|
|
|
end
|
|
|
|
return
|
|
|
|
Add_Native_Control_Information:
|
|
MRIndex = RowMap<1, 1, 4>
|
|
Control = SRP_FastArray_Extract(MasterRowMap, MRIndex, 1, 0)
|
|
EdtCol = SRP_FastArray_Extract(MasterRowMap, MRIndex, 2, 0)
|
|
CtrlType = SRP_FastArray_Extract(MasterRowMap, MRIndex, 3, 0)
|
|
If CtrlType NE "OLECONTROL" then
|
|
// Only native OpenInsight controls apply here.
|
|
|
|
If CtrlType EQ "EDITTABLE" then
|
|
// EditTable controls need to have enough empty rows to display the data being added. Compute the number of
|
|
// additional rows and use the INSERT method to create them.
|
|
Invalue = Get_Property(Control, "INVALUE")
|
|
CurrNumRows = Count(Invalue<1>, @VM) + (Invalue<1> NE "")
|
|
NeededRows = Count(FieldData, @VM) + (FieldData NE "")
|
|
For i = CurrNumRows to NeededRows
|
|
Send_Message(Control, "INSERT", -1, "")
|
|
Next i
|
|
end
|
|
|
|
Controls := @RM : Control
|
|
Properties := @RM : "INVALUE"
|
|
Values := @RM : FieldData
|
|
EdtCols := @RM : EdtCol
|
|
end
|
|
return
|
|
|
|
Add_OI_Control_Information:
|
|
TempOICtrlColPos = SRP_FastArray_GetVariable(OICtrlColPos)
|
|
Match = Yes$
|
|
|
|
Loop
|
|
Locate DictColPos in TempOICtrlColPos using @FM setting fPos then
|
|
Control = SRP_FastArray_Extract(OICtrls, fPos, 0, 0)
|
|
CtrlType = SRP_FastArray_Extract(OICtrlTypes, fPos, 0, 0)
|
|
|
|
If CtrlType EQ "EDITTABLE" then
|
|
// EditTable controls need to have enough empty rows to display the data being added. Compute the number
|
|
// of additional rows and use the INSERT method to create them.
|
|
Invalue = Get_Property(Control, "INVALUE")
|
|
CurrNumRows = Count(Invalue<1>, @VM) + (Invalue<1> NE "")
|
|
NeededRows = Count(FieldData, @VM) + (FieldData NE "")
|
|
For i = CurrNumRows to NeededRows
|
|
Send_Message(Control, "INSERT", -1, "")
|
|
Next i
|
|
end
|
|
|
|
Controls := @RM : Control
|
|
Properties := @RM : "INVALUE"
|
|
Values := @RM : FieldData
|
|
EdtCol = SRP_FastArray_Extract(OICtrlEdtCol, fPos, 0, 0)
|
|
EdtCols := @RM : EdtCol
|
|
|
|
TempOICtrlColPos<fPos> = ""
|
|
|
|
end else
|
|
Match = No$
|
|
end
|
|
Until Not(Match)
|
|
Repeat
|
|
return
|
|
|
|
Add_UDP_Control_Information:
|
|
TempUDPCtrlColPos = SRP_FastArray_GetVariable(UDPCtrlColPos)
|
|
Match = Yes$
|
|
|
|
Loop
|
|
Locate DictColPos in TempUDPCtrlColPos using @FM setting fPos then
|
|
Control = SRP_FastArray_Extract(UDPCtrls, fPos, 0, 0)
|
|
RowsAsColumns = SRP_FastArray_Extract(UDPCtrlRowsAsColumnsList, fPos, 0, 0)
|
|
CellsAsFields = SRP_FastArray_Extract(UDPCtrlCellsAsFieldsList, fPos, 0, 0)
|
|
SelPos = SRP_FastArray_Extract(UDPCtrlSelPosList, fPos, 0, 0)
|
|
OrigText = SRP_FastArray_Extract(UDPCtrlOrigText, fPos, 0, 0)
|
|
// If DictColPos is not a number then this is a symbolic that needs to be calculated
|
|
If Not(Num(DictColPos)) then FieldData = Calculate(DictColPos)
|
|
|
|
Controls := @RM : Control
|
|
|
|
Begin Case
|
|
Case OrigText _EQC "SRP.EditTable.1"
|
|
// OLE EditTable controls need to have enough empty rows to display the data being added. Compute
|
|
// the number of additional rows and use the Dimension property to create them.
|
|
If WholeRecord EQ Yes$ then
|
|
Locate Control in UpdatedOLEEditTables using @FM setting Dummy else
|
|
// This OLE EditTable might have information from a previous record. Therefore, clear the
|
|
// OLE EditTable just in case but track the control so it won't get cleared if other columns
|
|
// are updated.
|
|
If Control NE FocusControl then
|
|
// If the control with focus is the control being updated then don't call the Clear
|
|
// method. First, the changes that are being made in this control will be cleared.
|
|
// Second, if the current cell is a Combobox type this will crash OpenInsight.
|
|
ClearFill = Get_Property(Control, "@CLEARFILL")
|
|
*If RowsAsColumns OR CellsAsFields then
|
|
Begin Case
|
|
Case ClearFill
|
|
// Clear using fill value defined for EditTable
|
|
Send_Message(Control, "OLE.Clear", ClearFill)
|
|
Case RowsAsColumns OR CellsAsFields
|
|
// Clear data but maintain the original rows
|
|
Send_Message(Control, "OLE.Clear", 2)
|
|
Case Otherwise$
|
|
// Clear data and rows
|
|
Send_Message(Control, "OLE.Clear", 0)
|
|
End Case
|
|
end
|
|
UpdatedOLEEditTables<-1> = Control ; // Track this OLE EditTable so the Clear method won't be executed again.
|
|
end
|
|
end
|
|
|
|
Dimension = Get_Property(Control, "OLE.Dimension")
|
|
CurrNumColumns = Dimension<1>
|
|
CurrNumRows = Dimension<2>
|
|
|
|
Begin Case
|
|
Case RowsAsColumns EQ Yes$
|
|
// Data in the SRP EditTable is being stored in a LIST format where rows are associated with
|
|
// field data.
|
|
NeededColumns = Count(FieldData, @VM) + (FieldData NE "")
|
|
If NeededColumns GT CurrNumColumns then
|
|
Dimension<1> = NeededColumns
|
|
Set_Property(Control, "OLE.Dimension", Dimension)
|
|
end
|
|
EdtCol = SRP_FastArray_Extract(UDPCtrlEdtCol, fPos, 0, 0)
|
|
Properties := @RM : "OLE.RecordData[":EdtCol:"]"
|
|
CellConv = Get_Property(Control, "OLE.CellConv[1;":EdtCol:"]")
|
|
|
|
Case CellsAsFields EQ Yes$
|
|
// Each cell within he SRP EditTable is associated with a specific field data.
|
|
NeededColumns = Trim(Field(SelPos, ";", 1))
|
|
NeededRows = Trim(Field(SelPos, ";", 2))
|
|
If (NeededColumns GT CurrNumColumns) OR (NeededRows GT CurrNumRows) then
|
|
If NeededColumns GT CurrNumColumns then Dimension<1> = NeededColumns
|
|
If NeededRows GT CurrNumRows then Dimension<2> = NeededRows
|
|
Set_Property(Control, "OLE.Dimension", Dimension)
|
|
end
|
|
Properties := @RM : "OLE.CellText[":SelPos:"]"
|
|
CellConv = Get_Property(Control, "OLE.CellConv[":SelPos:"]")
|
|
|
|
Case Otherwise$
|
|
// Data in the SRP EditTable is being stored in the traditional ARRAY format where columns
|
|
// are associated with field data.
|
|
NeededRows = Count(FieldData, @VM) + (FieldData NE "")
|
|
If NeededRows GT CurrNumRows then
|
|
Dimension<2> = NeededRows
|
|
Set_Property(Control, "OLE.Dimension", Dimension)
|
|
end
|
|
EdtCol = SRP_FastArray_Extract(UDPCtrlEdtCol, fPos, 0, 0)
|
|
Properties := @RM : "OLE.ColumnData[":EdtCol:"]"
|
|
CellConv = Get_Property(Control, "OLE.CellConv[":EdtCol:";1]")
|
|
|
|
End Case
|
|
|
|
Conv = CellConv<2>
|
|
If Conv NE "" then FieldData = Oconv(FieldData, Conv)
|
|
Values := @RM : FieldData
|
|
EdtCols := @RM : ""
|
|
|
|
Case Otherwise$
|
|
Properties := @RM : "INVALUE"
|
|
Values := @RM : FieldData
|
|
EdtCols := @RM : ""
|
|
|
|
End Case
|
|
|
|
TempUDPCtrlColPos<fPos> = ""
|
|
|
|
end else
|
|
Match = No$
|
|
end
|
|
Until Not(Match)
|
|
Repeat
|
|
return
|
|
|
|
Restore_At_Variables:
|
|
Record = @RECORD ; // Copy @RECORD before it gets restored (if necessary) so it can be returned.
|
|
|
|
If Window NE @Window then
|
|
// Restore the original values of @ variables in case a different window other than @Window is being updated.
|
|
Transfer OrigID to @ID
|
|
Transfer OrigRecord to @RECORD
|
|
Transfer OrigDict to @DICT
|
|
end
|
|
return
|
|
|
|
ParseDictColPos:
|
|
// Determine if the data needs to update a value, subvalue, text, or subtext part of a field.
|
|
DelimDepth = 0
|
|
|
|
Loop
|
|
DelimDepth += 1
|
|
Pos = Field(DictColPos, ",", DelimDepth)
|
|
Until Not(Num(Pos)) OR Pos EQ "" OR DelimDepth EQ 6
|
|
Begin Case
|
|
Case DelimDepth EQ 1 ; Transfer Pos to FieldPos
|
|
Case DelimDepth EQ 2 ; Transfer Pos to ValPos
|
|
Case DelimDepth EQ 3 ; Transfer Pos to SubValPos
|
|
Case DelimDepth EQ 4 ; Transfer Pos to TextPos
|
|
Case DelimDepth EQ 5 ; Transfer Pos to SubTextPos
|
|
End Case
|
|
Repeat
|
|
|
|
DictColPos = FieldPos
|
|
DelimDepth -= 1
|
|
return
|
|
|
|
Update_Data_Array:
|
|
// Drill into the data field as much as necessary and update with the data being passed in. The entire data field
|
|
// will then be put into each control that is bound to this database column.
|
|
DataArray = ""
|
|
DataArray<1> = @RECORD<FieldPos>
|
|
DataArray<2> = Field(DataArray<1>, @VM, ValPos)
|
|
If DelimDepth GT 2 then
|
|
DataArray<3> = Field(DataArray<2>, @SVM, SubValPos)
|
|
If DelimDepth GT 3 then
|
|
DataArray<4> = Field(DataArray<3>, @TM, TextPos)
|
|
|
|
If DelimDepth GT 4 then
|
|
Data = FieldStore(DataArray<4>, @STM, SubTextPos, 1, Data)
|
|
end
|
|
|
|
Data = FieldStore(DataArray<3>, @TM, TextPos, 1, Data)
|
|
end
|
|
|
|
Data = FieldStore(DataArray<2>, @SVM, SubValPos, 1, Data)
|
|
end
|
|
|
|
Data = FieldStore(DataArray<1>, @VM, ValPos, 1, Data)
|
|
return
|