Anmelden

View Full Version : Fortlaufende Felder bestücken - Ist das abkürzbar?



dholtmann
08-06-17, 09:32
Hallo *all,

ich habe Folgendes:


c if digits = 1 c eval AFeld1 = %subst($$_Var:1:byteleng)
c eval pointer = %addr(AFeld1)
c elseif digits = 2
c eval AFeld2 = %subst($$_Var:1:byteleng)
c eval pointer = %addr(AFeld2)

c elseif digits = 3
c eval AFeld3 = %subst($$_Var:1:byteleng)
c eval pointer = %addr(AFeld3
....

c elseif digits = N
c eval AFeldN = %subst($$_Var:1:byteleng)
c eval pointer = %addr(AFeldN)

c endif

Dabei ist mein Problem, dass AFeld1-N auch immer in seiner Länge um 1 wächst.
Gibt es eine Möglichkeit dies trotzdem als Schleife zu fassen?
Während des Tippens kam mir folgende Idee:

D Index s 2S 0 inz(1)
D AFeld S 63A dim(63) varying
/free
for Index = 1 by 1 to 63;
%len(AFeld(Index)) = Index;
AFeld(Index) = %subst($$_Var:1:byteleng);
pointer = %addr(AFeld(Index));
endfor;

Würde das gefahrlos funktionieren?

Fuerchau
08-06-17, 09:46
63A dim(63) heißt, dass du 63 Felder á 63 Bytes hast.

1A dim(63) sind dann 63 x 1 Byte. Allerdings kannst du mit %subst auch auf der linken Seite arbeiten, also %subst(...) = 'BlaBla'.

Was ist das Ziel des Ganzen?

dholtmann
08-06-17, 09:54
ich benötige von Länge 1-63 je ein Feld.
Je nach Durchlauf muss ich dann eins davon füllen.
ich möchte mir halt sparen 63 mal zu sagen: wenn X = 1...N dann füll Feld1...N.
Bei gleicher Feldgröße wären Dimensionen definitiv eine Lösung.

Besonders frage ich mich ob:


%len(AFeld(Index)) = 40;
pointer = %addr(AFeld(Index));


das den gleichen Pointer liefert wie:


pointer = %addr(AFeld40);
(AFeld40 definiert als Alpha mit 40 Zeichen)

Fuerchau
08-06-17, 12:22
Was willst du dann mit dem Pointer?
Dieser verweist nur auf den Speicher.
Was sich dahinter verbirgt, definierst du wiederum mit deiner based-DS und diese Definition entscheidet über den Inhalt ab dem Pointer bzw. ggf. einen MCH-Fehler.

Daher noch mal die Frage: was ist das Ziel des Ganzen?

Für Funktionen und Prozeduren übergibt man Werte und Zeichen. Die Maximalausprägung wird per Deklaration festgelegt und bei CONST/VALUE erfolgt auch eine Typanpassung.
Was also willst du mit solchen Konstrukten (außer Fingerübungen) tatsächlich erreichen?

dholtmann
09-06-17, 10:19
Mein letztendliches Ziel ist es, eine packed Zahl auszulesen.


D $$_Var S 100A Based(Pointereins)
D Feld5 S 5P 0 Based(pointer)
D AFeld5 S 3A



c eval AFeld5 = %subst($$_Var:1:byteleng)
c eval pointer = %addr(AFeld5)

So bekomme ich den Wert in mein Feld5. Das funktioniert auch super.
Aber ich würde mir gerne sparen, für jede Größe ein einzelnes Feld zu definieren.

BenderD
09-06-17, 10:53
... wenn man denn meint das so machen zu wollen, dann würde ich das in eine Subprocedure huddle2packed auslagern, die kriegt einen Parameter huddle 32 alfa varying und gibt result als 63 packed zurück. In der procedure braucht man nur den huddle per memcopy an die richtige Stelle zu kopieren (%length beachten!) und mit return zurückgeben.

D*B

Pikachu
09-06-17, 11:50
Mal was als Diskussionsgrundlage ...


D DS
DAFELD 32A
DFELD 63P 0 OVERLAY(AFELD)
DVAR S 100A INZ(X'123456789D1234')
DSTART S 3P 0 INZ(3)
DDIGITS S 3P 0 INZ(5)
DLEN S 3P 0 INZ
DMSG S 52A INZ
D
C DIGITS ADD 1 LEN
C DIV(H) 2 LEN
C MOVEL *ALLX'00' AFELD
C EVAL %SUBST(AFELD:%SIZE(AFELD)-LEN+1:LEN) =
C %SUBST(VAR:START:LEN)
C EVAL MSG = %CHAR(FELD)
C MSG DSPLY '*REQUESTER'
C SETON LR