locked
Programm greift nicht auf auch externen DBC zu... RRS feed

  • Frage

  • Hallo Leute,

    ich hab mal wieder ein Problem. Ich habe in Foxpro ein Programm geschrieben welches mir aus einer Textdatei ID Nummern extrahiert die ich später intern Überprüfen möchte. Es soll also geschaut werden ob die ID Nummer aus der txt-Datei den gleichen Standort besitzt wie im System. Nun will ich mit meinem Programm gerne den DBC von meiner DB anzapfen, wobei ich aber mein Problem hab.

    RE_ORADB = "C:\Revk\Re_oradb.dbc"
    OPEN DATABASE RE_ORADB
    MESSAGEBOX("Datenbank verknüpft")
    USE RE_ORADB!v_re_begle
    MESSAGEBOX("RE_BEGLE ALS USE  TEST")
    
    CREATE TABLE KORR_TABELLE (Id_nr C(25), Ziel c(5),Nstandort c(5),OLD_Standort c(5))
    For i=1 to ALEN(lcScanImport)
    SELECT a.Id_nr,a.Ziel,b.Nstandort INTO KORR_TABELLE FROM lcScanImport as a, v_re_begle as B WHERE a.Id_nr=b.Id_nr
    
    
    DO 	CASE
    	CASE SELECT NStandort FROM KORR_TABELLE = Ziel THEN
    	MESSAGEBOX("Datei bereit zum Importieren")
    	QUIT
    	
    	CASE NStandort = "   %" THEN 
    	Messagebox("Für das Gebinde gab es keinen eingetragenen Zielstandort!",64)
    		
    	QUIT
    
    	CASE NStandort <> Ziel THEN
    	Antwort= MESSAGEBOX("Test 123",4)
    		DO  CASE
    			CASE Antwort = 6
    			   		
    		Messagebox ("You chose Yes")
      			
    			
    			CASE Antwort = 7
      		Messagebox("You chose No")
    				
    		ENDCASE
    		QUIT
    ENDIF

    Zusätzlich weiß ich leider nicht warum er mir nichtmal eine Fehlermeldung bringt. Er findet die ID und das ZIEL aus der TXT... Aber wenn er es dann Vergleichen soll, macht er einfach im CODE weiter, wenn ich kein QUIT eingebaut hätte, saust er einfach alle Fälle durch....

    Wobei benötige ich also Hilfe? Ich würde gerne auf einen externen DBC zugreifen bzw auf eine bestimmte Tabelle (aus dem DB-System) und eine Fall Unterscheidung einführen. Er soll mich quasi Fragen, ob ich den Standort aus der Txt übernehmen will oder den Standort aus dem System behalten will....

    Über erleuchtende Hilfe wäre ich sehr Dankbar.

    Gruß Radioaktivman  

     
    Donnerstag, 13. August 2015 11:59

