TRANSFER-Befehl (für Datasets): Linefeed am Ende der Datei verhindern?

Alles rund um die Sprache ABAP®: Funktionsbausteine, Listen, ALV
16 Beiträge • Seite 1 von 2 (current) Nächste
16 Beiträge Seite 1 von 2 (current) Nächste

TRANSFER-Befehl (für Datasets): Linefeed am Ende der Datei verhindern?

Beitrag von DeathAndPain (Top Expert / 1961 / 261 / 415 ) »
Hallo zusammen,

ich erzeuge eine simple Textausgabe auf den SAP-Server:

Code: Alles auswählen.

    OPEN DATASET DATEINAME FOR OUTPUT IN TEXT MODE ENCODING UTF-8 MESSAGE ERRORMESSAGE.
    IF SY-SUBRC <> 0.
      WRITE: / 'File output failed for ', P_FILE.
      RETURN.
    ENDIF.

    LOOP AT AUSGABETABELLE ASSIGNING FIELD-SYMBOL(<AUSGABETABELLE>).
      TRANSFER <AUSGABETABELLE> TO DATEINAME.
    ENDLOOP.

    CLOSE DATASET DATEINAME.
Wenn ich die erzeugte Datei im Notepad öffne und ans Ende springe, steht der Cursor am Anfang einer neuen, leeren Zeile. Offenbar wird also auch nach der letzten Zeile der Datei ein Linefeed gesendet. Diese Leerzeile führt allerdings dazu, dass das empfangende System die Datei nicht importieren kann.

Ich habe mir den Zusatz "WITH ... LINEFEED" des OPEN DATASET-Befehls angeschaut, aber ich kann da nichts erkennen, was mir weiterhelfen könnte. Gibt es eine Möglichkeit, obenstehenden Code so zu ändern, dass die Leerzeile nicht entsteht?

gesponsert
Stellenangebote auf ABAPforum.com schalten
kostenfrei für Ausbildungsberufe und Werksstudenten


Re: TRANSFER-Befehl (für Datasets): Linefeed am Ende der Datei verhindern?

Beitrag von a-dead-trousers (Top Expert / 4414 / 224 / 1186 ) »
Hast du den Zusatz NO END OF LINE beim letzten TRANSFER schon ausprobiert?

Folgende Benutzer bedankten sich beim Autor a-dead-trousers für den Beitrag:
DeathAndPain

Theory is when you know something, but it doesn't work.
Practice is when something works, but you don't know why.
Programmers combine theory and practice: Nothing works and they don't know why.

ECC: 6.18
Basis: 7.50

Re: TRANSFER-Befehl (für Datasets): Linefeed am Ende der Datei verhindern?

Beitrag von Shortcut IT (ForumUser / 52 / 2 / 18 ) »
Hallo,
man kann darüber streiten, ob ans Dateiende wirklich ein Linefeed hingehört, aber im Allgemeinen ist das gut und richtig so. Man kann darüber philosophieren, es gibt historische Gründe (aus dem Unix-Umfeld) aber auch praktische dafür (einfach mal 2 Dateien per copy o.ä. verketten, die kein Linefeed am Dateiende haben - Weiterverarbeitung schwierig, weil der letzte Datensatz aus Datei 1 und der erste Datensatz der Datei 2 in einer Zeile landen).
Wenn eine Applikation Probleme mit der Verarbeitung einer solchen Datei hat, ist das eher als ein Problem in der Applikation anzusehen und weniger in der Applikation, die die Datei erstellt hat.
Aber wenn du das vermeiden willst, kannst du - wie a-dead-trousers schon geschrieben hat - den Zusatz NO END OF LINE beim _letzten_ TRANSFER verwenden.
Viele Grüße
Shortcut IT

Folgende Benutzer bedankten sich beim Autor Shortcut IT für den Beitrag:
DeathAndPain


