use - keine Variablen?

Zugriff, Engines, Konvertierung. Von ADS über DBF bis zu SQL.

Moderator: Moderatoren

Antworten
stevie
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 417
Registriert: Mo, 17. Sep 2007 18:20
Wohnort: Senftenberg
Kontaktdaten:

use - keine Variablen?

Beitrag von stevie »

Wieso erkennt use eigentlich keine Variablen?
Ich versuche USE cname alias Diffexcel new zu starten. In cname steht der vollständige Dateiname ohne Endung. Dann kommt die Fehlermeldung das die Datei cname nicht gefunden werden konnte, obwohl die Excelverbindung vorher klappt. cname wird durch einen Filedialog bestimmt und vor der Abfrage, der Dateiname von den Pfadangaben und der Dateiendung abgetrennt.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15707
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 71 Mal
Danksagung erhalten: 38 Mal
Kontaktdaten:

Beitrag von brandelh »

Hi,

weil das von dBase (Interpreter) her schon so war :!:

Bei Variablen in Befehlen (Funktionen gehen immer mit Variablen) muss man die in Klammern setzen. So funktioniert es:

Code: Alles auswählen

local cFile := "XYZ.DBF" // oder auch ohne Endung
use (cFile)
if neterr()  // immer abfragen !
Gruß
Hubert
Benutzeravatar
Rolf Ramacher
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1931
Registriert: Do, 09. Nov 2006 10:33
Wohnort: Bergheim
Danksagung erhalten: 3 Mal
Kontaktdaten:

Beitrag von Rolf Ramacher »

Hi,

zeig doch mal deinen code
Gruß Rolf

Mitglied der Gruppe XUG-Cologne
www.xug-cologne.de
stevie
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 417
Registriert: Mo, 17. Sep 2007 18:20
Wohnort: Senftenberg
Kontaktdaten:

Beitrag von stevie »

Ok, lag daran das ich bisher ohne Klammern geschrieben habe.
Wenn man die Variable mit dem Dateinamen in Klammern schreibt, gehts.
Also: use (cname) alias ...
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12913
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

Beitrag von AUGE_OHR »

hi,
stevie hat geschrieben: Ok, lag daran das ich bisher ohne Klammern geschrieben habe.
Wenn man die Variable mit dem Dateinamen in Klammern schreibt, gehts.
Also: use (cname) alias ...
Hintergrund: Es wäre zu empfehlen das Kapitel "&Operator" ( Makro-
Operator) in diesem Zusammenhang zu lesen.

Sollte man wiederrum eine Cl*pper Application nach Xbase++ migieren
so sind die "Klammer" oft die Lösung:

Code: Alles auswählen

Cl*pper   : USE &cName
Xbase++ : USE (cName)
gruss by OHR
Jimmy
stevie
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 417
Registriert: Mo, 17. Sep 2007 18:20
Wohnort: Senftenberg
Kontaktdaten:

Beitrag von stevie »

AUGE_OHR hat geschrieben:hi,

Hintergrund: Es wäre zu empfehlen das Kapitel "&Operator" ( Makro-
Operator) in diesem Zusammenhang zu lesen.

Sollte man wiederrum eine Cl*pper Application nach Xbase++ migieren
so sind die "Klammer" oft die Lösung:

Code: Alles auswählen

Cl*pper   : USE &cName
Xbase++ : USE (cName)
Da kann ich froh sein, das ich clipper niemals lernen werde.
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9394
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 104 Mal
Danksagung erhalten: 364 Mal
Kontaktdaten:

Beitrag von Tom »

Cl*pper : USE &cName
Xbase++ : USE (cName)

Xbase++ kann beides!
Herzlich,
Tom
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12913
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

Beitrag von AUGE_OHR »

hi,
Tom hat geschrieben: Cl*pper : USE &cName
Xbase++ : USE (cName)

Xbase++ kann beides!
JA ... aber nur wenn "cName" PRIVATE ist :)

... und das ist beim migieren oft das Problem wenn man "PARAMETER"
von S87 Funktionen nach v5.x/Xbase++ "umwandelt" dann werden die
Variabeln ja LOCAL sodas unter Xbase++ der &-Makro Operator nicht
mehr funktioniert. In beiden Fällen arbeitete die LOCAL aber mit "(...)".

das Kapitel &-Makro ist aber auch wegen Codeblock zu empfehlen und
deshalb nicht Cl*pper abhängig.

gruss by OHR
Jimmy
Rolf
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 258
Registriert: Do, 27. Apr 2006 12:28
Wohnort: Görlitz

Beitrag von Rolf »

Hi Jimmy

ich hab mich an das Konstrukt "use &cDbf" schon richtig gewöhnt, so das mir "use (cDbf)" fast komisch vorkommt. (cDbf ist bei mir als LOCAL deklariert.) Ich habe das von Anfang an so gefunden und bin eben dabei geblieben. Naja Geschmackssache.

Grüße Rolf
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15707
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 71 Mal
Danksagung erhalten: 38 Mal
Kontaktdaten:

Beitrag von brandelh »

