Scanner - Eingaben

Hier könnt ihr alle Fragen zu SpiderBasic austauschen.
Benutzeravatar
H.Brill
Beiträge: 496
Registriert: 15.10.2004 17:42
Wohnort: 66557 Neunkirchen

Scanner - Eingaben

Beitrag von H.Brill »

Hallo,
Könnte irgendwer mal über meinen Code schauen ?
Wenn ich die File-Routinen reinmache, löscht es mir nicht mehr das Editfeld.
Info zum Programm :
Ich möchte ein Android-Programm schreiben, das in einer Kantine einen QR-Code
über BT-Scanner und HID-Tastatur einliest. Im QR-Code steht nur die Personalnummer
des jeweiligen Mitarbeiters. Es geht um Essenszuschlag. Da soll jeder Mitarbeiter, der
ein Essen (egal was) verzehrt, einen Essenszuschlag bekommen. Das gilt aber nur für ein
Essen pro Tag. Damit man sich nicht zweimal eintragen kann, wird geprüft, ob Personalnr
und Datum (heutiger Tag) schon in der Datei vorhanden ist. Wenn ja, hat er schon gescannt
und gegessen, wenn nicht wird er in die Liste (Datei) eingetragen. Auch soll jeden Monat
eine neue Datei angelegt werden, damit die alte von der Lohnbuchhaltung ausgewertet
werden kann. Existiert noch keine Datei, soll eine neue, leere Datei angelegt werden.
Das ist der Fall beim Erststart und jeden neuen Monat.

Das Scannen an sich funktioniert und den Scanner habe ich auf ein Endezeichen (RETURN)
eingestellt.

Code: Alles auswählen

Datei$ = FormatDate("%mm_%yyyy", Date()) + ".txt"  ; z.B. 07_2023 für Juli 2023
gefunden.i = 0
MA_nr$ = ""
Datum$ = ""
zeile$ = ""

Procedure CreateCallback(Status, Filename$, File, SizeRead)
    Select Status
      Case #PB_Status_Saved
        ; File correctly saved
        
      Case #PB_Status_Error
        ; File saving has failed
    EndSelect
  EndProcedure

Procedure ReadCallback(Status, Filename$, File, Size)
  If Status = #PB_Status_Loaded
      gefunden = 0
      While Eof(0) = 0
        zeile$ = ReadString(0)            
        If (StringField(zeile$, 1, ",") = Datum$) And (StringField(zeile$, 2, ",") = MA_nr$)
          gefunden = 1
        EndIf  
      Wend
      
      CloseFile(0)
      
    ElseIf Status = #PB_Status_Error
      Debug "Error when loading the file: " + Filename$
    EndIf
  EndProcedure

