2.)Daten speichern u. bearbeiten mit mehrspaltigen Tabellen

Anfängerfragen zum Programmieren mit PureBasic.
xcello
Beiträge: 5
Registriert: 24.11.2008 12:00

2.)Daten speichern u. bearbeiten mit mehrspaltigen Tabellen

Beitrag von xcello »

Hallo AND51,

hier bin ich wieder. Deine Tipps waren sehr gut und ich habe mir die Woche über etwas zusammengebastelt ( siehe Codeausschnitt unten)
Leider hänge ich jetzt an dem nächsten Thema, denn nach dem Anlegen der Datei mit den obigen Adressinhalten wird zwar eine schöne
Tabelle aufgebaut aber als Inhalt erscheinen nicht die Datensätze, wie gewünscht, sondern nur die Platzhalter für die einzelnen Werte.

Irgendwie scheint die Zuordnung bei den Schleifendurchläufen an die Variablen nicht zu funktionieren und ich komme an diesem Punkt
einfach nicht weiter aber vielleicht sieht es ein Profi mit einem Blick was hier nicht passt.

Mein Denkfehler muss in dem umrahmten Programmteil liegen ";==??????????==" aber manschmal steht man einfach auf dem Schlauch
und sieht den Wald vor Bäumen nicht mehr - würde mich über einen kurzen Hinweis, wenn es nicht zu viel Mühe macht, sehr freuen und
bedanke mich schon jetzt dafür

viele Grüße
xcedllo

Code: Alles auswählen


