locked
Standardpfade RRS feed

  • Frage

  • Hallo zusammen,

    habe ein Problem mit dem Öffnen der richtigen Datenbank.

    Mein Programm hat ein kleines Hauptprogramm (setzten von Defaults, Anlegen von globalen Variablen, etc..). Ebenso öffne ich die dazugehörige Dantenbank mit

    open database (Pfad+name) shared

    Das Programm wird vom Netzwerk gestartet und greift auf die lokale Datenbank zu. Aus bestimmten Gründen ist die gleiche Datenbank ebenfall auf dem Netz installiert (gleicher Name). Die Netz-Version der DB dient nur zu Installationszwecken bzw um Grundkonfigurationen (Datenbank und Tabellenstruktur...) bereitzustellen. Sie ist aber nicht in permanenten Zugriff.

    Aus dem Menüsystem rufe ich dann die entsprechenden Forms auf. Im Datenenvironment der Forms sind Autoopen und Autoclose eingeschaltet. Im Datenenvironment der Fordm gibt es keinen Code zu öffnen der Datenbank (diese wurde ja im Hauptprog. geöffenen).

    Jetzt zeigt sich folgendes Phänomen:

    Das Hauptprogramm hat tatsächlich die lokale DB im Zugriff. Eine geöffnete Form greift auf die Netzwerkversion zu. Was mache ich falsch? Bin für jeden Tip dankbar.

    Gruß

    Christoph

    Mittwoch, 14. September 2016 10:58