Antworten

  • Der Screen ist das Foxpro Hauptfenster. Also wenn Du Foxpro selbst (vfp9.exe) startest, siehst Du nix als den Screen. Allerdings wirkt das Kommando ? nicht nur auf den Screen, es zeigt Text im aktiven Formular an, wenn man nicht vorab ACTIVATE SCREEN macht. Der einfache Errorhandler, der direkt nur einen Befehl nach dem ON hat, kann nicht vorher noch ACTIVATE SCREEN ausführen.

    In dem Fall wäre es wohl einfacher, Du läßt die Zeile weg, dann kriegst Du wieder jede Fehlermeldung als Messagebox. Ich weiß nicht in welcher Situation Du letztes Mal warst, dass wir mal die Fehleranzeige einfach auf den Schirm geschrieben hatten, der "Vorteil" ist, das Programm fährt einfach fort, man kann ein paar Fehler sehen, aber das ist auch ein Nachteil, ein Programm scheint abgesehen von diesen Meldungen zu gehen, insbesondere wenn es Compiliert, obwohl die Befehlskonstrukte so gar nicht ausführbar sind.

    >Wie kann ich eine Tabelle via Select ansprechen die nicht Teil des Programms ist?

    Du meinst, die kein DBF ist.

    Wir reden jetzt wohl von den Oracle Daten. Du hast einen DBC, den Re_oradb.dbc, der enthält aber keine Tabellen. Schau nochmal genauer hin mit MODIFY DATABASE, der DBC enthät Views statt DBFs und zwar remoteviews. Das RE steht wohl auch für Remote.

    Remote heißt entfernt, nicht unbedingt in Australien, u.U. sogar immer noch im LAN oder sogar an Deinem PC; aber nicht DBF. Die Remoteviews sind nicht viel mehr als SQL-Abfragen, die diese remotedaten einlesen in einen Cursor.

    D.h. Der Befehl USE RE_ORADB!v_re_begle sertzt die SQL-Abfrage, die den View v_re_begle definiert an die Oracle DB ab und Du hast dann wie durch den CREATE CURSOR lcSanImport einen Cursor der den Aliasnamen v_re_begle hat.

    Mach Da mal einen Breakpoint bzw. das schon erwähnte SET STEP ON und dann wirst Du per BROWSE die von Oracle abgefragen Daten sehen.

    Die Daten aus Scandatei im lcScanImport Cursor und v_re_begle View lassen sich nun z.B. mit weiterem SQL oder anderen Mitteln des Zugriffs auf Cursoren und deren Datensätze vergleichen. Dein eigentliches Problem ist nicht, dass Du nicht an Daten kommst, Du hast Sie schon beisammen, Dein Problem ist die Vielzahl von Fehlern in Deinem Programm, da bin ich erst einmal ratlos.

    Abschließend etwas über Namensgebung: lcScanImport sieht für mich und viele hier Nach dem Namen einer Variablen aus, nicht nach einem Cursor. Die ersten beiden Buchstaben stellen Gültigkeitbereich und Typ dar. L steht für Local und C für Character, also eine lokale Stringvariable. Wenn Du einen Cursor per CREATE CURSOR machst, dann geb eher den Prefix cur oder crs, das macht das nachvollziehbarer. Ein SELECT * FROM lcScanImport sieht aus, als würdest Du von einer Variable selektieren wollen. Das trägt zur Verwirrung bei und macht Deinen Code nicht nachvollziehbar. Noch dazu hattest Du in Deinem Ersten Posting ALEN(lcScanImport), und ALEN geht nur bei Arrays. Die Anzahl der Datensätze eines Cursors lcScanImport sind RECCOUNT("lcScanImport"). Ich war also doppelt verwirrt. Du siehst wie wichtig es ist, sich an Komventionen zu halten. Nicht nur Du selbst, auch andere kommen mit Deinem Code dann ncht mehr klar.

    Dewegen belächle ich auch immer wieder Leute die meinen Namenskoonventionen sind sinnlos, weil die Mittel der Reflektion (in .NET ist das ein größeres Thema) Typen und Klassen ermitteln lassen und Intellisense zur Entwicklungszeit schon hilft. Wenn Du aber nur ein Stück Code eines Fremden in einem Forum liest, sind Namenskonventionen und sich daran haltende Programmierer das einzige, was solche Metainformationen mit rüber bringt, auch wenn das nicht verbindlich richtig sein muß. Letzteres heißt, nur weil man eine Variable lcString nennt, ist VFP selbst das egal, es nimmt es auch als Cursornamen oder läßt zu da eine Zahl oder sonstiges zu speichern.

    Wenn Du Code geändert hast, der vorher die Scandatei per FILETOSTR in eine Stringvariable liest, indem Du sie eben stattdessen per APPEND in einen Cursor einlist, dann funktioniert eine Menge nicht mehr, was davon ausgeht es noch mit einem String zu tun zu haben. So eine Umstelung ist nicht verkehrt, weil man nun statt eines Strings ein oder mehrere Datensätze mit Feldnamen hat. Aber das umzustellen erfordert eine Menge Ubauarbeiten. Wenn der komplette Satz an Daten vorher mal in einem String stand, konnte man da per AT() oder $ OPerator Teilstrings suchen und finden, aber ganz unspezifisch an welcher Stelle mit welcher Bedeutung, einen Cursor zu haben erlaubt jetzt ja z.B. im Feld Standort oder Ziel gezielt zu Suchen.

    Tschüß, Olaf.


    Olaf Doschke - TMN Systemberatung GmbH

    http://www.tmn-systemberatung.de

    Samstag, 22. August 2015 06:01

