| |
|
|
- Seite 1 - |
|
Uwe Lang | Ich habe in meinen Programm mit der Listview.dll ein Listview erstellt. Nun möchte ich den Inhalt als CSV Datei speichern zusammen mit dem Header der Tabelle. Wie muss ich den Speicherbereich von HeaderToCSV (lvhed#) in WriteFileQuick einbauen damit der Header und der Tabelleninhalt zusammen in eine Datei 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 Header
ClearList 0
Move("FileToList", datei)
Header = GetString$(0, 0)' Hier hast du die Headerzeile
DeleteString(0, 0)
' die Headerzeile einfach in Header speichern und in der
' Listboxliste löschen. Jetzt kannst du mit dem Header
' 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 Header
anzahlColumns = GetColumns(grid)
WhileLoop 0, anzahlColumns - 1
Clear bereich1
GetColumnName(grid, bereich1, &LOOP)
If &LOOP < (anzahlColumns - 1)
Header = Header + String$(bereich1, 0) + ","
Else
Header = Header + String$(bereich1, 0)
EndIf
EndWhile
ClearList 0
AddString(0, Header)
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, dürfte 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 Datei.
Reserviere Dir 1 Speicher so groß 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 für die schnelle Antwort, das hatte ich in ähnlicher Form auch schon. Mit dem selben Ergebnis, der Header wird geschrieben und danach wird der Inhalt der Datenbank total verschoben. Das sieht so aus als ob die Größe des Speicherbereichs des Headers größer ist als berechnet b.z.w vorgegeben. Ich muss über das Problem noch einmal in Ruhe nachdenken. |
|
|
| |
|
|
|
H.Brill | lvhead# ist ja auch nicht groß 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 für 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 Header
ClearList 0
Move("FileToList", datei)
Header = GetString$(0, 0)' Hier hast du die Headerzeile
DeleteString(0, 0)
' die Headerzeile einfach in Header speichern und in der
' Listboxliste löschen. Jetzt kannst du mit dem Header
' 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 Header
anzahlColumns = GetColumns(grid)
WhileLoop 0, anzahlColumns - 1
Clear bereich1
GetColumnName(grid, bereich1, &LOOP)
If &LOOP < (anzahlColumns - 1)
Header = Header + String$(bereich1, 0) + ","
Else
Header = Header + String$(bereich1, 0)
EndIf
EndWhile
ClearList 0
AddString(0, Header)
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, dürfte 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' für 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 könnte 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 natürlich 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 benötigt.
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. |
|
|
| |
|
|