ANSI-Datei mit verschiedenen Satzlängen

Alle Fragen um die Programmierung, die sich sonst nicht kategorisieren lassen. Von Makro bis Codeblock, von IF bis ENDIF

Moderator: Moderatoren

Antworten
Robert_Steph
Rookie
Rookie
Beiträge: 5
Registriert: Fr, 28. Nov 2014 14:27

ANSI-Datei mit verschiedenen Satzlängen

Beitrag von Robert_Steph »

Hallo,
dies ist mein erster Beitrag, ich stelle mich kurz vor:
Ich werde im Februar 62 Jahre alt, komme aus der dBase-Ecke und bin kein Profi-Codierer. :oops: Ich habe unter dBase für Dos Einzelplatz-Anwendungen (Leihgeräte-Verwaltung, Arbeitszeitverwaltung) erstellt. Umstieg auf xbase mit GUI ist für mich also kein Thema mehr.
Mein Problem:
Ich muß eine ANSI-Datei (Schnittstelle) erzeugen, die 7 verschiedene Satzarten beinhaltet. Jede Satzart hat eine andere Satzlänge, genau das ist mein Problem. Die Daten mit xbase zu selektieren und mit der sdfdbe in eine Textdatei zu schreiben, funtionierte wunderbar. Aber die Satzlänge resultierte immer in der längsten vorkommenden Satzlänge.

Auch Versuche mit fread() und fwrite() führten zu keinem anderen Ergebnis. Nun ist dieses Forum meine Hoffnung, ich kann mir einfach nicht vorstellen, dass es dafür keine Lösung gibt.

Die xbase++ Version ist 1.9

Ich würde mich über Hilfe von euch freuen.

Grüße
Robert
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16508
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Re: ANSI-Datei mit verschiedenen Satzlängen

Beitrag von Martin Altmann »

Moin Robert,
willkommen!
Hast Du es ganz einfach mit ? versucht?

Code: Alles auswählen

set alternate to ( textkata + "\unsortierte_Hunde.rtf" )
set alternate on
set console off
goto top
do while .not. eof()
	? ConvToAnsiCP( alltrim( hvar[ nI ] ) + iif( hnatras[ nI ], " (nat. Rasse)", "" ) ) + CRLF
	skip
enddo
set console on
set alternate off
set alternate to
Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2824
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 95 Mal
Danksagung erhalten: 13 Mal

Re: ANSI-Datei mit verschiedenen Satzlängen

Beitrag von georg »

Hallo, Robert -


also, die Satzlänge ist doch egal ...

Vermutlich hat jeder Satz vorne eine Angabe über die Satzlänge, dann setzt Du diesen Wert auf die grösste Länge.

Alternativ: bei fWrite(nHandle, cString, nLen) kannst Du über den Parameter nLen steuern, wieviele Bytes geschrieben werden sollen. Gibst Du den Wert nicht an, wird die Länge von cString verwendet. Und wenn diese Variable immer die gleiche Länge hat, haben die resultierenden Sätze in der Datei auch die gleiche Länge.
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Robert_Steph
Rookie
Rookie
Beiträge: 5
Registriert: Fr, 28. Nov 2014 14:27

Re: ANSI-Datei mit verschiedenen Satzlängen

Beitrag von Robert_Steph »

Hallo Martin und Georg,

vielen Dank für die prompten Antworten.
@Martin: wenn ich es richtig verstehe, hätte ich mir den "Umweg" über die sdfdbe ersparen können. Muss ich mal versuchen.

@Georg: die Satzlängen sind mir bekannt, aber auch wenn ich die entsprechend abändere, wird jeder Datensatz mit der gleichen, nämlich der längsten vorkommenden, Satzlänge gelesen und geschrieben.

Toll, wie schnell hier eine Antwort kommt. Nochmal: ich bin halt kein Profi und mein Code ist manchmal etwas holprig.

Grüße aus Stephanskirchen/Bayern

Robert
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2824
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 95 Mal
Danksagung erhalten: 13 Mal

