Das Notes Forum
Domino 9 und frühere Versionen => ND7: Entwicklung => Thema gestartet von: Demian am 30.11.07 - 09:54:43
-
Moin,moin,
ich versuche mich gerade ein bisschen in der Schnittstellendatei-Programmierung. In unserer Zeiterfassung werden sequentielle Dateien erzeugt, die in unserem eigentlichen Abrechnungsprogramm eingelesen werden.
Da hier einiges manuell nachbearbeitet werden muss, habe ich mir überlegt, die Dateien einzulesen, bestimmte Datensätze ändern zu lassen und eine neue Datei auszugeben.
Im Großen und Ganzen funktioniert das. Wenn ich die Datei in unser Abrechnungsprogramm einlesen will, erscheint jedoch der Hinweis, dass im letzten Datensatz der Wert numerisch sein muss und nicht eingelesen werden könne.
Seltsamerweise wird er eingelesen, aber irgendwas scheint da ja nicht ganz sauber zu sein. Ein Datensatz hat eine Länge von 162 Zeichen. Wenn ich die von mir erstellte Datei einlese und mit len die Anzahl der Zeichen ermittel, komme ich auch auf die 162 Zeichen.
Mit diesem Code lese ich die Original-Dateien ein:
Function DateiEinlesen(Datei As String)
Dim s As New NotesSession
Dim db As NotesDatabase
Dim doc As NotesDocument
Set db = s.CurrentDatabase
'Dateibezogene Variablen
Dim DateiStream As Integer, Pos As Long,Datensatz
'Freie Dateinummer suchen
Dateistream = Freefile()
Pos = 1
Open Datei For Input Access Read As Dateistream
While Not Eof(Dateistream)
Seek #Dateistream,Pos
Set doc = db.CreateDocument
doc.form = "Schnittstelle - Datensatz"
doc.Firma = Input$(4,Dateistream)
Pos = Pos + 4
Seek #Dateistream,Pos
doc.Periode = Input$(8,Dateistream)
Pos = Pos + 8
Seek #Dateistream,Pos
doc.Personalnummer = Input$(10,Dateistream)
Pos = Pos + 10
Seek #Dateistream,Pos
doc.Lohnart = Input$(4,Dateistream)
Pos = Pos + 4
Seek #Dateistream,Pos
doc.Menge = Input$(11,Dateistream)
Pos = Pos + 11
Seek #Dateistream,Pos
doc.Lohngruppe = Input$(3,Dateistream)
Pos = Pos + 3
Seek #Dateistream,Pos
doc.Preis = Input$(8,Dateistream)
Pos = Pos +8
Seek #Dateistream,Pos
doc.Faktor = Input$(7,Dateistream)
Pos = Pos + 7 'nach Faktor
Seek #Dateistream,Pos
doc.Kostenstelle = Input$(16,Dateistream)
Pos = Pos + 16
Seek #Dateistream,Pos
doc.Auftragsnummer =Input$(20,Dateistream)
Pos = Pos + 20
Seek #Dateistream,Pos
doc.Kostenart = Input$(8,Dateistream)
Pos = Pos + 8
Seek #Dateistream,Pos
doc.LeistendeKostenstelle = Input$(16,Dateistream)
Pos = Pos + 16
Seek #Dateistream,Pos
doc.Mitteilung = Input$(24,Dateistream)
Pos = Pos + 24 'nach MTTLG
Seek #Dateistream,Pos
doc.Puffer = Input$(23,Dateistream)
Pos = Pos + 23
Call doc.Save(True,False)
Lohnartensummen = Lohnartensummen + 1
Print Lohnartensummen & " Lohnartensummen eingelesen"
Wend
Close Dateistream
Nachdem die Änderungen durch eine Funktion vorgenommen wurden, wird mit diesem Code die neue Datei erzeugt:
Function DateiErstellen(Datei As String)
Dim s As New NotesSession
Dim db As NotesDatabase
Dim view As NotesView
Dim doc As NotesDocument
Dim i As Long
'Dateibezogene Variablen
Dim Dateistream As Integer, Pos As Long, Zeile As String
Set db = s.CurrentDatabase
Set view = db.GetView("Schnittstelle - Datensätze")
Call view.Refresh
'2. \ suchen und Dateinamen bilden
Zaehler = Instr(6,Datei,"\")
Datei = "G:\Schnittstellen\Ausbildung\" & Right(Datei,Len(Datei)-Zaehler)
'Freie Ddateinnummer suchen
DateiStream = Freefile()
'Datei erstellen
Open Datei For Output Access Write As DateiStream
'Datensatz bilden
Set doc = view.GetFirstDocument
Pos = 1
Do While Not (doc Is Nothing)
Seek #Dateistream,Pos
Print #DateiStream,Cstr(doc.Firma(0))
Pos = Pos + 4
Seek #Dateistream,Pos
Print #DateiStream,Cstr(doc.Periode(0))
Pos = Pos + 8
Seek #Dateistream,Pos
Print #DateiStream,Cstr(doc.Personalnummer(0))
Pos = Pos + 10
Seek #Dateistream,Pos
Print #DateiStream,Cstr(doc.Lohnart(0))
Pos = Pos + 4
Seek #Dateistream,Pos
Print #DateiStream,Cstr(doc.Menge(0))
Pos = Pos + 11
Seek #Dateistream,Pos
Print #DateiStream,Cstr(doc.Lohngruppe(0))
Pos = Pos + 3
Seek #Dateistream,Pos
Print #DateiStream,Cstr(doc.Preis(0))
Pos = Pos +8
Seek #Dateistream,Pos
Print #DateiStream,Cstr(doc.Faktor(0))
Pos = Pos + 7 'nach Faktor
Seek #Dateistream,Pos
Print #DateiStream,Cstr(doc.Kostenstelle(0))
Pos = Pos + 16
Seek #Dateistream,Pos
Print #DateiStream,Cstr(doc.Auftragsnummer(0))
Pos = Pos + 20
Seek #Dateistream,Pos
Print #DateiStream,Cstr(doc.Kostenart(0))
Pos = Pos + 8
Seek #Dateistream,Pos
Print #DateiStream,Cstr(doc.LeistendeKostenstelle(0))
Pos = Pos + 16
Seek #Dateistream,Pos
Print #DateiStream,Cstr(doc.Mitteilung(0))
Pos = Pos + 24 'nach MTTLG
Seek #Dateistream,Pos
Print #DateiStream,Cstr(doc.Puffer(0))
Pos = Pos + 23
Set doc = view.GetNextDocument(doc)
'für spätere Ausgabe in Statuszeile
AnzahlGeschriebenerDatensaetze = AnzahlGeschriebenerDatensaetze + 1
Loop
'Erstellte Datei schließen
Close DateiStream
End Function
Das Problem ist, das sich nicht nachvollziehen lässt, welcher Wert numerisch sein muss. Die Menge zum Beispiel muss 11-stellig sein und sieht optisch im Editor so aus
" 0000005.80"
das erste Zeichen ist das Vorzeichen und muss bei positiven Werten nicht mitangegeben werden. Das ist doch aber eigentlich kein numerischer Wert, oder?
Hat jemand ne Idee, wo der Fehler liegen könnte? Gibt es eine Möglichkeit die Original-Datei mit der von mir erstellten Datei zu vergleichen? Im Editor sieht beides gleich aus.
Gruß
Demian
PS: Die eingelesenen Datensätze sehen wie auf dem Screenshot aus. Ich habe auch die Zeichen der einzelnen Felder nachgezählt. Es entspricht den Vorgaben.
-
Also,
ich habe das Ganze jetzt nochmal mit einem einzelnen Datensatz gemacht. Obwohl der Datensatz in dem Dokument nur 162 Zeichen hat, zeigt er mir bei filelen(Datei) 164 Zeichen an.
Ich habe in dem Dokument mal ein Feld gemacht, dass die Werte aus allen anderen beeinhaltet und die Datei folgendermaßen gefüllt:
Do While Not (doc Is Nothing)
Seek #Dateistream,Pos
Print #Dateistream,doc.Satz(0)
Pos = Pos + 162
Set doc = view.GetNextDocument(doc)
'für spätere Ausgabe in Statuszeile
AnzahlGeschriebenerDatensaetze = AnzahlGeschriebenerDatensaetze + 1
Loop
len(doc.Satz(0)) ergibt auch 162 und trotzdem wirft er mir bei filelen(Datei) 164 aus. Also hängt er mir einfach 2 Zeichen mehr an. Laut Hexeditor sind in der Datei an den letzten beiden Stellen 2 . . (siehe Screenshot). Die . . sind im Edotir aber nicht zu sehen. Was mache ich nur falsch???
Gruß
Demian
-
0D0A ist eine Zeilenschaltung - vermutlich Dein Record-Trennzeichen. Das sieht vollkommen normal aus.
Bernhard
-
Moin Bernhard,
aber in meinem Script ist doch gar keine Zeilenschaltung??? In der Originaldatei sind die auch nciht drin.
Gruß
Demian
-
Woher kommt denn nun die bemängelte Datei? Aus einem externen Programm (und Dein Notes-Programm meckert) oder aus Notes (und das externe Programm schimpft)?
Bernhard
-
Die ursprüngliche Datei kommt aus unserer Zeiterfassung. Diese lese ich in Notes ein, lasse diverse Werte ändern, und möchte diese in eine neue Datei ausgeben. Und bis auf diese Zeilenschaltung, die sich bei "meiner" Datei immer am Ende befindet klappt es ja.
Ich verstehe nicht, wo das crlf überhaupt herkommt???
Gruß
Demian
EDIT: Meckern tut das Programm in das ich dann die von mir aus Notes erstellte Datei einspielen möchte, mit dem Hinweis dass der Wert numerisch sein müsste. Das kann sich dann eigentlich nur auf diese Zeilenschaltung beziehen, da ansonsten meine Datei, mit der "echten" aus der Zeiterfassung übereinstimmt.
-
Man sollte sich die Hilfe doch etwas genauer anschauen, auch wenn die Englisch-Kenntnisse dann nicht so prickelnd sind.
Hinweis Newline does not mean either chr(10) or chr(13) on all platforms. Newline is the character or sequence of characters that is used to mark the end of a line. This may be chr(10), or chr(13), but it may also be something else, because the actual value of newline depends on the platform.
Also, hängt er mir den Zeilenumbruch durch print automatisch an, sehe ich das richtig? Warum dann aber erst bei der letzten print-Anweisung und nicht bei jeder???
Desweiteren habe ich unter widht # gesehen, dass nach print #Dateistream,Text noch ein ; steht. Habe das einfach mal der letzten print-Anweisung hinzugefügt und siehe da laut Hex-Editor kein Zeilenumbruch mehr. Nur warum das so ist, ist mir überhaupt nicht klar.
Gruß
Demian
-
... den Zeilenumbruch hast du auf jeden Fall - sonst wäre es keine Zeile, sondern Fließtext in einer einzigen Zeile. Beim Einlesen wird der Umbruch aber wieder ignoriert, da ja zeilenweise eingelesen wird. Das Problem scheint mir das Semikolon zu sein...
Toni
-
Moin Toni,
aber durch Setzen des ; erscheint laut Hex-Editor kein Zeilenumbruch mehr. Und diese Dateien lassen sich dann auch fehlerfrei in das Programm einspielen. Wenn ich die Datei mit dem normalen Editor öffne, stehen die Datensätze auch nacheinander weg.
Bei 2 Datensätzen entspricht das genau einer Zeile. Ich kann den Cursor auch nicht in die 2. Zeile setzen. Und so ist das auch bei der "Orginal"-Datei aus unserer Zeiterfassung. Also scheint das ; des Rätsel Lösung zu sein, aber warum?
Gruß
Demian
-
... vielleicht wird der Zeilenumbruch erst beim Einfügen einer zweiten Zeile vorangestellt - may be...
Hauptsache es tut...
Toni
-
eben. Aber trotzdem vielen Dank euch beiden.