Antworten

  • Hallo Christoph,

    also an der SET DEFAULT und der SET PATH Einstellung kann es eigentlich nicht liegen, die sehen jedesmal OK aus.

    Ich würde höchstens auch bei SET DEFAULT runde Klammern verwenden, also: SET DEFAULT TO (datafolder_v)

    Das wird aber natürlich nicht Dein Problem lösen.

    Ich erinnere mich aber, daß ich vor vielen Jahren auch genau das selbe Problem hatte, und es auch nur dadurch lösen konnte, daß die Pfade zu den Daten leicht unterschiedlich waren !!!

    Meistens hat der Zugriff auf die richtigen Daten funktioniert, in seltenen Fällen aber auch nicht !!! Absolut nervtötend !!!  :-(

    Du könntest z. B. den Pfad auf dem Netzlaufwerk auch folgendermaßen benennen:

    S:...\Blockfinder_Setup\Daten\

    Du kannst aber noch folgendes überprüfen - öffne mal eine Form wie eine Tabelle (bei Visual Foxpro ist jede Form auch eine Tabelle !!!):

    - USE Pfad/Formname.scx

    - gebe dann BROWSE ein

    Deine Form wird jetzt wie eine Tabelle angezeigt. Doppelklicke jetzt in jeder Zeile jeweils in der Spalte Properties auf Memo     (memo kleingeschrieben enthält keine Daten)

    Jetzt wird z. B. angezeigt:

    Left = 287
    Top = 166
    Width = 92
    Height = 90
    Alias = "rech_pos"
    CursorSource = ..\daten\rech_pos.dbf
    Name = "Cursor13"

    Hier sollte natürlich kein Pfad zum Netzlaufwerk erscheinen, sondern nur ein relativer Pfad wie oben !

    Gruß, Stefan



    • Bearbeitet Stefan Förner Donnerstag, 15. September 2016 07:58
    • Als Antwort markiert CLTBEN Donnerstag, 15. September 2016 12:39
    Donnerstag, 15. September 2016 07:51
  • Hallo Christoph,

    1) die relativen Pfade wie daten\data1.dbc sind schon OK, so kann man über SET DEFAULT und SET PATH steuern welcher Datenbestand geöffnet wird - bzw. sollte es können . . .  :-)

    2) wenn Du selbst den korrekten Pfad setzen willst, wird es natürlich viel aufwendiger:

    Du mußt AutoOpenTables und AutoCloseTables auf .F. setzen und mußt dann die Datenbank und die zugehörigen Tabbelen selbst öffnen und schließen. Das ganze solltest Du auch möglichst früh tun, also schon im Load-Ereignis der Form machen, damit alle Operationen vom Init-Ereignis eine geöffnete Datenbank / geöffnete Tabellen vorfinden.

    - ich würde davon aber abraten !!! Man schafft sich so nur evtl. wieder ganz neue Probleme . . .

    Ich verwende z. B. nur freie Tabellen. Die füge ich zur Entwurfszeit der Datenumgebeung des Formulars hinzu und lasse natürlich AutoOpenTables und AutoCloseTables auf .T. eingestellt.

    Aber egal ob man freie Tabellen verwendet oder eine Datenbank, das hat nichts mit dem von Dir geschilderten Problem zu tun.

    Aber eine anderer Frage: wie hast Du bei Deinen Formularen DataSession eingestellt: 1 - Default ... oder 2 - Private ... ???

    Gruß, Stefan

    • Als Antwort markiert CLTBEN Donnerstag, 15. September 2016 12:39
    Donnerstag, 15. September 2016 10:25
  • . . . noch ein kleiner Nachtrag:

    ich vermute DataSesion hast Du jeweils auf 2 - Private ... eingestellt.

    Du kannst natürlich auch in Deinen Formularen die gewünschte Datenbank genau so öffnen wie in Deinem Hauptprogramm

    - im Form Load-Ereignis: open database (Pfad+name) shared

    und

    - im Form Unload-Ereignis: CLOSE DATABASES bzw. CLOSE DATABASES ALL

    Du brauchst dann der Datenumgebung des Formulars auch nichts hinzuzufügen bzw. Du stellst AutoOpenTables und AutoCloseTables auf .F., also:

    - Datenumgebung ist leer, dann kann AutoOpenTables und AutoCloseTables auf .T. stehen

    - Datenumgebung ist nicht leer, dann AutoOpenTables und AutoCloseTables auf .F. einstellen

    Gruß, Stefan

    • Als Antwort markiert CLTBEN Donnerstag, 15. September 2016 12:39
    Donnerstag, 15. September 2016 10:49
  • Hallo Christoph,

    wenn Du die DB immer mit SHARED öffnest, mußt Du sie im Hauptprogramm nicht schließen, wenn Du ein Formular öffnest. Du mußt sie erst schließen, wenn Du Dein Hauptprogramm beendest.

    D. h. geöffnet jeweils mit SHARED kannst Du Dein Hauptprogramm starten und (rein theoretisch) noch beliebig viele weitere Formulare gleichzeitig öffnen, wobei jedes Formular wiederum dieselbe DB mit SHARED öffnet !

    Ich verwende in allen meinen Formularen (und auch Berichten) immer DataSession = 2. Dann erhält jedes Formular (jeder Bericht) immer eine neue eigene Datenumgeben mit neuen eigenen Arbeitsbereichen (geöffnete Tabellen, ein Arbeitsbereich entspricht einer geöffneten Tabelle).

    Bei DataSession = 1 verwenden dagegen alle so eingestellten Formulare dieselbe Datenumgebung mit denselben Arbeitsbereichen (denselben geöffneten Tabellen).

    Wenn jetzt ein Formular den Datensatzzeiger / die Recordnummer einer Tabelle verändert, wird das auch in allen anderen Formularen mit DataSession = 1 gleich mitverändert !!!

    Oder: wenn ein Formular eine Tabelle / eine Datenbank schließt, wird diese auch für alle anderen Formulare mit DataSession = 1 gleich mitgeschlossen !!!

    Das ist höchstwahrscheinlich nicht das, was man möchte bzw. erwartet.

    Das jeweilige Verhalten bei DataSession = 1 bzw. DataSession = 2 ist auch in der Hilfe von Visual Foxpro recht ausführlich beschrieben.

    Gruß, Stefan


    • Bearbeitet Stefan Förner Donnerstag, 15. September 2016 12:14
    • Als Antwort markiert CLTBEN Donnerstag, 15. September 2016 12:39
    Donnerstag, 15. September 2016 12:11

