Vielen Dank für die rege Beteiligung!

Hier die Antworten auf die Anmerkungen/Fragen:

Wehre mich gegen das Execute Immediate, weil ich nicht glaube, dass sich meine Anwendung hiermit realisieren lässt. Gehe nach wie vor davon aus, dass ich um das Prepare (ob in Subprozedur oder direkt) nicht umhin komme.
Aber urteilt selbst:


// Select-Statement aufbereiten
SelectStmt = 'insert into libneu.dateineu -

Select ' + '''' + MandAlpha + '''' + ', ' + %char(Jahr) + ', -

' + %char(
MonVon) + ', ' + %char(MonBis) + ', vstnr, -

vsgeba, vsgebi, vsmark, vsprhg, vsprgr, -

vskdgr, vsvtr, vskdnr, vsvbnr,-

sum(' + %trim(AbsMonate) + '), sum(' + %trim(UmsMonate) + '), -

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '' '', '' '', '' '', 0, 0, 0, 0 -

from Statistik inner join Kundenstamm on vskdnr = kdnr -

where vsbla = ''A'' and kdanzp <> 4 -

and vsmrze not in(''54'', ''98'') and vsmatg = ''0001'' -

group by ' + '''' +
MandAlpha + '''' + ', ' + %char(Jahr) + ', -

' + %char(MonVon) + ', ' + %char(MonBis) + ', vstnr, -

vsgeba, vsgebi, vsmark, vsprhg, vsprgr, -

vskdgr, vsvtr, vskdnr, vsvbnr -

having sum(' + %trim(
AbsMonate) + ') <> 0 or -

sum(' + %trim(
UmsMonate) + ') <> 0';


ExecSQL
Prepare BuchenAbsAT from :SelectStmt;


// Ausführen vorbereitetes SQL-Statement
ExecSQL
Execute BuchenAbsAT;


Die orange markierten Felder sind Eingaben von Benutzern.
Die rot markierten Felder sind Inhalte, die sich auf Basis der gewählten Zeiträume aus den entsprechenden Datenbankfelder zusammensetzen.

Hier ein bisschen mehr Code zum besseren Verständnis:
// Initialisieren Array Feldnamen AbsatzMonate
aryAbsMon(1) = 'vimja2';
aryAbsMon(2) = 'vimfe2';
aryAbsMon(3) = 'vimmz2';
aryAbsMon(4) = 'vimap2';
aryAbsMon(5) = 'vimma2';
aryAbsMon(6) = 'vimjn2';
aryAbsMon(7) = 'vimjl2';
aryAbsMon(8) = 'vimau2';
aryAbsMon(9) = 'vimse2';
aryAbsMon(10) = 'vimok2';
aryAbsMon(11) = 'vimno2';
aryAbsMon(12) = 'vimde2';
aryAbsMon(13) = 'vimja1';
aryAbsMon(14) = 'vimfe1';
aryAbsMon(15) = 'vimmz1';
aryAbsMon(16) = 'vimap1';
aryAbsMon(17) = 'vimma1';
aryAbsMon(18) = 'vimjn1';
aryAbsMon(19) = 'vimjl1';
aryAbsMon(20) = 'vimau1';
aryAbsMon(21) = 'vimse1';
aryAbsMon(22) = 'vimok1';
aryAbsMon(23) = 'vimno1';
aryAbsMon(24) = 'vimde1';
aryAbsMon(25) = 'vimja0';
aryAbsMon(26) = 'vimfe0';
aryAbsMon(27) = 'vimmz0';
aryAbsMon(28) = 'vimap0';
aryAbsMon(29) = 'vimma0';
aryAbsMon(30) = 'vimjn0';
aryAbsMon(31) = 'vimjl0';
aryAbsMon(32) = 'vimau0';
aryAbsMon(33) = 'vimse0';
aryAbsMon(34) = 'vimok0';
aryAbsMon(35) = 'vimno0';
aryAbsMon(36) = 'vimde0';
// Initialisieren Array Feldnamen UmsatzMonate
aryUmsMon(1) = 'viwja2';
aryUmsMon(2) = 'viwfe2';
aryUmsMon(3) = 'viwmz2';
aryUmsMon(4) = 'viwap2';
aryUmsMon(5) = 'viwma2';
aryUmsMon(6) = 'viwjn2';
aryUmsMon(7) = 'viwjl2';
aryUmsMon(8) = 'viwau2';
aryUmsMon(9) = 'viwse2';
aryUmsMon(10) = 'viwok2';
aryUmsMon(11) = 'viwno2';
aryUmsMon(12) = 'viwde2';
aryUmsMon(13) = 'viwja1';
aryUmsMon(14) = 'viwfe1';
aryUmsMon(15) = 'viwmz1';
aryUmsMon(16) = 'viwap1';
aryUmsMon(17) = 'viwma1';
aryUmsMon(18) = 'viwjn1';
aryUmsMon(19) = 'viwjl1';
aryUmsMon(20) = 'viwau1';
aryUmsMon(21) = 'viwse1';
aryUmsMon(22) = 'viwok1';
aryUmsMon(23) = 'viwno1';
aryUmsMon(24) = 'viwde1';
aryUmsMon(25) = 'viwja0';
aryUmsMon(26) = 'viwfe0';
aryUmsMon(27) = 'viwmz0';
aryUmsMon(28) = 'viwap0';
aryUmsMon(29) = 'viwma0';
aryUmsMon(30) = 'viwjn0';
aryUmsMon(31) = 'viwjl0';
aryUmsMon(32) = 'viwau0';
aryUmsMon(33) = 'viwse0';
aryUmsMon(34) = 'viwok0';
aryUmsMon(35) = 'viwno0';
aryUmsMon(36) = 'viwde0';