Re: ANSI-Datei mit verschiedenen Satzlängen

Beitrag von georg »

Hallo, Robert -


im Rahmen der Einführung der Änderung zu KWG 26 (Kontenevidenzzentrale) hatten wir damals zwei Systeme am Start, die beide die Austauschdateien erstellten. Die eine Seite erzeugte Dateien, in denen jeder Satz die kleinste, nötige Länge hatte - technisch hervorragend. Die andere Gruppe erstellte alle Dateien mit der maximalen Satzlänge (d.h. Felder wurden nicht trim()ed, sondern mit der definierten Länge abgelegt) - deutlich schneller realisiert.

Beides geht. Was mich interessieren würde: wie sieht der Code aus, mit dem Du per fWrite() die Datei erzeugst?

Und: ja, Du bekommst nicht nur schnell Antworten, sondern manchmal auch mehr, als einem lieb ist ... Warte die Nacht ab. :D
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Robert_Steph
Rookie
Rookie
Beiträge: 5
Registriert: Fr, 28. Nov 2014 14:27

Re: ANSI-Datei mit verschiedenen Satzlängen

Beitrag von Robert_Steph »

Servus Georg,

also die Schnittstellendatei ("work158.txt") habe ich via sdfdbe erstellt, die wollte ich dann entsprechend trim(men). Ich hab es als Test ziemlich hart codiert, und nach der 2. Satzlänge die Variable nicht mehr angepasst.

Hier der code:

// Datensätze aus Datei lesen, dann in neue Datei schreiben...

Code: Alles auswählen

#include "Appevent.ch"
#include "Gra.ch"
#include "Xbp.ch"
#include "Font.ch"
#include "activex.CH"
#include "Fileio.ch"

#define BUFFER_SIZE 2^16


[color=#000080]PROCEDURE Main

nHdl1:=0 &&Datei in die geschrieben wird
nHdl2:=0 && zu lesende Datei
cBuffer:=space(150)
nBytes:=96 && Länge erster Datensatz (header) 
nCount:=0


//nHdl1:=fcreate("TESTDATEI.TXT",FO_READWRITE)
nHdl1:=fopen("TESTDATEI.TXT",FO_READWRITE)

nHdl2:=fopen("WORK158.TXT",FO_READWRITE)
?ferror(),nHdl2,nHdl1
wait

do while ferror()==0 .and. nCount<=9209 && 9209=reccount("work158.txt")
if nCount>1 
   nBytes=150 &&(Länge der nächsten n Datensätze)
endif
nBytes=fread(nHdl2,@cBuffer,nBytes)
   nCount++
   ?cbuffer,nCount
   fwrite(nHdl1,cBuffer,nBytes)
enddo
?nCount
wait

RETURN
[/color]

Und: lieber viele Antworten, als gar keine. :D

Grüße
Robert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: ANSI-Datei mit verschiedenen Satzlängen

Beitrag von brandelh »

Für das einlesen habe ich in der Wissensdatenbank die Textreader Klasse geschrieben.
Ausgeben kann man wie bei clipper mit set alternate to und ? ...
oder alles in einen string und str2disk() oder fwrite.
sdfdbe kann nur gleiche Satzlängen ind ist meiner Meinung nach etwas seltsam ;-)
PS: vom Handy as La Palma 22:00 Uhr 22° C :-)
Gruß
Hubert
Benutzeravatar
satmax
1000 working lines a day
1000 working lines a day
Beiträge: 831
Registriert: Do, 02. Dez 2010 19:34
Wohnort: Biberbach in Österreich
Hat sich bedankt: 1 Mal
Danksagung erhalten: 1 Mal
Kontaktdaten:

Re: ANSI-Datei mit verschiedenen Satzlängen

Beitrag von satmax »