If OpenWindow(0, 100, 100, 1250, 850, "Anzeige Telefonbuch", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_TitleBar| #PB_Window_ScreenCentered)
   
   If CreateGadgetList(WindowID(0))
     ListIconGadget(0, 5, 35, 1050, 750, "Name", 100,#PB_ListIcon_GridLines |#PB_ListIcon_FullRowSelect|#PB_ListIcon_AlwaysShowSelection)
     AddGadgetColumn(0, 1, "Vorname", 100)
     AddGadgetColumn(0, 2, "Strasse", 100)
     AddGadgetColumn(0, 3, "Nr", 100)
     AddGadgetColumn(0, 4, "Postleitzahl", 100)
     AddGadgetColumn(0, 5, "Ort", 100) 
     AddGadgetColumn(0, 6, "Telefon", 100)
     TextGadget(1, 5,  7, 270, 20, "Aktuelle Datensätze")
     
   
;=======??????????==========================================================================================??????????=======
;=======??????????==========================================================================================??????????=======
;=======??????????==========================================================================================??????????======= 
 If ReadFile(1,"c:/Datei.txt")
 laenge.l= Lof(1)
 zeilenanzahlw.w =laenge.l/101       
 For z.w= 1 To zeilenanzahlw.w
 Debug (z.w)
 FileSeek(1,z.w*101)                                       
                 
 wert.s=ReadString(1)
        
 Name.s        =Left(wert.s,10   )
 Vorname.s     =Mid (wert.s,11,15)
 Strasse.s     =Mid (wert.s,26,15)
 Nr.s          =Mid (wert.s,41,15)
 Postleitzahl.s=Mid (wert.s,56,15)
 Ort.s         =Mid (wert.s,71,15)
 Telefon.s     =Mid (wert.s,86,15)
 AddGadgetItem(0, -1,"Name.s"+Chr(10)+"Vorname.s"+Chr(10)+"Strasse.s"+Chr(10)+"Nr.s"+Chr(10)+"Postleitzahl.s"+Chr(10)+"Ort.s"+Chr(10)+"Telefon.s")              
 Next z.w
       
 CloseFile(1)
 EndIf
   
 EndIf 
 EndIf
  
 
 ;=======??????????==========================================================================================??????????=======
 ;=======??????????==========================================================================================??????????=======
 ;=======??????????==========================================================================================??????????======= 
 
 
 
   Repeat
    EventID = WaitWindowEvent()
    If EventID = #PB_Event_CloseWindow
    Quit = 1
    EndIf
   
    If EventID = #PB_Event_Gadget
     
     
     
     If EventGadget()=2
         
        wertw.w = GetGadgetState(0)
        ergebniss.s = Str(wertw.w)
           
            
                   
     CloseWindow(0)
           
        
           
     EndIf
     EndIf
            
         a=0
         a=a+5
Until a>100
__________________________________________________
Code-Tags angepasst
29.11.2008
RSBasic
Benutzeravatar
HeX0R
Beiträge: 3042
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win11 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 + 3
Kontaktdaten:

Beitrag von HeX0R »

A propos zuviel Mühe macht:

Hättest du Korrektur gelesen, hättest du bestimmt bemerkt, dass mit deinen Code-Tags was nicht stimmt.

Solchen Code zu lesen ist den meisten (inklusive mir) nun mal zu mühsam.
Benutzeravatar
hjbremer
Beiträge: 822
Registriert: 27.02.2006 22:30
Computerausstattung: von gestern
Wohnort: Neumünster

Beitrag von hjbremer »

Laß doch mal die Tüttel weg ! in dem bewußtem Code-Abschnitt
Purebasic 5.70 x86 5.72 X 64 - Windows 10

Der Computer hat dem menschlichen Gehirn gegenüber nur einen Vorteil: Er wird benutzt
grüße hjbremer
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Re: 2.)Daten speichern u. bearbeiten mit mehrspaltigen Tabel

Beitrag von AND51 »

Code: Alles auswählen

 Name.s        =Left(wert.s,10   )
 Vorname.s     =Mid (wert.s,11,15)
 Strasse.s     =Mid (wert.s,26,15)
 Nr.s          =Mid (wert.s,41,15)
 Postleitzahl.s=Mid (wert.s,56,15)
 Ort.s         =Mid (wert.s,71,15)
 Telefon.s     =Mid (wert.s,86,15)
 AddGadgetItem(0, -1,"Name.s"+Chr(10)+"Vorname.s"+Chr(10)+"Strasse.s"+Chr(10)+"Nr.s"+Chr(10)+"Postleitzahl.s"+Chr(10)+"Ort.s"+Chr(10)+"Telefon.s")      
Hallo,

Ich glaube, hjbremer hat es schon genannt. Musste aber selbst erst zwei Mal überlegen, was er meinte. Du musst die Anführungszeichen weglassen in der AddGadgetItem()-Zeile.
AddGadgetItem(0, -1, "Name.s") weist dein Programm an, einen String einzufügen. Du möchtest aber den Inhalt der Variable einfügen, stimmt's? Dann darfst du nur AddGadgetItem(0, -1, Name.s) schreiben. Ohne die Anführungszeichen erkennt PureBasic, dass du nicht das Wort "Name", sondern den Inhalt von "Name" einfügen willst.

Ich habe übrigens noch ein paar Tipps für dich. Ich weiß, du bist noch Anfänger, aber gerade deshalb will ich dir ein bisschen helfen, damit du vielleicht einen besseren Überblick über die PureBasic-Kapitel hast, die du als nächstes lernen kannst.
  • Warum liest du die Datei in einer For-Schleife ein? Auch wenn du vorher schon weißt, wie viele zeilen eine Datei hat, ist folgende Art immer die beste Lösung, eine Datei zeilenweise einzulesen:

    Code: Alles auswählen

    If ReadFile(1, "C:\Datei.txt")
       While Eof(1) = 0
          zeile.s=ReadString(1) ; liest automatisch eine ganze Zeile ein
         
          ; hier kann etwas mit "zeile.s" gemacht werden
         
       Wend ; Verlässt automatisch die Schleife, wenn Dateiende erreicht
       CloseFile(1)
    EndIf
    ReadString() liest automatisch eine Zeile aus einer Datei. Der Punkt ist jedoch, dass du kein extra FileSeek() brauchst! ReadString() verschiebt nämlich den Dateizeiger nach dem Auslesen einer Zeile automatisch auf den Anfang der nächsten Zeile! Der Befehl Eof() gibt genau dann 0 zurück, wenn das Ende der Datei erreicht wurde. Die While-Schleife wird also verlassen, sobald der Dateizeiger ans Ende dieser Datei kommt. Das bedeutet: Kein aufwändiges Selber-Rumpfuschen mit FileSeek().
  • Du brauchst Variablentypen nicht extra anzugeben!
    Man sieht, du definierst eine Variable, zum beispiel laenge.l. Bei der Definition einer Variable muss man den Typ ".l" angeben, ist klar. Bei allen weiteren Aufrufen dieser Variable braucht man dann aber nicht mehr ".l" schreiben! Bei weiteren Aufrufen weiß PureBasic doch bereits, von welchem Typ die Variable ist - wozu also noch einmal notieren? Schreibst du außerdem erst laenge.l und später irgendwo laenge.w, dann meckert PureBasic beim Kompilieren, dass du versehentlich durch einen Tippfehler zwei verschiedene Variablentypen benutzt.
  • Das führt uns zum nächsten Tipp: EnableExplicit benutzen! Glaub mir, ich war anfangs total dagegen. Mittlerweile mach ich's nicht mehr ohne. :mrgreen: Denn EnableExplicit passt auf, dass du nur Variablen benutzt, die du ausdrücklich (explicit = ausdrücklich, englisch) definiert hast. Denn das bewahrt dich vor haarsträubenden Situationen wie diese hier:

    Code: Alles auswählen

    joghurt=5
    Debug jogurt+1
    Nanu, warum kommt hier nicht 6 raus? "Jogurt" darf man nach der neuen Rechtschreibung auch ohne 'h' schreiben (Nein TS-Soft, keinen Flamewar an dieser Stelle!!).
    Kommt man aber durcheinander, und schreibt eine bereits benutzte Variable falsch hin, dann erstellt PureBasic aus dem zweiten, fehlerhaften Wort eine neue Variable mit dem Anfangswert 0. In der obigen Debug-Zeile soll PureBasic also "jogurt+1" rechnen. Da "jogurt" aber nicht existiert, erstellt PureBasic diese Variable neu mit dem Wert 0 und addiert 1. Ergebnis: 1 statt der gewünschten 6.
    Glaub mir, solche Fehler können dich sehr viel Zeit kosten, wenn dein Programm wegen sowas nicht richtig funktioniert. Mich hat sowas schon mal 20 Minuten gekostet, plus anschließend so viel Frust, dass ich zwei Tage kein Bock mehr auf Programmieren hatte. :lol:
    Unser obiges Programm sollte also so aussehen:

    Code: Alles auswählen

    EnableExplicit
    Define joghurt=5
    ;Debug jogurt+1  ; diese Zeile auskommentieren und PB zeigt einen Fehler an
    Debug joghurt+1  ; diese Zeile ist richtig
    Schau einfach mal in der Hilfe bei EnableExplicit nach.
  • Variablentypen außer $/.s, .f/.d und .i sind unnötig. Als Anfänger wirst du höchstens 3 verschiedene Typen brauchen: Strings, Ganzzahlen und Dezimalzahlen (Kommazahlen). Strings definierst du wunderbar mit .s oder $ hinten dran. Kommazahlen werden mit .f bzw. .d definiert (.d ist genauer als .f).

    Wenn man aber wie du mit Ganzzahlen arbeiten will, dann sind .w, .l und .b Schnee von gestern. Lass diese Endungen einfach weg! PureBasic nimmt in Version 4.20 automatisch den Datentyp .l, also Long und ab 4.30 den Datentyp .i, also Integer. Die anderen Datentypen .b und .w (Byte und Word) sind Relikte aus alten Tagen, als man noch sparsam mit Arbeitsspeicher umgehen musste. Bytes und Words verbrauchen nur 1 und 2 Byte Speicher, Longs dagegen 4 und Integer 4 bzw. 8 Byte. Heutzutage ist es schwer, nur mit Longs einen Arbeitsspeicher gänzlich zu füllen. Man hat einfach genug davon.
    Schreibe also in Zukunft anstatt laenge.l=Lof(1) lieber laenge=Lof(1) und anstatt For z.w=1 To zeilenanzahlw.w lieber For z=1 To zeilenanzahl.
    Also einfach die Endung weglassen und PB nimmt automatisch Longs. Es sei denn du benötigst so große Zahlen, dass diese nicht mehr in ein Long passen, dann musst du auf den Datentyp .q (Quad) zugreifen. Und .q musst du (nur bein Definieren einer Variable) hinschreiben.
    Übrigens: CPUs können mit Longs bzw. Integers (.l und .i) schneller rechnen, als mit .b und .w! Aber das nur am Rande.
    Noch ein Tipp: Codes und Prozeduren, die Programmeirer hier in das Forum stellen, damit andere sie nutzen können, sollten immer so geschrieben sein, dass sie mit EnableExplicit kompatibel sind. Das bedeutet: Wenn ich ein meinem Programm EnableExplicit benutze finde im Forum einen Code, den ich in meinem Programm einfüge, dann darf es keine EnableExplicit-bedingte Fehlermeldung geben. Sowas wirkt unprofessionell und halst dem jeweiligen Programmierer unnötige Zusatzarbeit auf. Also: Immer schön EnableExplicit benutzen und jede Variable mit Define, Global oder Protected definieren! Ein weiterer Vorteil ist nämlich, dass man durch diese Schlüsselwörter die Stellen, an denen Variablen definiert werden, schneller erkennt und der Code somit übersichtlicher wird.
  • Kannst du vielleicht mal ein bisschen was aus deiner Text-Datei hier posten? Man sieht, du zerlegst jede eingelesene Zeile mit Left() und Mid(). Ich vermute, dass Name, Adresse usw. durch ein Trennzeichen getrennt sind? Dann dürfe nämlich StringField() dein Freund sein! :D
    Aber um dir den besten/einfachsten/elegantesten Weg zu zeigen, wie du deine Einträge auslesen kannst, wäre es hilfreich, einige Beispieleinträge aus deiner Datei zu sehen.
Sonst fällt mir nichts mehr ein - sollte auch erstmal reichen, als Hilfestellungen und Tipps, was du dir als Anfänger am ehesten anschauen kannst. Wenn du fragen hast, kannst du dich natürlich gerne noch mal im Forum bemerkbar machen; dazu ist das Forum ja da.

Gruß, AND51
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
xcello
Beiträge: 5
Registriert: 24.11.2008 12:00

Daten speichern und bearbeiten mit mehrspaltigen Tabellen

Beitrag von xcello »

Erst mal vielen Dank an alle für die Hinweise!

Hallo AND51,

deine Tipps haben mich in PB wieder ein gutes Stück weiter gebracht :allright: und dafür bedanke ich mich noch einmal bei dir. Ich hoffe, dass ich eines Tages
auch einmal jemanden helfen kann, wenn er den Einstieg in die Programmierung mit PB sucht. Unten habe ich dir einmal meine Text-Datei gepostet,
die ich als Testdatei benutze. Die Datei habe ich in Excel 2000 angelegt und dann als Textdatei abgespeichert ( Auswahl in Excel: " gespeichert mit Text
(Tabs getrennt)).

Zur Zeit versuche ich deine Tipps zu verarbeiten und ich bin deinen Vorschlägen gefolgt und benutze jetzt den ReadFile Befehl etc. zur Bearbeitung der
Testdatei. Die For- Schleife bzw. Left() und Mid() Befehle verwende ich nicht mehr. Dafür aber den StringField() Befehl.

Klappt aber noch nicht 100% :mrgreen:, denn alle Zeilen der Testdatei werden in der Bildschirmanzeige unter die erste Spaltenüberschrift ( Name) geschrieben.
Alle Daten stehen zwar sauber untereinander, wie in der Testdatei aber unter den weiteren Überschriften ist kein Eintrag - :roll: hier muss ich noch
weiter knobeln und suchen.

Meine Testdatei:
Name Vorname Strasse Nr Plz Ort Telefon
Mueller Heinz Gasse 34 1000 Berlin 123
Krueger Fridolin Hauptweg 78 5000 Köln 456
Kross Friedhelm Sonnenweg 178 6000 Frankfurt 823



Viele Grüße

xcello
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Re: Daten speichern und bearbeiten mit mehrspaltigen Tabelle

Beitrag von AND51 »

Hallo xcello,

Kein Problem für diese Tipps. Ich gebe die ja auch gerne.

Zu deinem Problem fallen mir zwei Lösungen ein. Die eine, da helfe ich dir bei deinem StringField()-Problem. Ich zeige dir, wie du eine Zeile aus deiner Datei richtig zerlegst und diese in dein Gadget einfügst.
Die andere, die fiel mir gerade ein, als ich den Beispielcode schrieb, ist völlig simpel und genial. Die ist nur 2 Zeilen lang!

Lies aber bitte trotzdem beide, um den Sinn, wie man was technisch umsetzen kann, zu verstehen. Denn es gibt immer mehrere Wege, etwas zu erreichen. Natürlich darfst du gern meine 2-Zeilen Lösung benutzen, aber die wird dir nicht viel bringen, wenn du das Basiswissen aus Lösung 1 nicht verstehst.


Lösung 1
Wie gesagt, musst du eine Zeile aus der Datei nehmen mit ReadString() und dann die einzelnen Daten mit StringField() extrahieren (auslesen). Diese Daten habe ich der Übersicht wegen zunächst in einzelen Variablen gespeichert. Diese Variablen, getrennt mit Chr(10), setzt du einfach in AddGadgetItem() ein.
Das sollte dann so aussehen:

Code: Alles auswählen

zeiile.s="Krueger"+Chr(9)+"Fridolin"+Chr(9)+"Hauptweg"+Chr(9)+"    78	"+Chr(9)+"5000"+Chr(9)+" Köln"+Chr(9)+"	 456"

name.s     =StringField(zeile, 1, Chr(9))
vorname.s  =StringField(zeile, 2, Chr(9))
strasse.s  =StringField(zeile, 3, Chr(9))
nr.s       =StringField(zeile, 4, Chr(9))
plz.s      =StringField(zeile, 5, Chr(9))
ort.s      =StringField(zeile, 6, Chr(9))
tel.s      =StringField(zeile, 7, Chr(9))

AddGadgetItem(0, -1, name+Chr(10)+vorname+Chr(10)+strasse+Chr(10)+nr+Chr(10)+plz+Chr(10)+ort+Chr(10)+tel)
  • Beachte: Damit du diesen Code direkt aus dem Forum kopieren kannst, habe ich die Tabs durch Chr(9) ersetzt, weil beim Kopieren von einer Internetseite in den Editor Tabs durch Leerzeichen ersetzt werden.
  • Natürlich sollte man EnableExplicit benutzen. Aber bei so Codes wie diesem hier, die "nur mal eben was verdeutlichen" sollen, ist das nicht nötig. Also anpassen, wenn du den Code in dein Programm einfügst.
  • Wichtig: Man stellt fest, dass Leerzeichen die Ausgabe stören. Die Hausnummer zum Beispiel ist von Leerzeichen umgeben. Das kann verschiedene Gründe haben. Ist das schon in Excel so? Oder speichert Excel das so ab? Egal, es gibt Abhilfe, und der Befehl dazu heißt Trim(). Trim() entfernt Leerzeichen vor oder nach einem Text, aber nicht dazwischen. Es entfernt also nur führende und abschließende Leerzeichen.
    Setze also um alle StringField()-Befehle in meinem Beispielcode ein Trim(), wenn nötig.
Soweit alles klar? Oder noch Fragen dazu? Ich finde, der Code macht schon alles deutlich, aber ich weiß ja nicht, ob du als Anfänger (oder Anfängerin? :) ) das ein oder andere noch nicht verstehst. Einfach fragen!


