| |
|
|
- Page 1 - |
|
Uwe Lang | Ich habe in meinen Programm mit der Listview.dll ein Listview erstellt. Nun möchte Io l' Inhalt als CSV File speichern zusammen mit dem Testata der Tabelle. Wie muss Io l' Speicherbereich von HeaderToCSV (lvhed#) in WriteFileQuick einbauen damit der Testata und der Tabelleninhalt zusammen in un File gespeichert wird? Nacht etlichen erfolglosen versuchen weiß ich nicht weiter.
Proc CSV_Speichern
Declare tx$,xs&,lvber#,hd&,lvhed#
Dim lvhed#,1848'Anzahl Spalten * 264
tx$ = datname$
xs&=GetNeededMemory(lv&,1)
Dim lvber#, xs&
hd&=HeaderToCsv(lv&,lvhed#,59,1)
xs&=ListviewToCsv(lv&,lvber#,59,1)
WriteFileQuick(addr(tx$),lvber#,0,(hd& + xs&))
Dispose lvber#
Dispose lvhed#
EndProc
|
|
|
| |
|
|
|
« Dieser Beitrag wurde als Lösung gekennzeichnet. » |
|
H.Brill | Wie ich sehe, hast du ja auch XProfan X3. Man kann durchaus ein Listview, das mit der Listview.dll erstellt worden ist, mit XProfans eigenen Funktionen bearbeiten. Es ist damit auch nicht unbedingt vorgeschrieben, den Inhalt des Listview in einen Speicherbereich zu schieben, um diesen dann mit WritFileQuick() zu speichern. In den folgenden Procs verwende ich die wunderbaren neuen Move-Funktionen :
Proc Lade
Declare Int bytes1, bytes2
Declare String Testata
ClearList 0
Move("FileToList", datei)
Testata = GetString$(0, 0)' Hier hast du die Headerzeile
DeleteString(0, 0)
' die Headerzeile einfach in Testata speichern und in der
' Listboxliste löschen. Jetzt kannst du mit dem Testata
' machen, was du vorhast oder willst.
ClearList grid
Move("ListToHandle", grid)
EndProc
Proc Speichere
Declare Memory bereich1
Dim bereich1, 256
Declare Int bytes1, bytes2, anzahlColumns
Declare String Testata
anzahlColumns = GetColumns(grid)
WhileLoop 0, anzahlColumns - 1
Clear bereich1
GetColumnName(grid, bereich1, &LOOP)
If &LOOP < (anzahlColumns - 1)
Testata = Testata + String$(bereich1, 0) + ","
Else
Testata = Testata + String$(bereich1, 0)
EndIf
EndWhile
ClearList 0
AddString(0, Testata)
Move("HandleToList", grid)
Move("ListToFile", datei)
Messagebox(datei + " gespeichert", "Info", 0)
Dispose bereich1
EndProc
Das Handle grid ist ein mit der Listview.dll erstelltes Listview. Das klappt bei mir wunderbar. Wie man sieht, lassen sich die Vorteile der Listview.dll (editierbare Felder, PrintListview usw.) mit den neuen Vorteilen von XProfan X3 prima kombinieren. Das geht auch anders rum, also eine mit XProfan erstellte Gridbox und den Funktionen der Listview.dll.
PS : Ob da jetzt ein Komma oder ein | zwischen den Einträgen steht, potrebbe egal sein. Wenn es dich stört, kannst du sie ja austauschen. Ich hoffe, ich konnte dir etwas helfen. |
|
|
| Benutze XPROFAN X3 + FREEPROFAN Wir sind die XProfaner. Sie werden von uns assimiliert. Widerstand ist zwecklos! Wir werden alle ihre Funktionen und Algorithmen den unseren hinzufügen.
Was die Borg können, können wir schon lange. | 20.09.2015 ▲ |
|
|
|
|
|
| Wie ich das sehe schreibt writefilequick 1 Speicher in 1 File.
Reserviere Dir 1 Speicher so grande wie lvhed# und lvber# zusammen.
Kopiere lvhed# und lvber# in den neuen Speicher.
writefilequick neuen Speicher.
Code ungetestet hier einfach reingepinselt nur zum Verständnis. |
|
|
| |
|
|
|
Uwe Lang | Danke per die schnelle Antwort, das hatte ich in ähnlicher Form auch schon. Mit dem selben Ergebnis, der Testata wird geschrieben und danach wird der Inhalt der Datenbank total verschoben. Das sieht so aus als ob die Dimensione des Speicherbereichs des Headers größer ist als berechnet b.z.w vorgegeben. Ich muss circa das Problem noch einmal in Ruhe nachdenken. |
|
|
| |
|
|
|
H.Brill | lvhead# ist ja auch nicht grande genug. Am besten ist es, die Anzahl der tatsächlichen Spalten zu ermitteln. Außerdem sind die Kommas (Anzahl spalten - 1) dazu zu rechnen. Wenn als Flag bei HeaderToCSv() noch die Anführungszeichen dazu kommen (Flag = 0) mußt du auch noch pro Spalte zwei " mitrechnen. Außerdem ist noch das Nullbyte am Ende des Strings im Bereich dazu zu zählen.
Genau diese Anzahl bringt dir dann HeaderToCsv(). Da man den Bereich spalten * 264 + die zus. Kommas usw.nehmen muß (Mit GetColumns(H) bekommt man ja die Anzahl Spalten des Grid heraus), wäre es am besten, einen separaten Bereich mit dem Ergebnis von HeaderToCsv() zu dimmen und auch soviele Bytes vom alten Bereich in den Neuen zu kopieren.
Ich denke mal, das ist das Sicherste. |
|
|
| Benutze XPROFAN X3 + FREEPROFAN Wir sind die XProfaner. Sie werden von uns assimiliert. Widerstand ist zwecklos! Wir werden alle ihre Funktionen und Algorithmen den unseren hinzufügen.
Was die Borg können, können wir schon lange. | 15.09.2015 ▲ |
|
|
|
|
Uwe Lang | Ich komme erst jetzt dazu zu antworten, so wie ich das Problem lösen wollte habe ich es nicht hinbekommen. Ich habe das Ganze erst einmal als Notlösung so gemacht, das ich in das Listview eine leere Zeile an Position 0 einfüge und danach die Spaltenköpfe auslese und den Text in die entsprechenden Felder eintrage. Nach dem Speichern entferne ich die Zeile wieder aus dem Listview. Das kurze Geruckel fällt nicht auf, da ich vor dem Speichern noch Daten aus einem anderen Listview hineinkopiere. Trotzdem danke per die Hinweise. Wenn ich wieder etwas mehr Zeit habe, werde ich mir das Problem noch einmal anschauen. |
|
|
| |
|
|
|
H.Brill | Wie ich sehe, hast du ja auch XProfan X3. Man kann durchaus ein Listview, das mit der Listview.dll erstellt worden ist, mit XProfans eigenen Funktionen bearbeiten. Es ist damit auch nicht unbedingt vorgeschrieben, den Inhalt des Listview in einen Speicherbereich zu schieben, um diesen dann mit WritFileQuick() zu speichern. In den folgenden Procs verwende ich die wunderbaren neuen Move-Funktionen :
Proc Lade
Declare Int bytes1, bytes2
Declare String Testata
ClearList 0
Move("FileToList", datei)
Testata = GetString$(0, 0)' Hier hast du die Headerzeile
DeleteString(0, 0)
' die Headerzeile einfach in Testata speichern und in der
' Listboxliste löschen. Jetzt kannst du mit dem Testata
' machen, was du vorhast oder willst.
ClearList grid
Move("ListToHandle", grid)
EndProc
Proc Speichere
Declare Memory bereich1
Dim bereich1, 256
Declare Int bytes1, bytes2, anzahlColumns
Declare String Testata
anzahlColumns = GetColumns(grid)
WhileLoop 0, anzahlColumns - 1
Clear bereich1
GetColumnName(grid, bereich1, &LOOP)
If &LOOP < (anzahlColumns - 1)
Testata = Testata + String$(bereich1, 0) + ","
Else
Testata = Testata + String$(bereich1, 0)
EndIf
EndWhile
ClearList 0
AddString(0, Testata)
Move("HandleToList", grid)
Move("ListToFile", datei)
Messagebox(datei + " gespeichert", "Info", 0)
Dispose bereich1
EndProc
Das Handle grid ist ein mit der Listview.dll erstelltes Listview. Das klappt bei mir wunderbar. Wie man sieht, lassen sich die Vorteile der Listview.dll (editierbare Felder, PrintListview usw.) mit den neuen Vorteilen von XProfan X3 prima kombinieren. Das geht auch anders rum, also eine mit XProfan erstellte Gridbox und den Funktionen der Listview.dll.
PS : Ob da jetzt ein Komma oder ein | zwischen den Einträgen steht, potrebbe egal sein. Wenn es dich stört, kannst du sie ja austauschen. Ich hoffe, ich konnte dir etwas helfen. |
|
|
| Benutze XPROFAN X3 + FREEPROFAN Wir sind die XProfaner. Sie werden von uns assimiliert. Widerstand ist zwecklos! Wir werden alle ihre Funktionen und Algorithmen den unseren hinzufügen.
Was die Borg können, können wir schon lange. | 20.09.2015 ▲ |
|
|
|
|
H.Brill | Hier noch ein Abfallprodukt, um besser Stringadressen in einen Bereich zu schaufeln, wobei vorteilhaft ist, daß es auch mit Variablen geht. Ist jedenfalls einfacher, als einzeln mit den Bereichsbefehlen zu hantieren. SItem() der Listview.dll verlangt ja sowas :
SUBPROC Move.StringAdrToMem
Parameters String s, String d, Memory B
' s = der zusammengesetzte String
' d = der Trenner
' B = der Bereich
Declare Long anzahl
Declare String TArray[]
ClearList 0
Clear B, TArray[]
anzahl = Move("StrToList", s, d)
anzahl = Move("ListToArr", TArray[])
Var Int z = 0
WhileLoop 0, anzahl - 1
Long B, z = Addr(TArray[&LOOP])
Inc z, 4
EndWhile
Return anzahl
ENDPROC
Declare Memory bereich
Dim bereich, 12' per 3 Stringadressen
Clear bereich
Move("StringAdrToMem", "Maier,Hamburg,4711", ",", bereich)
SItem(grid, bereich, 3)
Clear bereich
eintrag = "Müller,Berlin,4714"
Move("StringAdrToMem", eintrag, ",", bereich)
SItem(grid, bereich, 3)
Vielleicht kann es ja jemand brauchen. |
|
|
| Benutze XPROFAN X3 + FREEPROFAN Wir sind die XProfaner. Sie werden von uns assimiliert. Widerstand ist zwecklos! Wir werden alle ihre Funktionen und Algorithmen den unseren hinzufügen.
Was die Borg können, können wir schon lange. | 21.09.2015 ▲ |
|
|
|
|
| Bestimmt, aber hier in diesem Thema würde er es ja nicht finden.
Besser hier bei den Quelltexten posten: [...] |
|
|
| |
|
|
|
H.Brill | Da hast du Recht. Obwohl ich nicht weiß, warum obiges funktioniert. Hatte vor einiger Zeit das ausprobiert und war erstaunt. Normalerweise müßte doch nach der Proc bzw. SubProc das TArray[] wieder freigegeben worden sein bzw. nicht mehr existieren. Das TArray[] ist ja lokal definiert. Somit sollten auch die Stringadressen in diesem nicht mehr existieren. Trotzdem kann man sie außerhalb nutzen.
Ich potuto mir höchstens denken, daß diese Arrays trotzdem global sind.
Oder hat sonst noch jemand eine Erklärung dafür ? |
|
|
| Benutze XPROFAN X3 + FREEPROFAN Wir sind die XProfaner. Sie werden von uns assimiliert. Widerstand ist zwecklos! Wir werden alle ihre Funktionen und Algorithmen den unseren hinzufügen.
Was die Borg können, können wir schon lange. | 21.09.2015 ▲ |
|
|
|
|
| Es gibt da naturalmente mehrere Mgl.
Auszuschließen ist vlt, dass bei:
proc so declare lala[] das lala von Roland global als __int__proc_so_lala[] verarbeitet wird denn sonst würde z.B. Rekursion nicht funktionieren. Funktioniert sie?
Ich schätze eher, dass hier Windows tut was es immer tut: Speicherhandle freigeben aber Speicherinhalt dabei nicht antasten und einfach überschreiben wenn mal wieder necessario.
Oder Roland hat einfach nochmal ein eigenes Management drübergelegt. |
|
|
| |
|
|
|
H.Brill | Ich glaube, mit deiner Vermutung mit Windows hast du recht. Hab mal etwas gespielt :
Declare Long t[]
Cls
TesteArray()
Print
Print t[0], String$(t[0], 0)
Print t[1], String$(t[1], 0)
Print "Addresse : "; t[0]; " Inhalt : "; String$(t[0], 0)
Print "Addresse : "; t[1]; " Inhalt : "; String$(t[1], 0)
Print t[0], String$(t[0], 0)
Print t[1], String$(t[1], 0)
WaitKey
End
Proc TesteArray
Declare String lokalarray[]
lokalarray[0] = "Hallo"
lokalarray[1] = "Welt"
WhileLoop 0, 1
Print lokalarray[&LOOP]
t[&LOOP] = Addr(lokalarray[&LOOP])
EndWhile
Clear lokalarray[]
EndProc
Also, verlassen kann man sich darauf nicht. Das sieht man, wenn nochmals Strings ("blabla") mit ins Spiel kommen. Deswegen ist Vorsicht geboten, wenn zwischen Proc-Aufruf und Weiterverabeitung noch was anderes gemacht wird. |
|
|
| Benutze XPROFAN X3 + FREEPROFAN Wir sind die XProfaner. Sie werden von uns assimiliert. Widerstand ist zwecklos! Wir werden alle ihre Funktionen und Algorithmen den unseren hinzufügen.
Was die Borg können, können wir schon lange. | 22.09.2015 ▲ |
|
|
|
|
Uwe Lang | Nach längerer Abwesenheit komme ich erst jetzt wieder dazu, mich dem Problem noch einmal zu widmen. Ich habe jetzt die oben beschriebene Variante gewählt und alles mit den XProfan Bordmitteln gelöst.
Mein Dank an alle, die mir mit den Anregungen geholfen haben. |
|
|
| |
|
|