Code: Alles auswählen.
report zsgruntxt line-size 999.
** Liste der Grunddatentexte generieren von allen Aufträgen
*****************************************************************
** Aenderungen: **
** DD.MM.JJ Wer: Was: **
** 27.01.05 Dani Umbricht Programmanfang
** 31.01.05 Im Material_select ErfasserName mit like abfragen
** Somit kann nach S% gesucht werden -> % statt * nehmen
** Daten in eine Exceltabelle exportieren in c:\copyslot
** Die Domäne DATS hat das Format Datumsfeld (JJJJMMDD),
** dies gilt für das Datumsfeld stxh-tdfdate.
** 01.02.05 Selektion nach Datum mit between
*****************************************************************
tables: stxh. "für Grunddatentexte Verweisdaten zum Cluster
selection-screen comment /1(70) text-001. "/Position(TextLänge)
selection-screen uline. "Linie über den gesamten Bildschirm
parameters: gitxtid like stxh-tdid default 'GRUN'. "TextID
parameters: gierfass(8) default 'S%'. "Erfasser
parameters: givondat(8) default '20040101'. " type D. "von Datum
parameters: gibisdat(8) default '20041231'. " type D. "bis Datum
data: begin of gt_allemat occurs 999999, " war 9999
tdname(70), "Verweisfeld in den Cluster
end of gt_allemat.
* Var. für VertriebsTexte Anfang, THead und TLine sind im Dictionary
data: begin of texttab occurs 2, "SapScripts TextZeilen
tdformat like tline-tdformat, "Formatspalte, 2Zch
tdline like tline-tdline. "TextZeile, 132 lang
data: end of texttab.
data: begin of textkopf occurs 2.
include structure thead. "SapScripts Text Header
data: end of textkopf.
* Exceltabelle definieren
types: tab_type(999) type c.
data: exceltab type table of tab_type.
** ------------
data: g_erstetextzeile(70). "erste Zeile des Beschriebes
data: g_zweitetextzeile(70)."zweite Zeile des Beschriebes
data: g_drittetextzeile(70)."dritte Zeile des Beschriebes
data: g_viertetextzeile(70)."vierte Zeile des Beschriebes
data: g_fuenftetextzeile(70).
data: g_sechstetextzeile(70).
data: g_siebtetextzeile(70).
data: g_achtetextzeile(70).
data: g_neuntetextzeile(70).
data: textobjekt(10) type c value 'VBBP'. "Grunddaten-Text
data: textid(4) type c value 'GRUN'. "Grunddaten-Text
* Variablen für Datenausgabe
data: textzeile(999). "Record der angezeigt + exportiert wird
* Variablen für Datenexport in eine TextDatei
data: filegroesse type i.
data: tab type x value '09'. " tabulatorzeichen
*****************************************************************
*** Hauptprogramm Anfang ****************************************
*****************************************************************
start-of-selection.
*******************
perform material_select. "Alle Materialien selektieren
perform vertriebstexte_select.
perform excel_kopfzeile.
perform excel_schreiben.
*******************
end-of-selection.
*****************************************************************
** Proceduren *************************************************
*****************************************************************
form material_select. "Alle Materialien selektieren
select distinct
a~tdname "Verweisfeld in den Cluster
into corresponding fields of table gt_allemat
from stxh as a "Textdatei Headertabelle
where a~tdid = gitxtid "welche TextID
and a~tdspras = 'DE' "Sprache
and a~tdfuser like gierfass "Ersteller des Eintrags
and a~tdfdate between givondat and gibisdat "Von datum - datum
and a~mandt = '010'. "Mandant
endform.
*****************************************************************
form vertriebstexte_select. "Vertriebstexte selektieren
loop at gt_allemat. "TempListe durchlaufen
perform stxh_zugriff.
if stxh-tdobject ne space or " Text fehlt: Skip Rest
stxh-tdname ne space or
stxh-tdid ne space or
stxh-tdspras ne space.
call function 'READ_TEXT'
exporting
object = textobjekt "z.B. MVKE
name = gt_allemat-tdname
id = textid "z.B. 0001
language = 'D' "textkopf-tdspras
importing
newheader = textkopf
tables
lines = texttab
exceptions
not_found = 1
others = 2.
if sy-subrc = 0. "kein Fehler aus der Function
loop at texttab.
case sy-tabix.
when 1. g_erstetextzeile = texttab-tdline.
when 2. g_zweitetextzeile = texttab-tdline.
when 3. g_drittetextzeile = texttab-tdline.
when 4. g_viertetextzeile = texttab-tdline.
when 5. g_fuenftetextzeile = texttab-tdline.
when 6. g_sechstetextzeile = texttab-tdline.
when 7. g_siebtetextzeile = texttab-tdline.
when 8. g_achtetextzeile = texttab-tdline.
when others. exit. " Ignore Rest
endcase.
endloop.
perform liste_schreiben. "gefundene Werte ausgeben
endif.
endif.
endloop.
endform.
*****************************************************************
form stxh_zugriff. "Vertriebstextkopf selektieren
clear stxh.
select single * from stxh
where tdobject = textobjekt "z.B. MVKE
and tdname = gt_allemat-tdname "Key
and tdid = textid "z.B. 0001
and tdspras = 'D'. "Sprache
endform.
*****************************************************************
form liste_schreiben. "Inhalt der Internen Tabelle schreiben
data: jahr(4).
data: monat(2).
data: tag(2).
data: hilfs_string type string.
data: posnr(5). "letze 5 Ziffern sind die PosNr
data: auftrnr(11). " Erste 11 Ziffern sind die AuftrNr
* PosNr herausschneiden, 5 Stellig Rechtsbündig
hilfs_string = stxh-tdname.
shift hilfs_string by 5 places right circular.
posnr = hilfs_string(5).
* Auftragsnummer aus dem Keyfeld rausnehmen
auftrnr = stxh-tdname(11). "Erste 11 Zeichen nehmen
* Datum vom Format YYYYMMTT richtig formatieren
jahr = stxh-tdfdate(4). "Erste 4 Ziffern sind das Jahr
hilfs_string = stxh-tdfdate.
shift hilfs_string by 2 places right circular.
tag = hilfs_string(2).
shift hilfs_string by 2 places right circular.
monat = hilfs_string(2).
* Leerzeichen entfernen in den Strings
condense g_erstetextzeile.
condense g_zweitetextzeile.
condense g_drittetextzeile.
condense g_viertetextzeile.
condense g_fuenftetextzeile.
condense g_sechstetextzeile.
condense g_siebtetextzeile.
condense g_achtetextzeile.
condense g_neuntetextzeile.
** alle Felder aneinanderhängen, ohne Leerzeichen dazwischen
concatenate stxh-tdid tab "TextID z.B. GRUN
stxh-tdname tab "Verweis in den Cluster
auftrnr tab "Auftr Nummer
posnr tab "PositionsNr
tag '.' monat '.' jahr tab "Datum des Auftrages
stxh-tdfuser tab "BenutzerID
g_erstetextzeile tab "Textzeile 1 der Grunddaten
g_zweitetextzeile tab "Textzeile 2 der Grunddaten
g_drittetextzeile tab
g_viertetextzeile tab
g_fuenftetextzeile tab
g_sechstetextzeile tab
g_siebtetextzeile tab
g_achtetextzeile tab
g_neuntetextzeile tab
into textzeile.
append textzeile to exceltab. " Einzelzeile an Exceltab anhängen
clear textzeile. "Zurücksetzen
g_erstetextzeile = ''. "Zurücksetzen
g_zweitetextzeile = ''.
g_drittetextzeile = ''.
g_viertetextzeile = ''.
g_fuenftetextzeile = ''.
g_sechstetextzeile = ''.
g_siebtetextzeile = ''.
g_achtetextzeile = ''.
g_neuntetextzeile = ''.
endform.
*****************************************************************
form excel_schreiben.
* Uebertrag der Tabelle in eine lokale Datei.
call function 'DOWNLOAD'
exporting
filename = 'c:\copyslot\Grunddatentexte.xls'
filetype = 'ASC' " AsciiDatei mit Tabtrenner
silent = 'S' "keine Frage für Dateiname
importing
filesize = filegroesse
tables
data_tab = exceltab "itab
exceptions
invalid_filesize = 1
invalid_table_width = 2
invalid_type = 3
no_batch = 4
unknown_error = 5
gui_refuse_filetransfer = 6
others = 7.
write: 'SY-SUBRC (Fehlercode) :', sy-subrc,
/ 'Dateigrösse :', filegroesse,
/ 'Dateiname : c:\copyslot\Grunddatentexte.xls'.
endform.
*****************************************************************
form excel_kopfzeile.
** alle Felder aneinanderhängen, ohne Leerzeichen dazwischen
concatenate '_TextID' tab "TextID z.B. GRUN
'key' tab "Verweis in den Cluster
'AuftrNr' tab "AuftrNummer
'PosNr' tab "PosNummer
'Datum' tab "Datum des Auftrages
'UserID' tab "BenutzerID
'Textzeile 1' tab "Textzeile 1 der Grunddaten
'Textzeile 2' tab "Textzeile 2 der Grunddaten
'Textzeile 3' tab
'Textzeile 4' tab
'Textzeile 5' tab
'Textzeile 6' tab
'Textzeile 7' tab
'Textzeile 8' tab
'Textzeile 9' tab
into textzeile.
append textzeile to exceltab. " Einzelzeile an Exceltab anhängen
endform.
*****************************************************************
Code: Alles auswählen.
filetype = 'DAT'
col_select = 'X'
col_selectmask = 'XXXXXXX'
Code: Alles auswählen.
clear textzeile. "Zurücksetzen
g_erstetextzeile = ''. "Zurücksetzen
g_zweitetextzeile = ''.
g_drittetextzeile = ''.
g_viertetextzeile = ''.
g_fuenftetextzeile = ''.
g_sechstetextzeile = ''.
g_siebtetextzeile = ''.
g_achtetextzeile = ''.
g_neuntetextzeile = ''.
Code: Alles auswählen.
clear:
textzeile, "Zurücksetzen
g_erstetextzeile, "Zurücksetzen
g_zweitetextzeile,
g_drittetextzeile,
g_viertetextzeile,
g_fuenftetextzeile,
g_sechstetextzeile,
g_siebtetextzeile,
g_achtetextzeile,
g_neuntetextzeile.
Code: Alles auswählen.
data: textobjekt(10) type c value 'VBBP'. "Grunddaten-Text
data: textid(4) type c value 'GRUN'. "Grunddaten-Text
* besser (meiner Meinung nach ;)
data:
textobjekt type TDOBJECT value 'VBBP', "Grunddaten-Text
textid type TDID value 'GRUN'. "Grunddaten-Text
Code: Alles auswählen.
TABLES:
stxh.
PARAMETERS:
gitxtid LIKE stxh-tdid DEFAULT 'GRUN'. "TextID
SELECT-OPTIONS:
gierfass FOR stxh-tdfuser DEFAULT 'S*'
OPTION cp
NO INTERVALS "kein Interval
NO-EXTENSION, "einzeilig
givondat FOR stxh-tdfdate DEFAULT '20040101'
TO '20041231'. "bis Datum
SELECT DISTINCT
a~tdname "Verweisfeld in den Cluster
INTO CORRESPONDING FIELDS OF TABLE gt_allemat
FROM stxh AS a "Textdatei Headertabelle
WHERE a~tdid = gitxtid "welche TextID
AND a~tdspras = 'DE' "Sprache
AND a~tdfuser IN gierfass "Ersteller des Eintrags
AND a~tdfdate IN gibisdat. "Von datum - datum
Code: Alles auswählen.
TYPES:
tt_spalten TYPE string_table, "oder TABLE OF string
* Zusatz STANDARD nicht notwendig
tt_zeilen TYPE STANDARD TABLE OF tt_spalten.
CONSTANTS:
con_tab TYPE x LENGTH 1 VALUE '09'. "Tabulator
DATA:
gt_zeilen TYPE tt_zeilen,
gt_spalten LIKE LINE OF gt_zeilen, "gt => globale Tabelle
gs_spalte LIKE LINE OF gt_spalten,
gt_outtab TYPE string_table,
gs_outtab LIKE LINE OF gt_outtab,
gf_tab TYPE char1.
* kleiner Trick, um Tab-Zeichen im CONCATENATE zu benutzen
gf_tab = con_tab.
* Befüllen
gs_spalte = `<textid>`.
INSERT gs_spalte
INTO TABLE gt_spalten.
* wirkt als APPEND bei STANDARD TABLE
* hier die restlichen Spalten einfügen
INSERT gt_spalten
INTO TABLE gt_zeilen.
* Aufbau der EXCEL-CSV-Struktur
CLEAR:
gs_outtab.
LOOP AT gt_zeilen INTO gt_spalten.
LOOP AT gt_spalten INTO gs_spalte.
IF gs_outtab IS INITIAL.
gs_outtab = gs_spalte.
ELSE.
CONCATENATE
gs_outtab
gs_spalte
INTO gs_outtab
SEPARATED BY gf_tab.
ENDIF.
ENDLOOP.
INSERT gs_outtab INTO TABLE gt_outtab.
CLEAR:
gs_outtab.
ENDLOOP.
* hier kommt jetzt die weitere Verarbeitung sprich der Download
Hallo ereglamereglam hat geschrieben:Hallo Dani,
ich finde es klasse, dass Du das Ergebnis hier gepostet hast. Leider ist nicht jeder bereit sein Wissen zu teilen.
Dennoch möchte ich eine paar Anmerkungen zu Deinem Programm machen, die als Hilfestellung dienen sollen, wie man es besser machen kann.
Bitte nicht böse sein.
Was ist daran einfach?Anonymous hat geschrieben:einfach:
genommen.Code: Alles auswählen.
clear: textzeile, "Zurücksetzen g_erstetextzeile, "Zurücksetzen g_zweitetextzeile, g_drittetextzeile, g_viertetextzeile, g_fuenftetextzeile, g_sechstetextzeile, g_siebtetextzeile, g_achtetextzeile, g_neuntetextzeile.
Ja.ereglam hat geschrieben:ich finde es klasse, dass Du das Ergebnis hier gepostet hast. Leider ist nicht jeder bereit sein Wissen zu teilen.
Ob man sich auf das Datenelement oder Tabellenname-Feldname bezieht, ist sicher Geschmackssache.Ich bevorzuge z.B. Bezug auf das passende Feld aus einer Tabelle, aus der das Programm auch liest ...
- mir fehlen leider saubere Typisierungen
Eine der Stärken von SAP ist die Verwendung von bestehenden TypisierungenCode: Alles auswählen.
data: textobjekt(10) type c value 'VBBP'. "Grunddaten-Text data: textid(4) type c value 'GRUN'. "Grunddaten-Text * besser (meiner Meinung nach ;) data: textobjekt type TDOBJECT value 'VBBP', "Grunddaten-Text textid type TDID value 'GRUN'. "Grunddaten-Text
Warum (abgesehen davon, dass die Pattern-Eingabe in einer dem Benutzer geläufigeren Form erfolgen kann)?[*]Benutze für maskierte Selektionen trotzdem SELECT-OPTIONSCode: Alles auswählen.
TABLES: stxh. PARAMETERS: gitxtid LIKE stxh-tdid DEFAULT 'GRUN'. "TextID SELECT-OPTIONS: gierfass FOR stxh-tdfuser DEFAULT 'S*' OPTION cp NO INTERVALS "kein Interval NO-EXTENSION, "einzeilig
Die Parameter für Von-Und Bis-Datum korrekt zu typisieren (statt C mit Länge 8) finde ich auch besser, ebenso die Umwandlung in eine SELECT-OPTION.Code: Alles auswählen.
givondat FOR stxh-tdfdate DEFAULT '20040101' TO '20041231'. "bis Datum SELECT DISTINCT a~tdname "Verweisfeld in den Cluster INTO CORRESPONDING FIELDS OF TABLE gt_allemat FROM stxh AS a "Textdatei Headertabelle WHERE a~tdid = gitxtid "welche TextID AND a~tdspras = 'DE' "Sprache AND a~tdfuser IN gierfass "Ersteller des Eintrags AND a~tdfdate IN gibisdat. "Von datum - datum
Code: Alles auswählen.
tdspras EQ sy-langu
Code: Alles auswählen.
tdspras EQ p_langu
Code: Alles auswählen.
tdspras EQ 'D'
Das stimmt so nicht wirklich.[*]Eine Selektion nach Mandant ist nicht notwendig. Dies wird von SAP implizit gemacht und ist auch performanter
Schreibst Du da wirklich "LENGTH 1" hin?Code: Alles auswählen.
CONSTANTS: con_tab TYPE x LENGTH 1 VALUE '09'. "Tabulator
Code: Alles auswählen.
CONSTANTS:
con_tab(1) TYPE x VALUE '09'.
Der Trick funktioniert bei mir nur mitCode: Alles auswählen.
* kleiner Trick, um Tab-Zeichen im CONCATENATE zu benutzen gf_tab = con_tab.
Dürfte aber von vielen als schwerer lesbar empfunden werdenCode: Alles auswählen.
INSERT gs_spalte INTO TABLE gt_spalten. * wirkt als APPEND bei STANDARD TABLE
hab ich glatt übersehen...Frank Dittrich hat geschrieben:...
Ja.
Hoffentlich wirkt es nicht allzu abschreckend, wenn wir jetzt das veröffentlichte Programm zerpflücken.Ob man sich auf das Datenelement oder Tabellenname-Feldname bezieht, ist sicher Geschmackssache.Ich bevorzuge z.B. Bezug auf das passende Feld aus einer Tabelle, aus der das Programm auch liest ...
- mir fehlen leider saubere Typisierungen
...Code: Alles auswählen.
data: textobjekt(10) type c value 'VBBP'. "Grunddaten-Text data: textid(4) type c value 'GRUN'. "Grunddaten-Text * besser (meiner Meinung nach ;) data: textobjekt type TDOBJECT value 'VBBP', "Grunddaten-Text textid type TDID value 'GRUN'. "Grunddaten-Text
Auf jeden Fall hätte ich hier (und an anderen Stellen) für Konstanten CONSTANTS statt DATA genommen.
eben wegen der geläufigeren Verwendung der Wildcards... (sehe ich als einen Beitrag zur Bedienerfreundlichkeit)Frank Dittrich hat geschrieben:Warum (abgesehen davon, dass die Pattern-Eingabe in einer dem Benutzer geläufigeren Form erfolgen kann)?[*]Benutze für maskierte Selektionen trotzdem SELECT-OPTIONSCode: Alles auswählen.
TABLES: stxh. PARAMETERS: gitxtid LIKE stxh-tdid DEFAULT 'GRUN'. "TextID SELECT-OPTIONS: gierfass FOR stxh-tdfuser DEFAULT 'S*' OPTION cp NO INTERVALS "kein Interval NO-EXTENSION, "einzeilig
Und was ist ein "Gierfass"?
ist auch ein Thema, was ich jetzt aber noch nicht ansprechen wollte. (ich weiß, ist auch ein wichtiges Thema )Frank Dittrich hat geschrieben: (Die Namenskonventionen für Globale Felder ... wurden übrigens nicht konsequent durchgehalten.)
dem kann ich auch nur zustimmenFrank Dittrich hat geschrieben: ...
-auf keinen Fall tdspras = 'DE' verwendet
(ich finde es ärgerlich, dass SAP solche Schlampereien zulässt).
Es gibt keinen Eintrag mit tdspras = 'DE'.
(Das Feld ist vom Typ C, Länge 1).
Also entwederoderCode: Alles auswählen.
tdspras EQ sy-langu
(mit PARAMETERS p_langu TYPE sy-langu OBLIGATORY DEFAULT sy-langu.)Code: Alles auswählen.
tdspras EQ p_langu
oder notfalls auch nochCode: Alles auswählen.
tdspras EQ 'D'
ja, Du hast in sofern recht, als meine Bemerkung sich auf den Zusatz CLIENT SPECIFIED bezieht, der aber hier nicht verwendet wurdeFrank Dittrich hat geschrieben:Das stimmt so nicht wirklich.[*]Eine Selektion nach Mandant ist nicht notwendig. Dies wird von SAP implizit gemacht und ist auch performanter
umgekehrt mag ich die Klammerdeklaration nicht und die Angabe LENGTH wird u.a. wohl auch von SAP empfohlenFrank Dittrich hat geschrieben:Schreibst Du da wirklich "LENGTH 1" hin?Code: Alles auswählen.
CONSTANTS: con_tab TYPE x LENGTH 1 VALUE '09'. "Tabulator
Würde ich nie machen.
Und wenn ich die Default-Länge explizit angeben würde, dann eher so:Code: Alles auswählen.
CONSTANTS: con_tab(1) TYPE x VALUE '09'.
Code: Alles auswählen.
DATA dummy(1).
hatte ich zwar auch schon dran gedacht, wollte aber OO aus dem Spiel lassenFrank Dittrich hat geschrieben:Der Trick funktioniert bei mir nur mitCode: Alles auswählen.
* kleiner Trick, um Tab-Zeichen im CONCATENATE zu benutzen gf_tab = con_tab.
CLEAR gf_tab WITH con_tab.
Wenn verfügbar, sollte man aber lieber auf CL_ABAP_CHAR_UTILITIES=>HORIOZONTAL_TAB zugreifen.
wird aber so von SAP empfohlen, weil es für alle Tabellentypen (STANDARD, SORTED und HASHED) gültig ist.Frank Dittrich hat geschrieben:Dürfte aber von vielen als schwerer lesbar empfunden werdenCode: Alles auswählen.
INSERT gs_spalte INTO TABLE gt_spalten. * wirkt als APPEND bei STANDARD TABLE
(bei APPEND muss man nicht erst nachdenken)
@DaniUFrank Dittrich hat geschrieben:
Und die restlichen Anmerkungen muss ich erst mal vertagen.
Code: Alles auswählen.
call function 'READ_TEXT'
exporting
object = textobjekt "z.B. MVKE
name = gt_allemat-tdname
id = textid "z.B. 0001
language = 'D' "textkopf-tdspras
importing
newheader = textkopf
tables
lines = texttab
exceptions
not_found = 1
others = 2.