Re: TRANSFER-Befehl (für Datasets): Linefeed am Ende der Datei verhindern?

Beitrag von DeathAndPain (Top Expert / 1961 / 261 / 415 ) »
Vielen Dank euch beiden, der Befehl wird es sicherlich richten.

@ShortcutIT: Ich bin völlig Deiner Meinung und habe auch noch kein anderes System angetroffen, das ein Problem damit gehabt hätte. Aber jetzt stehe ich vor einem solchen, und wie das bei Cloudlösungen immer so ist, können die nix, und man muss alles auf SAP-Seite realisieren. Ich muss diesem System Daten übergeben, und wenn es mit Carriage Return am Dateiende auf die Bretter geht, dann bin ich derjenige, der das Problem lösen muss, weil sich die Flexibilität von Cloudlösungen halt auf ihr starres Korsett beschränkt, wohingegen wir SAP-ler prinzipiell alles realisieren können.

Es funktioniert nicht :-(

Beitrag von DeathAndPain (Top Expert / 1961 / 261 / 415 ) »
Leider musste ich feststellen, dass der Zusatz NO END OF LINE sein Wort nicht hält. Ich habe den Code jetzt so verändert:

Code: Alles auswählen.

    OPEN DATASET DATEINAME FOR OUTPUT IN TEXT MODE ENCODING UTF-8 MESSAGE ERRORMESSAGE.
    IF SY-SUBRC <> 0.
      WRITE: / 'File output failed for ', P_FILE.
      RETURN.
    ENDIF.

    LOOP AT AUSGABETABELLE ASSIGNING FIELD-SYMBOL(<AUSGABETABELLE>) TO LINES( AUSGABETABELLE ) - 1.
      TRANSFER <AUSGABETABELLE> TO DATEINAME.
    ENDLOOP.

    ASSIGN AUSGABETABELLE[ LINES( AUSGABETABELLE ) ] TO <AUSGABETABELLE>.
    TRANSFER <AUSGABETABELLE> TO DATEINAME NO END OF LINE.

    CLOSE DATASET DATEINAME.
Dann habe ich es ausgeführt und mir die erzeugte Datei mit einem Hex-Editor angeschaut. Die letzten beiden Zeichen in der Datei sind 0D 0A, das sind die ASCII-Codes für "Carriage Return" und "Line Feed". Es funktioniert also nicht.

Was kann ich jetzt noch versuchen? Spontan habe ich an BINARY MODE gedacht, aber ich wüsste nicht, wie ich damit ein UTF-8-Encoding hinbekommen sollte.

Re: TRANSFER-Befehl (für Datasets): Linefeed am Ende der Datei verhindern?

Beitrag von ewx (Top Expert / 4854 / 313 / 644 ) »
Und in AUSGABETABELLE steht auch nur EIN Eintrag?

Re: TRANSFER-Befehl (für Datasets): Linefeed am Ende der Datei verhindern?

Beitrag von DeathAndPain (Top Expert / 1961 / 261 / 415 ) »
Nein, in meiner Beispieldatei sind es zwei Zeilen. Er soll ja nur nach der letzten Zeile die Zeilenendmarkierung unterdrücken, weil das empfangende System sonst eine weitere Zeile (Leerzeile) am Ende der Datei sieht und damit auf die Bretter geht.

Re: TRANSFER-Befehl (für Datasets): Linefeed am Ende der Datei verhindern?

Beitrag von ewx (Top Expert / 4854 / 313 / 644 ) »
ich wollte nur sichergehen, dass nicht noch ein "Leereintrag" durch den LOOP erzeugt wird.

Re: TRANSFER-Befehl (für Datasets): Linefeed am Ende der Datei verhindern?

Beitrag von DeathAndPain (Top Expert / 1961 / 261 / 415 ) »
Der letzte TRANSFER in meinem Code mit dem NO END OF LINE ist ja noch nicht einmal innerhalb des LOOPs.

Re: TRANSFER-Befehl (für Datasets): Linefeed am Ende der Datei verhindern?

Beitrag von ewx (Top Expert / 4854 / 313 / 644 ) »
In der Doku steht:
Dann wird standardmäßig an den verbleibenden Inhalt des Datenobjekts bzw. an das Ergebnis der Konvertierung die beim Öffnen der Datei festgelegte Zeilenende-Markierung angefügt und das Resultat byteweise in die Datei geschrieben.
OPEN DATASET os_Additions
Vielleicht ist das noch ein Ansatz?

Das Anhängen der Zeilenende-Markierung kann mit dem Zusatz NO END OF LINE verhindert werden.
Wenn das alles nicht funktioniert, würde ich SAP den Fehler melden.

Re: TRANSFER-Befehl (für Datasets): Linefeed am Ende der Datei verhindern?

Beitrag von DeathAndPain (Top Expert / 1961 / 261 / 415 ) »
Wahrscheinlich funktioniert der NO END OF LINE doch, und ich bin auf etwas anderes hereingefallen. Ich habe nämlich jetzt versucht, mich mit folgendem Code zu retten:

Code: Alles auswählen.

    LOOP AT AUSGABETABELLE ASSIGNING FIELD-SYMBOL(<AUSGABETABELLE>) TO LINES( AUSGABETABELLE ) - 1.
      AUSGABE_ALS_XSTRING = AUSGABE_ALS_XSTRING && CL_ABAP_CODEPAGE=>CONVERT_TO( SOURCE = CONV STRING( <AUSGABETABELLE> ) && CL_ABAP_CHAR_UTILITIES=>CR_LF ).
    ENDLOOP.

    ASSIGN AUSGABETABELLE[ LINES( AUSGABETABELLE ) ] TO <AUSGABETABELLE>.
    AUSGABE_ALS_XSTRING = AUSGABE_ALS_XSTRING && CL_ABAP_CODEPAGE=>CONVERT_TO( SOURCE = CONV STRING( <AUSGABETABELLE> ) ).

    OPEN DATASET DATEINAME FOR OUTPUT IN BINARY MODE MESSAGE ERRORMESSAGE.

    TRANSFER AUSGABE_ALS_XSTRING TO DATEINAME.

    CLOSE DATASET DATEINAME.
Da konnte ich im Debugger ganz präzise nachvollziehen, dass der XSTRING den CRLF am Ende nicht enthalten hat und genau so aussah, wie er sollte. Aber wenn ich mir nachher mit der AL11 die Datei herunterlade, ist er doch wieder drin. Also gehe ich davon aus, dass die SAP nicht einen funktionsuntüchtigen Befehlszusatz in ABAP eingebaut hat, sondern ich von der Downloadfunktionalität der AL11 verladen werde. Die Variante mit dem NO END OF LINE ist natürlich viel einfacher und schöner, und daher werde ich die produktiv schieben lassen und schauen, ob das Zielsystem (das die echte Datei über SFTP erhält) damit noch ein Problem hat.

Re: TRANSFER-Befehl (für Datasets): Linefeed am Ende der Datei verhindern?

Beitrag von a-dead-trousers (Top Expert / 4414 / 224 / 1186 ) »
Ich hätte noch einen Vorschlag für den LOOP:

Code: Alles auswählen.

LOOP AT AUSGABETABELLE ASSIGNING FIELD-SYMBOL(<AUSGABETABELLE>).
  IF sy-tabix EQ sy-tfill.
    TRANSFER <AUSGABETABELLE> TO DATEINAME NO END OF LINE.
  ELSE.
    TRANSFER <AUSGABETABELLE> TO DATEINAME.
  ENDIF.
ENDLOOP.
Ist IMHO etwas kompakter.
Theory is when you know something, but it doesn't work.
Practice is when something works, but you don't know why.
Programmers combine theory and practice: Nothing works and they don't know why.

ECC: 6.18
Basis: 7.50

Re: TRANSFER-Befehl (für Datasets): Linefeed am Ende der Datei verhindern?

Beitrag von DeathAndPain (Top Expert / 1961 / 261 / 415 ) »
Über diesen Ansatz habe ich auch nachgedacht und das Für und Wider abgewogen. Er ist etwas kompakter, ja, wird dafür aber die etwas schlechtere Laufzeit haben, da bei jedem einzelnen Schleifendurchlauf eine zusätzliche Bedingung geprüft werden muss.

Am Ende macht es wohl keinen Unterschied: Der Laufzeitgewinn ist nur minimal, aber meine Lösung halte ich auch noch für ausreichend nachvollziehbar.

Re: TRANSFER-Befehl (für Datasets): Linefeed am Ende der Datei verhindern?

Beitrag von Shortcut IT (ForumUser / 52 / 2 / 18 ) »
Hallo,
also, nichts für ungut, mir persönlich gefällt der Sourcecode von a-dead-trousers um einiges besser. Die Laufzeitkosten für das IF-Statement schätze ich deutlich geringer als die String-Verarbeitung inkl. Methodenaufruf (CL_ABAP_CODEPAGE etc.). In dem Zusammenhang: da du von einer Cloud-Anwendung geschrieben hast, vermute ich, dass die eher auf einem Unix-System als auf einem Windows-System läuft. Windows ist mit dem 2-Byte-Zeilenumbruch (CR+LF) etwas exotisch, Unix-Systeme verwenden nur das LF. Von daher, bist du dir mit CL_ABAP_CHAR_UTILITIES=>CR_LF sicher oder wäre CL_ABAP_CHAR_UTILITIES=>LINEFEED ggf. doch der richtige Zeilenumbruch?
Viele Grüße
Shortcut IT

Re: TRANSFER-Befehl (für Datasets): Linefeed am Ende der Datei verhindern?

Beitrag von a-dead-trousers (Top Expert / 4414 / 224 / 1186 ) »
Naja, D&P hatte vorher auch den Code mit dem LINES( ) - 1 und READ TABLE ohne der Codepage-Konvertierung gepostet auf den ich mich eigentlich bezog.

Persönlich finde ich aber die Variante mit eigenem Zusammenbauen eines Strings mit den gewünschten Zeilentrennzeichen, anschließender Codepagekonvertierung in einen xstring und schließlich schreiben im BINARY MODE wesentlich flexibler.
Theory is when you know something, but it doesn't work.
Practice is when something works, but you don't know why.
Programmers combine theory and practice: Nothing works and they don't know why.

ECC: 6.18
Basis: 7.50

Vergleichbare Themen

9
Antw.
3978
Views
transfer-Befehl
von guest » 19.08.2005 16:56 • Verfasst in ABAP® Core
12
Antw.
5562
Views
FUBA für File Transfer von int.Tabelle in Text-Datei
von cuncon » 21.02.2018 12:13 • Verfasst in ABAP® für Anfänger
8
Antw.
8428
Views
Open Dataset & Transfer ergibt fehler: Datei nicht geöffnet
von Thanatos82 » 24.09.2012 09:59 • Verfasst in ABAP® für Anfänger
1
Antw.
2413
Views
Open Dataset, Transfer, Close Dataset.Transfer unvollständig
von mari » 25.09.2007 09:28 • Verfasst in ABAP® Core
1
Antw.
1399
Views
Minisap am Ende ??
von SkyHobbit » 21.07.2008 19:38 • Verfasst in ABAP® Core

Newsletter Anmeldung

Keine Beiträge verpassen! Wöchentlich versenden wir lesenwerte Beiträge aus unserer Community.
Die letzte Ausgabe findest du hier.
Details zum Versandverfahren und zu Ihren Widerrufsmöglichkeiten findest du in unserer Datenschutzerklärung.