MainframeSupports
tip uge 28/2016:

En af mine læsere gjorde mig fornylig opmærksom på, at min SCRNSHOT REXX ikke virker, hvis man benytter en 3270 skærm med 132 tegns bredde. Variablen ZSCREENW bliver godt nok sat til 132, men indholdet af ZSCREENI er på mange skærmbilleder stadig opbygget i 80 tegns bredde. Hold da op for en overraskelse. Hvad tænker de dog på hos IBM??

Denne udfordring kunne jeg selvfølgelig ikke lade ligge, så her kommer en forbedret udgave af SCRNSHOT, som kan detektere om indholdet af ZSCREENI er formateret til en skærmbredde på 80 tegn eller 132 tegn:

/* REXX */
ARG LINECNT COLCNT REUSE
ADDRESS ISPEXEC "VGET (ZSCREENI ZSCREENW ZSCREEND ZSCREENC)"
ADDRESS TSO "ALLOC FI(SCRNSHOT) DA(SCRNSHOT) MOD CATALOG",
            " SPACE(1 1) TRACKS RECFM(F B) LRECL("ZSCREENW") REUSE"
DROP SCRNSHOT.
IF DATATYPE(LINECNT, 'W') = 0
THEN
  LINECNT = 1
IF DATATYPE(COLCNT, 'W') = 0
THEN
  COLCNT = 8
STARTPOS = ZSCREENC + 1
IF REUSE = ''
THEN DO
  SCRNSHOT = STARTPOS
  ADDRESS ISPEXEC "VPUT SCRNSHOT"
END
ELSE DO
  ADDRESS ISPEXEC "VGET SCRNSHOT"
  STARTPOS = SCRNSHOT
END
/* START EXTRA CODE TO DETECT SCREEN WIDTH */
WIDTH = 0
RULER = SUBSTR(ZSCREENI, 81, 54)' '
W = POS(' ', RULER) + 79
POSNO = 1
DO WHILE W < ZSCREENW
  WIDTH = W
  DO LINENO = 3 TO ZSCREEND
    IF SUBSTR(ZSCREENI, W * LINENO + 1, 1) <> ' '
    THEN DO
      WIDTH = 0
      LEAVE
    END
  END
  IF WIDTH > 0
  THEN
    W = ZSCREENW
  ELSE DO
    POSNO = POSNO + 1
    W = POS(' ', RULER, POSNO) + 79
  END
END
IF WIDTH = 0
THEN
  WIDTH = ZSCREENW
ELSE
  IF POS(COPIES('-', WIDTH - 1), ZSCREENI) > WIDTH + 2
  THEN
    WIDTH = ZSCREENW
COLCNT = MIN(WIDTH, COLCNT)
/* END EXTRA CODE TO DETECT SCREEN WIDTH */
DO LINENO = 1 TO LINECNT
  SCRNSHOT.LINENO = SUBSTR(ZSCREENI, STARTPOS, COLCNT)
  STARTPOS = STARTPOS + WIDTH
END
SCRNSHOT.0 = LINECNT
ADDRESS TSO "EXECIO * DISKW SCRNSHOT (STEM SCRNSHOT. OPEN FINIS)"
ADDRESS TSO "FREE FI(SCRNSHOT)"
ADDRESS ISPEXEC "EDIT DATASET(SCRNSHOT)"
EXIT

Jeg har simpelthen tilføjet en pænt stor stump kode til at detektere skærmbredden. Logikken er, at det første tegn i hver linie skal indeholde en blank. Det er normalt et felt-attribut tegn, der står her, som gemmes som en blank i skærmbufferen. Der er også en ekstra kontrol på, om den vandrette streg i linie 2 er til stede i den rigtige længde. Alle disse kontroller giver en rigtig god sikkerhed for, at variablen WIDTH (som benyttes i stedet for ZSCREENW i det afsluttende loop) har den rigtige værdi i forhold til indholdet af ZSCREENI. Jeg har i øvrigt forgæves ledt efter en Z-variabel, der indeholdt den aktuelle skærmbredde i ZSCREENI, men forgæves, så derfor ovenstående algoritme.

Der er ingen sikkerhed for, at ovenstående forbedringer virker under alle forhold. Der kan sagtens være paneler, hvor den første position i hver linie indeholder noget andet en blanke. Der findes masser af produkter, der selv styrer opbygningen af sine ISPF-paneler og her kan det nemt gå galt i forhold til den logik, jeg har tilføjet. Hvis du har et endnu bedre forslag til at løse denne udfordring, så er du velkommen til at give dit besyv med!

Forrige danske tip        Last tip in english        Tip oversigten