Fehler beim Reinschreiben in eine Textdatei

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Sebastian
Beiträge: 322
Registriert: 14.06.2006 16:46
Wohnort: Kiel

Beitrag von Sebastian »

Schön und gut. Dennoch sollte doch die Sprache verbessert werden, auch wenn man sich selber Macros basteln kann. Meiner Meinung nach wäre es eine Verbesserung. :)
(Win 11 64-bit, PB 6.04 und 6.10)
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Das PBTEAM ist nunmal sehr klein, deshalb
1. Bugs bereinigen

2. Sprache erweitern um fehlende Dinge, die man nur sehr schlecht oder
garnicht selber machen kann, vor allem Dinge für die der Compiler erweitert werden muß.

3. und dann erst Spracherweiterungen um Dinge die einem das Leben
einfacher machen, und darum gehts ja, hätte für mich keine Priorität, weils
wesentlich wichtigeres gibt.

Ein bissel sollten wir doch auch selber programmieren, das verbinden von
2 commandos mit einem Flag wäre eine Erweiterung die sich fast jeder
selber schreiben kann.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

seh ich auch so.
ein extra append-flag ist unnötig, weil ja wirklich alles da ist was man braucht.

so wie es jetzt ist ist er sogar logischer und lehrreicher.
wenn man eine datei öffnet, steht der zeiger am anfang. ist nunmal so.
wenn man was ans ende schreiben will, muss man den zeiger dahin setzen.
so lernen auch Anfänger, was eigentlich abläuft.
wenn du jemandem einen Append-Befehl vor die Nase setzt,
dann denkt der spontan das wäre schneller als die native Befehlskombination.

seinen Usern das Denken und seinen Anfängern den Lerneffekt abzunehmen,
halte ich nicht für eine verbesserung.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
HemSA
Beiträge: 221
Registriert: 16.10.2005 13:59
Wohnort: Manisa / Türkei
Kontaktdaten:

Beitrag von HemSA »

Hallole an alle und vielen Dank für eure Ideen.
Ich möcht euch noch erklären was die Funktion von dem Programm ist.

Es ist eine Exceltabelle, in der Konstanten berechnet werden. In der 1. Spalte ist die Kennung vom Satz ( für die Textdatei ), in den anderen Spalten sind die Konstanten die in dem Satz von der Textdatei überschrieben werden sollen abgelegt ( zum aktuallisieren ).

Das Programm liest nun den Wert aus der 2. Zeile von der 1. Spalte von der Exceltabelle aus, und sucht in der Textdatei in welcher Zeile der Satz steht. Wenn der Satz gefunden wurde dann werden innerhalb vom Satz ab einer bestimmten Stelle die Werte von den Konstanten in den Satz überschrieben ( aktuallisiert ).
Danach nimmt es sich den Wert von der 3. Zeile von der 1. Spalte der Exceltabelle und das gleiche spielt sich wieder ab.

Gleichzeitig wird in einer "Nachfolziehbarkeitsdatei" die reingeschriebenen Konstanten mit Datum und Uhrzeit zusammen am Schluss der Nachvollziehbarkeitsdatei" abgespeichert. So das man später nachvollziehen kann: "Welche Konstanten wurden am diesem Datum und Uhrzeit in die Textdatei reingeschrieben".
Und dies alles wird so alle 15 Minuten wiederholt ( deshalb ist die Laufzeit nicht so wichtig ).

Das klappt mit dem Programm alles wunderschön. Allerdings sollten jetzt die Werte in der Exceldatei von seither 40 Sätzen auf ca. 800 erhöht werden.
Mit Reserve habe ich dann die FOR-NEXT Schleife auf 1500 geändert. Auch das war kein Problem und funktioniert gut.

Allerdings will ich keine 1500 mal eine Datei aufmachen und wieder schliessen ( wäre zeitlich kein Problem - ist aber nicht die feine nette Art denke ich ). Deshalb die Frage an euch. So wie ich es mir gedacht habe klappt es nicht. Es sollen ja nicht nur Daten an eine bestehende Datei angehängt werden, es ist ja auch noch ein Suchablauf vorhanden, wo man irgendwo innerhalb von der Textdatei Werte aktuallisiert und wo ich nicht weiss wie man das ohne die Geschichte, 1500 mal öffnen und schliessen, machen kann.