Tom hat geschrieben:Cl*pper : USE &cName
Xbase++ : USE (cName)
Xbase++ kann beides!
Eigentlich können beide beides !

Clipper 5.x führte die LOCAL Variablen ein (ich denke mal dass ich mich richtig erinnere). PRIVATE Variablen kann man mit &MyPrivateVar interpretieren bei LOCAL geht das nicht. Egal ob Xbase++ oder Clipper 5.x.

Auf jeden Fall macht aber eine Macro + Private dem Rechner mehr Arbeit als eine Klammer + Local, also einfach Klammern und locale Variablen nutzen. Privates und Public nur verwenden wenn es unbedingt sein muss !
Gruß
Hubert
Rolf
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 258
Registriert: Do, 27. Apr 2006 12:28
Wohnort: Görlitz

Beitrag von Rolf »

Soory Hubert,
brandelh hat geschrieben:PRIVATE Variablen kann man mit &MyPrivateVar interpretieren bei LOCAL geht das nicht. Egal ob Xbase++ oder Clipper 5.x.
das irritiert mich ich verwende mit Xbass++ oft Funktionen mit

Code: Alles auswählen

LOCAL cDbf := "test.dbf"
use &cDbf
Aber du sagst, dass dies gar nicht gehen könnte. Bei mir geht es doch aber :? .

Grüße Rolf
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15707
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 71 Mal
Danksagung erhalten: 38 Mal
Kontaktdaten:

Beitrag von brandelh »

Hi,

jetzt bin ich aber irritiert. Wenn es bei dir geht, ist meine Aussage nicht ganz richtig. Alles hängt mit der Frage des Zustandes zur Ausführungszeit zusammen.

use (cFile) und use &cFile

machen ja nichts anderes als den Textinhalt in der Befehlszeile zu übergeben. So wie du schreibst ist also die einfache Verwendung identisch.

Weiterhin nimmt man den & Macrooperator um Codeblöcke oder komplexe IF Bedingungen zu erstellen. HIER liegt der Unterschied von LOCAL zu PRIVATE Variablen:

Code: Alles auswählen

PRIVATE cName := "Hubert"
private   cSuchstring := "field->Name = cName"

If &cSuchstring  ... funktioniert, da die private Variable cName zur Laufzeit bekannt ist.

Code: Alles auswählen

LOCAL cName := "Hubert"
LOCAL   cSuchstring := "field->Name = cName"

If &cSuchstring  ... geht nicht, da die locale Variable cName zur Laufzeit nicht mehr den Namen cName hat, sondern nur noch eine Speicheradresse ist.
daher musste man folgenden Code verwenden:

Code: Alles auswählen

LOCAL cName := "Hubert"
LOCAL  cSuchstring := "field->Name = '"+cName+"'"

If &cSuchstring  ... geht, da die locale Variable cName zur Compilierzeit aufgelöst wird.
so aus dem Gedächtnis ...
Gruß
Hubert
Rolf
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 258
Registriert: Do, 27. Apr 2006 12:28
Wohnort: Görlitz

Beitrag von Rolf »

Ok, in der XBase-Hile steht dazu
XBase++ Hilfe hat geschrieben:Der Makro-Operator in Befehlen

Der Makro-Operator kann keine Xbase++ Befehle interpretieren, da diese durch den Präprozessor zu Funktionsaufrufen übersetzt werden. Bei Befehlsargumenten kann der Operator dagegen verwendet werden. Als Beispiel folgende Zeilen:

PRIVATE cFileName := "KUNDEN.DBF"

USE Kunden // USE mit Literal
USE (cFileName) // USE mit Klammern


USE &cFileName // USE mit Makro-Operator

In dem Beispiel ist der Befehl USE in drei verschiedenen Formen angegeben. Der Dateiname kann bei dem Befehl optional als Literal oder als geklammerter Zeichenausdruck angegeben werden. Wenn das Argument mit dem Makro-Operator angegeben ist, wird der Operator vom Präprozessor ignoriert und das Argument wird so behandelt, als ob es in ()-Klammern eingeschlossen ist.
Ich mach auch solche Sachen und die gehen bisher auch.

Code: Alles auswählen

    //-- Datenbank anlegen falls sie nicht existiert
    if !file(cDbf) 
        dbcreate(cDbf,adbf)
        use
    endif
    //-- Indexdatei anlegen falls sie nicht existiert
    if !FILE(cNtx) 
        use &cDbf
        if !neterr()
            index on NR to &cNtx
        endif
        use
    endif
    //-- Öffnen
    use &cDbf shared
Grüße Rolf
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12913
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

Beitrag von AUGE_OHR »

hi,
Rolf hat geschrieben:Ok, in der XBase-Hile steht dazu
XBase++ Hilfe hat geschrieben:Der Makro-Operator in Befehlen
PRIVATE cFileName := "KUNDEN.DBF"
USE Kunden // USE mit Literal
USE (cFileName) // USE mit Klammern
USE &cFileName // USE mit Makro-Operator
aber da steht doch PRIVATE ?!

gruss by OHR
Jimmy
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12913
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

Beitrag von AUGE_OHR »

hi,
Rolf hat geschrieben: Ich mach auch solche Sachen und die gehen bisher auch.