// Füllen Variable für Absatz
Zaehler = IndexVon;
AbsMonate = *blanks;
dow Zaehler <= IndexBis;
AbsMonate = %trim(AbsMonate) + ' + ' + aryAbsMon(Zaehler);
Zaehler = Zaehler + 1;
enddo;

// Füllen Variable für Umsatz
Zaehler = IndexVon;
UmsMonate = *blanks;
dow Zaehler <= IndexBis; UmsMonate = %trim(UmsMonate) + ' + ' + aryUmsMon(Zaehler);
Zaehler = Zaehler + 1;
enddo;

Der Inhalt der Variable
UmsMonate stellt sich bei Auswahl des Jahres 2016 und der Monate von 9 bis 12 bspw. folgendermaßen dar:
EVAL UmsMonate
UMSMONATE =
....5...10...15...20...25...30...35...40...45...50 ...55...60
1 '+ viwse0 + viwok0 + viwno0 + viwde0 '
61 ' '
121 ' '
181 ' '

Da es (leider) noch keine Umsätze von 9-12 in 2016 gibt (SQLCODE 100 nach Execute BuchenAbsAT) und der Anwender nun seinen Fehler bemerkt, ändert er anschließend das Jahr von 2016 auf 2015 und bestätigt erneut seine Eingabe.
Nun stellt sich der Wert der Variable
UmsMonate zum Zeitpunkt des Prepare BuchenAbsAT from :SelectStmt; wie folgt dar:
UMSMONATE =
....5...10...15...20...25...30...35...40...45...50 ...55...60
1 '+ viwse1 + viwok1 + viwno1 + viwde1 '
61 ' '
121 ' '
181 ' '

Auch das SelectStmt zum Zeitpunkt des 2. Prepares ist richtig gefüllt:

SELECTSTMT =
....5...10...15...20...25...30...35...40...45...50 ...55...60
1 'insert into libneu.dateineu Select '007', 2015, 9, 12'
61 ', vstnr, vsgeba, vsgebi, vsmark, vsprhg, vsprgr, vskdg'
121 'r, vsvtr, vskdnr, vsvbnr, sum(+ vimse1 + vimok1 + vimno1 +'
181 ' vimde1), sum(+ viwse1 + viwok1 + viwno1 + viwde1), 0, 0,'
241 ' 0, 0, 0, 0, 0, 0, 0, 0, ' ', ' ', ' ', 0, 0, 0, 0 from Statistik'
301 ' inner join Kundenstamm on vskdnr = kdnr where vsbla '
361 '= 'A' and kdanzp <> 4 and vsmrze not in('54', '98') and v'
421 'smatg = '0001' group by '007', 2015, 9, 12, vstnr, '
481 'vsgeba, vsgebi, vsmark, vsprhg, vsprgr, vskdgr, vsvtr, vs'
541 'kdnr, vsvbnr having sum(+ vimse1 + vimok1 + vimno1 + vimd'
601 'e1) <> 0 or sum(+ viwse1 + viwok1 + viwno1 + viwde1) <> 0'

Der SQL-Code nach dem 2. Prepare ist 0, also i. O.

Nach dem erneuten Execute BuchenAbsAT ist der SQL-Code jedoch wieder 100, weil er keine Sätze finden konnte.
Kopiere ich jedoch den Inhalt der Variablen SelectStmt in den SQL-Editor, so bekomme ich folgerichtig die Absätze für die Monate 9-12 in 2015 angezeigt....

Release V7R1M0
PTF-Stand: TL13037

Um die Geschwindigkeit geht es mir im 1. Step noch gar nicht. Mir wäre eher daran gelegen, dass es überhaupt funktioniert :-/