Der gekürzte "funktionierende" jetztige Code ist hier aufgeführt ( vielleicht kann ihn jemand für ähnliche Zwecke gebrauchen - Messtechnik etc. - würde mich freuen ):

Code: Alles auswählen

Procedure Hauptprogramm()

Tabelle.s="C:\Tabelle.xls"

ExcelApp=OpenExcelFileTabelle(Tabelle.s)


For i=2 To 1500 ; in Excelseite mit 2. Zeile beginnen mit auslesen

If ExcelApp
 
  ExcelVisible(ExcelApp,2) ;wenn Excel sichtbar sein soll: "1" wenn nicht dann "2"
  AskToUpdateLinks(ExcelApp,0) ; keine Abfrage zu UpdateLinks
  DisplayAlertsOnOff(ExcelApp,0)  ; wenn "0" dann wird Speicherabfrage unterdrückt - wenn "1" dann nicht
  
  Arbeitsblatt.s="Allgemeintable"
  ChangeToWorksheet(ExcelApp,Arbeitsblatt.s)

  allgemeintabelleexcels.s=ReadCellS1(ExcelApp, i, 1);Spalte,Zeile
  co2maxburnexcelkommas.s=ReadCellS1(ExcelApp, i, 4)
  co2minburnexcelkommas.s=ReadCellS1(ExcelApp, i, 5)
        
    
  co2maxburnexcels.s=ReplaceString(co2maxburnexcelkommas.s, ",", ".")
  co2minburnexcels.s=ReplaceString(co2minburnexcelkommas.s, ",", ".")
  
  allgemeintabelletrims.s=Trim (allgemeintabelleexcels.s)
  co2maxburntrims.s=Trim (co2maxburnexcels.s)
  co2minburntrims.s=Trim (co2minburnexcels.s)
       
  allgemeintabelles.s= LSet(allgemeintabelletrims.s, 10) 
  co2maxburns.s= LSet(co2maxburntrims.s, 5,"0") 
  co2minburns.s= LSet(co2minburntrims.s, 5,"0") 
    
  ExcelVisible(ExcelApp,2) ;wenn Excel sichtbar sein soll: "1" wenn nicht dann "2"
 
Else
   MessageRequester("Uyarı", "Excel acamıyor")
EndIf

zeilel.l=0

If OpenFile(1,"C:\ALLGEM.TAB") 
     
    While Eof(1) = 0 ; sich wiederholende Schleife bis das Ende der Allgemeintabelle ("end of file") erreicht ist
                     
       zeilensatzs.s=ReadString(1) 
       zeilel.l=zeilel.l+1                            ;gibt die Zeile an in der der Suchbegriff steht
       
       allgemeintabs.s=Left(zeilensatzs.s,10)         ;beim Suchmodus wird vorausgesetzt, dass
       
       If allgemeintabs.s=allgemeintabelles.s
       
        zeiles.s=Str(zeilel.l) 
     
        FileSeek(1,(zeilel.l-1)*229+143)          ;229 = Zeilenlänge von der Textdatei + 2
        WriteString(1, co2maxburns.s)             ;schreibt den String ab einer bestimmten Position in die Zeile
        
        FileSeek(1,(zeilel.l-1)*229+161)          ;zeile-1 ==> damit der Zeiger am Anfang von der Suchzeile steht 
        WriteString(1, co2minburns.s)            
        
        jahrs.s=FormatDate("%yyyy",Date())
        monats.s=FormatDate("%mm",Date())
        tags.s=FormatDate("%dd",Date()) 
        stundens.s=FormatDate("%hh",Date()) 
        minutens.s=FormatDate("%ii",Date())
        sekundens.s=FormatDate("%ss",Date()) 
          
        textgesamtallgemeintabs.s = allgemeintabelles.s+" "+tags.s+"."+monats.s+"."+jahrs.s+" "+stundens.s+":"+minutens.s+":"+sekundens.s+" "+co2maxburns.s+" "+co2minburns.s
          
 
         If OpenFile(2,"C:\Allgemein.log")
             laengel.l= Lof(2)                                      ; ermitteln der Dateilaenge              
             FileSeek(2,laengel.l)                                  ; setzt den Zeiger ans Dateiende           
      
             WriteStringN(2,textgesamtallgemeintabs.s)              ; schreibt den Gesamttext an das Ende von der Datei
      
             CloseFile(2)                                           ; schließt die Datei
         EndIf
        
        EndIf
      
    Wend
  
