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.