Alle Antworten

  • Hi :)

    anbei erst einmal ein wenig Mustercode, um Dir eine der vielen Möglichkeiten aufzuzeigen, wie Du in VFP Textdateien verarbeiten kannst.

    Das Beispiel geht von einer Textdatei aus, die je Zeile (mit CRLF getrennt) ZWEI Felder mit KOMMA (,) voneinander separiert enthält. Zusätzlich ist das Textfeld in Anführungszeichen gesetzt. Ist dies nicht der Fall, dann muss aus dem Mustercode nur die STREXTRACT() Funktion entfernt werden.

    Desweiteren gibt es im Muster eine Tabelle die aus zwei übereinstimmenden Feldern besteht, einem ID Feld und einem Textfeld.

    Bei größeren Tabellendefinitionen ist logischerweise ein wenig mehr Extraktionscode notwendig, aber letztlich wiederholt sich das Spiel einfach nur.

    * // DB Tabelle simulieren
    CREATE CURSOR crsTest ( test_pk i, test_text c(10) )
    INSERT INTO crsTest( test_pk, test_text ) VALUES ( 1 , [Satz 01] )
    INSERT INTO crsTest( test_pk, test_text ) VALUES ( 2 , [Satz 02] )
    INSERT INTO crsTest( test_pk, test_text ) VALUES ( 3 , [Satz 03] )
    INSERT INTO crsTest( test_pk, test_text ) VALUES ( 4 , [Satz 04] )
    INSERT INTO crsTest( test_pk, test_text ) VALUES ( 5 , [Satz 05] )
    INSERT INTO crsTest( test_pk, test_text ) VALUES ( 6 , [Satz 06] )
    
    * // Textdatei simulieren und Blanks, Tabs und Leerzeilen entsorgen
    LOCAL lcBulkData as String, liRows as Integer, liLoop as Integer, lcRow as String
    TEXT TO lcBulkData TEXTMERGE NOSHOW PRETEXT 1+2+4
    	
    	2,"Satz 02 aktuell"
    	5,"Satz 05 aktuell"
    	7,"Satz 07 neu"
    	8,"Satz 08 neu"
    
    ENDTEXT 
    
    * // _screen aufräumen und Infos anzeigen mit ?, ??
    CLEAR 
    ? [-----Aufbereitung]
    SET MEMOWIDTH TO 40
    liRows = MEMLINES( lcBulkdata )
    FOR liLoop = 1 TO liRows
    	lcRow	= MLINE( lcBulkdata , liLoop )
    	liPk	= INT( VAL( GETWORDNUM( lcRow , 1 , [,] ) ) )
    	lcText	= STREXTRACT( GETWORDNUM( lcRow , 2 , [,] ),["],["])
    	LOCATE FOR test_pk = liPk
    	IF FOUND()
    		* // Altdaten, als evtl. UPDATE nach Rückfrage
    		IF ALLTRIM( crstest.test_text ) <> lcText
    			? [Altdaten:]
    			? crstest.test_pk
    			?? [ | ] + crstest.test_text
    			? [Korrekturdaten:]
    			? liPK
    			?? [ | ] + lcText
    			? [--------------------]
    		ENDIF 		
    	ELSE 
    		* // = Neudaten, also INSERT
    		? [Neudaten:]
    		? liPK
    		?? [ | ] + lcText
    		? [--------------------]
    	ENDIF 
    ENDFOR 
    
    * // Arbeitstablle ensorgen
    USE IN SELECT( [crsTest] )
    * // Arbeitsvariablen entsorgen
    RELEASE lcBulkData
    

    Anstelle der rausgehauenen Textinformationen über ? und ?? müssen im Echtcode logischerweise Infofenster und INSERT/UPDATE Befehle eingesetzt werden. Aber das ist nicht der Sinn dieses Codemusters :)

    Was passiert nun im Detail:

    VFP kann keine Selects auf Textdateien durchführen. Texte müssen zeilenweise ausgelesen, zerlegt und danach validiert werden. Dies passiert innerhalb FOR..ENDFOR Loops. Zum besseren Verständnis solltest Du in der VFP Hilfe die verwendeten Befehle und Funktionen

    SET MEMOWIDTH TO
    MEMLINES()
    MLINE()
    GETWORDNUM()
    STREXTRACT()
    LOCATE FOR
    FOUND()

    ansehen. Sinnvoll wäre es, die Altdaten/Korrekturdaten Validierung mitsamt der Abfragemaske in eine gesonderte Funktion zu kapseln und bei einem positiven Rückgabewert dann einen UPDATE zu starten.

    HTH


    Gruss / Best regards
    -Tom
    Debugging is twice as hard as writing the code in the first place.
    Therefore, if you write the code as cleverly as possible,
    you are, by definition, not smart enough to debug it. 010101100100011001010000011110000101001001101111011000110110101101110011

    Freitag, 14. August 2015 09:43
  • Du machst einige Dinge, die nicht im Sprachumfang von VFP sind und Dir jede Menge Fehler geben müssen.

    Hast Du in dem Objekt, in dem der Code läuft etwas im Error Event außer der LPARAMETERS Zeile? Das würde Fehler z.B. schlucken.

    zu den Unmöglichkeiten:

    1. lcScanImport fällt vom Himmel, da Du eine Schleife bis ALEN(lcScanImport) machst scheint es ein ARRAY zu sein. Soweit nur unschön aber noch nicht falsch.

    2. Du versuchst ein SELECT ... INTO Tabelle FROM, das geht schief, es geht ein INSERT INTO Tabelle SELECT FROM..., es geht auch ein SELECT INTO TABLE Tabelle, das erzeugt aber die Tabelle.

    3. Du versucht in diesem SELECT INTO von dem Array zu selektieren, FROM lcScanImport a. Was es gibt is SELECT INTO ARRAY oder APPEND FROM ARRAY, aber Arrays können nicht als Tabellen in SQL Abfragen dienen, sie können zwar 2d sein, aber die spalten haben keine Namen, ergo können Sie nicht mit SQL angesprochen werden.

    4. Du machst eine SQL Abfrage innerhalb CASE, ein CASE braucht einen boolschen Ausdruck eine Query nutzt boolsche Ausdrücke in seiner WHERE Klausel, ist aber insgesamt kein boolscher Ausdruck, es ist nicht mal eine Funktion die irgendeinen Rückgabetypen hat, es ist ein Kommando.

    An der Stelle macht es keinen Sinn weiter zu lesen, der Code muß einmal komplett neu geschrieben werden. Ich hoffe mit den Augenmerk auf offensichtliche Fehler findest Du heraus, wie Dein Code lauten müsste, ich kann Deine Intention leider nicht wirklich ersehen.

    Tschüß, Olaf.


    Olaf Doschke - TMN Systemberatung GmbH

    http://www.tmn-systemberatung.de

    Samstag, 15. August 2015 08:38
  • Statt auf den Code gehe ich mal hierauf ein:

    Ich würde gerne auf einen externen DBC zugreifen bzw auf eine bestimmte Tabelle (aus dem DB-System) und eine Fall Unterscheidung einführen. Er soll mich quasi Fragen, ob ich den Standort aus der Txt übernehmen will oder den Standort aus dem System behalten will....

    Den Standort von was? Von einer Datei? Von Daten innerhalb einer Tabelle?

    Wie sieht die TXT Datei aus? Was steht drin? Wie ist Du sie ein?

    Tschüß, Olaf.


    Olaf Doschke - TMN Systemberatung GmbH http://www.tmn-systemberatung.de

    Samstag, 15. August 2015 08:41
  • Hallo Leute,

    erst mal Danke für die Lehrreichen antworten. Ich versuche mich in Zukunft präziser auszudrücken.

    Also bei der Standortfrage geht es um Artikel, ob sie in diesem Raum sind oder in einem Anderen. Jeder Artikel hat eine Artikelnr. und einen Standort. In der Datenbank hat jeder Artikel einen Standort. Jetzt komme ich mit einem externen nicht ans Systemgekoppelten Scanner und scanne z.b bei einer Inventur den Artikel. Da ich den Scanner (txt-Datei) importieren muss, wird die txt vorab bearbeitet und geschaut ob der Standort in der Txt vom Scanner der selbe ist wie in der Datenbank.

    Tut mir Leid das ich für Verwirrung gesorgt habe, da ich nicht den ganzen Code gepostet habe. Es ging mir ja wie gesagt hauptsächlich um das Zugreifen der Tabelle der Datenbank.

    Hier nochmal mein ganzer Code:

    SET DEFAULT TO o:\Entsorgung\Datenbanken\DB_Scanner
    ON ERROR ? ERROR(), MESSAGE(),MESSAGE(1), " in ",PROGRAM(), " Zeile", LINENO()
    
    *MESSAGEBOX("Start")
    oFolder = "o:\Entsorgun\Datenbanken\DB_Scanner\Scan_dateien"
    OrdnerInhalt(oFolder)
    FUNCTION OrdnerInhalt
       LPARAMETERS loFolder
       LOCAL lcFiles
       LOCAL lcFile
       LOCAL m.lcCr            AS String
       LOCAL m.lcFileReVK      AS String 
       RE_ORADB as String	   
    
    m.lcCr=CHR(13)+CHR(10)
    
    lcVerzeichnis = "o:\Entsorgung\Datenbanken\DB_Scanner\Scan_dateien\"   
       	nFilesFound = ADIR(aDateien,lcVerzeichnis+"*SAM.csv")
      	lcAnzahl= "Anzahl nFilesFound "+STR(nFilesFound)
       
    *MESSAGEBOX(lcAnzahl)   
       IF nFilesFound <1
    *MESSAGEBOX("Keine Scannerdaten vorhanden")
    EXIT
    endif
    ASORT(aDateien,3,-1,-1)
       
    *MESSAGEBOX("nächster Schritt")
    	FOR i = 1 TO nFilesFound
          Datei= aDateien[ i, 1]
          ScanDat =(aDateien [i,3])
    *MESSAGEBOX (ScanDat)
    *MESSAGEBOX(" Dateiordner "+(Datei))
    
    
          
          Erstelldatum=(aDateien[i,3])
          Erstelldatum = DTOS(Erstelldatum)
          Änderung = aDateien[i,4]
    	*MESSAGEBOX(Datei)
    *MESSAGEBOX(Erstelldatum)	
    *MESSAGEBOX(Änderung)
    Filename =" "
    			
    	
    
    
    				iF "SAM" $ Datei = .T.
    				Filename ="("+ALLTRIM(STR(i))+")"+(Erstelldatum)+"_"+ strtran(Änderung,":","")+"_SAM.txt"
    *MESSAGEBOX("Gefundener Filename "+Filename)
    rename (lcVerzeichnis+Datei) to &Filename
    *MESSAGEBOX ("Filename  : "+lcVerzeichnis +"_" +Filename)
    
    ENDIF
    	CREATE cursor lcScanImport;
    	(Standort c(5), Ziel c(5), Id_nr C(25), Datum c(18), ScanIdent c(3))
    	APPEND FROM (Filename) TYPE DELIMITED 
    
    	
    
    SELECT Standort, Ziel, strTran((Id_nr),"_","/") as ReVK_ID, Datum as KonvDatum, ScanIdent  FROM lcScanImport INTO CURSOR lcScanImport
    	SELECT * FROM lcScanImport
    Messagebox "import LCScanImport erfolgt"
     
    SELECT distinct Ziel FROM lcScanImport INTO Cursor lcZiel			&& Selektiert sämtliche im Import vorkommende Standorte (ohne lcStandort funktioniert DISTINCT beim Array nicht)	
    COUNT all  TO AnzZiel
    *MESSAGEBOX("Cursor-"+STR(AnzStand))
    SELECT distinct Ziel FROM lcScanImport INTO Array aZiel				&& sauberes Array zum Standortauslesen
    COUNT all TO aAnzZiel												&& ermittelt Anzahl der unterschiedlichen Standorte
    *MESSAGEBOX("Array-"+STR(aAnzStand))
    
    FOR x = 1 TO aAnzZiel
    		ScanZiel = aZiel[x,1]										&& weist ScanOrt pro Durchlauf die unterschiedlichen Standorte zu
    		
    *MESSAGEBOX(ScanOrt)
    		m.lcFileReVK=(Erstelldatum+ALLTRIM(ScanZiel)+".TXT") 		&& generiert einen Tabellennamen für jeden Standort
    
    IF FILE (m.lcFileReVK)													&& Tabelle wird gelöscht falls vorher im Verzeichnis 
    DELETE FILE (m.lcFileReVK)
    ENDIF
    
    *MESSAGEBOX(m.lcFileReVK)
    
    *!*			SELECT a.Ausver, a.ReVK_ID, a.KonvDatum, ;   && übernimmt nur den aktuellsten Datensatz pro Gebinde in den Cursor
    *!*			FROM lcScanImport a;
    *!*			left outer Join lcScanImport b on b.ReVK_ID = a.ReVK_ID;
    *!*											 and b.KonvDatum > a.KonvDatum;
    *!*			where b.KonvDatum is NUll;								 
    *!*			INTO CURSOR lcScanImport_2;
    
    		
    
    		SELECT * FROM lcScanImport WHERE Ziel= (ScanZiel) INTO CURSOR lcINV_Ziel	
    *MESSAGEBOX(Konvdatum)
    
    	STRTOFILE("Sammelumsetzen"+m.lcCr,m.lcFileReVK,1)           && Zeile 1 -> Kennung
    	STRTOFILE("-Leer-"+m.lcCr,m.lcFileReVK,1)                  	&& Zeile 2 -> leer bei Inventur
    	STRTOFILE("-Leer-"+m.lcCr,m.lcFileReVK,1)                  	&& Zeile 3 -> leer bei Inventur
    	STRTOFILE((KonvDatum)+m.lcCr,m.lcFileReVK,1)             	&& Zeile 4 -> Datum des Scanns
    	STRTOFILE("TRANS"+m.lcCr,m.lcFileReVK,1)                    && Zeile 5 -> aktueller Standort
    	STRTOFILE(Ziel+m.lcCr,m.lcFileReVK,1)    				    && Zeile 6 -> leer bei Inventur Zielstandort
    	STRTOFILE("-Leer-"+m.lcCr,m.lcFileReVK,1)                   && Zeile 7 -> leer bei Inventur Behandlung
        SCAN
        STRTOFILE((ALLTRIM(UPPER(ReVK_ID)))+m.lcCr,m.lcFileReVK,1)
        ENDSCAN
    			IF FILE(m.lcFileReVK)
    Messagebox ("MELDUNG: Datei wurde generiert:" + m.lcFileReVK)
    			ENDIF
    
    
    *RE_Begle = C:\Revk\Re_oradb.dbc\kwo_REVK_RE_BEGLE
    *Messagebox RE_Begle
    RE_ORADB = "C:\Revk\Re_oradb.dbc"
    OPEN DATABASE RE_ORADB
    MESSAGEBOX("Datenbank verknüpft")
    USE RE_ORADB!v_re_begle
    MESSAGEBOX("RE_BEGLE ALS USE")
    
    CREATE TABLE KORR_TABELLE (Id_nr C(25), Ziel c(5),Nstandort c(5),OLD_Standort c(5))
    For i=1 to ALEN(lcScanImport)
    SELECT a.Id_nr,a.Ziel,b.Nstandort INTO KORR_TABELLE FROM lcScanImport as a, v_re_begle as B WHERE a.Id_nr=b.Id_nr
    
    MESSAGEBOX("Test"+Test)
    
    DO 	CASE
    	CASE SELECT NStandort FROM KORR_TABELLE = Ziel THEN
    	MESSAGEBOX("Datei bereit zum Importieren")
    	
    	QUIT
    	
    	CASE NStandort = "   %" THEN 
    	Messagebox("Für das Gebinde gab es keinen eingetragenen Zielstandort!",64)
    		QUIT
    
    	CASE NStandort <> Ziel THEN
    	Antwort= MESSAGEBOX("Test 123",4)
    		DO  CASE
    			CASE Antwort = 6
    			   		
    			Messagebox ("You chose Yes")
      			
    			
    			CASE Antwort = 7
      		    Messagebox("You chose No")
    				
    		ENDCASE
    		QUIT
    ENDIF

    Das Programm funktioniert soweit, nur dieser Vergleich der Standorte aus lcScan und der ORADB will mir nicht gelingen.
    Montag, 17. August 2015 10:17
  • Ohne zu wissen wie so eine Scannerdatei aussieht hilft auch der komplettte Code wenig.

    Und dito ohne Wissen um die schematische Struktur des Cursor, den z.B. der Viewv_re_begle hat.

    Und sowas muß Dir immer noch bzw. erst recht einen Fehler um die Ohren hauen:

    CASE SELECT NStandort FROM KORR_TABELLE = Ziel THEN

    Eine SQL-Query ergibt Datensätze, keinen Boolwert .T. oder .F. und in diesem Fall ist die SQL-Abfrage sogar noch inkorrekt FROM Tabelle = Ziel gibt es nicht im SQL Sprachumfang.

    Willst Du prüfen, ob Cursorname.NSTandort = Ziel ? Dann tu das. Für welchen Datensatz? Für irgendeinen davon? Mach die Abfrage vorab, und prüfe ab, ob das Ergebnis des SQL einen Datensatz findet, z.B. Reccount()>0 ist. Oder _TALLY>0.

    Und wenn Du das jetzt nicht verstehst, kann ich Dich gut verstehen, ich gebe Dir nämlich nur grob den Ansatz ohne konkret zu werden.

    Tut mir leid, es bleibt recht unmöglich, Dir mit Deinem Problem zu helfen, wenn Du es nicht auf den Punkt bringen kannst. Wir haben hier weder DEine Festplatte, Deine Dateien nocht Scanner noch Deine Oracle Datenbank (ist es eine?) zur Hand. Dein Code ist auch nicht lauffähig, die Idee dahinter ist nur Dir selbst klar.

    Den einzigen Tipp,  den ich Dir geben kann: Setze als erste Zeile den Befehl

    SET STEP ON

    Es wird sich dann der Debugger öffnen, mit einem Pfeil auf die Zeile SET STEP ON
    In der Toolbar sind einige Buttons, die die Codefortführung nun beeinflulssen. der einfachste ist der mit einem Pfeil, welcher in geschweifte Klammern hinein zeigt, der führt die nächste Zeile aus, und nur eine.

    Wenn Du das tust, kannst Du in anderen Fenstern sehen, wie sich das auswirkt, wie Variable gesetzt werden, was in Abfrageergebnissen steht kannst Du wiederum mit Wechsel in die Datensitzung in VFP sehen und so weiter.

    Wenn irgendein Befehl, den Du mit diesem Toolbar-Button bzw. mit F8 ausführst zu irgendeinem Fehler führt hast Du die erste Zeile Deines Codes, die nicht funktioniert. Selbst wenn der Zeiger dann eine Zeile weiter spring, aber eine Varriable leer bleibt, in der Du einen Wert erwartest oder sonst etwas von Dir nicht erwartetes passiert, hast Du wieder einen Hinweis.

    Wenn Du damit nicht zurecht kommst, frag nach wo Du was sehen kannst und wie Du weiter kommst.

    Tschüß, Olaf.


    Olaf Doschke - TMN Systemberatung GmbH

    http://www.tmn-systemberatung.de

    Montag, 17. August 2015 14:48
  • So ganz langsam dämmert es... Danke für die Geduld und es ist eine Oracle DB.

    Meine Textdatei ist nichts weiter als: "SCHUL","I-B60","XXX_99_999_1234567",01.07.2015 14:42:04,"SAM"

    Umformatiert komm das Heraus....

    Sammelumsetzen
    -Leer-
    -Leer-
    01.07.2015 14:42:04
    SCHUL
    I-B60
    -Leer-
    XXX/99/999/1234567

    .........................................................................................................................................

    Mit _tally habe ich schon mal was gemacht. Eigentlich will ich gar nicht den View ansprechen sondern die Tabelle. Wenn ich aber im DBC über find Objekt suche hab ich nur den View gefunden.

    Denke ich richtig, als nächste würde ich folgendes versuchen. Ich selektiere alle ID-Nummern aus dem lcScan bei denen der Standort vom lcScan von der RE_BEGLE (Wie spreche ich die an ? ODBC-Verbindung?Verknüpfung?) abweicht in ein Array a_fehl. Dort stehen dann alle betroffenen Gebinde drinne. If Tally = 0  MsgBox " Alles in Ordnung" IF TALLY >0 ...da muss jetzt ein Boolwert kommen. Aber brauche ich jetzt nicht noch eine Variable? Ich will halt das jeder ID-Nr aus a_fehl betrachtet wird. Wenn der Standort abweicht soll eine Entscheidung getroffen werden (über eine Msgbox) und dann bei Änderungswunsch in RE_BEGLE geschrieben werden. 

    Bei der Beispiel Datei wäre es nur eine ID-Nr. es soll aber mehrere ID`Nummern aus A_Fehl abarbeiten können.

    Wo kann ich also den PFAD meiner Tabelle RE_BEGLE finden?

    Tschüß, Radioaktivman 

    Dienstag, 18. August 2015 12:24
  • Ich kann Dir nicht folgen, aber Du scheinst jegliche Fehlermeldung einfach zu ignorieren.

    Also die Zeile hier könntest Du mal von mir bekommen haben:

    ON ERROR ? ERROR(), MESSAGE(),MESSAGE(1), " in ",PROGRAM(), " Zeile", LINENO()

    Die schreibt Di jeden Fehler auf den Screen, wenn Du nicht gerade in einem Formular mit AllowOutput = .F. bist.

    Außerdem macht der Code nach jedem Fehler dann einfach weiter.

    Du mußt Dir das schon anschauen, was Du damit angezeigt bekommst, und die Fehlerzeile dann mal untersuchen und korrigieren...

    Tschüß, Olaf.


    Olaf Doschke - TMN Systemberatung GmbH http://www.tmn-systemberatung.de

    Mittwoch, 19. August 2015 12:32
  • Jetzt weiß ich endlich was du meinst!!! Sry ich bin ja nur ein Laie.

    Und richtig die Zeile hab ich mal von dir bekommen! :) *Shame on me* Ich habs nur damals nicht verstanden...

    Mein Fehler war das ich dieses Screen in der Programmierumgebung gesucht habe...aber bis auf die Msgboxen beim ausführen erschien nix. Mir ist jetzt nach intensiver Suche aufgefallen das der Screen nur erscheint wenn ich das Programm als solches via EXE starte. Jetzt habe ich mir einen Screenshot gemacht und morgen werde ich die Fehler mal abgehen und Überprüfen. Ich bin jetzt hellauf begeistert vom Nutzen dieser Zeile...

    Wieder etwas gelernt. Danke, Danke, Danke.

    Trotzdem bleibt meine Frage: Wie kann ich eine Tabelle via Select ansprechen die nicht Teil des Programms ist? Via String bzw. Variable mit Pfadangabe? Oder benutze ich OPEN DATABASE? Muss ich die Tabelle Importieren oder irgendwie Verknüpfen? Ich will doch nur die Spalte NStandort aus der Tabelle RE_BEGLE selektieren ...

    Gruß Radioaktivman

    Mittwoch, 19. August 2015 14:14
  • Der Screen ist das Foxpro Hauptfenster. Also wenn Du Foxpro selbst (vfp9.exe) startest, siehst Du nix als den Screen. Allerdings wirkt das Kommando ? nicht nur auf den Screen, es zeigt Text im aktiven Formular an, wenn man nicht vorab ACTIVATE SCREEN macht. Der einfache Errorhandler, der direkt nur einen Befehl nach dem ON hat, kann nicht vorher noch ACTIVATE SCREEN ausführen.

    In dem Fall wäre es wohl einfacher, Du läßt die Zeile weg, dann kriegst Du wieder jede Fehlermeldung als Messagebox. Ich weiß nicht in welcher Situation Du letztes Mal warst, dass wir mal die Fehleranzeige einfach auf den Schirm geschrieben hatten, der "Vorteil" ist, das Programm fährt einfach fort, man kann ein paar Fehler sehen, aber das ist auch ein Nachteil, ein Programm scheint abgesehen von diesen Meldungen zu gehen, insbesondere wenn es Compiliert, obwohl die Befehlskonstrukte so gar nicht ausführbar sind.

    >Wie kann ich eine Tabelle via Select ansprechen die nicht Teil des Programms ist?

    Du meinst, die kein DBF ist.

    Wir reden jetzt wohl von den Oracle Daten. Du hast einen DBC, den Re_oradb.dbc, der enthält aber keine Tabellen. Schau nochmal genauer hin mit MODIFY DATABASE, der DBC enthät Views statt DBFs und zwar remoteviews. Das RE steht wohl auch für Remote.

    Remote heißt entfernt, nicht unbedingt in Australien, u.U. sogar immer noch im LAN oder sogar an Deinem PC; aber nicht DBF. Die Remoteviews sind nicht viel mehr als SQL-Abfragen, die diese remotedaten einlesen in einen Cursor.

    D.h. Der Befehl USE RE_ORADB!v_re_begle sertzt die SQL-Abfrage, die den View v_re_begle definiert an die Oracle DB ab und Du hast dann wie durch den CREATE CURSOR lcSanImport einen Cursor der den Aliasnamen v_re_begle hat.

    Mach Da mal einen Breakpoint bzw. das schon erwähnte SET STEP ON und dann wirst Du per BROWSE die von Oracle abgefragen Daten sehen.

    Die Daten aus Scandatei im lcScanImport Cursor und v_re_begle View lassen sich nun z.B. mit weiterem SQL oder anderen Mitteln des Zugriffs auf Cursoren und deren Datensätze vergleichen. Dein eigentliches Problem ist nicht, dass Du nicht an Daten kommst, Du hast Sie schon beisammen, Dein Problem ist die Vielzahl von Fehlern in Deinem Programm, da bin ich erst einmal ratlos.

    Abschließend etwas über Namensgebung: lcScanImport sieht für mich und viele hier Nach dem Namen einer Variablen aus, nicht nach einem Cursor. Die ersten beiden Buchstaben stellen Gültigkeitbereich und Typ dar. L steht für Local und C für Character, also eine lokale Stringvariable. Wenn Du einen Cursor per CREATE CURSOR machst, dann geb eher den Prefix cur oder crs, das macht das nachvollziehbarer. Ein SELECT * FROM lcScanImport sieht aus, als würdest Du von einer Variable selektieren wollen. Das trägt zur Verwirrung bei und macht Deinen Code nicht nachvollziehbar. Noch dazu hattest Du in Deinem Ersten Posting ALEN(lcScanImport), und ALEN geht nur bei Arrays. Die Anzahl der Datensätze eines Cursors lcScanImport sind RECCOUNT("lcScanImport"). Ich war also doppelt verwirrt. Du siehst wie wichtig es ist, sich an Komventionen zu halten. Nicht nur Du selbst, auch andere kommen mit Deinem Code dann ncht mehr klar.

    Dewegen belächle ich auch immer wieder Leute die meinen Namenskoonventionen sind sinnlos, weil die Mittel der Reflektion (in .NET ist das ein größeres Thema) Typen und Klassen ermitteln lassen und Intellisense zur Entwicklungszeit schon hilft. Wenn Du aber nur ein Stück Code eines Fremden in einem Forum liest, sind Namenskonventionen und sich daran haltende Programmierer das einzige, was solche Metainformationen mit rüber bringt, auch wenn das nicht verbindlich richtig sein muß. Letzteres heißt, nur weil man eine Variable lcString nennt, ist VFP selbst das egal, es nimmt es auch als Cursornamen oder läßt zu da eine Zahl oder sonstiges zu speichern.

    Wenn Du Code geändert hast, der vorher die Scandatei per FILETOSTR in eine Stringvariable liest, indem Du sie eben stattdessen per APPEND in einen Cursor einlist, dann funktioniert eine Menge nicht mehr, was davon ausgeht es noch mit einem String zu tun zu haben. So eine Umstelung ist nicht verkehrt, weil man nun statt eines Strings ein oder mehrere Datensätze mit Feldnamen hat. Aber das umzustellen erfordert eine Menge Ubauarbeiten. Wenn der komplette Satz an Daten vorher mal in einem String stand, konnte man da per AT() oder $ OPerator Teilstrings suchen und finden, aber ganz unspezifisch an welcher Stelle mit welcher Bedeutung, einen Cursor zu haben erlaubt jetzt ja z.B. im Feld Standort oder Ziel gezielt zu Suchen.

    Tschüß, Olaf.


    Olaf Doschke - TMN Systemberatung GmbH

    http://www.tmn-systemberatung.de

    Samstag, 22. August 2015 06:01