Else
    MessageRequester("Uyarı","Allgemein tablosu acamadı!")
EndIf

  CloseFile(1)
  
Next i  
   
CloseWorkbook(ExcelApp); schliesst Excelseite um andere Seiten zu bearbeiten
ExcelVisible(ExcelApp,2) ;wenn Excel sichtbar sein soll: "1" wenn nicht dann "2"
CloseExcelAll(ExcelApp); um Excel zu schliessen

EndProcedure
==> wenn es nicht geht dann eben der NASA-Spruch: Never change a working sistem
PB 4.02 (wegen Disphelper), 5.72 (Windows) (x64)
Benutzeravatar
Falko
Admin
Beiträge: 3535
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.11b1
HP255G8 Notebook @AMD Ryzen 5 5500U with Radeon Graphics 2.10 GHz 3.4GHz, 32GB_RAM, 3TB_SSD (Win11 Pro 64-Bit)
Kontaktdaten:

Beitrag von Falko »

Ich habe den Source nun nicht ausprobiert. Zudem müsste ich von der Excellib noch einige Änderungen machen, damit sie mit deinem Programm laufen.

Aber mit dem openfile liegt für mich ganz einfach darin, das du innerhalb der 1500 Durchläufe jedesmal die File öffnest intern diese File bis zu 1500 Einträgen absuchst und änderst und dann diese File schliesst. Das wiederholt sich dann bis aus Excel alles ausgelesen wurde.

Ich hoffe ich liege damit richtig. Durch das file öffnen und wieder schließen innerhalb der Excel - Schleife wird dann auch jedesmal der Filepointer am
Anfang beginnen. Und darum läuft es auch.

Wenn du also diese File nur einmal öffnen willst, und beim und auf EOF prüfen willst, solltest du dann den filepointer wieder auf den Anfang setzen. und irgendwie die Whileschleife verlassen. Dann müsste es mit
einmal openfile und am Ende closefile gehen. Daran liegt es bestimmt.

Wie gesagt, ich werde meine lib anpassen und es irgendwie nachahmen.

Vielleicht kriegst du es mit diesen Tips selber heraus

Gruß Falko
Bild
Win11 Pro 64-Bit, PB_6.11b1
HemSA
Beiträge: 221
Registriert: 16.10.2005 13:59
Wohnort: Manisa / Türkei
Kontaktdaten:

Beitrag von HemSA »

Hallo Falko,
ja den Ablauf hast du richtig verstanden.

Das dieser Code überhaupt funktioniert liegt ehh an dir und eine Unterstützer von deinem Disphelper. Danke nochmals an alle!

Aber ich denke, dass ich - allein wegen dem Suchdurchlauf - wohl nicht auf das Öffnen und Schliessen von den Dateien herumkomme. Es sind ja auch nicht die einzigsten Dateien die ich so "behandle" - damit der gezeigte Code kürzer ist habe ich die anderen Programmteile - die genauso behandelt werden ( Daten von anderen Arbeitsblättern ) rausgelöscht.

Und da das Programm auf dem Server liegt, denke ich wird das wohl mit den 1500 Dateien öffnen und schliessen nicht gleich zum "Serverausfall" führen - obwohl es wohl nicht die beste Lösung ist.
PB 4.02 (wegen Disphelper), 5.72 (Windows) (x64)
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

HemSA hat geschrieben:aber eigendlich verwende ich nur noch PB 4.02
wo hast'n das her? ;)
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
Falko
Admin
Beiträge: 3535
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.11b1
HP255G8 Notebook @AMD Ryzen 5 5500U with Radeon Graphics 2.10 GHz 3.4GHz, 32GB_RAM, 3TB_SSD (Win11 Pro 64-Bit)
Kontaktdaten:

Beitrag von Falko »

Der Displhelper ist von MK-Soft.

Nun zum Programm. Probier mal dieses so aus. Habs nun nicht getestet, aber so müsste es evtl. mit kleinen Korrekturen richtig ablaufen :wink:

Code: Alles auswählen

Procedure Hauptprogramm()
If OpenFile(1,"C:\ALLGEM.TAB"); Da das abhängig von der Exceltabelle ist, würde ich diese File hier ausserhalb der Schleife öffnen
Tabelle.s="C:\Tabelle.xls"

ExcelApp=OpenExcelFileTabelle(Tabelle.s)

For i=2 To 1500 ; in Excelseite mit 2. Zeile beginnen mit auslesen

