Seite 1 von 1
Anomalie mit SELECT [ERLEDIGT]
Verfasst: Di, 22. Jan 2013 10:49
von Rolf
Guten Tag
Beim Zerlegen einer großen Datei in mehrere kleinere (je nach Gruppe), feuerte in der DO WHILE das EOF() zu zeitig, dannach habe ich es mit FOR NEXT probiert auch da gab es Probleme. Später bekam ich mit das es immer an der Stelle Probleme gab, wie der SELECT-Bereich (z.b. 4) lautetete.
Bsp.:
Code: Alles auswählen
FUNCTION xTest()
LOCAL iPos := 0
LOCAL iCount := 0
LOCAL cAP := ""
LOCAL aDbf := {}
LOCAL cMerk := "--"
LOCAL cSGRUP
LOCAL cPZNR
//** DEMO-Datei erzeugen
SELECT 158
aAdd(adbf, {"SGRUP" , "C", 4, 0 })
aAdd(adbf, {"POSNR" , "C", 8, 0 })
dbcreate( cAP+"PzGr.dbf", aDbf )
use (cAP+"PzGr.dbf")
//-- 160
iCount = 160
FOR iPos = 1 to iCount
APPEND BLANK
replace SGRUP with Alltrim(str(iPos))
replace POSNR with "12345678"
APPEND BLANK
replace SGRUP with Alltrim(str(iPos))
replace POSNR with "11111111"
APPEND BLANK
replace SGRUP with Alltrim(str(iPos))
replace POSNR with "22222222"
APPEND BLANK
replace SGRUP with Alltrim(str(iPos))
replace POSNR with "33333333"
APPEND BLANK
replace SGRUP with Alltrim(str(iPos))
replace POSNR with "44444444"
APPEND BLANK
replace SGRUP with Alltrim(str(iPos))
replace POSNR with "55555555"
APPEND BLANK
replace SGRUP with Alltrim(str(iPos))
replace POSNR with "66666666"
APPEND BLANK
replace SGRUP with Alltrim(str(iPos))
replace POSNR with "77777777"
APPEND BLANK
replace SGRUP with Alltrim(str(iPos))
replace POSNR with "88888888"
APPEND BLANK
replace SGRUP with Alltrim(str(iPos))
replace POSNR with "99999999"
NEXT
use
//** FEHLER ??
//SELECT 158 //-- PzGr.dbf // GEHT NICHT ANOMALIE bei 158
SELECT 4 //-- PzGr.dbf // GEHT NICHT ANOMALIE bei 4
SELECT 4 //-- PzGr.dbf // GEHT NICHT ANOMALIE bei 4
//SELECT(4) //-- PzGr.dbf // GEHT
use (cAP+"PzGr.dbf") shared
aDbf := DbStruct()
//DO WHILE !EOF()
iCount := LASTREC()
FOR iPos = 1 to iCount
//SELECT 158 //-- PzGr.dbf // GEHT NICHT ANOMALIE bei 158
SELECT 4 //-- PzGr.dbf // GEHT NICHT ANOMALIE bei 4
//SELECT(4) //-- PzGr.dbf // GEHT
GOTO iPos
cPOSNR := POSNR
cSGRUP := SGRUP
//cZeroGrup := StrZero(val(cSGRUP),5) //-- GEHT
cZeroGrup := alltrim(cSGRUP) //-- GEHT NICHT
if(cMerk == cZeroGrup)
else
cMerk := cZeroGrup
//Msgbox(cMerk)
@ Row(),Col() SAY cMerk+";"
SELECT 1 //-- Tempfile
dbcreate( cAP+Alltrim(cZeroGrup)+".dbf", aDbf )
use (cAP+Alltrim(cZeroGrup)+".dbf") shared
endif
SELECT 1 //-- Tempfile
APPEND BLANK
replace SGRUP with cSGRUP
replace POSNR with cPOSNR
// SELECT 4
// SKIP
// ENDDO
NEXT
CLOSE ALL
//Msgbox("Fertig")
@ 24,Col() SAY "FERTIG - Taste..."
RETURN NIL
Wenn ich die Funktion ausführe erhalte ich
SELECT 4 -> in PPO dbSelectArea( "4" )
"1;2;3;4;;4;;4;;4;;4;;5;6;7;8;9;"
bei SELECT(4) -> in PPO dbSelectArea( (4) )
"1;2;3;4;5;6;7;8;9;"
auch wenn ich die Datei anders nennen also mit StrZero(val(cSGRUP),5) funktioniert es.
ich weiß das man SELECT <nWorkArea> | <cAlias> übgeben kann
Gibt es dafür schon ein PDR oder sollte man eins eröffnen?
Wenn ja wo auf der Alaska-Seite macht man das?
Win 7 32 Bit
XBase 1.9.331
Liebe Grüße
Rolf
Re: Anomalie mit SELECT
Verfasst: Di, 22. Jan 2013 10:54
von Manfred
Hi Rolf,
PDR werden nur von Alaska Leuten eröffnet.
Ich würde auf jeden Fall erstmal alle Select Nr. in DbSelectarea("dbname") usw ändern (eigentlich generell überall die Tabelle mit Alias Pfeil angeben), damit Du und alle anderen auch den Überblick haben. Evtl. könnte sich dadurch schon so einiges ergeben. bei der reinen Nummernangabe besteht die große Gefahr sich total zu verhaspeln. Nur mal so für den Anfang.
Re: Anomalie mit SELECT
Verfasst: Di, 22. Jan 2013 11:02
von Tom
Workarea # 158 ist selektiert, dann machst Du ein "USE" ohne Parameter, was zur Schließung der Tabelle in der selektierten Workarea # 158 führt. Kein Wunder, dass Du dann nicht mehr mit der Tabelle in dieser Workarea arbeiten kannst.
Ist ohnehin sinnvoller - und eleganter - mit Aliasen zu arbeiten. Diese Workareanummern sind nicht sehr handlich.
Re: Anomalie mit SELECT
Verfasst: Di, 22. Jan 2013 12:01
von brandelh
Hi,
ich finde auch die String Aliase unhandlich da bei mehrfacher Öffnung der Namen nicht eindeutig ist.
Ich überlasse es dem System eine freie Workarea zu suchen und nutze eine Variable mit dem Select-Bereichswert.
Code: Alles auswählen
nAltSelect := select()
USE (cArtikelStammDBF) NEW ... // öffnet die Datei in einer freien Workarea
if neterr() // NIE VERGESSEN !!!
... Fehlermeldung
else
nArtikelStamm := select()
cAlias := alias()
...
endif
* (cAlias)->(used()) // GIBT einen Fehler, wenn die Datei nicht geöffnet oder schon geschlossen wurde !
if (nArtikelStamm)->(used()) // gibt NIE einen Fehler
(nArtikelStamm)->(dbCloseArea())
endif
select (nAltSelect) // nur zur Sicherheit, besser spricht man immer alles so an: [b](nArtikelStamm)->[/b]
In einer GUI Anwendung lege ich die Variable für den Select-Bereich in Instanzvariablen des Fensters, somit hat jedes Fenster seine DBF.
Mit fixen Namen für select Bereiche geht sowas nicht und auch fixe Aliasnamen sind problematisch, wenn man sie nicht nach der Öffnung ermittelt.
Re: Anomalie mit SELECT
Verfasst: Di, 22. Jan 2013 12:07
von Tom
ich finde auch die String Aliase unhandlich da bei mehrfacher Öffnung der Namen nicht eindeutig ist.
Deshalb
vergebe ich Aliase.
Re: Anomalie mit SELECT
Verfasst: Di, 22. Jan 2013 12:55
von brandelh
Tom hat geschrieben:ich finde auch die String Aliase unhandlich da bei mehrfacher Öffnung der Namen nicht eindeutig ist.
Deshalb
vergebe ich Aliase.
ich bin mit sicher, dass du weißt was du tuest, aber bei mehreren Fenstern ist es einfach einfacher sich nicht darum kümmern zu müssen
und einfach den Rückgabewert von select() zu verwenden.
Computer mögen INTEGER Zahlen eh lieber als Zeichenketten
Wer weiß was er tut kann immer alles machen, aber viele Anfänger oder Umsteiger von Clipper tun sich damit schwer und warum nicht die einfachste Lösung wählen die funktioniert
Re: Anomalie mit SELECT [ERLEDIGT]
Verfasst: Di, 22. Jan 2013 13:17
von Tom
aber bei mehreren Fenstern ist es einfach einfacher sich nicht darum kümmern zu müssen
Bei abhängigen Fenstern - also Eltern-Kind-Dialog-Relationen -
will ich mich darum kümmern. Es wäre - aus meiner Sicht - unsaubere Programmierung, das nicht zu tun, vor allem beim Schließen von Dateien. Bei mehreren Fenstern, die immer wieder dieselben Dialoge anzeigen, wird mit Multithreading gearbeitet. Und da sind die Workareas gekapselt.
Re: Anomalie mit SELECT [ERLEDIGT]
Verfasst: Di, 22. Jan 2013 13:18
von Tom
Mich würde allerdings schon interessieren, wodurch sich die Threadfrage erledigt hat. Eine "Anomalie mit SELECT", wie der Titel besagt, wäre sicher recht interessant - gäbe es tatsächlich eine.
Re: Anomalie mit SELECT [ERLEDIGT]
Verfasst: Di, 22. Jan 2013 14:11
von brandelh
Tom hat geschrieben:aber bei mehreren Fenstern ist es einfach einfacher sich nicht darum kümmern zu müssen
Bei abhängigen Fenstern - also Eltern-Kind-Dialog-Relationen -
will ich mich darum kümmern.
Es wäre - aus meiner Sicht - unsaubere Programmierung, das nicht zu tun, vor allem beim Schließen von Dateien.
klar kümmert sich hier mein ELTERNFENSTER um alle Dateien ... ich war ungenau und meinte "mehreren Fenstern der gleichen Art"
Tom hat geschrieben:Bei mehreren Fenstern, die immer wieder dieselben Dialoge anzeigen, wird mit Multithreading gearbeitet. Und da sind die Workareas gekapselt.
wenn du dazu Threads verwendest, OK, ich nicht
Re: Anomalie mit SELECT [ERLEDIGT]
Verfasst: Di, 22. Jan 2013 14:12
von Rolf
@Tom
Workarea 158 war nur zum anlegen der Testdatei (Oberer Teil des Code-Blockes)
Das eigentliche Problem war der Unterschied zwischen.
SELECT 4 -> in PPO dbSelectArea( "4" )
SELECT(4) -> in PPO dbSelectArea( (4) )
in Verbindung mit einer Datei "4.dbf",
welches zu einem Fehlverhalten führte z.B. bei EOF() mit DO WHILE oder beim Auslesen eines Feldes mit FOR NEXT.
Die ganze Routine war für mich nur notwendig um eine Datenbank mit über 1 Million Datensätzen zu zerlegen.
Also betraf es nur eine Konvertierungsroutine.
Den Thread habe ich als [ERLEDIGT] markiert, weil meine Frage ob es sich um ein PDR handelt oder wie man sich verhalten sollte von Manfred beantwortet wurde. Der Workaround ist auch durch die Klammerung bei Select oder durch StrZero() für den Dateinamen gegeben.
Ich habe diesen Thread eröffnet um ggf. andere auf das Problem hinzuweisen, weil ich befürchtetete, dass dies auch an anderen Stellen in meinen Programmen Fehler verursachen könnte. Als mir aber bewusst wurde das die Fehlerursache auch am Dateinamen hängt und dieser Fall mit hoher Wahrscheinlichkeit nicht eintritt, war ich beruhigt.
Viele Grüße
Rolf
Re: Anomalie mit SELECT [ERLEDIGT]
Verfasst: Di, 22. Jan 2013 14:18
von brandelh
Rolf hat geschrieben:
Das eigentliche Problem war der Unterschied zwischen.
SELECT 4 -> in PPO dbSelectArea( "4" )
SELECT(4) -> in PPO dbSelectArea( (4) )
in Verbindung mit einer Datei "4.dbf", welches zu einem Fehlverhalten führte z.B. bei EOF() mit DO WHILE oder beim Auslesen eines Feldes mit FOR NEXT.
und genau das ist der Grund warum man den alten Zopf mit den Selectbereichen (diese per Nummer zu verwalten) lassen sollte wo er hingehört:
dBase Geschichte
Aber jeder wie es ihm beliebt
Re: Anomalie mit SELECT [ERLEDIGT]
Verfasst: Di, 22. Jan 2013 14:32
von georg
Hallo, Rolf -
hast Du mal in die Dokumentation geschaut?
Es gibt eine Funktion, Select(), und einen Befehl SELECT.
SELECT 4 verwendet den Befehl und wählt die Workarea 4 aus.
SELECT(4) verwendet die Funktion Select(), und die erwartet einen Alpha-Wert, nämlich den Namen der Workarea.
Re: Anomalie mit SELECT [ERLEDIGT]
Verfasst: Di, 22. Jan 2013 14:55
von brandelh
Es kommt noch schlimmer
Handbuch hat geschrieben:Hinweis: Nach dem Befehl SELECT kann ein Ausdruck in ()-Klammern angegeben werden. Dadurch wird der Befehl syntaktisch identisch zu dem Funktionsaufruf Select(). Der Befehl SELECT wird vom Präprozessor zu dem Funktionsaufruf DbSelectArea() übersetzt, die eine Workarea auswählt. Daher wird der Funktionsaufruf Select() zu DbSelectArea() übersetzt, solange er nicht Teil eines Ausdrucks
bei mir hat die Unterscheidung aber immer funktioniert, ich nutze beide um den Selectbereich in Funktionen zu speichern und zurückzusetzen:
Re: Anomalie mit SELECT [ERLEDIGT]
Verfasst: Di, 22. Jan 2013 15:15
von georg
Hallo, Hubert -
Select() habe ich schon lange nicht mehr verwendet, aber ... der Preprozessor kann nicht entscheiden, was nSelectArea für einen Feldtyp zur Laufzeit haben WIRD, aber "4" ist ein Literal und bereits zur Compile-Zeit bekannt, und wird daher (wahrscheinlich) "doppelt geklammert", wie:
oder
Re: Anomalie mit SELECT [ERLEDIGT]
Verfasst: Di, 22. Jan 2013 15:20
von UliTs
brandelh hat geschrieben:...
und genau das ist der Grund warum man den alten Zopf mit den Selectbereichen (diese per Nummer zu verwalten) lassen sollte wo er hingehört: dBase Geschichte
Also ich bin mir nicht sicher, wie Du es meinst.
Alaska (Steffen Pirsig) empfiehlt ausdrücklich die Verwendung der Select-Nummern!
Man sollte diese (natürlich) nicht mittels
verwenden, sondern grundsätzlich mittels Variablen
Code: Alles auswählen
DbUseArea( TRUE/*lNewArea*/,... )
nTableBlaBla := select()
...
(nTableBlaBla)->BlaBla
Dann kann man auch wunderbar die Tabelle als Parameter in Funktionen oder innerhalb Klassen verwenden!
Und wenn man grundsätzlich den aktuellen Selectbereich so einstellt, dass da KEINE Tabelle geöffnet ist, kann man auch halbwegs die Nebenwirkungen aufgrund der fehlenden Kapselfähigkeit der Selectbereiche eliminieren.
Uli
Re: Anomalie mit SELECT [ERLEDIGT]
Verfasst: Di, 22. Jan 2013 15:48
von brandelh
Hallo ULI,
genauso meinte ich es
(diese per Nummer zu verwalten)
war wohl nicht so deutlich, sollte ausdrücken, schlecht ist es direkt die ZAHL im Quellcode zu schreiben ( select 1 // Stammdaten ...)
statt diese in einer Variablen zu verwalten ( nStammdaten := select() ) ...
Re: Anomalie mit SELECT [ERLEDIGT]
Verfasst: Di, 22. Jan 2013 16:22
von UliTs
Das ist doch schön, wenn man einer Meinung ist
Uli
Re: Anomalie mit SELECT [ERLEDIGT]
Verfasst: Di, 22. Jan 2013 17:11
von Tom
Es gibt viele Wege, und keiner davon ist grundfalsch, außer vielleicht der Spaghettiansatz. Wenn ich mit konkreten Aliasen arbeite, kann ich beispielsweise in fallweise genutzten Funktionen Dateien einmalig öffnen, die von dieser Funktion wiederholt verwendet werden, und weiß über den Alias, ob das bereits geschehen ist - ohne Kenntnis der aufrufenden Funktion, also allgemein verwendbar. Okay, auch dafür gäbe es andere Ansätze, aber
unzulässig ist keiner davon. Auch einen Alias kann ich so verwenden:
Code: Alles auswählen
cAlias := 'whatever'
USE MeineDatei ALIAS (cAlias) NEW
(cAlias)->(DbSeek('test')) // usw.
Ich habe mal spaßenshalber eine ohnehin vorhandene Testroutine, die die Datenperformance ermittelt, auf die numerischen Rückgaben der Select-Funktion umgestellt. Kein Unterschied. Warum hatte Steffen empfohlen, so zu arbeiten?
Re: Anomalie mit SELECT [ERLEDIGT]
Verfasst: Di, 22. Jan 2013 19:00
von azzo
Hallo,
>cAlias := 'whatever'
>USE MeineDatei ALIAS (cAlias) NEW
Ich verwende die Funktion - cGetNewAlias damit ich auch eine Datei mehrmals öffnen kann.
lg
Otto
local cAlias := cGetNewAlias( 'CUST' ) // Returns string like "Cust001" (If "Cust" is already used)
USE CUSTOMER NEW SHARED Alias ( cAlias )
function cGetNewAlias( cAlias )
*******************************
local cNewAlias, nArea := 1
if Select( cAlias ) != 0
while Select( cNewAlias := ( cAlias + ;
StrZero( nArea++, 2 ) ) ) != 0
end
else
cNewAlias = cAlias
endif
return ( cNewAlias )
(
http://fivetechsupport.com/forums/viewt ... 71&start=0)
Re: Anomalie mit SELECT [ERLEDIGT]
Verfasst: Di, 22. Jan 2013 21:45
von UliTs
Tom hat geschrieben:Warum hatte Steffen empfohlen, so zu arbeiten?
Ist das aus meiner Antwort nicht ersichtlich gewesen?
-
Wenn man die gleiche Funktionalität mit Alias-Bezeichnungen erreichen will, muß man entsprechend Aufwand betreiben, wie man auch schön anhand Azzo's Antwort sehen kann.
Das ist bei Benutzung von Select-Nrn. nicht notwendig, wenn man DbUseArea mit Parameter lNewArea=TRUE verwendet. xBase nimmt einem so die Arbeit ab.
-
Tom, siehst Du denn einen Vorteil, wenn man mit cAliasBlaBla := "BlaBla" oder ähnlichem arbeitet?
Uli
Re: Anomalie mit SELECT [ERLEDIGT]
Verfasst: Di, 22. Jan 2013 22:00
von Tom
Tom, siehst Du denn einen Vorteil, wenn man mit cAliasBlaBla := "BlaBla" oder ähnlichem arbeitet?
Meine Aliase identifizieren
Bedeutung und Verwendung (!) einer Tabelle. Das gilt auch und insbesondere für Mehrfachverwendungen. Es gibt bei mir auch hunderte von Tabellen, die periodenbezogen erzeugt und verwaltet werden (etwa für monatsbezogene Planungssystematiken), und deren Aliase dann Auskunft darüber geben, für welchen Zeitraum sie gelten und warum sie geöffnet sind, etwa für Auswertungen
oder Bearbeitungen.
Auf diese Art kann ich in allgemeinen Funktionen, die bestimmte Daten erheben/zurückliefern, prüfen, ob die hierfür nötigen Tabellen bereits geöffnet sind, und, wenn ja, ob das auch für den richtigen Zweck erfolgt ist. Wenn nicht, werden sie geöffnet - und bleiben auch offen. Solche Funktionen werden aus diversen Modulen heraus verwendet, liefern immer die richtigen Daten, müssen sich aber um die Verwaltung der Tabellen nicht scheren. Für das ordentliche Schließen solcher Tabellen sorgen die aufrufenden Module über wiederum allgemeine Funktionen. All das ist auch noch von vielen Optionen und Einstellungen abhängig. Es wäre aber sinnlos und verlangsamend, zum Beispiel solche Tabellen im Vorfeld zu öffnen. Möglicherweise werden sie nämlich überhaupt nicht benötigt. Ist nur
ein Beispiel von vielen. Kurz gesagt: Wenn Used() mit dem richtigen Parameter ein .T. zurückliefert, weiß ich, dass eine bestimmte Tabelle zu einem bestimmten Zweck geöffnet, ungesperrt (!) und nutzbar ist.
Das klingt vielleicht alles ein bisschen merkwürdig und schwer nachvollziehbar, ist aber ein komplexes, ausgeklügeltes und optimiertes System. Zudem threadsafe - und viel schneller als alle Alternativen, die ich ausprobiert habe, einschließlich die hier genannten. Es endet allerdings nicht hiermit, sondern führt noch sehr viel weiter. Das würde aber den Rahmen sprengen.
Re: Anomalie mit SELECT [ERLEDIGT]
Verfasst: Di, 22. Jan 2013 22:17
von UliTs
Hallo Tom,
dass Deine Vorgehensweise ohne Kapselung insbesondere bei xBase viel schneller ist, kann ich mir gut vorstellen.
Ich versuche vollständig auf globale Variablen zu verzichten. Mich stört es schon sehr, dass man die Select-Bereiche nicht "Function-Safe" oder "CLASS-Save" machen kann
. Und jede Funktion oder Klasse schließt bei mir möglichst auch alle Tabellen, die sie zuvor geöffnet hat; es sei denn, die Tabelle wurde als Parameter übergeben
.
Wenn man aber sehr diszipliniert (und nur dann!) damit umgeht und als einziger an einem Projekt arbeitet, ist Deine Art sicher auch sehr gut!
Uli
Edit: Tippfehler korrigiert
Re: Anomalie mit SELECT [ERLEDIGT]
Verfasst: Mi, 23. Jan 2013 9:13
von brandelh
Hallo ULI,
ich kann mich deinen Ausführungen nur VOLL ANSCHLIEßEN
Hallo TOM,
ich denke ich habe oben mehrfach betont, dass DU sicher weißt was du tust.
Natürlich ist es auch nicht falsch eine vorhandene Funktionalität zu nutzen, aber es gibt eben sicherere und einfacherere Wege als den Alias.
Dass dein Alias über den Namen eine Bedeutung hat ist aber nichts besonderes, Dateien mit D1 bis D? zu benennen ist ja wohl lange nicht mehr üblich.
Ich mache das über den VariablenNamen grundsätzlich und natürlich auch bei denen der Selectbereiche:
Beispiel:
Kopieren von Quelle nach Ziel, egal wie der Dateiname wirklich lautet ...
nQuelle und
nZiel,
nStammdaten,
nRechnungsStammdaten etc. alles einfach zu verstehende Bezeichnungen mit denen jeder weiß was gemeint ist.
An Alle,
gerade ich bin nicht so schnell bereit erprobte Vorgehensweisen umzustellen, weshalb ich mich auch mit der VX schwertue.
Solange man also mit seinem Vorgehen gut zurecht kommt OK
Für die, welche neu anfangen oder jene, die offensichtlich Probleme wegen dieses (oder eines anderen) Ansatzes haben, sollten sich an die (für sie) einfachste Methode halten die sicher funktioniert
Re: Anomalie mit SELECT [ERLEDIGT]
Verfasst: Mi, 30. Jan 2013 0:35
von AUGE_OHR
Rolf hat geschrieben:in Verbindung mit einer Datei "4.dbf"
versuche doch mal "4.DBF" mit DBU (original) zu öffnen ...
Nicht erlaubte Zeichen im ALIAS: 4
wenn man nicht explizit ein ALIAS angibt wird der DBF Name genommen aber eine Ziffer allein mag Cl*pper / Xbase++ nicht.