Alle Antworten

  • Hallo Christoph,

    setzte doch mal in Dein Hauptprogramm direkt vor dem Öffnen der Datenbank (open database (Pfad+name) shared) folgende Testausgabe:

    MESSAGEBOX( "Default: " + SYS( 5 ) + SYS( 2003 ) + CHR( 13 ) + CHR( 13 ) + "Path: " + SET( "PATH" ) )

    Setzte dann in den Init-Event einer Form die selbe Testausgabe.

    Die jeweils angezeigten Testausgaben / Werte bitte dann hier mal posten.

    Gruß, Stefan


    Mittwoch, 14. September 2016 21:05
  • Hallo Stefan,

    erstmal Danke für Deine Antwort. Anbei die ScreenShots:

    Hauptprogramm:

    Form:

    Das war auch meine erste Vermutung. Im Hauptprogramm habe ich schon folgendes drin:

            SET PATH TO (datafolder_v)
            SET DEFAULT TO &datafolder_v

    Wenn ich auf dem Netzwerklaufwerk (S:\) den Pfad für die Datenbank umbenenne (S:...\Blockfinder\Daten_xxx\), dann greift das Programm auf D: zu (ohne Fehlermeldung!); aus meiner Sicht gibts hier ne Suchreihenfolge... aber wo kann man die beeinflussen?

    Gruß

    Christoph

    Donnerstag, 15. September 2016 06:39
  • Habe gerade gesehen, dass die Screen-Shots nicht durchgehen...

    Hauptprogramm:

    Form

    Donnerstag, 15. September 2016 06:45
  • Hallo Christoph,

    - leider sehe ich keine Screen-Shots! Vielleicht hast Du sie mit STRG+C eingefügt?

    - das funktioniert leider nicht, Du mußt sie mit der kleinen Ikone Insert Image oben rechts in der Toolbar B I U einfügen / hochladen.

    Gruß, Stefan

    Donnerstag, 15. September 2016 06:57
  • Hallo Christoph,

    also an der SET DEFAULT und der SET PATH Einstellung kann es eigentlich nicht liegen, die sehen jedesmal OK aus.

    Ich würde höchstens auch bei SET DEFAULT runde Klammern verwenden, also: SET DEFAULT TO (datafolder_v)

    Das wird aber natürlich nicht Dein Problem lösen.

    Ich erinnere mich aber, daß ich vor vielen Jahren auch genau das selbe Problem hatte, und es auch nur dadurch lösen konnte, daß die Pfade zu den Daten leicht unterschiedlich waren !!!

    Meistens hat der Zugriff auf die richtigen Daten funktioniert, in seltenen Fällen aber auch nicht !!! Absolut nervtötend !!!  :-(

    Du könntest z. B. den Pfad auf dem Netzlaufwerk auch folgendermaßen benennen:

    S:...\Blockfinder_Setup\Daten\

    Du kannst aber noch folgendes überprüfen - öffne mal eine Form wie eine Tabelle (bei Visual Foxpro ist jede Form auch eine Tabelle !!!):

    - USE Pfad/Formname.scx

    - gebe dann BROWSE ein

    Deine Form wird jetzt wie eine Tabelle angezeigt. Doppelklicke jetzt in jeder Zeile jeweils in der Spalte Properties auf Memo     (memo kleingeschrieben enthält keine Daten)

    Jetzt wird z. B. angezeigt:

    Left = 287
    Top = 166
    Width = 92
    Height = 90
    Alias = "rech_pos"
    CursorSource = ..\daten\rech_pos.dbf
    Name = "Cursor13"

    Hier sollte natürlich kein Pfad zum Netzlaufwerk erscheinen, sondern nur ein relativer Pfad wie oben !

    Gruß, Stefan



    • Bearbeitet Stefan Förner Donnerstag, 15. September 2016 07:58
    • Als Antwort markiert CLTBEN Donnerstag, 15. September 2016 12:39
    Donnerstag, 15. September 2016 07:51
  • Hallo Stefan,

    kurz vorab: ich sehe die Bilder und habe sie auch entsprechend über das Symbol eingebunden. Aber egal, sie enthalten den gleichen Pfad.

    Habe die Form als Tabelle untersucht. Es steht folgendes drin:

    Top = 20
    Left = 10
    Height = 244
    Width = 109
    Alias = "nc_data"
    Order = "komplett"
    Database = daten\data1.dbc
    CursorSource = "nc_data"
    Name = "Cursor1"

    Top = 11
    Left = 138
    Height = 90
    Width = 109
    Alias = "maschinen"
    Order = "masch_id"
    Database = daten\data1.dbc
    CursorSource = "maschinen"
    ReadOnly = .T.
    Name = "Cursor2"

    Die Angabe "daten\data1.dbc" ist natürlich für lokales als auch Netzlaufwerk korrekt.

    Könnte man diese Daten nicht in der Ini-Methode der Form auf den korrekten Pfad (inkl. Laufwerk) setzen?

    Gruß

    Christoph

    Donnerstag, 15. September 2016 09:36
  • Hallo Christoph,

    1) die relativen Pfade wie daten\data1.dbc sind schon OK, so kann man über SET DEFAULT und SET PATH steuern welcher Datenbestand geöffnet wird - bzw. sollte es können . . .  :-)

    2) wenn Du selbst den korrekten Pfad setzen willst, wird es natürlich viel aufwendiger:

    Du mußt AutoOpenTables und AutoCloseTables auf .F. setzen und mußt dann die Datenbank und die zugehörigen Tabbelen selbst öffnen und schließen. Das ganze solltest Du auch möglichst früh tun, also schon im Load-Ereignis der Form machen, damit alle Operationen vom Init-Ereignis eine geöffnete Datenbank / geöffnete Tabellen vorfinden.

    - ich würde davon aber abraten !!! Man schafft sich so nur evtl. wieder ganz neue Probleme . . .

    Ich verwende z. B. nur freie Tabellen. Die füge ich zur Entwurfszeit der Datenumgebeung des Formulars hinzu und lasse natürlich AutoOpenTables und AutoCloseTables auf .T. eingestellt.

    Aber egal ob man freie Tabellen verwendet oder eine Datenbank, das hat nichts mit dem von Dir geschilderten Problem zu tun.

    Aber eine anderer Frage: wie hast Du bei Deinen Formularen DataSession eingestellt: 1 - Default ... oder 2 - Private ... ???

    Gruß, Stefan

    • Als Antwort markiert CLTBEN Donnerstag, 15. September 2016 12:39
    Donnerstag, 15. September 2016 10:25
  • . . . noch ein kleiner Nachtrag:

    ich vermute DataSesion hast Du jeweils auf 2 - Private ... eingestellt.

    Du kannst natürlich auch in Deinen Formularen die gewünschte Datenbank genau so öffnen wie in Deinem Hauptprogramm

    - im Form Load-Ereignis: open database (Pfad+name) shared

    und

    - im Form Unload-Ereignis: CLOSE DATABASES bzw. CLOSE DATABASES ALL

    Du brauchst dann der Datenumgebung des Formulars auch nichts hinzuzufügen bzw. Du stellst AutoOpenTables und AutoCloseTables auf .F., also:

    - Datenumgebung ist leer, dann kann AutoOpenTables und AutoCloseTables auf .T. stehen

    - Datenumgebung ist nicht leer, dann AutoOpenTables und AutoCloseTables auf .F. einstellen

    Gruß, Stefan

    • Als Antwort markiert CLTBEN Donnerstag, 15. September 2016 12:39
    Donnerstag, 15. September 2016 10:49
  • Hallo Stefan,

    hatte beide Varianten der DataSession ausprobiert und keinen Unterschied festgestellt. Esd könnte aber auch sein, daß ich hierbei die notwendige Sorgfalt nicht eingehalten habe, da für mich kein direkter Zusammenhang erkennbar war.

    Gibt es einen Solchen Zusammenhang? Wenn ja, würde ich das nochmals prüfen.

    Ansonsten werde ich (dank Deiner Unterstützung) den Weg probieren, die DB im Hauptprogramm wieder zu schliesen und in der  Load/UnLoad-Methode zu öffnen/schließen.

    Für mich sind aus dieser Aktion zwei Dinge wesentlich:

    1. Es gibt noch andere Menschen, denen dieser Fehler aufgefallen ist

    2. Die Erklärung des Fehler ist gut, einleuchtend und nachvollziehbar.

    Einen entsprechend (guten/schlechten) Workaround findet man in den allermeisten Fällen.

    Gruß, Christoph

    Donnerstag, 15. September 2016 11:29
  • Hallo Christoph,

    wenn Du die DB immer mit SHARED öffnest, mußt Du sie im Hauptprogramm nicht schließen, wenn Du ein Formular öffnest. Du mußt sie erst schließen, wenn Du Dein Hauptprogramm beendest.

    D. h. geöffnet jeweils mit SHARED kannst Du Dein Hauptprogramm starten und (rein theoretisch) noch beliebig viele weitere Formulare gleichzeitig öffnen, wobei jedes Formular wiederum dieselbe DB mit SHARED öffnet !

    Ich verwende in allen meinen Formularen (und auch Berichten) immer DataSession = 2. Dann erhält jedes Formular (jeder Bericht) immer eine neue eigene Datenumgeben mit neuen eigenen Arbeitsbereichen (geöffnete Tabellen, ein Arbeitsbereich entspricht einer geöffneten Tabelle).

    Bei DataSession = 1 verwenden dagegen alle so eingestellten Formulare dieselbe Datenumgebung mit denselben Arbeitsbereichen (denselben geöffneten Tabellen).

    Wenn jetzt ein Formular den Datensatzzeiger / die Recordnummer einer Tabelle verändert, wird das auch in allen anderen Formularen mit DataSession = 1 gleich mitverändert !!!

    Oder: wenn ein Formular eine Tabelle / eine Datenbank schließt, wird diese auch für alle anderen Formulare mit DataSession = 1 gleich mitgeschlossen !!!

    Das ist höchstwahrscheinlich nicht das, was man möchte bzw. erwartet.

    Das jeweilige Verhalten bei DataSession = 1 bzw. DataSession = 2 ist auch in der Hilfe von Visual Foxpro recht ausführlich beschrieben.

    Gruß, Stefan


    • Bearbeitet Stefan Förner Donnerstag, 15. September 2016 12:14
    • Als Antwort markiert CLTBEN Donnerstag, 15. September 2016 12:39
    Donnerstag, 15. September 2016 12:11
  • Hallo Stefan,

    vielen Dank für deinen sehr kompetenten Support. Mit den Einträgen in Load/UnLoad läuft die Sache augenscheinlich. DataSession werde ich nochmals entsprechend checken.

    Gruß, Christoph

    Donnerstag, 15. September 2016 12:37
  • Soweit ich gelesen habe war Dein Hauptproblem eher den Unterschied im Verhalten von private und default datasession nicht zu kennen. Ein DBC ist zwar für alle Datasessions geöffnet, aber jede private/neue Datasession hat anfangs erst einmal 0 Workareas belegt und jede DBF, die Du neu öffnest hat damit einen eigenen Datensatzzeiger, Du kannst Dasselbe Formular zweimal mit privater Datasession starten und das eine zeigt von einer DBF ID1 und das andere ID 2 an, ohne dass sich das irgendwo beißt oder gegenseitig beeinflusst. Natürlich teilen beide Formulare trotzdem dieselbe Tabelle shared.

    Nur noch soviel: Selbst wenn Du in einem Formular Dataenvironment eine Datenbank außerhalb Deines PRojektordners verwendest, z.B. den Sample Northwind.DBC auf C:\ nimmst, während Deine Projektsourcen z.B. auf D:\ liegen, dann hast Du im Properties Memo einen absoluten Pfad wie z.B. Database = c:\program files (x86)\microsoft visual foxpro 9\samples\northwind\northwind.dbc

    Selbst dann wenn die Datenbank für den Enduser dort nicht bereitsteht, sondern Du sie kann eine laufende EXE der Northwind.DBC irgendwo in einem Netzwerkshare bereitsteht wird das Dataenvironment dort seine Tabellen suchen, nachdem es einen erfolglosen Versuch in c:\program files (x86)\microsoft visual foxpro 9\samples\northwind\ gemacht hat. Es wird dann entlang SET PATH Pfaden weitergesucht. Aber selbst ein schon geöffneter DBC veranlasst ein Tabellenobjekt in einem Dataenvironment nicht, die schon geöffnete DBC zu nehmen. 

    Gerade ein Dataenvironment mit relative Pfaden bedeutet, dass die Datenbank auch relativ zum Standort der EXE gefunden und genutzt wird, was Du dann u.U. gar nicht möchtest. Deswegen ist es auch üblich, eine EXE gar nicht im Netzwerk aufzurufen, sondern zuerst in ein lokales Laufwerk zu kopieren und dort zu starten.

    Wobei es dann davon abhängt, ob die Anwendung Single oder Multi User ist, ob jeder User seinen eigenen DBC kriegen sollte oder der DBC zentral liegt.

    Um da ein bewegliches Gelenk zu haben, was den DBC angeht, nutze ich die Dataenvironments von Formularen gar nicht. Man entwickelt heute OOP und dazu zählen dann Formularklassen statt SCX. Formularklassen havben gar kein Dataenvironment, daher kommt man gar nicht erst in Versuchung, dieses leicht verschrobene Konstrukt zu nutzen in dem man nie genau weißt, was eigentlich abläuft. Der Luxus die Tabellen da visuell reinzuziehen und relationen automatisch zu erben ist durchaus auch Nachteil. Wenn Du wissen willst, was passiert, codierst Du einfach OPEN DATABASE (in main o.ä. auch ok) und dann die einzelnen USE, wenn überhaupt.

    Heutzutage (seit VFP8 mein ich) hast Du noch das Dataenvironment als einzelne Klasse. Das stand einem in VFP7 auf jeden Fall noch nicht zur Verfügung. Das ermöglicht auch noch hier OOP anzuwenden und ein und dasselbe Dataenvironment auch für verschiedene Formularklassen zu nutzen und das nicht nur als Kopie, sondern über Nutzung der gleichen Klasse, die zentral aktualisierbar ist. Du kannst viel exakter objektorienteirt arbeiten und wie das die 3 Tier Architektur verlangt sauber Datenzugriff und Frontend/Interface trennen, eine Formularfreie Datenzugriffsschicht programmieren und testen, ohne ein Formular davor setzen zu müssen, etc.

    Tschüß, Olaf.


    Olaf Doschke - TMN Systemberatung GmbH

    Freitag, 23. September 2016 19:46
  • Hi Olaf,

    zum Einen hast Du durchaus recht, daß mir der Unterschied innerhalb der Möglichkeiten für die Data-Session anfangs noch nicht so klar war , wie danach. Das war aber nicht mein Hauptproblem. Sondern wie beschrieben, daß aufgrund der relativen Pfade tatsächlich die 'falsche DBC' nebst Tables geöffnet wurde. Das ist aber (dank Euch) mittlerweile geklärt.

    Gruß

    Christoph

    P.S.

    mir wird bestimmt demnächst nochwas einfallen, womit ich wieder nerven kann :-)

    Dienstag, 27. September 2016 14:38