If ExcelApp
 
  ExcelVisible(ExcelApp,2) ;wenn Excel sichtbar sein soll: "1" wenn nicht dann "2"
  AskToUpdateLinks(ExcelApp,0) ; keine Abfrage zu UpdateLinks
  DisplayAlertsOnOff(ExcelApp,0)  ; wenn "0" dann wird Speicherabfrage unterdrückt - wenn "1" dann nicht
 
  Arbeitsblatt.s="Allgemeintable"
  ChangeToWorksheet(ExcelApp,Arbeitsblatt.s)

  allgemeintabelleexcels.s=ReadCellS1(ExcelApp, i, 1);Spalte,Zeile
  co2maxburnexcelkommas.s=ReadCellS1(ExcelApp, i, 4)
  co2minburnexcelkommas.s=ReadCellS1(ExcelApp, i, 5)
       
   
  co2maxburnexcels.s=ReplaceString(co2maxburnexcelkommas.s, ",", ".")
  co2minburnexcels.s=ReplaceString(co2minburnexcelkommas.s, ",", ".")
 
  allgemeintabelletrims.s=Trim (allgemeintabelleexcels.s)
  co2maxburntrims.s=Trim (co2maxburnexcels.s)
  co2minburntrims.s=Trim (co2minburnexcels.s)
       
  allgemeintabelles.s= LSet(allgemeintabelletrims.s, 10)
  co2maxburns.s= LSet(co2maxburntrims.s, 5,"0")
  co2minburns.s= LSet(co2minburntrims.s, 5,"0")
   
  ExcelVisible(ExcelApp,2) ;wenn Excel sichtbar sein soll: "1" wenn nicht dann "2"
 
Else
   MessageRequester("Uyari", "Excel acamiyor")
EndIf

zeilel.l=0

;If OpenFile(1,"C:\ALLGEM.TAB")
     
    While Eof(1) = 0 ; sich wiederholende Schleife bis das Ende der Allgemeintabelle ("end of file") erreicht ist
                     
       zeilensatzs.s=ReadString(1)
       zeilel.l=zeilel.l+1                            ;gibt die Zeile an in der der Suchbegriff steht
       
       allgemeintabs.s=Left(zeilensatzs.s,10)         ;beim Suchmodus wird vorausgesetzt, dass
       
       If allgemeintabs.s=allgemeintabelles.s
       
        zeiles.s=Str(zeilel.l)
     
        FileSeek(1,(zeilel.l-1)*229+143)          ;229 = Zeilenlänge von der Textdatei + 2
        WriteString(1, co2maxburns.s)             ;schreibt den String ab einer bestimmten Position in die Zeile
       
        FileSeek(1,(zeilel.l-1)*229+161)          ;zeile-1 ==> damit der Zeiger am Anfang von der Suchzeile steht
        WriteString(1, co2minburns.s)           
       
        jahrs.s=FormatDate("%yyyy",Date())
        monats.s=FormatDate("%mm",Date())
        tags.s=FormatDate("%dd",Date())
        stundens.s=FormatDate("%hh",Date())
        minutens.s=FormatDate("%ii",Date())
        sekundens.s=FormatDate("%ss",Date())
         
        textgesamtallgemeintabs.s = allgemeintabelles.s+" "+tags.s+"."+monats.s+"."+jahrs.s+" "+stundens.s+":"+minutens.s+":"+sekundens.s+" "+co2maxburns.s+" "+co2minburns.s
         
 
         If OpenFile(2,"C:\Allgemein.log")
             laengel.l= Lof(2)                                      ; ermitteln der Dateilaenge             
             FileSeek(2,laengel.l)                                  ; setzt den Zeiger ans Dateiende           
     
             WriteStringN(2,textgesamtallgemeintabs.s)              ; schreibt den Gesamttext an das Ende von der Datei
     
             CloseFile(2)                                           ; schließt die Datei
         EndIf
       
        EndIf
     
    Wend
 
Else
    MessageRequester("Uyari","Allgemein tablosu acamadi!")
EndIf
   FileSeek(1,1) ; kann auch Null sein. Habs nicht probieren können
  ;CloseFile(1)
 
Next i 
   
