Question v11.7 Open Edge UI possibilities (automatic generated) - Forum - OpenEdge General - Progress Community

Question v11.7 Open Edge UI possibilities (automatic generated)

 Forum

Question v11.7 Open Edge UI possibilities (automatic generated)

This question is not answered

Hello

First a short introduction while i'm new here.
I (including some of my colleagues) have worked with Progress since the early 90's.
From the DOS and OS/2 versions we worked longtime with version 8 (8.3) and 9.
Recently we've upgraded to v11.7 Open Edge.

My question is about the possibilities in User interfaces.
In v8 and 9 we've used the so-called MKALL.p code for generating UI.
Don't if somebody is familiar with this code.
It generates, based on the defined tables/fiels/indexes, code. With this code a standard user interface is available per table, with the standard options (edit/delete etc) but also the possibility to open other tables via their relations.

It works weel, but it is a bit of a tradional UI. For example it is not possible to re-order the view, to copy-paste-change a record etc.

Because we make a lot of changes in dthe db during a project , there is a need to automatically generate the UI after changes in tables / fields / indexes. So building our own UI (in C ## for example) always takes too much time to be up-to-date again.

If somebody is interested i can send/place this MKALL code.

So my question is: are there other ways to generate the UI  based on the defined tables/fiels/indexes, but then in a modern look and feel, including modern edit posibilities?

All Replies
  • I"m interested in the MKALL code.

  • Could you post it on GitHub?

  • I'd be interested in seeing MKALL.p as well.

    Regarding generating the UI, what is your target UI environment? Character UI, Windows Application, Web Application, Mobile Application? I'm not familiar with any code that automatically updates the UI based on db schema. The closest thing coming to mind is the Business Entity tool in PDSOE. That will generate a business logic class with CRUD + Submit methods based on schema, but you'd still have to generate something for the target UI environment. Kendo UI Builder may have something for the UI side, but it relies on a Business Entity, so you'd have to do both sides.

    You will probably need to select your target environment and alter MKALL to generate code for the new UI environment to accomplish what you are trying to do. Whoever wrote MKALL did it for the Character UI, I'm assuming. The same logic it uses to iterate over db schema will apply for any UI; you'll just need to determine the target UI syntax.

    On a separate note, if you are making a lot of changes in the db during a project, is it possible that your projects have not been defined well enough before your team starts working? You might save more time by getting a more clear scope of work / software specification up front and only have to alter the db and UI a couple times during the project. We don't have a perfect software specification model, but we don't seem to change much in the db schema after we make our initial changes at the beginning of the project.

    Best Regards,

    Tim

  • Thanks for the response.  

    My question is still open

    How can i upload jpg/png files in this forum?

    View of the mkall-UI is windows (bit old school), but not basic character oriented

    As a company we design/engineer/build/test and maintain industrial / technical automation systems for plants/tunnels/bridges/metro etc.

    We use the progress db's partly as a engineering db and also as a confuguration tool for these systems. The systems are well specified. In every sprint/iteration/release new features we decide how to use de eng db. So that's why al lot of changes are needed. Also it is used by autotomation engineers, so no end users etc

    ===============================

    About MKALL in short.

    Version was (by my knowledge) part of the DOS version (somewhere 1992)

    We changed the browse code so we have different sizes of the client.

    19 is small on screen on 23" 16:9  /  1920x1080

    22 is width on screen on 23" 16:9  /  1920x1080

    25 is almost full  screen on 23" 16:9  /  1920x1080

    starts with call

    run mkall.p (19)

    run mkall.p (22)

    run mkall.p (25)

    - needs a project folder (in this example  c:\project\x\data\

    - needs also 3 subfolders for the different sizes c:\project\x\data\browse19 /22 /25

    i post it below. In total 11 files (3 similar):

    BROWSE.DOC

    Browse_19.i

    Browse_22.i

    Browse_25.i

    CASCADE.P

    COMMENT.I

    COMMENT2.I

    Mkall.p

    MKBROWSE.P

    MKFORM.P

    RELATE.P

  • filename: BROWSE.DOC

       -----------------------

       PROGRESS Browse Utility

       -----------------------

    'mkall.p' calls 'relate.p' and 'mkbrowse.p' to create a browse

     procedure for every file in the database.

    'relate.p' builds a workfile containing the implied relationships

     in your database.

    'mkbrowse.p' creates the actual .p files that contain the calls to

     browse.i.

    'browse.i' is an include file to browse a file in a database.

     It allows creation of new records and the update or deletion of

     existing records.  It takes many parameters, some optional,

     some not.  These are the parameters :

    {browse.i

     &file=     /* file name */

     &lform=    /* listing form (WITH) include filename (no SKIP/SPACE) */

     &uform=    /* update  form (WITH) include filename (no SKIP/SPACE) */

     &sfld=     /* field to scan over */

     /* optional parameters:

     &where=    /* of xxx where yyy > 35 ... */

     &tlform=   /* listing form include filename (SKIP ok, no WITH) */

     &tuform=   /* update  form include filename (SKIP ok, no WITH) */

     &postfind= /* processing following successful find include filename */

     &release=  /* release processing include filename */

     &seq=      /* id to distinguish names if nested browse */

     &other=    /* other key handling include filename */

     &create=   /* post create processing include filename */

     &update=   /* post update processing include filename */

     &delete=   /* pre  delete processing include filename */

     &numfiles= /* number of related files in jfiles list */

     &jfiles=   /* list of related files "<file1>,<file2>,..." */

     &startup=  /* startup processing after defines */

     all optional include filenames require trailing blank (&xxx="x.i ") */

    }

  • filename: Browse_19.i

    /* browse.i -- generic browse include file

    {browse.i

       &file=      /* file name met database naam*/

       &lform=     /* listing form include filename (no SKIP/SPACE) */

       &uform=     /* update  form include filename (no SKIP/SPACE) */

       &sfld=      /* field to scan over */

       /* optional parameters

       &where=     /* of xxx where yyy > 35 ... */

       &tlform=    /* listing form include filename (SKIP/SPACE ok) */

       &tuform=    /* update  form include filename (SKIP/SPACE ok) */

       &postfind=  /* processing following successful find include filename */

       &release=   /* release processing include filename */

       &nodef=     /* pass a comment start (/ *) to avoid redundant definitions */

       &seq=       /* id to distinguish names if multiple browse */

       &panel=     /* other control panel options */

       &other=     /* handling for other control panel options */

       &create=    /* post create processing include filename */

       &update=    /* post update processing include filename */

       &delete=    /* pre  delete processing include filename */

       &numfiles=  /* number of related files in jfiles list */

       &jfiles=    /* list of related files "<file1>,<file2>,..." */

       &startup=   /* startup processing after defines */

       all optional include filenames require trailing blank (&xxx="x.i ") */

    }

    */

    define variable rid{&seq} as recid extent 50 no-undo.

    {&nodef} /* nodef starts a comment if defines are already done */

    def new global shared variable pick-recid as recid no-undo.

    def new global shared variable join-recid as recid no-undo.

    def var command   as character no-undo.

    def var j         as integer no-undo.

    def var k         as integer no-undo.

    def var crecid    as recid  initial ? no-undo.

    def var verify    as logical no-undo.

    DEFINE VARIABLE mywin    AS WIDGET-HANDLE.

    /{&nodef}* end of conditional defines */

    form {{&tuform}{&*}} with frame uform{&seq} scrollable 1 columns side-labels overlay top-only view-as dialog-box color bright-blue.

    {{&startup}{&*}}

    DEFINE QUERY quer1 FOR {&file} SCROLLING.

    DEF buffer b_{&file} FOR {&file}.

    DEFINE VARIABLE exit-item-ptr    AS WIDGET-HANDLE.

    DEFINE VARIABLE relate-menu-ptr AS WIDGET-HANDLE.

    DEFINE VARIABLE main-bar-ptr AS WIDGET-HANDLE.

    DEFINE VARIABLE temp-hand-ptr AS WIDGET-HANDLE.

    DEFINE VARIABLE choose-menu-ptr AS WIDGET-HANDLE.

    DEFINE VARIABLE oldmenu AS WIDGET-HANDLE.

    DEFINE var rec_id AS RECID.

    DEFINE var new_recid AS RECID init ?.

    DEFINE var old_recid AS RECID init ?.

    oldmenu=CURRENT-WINDOW:MENUBAR.

    /* Create the main menu bar. */

    CREATE MENU main-bar-ptr.

    CREATE MENU-ITEM temp-hand-ptr

       ASSIGN PARENT = main-bar-ptr

      LABEL  = "&Search"

      SENSITIVE = TRUE

    TRIGGERS:

       ON CHOOSE

    RUN cp-search.

    END TRIGGERS.

    CREATE SUB-MENU choose-menu-ptr

       ASSIGN PARENT = main-bar-ptr

      LABEL  = "&Option"

      SENSITIVE = TRUE.

    CREATE MENU-ITEM temp-hand-ptr

       ASSIGN PARENT = main-bar-ptr

      LABEL  = "&Add"

      SENSITIVE = TRUE

    TRIGGERS:

       ON CHOOSE

    run cp-create.

    END TRIGGERS.

    CREATE MENU-ITEM temp-hand-ptr

       ASSIGN PARENT = main-bar-ptr

      LABEL  = "&Update"

      SENSITIVE = TRUE

    TRIGGERS:

       ON CHOOSE

    run cp-Update.

    END TRIGGERS.

    CREATE MENU-ITEM temp-hand-ptr

       ASSIGN PARENT = main-bar-ptr

      LABEL  = "&Copy-New"

      SENSITIVE = TRUE

    TRIGGERS:

       ON CHOOSE

    run cp-Copy-new.

    END TRIGGERS.

    CREATE MENU-ITEM temp-hand-ptr

       ASSIGN PARENT = main-bar-ptr

      LABEL  = "&Kopy-Org"

      SENSITIVE = TRUE

    TRIGGERS:

       ON CHOOSE

    run cp-Copy-org.

    END TRIGGERS.

    CREATE SUB-MENU relate-menu-ptr

       ASSIGN PARENT = main-bar-ptr

      LABEL  = "&Relate"

      SENSITIVE = TRUE.

    /*

    CREATE MENU-ITEM temp-hand-ptr

       ASSIGN PARENT = main-bar-ptr

      LABEL  = "&Put"

      SENSITIVE = TRUE.

    */

    CREATE MENU-ITEM temp-hand-ptr

       ASSIGN PARENT = main-bar-ptr

      LABEL  = "&List"

      SENSITIVE = TRUE

    TRIGGERS:

       ON CHOOSE

    run cp-List.

    END TRIGGERS.

    CREATE MENU-ITEM temp-hand-ptr

       ASSIGN PARENT = main-bar-ptr

      LABEL  = "&Help"

      SENSITIVE = TRUE

    TRIGGERS:

       ON CHOOSE

    run cp-Help.

    END TRIGGERS.

    CREATE MENU-ITEM temp-hand-ptr

       ASSIGN PARENT = main-bar-ptr

      LABEL  = "&Delete"

      SENSITIVE = TRUE

    TRIGGERS:

       ON CHOOSE

    run cp-delete.

    END TRIGGERS.

    CREATE MENU-ITEM exit-item-ptr

       ASSIGN PARENT = main-bar-ptr

      LABEL  = "&Exit"

      SENSITIVE = TRUE

    TRIGGERS:

       ON CHOOSE

    run cp-exit.

    END TRIGGERS.

    /* build the relate menu */

    /*

    create window mywin.

    CURRENT-WINDOW:VISIBLE=FALSE.

    CURRENT-WINDOW=mywin.

    */

    /* aantal rows & columns */

    /* let op

    - deze size moet ook gedefinieerd worden / is een combinatie verderop in dit bestand en nog in 1 ander bestand (PRO_DEVxx.i)

    current-window:width-chars

    = aantal colums  

    - moet gelijk zijn aan de waarde die in bestand \CONNECT\PRO_DEVxx.INI staat bij "columns="

    - moet 1 groter zijn dan de waarde die verderop in dit bestand staat bij

    DEFINE BROWSE brow1 QUERY quer1 DISPLAY {{&lform} {&*}} WITH x DOWN size y by z separators.

    na "size"

    of anders gesteld: 1 lager in de DEFINE BROWSE dan de waarde in de PRO_DEVxx.INI bij Columns / current-window:width-chars

    current-window:height-chars

    = aantal rows

    - moet gelijk zijn aan de waarde die in bestand \CONNECT\PRO_DEVxx.INI  bij "rows=  staat

    - moet gelijk zijn aan de waarde die verder op in dit bestand staat bij

    DEFINE BROWSE brow1 QUERY quer1 DISPLAY {{&lform} {&*}} WITH x DOWN size y by z separators.

    na "WITH"

    - moet 1 groter zijn aan de waarde die verder op in dit bestand staat bij

    DEFINE BROWSE brow1 QUERY quer1 DISPLAY {{&lform} {&*}} WITH x DOWN size y by z separators.

    na "by"

    of anders gesteld:

          gelijk in de DEFINE BROWSE achter "WITH" als de waarde in de PRO_DEVxx.INI bij Rows / current-window:height-chars

          1 lager in de DEFINE BROWSE achter "by " als de waarde in de PRO_DEVxx.INI bij Rows / current-window:height-chars

    */

    /**********************/

    /* KEUZE hoeveel inch */

    /**********************/

    /*

    klein (de oude)

    current-window:width-chars=120.

    current-window:height-chars=23.

    breed voor 3:4 19"

    current-window:width-chars=155.

    current-window:height-chars=25.

    lekker breed voor 16:9 22"

    current-window:width-chars=235.

    current-window:height-chars=25.

    lekker groot full screen  voor 16:9

    current-window:width-chars=240.

    current-window:height-chars=44.

    */

    /* HUIDIG GEBRUIKT: */

    current-window:width-chars=155.

    current-window:height-chars=25.

    /* Set up the menu bar. */

    CURRENT-WINDOW:MENUBAR = main-bar-ptr.

    run ververs.

    /*WAIT-FOR CHOOSE OF exit-item-ptr.*/

    CURRENT-WINDOW:MENUBAR=oldmenu.

    /*************************************************/

    procedure ververs:

    /* Create a menu item for each record in the relate option. */

    j = 1.

    k = 0{&numfiles}.

    DO WHILE j <= k:

    FIND _file WHERE _file._file-name =  "{&file}".

    IF NOT AVAILABLE _FILE THEN MESSAGE "Er is iets mis gegaan !".

    IF entry(j, "{&jfiles}") ne "-" THEN DO:

    CREATE MENU-ITEM temp-hand-ptr

    ASSIGN PARENT = relate-menu-ptr

    LABEL = entry(j, "{&jfiles}")

    PRIVATE-DATA=lc(substr(_file._dump-name, 1, 7)) + STRING(j) + ".p"

    TRIGGERS:

    ON CHOOSE DO:

    join-recid = recid({&file}).

    MESSAGE SELF:PRIVATE-DATA.

    RUN VALUE(SELF:PRIVATE-DATA).

    CURRENT-WINDOW:MENUBAR = main-bar-ptr.

    END.

    END TRIGGERS.

    END.

    ELSE k = k + 1.

    j = j + 1.

    END.

    /* Create a menu item for each record in the choose option. */

    FOR EACH filecall WHERE filecall.filenaam = "{&file}":

    CREATE MENU-ITEM temp-hand-ptr

    ASSIGN PARENT = choose-menu-ptr

    LABEL = STRING(filecall.titel)

    PRIVATE-DATA=(filecall.program) + ".p"

    TRIGGERS:

    ON CHOOSE DO:

    join-recid = recid({&file}).

    MESSAGE SELF:PRIVATE-DATA.

    RUN VALUE(SELF:PRIVATE-DATA) (input join-recid, output new_recid).

    CURRENT-WINDOW:MENUBAR = main-bar-ptr.

    /* new gecreerde record laten zien */

    HIDE FRAME uform{&seq}.

    OPEN QUERY quer1 FOR EACH {&file} {&where}.

    IF new_recid <> ? THEN reposition quer1 to recid new_recid.

    END.

    END TRIGGERS.

    END.

    /********************/

    /*keuze hoeveel inch*/

    /********************/

    /* define van de browse query

    let op, zie opmerkingen hierboven voor de juiste instelling

    - waardes hebben relatie met nog 2 plekken, zie begin van deze browse.i

    9-6-2015 17:20  goed  oude 4:3

     DEFINE BROWSE brow1 QUERY quer1 DISPLAY {{&lform} {&*}} WITH 22 DOWN size 119 by 22 separators.

    19

    size voor een 16:9 scherm  smal

     DEFINE BROWSE brow1 QUERY quer1 DISPLAY {{&lform} {&*}} WITH 25 DOWN size 154 by 24 separators.

    size voor breed  voor 16:9

     DEFINE BROWSE brow1 QUERY quer1 DISPLAY {{&lform} {&*}} WITH 25 DOWN size 229 by 24 separators.

    size voor full screen 23 :25

     DEFINE BROWSE brow1 QUERY quer1 DISPLAY {{&lform} {&*}} WITH 44 DOWN size 239 by 43 separators.

    HUIDIG GEBRUIKT:  

    */

     DEFINE BROWSE brow1 QUERY quer1 DISPLAY {{&lform} {&*}} WITH 25 DOWN size 154 by 24 separators.

    /* define van de frame */

    /*

    org:

    DEFINE FRAME fram1 brow1 WITH SIDE-LABELS THREE-D.

    kan ook:

    DEFINE FRAME fram1 brow1 WITH SIDE-LABELS color Red/white THREE-D.

    */

    DEFINE FRAME fram1 brow1 WITH SIDE-LABELS color bright-blue/white THREE-D.

    OPEN QUERY quer1 FOR EACH {&file} {&where}.

    ENABLE ALL.

    ENABLE brow1 WITH FRAME fram1 THREE-D.

    WAIT-FOR CHOOSE OF exit-item-ptr.

    HIDE FRAME fram1.

    END.

    /********************************************************************/

    procedure cp-search:

    prompt {&file}.{&sfld} with frame keyfld{&seq}

    overlay attr-space side-labels row 6 top-only view-as dialog-box

    centered title "Search" THREE-D.

    FIND first {&file} {&where} using frame keyfld{&seq} {&file}.{&sfld} no-error.

    HIDE FRAME keyfld{&seq}.

    IF NOT AVAILABLE {&file} THEN FIND prev {&file} {&where} no-error.

    reposition quer1 to recid recid({&file}).

    END.

    /********************************************************************/

    procedure cp-create:

    crecid = ?.

    old_recid = recid({&file}).

    DO on error undo, retry on endkey undo, leave:

    /* schonen form */

    clear frame uform{&seq} all.

    create {&file}.

    {{&create}{&*}}

    join-recid = recid({&file}).

    prompt {{&uform} &text=TEXT( &endtext=) &noupdate="/*" {&*}}

    with frame uform{&seq} three-d.

    FIND {&file} WHERE recid({&file}) = join-recid EXCLUSIVE-LOCK.

    IF AVAILABLE {&file} THEN DO:

    assign {{&uform} &input="input frame uform{&seq}" &nowith="/*" {&*}}.

    END.

    IF NOT AVAILABLE {&file} THEN DO:

    message "Record in use".

    END.

    clear frame uform{&seq} all.

    validate {&file}.

    IF crecid = ? THEN crecid = recid({&file}).

    release {&file}.

    {{&release}{&*}}

    DOWN.

    END.

    HIDE FRAME uform{&seq}.

    OPEN QUERY quer1 FOR EACH {&file} {&where}.

    IF crecid <> ? THEN reposition quer1 to recid crecid.

    IF crecid =  ? THEN reposition quer1 to recid old_recid.

    END.

    /********************************************************************/

    procedure cp-delete:

    /*

    26-8-2015 16:58 origineel

    verify = no.

    MESSAGE " Record verwijderen ? "

    VIEW-AS ALERT-BOX QUESTION BUTTONS YES-NO UPDATE verify.

    IF NOT verify THEN leave.

    get current quer1 exclusive-lock.

    {{&postfind}{&*}}

    {{&delete}{&*}}

    delete {&file}.

    {{&release}{&*}}

    OPEN QUERY quer1 FOR EACH {&file} {&where}.

    */

    verify = no.

    old_recid = recid({&file}).

    crecid = ?.

    /* record nogmaals zoeken via buffer om de volgende of vorige te zoeken

    let op, als je gerelateerd via een andere tabel in een volgende tabel gaat deleten (vb FUNCTIE -> FUNCBIT),

    vindt deze procedure wel een volgende record, maar kan hem niet tonen, dus dan gaat de UI niet helemaal lekker: springt terug naar 1e record

    */

    FIND FIRST b_{&file} WHERE recid(b_{&file}) = old_recid NO-ERROR.

    IF AVAILABLE b_{&file} THEN DO:

    /* volgende record zoeken */

    FIND NEXT b_{&file} no-error.

    IF AVAILABLE b_{&file} THEN DO:

    /*

    disp b_{&file} with frame b1.

    disp recid(b_{&file}) with frame b2.

    */

    /* vastleggen record ID */

    crecid = recid(b_{&file}).

    END.

    IF NOT AVAILABLE b_{&file} THEN DO:

    /* dan 2 records terug zoeken = de vorige */

    FIND PREV b_{&file} no-error.

    IF AVAILABLE b_{&file} THEN DO:

    FIND PREV b_{&file} no-error.

    IF AVAILABLE b_{&file} THEN DO:

    /*

    disp b_{&file} with frame c1.

    disp recid(b_{&file}) with frame c2.

    */

    /* vastleggen record ID */

    crecid = recid(b_{&file}).

    END.

    END.

    END.

    END.

    HIDE FRAME uform{&seq}.

    MESSAGE " Record verwijderen ? "

    VIEW-AS ALERT-BOX QUESTION BUTTONS YES-NO UPDATE verify.

    IF NOT verify THEN leave.

    get current quer1 exclusive-lock.

    {{&postfind}{&*}}

    {{&delete}{&*}}

    delete {&file}.

    {{&release}{&*}}

    HIDE FRAME uform{&seq}.

    OPEN QUERY quer1 FOR EACH {&file} {&where}.

    IF crecid <> ? THEN reposition quer1 to recid crecid no-error.

    END.

    /********************************************************************/

    procedure cp-update:

    {{&postfind}{&*}}

    join-recid = recid({&file}).

    get current quer1 exclusive-lock.

    display {{&uform} {&*}} with frame uform{&seq}.

    DO on error undo, retry on endkey undo, leave:

    prompt {{&uform} &text=TEXT( &endtext=) &noupdate="/*" {&*}}

    with frame uform{&seq} three-d.

    {{&update}{&*}}

    FIND FIRST {&file} WHERE recid({&file}) = join-recid.

    IF AVAILABLE {&file} THEN

    assign {{&uform} &input="input frame uform{&seq}" &nowith="/*" {&*}}.

    END.

    HIDE FRAME uform{&seq}.

    clear frame uform{&seq} all.

    validate {&file}.

    release {&file}.

    {{&release}{&*}}

    OPEN QUERY quer1 FOR EACH {&file} {&where}.

    reposition quer1 to recid join-recid.

    END.

    /********************************************************************/

    procedure cp-copy-new:

    /* LABEL  = "&Copy-New" */

    crecid = ?.

    old_recid = recid({&file}).

    DO on error undo, retry on endkey undo, leave:

    display {{&uform} {&*}} with frame uform{&seq}.

    create {&file}.

    {{&create}{&*}}

    join-recid = recid({&file}).

    prompt {{&uform} &text=TEXT( &endtext=) &noupdate="/*" {&*}}

    with frame uform{&seq} three-d.

    FIND {&file} WHERE recid({&file}) = join-recid EXCLUSIVE-LOCK.

    IF AVAILABLE {&file} THEN DO:

    assign {{&uform} &input="input frame uform{&seq}" &nowith="/*" {&*}}.

    END.

    IF NOT AVAILABLE {&file} THEN DO:

    message "Record in use".

    END.

    clear frame uform{&seq} all.

    validate {&file}.

    IF crecid = ? THEN crecid = recid({&file}).

    release {&file}.

    {{&release}{&*}}

    DOWN.

    END.

    HIDE FRAME uform{&seq}.

    OPEN QUERY quer1 FOR EACH {&file} {&where}.

    /* als copy gedaan is dan view op nieuwe record */

    IF crecid <> ? THEN reposition quer1 to recid crecid.

    IF crecid =  ? THEN reposition quer1 to recid old_recid.

    END.

    /********************************************************************/

    procedure cp-copy-org:

    /* LABEL  = "&Kopy-Org" */

    crecid = ?.

    old_recid = recid({&file}).

    DO on error undo, retry on endkey undo, leave:

    display {{&uform} {&*}} with frame uform{&seq}.

    create {&file}.

    {{&create}{&*}}

    join-recid = recid({&file}).

    prompt {{&uform} &text=TEXT( &endtext=) &noupdate="/*" {&*}}

    with frame uform{&seq} three-d.

    FIND {&file} WHERE recid({&file}) = join-recid EXCLUSIVE-LOCK.

    IF AVAILABLE {&file} THEN DO:

    assign {{&uform} &input="input frame uform{&seq}" &nowith="/*" {&*}}.

    END.

    IF NOT AVAILABLE {&file} THEN DO:

    message "Record in use".

    END.

    clear frame uform{&seq} all.

    validate {&file}.

    release {&file}.

    {{&release}{&*}}

    DOWN.

    END.

    HIDE FRAME uform{&seq}.

    OPEN QUERY quer1 FOR EACH {&file} {&where}.

    reposition quer1 to recid old_recid.

    END.

    /********************************************************************/

    procedure cp-List:

    run l_{&file}.p (rec_id).

    END.

    /********************************************************************/

    procedure cp-Help:

    run h_{&file}.p (rec_id).

    END.

    /********************************************************************/

    procedure cp-exit:

    /*

    release {&file}.

    HIDE FRAME {&lform}.

    HIDE FRAME fram1.

    */

    END.

    hide all.

  • filename: CASCADE.P

    /************************************************************************/

    /* cascade.p -- to build include that cascades updates of match keys */

    /* */

    /* Input: */

    /* parameter "file-name" of owner file */

    /* parameter "omatchlst" of owner fields to ignore */

    /* shared workfile "relate" describing database relationships */

    /************************************************************************/

    define shared workfile relate

       field owner    like _file._file-name

       field mem   like _file._file-name

       field idx      like _index._index-name

       field numfld   as integer format ">9"

       field matchlst as character format "x(80)"

       field dumpowner like _file._dump-name

       field dumpmem like _file._dump-name.

    define input parameter file-name like _file._file-name.

    define input parameter omatchlst  as character.

    define variable i as integer.

    define variable tst as character.

    for each relate where owner = file-name break by idx:

       if first-of (idx)

       then do:

    tst = "if ".

    do i = 1 to numfld:

       if lookup(entry(i, matchlst), omatchlst) ne 0

       then next.

       put unformatted

    tst /* "if " or "or " */

    "input frame uform~{&seq~} ~{&file~}." entry(i, matchlst)

    " entered" skip.

       tst = "or ".

    end.

    put unformatted "then do:" skip.

       end.

       put unformatted space(4)

    "for each " mem " of ~{&file~}:" skip

    space(8) "assign" .

       do i = 1 to numfld:

    if lookup(entry(i, matchlst), omatchlst) ne 0

    then next.

    put unformatted skip

       space(12) mem "." entry(i, matchlst)

    " = input frame uform~{&seq~} ~{&file~}." entry(i, matchlst).

       end.

       put unformatted

    "." skip

    space(4) "end." skip.

       if last-of (idx)

       then put unformatted "end." skip.

    end.

  • filename: COMMENT.I

    /*

    ======================

    filename: COMMENT2.I

    /*/*

  • filename: MKBROWSE.P

    /************************************************************************/

    /* mkbrowse.p -- to build generic browse procedures for a database file */

    /* */

    /* Input: */

    /* _File record in shared buffer "file" */

    /* shared workfile "relate" describing database relationships */

    /* */

    /* For each "owner" of the given file, it produces: */

    /* <file>n.p - to browse the owner */

    /* uses: <file>.rec, <owner>.upd, <owner>.lf */

    /* */

    /* For each "mem" of the given file, it produces: */

    /* <file>n.p - to browse the member */

    /* <file>n.cr - to copy match fields from parent on create */

    /* <file>n.upd - to cascade update of match key in members */

    /* Looks for index with leading match fields and */

    /*  uses subsequent component as scan field (warning if none) */

    /* Uses: <member>.lf, <member>.upd, <file>.rec */

    /* */

    /* For the file, it produces: */

    /* <file>.rec - to find the original record when joining */

    /* <file>.p - to browse the file */

    /* <file>.upd - to cascade update of match key in members */

    /* */

    /************************************************************************/

    Define input parameter cFormaatGUI AS char.

    define shared buffer file for _file.

    define shared variable progpad as char.

    define shared workfile relate

       field owner    like _file._file-name

       field mem   like _file._file-name

       field idx      like _index._index-name

       field numfld   as integer format ">9"

       field matchlst as character format "x(80)"

       field dumpowner like _file._dump-name

       field dumpmem like _file._dump-name.

    define buffer xrelate for relate.

    define variable numfiles as integer.

    define variable jfiles as character.

    define variable xnumfiles as integer.

    define variable xjfiles as character.

    define variable i as integer.

    /**/

    /********************* Process each owner of given file *********************/

    for each relate where relate.mem = file._file-name by relate.owner:

       numfiles = numfiles + 1.

       jfiles = jfiles + "," + relate.owner.

       find _file where _file-name = relate.owner.

       find _index where recid(_index) = _file._Prime-Index.

       find first _index-field of _index.

       find _field of _index-field.

     xnumfiles = 0.

     xjfiles = "".

     for each xrelate where xrelate.mem = relate.owner by xrelate.owner:

       xnumfiles = xnumfiles + 1.

       xjfiles = xjfiles + "," + xrelate.owner.

     end.

     for each xrelate where xrelate.owner = relate.owner by xrelate.mem:

       if xrelate.mem = relate.mem then xjfiles = xjfiles + ",-".

       else do:

         xjfiles = xjfiles + "," + xrelate.mem.

         xnumfiles = xnumfiles + 1.

       end.

     end.

     output to value(progpad + lc(substr(relate.dumpmem, 1, 7)) + string(numfiles) + ".p").

     put unformatted "~{browse_"

    cFormaatGUI

       ".i"

    skip

       space(4) "&file=" relate.owner skip

       space(4) "&where=""of " relate.mem """" skip

       space(4) "&lform=" lc(substr(relate.dumpowner, 1, 8)) ".lf" skip

       space(4) "&uform=" lc(substr(relate.dumpowner, 1, 8)) ".lf" skip

       space(4) "&OF" relate.mem "=/~*" skip.

       put unformatted space(4) "&sfld=" _field-name skip.

     put unformatted

     space(4) "&startup=""" lc(substr(relate.dumpmem, 1, 8)) ".rec """ skip

     space(4) "&update=""" lc(substr(relate.dumpowner, 1, 8)) ".upd """ skip.

     if xnumfiles > 0

     then put unformatted

       space(4) "&numfiles=" xnumfiles skip

       space(4) "&jfiles=""" substring(xjfiles, 2) """" skip.

     put unformatted

       "}" skip

       "form with frame xlist 1 down." skip.

       output close.

    end.

    /**/

    /******************** Process each member of given file ********************/

    for each relate where relate.owner = file._file-name by relate.mem:

       numfiles = numfiles + 1.

       jfiles = jfiles + "," + relate.mem.

       output to value(progpad + lc(substr(relate.dumpowner, 1, 7)) + string(numfiles) + ".cr").

       do i = 1 to relate.numfld:

    put unformatted

         relate.mem "." entry(i, relate.matchlst) " = "

         relate.owner  "." entry(i, relate.matchlst) "." skip.

       end.

       output close.

       xnumfiles = 0.

       xjfiles = "".

       for each xrelate where xrelate.mem = relate.mem by xrelate.owner:

    if xrelate.owner = relate.owner

    then xjfiles = xjfiles + ",-".

    else do:

       xjfiles = xjfiles + "," + xrelate.owner.

       xnumfiles = xnumfiles + 1.

    end.

       end.

       for each xrelate where xrelate.owner = relate.mem by xrelate.mem:

    xnumfiles = xnumfiles + 1.

    xjfiles = xjfiles + "," + xrelate.mem.

       end.

       for _file where _file._file-name = relate.mem, each _index of _file:

    for each _index-field of _index, _field of _index-field:

       if lookup(_field-name, matchlst) = 0

       then leave.

    end.

     if available _index-field /* and _index-seq = numfld + 1 JB */

    then do:

    leave.

    end.

    else release _field.

       end.

       if not available _field

       then do:

            message "Could not find appropriate sfld for"

            relate.owner relate.mem.

            /*

            create _field.

            update _field.

            */

            end.

         else do:

    /**/

       output to value(progpad + lc(substr(relate.dumpowner, 1, 7)) + string(numfiles) + ".p").

     put unformatted "~{browse_"

    cFormaatGUI

       ".i"

    skip

    space(4) "&file=" relate.mem skip

    space(4) "&where=""of " relate.owner """" skip

    space(4) "&lform=" lc(substr(relate.dumpmem, 1, 8)) ".lf" skip

    space(4) "&uform=" lc(substr(relate.dumpmem, 1, 8)) ".lf" skip

    space(4) "&OF" relate.owner "=/~*" skip.

      put unformatted space(4) "&sfld=" _field._field-name skip.

    put unformatted

    space(4) "&create=""" lc(substr(relate.dumpowner, 1, 7))

       numfiles ".cr """ skip

    space(4) "&startup=""" lc(substr(relate.dumpowner, 1, 8)) ".rec """ skip

    space(4) "&update=""" lc(substr(relate.dumpowner, 1, 7))

       numfiles ".upd """ skip.

       if xnumfiles > 0

       then put unformatted

    space(4) "&numfiles=" xnumfiles skip

    space(4) "&jfiles=""" substring(xjfiles, 2) """" skip.

       put unformatted

    "}" skip.

       output close.

       end.

       output to value(progpad + lc(substr(relate.dumpowner, 1, 7)) + string(numfiles) + ".upd").

       run cascade.p (input relate.mem, input matchlst).

       output close.

    end.

    /**************************** Process given file ****************************/

    if numfiles > 0

    then do:

       output to value(progpad + lc(substr(file._dump-name, 1, 8)) + ".rec").

       put unformatted "find " file._file-name

    " where recid(" file._file-name ") = join-recid." skip.

       output close.

    end.

    find _index where recid(_index) = file._Prime-Index.

    find first _index-field of _index.

    find _field of _index-field.

    output to value(progpad + lc(substr(file._dump-name, 1, 8)) + ".p").

     put unformatted

       "~{browse_"

    cFormaatGUI

       ".i"

    skip

       space(4) "&file=" file._file-name skip

       space(4) "&lform=" lc(substr(file._dump-name, 1, 8)) ".lf" skip

       space(4) "&uform=" lc(substr(file._dump-name, 1, 8)) ".lf" skip.

       put unformatted space(4) "&sfld=" _field-name skip.

    put unformatted

       space(4) "&update=""" lc(substr(file._dump-name, 1, 8)) ".upd """ skip.

    if numfiles > 0

    then put unformatted

       space(4) "&numfiles=" numfiles skip

       space(4) "&jfiles=""" substring(jfiles, 2) """" skip.

    put unformatted

       "}" skip.

    output close.

    /************************** JB ****************************/

    output to value(progpad + lc(substr(file._dump-name, 1, 8)) + ".upd").

      run cascade.p (input file._file-name, input "").

    output close.

  • filename: MKBROWSE.P

    /************************************************************************/

    /* mkbrowse.p -- to build generic browse procedures for a database file */

    /* */

    /* Input: */

    /* _File record in shared buffer "file" */

    /* shared workfile "relate" describing database relationships */

    /* */

    /* For each "owner" of the given file, it produces: */

    /* <file>n.p - to browse the owner */

    /* uses: <file>.rec, <owner>.upd, <owner>.lf */

    /* */

    /* For each "mem" of the given file, it produces: */

    /* <file>n.p - to browse the member */

    /* <file>n.cr - to copy match fields from parent on create */

    /* <file>n.upd - to cascade update of match key in members */

    /* Looks for index with leading match fields and */

    /*  uses subsequent component as scan field (warning if none) */

    /* Uses: <member>.lf, <member>.upd, <file>.rec */

    /* */

    /* For the file, it produces: */

    /* <file>.rec - to find the original record when joining */

    /* <file>.p - to browse the file */

    /* <file>.upd - to cascade update of match key in members */

    /* */

    /************************************************************************/

    Define input parameter cFormaatGUI AS char.

    define shared buffer file for _file.

    define shared variable progpad as char.

    define shared workfile relate

       field owner    like _file._file-name

       field mem   like _file._file-name

       field idx      like _index._index-name

       field numfld   as integer format ">9"

       field matchlst as character format "x(80)"

       field dumpowner like _file._dump-name

       field dumpmem like _file._dump-name.

    define buffer xrelate for relate.

    define variable numfiles as integer.

    define variable jfiles as character.

    define variable xnumfiles as integer.

    define variable xjfiles as character.

    define variable i as integer.

    /**/

    /********************* Process each owner of given file *********************/

    for each relate where relate.mem = file._file-name by relate.owner:

       numfiles = numfiles + 1.

       jfiles = jfiles + "," + relate.owner.

       find _file where _file-name = relate.owner.

       find _index where recid(_index) = _file._Prime-Index.

       find first _index-field of _index.

       find _field of _index-field.

     xnumfiles = 0.

     xjfiles = "".

     for each xrelate where xrelate.mem = relate.owner by xrelate.owner:

       xnumfiles = xnumfiles + 1.

       xjfiles = xjfiles + "," + xrelate.owner.

     end.

     for each xrelate where xrelate.owner = relate.owner by xrelate.mem:

       if xrelate.mem = relate.mem then xjfiles = xjfiles + ",-".

       else do:

         xjfiles = xjfiles + "," + xrelate.mem.

         xnumfiles = xnumfiles + 1.

       end.

     end.

     output to value(progpad + lc(substr(relate.dumpmem, 1, 7)) + string(numfiles) + ".p").

     put unformatted "~{browse_"

    cFormaatGUI

       ".i"

    skip

       space(4) "&file=" relate.owner skip

       space(4) "&where=""of " relate.mem """" skip

       space(4) "&lform=" lc(substr(relate.dumpowner, 1, 8)) ".lf" skip

       space(4) "&uform=" lc(substr(relate.dumpowner, 1, 8)) ".lf" skip

       space(4) "&OF" relate.mem "=/~*" skip.

       put unformatted space(4) "&sfld=" _field-name skip.

     put unformatted

     space(4) "&startup=""" lc(substr(relate.dumpmem, 1, 8)) ".rec """ skip

     space(4) "&update=""" lc(substr(relate.dumpowner, 1, 8)) ".upd """ skip.

     if xnumfiles > 0

     then put unformatted

       space(4) "&numfiles=" xnumfiles skip

       space(4) "&jfiles=""" substring(xjfiles, 2) """" skip.

     put unformatted

       "}" skip

       "form with frame xlist 1 down." skip.

       output close.

    end.

    /**/

    /******************** Process each member of given file ********************/

    for each relate where relate.owner = file._file-name by relate.mem:

       numfiles = numfiles + 1.

       jfiles = jfiles + "," + relate.mem.

       output to value(progpad + lc(substr(relate.dumpowner, 1, 7)) + string(numfiles) + ".cr").

       do i = 1 to relate.numfld:

    put unformatted

         relate.mem "." entry(i, relate.matchlst) " = "

         relate.owner  "." entry(i, relate.matchlst) "." skip.

       end.

       output close.

       xnumfiles = 0.

       xjfiles = "".

       for each xrelate where xrelate.mem = relate.mem by xrelate.owner:

    if xrelate.owner = relate.owner

    then xjfiles = xjfiles + ",-".

    else do:

       xjfiles = xjfiles + "," + xrelate.owner.

       xnumfiles = xnumfiles + 1.

    end.

       end.

       for each xrelate where xrelate.owner = relate.mem by xrelate.mem:

    xnumfiles = xnumfiles + 1.

    xjfiles = xjfiles + "," + xrelate.mem.

       end.

       for _file where _file._file-name = relate.mem, each _index of _file:

    for each _index-field of _index, _field of _index-field:

       if lookup(_field-name, matchlst) = 0

       then leave.

    end.

     if available _index-field /* and _index-seq = numfld + 1 JB */

    then do:

    leave.

    end.

    else release _field.

       end.

       if not available _field

       then do:

            message "Could not find appropriate sfld for"

            relate.owner relate.mem.

            /*

            create _field.

            update _field.

            */

            end.

         else do:

    /**/

       output to value(progpad + lc(substr(relate.dumpowner, 1, 7)) + string(numfiles) + ".p").

     put unformatted "~{browse_"

    cFormaatGUI

       ".i"

    skip

    space(4) "&file=" relate.mem skip

    space(4) "&where=""of " relate.owner """" skip

    space(4) "&lform=" lc(substr(relate.dumpmem, 1, 8)) ".lf" skip

    space(4) "&uform=" lc(substr(relate.dumpmem, 1, 8)) ".lf" skip

    space(4) "&OF" relate.owner "=/~*" skip.

      put unformatted space(4) "&sfld=" _field._field-name skip.

    put unformatted

    space(4) "&create=""" lc(substr(relate.dumpowner, 1, 7))

       numfiles ".cr """ skip

    space(4) "&startup=""" lc(substr(relate.dumpowner, 1, 8)) ".rec """ skip

    space(4) "&update=""" lc(substr(relate.dumpowner, 1, 7))

       numfiles ".upd """ skip.

       if xnumfiles > 0

       then put unformatted

    space(4) "&numfiles=" xnumfiles skip

    space(4) "&jfiles=""" substring(xjfiles, 2) """" skip.

       put unformatted

    "}" skip.

       output close.

       end.

       output to value(progpad + lc(substr(relate.dumpowner, 1, 7)) + string(numfiles) + ".upd").

       run cascade.p (input relate.mem, input matchlst).

       output close.

    end.

    /**************************** Process given file ****************************/

    if numfiles > 0

    then do:

       output to value(progpad + lc(substr(file._dump-name, 1, 8)) + ".rec").

       put unformatted "find " file._file-name

    " where recid(" file._file-name ") = join-recid." skip.

       output close.

    end.

    find _index where recid(_index) = file._Prime-Index.

    find first _index-field of _index.

    find _field of _index-field.

    output to value(progpad + lc(substr(file._dump-name, 1, 8)) + ".p").

     put unformatted

       "~{browse_"

    cFormaatGUI

       ".i"

    skip

       space(4) "&file=" file._file-name skip

       space(4) "&lform=" lc(substr(file._dump-name, 1, 8)) ".lf" skip

       space(4) "&uform=" lc(substr(file._dump-name, 1, 8)) ".lf" skip.

       put unformatted space(4) "&sfld=" _field-name skip.

    put unformatted

       space(4) "&update=""" lc(substr(file._dump-name, 1, 8)) ".upd """ skip.

    if numfiles > 0

    then put unformatted

       space(4) "&numfiles=" numfiles skip

       space(4) "&jfiles=""" substring(jfiles, 2) """" skip.

    put unformatted

       "}" skip.

    output close.

    /************************** JB ****************************/

    output to value(progpad + lc(substr(file._dump-name, 1, 8)) + ".upd").

      run cascade.p (input file._file-name, input "").

    output close.

  • filename: MKFORM.P

    /************************************************************************/

    /* mkform.p -- to build a form include for a file (<filename>.lf) */

    /* */

    /* Input: */

    /* _File record in shared buffer "file" */

    /* shared workfile "relate" describing database relationships */

    /************************************************************************/

    define shared buffer file for _file.

    define shared variable progpad as char.

    define shared workfile relate

       field owner    like _file._file-name

       field mem   like _file._file-name

       field idx      like _index._index-name

       field numfld   as integer format ">9"

       field matchlst as character format "x(80)"

       field dumpowner like _file._dump-name

       field dumpmem like _file._dump-name.

    define variable close-comment as logical.

    define variable temp as char.

    define variable cTitel as char.

    output to value(progpad + lc(substr(file._dump-name, 1, 8)) + ".lf").

    for each _field of file break by _order:

       close-comment = no.

       for each relate where relate.mem = file._file-name by relate.owner:

    if lookup(_field-name, relate.matchlst) ne 0

    then do:

       put unformatted "~{&OF" relate.owner "}" skip.

       close-comment = yes.

    end.

       end.

       if _dtype = 1 /* character */ and _Extent > 0

       then put unformatted "~{~&text}" skip.

        put unformatted "~{&input} ~{&file}." _field-name skip.

       if _dtype = 1 /* character */ and _Extent > 0

       then put unformatted "~{~&endtext}" skip.

       if close-comment

       then put unformatted "~{comment.i} */" skip.

    end.

    /**/

    /* van

    D:\projects\xx\data\"db"

    naar

    xx

    */

    cTitel = progpad.

    cTitel = replace(cTitel,"\c:\project\x\data\","").

    cTitel = replace(cTitel,"browse19\"," (19)").

    cTitel = replace(cTitel,"browse22\"," (22)").

    cTitel = replace(cTitel,"browse25\"," (25)").

    put unformatted "~{&nowith}" skip

       "with centered overlay title "" DB :  " + upper(cTitel) + "  -  " + upper(cTitel) + "  -  " + upper(cTitel) + "   -   Tabel :  <~{&file}>    " + "~"" skip.

    for each relate where relate.owner = file._file-name by relate.mem:

       put unformatted "~{&OF" relate.mem "} ~{comment2.i} */ ~{&nowith}" skip

    space(4) " + "" of tabel <" relate.mem ">   Record(s):  """ skip.

       for _file where _file._file-name = relate.mem,

    _index where recid(_index) = _file._Prime-Index,

    each _index-field of _index,

    _field of _index-field:

    put unformatted space(4) " + string("

       relate.mem "." _field-name ") + "" """ skip.

       end.

       put unformatted "~{comment.i} */ ~{&nowith}" skip.

    end.

    for each relate where relate.mem = file._file-name by relate.owner:

       put unformatted "~{&OF" relate.owner "} ~{comment2.i} */ ~{&nowith}" skip

    space(4) " + "" of tabel <" relate.owner ">   Record(s):  """ skip.

       for _file where _file._file-name = relate.owner,

    _index where recid(_index) = _file._Prime-Index,

    each _index-field of _index,

    _field of _index-field:

    put unformatted space(4) " + string("

       relate.owner "." _field-name ")   + "" . """ skip.

       end.

       put unformatted "~{comment.i} */ ~{&nowith}" skip.

    end.

    put unformatted "~{comment.i} */" skip.

    output close.

  • filename: RELATE.P

    /************************************************************************/

    /* relate.p -- to populate workfile "relate" with db relationships */

    /* */

    /* Input: */

    /* shared workfile "relate" to describe database relationships */

    /************************************************************************/

    define shared workfile relate

       field owner    like _file._file-name

       field mem   like _file._file-name

       field idx      like _index._index-name

       field numfld   as integer format ">9"

       field matchlst as character format "x(80)"

       field dumpowner like _file._dump-name

       field dumpmem like _file._dump-name.

    define buffer xfld for _field.

    define buffer xfile for _file.

    define variable tnum as integer format ">9".

    define variable tmatch as character format "x(80)".

    define variable tdt like _field._data-type extent 10.

    define variable idx as integer.

    /*for each _index where _unique, each _file of _index where _file-number > 0:*/

    for each _index where _unique, each _file of _index {_file2.i}:

       tnum = 0.

       for each _index-field of _index, _field of _index-field:

    tnum = tnum + 1.

    tmatch = if tnum = 1 then _field-name else tmatch + "," + _field-name.

    tdt[tnum] = _Data-Type.

              if _index._index-name = "{2}" then do:

                 disp _index._index-name _index-field._index-seq.

              end.

           /*

           disp _index._index-name.

           disp _index-field._index-seq.

           */

       end.

       if tnum = 0 then next.

    mbr:

       for each _field where _field-name = entry(1, tmatch) and

       _Data-Type = tdt[1] and

       _File-Recid ne recid(_File), xfile of _field:

           do idx = 2 to tnum:

              find xfld of xfile where

              xfld._field-name = entry(idx, tmatch) and

              xfld._Data-Type = tdt[idx] no-error.

              if not available xfld then next mbr.

           end.

           create relate.

           relate.owner     = _file._file-name.

           relate.dumpowner = _file._dump-name.

           relate.mem       = xfile._file-name.

           relate.dumpmem   = xfile._dump-name.

           relate.idx       = _index._index-name.

           relate.numfld    = tnum.

           relate.matchlst  = tmatch.

       end.

    end.

    for each relate break by owner by mem:

       if not (first-of (mem) and last-of (mem)) then do:

           display relate.owner relate.mem relate.idx

           with centered title "Duplicate relationships".

           delete relate.

       end.

    end.

  • filename: CASCADE.P

    /************************************************************************/

    /* cascade.p -- to build include that cascades updates of match keys */

    /* */

    /* Input: */

    /* parameter "file-name" of owner file */

    /* parameter "omatchlst" of owner fields to ignore */

    /* shared workfile "relate" describing database relationships */

    /************************************************************************/

    define shared workfile relate

       field owner    like _file._file-name

       field mem   like _file._file-name

       field idx      like _index._index-name

       field numfld   as integer format ">9"

       field matchlst as character format "x(80)"

       field dumpowner like _file._dump-name

       field dumpmem like _file._dump-name.

    define input parameter file-name like _file._file-name.

    define input parameter omatchlst  as character.

    define variable i as integer.

    define variable tst as character.

    for each relate where owner = file-name break by idx:

       if first-of (idx)

       then do:

    tst = "if ".

    do i = 1 to numfld:

       if lookup(entry(i, matchlst), omatchlst) ne 0

       then next.

       put unformatted

    tst /* "if " or "or " */

    "input frame uform~{&seq~} ~{&file~}." entry(i, matchlst)

    " entered" skip.

       tst = "or ".

    end.

    put unformatted "then do:" skip.

       end.

       put unformatted space(4)

    "for each " mem " of ~{&file~}:" skip

    space(8) "assign" .

       do i = 1 to numfld:

    if lookup(entry(i, matchlst), omatchlst) ne 0

    then next.

    put unformatted skip

       space(12) mem "." entry(i, matchlst)

    " = input frame uform~{&seq~} ~{&file~}." entry(i, matchlst).

       end.

       put unformatted

    "." skip

    space(4) "end." skip.

       if last-of (idx)

       then put unformatted "end." skip.

    end.

  • ,

    If the intent is to provide a UI that gives the end user (automation engineer) full access to manipulate the values contained in your database, have you considered DataDigger? datadigger.wordpress.com/ It is a free Windows executable that will connect to your Progress database to let you view schema/data and also create/update/delete data directly. Normally I wouldn't recommend this for a UI, but since your users are the engineers that are working directly on the database, this might work well for you. You wouldn't actually have to recompile like it appears you would need to with MKALL.p. It just connects to the database and displays the schema/data based on the live schema definitions.

    Hope this helps,

    Tim

  • Tim

    thanks! Seems right on the spot (in good english ;-) )

    We will test it. Looks promising.