Code: Alles auswählen

    //-- Datenbank anlegen falls sie nicht existiert
    if !file(cDbf) 
        dbcreate(cDbf,adbf)
        use
    endif
    //-- Indexdatei anlegen falls sie nicht existiert
    if !FILE(cNtx) 
        use &cDbf
        if !neterr()
            index on NR to &cNtx
        endif
        use
    endif
    //-- Öffnen
    use &cDbf shared
so nun hab ich mir das ganze noch mal angesehen und bin verwundert ...
tatsächlich scheinen LOCAL auch mit Markos zu gehen ... ?!
Help file hat geschrieben: Eine Zeichenkette, die Namen für LOCAL- bzw. STATIC-Variablen oder STATIC Funktionen enthält, kann vom Makro-Operator nicht interpretiert werden, da die entsprechenden Symbolreferenzen zur Compile-Zeit aufgelöst werden und zur Laufzeit nicht mehr existieren.
Ist da was geändert worden (in der v1.9x) den danach dürfte es immer
noch nicht funktionieren?

Meine NET_USE hatte ich für Xbase++ extra so abgeändert :

Code: Alles auswählen

   DO WHILE .T.
      IF FILE( file_dbf )
         DO WHILE m_dauer > 0
            IF ex_use
#IFDEF __XPP__
               IF lNewAlias
                  USE (file_dbf) EXCLUSIVE ALIAS (myalias)
               ELSE
                  USE (file_dbf) EXCLUSIVE
               ENDIF
#ELSE
               IF lNewAlias
                  USE &file_dbf EXCLUSIVE ALIAS &myalias
               ELSE
                  USE &file_dbf EXCLUSIVE
               ENDIF
#ENDIF

            ELSE
#IFDEF __XPP__
               IF lNewAlias
                  USE (file_dbf) ALIAS (myalias)
               ELSE
                  USE (file_dbf)
               ENDIF
#ELSE
               IF lNewAlias
                  USE &file_dbf ALIAS &myalias
               ELSE
                  USE &file_dbf
               ENDIF
#ENDIF
            ENDIF

            IF .NOT. NETERR()
wie man sieht verwende ich hier __XPP__ damit ich den Code sowohl
unter Cl*pper als auch Xbase++ verwenden kann.

da aber die "()" bei beiden funktionieren hab ich versucht das "&" möglist
wenig zu verwenden und die "()" zu nehmen.

gruss by OHR
Jimmy
Rolf
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 258
Registriert: Do, 27. Apr 2006 12:28
Wohnort: Görlitz

Beitrag von Rolf »

Hallo Jimmy

Das ging auch schon mit der 1.72 von der haben wir gerade auf die 1.90 umgestellt auch ohne Probleme in dem Bereich.

Das Augenmerk ist wahrscheinlich auf den letzten Satz zu setzen.
XBase++ Hilfe hat geschrieben:Wenn das Argument mit dem Makro-Operator angegeben ist, wird der Operator vom Präprozessor ignoriert und das Argument wird so behandelt, als ob es in ()-Klammern eingeschlossen ist.
Grüße Rolf
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15707
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 71 Mal
Danksagung erhalten: 38 Mal
Kontaktdaten:

Beitrag von brandelh »

Hi,

nein der Knackpunkt liegt darin, dass die Namen von LOCAL oder STATIC Variablen nicht in einem String von dem Macrooperator bearbeitet werden. Texte oder Feldnamen dagegen schon.

Wie oben ausgeführt geht das:

&"Name = 'Hubert'" // wobei NAME ein DBF-Feld ist.
&"Name = cName" // solange cName eine private oder public ist.

aber cName darf keine LOCAL sein. Denn zur Laufzeit versucht Xbase++ eine Variable oder ein Feld NAME und cNAME zu finden. Felder und privates / publics sind per Namen zur Laufzeit bekannt. Local und Statics nicht mehr. Bei letzteren hat der Compiler die Namen in Speicheradressen getauscht, was auch ein Grund für die schnellere Verarbeitung ist.
Gruß
Hubert
Rolf
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 258
Registriert: Do, 27. Apr 2006 12:28
Wohnort: Görlitz

Beitrag von Rolf »

Hm,

Ich hab nun mal mit dem Compilierflag die *.ppo erzeugt die übersetzt das dann von

Code: Alles auswählen

    LOCAL cDbf := "Test.dbf"
    nSeconds1 := Seconds()
    FOR iPos = 1 to 20000
        use &cDbf
        use
    NEXT
    nSeconds2 := Seconds()
    Msgbox( Alltrim(str(nSeconds2-nSeconds1)) )
nach übersetzt

Code: Alles auswählen

    LOCAL cDbf := "Test.dbf"
    nSeconds1 := Seconds()
    FOR iPos = 1 to 20000
        dbUseArea( .F., , cDbf, , iif(.F. .or. .F., !.F., NIL), .F.)  
        dbCloseArea()
    NEXT
    nSeconds2 := Seconds()
Mit DbUseArea() scheint das dann auch mit einer Local zu gehen.

Grüße Rolf
Antworten