|
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
bobby85cr
Anmeldungsdatum: 17.12.2021 Beiträge: 4 Wohnort: JN59AD
|
Verfasst am: 18.12.2021, 02:52 Titel: Schleife ausführen ähnlich "dir /p" |
|
|
Guten Abend zusammen,
leider fällt mir keine richtige Bezeichnung für den Titel ein, warum ich wohl auch bei meinen Recherchen nichts gefunden habe.
Kurz zum Hintergrund:
Ich möchte mir für mich in QB eine kleine Wirtschaftssimulation programmieren. Im wesentlichen sollen per Zufallsgeneratoren Bestellungen ausgelöst werden in denen Kundendatenbanken und Produktlisten miteinander verknüpft werden.
Warum QB? Habe noch 386er und 486er Kisten worauf das nach Lust und Laune laufen soll und ich weder Assembler noch Fortran beherrsche. Turbopascal 5 hätte ich auch noch von der Schule, aber da würde ich nichtmal mehr ein "Hallo Welt" hinbekommen. Dafür einen fbas-Compiler. Achso, Microschrott Basic 4.5 ist zur Not auch noch als 3,5" Floppy vorhanden und auf einem PCD-4ND installiert.
Die Datenbanken habe ich mit sequentiellen Dateien realisiert, funktioniert soweit auch alles, für meine Zwecke ausreichend.
Das jetzt detailliert zu beschreiben würde den Rahmen sprengen. Kann aber bei Fragen gerne näheres erläutern.
Nun zu meiner Frage bzw. Hauptproblem:
Ich möchte mir eine Liste anzeigen lassen, z.B. die Kundendatei in einer Übersicht, in der nur Kundennummer und Firmenname stehen.
Als Bsp. meine Kundendatei hat 50 Einträge, sprich EOF = 50 in eine Variable (z%) speichern kein Problem.
Da ich Kopf und Fußzeile habe (mit locate 1,1 und locate 23,1) , möchte ich pro "Tastendruck" 15 Zeilen dargestellt haben.
Also setze ich z.B.
kundendatei = freefile
listenanfang% = 1
listenende% = 15
z% = 50
Dann habe ich eine Schleife zur Anzeige der ersten 15 Einträge, die Funktioniert auch (das Datei-Gedöns habe ich einfachheit halber jetzt weggelassen):
zeile% = 1
for i% = listenanfang% to listenende%
input #kundendatei, kundennummer%, firmenname$, usw
locate zeile%, 1 : print "Kundennummer: "
locate zeile%, 15 : print kundennummer%
locate zeile%, 30 : print "Firma: "
locate zeile%, 37 : firmenname$
zeile% = zeile% + 1
next i%
zeile% = 1
Die locate-Befehle dienen der Formatierung, primitiv, aber reicht für meinen Zweck.
Woran ich nun verzweifle ist, dass mit beliebiger Taste die nächsten 15 Einträge angezeigt werden bis EOF erreicht wird.
Also ähnlich wie "dir /p".
In meinem Beispiel müsste ich einmal eine Taste drücken, dann kommt Zeile 16 bis 30, dann 31 bis 45 und 46 bis 50.
Ich hoffe da kann mir jemand weiterhelfen, da ich nicht dahinter komme wie die Berechnung von listenanfang% und listenende% bis z% anstellen soll und die entsprechende Schleife aussehen muss.
Um meine ganze "Bildschirmformatierung" zu erhalten ist Einsatz von VIEW PRINT vermutlich unerlässlich, aber hier gehts erstmal um die entsprechende Schleife.
Die Formatierung bekomme ich dann schon hin.
Und natürlich lautet der erste Befel CLS und der zweite COLOR 2, da ich leider keinen Olympia BOSS habe. _________________ 73, de DO3IGN |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4594 Wohnort: ~/
|
Verfasst am: 18.12.2021, 09:13 Titel: |
|
|
Vielleicht etwas in der Art (nur ein Denkgerüst, nicht getestet):
Code: | listenanfang% = 1
listenlaenge% = 15 ' Länge statt Ende, dann muss nur eine Variable aktualisiert werden
do
for i% = listenanfang% to listenanfang% + listenlaenge% - 1
' Hier deine Schleife zum Anzeigen der entsprechenden Einträge
next i%
a$ = input$(1)
listenanfang% = listenanfang% + listenlaenge% ' "weiterblättern"
loop until listenanfang% > z% |
In der FOR-Schleife solltest du dann aber noch abfangen, dass bei i% > z% keine Daten mehr abgefragt und ausgegeben werden.
Nach dem a$ = input$(1) kannst du dann außerdem, abhängig von der gedrückten Taste, entscheiden, ob weiter- oder zurückgeblättert wird oder ob die Ausgabe abgebrochen werden soll - was man halt möglicherweise sonst noch so an Optionen braucht. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1208 Wohnort: Ruhrpott
|
Verfasst am: 18.12.2021, 16:27 Titel: |
|
|
Hallo bobby85cr und willkommen im Forum.
nemoreds Ansatz ist soweit ganz gut, allerdings würden bei dieser Abbruchbedingung die letzten Zeilen der Datei "verschluckt", sofern die Länge nicht ein Vielfaches von 15 ist.
Code: | listenanfang% = 1
listenlaenge% = 15 ' Länge statt Ende, dann muss nur eine Variable aktualisiert werden
Do
Cls
zeile% = 1
For i% = listenanfang% To listenanfang% + listenlaenge% - 1
Input #kundendatei, kundennummer%, firmenname$, usw
Locate zeile%, 1 : Print "Kundennummer: "
Locate zeile%, 15 : Print kundennummer%
Locate zeile%, 30 : Print "Firma: "
Locate zeile%, 37 : firmenname$
zeile% = zeile% + 1
If Eof(#kundendatei) Then 'Abbruch beim Erreichen des Dateiendes
Exit Do
EndIf
Next i%
listenanfang% = listenanfang% + listenlaenge% ' "weiterblättern"
Sleep 'warten auf Tastendruck
Loop
Sleep |
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4594 Wohnort: ~/
|
Verfasst am: 18.12.2021, 16:47 Titel: |
|
|
grindstone hat Folgendes geschrieben: | nemoreds Ansatz ist soweit ganz gut, allerdings würden bei dieser Abbruchbedingung die letzten Zeilen der Datei "verschluckt", sofern die Länge nicht ein Vielfaches von 15 ist. |
Ich bin mir gerade nicht sicher, warum das so sein sollte, aber vielleicht bin ich auch nur zu müde. Ich breche doch erst ab, wenn der neue Anfang jenseits der verfügbaren Einträge liegen würde?
Das Problem bei meinem (unmodifizierten) Ansatz sollte vielmehr darin liegen, dass bei einer Länge, die kein Vielfaches von 15 ist, über das Dateiende hinaus gelesen würde. Aber vielleicht habe ich auch gerade einen Denkknoten. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
bobby85cr
Anmeldungsdatum: 17.12.2021 Beiträge: 4 Wohnort: JN59AD
|
Verfasst am: 19.12.2021, 14:58 Titel: |
|
|
Hallo nemored, hallo grindstone,
erstmal vielen Dank für Eure Antworten.
Der Einwand von grindstone ist schon berechtigt.
1. Durchlauf 1-15, 15 < 50, also führe Schleife aus
2. Durchlauf 16-30, 30 < 50, also führe Schleife aus
3. Durchlauf 31-45, 45 < 50, also führe Schleife aus
4. Durchlauf 46-60, 60 > 50 also breche Schleife ab
Soweit ware ich auch schon.
Die Idee mit zurückblättern ist auch gut. Mal sehen ob ich das hinbekomme
Ich weiss nur nicht, wie ich im 4. Durchlauf die "Restlänge" berechne.
Mathematisch würde ich so vorgehen, berechne wie oft "länge" in EOF geht, in meinm Bsp. 3x.
Was meinen Horizont aber gerade übersteigt, ist wie das programmiere, so das der Rest übernommen wird und in der letzten Schleifenausfürung addiert wird.
Also so in der Art:
50(EOF) : 15 (listenlänge) = 3,3333
schneide Nachkommastellen ab = 3 Durchläufe
3 Durchläufe x 15 (listenlänge) = 45 (Zwischensumme)
50 (EOF) - 45 (Zwischensumme) = 5 (Restwert)
führe Schleife 3x aus, dann addiere Restwert.
So hatte ich das mal versucht und zur Kontrolle nach jedem Schritt mir mit Print und sleep die Variablen anzeigen lassen, damit ich sehe was er tut, aber da kamen ganz diffuse Werte heraus.
Gruß
Robert _________________ 73, de DO3IGN |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4594 Wohnort: ~/
|
Verfasst am: 19.12.2021, 15:11 Titel: |
|
|
Die Restlänge lässt sich einfach berechnen durch
Code: | restlaenge% = z% mod listenlaenge% |
Die brauchst du aber gar nicht. Prüfe einfach während des Durchlaufs der FOR-Schleife, ob der aktuelle Index i% bereits größer ist als z% und breche in diesem Fall die Schleife ab (siehe Beispiel von grindstone). _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
bobby85cr
Anmeldungsdatum: 17.12.2021 Beiträge: 4 Wohnort: JN59AD
|
Verfasst am: 19.12.2021, 18:15 Titel: |
|
|
Halle nemored,
Dein Hinweis mit dem "mod" war meine Lösung.
Jetzt funktionierts.
Das blättern habe ich nocht nicht eingebaut, das kommt dann in der nächsten Version.
Anbei der vollständige Code des SUBs
(KDS = KundenDatenSatz)
hos$ = Laufwerk, kunden$ = Verzeichnis mit den Kundendaten, werden aus einer ini gelesen
liste5% = Behelfsvariable
Der Code enthält noch einige Zeilen für debugging (also PRINT %variable%), damit ich kontrollieren kann wann welche Variable wie verändert wird.
Code: |
kdsliste:
CLS
COLOR 2
kfile = FREEFILE
zzkd = FREEFILE
z% = 0
OPEN host$ + kunden$ + "kds.dat" FOR INPUT AS #zzkd
DO
LINE INPUT #zzkd, tmpkd$
z% = z% + 1
LOOP UNTIL EOF(zzkd)
CLOSE #zzkd
liste1% = 1
IF z% > 15 THEN
liste2% = 15
ELSEIF z% < 15 THEN
liste2% = z%
END IF
PRINT z%, "Datensätze gespeichert"
durchlaeufe% = z% / 15
durchlaeufe% = durchlaeufe% + 1
rest% = z% MOD 15
PRINT "Durchläufe: ", durchlaeufe%
PRINT "Rest: ", rest%
SLEEP 2
OPEN host$ + kunden$ + "kds.dat" FOR INPUT AS #kfile
listenschleife:
FOR j% = 1 TO durchlaeufe%
zeil1% = 3
CLS
COLOR 2
LOCATE 1, 1: COLOR 0, 2: PRINT "Wirtschaftssimulation Version 1.1": COLOR 2, 0
LOCATE 23, 1: COLOR 0, 2: PRINT " ": COLOR 2, 0
FOR i% = liste1% TO liste2%
INPUT #kfile, kn$, bezkd$, firma$, anrkd$, vnkd$, nnkd$, strkd$, plzkd$, ortkd$, bulakd$, telkd$, faxkd$, emailkd$
COLOR 0, 2
LOCATE zeil1%, 1: PRINT "Kundennummer: "
LOCATE zeil1%, 15: PRINT kn$;
COLOR 2, 0
LOCATE zeil1%, 30: PRINT "Firma: "
LOCATE zeil1%, 37: PRINT firma$
zeil1% = zeil1% + 1
NEXT i%
SLEEP
CLS
COLOR 2
PRINT "Kontrolle nach Durchlauf ", j%
PRINT "Rest: ", rest%
liste5% = liste2% + 15
IF liste5% < z% THEN
liste1% = liste1% + 15
liste2% = liste2% + 15
ELSEIF liste5% > z% THEN
liste1% = liste1% + 15
liste2% = liste2% + rest%
END IF
PRINT
PRINT "liste1: ", liste1%
PRINT "liste2: ", liste2%
PRINT "liste5: ", liste5%
PRINT "z: ", z%
PRINT "rest: ", rest%
SLEEP
NEXT j%
CLOSE #kfile
GOTO kundenmenu
|
Mag zwar nicht elegant sein und noch optimierungsfähig, aber ich will ja keine tausende Datensätze speichern, sondern nur ein kleines Spiel erstellen.
@grindstone:
Habe Deinen Code natürlich vorher ausprobiert, aber gleich in der ersten Schleife ging nix mehr, außer reset.
Vielen Dank für Eure Beiträge,
schöne Weihnachten,
73, Robert _________________ 73, de DO3IGN |
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1208 Wohnort: Ruhrpott
|
Verfasst am: 19.12.2021, 19:15 Titel: |
|
|
Zurückblättern macht die Sache ein weinig komplizierter, weil die Dateien nicht rückwärts gelesen werden können. Ich habe das seinerzeit so gemacht, daß ich ein Array mit den Zeigern auf die einzelnen Datensätze angelegt habe, dann konnte ich mit SEEK gezielt darauf zugreifen. Da QB kein PRESERVE kennt, muß zuerst einmal die erforderliche Größe des Arrays ermittelt werden. Code: | datei% = FreeFile
zaehler% = 0
Open "kundendatei.dat" For Input As #datei%
Do 'anzahl der datensätze ermitteln
zaehler% = zaehler% + 1
Input #datei%, kundennummer%, firmenname$
Loop Until Eof(datei%)
ReDim dateizeiger%(zaehler%) 'ausreichend großes array anlegen
Seek datei%, 1 'dateizeiger auf anfang der datei zurücksetzen
For zaehler% = 1 To UBound(dateizeiger%) 'zeiger auf datensätze ermitteln und in array schreiben
dateizeiger%(zaehler%) = Seek(datei%) 'aktuellen zeiger in array schreiben
Input #datei%, kundennummer%, firmenname$ 'zeiger auf nächsten datensatz
Next
Close datei%
datei% = FreeFile
Open "kundendatei.dat" For Input As #datei%
zaehler% = 1
Do
Select Case InKey$
Case "+"
If zaehler% < UBound(dateizeiger%) Then
zaehler% = zaehler% + 1
Seek datei%, dateizeiger%(zaehler%)
Input #datei%, kundennummer%, firmenname$
Print zaehler%; Seek(datei%), kundennummer%, firmenname$
EndIf
Case "-"
If zaehler% > 1 Then
zaehler% = zaehler% - 1
Seek datei%, dateizeiger%(zaehler%)
Input #datei%, kundennummer%, firmenname$
Print zaehler%; Seek(datei%), kundennummer%, firmenname$
EndIf
Case Chr$(27) 'Esc
Exit Do
End Select
Loop | Vor- und zurückblättern mit "+" und "-", beenden mit "Esc".
bobby85cr hat Folgendes geschrieben: | @grindstone:
Habe Deinen Code natürlich vorher ausprobiert, aber gleich in der ersten Schleife ging nix mehr, außer reset. | Das liegt an dem "usw" am Ende der INPUT - Zeile. Du mußt die Zeile so abändern, daß jedesmal exakt ein Datensatz ausgelesen wird, sonst kommt das Ganze aus dem Tritt. Das gilt auch für den Programmschnippsel oben.
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
|
bobby85cr
Anmeldungsdatum: 17.12.2021 Beiträge: 4 Wohnort: JN59AD
|
Verfasst am: 19.12.2021, 23:18 Titel: |
|
|
Hallo grindstone,
nee, ich habe den Code schon richtig portiert.
Hab das manuell eingehackt auf einem anderen Rechner. Sei's drum, jetzt geht's ja.
Deine Erweiterung für das Blättern werde ich im Laufe der Woche testen. Vielen Dank schonmal für die Anregungen und den Code.
Habe noch nie mit arrays gearbeitet, hatte bisher noch keine Verwendung dafür.
Kann sein, dass ich mich auch erst übernächste Woche wieder melde, da ich nächste Woche volles Programm habe.
Arbeitsmäßig, sowie auch im privaten. Also nicht wundern, wenn ich mich ein paar Tage nicht melde.
Falls man sich vorher nicht mehr "hört" frohe Weihnachten.
73 und 55, Robert _________________ 73, de DO3IGN |
|
Nach oben |
|
|
HorstD
Anmeldungsdatum: 01.11.2007 Beiträge: 107
|
Verfasst am: 20.12.2021, 11:45 Titel: |
|
|
Zitat: | Um meine ganze "Bildschirmformatierung" zu erhalten ist Einsatz von VIEW PRINT vermutlich unerlässlich, |
Es reicht, wenn du nach jedem Print ein ';' anfügst, dann erfolgt kein Zeilenvorschub. Setzt 'Locate' vor 'Print' voraus.
Code: |
LOCATE 1, 1: COLOR 0, 2: PRINT "Wirtschaftssimulation Version 1.1"; : COLOR 2, 0
LOCATE 23, 1: COLOR 0, 2: PRINT " "; : COLOR 2, 0
FOR i% = liste1% TO liste2%
INPUT #kfile, kn$, bezkd$, firma$, anrkd$, vnkd$, nnkd$, strkd$, plzkd$, ortkd$, bulakd$, telkd$, faxkd$, emailkd$
COLOR 0, 2
LOCATE zeil1%, 1: PRINT "Kundennummer: ";
LOCATE zeil1%, 15: PRINT kn$;
COLOR 2, 0
LOCATE zeil1%, 30: PRINT "Firma: ";
LOCATE zeil1%, 37: PRINT firma$;
zeil1% = zeil1% + 1 |
|
|
Nach oben |
|
|
SpionAtom
Anmeldungsdatum: 10.01.2005 Beiträge: 338
|
Verfasst am: 21.12.2021, 12:17 Titel: |
|
|
Kleiner Tipp für tabellarische Anordnungen: PRINT USING
Code: | CLS
READ datensaetze%
FOR i% = 1 TO datensaetze%
READ nr%, firma$, anrede$, vname$, nname$, strasse$, plz$, ort$
LOCATE i%, 1
PRINT USING "## \ \ \ \ \ \ \ \ \ \ \ \ \ \"; nr%; firma$; anrede$; vname$; nname$; strasse$; plz$; ort$
NEXT
DATA 3
DATA 1, "Microschrott", "Herr", "Bill", "Gates", "Wall Street 23", "12345", "New York"
DATA 2, "Jahoo", "Frau", "Marissa", "Mayer", "Test Avenue 11", "54321", "Palo Alto"
DATA 3, "M„rchenbuch", "Gebr", "Jacob + Wilhelm", "Grimm", "Schwarzwald 1", "22334", "Hinter den Sieben Bergen"
|
https://www.qbasic.net/en/reference/qb11/Statement/PRINT-USING.htm _________________ Inzwischen gehöre ich auch zu den BlitzBasicern. Also verzeiht mir, wenn mir mal ein LOCATE 100, 100 oder dergleichen rausrutscht. |
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|