Procedure MenuEvents()
  If EventMenu() = 15
     Datum$ = FormatDate("%dd.%mm.%yyyy", Date())
     MA_nr$ = GetGadgetText(1)
     ; hier prüfen, ob MA_nr + aktuelles Datum in Datei
     ; wenn nicht vorhanden, reinschreiben 
     
     If OpenFile(0, Datei$, @ReadCallback(), #PB_LocalFile)
        If gefunden < 1
           WriteStringN(0, Datum$ + "," + MA_nr$)
           CloseFile(0) 
        EndIf   
     Else
       If CreateFile(0, Datei$, @CreateCallback())
         ; leere Datei
         ExportFile(0, "text/plain", #PB_LocalFile)
         CloseFile(0)  
       EndIf 
     EndIf  
     SetGadgetText(1, "") ; Editfeld leeren für neuen Scan
     SetActiveGadget(1)   ; Fokus auf Editfeld setzen
 EndIf  
EndProcedure

If OpenWindow(0, 0, 0, 322, 205, "QR-Code Scanner", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  StringGadget(1, 8,  10, 306, 20, "")
  AddKeyboardShortcut(0, #PB_Shortcut_Return, 15)
  BindEvent(#PB_Event_Menu, @MenuEvents())
  SetActiveGadget(1)
EndIf

Zum Probieren müßte ja auch ein ENTER im Editfeld passen.
PS: Wie behandelt SpiderBasic denn die Schreibrechte von Dateien ?
Android ist da ja mittlerweile recht restriktiv geworden.
Ich muß ja auch später wissen, wo die Datei gespeichert ist, damit man sie
per BT verschicken und weiter verarbeiten kann.
PB 6.10
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Scanner - Eingaben

Beitrag von Kiffi »

Du kannst aus Sicherheitsgründen OpenFile() mit dem Flag #PB_LocalFile nicht aufrufen, ohne zuvor ein OpenFileRequester() ausgeführt zu haben.
a²+b²=mc²
Benutzeravatar
H.Brill
Beiträge: 496
Registriert: 15.10.2004 17:42
Wohnort: 66557 Neunkirchen

Re: Scanner - Eingaben

Beitrag von H.Brill »

OpenfileRequester brauche ich nicht, da die App autark laufen soll,
also ohne Eingriff des Küchenpersonals.
Das Smartphone mit so nem 10000mA Akkulader wird einmal über
BT mit dem Scanner verbunden und die App gestartet.
Deshalb wird ja auch das RETURN in dem Editfeld abgefragt, das dann
ähnlich eines Buttons reagiert.

Dann muß ich es wohl doch in B4A machen. Da geht das, wenn man
die Schreibrechte der Ordner beachtet. Wäre mit SpiderBasic etwas
einfacher gewesen.
PB 6.10
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Scanner - Eingaben

Beitrag von Kiffi »

Alternativ könntest Du mein Preferences-Modul verwenden, welches den LocalStorage verwendet.
Von der Bedienung her funktioniert es genauso wie die Preferences Lib von PureBasic.
a²+b²=mc²
Benutzeravatar
H.Brill
Beiträge: 496
Registriert: 15.10.2004 17:42
Wohnort: 66557 Neunkirchen

Re: Scanner - Eingaben

Beitrag von H.Brill »

Kiffi hat geschrieben: 21.07.2023 08:34 Alternativ könntest Du mein Preferences-Modul verwenden, welches den LocalStorage verwendet.
Von der Bedienung her funktioniert es genauso wie die Preferences Lib von PureBasic.
Das muß ich mir mal ansehen. Muß mal schauen, was und wie man so ein Modul einbindet, bzw. was ich
vom Downloadlink alles brauche. Habe mit Modulen noch nie gearbeitet.
Im Prinzip wäre es ja das richtige. Der key$ ist die Personalnr und der Wert ist das Datum. Also ähnlich
wie bei einem Hash, der in eine Art Ini-Datei gespeichert wird.

LocalStorage : Wo muß ich da z.B. mit dem MyPhoneExplorer suchen, um die Datei per BT an den PC zu schicken ?
PB 6.10
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Scanner - Eingaben

Beitrag von Kiffi »

H.Brill hat geschrieben: 21.07.2023 10:02Hättest du ein Beispielcode für mich ?
schau mal in die PreferencesDemo.sb. Wie geschrieben: Prinzipiel wird das Modul genauso verwendet, wie die Preferences Lib von PureBasic.

H.Brill hat geschrieben: 21.07.2023 10:02LocalStorage : Wo muß ich da z.B. mit dem MyPhoneExplorer suchen, um die Datei per BT an den PC zu schicken ?
der LocalStorage ist eine Art interner Speicher einer SpiderBasic-App. Du wirst von "ausserhalb" wohl nicht darauf zugreifen können.

Allerdings kannst Du die Daten ja auch via HTTPRequest() direkt von SpiderBasic aus an den Zielrechner senden.
a²+b²=mc²
Benutzeravatar
H.Brill
Beiträge: 496
Registriert: 15.10.2004 17:42
Wohnort: 66557 Neunkirchen

Re: Scanner - Eingaben

Beitrag von H.Brill »

Da müßte ich mal sehen. Ich muß die Daten ja als .csv-Datei aufbereiten (PersonalNr;Datum)
Schade, daß SpiderBasic noch kein Bluetooth unterstützt.
Aber erstmal schaue ich, wie das mit den Preferences klappt.
Danke.
PB 6.10
Benutzeravatar
H.Brill
Beiträge: 496
Registriert: 15.10.2004 17:42
Wohnort: 66557 Neunkirchen

Re: Scanner - Eingaben

Beitrag von H.Brill »

Schau mal :

Code: Alles auswählen

Procedure MenuEvents()
  If EventMenu() = 15
     Datum$ = FormatDate("%dd.%mm.%yyyy", Date())
     MA_nr$ = GetGadgetText(1)
     ; hier prüfen, ob MA_nr + aktuelles Datum in Datei
     ; wenn nicht vorhanden, reinschreiben 
     gefunden = 0
     If OpenPreferences("Personen.prefs")
       PreferenceGroup("Personal")
       ExaminePreferenceKeys()
       While  NextPreferenceKey() ; While a key exists
         If (PreferenceKeyName() = MA_Nr$) And (PreferenceKeyValue() = Datum$)
           gefunden = 1
           Debug "Schon vorhanden"
         EndIf
       Wend
       If gefunden < 1
          WritePreferenceString(MA_Nr$, Datum$)
       EndIf 
       ClosePreferences()
     Else
       If CreatePreferences("Personen.prefs")
         PreferenceGroup("Personal")
         WritePreferenceString(MA_Nr$, Datum$)
         ClosePreferences()
       EndIf  
     EndIf  
     SetGadgetText(1, "") ; Editfeld leeren für neuen Scan
     SetActiveGadget(1)   ; Fokus auf Editfeld setzen
 EndIf  
EndProcedure
Müßte eigentlich so funktionieren.
Braucht man denn unbedingt eine PreferenceGroup oder funktioniert das auch ohne.
Ich hätte ja nur eine Gruppe.
PB 6.10
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Scanner - Eingaben

Beitrag von Kiffi »

Wenn ich das richtig verstanden habe, möchtest Du lediglich testen, ob der Mitarbeiter heute schon gegessen und somit den Essenszuschlag bekommen hat.

Wenn dem so ist, dann könnte man den Code vereinfachen:

Code: Alles auswählen

Procedure MenuEvents()
  
  Protected Heute$
  Protected MitarbeiterNummer$
  Protected GefundenesDatum$
  Protected Gefunden
  
  If EventMenu() = 15
    
    Heute$ = FormatDate("%dd.%mm.%yyyy", Date())
    MitarbeiterNummer$ = GetGadgetText(1)
    
    OpenPreferences("Personen.prefs")
    
    GefundenesDatum$ = ReadPreferenceString(MitarbeiterNummer$, "")
    
    If GefundenesDatum$ = Heute$
      Gefunden = 1
    Else
      WritePreferenceString(MitarbeiterNummer$, Heute$)
    EndIf
    
    ClosePreferences()
    
    SetGadgetText(1, "") ; Editfeld leeren für neuen Scan
    SetActiveGadget(1)   ; Fokus auf Editfeld setzen
    
    If Gefunden = 1
      Debug "Mitarbeiter hat heute bereits den Essenszuschlag bekommen"
    Else
      Debug "Mitarbeiter hat heute noch keinen Essenszuschlag bekommen"
    EndIf
        
  EndIf  
  
EndProcedure
(ich habe für meine Zwecke die Variablen mal umbenannt)
a²+b²=mc²
Benutzeravatar
H.Brill
Beiträge: 496
Registriert: 15.10.2004 17:42
Wohnort: 66557 Neunkirchen

Re: Scanner - Eingaben

Beitrag von H.Brill »

Habe meinen obigen Code im Browser getestet. Das läuft soweit.
Den Essenszuschlag bekommt er ja erst am Monatsende. Es soll nur festgestellt werden,
ob er heute schon eingescannt hat und somit auch ein Essen bekommen hat. Sonst kommen
ja besonders pfiffige Leute auf die Idee, noch einmal am selben Tag zu scannen um somit
nochmals in die Liste/Datei eingetragen werden. Es gibt aber nur einmal Zuschuß pro Tag.
Aufgrund der Personalnr und dem Datum jedes einzelnen Tages wird wird dann später die
Anzahl der gescannten einzelnen Personalnr als Multiplikator für den Zuschlag (3 €) genommen.
Wenn er also 20 mal jeweils an einem anderen Tag gescannt hat, stehen ihm 60 € zu.
Deshalb ist ja auch das Datum wichtig.
Da sollte folgendes in der Datei stehen :
Personalnr., Datum
4711,05.07.2023
4712,05.07.2023
4711,12.07.2023
4712,12.07.2023
4711,16.07.2023
4711,18.07.2023
4712,18.07.2023
usw.
Hier sind es nur 2 Personalnummern als Beispiel. Aufgrund der Häufigkeit von Personalnr. 4711, kann ich errechnen, daß
er 4 mal essen war und 4712 nur 3 mal.
Mein Programm habe ich nochmals mit einem Button und einem ListIconGadget erweitert. Da kann ich am Monatsende
mir schonmal eine Liste anzeigen lassen.

PS: Was bedeutet "App build failed" ? wenn ich Create App starte, bricht er bei 50% ab. Wonach soll ich suchen ?
Das JDK ist bei den Preferences mit Pfad angegeben. Es bricht halt ohne genauere Fehlermeldung ab.
Oder soll ich mal die neuste Version von Spiderbasic laden ? Ich habe noch die 2.21, da ich jetzt länger nichts
damit gemacht hatte.



Gibt es vllt. bei Android was ähnliches wie das Clipboard ?
Wäre ja auch ein Weg, die Daten als Block ins Clipboard zu schieben und dann in einem Standard-Editor
einzufügen. Der hat mehr Möglichkeiten zum Speichern. Dann halt mit BT senden.

Und noch was :
Muß der Key$ einzigartig sein ? Sonst würde er ja den vorhanden überschreiben, richtig ?
die 4711 mit dem Wert 05.07.2023 würde ja am nächsten Tag mit 4711, 06.07.2023 überschrieben werden
und der 05.07.2023 wäre verloren. Dann muß ich mir was anderes überlegen. Ist das bei PreferenceGroup
auch übergreifend ? Da wäre zu überlegen, für jeden Tag (1-31) ein Gruppe anzulegen und darin die täglichen
Scanns speichern. Die Gruppennummer (1-31) ist ja leicht aus dem jeweiligen Tagesdatum zu ermitteln.
Oder die Personalnr jeweils als Gruppe und die Tage als Key und Wert = 1/0 für die Essensnahme.

Vielleicht hast du ja noch eine Idee.
PB 6.10
Antworten