[phpBB Debug] PHP Warning: in file [ROOT]/ext/tas2580/privacyprotection/cron/task/anonymize_ip.php on line 83: A non-numeric value encountered
Inoffizielles deutsches Xbase-Forum • Anomalie mit SELECT [ERLEDIGT]
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. :wink:

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. :wink:
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 :D
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 8)

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. :wink:

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. :wink:

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. :wink:
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 :D

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:

Code: Alles auswählen

nAltSelect := select()
select (nAltSelect)

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:

Code: Alles auswählen

USE "Datei"
oder

Code: Alles auswählen

cDatei := "Datei"
USE (cDatei)

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

Code: Alles auswählen

4->BlaBla
oder
(4)->BlaBla
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! :D

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. 8)

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 :o :) :D
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 :shock: . 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. :D
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.