ARRAY & Memo

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

Moderator: Moderatoren

Antworten
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12909
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

ARRAY & Memo

Beitrag von AUGE_OHR »

Martin hat geschrieben: Als Feld würde sich da wohl bei Fox ein Feld vom Typ "V" (Memo, binär) anbieten - denke ich mal, benutzt habe ich es noch nicht.
Und Index? Eher nicht, eher eine Volltextsuche...
also ich hab es mal mit einem "normalen" Memo versucht und einen
"komischen" Effekt

Code: Alles auswählen

PROCEDURE MAIN(cFlag)
LOCAL TEST := .F.
LOCAL aNum := {}

   IF PCOUNT() > 0
      TEST := .T.
   ENDIF

   SET DATE GERMAN
   SET EPOCH TO YEAR(DATE())-50
   SET EXCLUSIV OFF
   SETCANCEL (.T.)

   IF .NOT. FILE("DEVCON.DBF")
      CREATE2007()
      TEST := .T.
   ENDIF

   USE ("DEVCON.DBF")
   SET INDEX TO DEVKDNR, DEVVILM
   SET ORDER TO 2

   IF TEST

      aNum  := {1,3,5,7,11,13,17,19,23,27}
      FILLSCOPE(aNum)

      SET SCOPETOP    TO "1"
      SET SCOPEBOTTOM TO "1"
      BROWSE()
      SET SCOPETOP    TO

      aNum  := {2,4,6,7,10,12,14,16,18,20,22,200}
      FILLSCOPE(aNum)

      SET SCOPETOP    TO "1"
      SET SCOPEBOTTOM TO "1"
      BROWSE()
      SET SCOPETOP    TO

      GO TOP
      IF RLOCK()
         REPLACE KOMMENTAR WITH Var2Bin(aNum)
         UNLOCK
      ENDIF
      CLOSE

   ENDIF

   USE ("DEVCON.DBF")
   SET INDEX TO DEVKDNR, DEVVILM
   SET ORDER TO 2

   aNum  := Bin2Var(KOMMENTAR)
   FILLSCOPE(aNum)

   SET SCOPETOP    TO "1"
   SET SCOPEBOTTOM TO "1"
   BROWSE()
   SET SCOPETOP    TO

RETURN

STATIC PROCEDURE CREATE2007
Local aStruct := {                 ;
   { "KDNR"        ,"C" ,  5, 0 } ,;
   { "NAME"        ,"C" , 30, 0 } ,;
   { "VORNAME"     ,"C" , 30, 0 } ,;
   { "FIRMA"       ,"C" , 30, 0 } ,;
   { "STRASSE"     ,"C" , 30, 2 } ,;
   { "PLZ"         ,"C" , 10, 2 } ,;
   { "ORT"         ,"C" , 30, 0 } ,;
   { "LAND"        ,"C" ,  2, 0 } ,;
   { "EMAIL"       ,"C" , 30, 0 } ,;
   { "IRQ"         ,"C" , 30, 0 } ,;
   { "GEBURT"      ,"D" ,  8, 0 } ,;
   { "KOMMENTAR"   ,"M" , 10, 0 } ,;
   { "VILMESUCH"   ,"C" ,  1, 0 }   }

 DbCreate( "DEVCON.DBF", aStruct )

 FILLITNOW()

RETURN

STATIC PROCEDURE FILLITNOW()
LOCAL i, iMax := 250

   USE ("DEVCON.DBF")
   FOR I = 1 TO iMax
      APPEND BLANK

      REPLACE KDNR      WITH STRZERO(RECNO(),5)
*      REPLACE NAME
*      REPLACE VORNAME
*      REPLACE FIRMA
*      REPLACE STRASSE
*      REPLACE PLZ
*      REPLACE ORT
*      REPLACE LAND
*      REPLACE EMAIL
*      REPLACE IRQ
*      REPLACE GEBURT
*      REPLACE KOMMENTAR
      REPLACE VILMESUCH WITH "0"
   NEXT

   INDEX ON KDNR      TO DEVKDNR
   CLOSE INDEX
   INDEX ON VILMESUCH TO DEVVILM
   CLOSE INDEX

   CLOSE DATABASE
RETURN

STATIC FUNCTION MARKPOSI()
   IF RLOCK()
      REPLACE VILMESUCH WITH "0"
      UNLOCK
   ENDIF
RETURN .T.

STATIC FUNCTION FILLSCOPE(aNum)
LOCAL i, iMax := LEN(aNum)

   DBEVAL( {|| MARKPOSI() }      ,; // <bBlock>,
           {|| VILMESUCH = "1" } )  // <bForCondition>

   FOR i = 1 TO iMax
       GOTO (aNum[i])
       IF RLOCK()
          REPLACE VILMESUCH WITH "1"
          UNLOCK
       ENDIF
   NEXT

RETURN NIL

*
* eof
*
also wenn ich den das erste Mal starte zeigt er mir die 1,3,5 ... sowie
die 2,4,6 ... Reihen korrekt im Browse an. Nun "speicher" ich das Array
im Memo und bekomme "nur" 3 Elemente {2,4,6} ... ?
Das sieht man dann auch wenn man das Programm noch mal started
(ohne parameter)

wenn ich ihn nun "zwinge" (mit parameter) "speichert" er korrekt das
ganze Array ab.

was läuft da "beim ersten Mal" ab ? muss ich Memo "vorbelegen" wenn
ich es mit einem Array "nutzen" will ?

gruss by OHR
Jimmy
Sören
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 205
Registriert: Mo, 07. Aug 2006 10:18
Wohnort: Leipzig
Danksagung erhalten: 11 Mal

Beitrag von Sören »

Hallo Jimmy,

Du speicherst binäre Daten in ein Memo-Feld, das nur für Plain-Text ausgelegt ist. Da liegt Dein Problem.

