UNIQUE auf grossen Tabellen [erledigt]

Zugriff, Engines, Konvertierung. Von ADS über DBF bis zu SQL.

Moderator: Moderatoren

Antworten
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

UNIQUE auf grossen Tabellen [erledigt]

Beitrag von AUGE_OHR »

hi,

ich habe eine Faktura DBF und einen Index

Code: Alles auswählen

FAKTU->KDNR + FAKTU->ARTNR
wobei beide Type "C" sind.
wenn ich nun wissen will was der Kunde kauft kann ich einen SCOPE auf die Kundennummer machen.

Code: Alles auswählen

   SEEK(FAKTU->KDNR)
   IF FOUND()
       SET SCOPE TO FAKTU->KDNR
       Browse()
       SET SCOPE TO 
   ENDIF
nun bekomme ich alle Artikel die der Kunde gekauft hat ... aber auch "mehrfach" Artikel die er jedes mal kauft.

mögliche Lösungen :
1.) Indexkey mit UNIQUE
2.) "sammeln" in einem Array

Nachteile :
zu 1.) es wird nur der 1st Treffer, der meisten älter ist, angezeigt.
man bekommt keine Summe "wie oft" der Artikel zu welchem (Tages) Preis verkauft wurde.

zu 2.) das "sammeln" kann eine ganze Zeit lang dauern ( 500000 Sätze ) wo man nichts "sieht" ( Sand Uhr)

Frage : was kommt raus bei

Code: Alles auswählen

INDEX ON FAKTU->KDNR + FAKTU->ARTNR TO KDKAUFT UNIQUE DESCENDING
klar fängt er bei der höchsten KDNR und ARTNR an aber ist das auch der "latest" Eintrag ?

sonst noch eine Idee wie man zu einer (schnellen) Anzeige kommt ?

Nachtrag : so sieht der Cl*pper Code aus

Code: Alles auswählen

   SEEK(cKDNR)
   IF FOUND()
      DO WHILE !EOF()
         IF cARTNR <> FAKTU->ARTNR
            cARTNR := FAKTU->ARTNR
            Zeile++
            SumAnZahl := 0
            SumPreis  := 0
         ENDIF

         IF Zeile = MaxRow() - nUnten
            IF JaNein("Weiter J/N")
               CLS
               Zeile := nOben
            ELSE
               EXIT
            ENDIF
         ENDIF

         SumAnZahl += FAKTU->Anzahl
         SumPreis  += FAKTU->Anzahl * FAKTU->Preis
         @ Zeile, Spalte SAY cARTNR+"...mehr Text ..."+STR(SumAnZahl)+" "+STR(SumPreis)+" "+STR(SumPreis/SumAnZahl)

         SKIP
         IF cKDNR <> FAKTU->KDNR
            EXIT
         ENDIF
      ENDDO
   ENDIF
womit natürlich "sofort" eine Anzeige beim ersten Treffer erscheint
Zuletzt geändert von AUGE_OHR am Di, 07. Apr 2015 10:59, insgesamt 1-mal geändert.
gruss by OHR
Jimmy
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2121
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 30 Mal
Danksagung erhalten: 72 Mal

Re: UNIQUE auf grossen Tabellen

Beitrag von Werner_Bayern »

Clippercode als Grundlage und damit on the fly eine ListBox bestücken. Dann hast Du den gleichen Effekt, Einträge werden gleich angezeigt.

Und du hast die Kontrolle, was währenddessen passiert. Ein Doppelklick auf ein Element (oder auf einen Button) beendet sofort die Suche und Addition etc.
es grüßt

Werner

<when the music is over, turn off the lights!>
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Re: UNIQUE auf grossen Tabellen

Beitrag von AUGE_OHR »

Werner_Bayern hat geschrieben:Clippercode als Grundlage und damit on the fly eine ListBox bestücken. Dann hast Du den gleichen Effekt, Einträge werden gleich angezeigt.
YUP ... das hatte ich zuerst gemacht.
Werner_Bayern hat geschrieben:Und du hast die Kontrolle, was währenddessen passiert. Ein Doppelklick auf ein Element (oder auf einen Button) beendet sofort die Suche und Addition etc.
der Grund warum ich das Array mit Quickbrowse statt Listbox anzeigen möchte :
Ich muss, wenn ich die Sortierung ändere, eine Listbox neu aufbauen während ich beim Quickbrowse es "on-fly" machen kann.

ich hatte mir zunächst "QuickSortBrowse" angesehen ... wie umständlich ... ist wie FBrowse über eine zusätzliche (Sortier-) Spalte gelöst. Es geht aber IMHO viel einfacher

Code: Alles auswählen

   oQB:heading:itemSelected := {| aRowCol, uNIL, oSelf |  ;
                                  ::SortArray(aRowCol)   ,;
                                  oQB:goTop()            ,;
                                  oQB:refreshAll() }

METHOD KundClass:SortArray(aRowCol)
LOCAL nCol := aRowCol[2]
STATIC lDescend := .F.

   IF lDescend = .T.
      lDescend := .F.
      ::KauftItem := ASORT( ::KauftItem,,, { | aX, aY | aX[ nCol ] > aY[ nCol ] } )
   ELSE
      lDescend := .T.
      ::KauftItem := ASORT( ::KauftItem,,, { | aX, aY | aX[ nCol ] < aY[ nCol ] } )
   ENDIF
RETURN NIL  
damit das funktioniert MUSS das Array und die Column-Reihenfolge übereinstimmen !!!
gruss by OHR
Jimmy
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Re: UNIQUE auf grossen Tabellen

Beitrag von AUGE_OHR »

so nun hab ich es mit einem Thread optimiert wobei ich jetzt, wegen den Möglichkeiten, beim XbpBrowse gelandet bin

Code: Alles auswählen

// XbpBrowse() als Array Browser

      // am Anfang einen Dummy Satz anlegen
      AADD(::KauftItem,{0,0,"",0,"","",0,0,"" .... })

      ::nKdRec  := 1
      // mit visible := .F. aufbauen
      ::oQBkunden := XbpBrowse():New( ::TabPage3,, { 10, 20 }, aaSize, aPP, .F. )
      ::oQBkunden:SkipBlock     := {|nSkip| ::DoKdSkip(nSkip) }
      ::oQBkunden:GoBottomBlock := {|| ::nKdRec := Len(::KauftItem) }
      ::oQBkunden:GoTopBlock    := {|| ::nKdRec := 1 }
      ::oQBkunden:PosBlock      := {|| ::nKdRec }
      ::oQBkunden:PhyPosBlock   := {|| ::nKdRec }
      ::oQBkunden:LastPosBlock  := {|| Len(::KauftItem) }
      ::oQBkunden:FirstPosBlock := {|| 1 }
      ::oQBkunden:CursorMode    := XBPBRW_CURSOR_ROW
      ::oQBkunden:Create()
      ::oQBkunden:Cargo := "KUNDEN"
   ...
   // nach dem letzten zufügen einer Column 
      ::oQBkunden:addColumn(oCol)

   // jetzt den Thread starten
       oThread := Thread():new()
       oThread:start( {|| ::LadeFSicher(cSeek),;
           IF(::oQBkunden:isVisible(),::oQBkunden:refreshAll(),NIL) } ) 

   // das reicht für eine Anzeige
       ::oQBkunden:Show()

       SetAppFocus( ::oQBkunden )
   // und hier hat der Thread schon gefüllt 
       ::oQBkunden:refreshAll()
der User kann nun o:PgDn drücken oder auch den Scrollbar betätigen und es passiert was ... ;)
gruss by OHR
Jimmy
Antworten