Lösung 2 - Die Lösung mit nur 2 Zeilen
Dieser Trick ist so ein typischer Profi-Programmierer-Trick. Auf sowas kommt man, wenn man schon Erfahrung hat. Man kann solche Ideen schon beinahe als geniale Geistesblitze beschreiben. Und ich wünsche dir, dass du bald auch diese Geistesblitz-Ideen hast. :allright:

Wir sparen uns das Auftrennen des Strings mit Hilfe von StringField().

Für diese Idee fällt uns zunächst eine Gemeinsamkeit auf: Excel speichert eine Zeile mit Tab als Trennzeichen, also Chr(9). Das Gadget benötigt aber Chr(10) als Trennzeichen. Der Punkt ist, dass wir einfach alle Chr(9) durch Chr(10) ersetzen. Wir tauschen also das Excel-Trennzeichen gegen das Gadget-Trennzeichen aus.
Das ist einfach, aber genial und geht mit ReplaceString().
Das schaut dann so aus:

Code: Alles auswählen

zeiile.s="Krueger"+Chr(9)+"Fridolin"+Chr(9)+"Hauptweg"+Chr(9)+"78"+Chr(9)+"5000"+Chr(9)+"Köln"+Chr(9)+"456"

zeile=ReplaceString(zeile, Chr(9), Chr(10))   ; nur  2
AddGadgetItem(0, -1, zeile)                   ; Zeilen
Na, sieht das nicht schon mal seeeh übersichtlicher aus? Klar doch.
Bei dieser Methode darf es allerdings keine Leerzeichen wie in Lösung 1 geben. Denn hier können wir mit Trim() nichts ausrichten. Dafür ist diese Lösung aber schneller. SPrich, dein Programm arbeitet schneller. Denn anstatt eine Zeile 7x auseinander zu nehmen, und mit Chr(10) getrennt wieder an AddGadgetItem() zu übergeben; da übergeben wir den Originalstring aus der Datei einfach an das Gadget, nur, dass wir Chr(9) durch Chr(10) ersetzt haben. Sieben Schritte in einem!

