Mehrere Scopes?
Moderator: Moderatoren
- Jan
- Marvin
- Beiträge: 14658
- Registriert: Fr, 23. Sep 2005 18:23
- Wohnort: 49328 Melle
- Hat sich bedankt: 21 Mal
- Danksagung erhalten: 88 Mal
- Kontaktdaten:
Mehrere Scopes?
Besteht die Möglichkeit, mehrere Scopes auf eine Datenbank zu setzen?
Ich habe das so versucht, daß ich den betreffenden Index wähle, den Scope setze, den nächsten Index wähle und auch hier den Scope setze. Aber das funktioniert nicht. Der 1. Scope wird anscheinend mit Setzen des 2. verworfen.
Gibt es da eine Lösung? Ich hoffe sehr, denn ich würde da gerne einige Filter mit loswerden, die einfach zu langsam sind.
Aber grundsätzlich: Ich verstehe das schon richtig daß ein Scope nur bei einem Index auf dem betreffenden Feld eingesetzt werden kann?
Jan
Ich habe das so versucht, daß ich den betreffenden Index wähle, den Scope setze, den nächsten Index wähle und auch hier den Scope setze. Aber das funktioniert nicht. Der 1. Scope wird anscheinend mit Setzen des 2. verworfen.
Gibt es da eine Lösung? Ich hoffe sehr, denn ich würde da gerne einige Filter mit loswerden, die einfach zu langsam sind.
Aber grundsätzlich: Ich verstehe das schon richtig daß ein Scope nur bei einem Index auf dem betreffenden Feld eingesetzt werden kann?
Jan
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9367
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 102 Mal
- Danksagung erhalten: 361 Mal
- Kontaktdaten:
Hallo, Jan.
Ein Scope funktioniert im Prinzip wie ein Filter; der einzige generelle Unterschied besteht darin, daß Indexausdrücke herangezogen werden. Deshalb kann es auch nur einen je Workarea (!) geben. Wenn Du zwei Scopes auf die selbe Tabelle setzen willst, dann mußt Du sie (einfach) ein zweites Mal parallel öffnen. Das kannst Du im Prinzip beliebig oft tun.
Ein Scope funktioniert im Prinzip wie ein Filter; der einzige generelle Unterschied besteht darin, daß Indexausdrücke herangezogen werden. Deshalb kann es auch nur einen je Workarea (!) geben. Wenn Du zwei Scopes auf die selbe Tabelle setzen willst, dann mußt Du sie (einfach) ein zweites Mal parallel öffnen. Das kannst Du im Prinzip beliebig oft tun.
Herzlich,
Tom
Tom
- brandelh
- Foren-Moderator
- Beiträge: 15697
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 33 Mal
- Kontaktdaten:
Hallo Jan,
ein Scope ist ein Filter auf den Indexausdruck.
Man kann aber leicht einen scope mit einem filter kombinieren.
Der Filter ist flexibler, der Scope schneller.
Somit musst du den Index so aufbauen, dass erstens die Sortierung stimmt und zweitens die Anzahl der Datensätze deutlich reduziert wird.
Nun noch den Filter dazu, der dann ja nur noch die Sätze im Scope Bereich durchsuchen muss und du bist schnell und flexibel:
Beispiel:
Filter auf PLZ+Name+Vorname ... bei 1000000 Datensätzen, indiskutabel ...
Scope auf PLZ+Namensteil ... wenn man Glück hat bleiben nur wenige (bis einige hundert) Datensätze.
nun Filter auf Vornamensteil, bei einigen 100 kein Problem.
Wenn man aber nur flexible Treffer im Index suchen will, z.B.
PLZ + Teilnamen aber nicht linksbündig, kann man auch den neuen
Befehl ordwildseek nutzen (Index selbst bleibt gleich) jeder Aufruf bringt den nächsten Treffer. Sehr schnell, eventuell Index erweitern, muss nicht linksbündig suchen.
Im Beispiel z.B. suche nach '67322*Elke' findet alle Elkes im Ort, wenn der Indexbegriff PLZ+Name+Vorname lautet.
Wenn man diese Ergebnisse allerdings browsen möchte, muss man ein Array mit Satznummern füllen und die Anzeige dann jeweils auf goto(recno(())) zwingen. Das habe ich noch nicht gemacht.
ein Scope ist ein Filter auf den Indexausdruck.
Man kann aber leicht einen scope mit einem filter kombinieren.
Der Filter ist flexibler, der Scope schneller.
Somit musst du den Index so aufbauen, dass erstens die Sortierung stimmt und zweitens die Anzahl der Datensätze deutlich reduziert wird.
Nun noch den Filter dazu, der dann ja nur noch die Sätze im Scope Bereich durchsuchen muss und du bist schnell und flexibel:
Beispiel:
Filter auf PLZ+Name+Vorname ... bei 1000000 Datensätzen, indiskutabel ...
Scope auf PLZ+Namensteil ... wenn man Glück hat bleiben nur wenige (bis einige hundert) Datensätze.
nun Filter auf Vornamensteil, bei einigen 100 kein Problem.
Wenn man aber nur flexible Treffer im Index suchen will, z.B.
PLZ + Teilnamen aber nicht linksbündig, kann man auch den neuen
Befehl ordwildseek nutzen (Index selbst bleibt gleich) jeder Aufruf bringt den nächsten Treffer. Sehr schnell, eventuell Index erweitern, muss nicht linksbündig suchen.
Im Beispiel z.B. suche nach '67322*Elke' findet alle Elkes im Ort, wenn der Indexbegriff PLZ+Name+Vorname lautet.
Wenn man diese Ergebnisse allerdings browsen möchte, muss man ein Array mit Satznummern füllen und die Anzeige dann jeweils auf goto(recno(())) zwingen. Das habe ich noch nicht gemacht.
Gruß
Hubert
Hubert
- Jan
- Marvin
- Beiträge: 14658
- Registriert: Fr, 23. Sep 2005 18:23
- Wohnort: 49328 Melle
- Hat sich bedankt: 21 Mal
- Danksagung erhalten: 88 Mal
- Kontaktdaten:
Hallo Hubert und Tom,
verstanden. Wenn auch ärgerlich, ich hatte mir das jetzt so schön gedacht.
Habt Ihr vielleicht eine Idee, wie ich das Problem lösen kann? Es geht da um folgendes:
Datenbank mit den Auftrags-Kopfdaten wird gebrowsed. Relationen bestehen zu den Verkäufernamen (werden im Browse in jedem Datensatz angezeigt), zu den Adressen (da könnte ich vielleicht tricksen und das entfernen) und zu den Anzahlungen. Dabei kann man folgende Filter per XbpCombobox einstellen:
Auftragsstatus: Aktuell (Standard), Archiv, beides, oder Gibt es neue Anzahlungen auf den Auftrag
Verkäufer: Alle (Standard) oder einen bestimmten auswählen
Und da gibt es dann natürlich alle möglichen Variationen. Die ich natürlich gerne flott im Browse aktualisieren möchte. Das geht als dbf übers Netz mit z. Zt. gut 20.000 Datensätzen. Dauert mit "normalem" Filter mehrere Sekunden, bis sich das aufgebaut hat. Das ist beim Öffnen der Oberfläche schon schlimm benug, beim Blättern aber absolut indiskutabel.
Jan
verstanden. Wenn auch ärgerlich, ich hatte mir das jetzt so schön gedacht.
Habt Ihr vielleicht eine Idee, wie ich das Problem lösen kann? Es geht da um folgendes:
Datenbank mit den Auftrags-Kopfdaten wird gebrowsed. Relationen bestehen zu den Verkäufernamen (werden im Browse in jedem Datensatz angezeigt), zu den Adressen (da könnte ich vielleicht tricksen und das entfernen) und zu den Anzahlungen. Dabei kann man folgende Filter per XbpCombobox einstellen:
Auftragsstatus: Aktuell (Standard), Archiv, beides, oder Gibt es neue Anzahlungen auf den Auftrag
Verkäufer: Alle (Standard) oder einen bestimmten auswählen
Und da gibt es dann natürlich alle möglichen Variationen. Die ich natürlich gerne flott im Browse aktualisieren möchte. Das geht als dbf übers Netz mit z. Zt. gut 20.000 Datensätzen. Dauert mit "normalem" Filter mehrere Sekunden, bis sich das aufgebaut hat. Das ist beim Öffnen der Oberfläche schon schlimm benug, beim Blättern aber absolut indiskutabel.
Jan
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9367
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 102 Mal
- Danksagung erhalten: 361 Mal
- Kontaktdaten:
Hallo, Jan.
Da Martin unvermeidlicherweise sowieso mit diesem Vorschlag kommen wird - es scheint mir tatsächlich am einfachsten, die vom Auftragskopf abhängigen Daten in Arrays zu sammeln. Sobald also der Zeiger in der Auftragsdatei bewegt wird, sammelst Du die abhängigen Daten in Arrays, zunächst alle. Und je nach Einstellung in den Auswahlboxen erzeugst Du aus den Arrays Klone, die nur die "gefilterten" Daten enthalten. Wenn die Auswahl geändert wird, ensteht ein neues geklontes Array aus dem Ursprungsarray. Die Zeit, die zum Zusammenstellen der Daten benötigt wird, dürfte gering sein (Scope auf Auftragsnummer), und danach geht es ratzfatz. Für die Verfügbarkeit der echten Daten nimmst Du die jeweilige RecNo() in das Array, DbGoto() - fertig.
Da Martin unvermeidlicherweise sowieso mit diesem Vorschlag kommen wird - es scheint mir tatsächlich am einfachsten, die vom Auftragskopf abhängigen Daten in Arrays zu sammeln. Sobald also der Zeiger in der Auftragsdatei bewegt wird, sammelst Du die abhängigen Daten in Arrays, zunächst alle. Und je nach Einstellung in den Auswahlboxen erzeugst Du aus den Arrays Klone, die nur die "gefilterten" Daten enthalten. Wenn die Auswahl geändert wird, ensteht ein neues geklontes Array aus dem Ursprungsarray. Die Zeit, die zum Zusammenstellen der Daten benötigt wird, dürfte gering sein (Scope auf Auftragsnummer), und danach geht es ratzfatz. Für die Verfügbarkeit der echten Daten nimmst Du die jeweilige RecNo() in das Array, DbGoto() - fertig.
Herzlich,
Tom
Tom
- brandelh
- Foren-Moderator
- Beiträge: 15697
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 33 Mal
- Kontaktdaten:
Hallo Jan,
ich würde die Relationen durch manuelles setzen von scopes etc. ersetzen.
1. habe ich überhaupt schlechte Erfahrungen mit Relationen und automatischem Verhalten ...
2. könnte durch scope und relation eine Art Rückkopplung entstehen.
Bei jeder Satzbewegung in der Hauptdatei prüfst du ob der Schlüsselbegriff in den Kinddaten geändert wurde.
Wenn ja, neuen scope in den Kinddateien setzen, eventuell zusätzliche Filter und die Browser neu einlesen lassen. Wenn die Daten statisch sind, können Arrays zum Puffern nützlich sein (mit genug RAM sind 20000 Einträge im Array je 100 Byte kein Problem).
Beim Browser müsste man das nachführen der Kinder darauf einschränken, dass die Anzeige stable ist um interne skips nicht mitzuführen.
Wenn der Quickbrowse reicht, diesen nutzen, der ist in Verbindung mit den DacPagedDataStore() wesentlich schneller im Aufbau und der Anzeige.
ich würde die Relationen durch manuelles setzen von scopes etc. ersetzen.
1. habe ich überhaupt schlechte Erfahrungen mit Relationen und automatischem Verhalten ...
2. könnte durch scope und relation eine Art Rückkopplung entstehen.
Bei jeder Satzbewegung in der Hauptdatei prüfst du ob der Schlüsselbegriff in den Kinddaten geändert wurde.
Wenn ja, neuen scope in den Kinddateien setzen, eventuell zusätzliche Filter und die Browser neu einlesen lassen. Wenn die Daten statisch sind, können Arrays zum Puffern nützlich sein (mit genug RAM sind 20000 Einträge im Array je 100 Byte kein Problem).
Beim Browser müsste man das nachführen der Kinder darauf einschränken, dass die Anzeige stable ist um interne skips nicht mitzuführen.
Wenn der Quickbrowse reicht, diesen nutzen, der ist in Verbindung mit den DacPagedDataStore() wesentlich schneller im Aufbau und der Anzeige.
Gruß
Hubert
Hubert
- brandelh
- Foren-Moderator
- Beiträge: 15697
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 33 Mal
- Kontaktdaten:
Hi Jan,
zu den Verkäufernamen fällt mir ein ...
die sind ja bestimmt recht statisch.
Ich habe häufig bei mir Hilfstabellen, deren Werte ich beim ersten Programmstart in einer Funktion (static var) zwischenspeichere.
In deinem Fall könnte eine Funktion in dieser Art nützlich sein:
Eventuell kann man so mehrere Felder dynamisch bis zum nächsten Programmstart zwischenspeichern und Plattenzugriffe verringern.
zu den Verkäufernamen fällt mir ein ...
die sind ja bestimmt recht statisch.
Ich habe häufig bei mir Hilfstabellen, deren Werte ich beim ersten Programmstart in einer Funktion (static var) zwischenspeichere.
In deinem Fall könnte eine Funktion in dieser Art nützlich sein:
Code: Alles auswählen
vorher schon offen Verkäuferdatei alias VK
im browser... getVerkInfo(stamm->VK_ID,"N") ...
function getVerkInfo(cVK_ID,cFeld)
static aVKINFO := {}
local x:=0, cReturn := ""
x := ascan(aVKINFO, Suchcodeblock je nach Arrayart nach cVK_ID)
if x = 0 // VK in Datei suchen
if VK->(dbseek(cVK_ID))
aadd(aVKINFO, {.....}) // Name oder mehr Infos
if cFeld="N" // oder mehr ??
cReturn := VK->NAME
endif
else
// Fehlermeldung ... wie man es will ?
aadd(aVKINFO, {.....}) // auch Fehler speichern ????
cReturn := "???"
endif
else
if cFeld="N" // oder mehr ??
cReturn := aVKINFO[x,nFeldName] // nFeldName sollte man über #DEFINE benennen
endif
endif
return cReturn
Zuletzt geändert von brandelh am Fr, 08. Dez 2006 17:15, insgesamt 1-mal geändert.
Gruß
Hubert
Hubert
- Jan
- Marvin
- Beiträge: 14658
- Registriert: Fr, 23. Sep 2005 18:23
- Wohnort: 49328 Melle
- Hat sich bedankt: 21 Mal
- Danksagung erhalten: 88 Mal
- Kontaktdaten:
Hubert,
nur eben schnell einer Deiner Punkte: Die Geschichte mit den Relationen. Ich bin selber auch überhaupt kein Freund davon. Wo immer es geht schmeiß ich die raus.
Nur: Ich bin noch nicht dahinter gekommen, wie ich ohne Relation einen Browse über mehrere Datenbanken bewerkstelligen soll. In diesem Fall ist es so, daß in den Auftrags-Kopfdaten nur die Verkäufernummer hinterlegt ist. Im Browse soll aber der Name erscheinen. Deswegen die Relation darauf. Und die "Neuen Zahlungen" auf den Auftrag werden ebenfalls in einer eigenen Datenbank verwaltet. Da ich auch hierauf filtern muß (die Verkäufer sollen eine Übersicht erhalten, wo es Zahlungen gibt, welche Aufträge damit zur verarbeitung anstehen), gibt es hierüber ebenfals eine Relation.
Abhängge Daten gibt es sonst nicht. Der Browse soll einfach nur einen Überblick geben. Sollen etwa die Positionen dieses Auftrages bearbeitet werden, so geschicht das in einem extra zu öffnenden Browse, wo dann die entsprechenden Datenbanken geöffnet werden, gefiltert um die entsprechende Auftragsnummer.
Jan
nur eben schnell einer Deiner Punkte: Die Geschichte mit den Relationen. Ich bin selber auch überhaupt kein Freund davon. Wo immer es geht schmeiß ich die raus.
Nur: Ich bin noch nicht dahinter gekommen, wie ich ohne Relation einen Browse über mehrere Datenbanken bewerkstelligen soll. In diesem Fall ist es so, daß in den Auftrags-Kopfdaten nur die Verkäufernummer hinterlegt ist. Im Browse soll aber der Name erscheinen. Deswegen die Relation darauf. Und die "Neuen Zahlungen" auf den Auftrag werden ebenfalls in einer eigenen Datenbank verwaltet. Da ich auch hierauf filtern muß (die Verkäufer sollen eine Übersicht erhalten, wo es Zahlungen gibt, welche Aufträge damit zur verarbeitung anstehen), gibt es hierüber ebenfals eine Relation.
Abhängge Daten gibt es sonst nicht. Der Browse soll einfach nur einen Überblick geben. Sollen etwa die Positionen dieses Auftrages bearbeitet werden, so geschicht das in einem extra zu öffnenden Browse, wo dann die entsprechenden Datenbanken geöffnet werden, gefiltert um die entsprechende Auftragsnummer.
Jan
- Manfred
- Foren-Administrator
- Beiträge: 21200
- Registriert: Di, 29. Nov 2005 16:58
- Wohnort: Kreis Wesel
- Hat sich bedankt: 210 Mal
- Danksagung erhalten: 67 Mal
Hi Jan,
ich habe auch noch keine Ahnung, wie man das in einem Browse einbaut. Ich weiß aber, dass Jimmy es mal erklärt hat, finde es aber nicht mehr wieder.
ich habe auch noch keine Ahnung, wie man das in einem Browse einbaut. Ich weiß aber, dass Jimmy es mal erklärt hat, finde es aber nicht mehr wieder.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
- Rolf Ramacher
- Der Entwickler von "Deep Thought"
- Beiträge: 1930
- Registriert: Do, 09. Nov 2006 10:33
- Wohnort: Bergheim
- Danksagung erhalten: 3 Mal
- Kontaktdaten:
Index suchen
Hallo Jan,
ich mache dies immer folgendermaßen
meistens habe ich dies beim start des Main-Programms das Indexdateien
festgelegt werden.
Index on xxx tag "xxxx" to ">name der index-Datei>.cdx"
beim bearbeiten nachher in den Programmroutinen nach dem use
set index to ">name der index-Datei>.cdx"
name der Datenbank ordsetfocus(>tagname<)
Hierbei kannst du mehrere Indexsortierungen in einer cdx-Datei gestalten.
ich mache dies immer folgendermaßen
meistens habe ich dies beim start des Main-Programms das Indexdateien
festgelegt werden.
Index on xxx tag "xxxx" to ">name der index-Datei>.cdx"
beim bearbeiten nachher in den Programmroutinen nach dem use
set index to ">name der index-Datei>.cdx"
name der Datenbank ordsetfocus(>tagname<)
Hierbei kannst du mehrere Indexsortierungen in einer cdx-Datei gestalten.
- Manfred
- Foren-Administrator
- Beiträge: 21200
- Registriert: Di, 29. Nov 2005 16:58
- Wohnort: Kreis Wesel
- Hat sich bedankt: 210 Mal
- Danksagung erhalten: 67 Mal
Hi Hubert,
die Frage verwundert mich jetzt aber doch. Wie willst Du ein relationales Db System sonst verwalten? Es müssen doch in einem Browse Verknüpfungen angezeigt werden. Wie willst Du sonst z.B. Aufträge, Lieferscheine oder Rechnungen anzeigen? Es muß Verknüpfungen untereinander geben. Oder habe ich Dich jetzt falsch verstanden? Es ging doch um Spalten aus verschiedenen Tabellen parallel in einem Browse?
die Frage verwundert mich jetzt aber doch. Wie willst Du ein relationales Db System sonst verwalten? Es müssen doch in einem Browse Verknüpfungen angezeigt werden. Wie willst Du sonst z.B. Aufträge, Lieferscheine oder Rechnungen anzeigen? Es muß Verknüpfungen untereinander geben. Oder habe ich Dich jetzt falsch verstanden? Es ging doch um Spalten aus verschiedenen Tabellen parallel in einem Browse?
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
- Rolf Ramacher
- Der Entwickler von "Deep Thought"
- Beiträge: 1930
- Registriert: Do, 09. Nov 2006 10:33
- Wohnort: Bergheim
- Danksagung erhalten: 3 Mal
- Kontaktdaten:
xbpbrowse
Hallo Jan,
du kannst ja auch mehrere Browse in einem Fenster anzeigen. Das Fenster muß nur groß genug sein. Dann brauchst du nur die browse mit der entsprechenden Größe zu positionieren.
Wenn du nur einen Browse erzeugen willst, und du hast Info aus mehreren Datenbanken, so erzeuge doch eine temporäre Datenbank, in der du Informationen zusammenträgst und dann die temporäre Datenbank in den browse zur Anzeige bringst.
du kannst ja auch mehrere Browse in einem Fenster anzeigen. Das Fenster muß nur groß genug sein. Dann brauchst du nur die browse mit der entsprechenden Größe zu positionieren.
Wenn du nur einen Browse erzeugen willst, und du hast Info aus mehreren Datenbanken, so erzeuge doch eine temporäre Datenbank, in der du Informationen zusammenträgst und dann die temporäre Datenbank in den browse zur Anzeige bringst.
- brandelh
- Foren-Moderator
- Beiträge: 15697
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 33 Mal
- Kontaktdaten:
Hallo,
ich habe in solchen Fällen tatsächlich eine Auswahl von Kunden (ein Kunde), einen für Rechnungsstammdaten (mehrere pro Kunde, aber nur einen pro Rechnung), ein weiteres für Rechnungspositionen (viele pro Rechnung) etc.
Man muss halt aufpassen, dass man keine wechselseitigen Abhängigkeiten erzeugt, sonst flippt der Browser nur noch. Aber das ist eigentlich bei Relationen immer so.
Wenn der Browser nur anzeigt, sollte man auf jeden Fall den Quickbrowse nehmen, der puffert die Daten zwischen und ist schneller.
ich habe in solchen Fällen tatsächlich eine Auswahl von Kunden (ein Kunde), einen für Rechnungsstammdaten (mehrere pro Kunde, aber nur einen pro Rechnung), ein weiteres für Rechnungspositionen (viele pro Rechnung) etc.
Man muss halt aufpassen, dass man keine wechselseitigen Abhängigkeiten erzeugt, sonst flippt der Browser nur noch. Aber das ist eigentlich bei Relationen immer so.
Wenn der Browser nur anzeigt, sollte man auf jeden Fall den Quickbrowse nehmen, der puffert die Daten zwischen und ist schneller.
Gruß
Hubert
Hubert
- AUGE_OHR
- Marvin
- Beiträge: 12909
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
hi,
(incl. Skipblock) Browse Objecten zusammen.
jedes Object wird also in ein Array aufgenommen.
Der "Witz" liegt nun in der "umschaltung" der Objecte :
wie man sieht gibt es einen "Zähler nBP". Der muss auch immer in
ApplyKey mit berücksichtigt werden.
In diesem Beispiel hab ich noch "Relationen". Wenn also "IF !EMPTY
(DBRELATION(1))" erfüllt ist wird ein "DrawAll" durchgeführt.
Da wir nur "bestimmte" Datensätze haben wollen müssen wir auch die
"Skipper" anpassen auf die "bWhileCond"
So damit müsste man alle "Bausteine" für ein "Multi-browse" haben.
gruss by OHR
Jimmy
Also im Prinzip baut man so ein Browse aus verschiedenen komplettenManfred hat geschrieben: ich habe auch noch keine Ahnung, wie man das in einem Browse einbaut. Ich weiß aber, dass Jimmy es mal erklärt hat, finde es aber nicht mehr wieder.
(incl. Skipblock) Browse Objecten zusammen.
Code: Alles auswählen
FUNCTION BrowseIt()
LOCAL aoBrowse := ARRAY(3)
...
// set up browse and display it
aoBrowse[1] := KRED1Browse()
aoBrowse[1]:goTop()
DispBrowse(aoBrowse[1])
// set up browse and display it
aoBrowse[2] := ARTQ2Browse()
aoBrowse[2]:goTop()
DispBrowse(aoBrowse[2])
// set up browse and display it
aoBrowse[3] := ABZU3Browse()
aoBrowse[3]:goTop()
DispBrowse(aoBrowse[3])
...
Der "Witz" liegt nun in der "umschaltung" der Objecte :
Code: Alles auswählen
// set browse pointer to first browse defined
nBP := LEN(aoBrowse)
DispBrowse(aoBrowse[nBP])
nBP := 1 // start with first window
// main browse display loop
lMore := .T.
DO WHILE lMore
nKey := 0
// Stabilize the browse until it's stable or a key is pressed
DO WHILE (nKey := INKEY()) == 0 .AND. !aoBrowse[nBP]:stabilize()
ENDDO
IF aoBrowse[nBP]:stable
// alert if hit top or bottom of browse
IF aoBrowse[nBP]:hitTop .OR. aoBrowse[nBP]:hitBottom
TONE(125, 0)
ENDIF
// update other browse screens in case relations are set
IF !EMPTY(DBRELATION(1))
DrawAll(aoBrowse, nBP)
ENDIF
aoBrowse[nBP]:hilite()
// Get a new keystroke
nKey := INKEY(0)
ENDIF
// Apply the key to the browse
lMore := ApplyKey(aoBrowse, nKey, @nBP)
ENDDO
ApplyKey mit berücksichtigt werden.
Code: Alles auswählen
FUNCTION ApplyKey(aoBrowse, nKey, nBP)
LOCAL lMore := .T.
DO CASE
CASE nKey == 5 ; aoBrowse[nBP]:up() // Up-arrow
CASE nKey == 24 ; aoBrowse[nBP]:down() // Down-arrow
...
CASE nKey == 27 ; lMore := .F. // Esc
CASE nKey == 13 // Enter
DoGet(aoBrowse[nBP]) ; aoBrowse[nBP]:refreshCurrent()
CASE nKey == K_TAB
nBP++
IF(nBP>3,nBP:=1,NIL)
ENDCASE
RETURN lMore
(DBRELATION(1))" erfüllt ist wird ein "DrawAll" durchgeführt.
Code: Alles auswählen
FUNCTION DrawAll(aoBrowse, nBP)
LOCAL n
...
FOR n := 1 TO LEN(aoBrowse)
IF n != nBP
DispBrowse(aoBrowse[n])
ENDIF
NEXT
DispBrowse(aoBrowse[nBP])
...
RETURN (NIL)
// Display the browse screen
FUNCTION DispBrowse(oBrowse)
// select the database for this browse
SELECT (oBrowse:cargo[ALIAS])
...
// clear old screen area
@ oBrowse:cargo[BOXTOP], oBrowse:cargo[BOXLEFT] CLEAR TO oBrowse:cargo[BOXBOTTOM], oBrowse:cargo[BOXRIGHT]
// display the browse box
DISPBOX(oBrowse:cargo[BOXTOP], oBrowse:cargo[BOXLEFT],;
oBrowse:cargo[BOXBOTTOM], oBrowse:cargo[BOXRIGHT],;
oBrowse:cargo[BOXTYPE], oBrowse:cargo[BOXBORDER])
// refresh browse so all data is redisplayed in the box
oBrowse:refreshAll()
ForceStable(oBrowse)
...
RETURN (NIL)
"Skipper" anpassen auf die "bWhileCond"
Code: Alles auswählen
STATIC FUNCTION GoNext(nToSkip, bWhileCond )
LOCAL nSkipped := 0, nDirection
nDirection := IIF(nToSkip > 0, 1, -1)
DO WHILE nSkipped != nToSkip .AND. EVAL(bWhileCond) .AND. ;
!EOF() .AND. !BOF()
SKIP nDirection
nSkipped += nDirection
ENDDO
IF EOF()
SKIP -1
nSkipped--
ELSEIF BOF()
GOTO RECNO()
nSkipped++
ELSEIF !EVAL(bWhileCond)
SKIP -nDirection
nSkipped += -nDirection
ENDIF
RETURN nSkipped
STATIC FUNCTION GoTop( bWhileCond )
WHILE EVAL( bWhileCond ) .AND. !BOF()
SKIP -1
IF !EVAL( bWhileCond )
SKIP
EXIT
ENDIF
END
RETURN (NIL)
STATIC FUNCTION GoBottom( bWhileCond )
WHILE EVAL( bWhileCond ) .AND. !EOF()
SKIP
END
// We always skip 1 too far, so skip back
SKIP -1
RETURN (NIL)
gruss by OHR
Jimmy