Wenn Du das Array wirklich in ein Memo-Feld und nicht in ein Binär-Datenfeld speichern willst/kannst, dann könntest Du:

1. wenn es sich um ein 1-dimensionales Array handelt, dieses in einen String umwandeln und dann speichern

2. es mit den Asinet-Funktionen ToBase64() und FromBase64() versuchen:

Field->memofeld := ToBase64( Var2Bin( aArray ) )
cZurueck := Bin2Var( FromBase64( Field->memofeld ) )

Tschüs,
Sören
Benutzeravatar
andreas
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1902
Registriert: Mi, 28. Sep 2005 10:53
Wohnort: Osnabrück
Hat sich bedankt: 4 Mal
Kontaktdaten:

Beitrag von andreas »

Sören hat geschrieben:Hallo Jimmy,

Du speicherst binäre Daten in ein Memo-Feld, das nur für Plain-Text ausgelegt ist. Da liegt Dein Problem.

Wenn Du das Array wirklich in ein Memo-Feld und nicht in ein Binär-Datenfeld speichern willst/kannst, dann könntest Du:

1. wenn es sich um ein 1-dimensionales Array handelt, dieses in einen String umwandeln und dann speichern

2. es mit den Asinet-Funktionen ToBase64() und FromBase64() versuchen:

Field->memofeld := ToBase64( Var2Bin( aArray ) )
cZurueck := Bin2Var( FromBase64( Field->memofeld ) )

Tschüs,
Sören
Hallo Jimmy,

den 2. von Sören vorgeschlagenen Punkt benutze ich auch, um Bitmaps im normalen Memofeld abzulegen. Funktioniert einwandfrei.
Gruß,

Andreas
VIP der XUG Osnabrück
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hi,

also wenn ich es recht weiß unterliegen die 'normalen' Memofelder der Typconvertierung beim Speichern (ANSI <-> OEM), was natürlich Schrott aus den Daten macht wenn ein Byte in die Konvertierung fällt.

Daher geht es mit DFBDBE gar nicht, und bei FOXDBE muss man 'V' wählen, zusätzlich zu dem oben gesagten.
Gruß
Hubert
Sören
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 205
Registriert: Mo, 07. Aug 2006 10:18
Wohnort: Leipzig
Danksagung erhalten: 11 Mal

Beitrag von Sören »

Hallo Hubert!

Dass man besser FOXDBE und "V"-Felder statt DBFDBE und "M"-Felder zum Speichern von Binärdaten verwendet, steht sicher außer Frage.

Aber wenn man es trotzdem machen möchte oder sogar muss (aus welchen Gründen auch immer), sehe ich in der Oem <--> Ansi - Konvertierung jedenfalls keine Behinderung.

Angenommen in der Applikation ist der Ansi-Zeichensatz eingestellt, so werden die Daten beim Speichern im Memo-Feld nach Oem konvertiert; wenn die Daten aus dem Memo-Feld wieder abgerufen werden, erfolgt eine Rückkonvertierung nach Ansi. Demnach sollte es in dieser Hinsicht keine Probleme geben.

Allerdings muss ich gestehen, dass es sich bei dem oben Gesagten lediglich um theoretische Überlegungen handelt - gemacht habe ich das noch nicht! Aber Andreas hat, wie er schrieb, keine Probleme damit.

Tschüs,
Sören
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Sören hat geschrieben:, sehe ich in der Oem <--> Ansi - Konvertierung jedenfalls keine Behinderung.
dass wir Probleme nicht sehen - oder noch nicht erkannt haben - hat nichts damit zu tun, dass sie nicht bestehen. :wink:
Sorry, ich konnte mir den kleinen Wink nicht verkneifen :D

Ich habe auch schon Dateien mit memoread() eingelesen und einer eigenen Funktion wieder weggespeichert. Ich habe zwar damit keine Probleme gehabt, aber sind die Dateien wirklich in jedem Byte unverändert geblieben ?

Stefen oder war es Till, hat dringend davon abgeraten Stringfunktionen (die Unterliegen der Ansi/OEM Konvertierung) für binäre Daten zu verwenden.
Ich habe deshalb meine eigenen Funktionen geschrieben.

Memodateien - soweit ich mich erinnern kann - reagieren äußerst empfindlich bei chr(0) und chr(26) (bei letztem bin ich nicht sicher).

Falls beim Lesen eine Konvertierung genau die vom Speichern aufhebt, sollte man davon ausgehen können, dass diese unerheblich ist.
Wenn aber Morgen ein anderes Programm oder eine andere PC Einstellung auch auf die Daten zugreift und nun die Konvertierung anders ist oder gar nicht stattfindet, sind die Daten nicht mehr so wie sie waren.

Natürlich kann man die Arrays als Strings abspeichern und wenn man diese in ein Format umwandelt, das keine Zeichen hat die überhaupt umgewandelt werden (7Bit) nun schön. Dann will ich dir zustimmen.
Gruß
Hubert
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12909
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

Beitrag von AUGE_OHR »

hi,

danke erstmal für eure Antworten. Leider hab ihr "nicht" auf meine Frage
geantwortet warum es "beim ersten Mal" nur 3 Elemente scheinbar
abspeichert und danach dann alle Elemente.

Auch ist es kein Problem ein Array mittels Var2Bin() in ein Memo Type
M,10 abzuspeichern. Das geht schon mit Cl*pper so.

"umlaute" hab ich nicht zu befürchten, da nur RECNO() ins Array auf-
genommen werden.

Meine Frage ist : warum speichert Xbase++ "beim ersten mal" nur 3
Elemente ab und danach dann "alle" ? Cl*pper macht das "richtig".

gruss by OHR
Jimmy
Antworten