xsharp.eu • Prüfen, ob der aktuelle Datensatz ausgefiltert ist?
Page 1 of 1

Prüfen, ob der aktuelle Datensatz ausgefiltert ist?

Posted: Tue Dec 01, 2020 5:58 pm
by g.bunzel@domonet.de
Hallo VO'ler,

gibt es eine Möglichkeit festzustellen, ob der aktuelle Datensatz einer DBF-Datei bei einem aktiven Filter 'ausgefiltert' oder 'angezeigt' wird?
Es gibt die Methode DBServer:RecordInfo() mit verschiedenen Infos zu einem Datensatz. Ein DBRI_FILTERED wäre hier praktisch.

Grund meiner Frage:
Eine DBF-Datei ist z.B. nach dem Datum '01.12.2020' gefiltert. In einem Datensatz dieser Tabelle wird das Datum auf '02.12.2020' geändert - damit verschwindet dieser Datensatz aus der Anzeige. Im bBrowser ist jetzt aber kein aktueller Datensatz mehr angezeigt, da dieser Datensatz jetzt 'ausgefiltert' ist. Mit 'Cursor down' wird auf den nächsten, gefilterten Datensatz gesprungen und die Anzeige für einen aktuellen Datensatz ist wieder zu sehen.
Ich würde gerne nach dem Speichern der Änderungen prüfen, ob der aktuelle Datensatz noch dem Filter entspricht. Wenn ja wird der Datensatz weiterhin angezeigt - wenn nicht, würde mit einem DBServer:Skip(1) zum nächsten 'sichtbaren' Datensatz gesprungen.

Vielen Dank für Infos im Voraus.

Gruss

Gerhard

Prüfen, ob der aktuelle Datensatz ausgefiltert ist?

Posted: Sat Dec 19, 2020 1:28 pm
by Karl-Heinz
Hallo Gerhard,

mit DBOrderInfo(DBOI_POSITION) kann man erkennen ob ein geänderter DS noch in einen Scope passt. Setze ich auf meine Testdaten einen "G" Scope zeigt mir DBOrderInfo(DBOI_POSITION) diese Positionen an:

Code: Select all

Goethe		- 1		
Goldmann	- 2	
Göbel		- 3	
Göthe		- 4	
Götz		- 5	


Ändere ich "Göbel" zu "Höbel" werden mir - natürlich ohne Refresh - dann diese Positionen angezeigt:

Code: Select all

Goethe		- 1
Goldmann	- 2
Höbel		- 0 <------ ok
Göthe		- 3
Götz		- 4


Verwendet man anstelle einem Scope einen Filter stimmt nach der "Höbel" Änderung die Positionsangabe allerdings nicht.

Code: Select all

Goethe		- 1
Goldmann	- 2
Höbel		- 4 <------- müsste 0 sein
Göthe		- 3
Götz		- 4


Dieses Problem könnte man aber umgehen indem man zuerst einen Scope und dann einen Filter setzt.

P.S. Mit X# zeigt DBOrderInfo(DBOI_POSITION) nach einer Änderung auch bei einem "reinen" Filter die korrekte Position an.

Gruß
Karl-Heinz

Prüfen, ob der aktuelle Datensatz ausgefiltert ist?

Posted: Sat Dec 19, 2020 1:55 pm
by robert
Gerhard,
With DbFilter() you can query for the current filter. If this is not an empty string then you can use the macro compiler to evaluate the filter for the current record. Something like this:

Code: Select all

FUNCTION IsRecordVisibleInFilter as LOGIC
LOCAL cFilter AS STRING
LOCAL lVisible AS LOGIC
cFilter := DbFilter()
IF Empty(cFilter)
  lVisible := TRUE
ELSE
  lVisible := &(cFilter)
ENDIF
RETURN lVisible
Robert

Prüfen, ob der aktuelle Datensatz ausgefiltert ist?

Posted: Sat Dec 19, 2020 3:57 pm
by g.bunzel@domonet.de
Hallo Karl-Heinz und Robert,

vielen Dank für die Antworten.

Ich habe inzwischen schon eine Lösung dafür erstellt - auch für ADS, da hier der macro compiler so evtl. nicht funktioniert:

// Passen die aktuellen Änderungen in einen aktiven Filter...
cFilter := oServer:Filter
IF SLen(cFilter) > 0
IF oServer:IsADS
IF (hTable := oServer:Info( DBI_GET_ACE_TABLE_HANDLE )) != 0
// find out if this is a valid expression
uRetVal := AdsIsExprValid( hTable, String2Psz(cFilter), @bValidExpr )
IF bValidExpr != 0
// now find out what type of expression this is
uRetVal := AdsEvalTestExpr( hTable, String2Psz(cFilter), @uExprType )
IF uRetVal == AE_SUCCESS
DO CASE
CASE uExprType == ADS_LOGICAL
uRetVal := AdsEvalLogicalExpr( hTable, String2Psz(cFilter), @bResult )
CASE uExprType == ADS_STRING
CASE uExprType == ADS_NUMERIC
ENDCASE
IF uRetVal == AE_SUCCESS
IF bResult == 0
// Record is NOT in filter
oServer:Skip(1)
IF oServer:EoF
oServer:Skip(-1)
IF oServer:BoF
oServer:GoTop()
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
cbFilter := &( "{ || " + cFilter + " }" )
IF .NOT. oServer:__DBServerEval( cbFilter, ;
NIL, ;
NIL, ;
1, ;
NIL, ;
FALSE, ;
DBCCON, ;
DBCCUPDATE )
oServer:Skip(1)
IF oServer:EoF
oServer:Skip(-1)
IF oServer:BoF
oServer:GoTop()
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF


Danke und Gruss

Gerhard