Sowas finde ich immer raffiniert: Mehrere Schritte oder ganze Codepassagen durch kleinere, elegantere Codes zu ersetzen. Das grenzt schon an Kunst, würde ich sagen und ist einer der Aspekte, warum mir Programmieren so gefällt.

Aber ich schweife ab.
Damit du, xcello, auch als Anfänger/Anfängerin auf solche Geistesblitze kommst, empfehle ich dir, mit ein paar Keksen und ner Tasse Kakao die komplette PB-Hilfe durchzulesen. Einfach mal alle Befehle aus den Kapiteln Strings, Files, FileSystem, LinkedLists, Gadget, usw. durchlesen. Nicht auswendig lernen, aber durchlesen. Denn dann stellt sich bei dir der Effekt ein, dass du beim Programmieren denkst: "Halt. Da war doch ein Befehl... mit dem gehts einfacher." Das reicht schon. Und mit der Zeit fallen dir auch öfter Lösungen wie diese hier ein.

Viel Spaß. :allright:
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
xcello
Beiträge: 5
Registriert: 24.11.2008 12:00

Beitrag von xcello »

Hallo AND51,

danke noch einmal für schnelle Antwort und die letzten Tipps. Jetzt bin ich für die nächste Zeit wirklich gut versorgt und kann das Thema rund um
die File - Programmierung weiter vertiefen.

Viele Grüße
xcello
Antworten