brandelh hat geschrieben: PS: vom Handy as La Palma 22:00 Uhr 22° C :-)
Na Dir gehts gut! :D , bei uns exakt 1° C :(
Gruß
Markus
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: ANSI-Datei mit verschiedenen Satzlängen

Beitrag von brandelh »

Ansi oder nicht hängt aich von set charset ab. Wenn nötig Ausgabe in string erzeugen und mit ConvToAnsiCP() vor spern umsetzen.
Gruß
Hubert
Robert_Steph
Rookie
Rookie
Beiträge: 5
Registriert: Fr, 28. Nov 2014 14:27

Re: ANSI-Datei mit verschiedenen Satzlängen

Beitrag von Robert_Steph »

Hallo Hubert,

"oder alles in einen string und str2disk() oder fwrite."

Ich hab via sdfdbe alles als ein Feld ausgegeben, auch die Funktion convtoansicp() habe ich dabei benutzt, sonst hätte ich keine Umlaute hinbekommen.
Ich werd mir mal deinen textreader zu Gemüte führen, hört sich schon mal gut an, danke.

Grüße

Robert
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14651
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Re: ANSI-Datei mit verschiedenen Satzlängen

Beitrag von Jan »

Hallo Robert,

es gibt mehrere Punkte, in denen man an ANSI/ASCII denken kann oder muß.
  • Set Charset To ANSI/ASCII
  • In was schreibt der Editor?
  • Mach ich irgendwelche Konvertierungen beim Kompilieren (/GA bzw. /GO)?
  • In welchem Format liegen die Daten vor?
  • Oberfläche OEM oder GUI?
Aus eigener Erfahrung kann ich sagen, das man sich manchmal selbst darein verzettelt. Meist geht es wesentlich einfacher als man denkt, wenn man einfach nur mal bei den Grundeinstellungen anfängt. Denn Xbase++ macht vieles im Hintergrund schon ganz richtig.

Mein Rat: Schau Dir mal die Hilfe zu Set Charset an. Da gibt es einige sehr gute Hinweise und Grafiken.

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Robert_Steph
Rookie
Rookie
Beiträge: 5
Registriert: Fr, 28. Nov 2014 14:27

Re: ANSI-Datei mit verschiedenen Satzlängen

Beitrag von Robert_Steph »

Hallo Jan,
ja, nur mit meinen 2 meist benutzten xbase-Funktionen -trial() und error()- :lol: bin ich über charset und convtoansicp zum gewünschten Ergebnis gelangt, ohne wirklich zu verstehen, warum.
Da ich zu Hause seit dem support-Ende von XP mit UBUNTU unterwegs bin, kann ich immer nur im Büro mit xbase arbeiten. Aber in einem thread über flagship hier im Forum hab ich von freedos gelesen, vielleicht ist das für mich ein Weg.

Grüße
Robert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: ANSI-Datei mit verschiedenen Satzlängen

Beitrag von brandelh »

Robert_Steph hat geschrieben:Hallo Hubert,
"oder alles in einen string und str2disk() oder fwrite."
Ich hab via sdfdbe alles als ein Feld ausgegeben, auch die Funktion convtoansicp() habe ich dabei benutzt, sonst hätte ich keine Umlaute hinbekommen.
ich werd mir mal deinen textreader zu Gemüte führen, hört sich schon mal gut an, danke.
Grüße
Robert
So nun habe ich wieder eine richtige Tastatur unter den Fingern ;-)

Die Idee von Alaska mit den DBEs auf Textdateien zugreifen zu können, die WIE DBFs mit fixer Satzlänge organisiert sind war sicher gut gemeint.
Als die mit OS/2 angefangen haben, gab es auf PC Seite genau einen Zeichensatz der verwendet wurde OEM basta.
Zeilenschaltungen waren chr(13)+chr(10) und durch die feste Satzlänge kann man schnell springen ... aber leider sehen Textdateien oft nicht so aus.
Nach einiger Zeit kam eine Nachbesserung, die flexibler war, aber für mich, der ich flexible Dateien mit PowerBasic und Clipper gewohnt war, war das alles nichts.

