ABL(old) Form: Searching for an user tag/id in an static bro

Posted by Stefan Marquardt on 27-Feb-2020 15:16

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?

All Replies

Posted by goo on 27-Feb-2020 15:34

I suppose you ain’t using same name for fields an columns? That would be too easy 😊 Temp-table has also serialize-name that can be used. You may make yourself a mappingtable, so that you can store the handle for each of them…. Etc…
 
//Geir Otto
 

Posted by Patrick Tingen on 28-Feb-2020 07:16

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))

Posted by Stefan Marquardt on 28-Feb-2020 08:46

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)

Posted by goo on 28-Feb-2020 11:00

Not sure what you really want, but depending on how dynamic you want it to be, you can do something like this to travers either frame or the browse columns ….
 
 
//Geir Otto
 
 
/*------------------------------------------------------------------------
    File        : browse_test.p
    Purpose     :
 
    Syntax      :
 
    Description :
 
    Author(s)   : goo_000
    Created     : Fri Feb 28 10:47:13 CET 2020
    Notes       :
  ----------------------------------------------------------------------*/
 
/* ***************************  Definitions  ************************** */
 
BLOCK-LEVEL ON ERROR UNDO, THROW.
 
/* ********************  Preprocessor Definitions  ******************** */
 
 
/* ***************************  Main Block  *************************** */
 
def temp-table tt no-undo
  field field1 as char
  field field2 as char
  .
 
  def var x as char format 'x(30)' view-as FILL-IN.
  def var B as char format 'x(30)' view-as FILL-IN.
  def var colName as char no-undo.
  def var ii as int no-undo.
 
  DEFINE QUERY b1 FOR
      tt SCROLLING.
 
  def browse b1 query b1  display field1 field2
    WITH NO-ROW-MARKERS SEPARATORS SIZE 113 BY 7.38 FIT-LAST-COLUMN.
 
def var mapFields as handle extent no-undo.
 
  def frame frame1
    x  at row 1 col 10 
    b  at row 2 col 10
    b1 at row 3 col 1
   with size 80 by 20 SIDE-LABELS.
 
on 'value-changed' of browse b1 do:
  do ii = 1 to extent(mapFields):
    mapFields[ii]:screen-value = browse b1:get-browse-column(ii):screen-value.
  end.
   
end.   
/*  x:PRIVATE-DATA = 'field1'.*/
/*  b:private-data = 'field2'.*/
 
  create tt.
  assign
    tt.field1 = 'aaaa'
    tt.field2 = 'bbb'
    .
  create tt.
  assign
    tt.field1 = 'ccc'
    tt.field2 = 'dddddd'
    .
 
  OPEN QUERY b1 FOR EACH tt.
  enable all with frame frame1.
 
  extent(mapFields) = browse b1:num-columns.
  do ii = 1 to browse b1:num-columns:
    colName = browse b1:GET-BROWSE-COLUMN (ii):name.
    case colname:
      when 'field1' then mapFields[ii] = x:handle in frame frame1.
      when 'field2' then mapFields[ii] = b:handle in frame frame1.
    end case.
  end
  x:screen-value in frame frame1 = 'Hello world'.
 
 
wait-for close of this-procedure.
 
 
 
 

Posted by Patrick Tingen on 28-Feb-2020 12:51

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.

Posted by frank.meulblok on 02-Mar-2020 09:43

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.

This thread is closed