Data

Dieses Thema enthält 12 Antworten und 2 Teilnehmer. Es wurde zuletzt aktualisiert von  Klaus Major vor 3 Monate.

  • Autor
    Beiträge
  • #14863

    Herby
    Teilnehmer

    Hallo zusammen,

    ich habe da noch ein Problem, für das ich derzeit eine Lösung suche.
    Ich würde gerne in einem DataGrid an verschiedene Stellen springen und es entsprechend anzeigen.
    Ich lade mit folgendem Programmcode das DataGrid und sortiere es alphabetisch :

     set the itemDelimiter to tab
       put revOpenDatabase("sqlite",xpfd, , , , ) into xsql
       repeat with x = 1 to xdsg -- Anzahl der Datensätze
          put "SELECT Begriff, Beschreibung, ID FROM DBMedizin WHERE ID = " &x into xsel
          put revDataFromQuery(tab,return,xsql,xsel) into xerg
          put textDecode(xerg,"UTF-8") into xerg  -- Umlaute umwandeln
          put item 1 of xerg after xxx
          put tab after xxx
          put item 2 of xerg after xxx
          put tab after xxx
          put item 3 of xerg after xxx
          put return after xxx
       end repeat
       revCloseDatabase xsql
       set the dgtext of group "DataM" to xxx
       dispatch "SortDataByKey" to grp "DataM" with "medizin","international","ascending","false"
      
    

    Da bei ca. 2550 Datensätze der Anwender lange braucht um von A (z.B.) nach K zu scrollen, würde ich gerne das Alphabet zum Anklicken am Rande anzeigen, damit er einfach "K" anklicken kann und das DataGrid mit "K" weitermacht. Ich könnte natürlich auch das DataGrid einfach mit allen K-Begriffen laden, aber ich möchte gerne A-Z im DataGrid haben und zwischen den Buchstaben hin- und herspringen. (ohne neu zu laden)

    Danke und Grüße aus Bayern
    herby

  • #14865

    Klaus Major
    Moderator

    Hi Herby,

    OHA! Wer keine Arbeit hat, macht sich welche! 😎

    Ich nehme mal an Dein erste Spalte im Datagrid heisst "Begriff" ("medizin"? Einheitliche Namensgebung HAT schon seine Vorteile! 😉 )

    Hier ein paar grundlegende Datanbankfakten:

    repeat with x = 1 to xdsg -- Anzahl der Datensätze
      put "SELECT Begriff, Beschreibung, ID FROM DBMedizin WHERE ID = " &x into xsel

    Wenn Du ALLE Datensätze haben willst, lass einfach das WHERE... weg!
    Ja, ich weiß, aber lies erst den nächsten Absatz 🙂
    put revDataFromQuery(tab,return,xsql,xsel) into xerg
    Offensichtlich ist Dir die Bedeutung der beiden ersten Parameter TAB, CR nicht bekannt, bitte immer mal im Dictionary nachlesen für weitergehende Infos!

    Sie bedeuten: Liefer mir die gewünschten Daten im folgenden Format:
    Inhalt der Datenbankfelder per TAB getrennt, ein Datensatz PRO ZEILE (= per CR getrennt)

    Also Das hier macht genau das, was Du umständlich geskriptet hast, allerdings ohne die leere Zeile am Ende:

    ...
    put revOpenDatabase("sqlite",xpfd, , , , ) into xsql
    put "SELECT Begriff, Beschreibung, ID FROM DBMedizin" into xsel
    put revDataFromQuery(tab,return,xsql,xsel) into xerg
    put textDecode(xerg,"UTF-8") into xerg 
    revCloseDatabase xsql
    set the dgtext of group "DataM" to xerg
    ...

    Du kannst auch die Datenbank selber sortieren lassen, die ist schneller als LC:
    put "SELECT Begriff, Beschreibung, ID FROM DBMedizin ORDER BY Begriff" into xsel

    Da bei ca. 2550 Datensätze der Anwender lange braucht um von A (z.B.) nach K zu scrollen, würde ich gerne das Alphabet zum Anklicken am Rande anzeigen, damit er einfach "K" anklicken kann und das DataGrid mit "K" weitermacht. Ich könnte natürlich auch das DataGrid einfach mit allen K-Begriffen laden, aber ich möchte gerne A-Z im DataGrid haben und zwischen den Buchstaben hin- und herspringen. (ohne neu zu laden)

    Der Zugriff auf lokale SQLite Datenbanken ist affenartig schnell, daher würde ich dennoch zu Letzterem raten!

    Bedenke, Dein Skript macht mehr als 2500 Datenbankabfragen und Du bearbeitst auch noch jedes Ergebnis! Du kannst ja mal Dein Skript gegen meines "timen".

    Ich empfehle, daß Du zuerst alles mit A lädst und eine Funktion oder Handler erstellst, der Dir die Daten mit den gewünschten Anfgangsbuchstaben liefert. Das wird schneller sein, als die gewüsnchte Zeile zu suchen und dahin zu scrollen!
    Sowas hier vielleicht:

    ## Über gib den gewünschten Anfangsbuchstaben oder * für ALLE datensätze
    ## Das SQL Zauberwort hierfür heisst -> LIKE
    command datensaetze_die_beginnen_mit demBuchstaben
    
       ## SQL für ALLE Datensätze
       put "SELECT Begriff, Beschreibung, ID FROM DBMedizin" into tSQL
    
      if demBuchstaben <> "*" then
       ## Bedingung an SQL anfügen
       put " WHERE Begriff LIKE" && q2(demBuchstaben & "%") after tSQL
      end if
    
      put revOpenDatabase("sqlite",xpfd, , , , ) into xsql
      put revDataFromQuery(tab,return,xsql,tSQL) into xerg
      if xerg = EMPTY then
        answer "Keine Datensätez mit" && demBuchstaben" && vorhanden!"
      else
       put textDecode(xerg,"UTF-8") into xerg  -- Umlaute umwandeln
       set the dgtext of group "DataM" to xerg
      end if
      revCloseDatabase xsql
    end datensaetze_die_beginnen_mit

    Beispiel, User klickt auf D in Deinem Index an der Seite:

    on mouseup
       datensaetze_die_beginnen_mit "D"
    end mouseup 

    Probiere das mal aus und freue Dich darüber, wie flott das geht! 🙂

    Gruß

    Klaus

  • #14873

    Herby
    Teilnehmer

    Hallo Klaus,

    ja, ich geb zu, ich habe gemogelt und mein Script ein wenig verkürzt.
    Ich poste jetzt doch das ganze Script, um zu erklären, warum ich es so programmierte.

    
    global xpfd
    global xdsg
    global xsmd
    global xtxs
    global xbeg
    
    on mouseUp
       switch 
          case "TY1" is in the target
             put "Vorsilbe" into xtxs
             set the label of btn bnsmd of card id 1032 to xtxs
             Ausblenden 
             LadeVHE
             break
          case "TY2" is in the target
             put "Wortstamm" into xtxs
             set the label of btn bnsmd of card id 1032 to xtxs
             Ausblenden 
             LadeVHE
             break
          case "TY3" is in the target
             put "Endsilbe" into xtxs
             set the label of btn bnsmd of card id 1032 to xtxs
             Ausblenden 
             LadeVHE
             break
          case "BY1" is in the target
             if xsmd = false then
                set the label of btn bnsmd to "deutsch"
                put true into xsmd
             else
                set the label of btn bnsmd to "medizin"
                put false into xsmd
             end if
             break
          case "BY2" is in the target
             put empty into fld fdgax
          case "BY3" is in the target
             put the fld fdgax into xbeg
             if xbeg is not empty then
                set the label of btn bnglo of card id 1032 to xbeg
             else
                set the label of btn bnglo of card id 1032 to "alle"
             end if
             Ausblenden 
             LadeABC        
             break
       end switch
    end mouseUp
    
    on LadeABC
       set the itemDelimiter to tab
       put revOpenDatabase("sqlite",xpfd, , , , ) into xsql
       repeat with x = 1 to xdsg
          put "SELECT Begriff, Beschreibung, ID FROM DBMedizin WHERE ID = " &x into xsel
          put revDataFromQuery(tab,return,xsql,xsel) into xxerg
          put textDecode(xxerg,"UTF-8") into xerg
          if xsmd = false then
             if item 1 of xerg begins with xbeg then
                put item 1 of xerg after xxx
                put tab after xxx
                put item 2 of xerg after xxx
                put tab after xxx
                put item 3 of xerg after xxx
                put return after xxx
             end if
          else
             if item 2 of xerg begins with xbeg then
                put item 1 of xerg after xxx
                put tab after xxx
                put item 2 of xerg after xxx
                put tab after xxx
                put item 3 of xerg after xxx
                put return after xxx
             end if
          end if
       end repeat
       revCloseDatabase xsql
       set the dgtext of group "DataM" to xxx
       if xsmd = false then
          dispatch "SortDataByKey" to grp "DataM" with "medizin","international","ascending","false"
       else
          dispatch "SortDataByKey" to grp "DataM" with "deutsch","international","ascending","false"
       end if
    end LadeABC
    
    on LadeVHE
       set the itemDelimiter to tab
       put revOpenDatabase("sqlite",xpfd, , , , ) into xsql
       repeat with x = 1 to xdsg
          put "SELECT Begriff, Beschreibung, Erklaerung FROM DBMedizin WHERE ID = " &x into xsel
          put revDataFromQuery(tab,return,xsql,xsel) into xxerg
          put textDecode(xxerg,"UTF-8") into xerg
          if item 2 of xerg begins with xtxs then
             put item 1 of xerg after xxx
             put tab after xxx
             put item 2 of xerg after xxx
             replace "Vorsilbe : " with empty in xxx 
             replace "Wortstamm : " with empty in xxx 
             replace "Endsilbe : " with empty in xxx 
             put tab after xxx
             put item 3 of xerg after xxx
             put return after xxx
          end if
       end repeat
       revCloseDatabase xsql
       set the dgtext of grp "DataM" to xxx
       dispatch "SortDataByKey" to grp "DataM" with "medizin","international","ascending","false"
    end LadeVHE
    
    on Ausblenden
       hide graphic viereck
       hide fld fdgax
       hide btn "TY1"
       hide btn "TY2"
       hide btn "TY3"
       hide btn "BY1"
       hide btn "BY2"
       hide btn "BY3"
       set the dgtext of group "DataM" to empty
       show grp "DataM"
    end Ausblenden
    

    Ich suche mit WHERE im SELECT, da ich on LadeLABC für die gesamte Suche (A-Z), wie auch für die Suche nach Buchstaben verwende. Ist der Suchbegriff leer, zeigt es mir nämlich alle Datensätze an.
    Ich sortiere das DataGrid mit dispatch zum Schluss, da ich "international" sortieren muss, damit die Umlaute bei A,O und U einsortiert werden, sonst werden sie ans Ende gestellt. (war zumindest mit der Sortierung vom DataGrid so, was vermutlich order by entspicht)
    Es lädt bei mir übrigens so schnell, dass es auch nur ratzefatze-fertig macht.
    Mein Zauberwort heißt begins with (like) und funkt auch gut.

    Meine Frage ist aber : Wie kann ich das DataGrin in der Anzeige hin- und herschieben, denn wenn ich nur "D"s lade, kann ich nicht nach "C" und "E" rüberschieben.
    Das Data Grid ist eigentlich nur eine Textdatei. Wie springe ich darin in den Zeilen von Buchstabe zu Buchstabe ? Zurück scrollt es ja von allein,
    Kann ich die Zeile im DataGrid suchen (die z,B, mit D beginnt) und dann dorthin springen ?

    Deine Antwort werde ich aber genau durchgehen und ausprobieren. Wie immer !

    Ich habe mir heute die Indy-Lizenz gekauft. Juchu ! (€ 158 mit Cloud)
    -----> jetzt nerve ich euch noch mehr <-------------

    Beste Grüße herby

  • #14875

    Klaus Major
    Moderator

    Hallo Herbie,

    ja, ich geb zu, ich habe gemogelt und mein Script ein wenig verkürzt.

    Tssss, ja dann... 😎

    Wie springe ich darin in den Zeilen von Buchstabe zu Buchstabe?
    Kann ich die Zeile im DataGrid suchen (die z,B, mit D beginnt) und dann dorthin springen?

    Sicher, mach es so, ich schreibe das mal als Funktion, die Dir die Zeilennummer des ersten Vorkommens des übergebenen Buchstabens liefert. Vorausgesetzt, das liegt in der ersten Spalte Deines Datagrids!
    Die Funktion kommt ins Kartenskript

    function zeilennummersuchen anfangsbuchstabe
       ## Mit diesem Trick können wir LINEOFFSET benutzen, was sonst nur die erste Zeile liefern würde,
       ## die den Buchstaben ENTHÄLT, und nicht unbedingt damit beginnt!
       put CR & the dgtext of grp "DataM" into tData
       put lineoffset(CR & anfangsbuchstabe,tData) into gefundene_zeile
       return gefundene_zeile
    end zeilennummersuchen

    Dann aufrufen mit:

    ...
    put "G" into tChar
    put zeilennummersuchen(tChar) into diezeile
    if diezeile = 0 then
       ## Buchstabe nicht in Liste, wir MÜSSEN als Programmierer ALLES abfangen,
       ## weil der User NIE Fehler macht, woll? :-D
       answer "GnaGnaGna, verdammich!"
       exit to top
    end if
    ## Netterweise gibt es diesen Befehl:
    dispatch "ScrollLineIntoView" to grp "DataM" with diezeile
    ...

    Deine Antwort werde ich aber genau durchgehen und ausprobieren. Wie immer!

    Schaden kanns nicht!

    Ich habe mir heute die Indy-Lizenz gekauft. Juchu ! (€ 158 mit Cloud)

    Guter Deal!

    -----> jetzt nerve ich euch noch mehr <-------------

    ACH, DU SCHEISSE! 😀

    Gruß

    Klaus

  • #14885

    Herby
    Teilnehmer

    Hallo LiveCoder,

    ich habe mein Problem ( DataGrid Anzeige rauf und runter) nun folgendermaßen gelöst :
    Funktioniert bei einem DataGrid mit Text !

    Button zurückspringen und anzeigen

    global xpos -- Datensatzposition (Anzahl Lines) 
    
    on mouseDown
       subtract 200 from xpos
       if xpos < 1 then
          put 1 into xpos
       end if
       dispatch "ScrollLineIntoView" to group "DataM" with xpos 
    end mouseDown
    

    Button vorspringen und anzeigen

    global xpos
    
    on mouseDown
       put the dgNumberOfLines of group "DataM" into xges --Gesamtanzahl lines ermitteln
       add 200 to xpos
       if xpos > xges then
          put xges into xpos
       end if
       dispatch "ScrollLineIntoView" to group "DataM" with xpos --zeige line xpos an
    end mouseDown
    

    Eigentlich ganz einfach.

    Beste Grüße
    Herby

  • #14889

    Klaus Major
    Moderator

    Du FUCHS! 🙂

    Aber woher kommt die 200 und wie springst Du damit genau zum ersten Vorkommen eines Buchstaben?

  • #14891

    Herby
    Teilnehmer

    Huhu,

    ich springe nicht auf den nächsten Bustaben, sondern zähle 200 zum aktuellen Datensatz (xpos ist gleichzeitig die line-number) hinzu oder ziehe 200 ab. Den nächsten Buchstaben könnte ich aber ermitteln, indem ich immer (ab Position) die nächsten Datensätze prüfe, ob der Buchstabe wechselt (begins with "K"). Ist mir aber zu aufwendig und der Anwender müsste 25 mal weiter drücken um nach "Z" zu kommen. (so drückt er nur 8 x weiter.

    Und ich bin kein Fuchs, sondern ein Fisch, denn mein Nachname ist "Hecht".
    Du General^^.

    Blub-blub
    Herby

  • #14893

    Klaus Major
    Moderator

    Aha! Ich dachte, Du wolltest einen Index für den User erstellen, also die Buchstaben, die der User dann klicken kann? Genau dafür waren meine beiden Skripte ja gedacht. Un gezz sowatt! Tssssss.... 😀

  • #14895

    Herby
    Teilnehmer

    kleines Problem noch:
    Ich müsste doch noch die aktuelle Position (line-number) im DataGrit ermitteln.
    Vielleicht hast du eine Idee, wie das geht.

    Grüße Herby

  • #14897

    Herby
    Teilnehmer

    Jup, zunächst wollte ich einen Index machen, aber so ist es einfacher und ich es finde besser.

  • #14899

    Klaus Major
    Moderator

    Schau mal unter -> dgVisibleLines im Dictionary.

  • #14901

    Herby
    Teilnehmer

    put item 1 of the dgVisibleLines of group "DataM" into xpos

    So kann ich den ersten Wert (erste Zeile) ermitteln.
    item 2 ergibt den Wert der letzten Zeile der Anzeige.

    Guter Tipp. Danke Klaus !

  • #14908

    Klaus Major
    Moderator

    Avec plaisir, mon ami!

Du musst angemeldet sein, um auf dieses Thema antworten zu können.