Domino 9 und frühere Versionen > ND7: Entwicklung

Letzter Datensatz in sequentieller Datei fehlerhaft

(1/3) > >>

Demian:
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.

Demian:
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

koehlerbv:
0D0A ist eine Zeilenschaltung - vermutlich Dein Record-Trennzeichen. Das sieht vollkommen normal aus.

Bernhard

Demian:
Moin Bernhard,

aber in meinem Script ist doch gar keine Zeilenschaltung??? In der Originaldatei sind die auch nciht drin.

Gruß
Demian

koehlerbv:
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

Navigation

[0] Themen-Index

[#] Nächste Seite

Zur normalen Ansicht wechseln