Heute sieht die Welt ganz anders aus. Je nach Herkunft der Datei muß man mit chr(13) oder chr(10) oder chr(13)+chr(10) als Zeilenende rechnen,
Die EXE selbst kann in OEM oder ANSI kompiliert sein, die Textdateien können auch ANSI oder OEM enthalten, aber auch in UTF8 oder UNICODE sein ...
meine Klasse berücksichtigt die Zeilenschaltung automatisch !

Aktuell hatte ich noch nicht den Bedarf eine Datei per TextWriter zu erstellen, da ich das immer anders mache, aber aus Gründen der Flexibilität plane ich auch einen Writer.

Geplant ist dabei auch die Erweiterung der TextReader Klasse, denn es stellt sich heraus, dass egal wie die interne Darstellung einer EXE ist (also SET CHARSET)
Das Einlesen einer OEM bzw. ANSI Datei (UTF8 ?) genauso sicher und flexibel gehen muss wie das Erstellen, das heißt man übergibt beim Öffnen neben dem Dateinamen noch "A" (Ansi), "O" (OEM) oder "U" (Uft8) ... und der Text wird intern verarbeitet und wieder im gewünschten Zielformat geschrieben.

Wenn man das z.B. mit ConvToOEMcp() selbst macht, darf man nicht durcheinander kommen, denn jeder Aufruf zuviel zerstört die Daten.
Ob Daten in OEM oder ANSI vorliegen kann man auch nicht abfragen, zumindest nicht sicher.

Und zumindest beim Export spielt es schon eine Rolle, ob man die NÖTIGEN Zeichen belegt oder immer fixe Satzlänge.
Im Besten Fall verschwendet man etwa 50-80% an Platz, im schlimmsten Fall kann das "unflexible" Zielsystem damit nichts anfangen.
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: ANSI-Datei mit verschiedenen Satzlängen

Beitrag von brandelh »

Hier die Links, die für dich interessant sein könnten:

HBTextReader - schnell, keine Größenbeschränkung, automatisch LINUX, MAC oder PC-Zeilenende erkennen.

:arrow: http://www.xbaseforum.de/viewtopic.php?f=16&t=7961

Hier habe ich verschiedene Funktionen zum Einlesen einer Textdatei in ein Array, bis 200 MB sind kein Problem, wenn man genug Ram hat ( >= 2 GB bei Win32, >= 4 GB bei Win64 ).
Diese Funktion kann beim Einlesen auch OEM / ANSI tauschen, aber nicht automatisch UNIX / MAC Dateien verarbeiten. Für Unix gibt es eine Umwandlungsfunktion.

:arrow: http://www.xbaseforum.de/viewtopic.php?f=16&t=4268

OEM, Ansi, Schreiben ...

http://www.xbaseforum.de/viewtopic.php?f=16&t=5943

Das Erstellen habe ich immer so gemacht:

Code: Alles auswählen

local cB := "" // (Buffer erstellen)
DEFINE CRLF chr(13)+chr(10) // windows, UNIX nur chr(10), Mac nur chr(13) als Zeilenende
for x := 1 to nAnzahlRecords
   cB += MeineDateinInnötigemFormat()+CRLF
next
// Wenn nötig ANSI oder OEM tauschen mit ConvAnsiToOemCP() oder ConvOemToAnsiCP() ....
cB :=  ConvAnsiToOemCP(cB) oder ConvOemToAnsiCP(cB) 
Str2Disk(cFile,cB) // oder ähnliche Funktion der Tools, aber KEINESFALLS MemoWrit()  :!: 

*---------------------------------------------------------------------------------------------
function Str2Disk(cFile,cTxt)             // memowrit() fgt ein chr(26) an die Datei an, was st”rt !
   local nResult, nHandle, nByte

   nResult := 0                           // wird schon alles gut gehen ...
   nHandle := FCreate(cFile)
   if nHandle = -1
      nResult := FError()
   else
      nByte := FWrite( nHandle, cTxt )
      if len(cTxt) # nByte
         nResult := FError()
      endif
   endif
   FClose(nHandle)
return nResult
   
Gruß
Hubert
Antworten