Hello,
i have this old style browser definition:
define browse BrwSearchResult
&ANALYZE-SUSPEND _UIB-CODE-BLOCK _DISPLAY-FIELDS BrwSearchResult MainWindow _FREEFORM
query BrwSearchResult display
TT.field1 format "x(15)" column-label "Nice field 1"
TT.field2 format "x(08)" column-label "Nice field 2"
formatdate(TT.field3) format "x(12)" column-label "Nice date"
...
How can I add a kind of ID to each field in the display statement which can be queried as an attribute in the column handle (get-browse-column) of the browser?
Like
TT.field1 format "x(15)" column-label "Nice field 1" private-data "1"
TT.field2 format "x(08)" column-label "Nice field 2" private-data "2"
formatdate(TT.field3) format "x(12)" column-label "Nice date" private-data "3"
Background: I like to have a kind of sequence which survives a later redefinition if more fields are inserted or removed
Tried to set the private-data attribute for the column which should fit for my purpose, found in help for column widget, but doesn't compile in the way i tried
Maybe my syntax is wrong?
Tried to misuse the help attribute in the TT definition but this doesn't work for the fomatdate column where isn't a valid buffer-field to read the help attribute.
Is this possible somehow?
You could store the column-handles in a comma separated list and use that to restore the order of the columns (at least, if that is what you are trying to do). You can retrieve the handle from the comma separated list with something like hColumn = HANDLE(ENTRY(i, cColumnHandleList))
Thanks for the suggestion. Serialize-name has the same limitation like the help attribute, does not work on the calculated col (with function), col:buffer-field isn't valid.
Column-handles are not valid for save the order in a config, would be different. I tested the unique-id but this it's only unique during the form lifetime,
Nobody knows how to set the attribute private-data of a column in the browser definition?
Then I would have the col ID in the definition and not in a helper list (char)
Not sure what it is you're after, but if you know the name of the fields of the TT, you can re-arrange the fields of the browse. Check this example:
After you click on the second button:
Source below. The 'magic' hapens in the procedure setColumnOrder
/* Connected Databases
*/
&Scoped-define WINDOW-NAME C-Win
/*------------------------------------------------------------------------
Browse demo
------------------------------------------------------------------------*/
CREATE WIDGET-POOL.
DEFINE TEMP-TABLE ttCustomer NO-UNDO RCODE-INFORMATION
FIELD CustNum AS INTEGER FORMAT ">>>>9" COLUMN-LABEL "Cust Num"
FIELD Country AS CHARACTER FORMAT "x(20)" COLUMN-LABEL "Country"
FIELD CustName AS CHARACTER FORMAT "x(30)" COLUMN-LABEL "Name"
FIELD City AS CHARACTER FORMAT "x(25)" COLUMN-LABEL "City"
.
CREATE ttCustomer.
ASSIGN
ttCustomer.CustNum = 1
ttCustomer.CustName = "Lift Tours"
ttCustomer.Country = "USA"
ttCustomer.City = "Burlington".
CREATE ttCustomer.
ASSIGN
ttCustomer.CustNum = 2
ttCustomer.CustName = "Urpon Frisbee"
ttCustomer.Country = "Finland"
ttCustomer.City = "Oslo".
CREATE ttCustomer.
ASSIGN
ttCustomer.CustNum = 3
ttCustomer.CustName = "Hoops"
ttCustomer.Country = "USA"
ttCustomer.City = "Atlanta".
/* ******************** Preprocessor Definitions ******************** */
&Scoped-define PROCEDURE-TYPE Window
&Scoped-define DB-AWARE no
/* Name of designated FRAME-NAME and/or first browse and/or first query */
&Scoped-define FRAME-NAME DEFAULT-FRAME
&Scoped-define BROWSE-NAME brCustomers
/* Internal Tables (found by Frame, Query & Browse Queries) */
&Scoped-define INTERNAL-TABLES ttCustomer
/* Definitions for BROWSE brCustomers */
&Scoped-define FIELDS-IN-QUERY-brCustomers ttCustomer.CustNum ttCustomer.CustName ttCustomer.Country ttCustomer.City
&Scoped-define ENABLED-FIELDS-IN-QUERY-brCustomers
&Scoped-define SELF-NAME brCustomers
&Scoped-define QUERY-STRING-brCustomers FOR EACH ttCustomer
&Scoped-define OPEN-QUERY-brCustomers OPEN QUERY {&SELF-NAME} FOR EACH ttCustomer.
&Scoped-define TABLES-IN-QUERY-brCustomers ttCustomer
&Scoped-define FIRST-TABLE-IN-QUERY-brCustomers ttCustomer
/* Definitions for FRAME DEFAULT-FRAME */
&Scoped-define OPEN-BROWSERS-IN-QUERY-DEFAULT-FRAME ~
~{&OPEN-QUERY-brCustomers}
/* Standard List Definitions */
&Scoped-Define ENABLED-OBJECTS brCustomers btnSetColumns-1 btnSetColumns-2 ~
btnSetColumns-3
/* Custom List Definitions */
/* List-1,List-2,List-3,List-4,List-5,List-6 */
/* *********************** Control Definitions ********************** */
/* Define the widget handle for the window */
DEFINE VAR C-Win AS WIDGET-HANDLE NO-UNDO.
/* Definitions of the field level widgets */
DEFINE BUTTON btnSetColumns-1
LABEL "CustNum,CustName,Country,City"
SIZE 49 BY 1.14.
DEFINE BUTTON btnSetColumns-2
LABEL "City,Country,CustNum,CustName"
SIZE 49 BY 1.14.
DEFINE BUTTON btnSetColumns-3
LABEL "CustNum,CustName,City"
SIZE 49 BY 1.14.
/* Query definitions */
DEFINE QUERY brCustomers FOR
ttCustomer SCROLLING.
/* Browse definitions */
DEFINE BROWSE brCustomers
QUERY brCustomers DISPLAY
ttCustomer.CustNum
ttCustomer.CustName
ttCustomer.Country
ttCustomer.City
WITH NO-ROW-MARKERS SEPARATORS SIZE 88 BY 4.52.
/* ************************ Frame Definitions *********************** */
DEFINE FRAME DEFAULT-FRAME
brCustomers AT ROW 1.24 COL 3 WIDGET-ID 200
btnSetColumns-1 AT ROW 7.19 COL 22 WIDGET-ID 2
btnSetColumns-2 AT ROW 8.62 COL 22 WIDGET-ID 4
btnSetColumns-3 AT ROW 10.05 COL 22 WIDGET-ID 6
WITH 1 DOWN NO-BOX KEEP-TAB-ORDER OVERLAY
SIDE-LABELS NO-UNDERLINE THREE-D
AT COL 1 ROW 1
SIZE 91.2 BY 11.67 WIDGET-ID 100.
/* *********************** Procedure Settings ************************ */
/* Settings for THIS-PROCEDURE
Type: Window
Allow: Basic,Browse,DB-Fields,Window,Query
Other Settings: COMPILE
*/
/* ************************* Create Window ************************** */
IF SESSION:DISPLAY-TYPE = "GUI":U THEN
CREATE WINDOW C-Win ASSIGN
HIDDEN = YES
TITLE = "Flexible Columns"
HEIGHT = 11.86
WIDTH = 91.2
MAX-HEIGHT = 16
MAX-WIDTH = 91.2
VIRTUAL-HEIGHT = 16
VIRTUAL-WIDTH = 91.2
RESIZE = yes
SCROLL-BARS = no
STATUS-AREA = no
BGCOLOR = ?
FGCOLOR = ?
KEEP-FRAME-Z-ORDER = yes
THREE-D = yes
MESSAGE-AREA = no
SENSITIVE = yes.
ELSE {&WINDOW-NAME} = CURRENT-WINDOW.
/* END WINDOW DEFINITION */
/* *********** Runtime Attributes and AppBuilder Settings *********** */
/* SETTINGS FOR WINDOW C-Win
VISIBLE,,RUN-PERSISTENT */
/* SETTINGS FOR FRAME DEFAULT-FRAME
FRAME-NAME */
/* BROWSE-TAB brCustomers 1 DEFAULT-FRAME */
IF SESSION:DISPLAY-TYPE = "GUI":U AND VALID-HANDLE(C-Win)
THEN C-Win:HIDDEN = no.
/* Setting information for Queries and Browse Widgets fields */
/* Query rebuild information for BROWSE brCustomers
_START_FREEFORM
OPEN QUERY {&SELF-NAME} FOR EACH ttCustomer.
_END_FREEFORM
_Query is OPENED
*/ /* BROWSE brCustomers */
/* ************************ Control Triggers ************************ */
&Scoped-define SELF-NAME C-Win
ON END-ERROR OF C-Win /* Flexible Columns */
OR ENDKEY OF {&WINDOW-NAME} ANYWHERE DO:
/* This case occurs when the user presses the "Esc" key.
In a persistently run window, just ignore this. If we did not, the
application would exit. */
IF THIS-PROCEDURE:PERSISTENT THEN RETURN NO-APPLY.
END.
ON WINDOW-CLOSE OF C-Win /* Flexible Columns */
DO:
/* This event will close the window and terminate the procedure. */
APPLY "CLOSE":U TO THIS-PROCEDURE.
RETURN NO-APPLY.
END.
&Scoped-define SELF-NAME btnSetColumns-1
ON CHOOSE OF btnSetColumns-1 IN FRAME DEFAULT-FRAME /* CustNum,CustName,Country,City */
DO:
RUN setColumnOrder(brCustomers:HANDLE, SELF:LABEL).
END.
&Scoped-define SELF-NAME btnSetColumns-2
ON CHOOSE OF btnSetColumns-2 IN FRAME DEFAULT-FRAME /* City,Country,CustNum,CustName */
DO:
RUN setColumnOrder(brCustomers:HANDLE, SELF:LABEL).
END.
&Scoped-define SELF-NAME btnSetColumns-3
ON CHOOSE OF btnSetColumns-3 IN FRAME DEFAULT-FRAME /* CustNum,CustName,City */
DO:
RUN setColumnOrder(brCustomers:HANDLE, SELF:LABEL).
END.
&Scoped-define BROWSE-NAME brCustomers
&UNDEFINE SELF-NAME
/* *************************** Main Block *************************** */
/* Set CURRENT-WINDOW: this will parent dialog-boxes and frames. */
ASSIGN CURRENT-WINDOW = {&WINDOW-NAME}
THIS-PROCEDURE:CURRENT-WINDOW = {&WINDOW-NAME}.
/* The CLOSE event can be used from inside or outside the procedure to */
/* terminate it. */
ON CLOSE OF THIS-PROCEDURE
RUN disable_UI.
/* Best default for GUI applications is... */
PAUSE 0 BEFORE-HIDE.
/* Now enable the interface and wait for the exit condition. */
/* (NOTE: handle ERROR and END-KEY so cleanup code will always fire. */
MAIN-BLOCK:
DO ON ERROR UNDO MAIN-BLOCK, LEAVE MAIN-BLOCK
ON END-KEY UNDO MAIN-BLOCK, LEAVE MAIN-BLOCK:
RUN enable_UI.
IF NOT THIS-PROCEDURE:PERSISTENT THEN
WAIT-FOR CLOSE OF THIS-PROCEDURE.
END.
/* ********************** Internal Procedures *********************** */
PROCEDURE disable_UI :
/*------------------------------------------------------------------------------
Purpose: DISABLE the User Interface
Parameters: <none>
Notes: Here we clean-up the user-interface by deleting
dynamic widgets we have created and/or hide
frames. This procedure is usually called when
we are ready to "clean-up" after running.
------------------------------------------------------------------------------*/
/* Delete the WINDOW we created */
IF SESSION:DISPLAY-TYPE = "GUI":U AND VALID-HANDLE(C-Win)
THEN DELETE WIDGET C-Win.
IF THIS-PROCEDURE:PERSISTENT THEN DELETE PROCEDURE THIS-PROCEDURE.
END PROCEDURE.
PROCEDURE enable_UI :
/*------------------------------------------------------------------------------
Purpose: ENABLE the User Interface
Parameters: <none>
Notes: Here we display/view/enable the widgets in the
user-interface. In addition, OPEN all queries
associated with each FRAME and BROWSE.
These statements here are based on the "Other
Settings" section of the widget Property Sheets.
------------------------------------------------------------------------------*/
ENABLE brCustomers btnSetColumns-1 btnSetColumns-2 btnSetColumns-3
WITH FRAME DEFAULT-FRAME IN WINDOW C-Win.
{&OPEN-BROWSERS-IN-QUERY-DEFAULT-FRAME}
VIEW C-Win.
END PROCEDURE.
PROCEDURE setColumnOrder :
/*
*/
DEFINE INPUT PARAMETER phBrowse AS HANDLE NO-UNDO.
DEFINE INPUT PARAMETER pcColumnList AS CHARACTER NO-UNDO.
DEFINE VARIABLE hColumn AS HANDLE NO-UNDO.
DEFINE VARIABLE iNewPos AS INTEGER NO-UNDO.
DEFINE VARIABLE iOldPos AS INTEGER NO-UNDO.
#BrowseColumn:
DO iNewPos = NUM-ENTRIES(pcColumnList) TO 1 BY -1:
DO iOldPos = 1 TO phBrowse:NUM-COLUMNS:
hColumn = phBrowse:GET-BROWSE-COLUMN(iOldPos).
hColumn:VISIBLE = (LOOKUP(hColumn:NAME, pcColumnList) > 0).
IF hColumn:NAME = ENTRY(iNewPos,pcColumnList) THEN
DO:
phBrowse:MOVE-COLUMN(iOldPos, iNewPos) NO-ERROR.
NEXT #BrowseColumn.
END. /* if hColumn:name */
END. /* DO i */
END. /* DO j */
END PROCEDURE.
If the question is limited to setting the private-data attribute on any browse column:
You can't do that within a static browse definition because the language syntax/compiler doesn't support that.
But you can do that by assigining
<column-name>:PRIVATE-DATA IN BROWSE <browse-name> = "insert what you need here".
after the browse is defined.
For calculated columns, use the "<expression> @ name" syntax to give them explicit names, then the same technique can be applied to those too.