CloseWorkbook(ExcelApp); schliesst Excelseite um andere Seiten zu bearbeiten
ExcelVisible(ExcelApp,2) ;wenn Excel sichtbar sein soll: "1" wenn nicht dann "2"
CloseExcelAll(ExcelApp); um Excel zu schliessen
CloseFile(1); Schließe Datei bis Excel komplett fertig ist
EndProcedure 
[Edit]
das OpenFile(2... könnte man auch nach dem ersten OpenFile(1... legen
und beim beenden von Excel und vor dem schliessen der File 1 beenden.

Evt. musst du die If --> Endif - Ausführung noch korrekt setzen.
[/Edit]
Bild
Win11 Pro 64-Bit, PB_6.11b1
Benutzeravatar
Falko
Admin
Beiträge: 3535
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.11b1
HP255G8 Notebook @AMD Ryzen 5 5500U with Radeon Graphics 2.10 GHz 3.4GHz, 32GB_RAM, 3TB_SSD (Win11 Pro 64-Bit)
Kontaktdaten:

Beitrag von Falko »

Mit dem FileSeek(0,1) habe ich hier ein kleines Beispiel ausprobiert,
sodass diese bei einer geöffneten File x-Mal wiederholt werden kann.
In diesem Beispiel nur zweimal 10 Sätze, wie man schön sehen kann.
Nach Ende dieser Wiederholungen wird die File erst nach den 20 Sätzen
geschlossen. Es könnten auch 1500 Durchläufe sein, ohne das die File
zwischendurch geschlossen wird.


Code: Alles auswählen

CreateFile(0,"Text.txt")
For i = 1 To 10
  WriteStringN(0,Str(i)+": Dieses ist ein Test")
Next i
CloseFile(0)

If ReadFile(0, "Text.txt")   ; wenn die Datei geöffnet werden konnte, setzen wir fort...
For i=1 To 2; hier könnte 1500 stehen. Dann würden es 15000 Sätze.
    While Eof(0) = 0           ; sich wiederholende Schleife bis das Ende der Datei ("end of file") erreicht ist
    Debug Eof(0)
      Debug ReadString(0)      ; Zeile für Zeile im Debugger-Fenster anzeigen
    Wend
    FileSeek(0,1)
Next i    
    
    CloseFile(0)               ; schließen der zuvor geöffneten Datei
Else
    MessageRequester("Information","Konnte Datei nicht öffnen!")
EndIf
Bild
Win11 Pro 64-Bit, PB_6.11b1
HemSA
Beiträge: 221
Registriert: 16.10.2005 13:59
Wohnort: Manisa / Türkei
Kontaktdaten:

Beitrag von HemSA »

Hallo Falko,
vielen Dank für die Zeit die du dir genommen hast. Ich war einige Tage nicht daheim, von dem her erst jetzt eine Reaktion von mir. Ich werde mir das Ganze mal anschauen und umprogrammieren. Bin mal gespannt was es zeitlich ausmacht ( während der Zeit zeigt es ja immer die Sanduhr bei meinen Kollegen am Bildschirm an, während sie unter Umständen wenn das Programm alle 15 Minuten läuft, andere Arbeiten tun ==> wäre aber wirklich nur das kleinere Übel, wenn man bedenkt was das meinen Kollegen an Arbeit erspart )

Habe nur noch eine Frage aus Neugierde:
Schadet es der Datei, wenn man sie 1000 mal öffnet und schliesst - es werden ja schliesslich immer nur 1er und 0 hin und hergewürfelt denke ich mal? Und wenn das Ganze fertig ist vom RAM auf die Festplatte geschrieben.

Kaeru Gaman sagte:
BeitragVerfasst am: 24 Jul 2008 23:43:32 Titel:
HemSA hat Folgendes geschrieben:
aber eigendlich verwende ich nur noch PB 4.02

wo hast'n das her?
Von Pure Basic selbst
PureBasic v4.02 (Windows - x86)
Feel the ..Pure.. Power

Team Members :
Frederic 'AlphaSND' Laboureur
Benny 'Berikco' Sels
Andre Beer
Timo 'Fr34k' Harter

Former Team Members :
Richard Andersson
Danilo Krahn

PureBasic, all the provided tools and components
are copyrighted (c) 2006 by Fantaisie Software

http://www.purebasic.com

Special thanks to all PureBasic users and beta-testers !
Ich wollte eigendlich das "Hilfe => Über => Bild" hier anzeigen. Wusste aber nicht wie das funktioniert.
PB 4.02 (wegen Disphelper), 5.72 (Windows) (x64)
Antworten