![]() |
StrinGrid in einer Datei speichern und auch wieder öffnen
Hallo!
Ich hab eine Tabelle(StringGrid) und will diese in einer Datei speichern (mit SaveDialog). mit dem OpenDialog soll die Datei wieder geöffnet werden können und der inhalt wieder in die tabelle geschrieben werden sollen. Wie stelle ich das an? Grüße, dopeline |
Die Dialoge dienen nur dazu dir einen Dateinamen zu liefern. Nicht mehr und nicht weniger. Um das Speichern mußt du sich schon selber kümmern.
kein in zwei verschachtelten for-Schleifen die Zeilen und Spalten durch und schreib sie in eine Stringliste. |
Hallo,
hier sind ein paar function's mit denen Du das machen kannst.
Delphi-Quellcode:
Die Funktionen auf die es ankommt sind:
function GetToken(aString:String; SepChar: Char;TokenNum: Integer):String;
var Token : String; StrLen : Integer; TNum : Integer; TEnd : Integer; begin StrLen := Length(aString); TNum := 1; TEnd := StrLen; while ((TNum <= TokenNum) and (TEnd <> 0)) do begin TEnd := Pos(SepChar,aString); if TEnd <> 0 then begin Token := Copy(aString,1,Tend - 1); Delete(aString,1,TEnd); Inc(TNum); end // if TEnd <> 0 then else begin Token := aString; end; // else if TEnd <> 0 then end; // while ((TNum <= TokenNum) and (TEnd <> 0)) do If TNum >= TokenNum then begin Result := Token; end // If TNum >= TokenNum then else begin Result := ''; end;// else If TNum >= TokenNum then end; function NumToken(aString:String; SepChar: Char):Integer; var RChar : Char; StrLen : Integer; TNum : Integer; TEnd : Integer; begin If SepChar = '#' then RChar := '*' else RChar := '#'; StrLen := Length(aString); TNum := 0; TEnd := StrLen; while TEnd <> 0 do begin Inc(TNum); TEnd := Pos(SepChar,aString); if TEnd <> 0 then begin aString[TEnd] := RChar; end; end; Result := TNum; end; procedure DeleteRow(yourStringGrid: TStringGrid; ARow: Integer); var i: Integer; begin with yourStringGrid do begin for i := ARow to RowCount-2 do Rows[i].Assign(Rows[i+1]); RowCount := RowCount - 1 end; end; procedure DeleteEmptyGridRows(Grid : TStringGrid); var aCol, aRow : Integer; CheckSum : Integer; begin CheckSum:=Grid.ColCount; aRow:=0; CheckSum:=0; While aRow<=Grid.RowCount-1 do begin CheckSum:=0; For aCol:=0 to Grid.ColCount-1 do begin If Grid.Cells[aCol,aRow]<>'' then Inc(CheckSum); end; If CheckSum=0 then DeleteRow(Grid,aRow) else Inc(aRow); end; end; function SaveGridToFile(Grid : TStringGrid; Filename : String; SepChar : Char; DelEmptyRows : Boolean) : Boolean; var Tmp : TStringList; aCol, aRow : Integer; H : String; aGrid : TStringGrid; begin Result:=True; Tmp:=TStringList.Create; aGrid:=TStringGrid.Create(Nil); Try Try aGrid.ColCount:=Grid.ColCount; aGrid.RowCount:=Grid.RowCount; For aRow:=0 to Grid.RowCount-1 do aGrid.Rows[aRow].Assign(Grid.Rows[aRow]); If DelEmptyRows then DeleteEmptyGridRows(aGrid); For aRow:=0 to aGrid.RowCount-1 do begin H:=''; For aCol:=0 to aGrid.ColCount-1 do H:=H+Grid.Cells[aCol,aRow]+SepChar; Tmp.Add(H); end; Tmp.SaveToFile(Filename); Except Result:=False; end; Finally aGrid.Free; Tmp.Free; end; end; function LoadGridFromFile(Grid : TStringGrid; Filename : String; SepChar : Char) : Boolean; var Tmp : TStringList; NewColCount : Integer; aCol, aRow : Integer; begin Result:=True; Tmp:=TStringList.Create; Try Try Tmp.LoadFromFile(Filename); NewColCount:=NumToken(Tmp.Strings[0],SepChar)-1; Grid.ColCount:=NewColCount; Grid.RowCount:=Tmp.Count; For aRow:=0 to Tmp.Count-1 do begin For aCol:=1 to NewColCount do Grid.Cells[aCol-1,aRow]:=GetToken(Tmp[aRow],SepChar,aCol); end; Except Result:=False; end; Finally Tmp.Free; end; end; function SaveGridToFile(Grid : TStringGrid; Filename : String; SepChar : Char; DelEmptyRows : Boolean) : Boolean; function LoadGridFromFile(Grid : TStringGrid; Filename : String; SepChar : Char) : Boolean; Die proceduren DeleteEmptyGridRows, DeleteRow, GetToken und NumToken sind nur Hilfsproceduren Parameter für SaveGridToFile: Grid : Das TStringGrid, dessn Inhalt gespeichert werden soll Filename : Pfad und Dateiname SepChar : Das Separierungzeichen für die einzelnen Strings einer Zeile z.B. ein ; DelEmptyRows : Wenn True, dann werden alle Zeilen ohne Inhalt nicht gespeichert. Parameter LoadGridFromFile: Grid : Das TStringGrid, dessn Inhalt gespeichert werden soll Filename : Pfad und Dateiname SepChar : Das Separierungzeichen für die einzelnen Strings einer Zeile z.B. ein ; |
Zitat:
sorry, finde ich zu kompliziert. insbeondere das Seperierungszeichen brauchst du nicht. Row und Col sind Tstrings und die bringen mit commatext schon sowas von haus aus mit. hier ist eine andere Variante: ![]() Mfg Frank |
Hallo Keldorn,
Du hast recht im Vergleich mit ![]() ist es tatsächlich komplizierter. Das mit dem SepChar hat natürlich seinen Grund. Damals, als meine Kunden noch Win 95 nutzen ist beim Zugriff von Delphi auf Excel der Rechner ständig abgeschmiert (Macke unter Win95 wenn man zu viele Interfacezeiger anfordert). Ich brauchte jedoch einen Export nach Excel. Da Excel von Haus aus den TapStop als SepChar eingestellt hat habe ich mir die o.g. Funktionen gebastelt. Damit brauchen die Anwender im Textdateiöffnungsassistenten (was für ein Wort) nur auf Fertigstellen klicken. |
außerdem sind fehler drin
Delphi-Quellcode:
du löschst mit deleteemptyrows die leeren Zeilen, ok
If DelEmptyRows then
DeleteEmptyGridRows(aGrid); For aRow:=0 to aGrid.RowCount-1 do begin H:=''; For aCol:=0 to aGrid.ColCount-1 do H:=H+Grid.Cells[aCol,aRow]+SepChar; Tmp.Add(H); end; Tmp.SaveToFile(Filename); anschließen durchläufst du die Zellen deines Hilfsgrids aGrid bis zum ende holst dir die Strings aber vom Originalem Grid (Grid) Zitat:
Mfg Frank |
Hallo Keldorn,
Du hast schon wieder recht. Es muss natürlich
Delphi-Quellcode:
lauten.
H:=H+aGrid.Cells[aCol,aRow]+SepChar;
Vielen Dank für den Hinweis. Der Fehler hat sich bei mir noch nie bermkbar gemacht. |
Zitat:
|
Hallo Keldorn,
die Möglichkeit des eigenen SepChar gibt es ab D6. Ich verwende aber immer noch D5 (wegen vielen Bugs in D6). Da aber meine Kunden jetzt alle min Win2000 verwenden und dort die Automationschnittstelle zu Excel einwandfrei funktioniert benötige ich die Funktionen SaveGridToFile und LoadGridFromFile gar nicht mehr. |
Also
![]() Gruß, dopeline :dancer: |
mit der löschmethode (DeleteRow) löscht man immer die unterste zeile der tabelle. wie stelle ich das so um, dass nur die zeile, die ich markiert habe gelöscht wird?
Grüße, dopeline :dancer: |
Hallo dopeline,
ich habe DeleteRow gerade getestet. Es wird genau die Zeile gelöscht, die im Paramter ARow übergeben wird. |
:( :( :( also irgentwie will das nicht...
und da gibt es keine andere möglichkeit?! :? dass er einließt, in welcher zeile er gerade ist und diese dann löscht. |
hy,
also saven kannstdu ein stringrid in eine csv datei so :
Delphi-Quellcode:
die passende funtion zum laden hab ich gerade nicht bei hand aber schicke dir sie so schnel es geht!
procedure TForm1.Button1Click(Sender: TObject);
var R, C : integeR; S : string; begin if SaveDialog.Execute then begin for R := 0 to sg.RowCount - 1 do begin S := ''; for C := 0 to sg.ColCount - 1 do S := S + sg.Cells[C,R] + ';'; delete(S,length(S),1); //loescht den ueberfluessigen ; lb.Items.Append(S); end; lb.Items.SaveToFile('SaveDialog.Filename'); end; end; cu |
Also das mit dem Speichern klappt schon wunderbar! jetzt ist noch dolgendes problem:
ich will (im laufenden programm) eine zeile markieren und diese dann mit einem button/short-cut entfehrnen. ich hab mir schon einige sachen ageschaut, aber da wurde immer nur die letzte (unterste) zeile der tabelle entfernt. man müsste gucken, welche zeile gerade markiert ist und sie dann löschen. (vielleicht mit onSelectCell ?) Gruß, dopeline |
Habe kein DeleteRow im StringGrid?
hmmm... eigentlich sollte das mit
StringGrid.DeleteRow (Stringgrid.row); gehen. Aber mein StringGrid hat die Methode DeleteRow nicht :?: Kann mir einer sagen warum? |
ich hab da noch ne frage:
wenn ich eine datei öffne bearbeite und dann wieder speichern will, erscheint immer der savedialog. beim abspeichern kommt dann die anfrage zum überschreiben (ist auch richtig so). das ist aber eher eine "Speichern unter"-Lösung. ich will, dass wenn ich ein dokument öffne, bearbeite und dann normal auf "speichern" (nicht auf "speichern unter") gehe, er das dokument am gleichen ort und mit dem gleich dateinamen abspeichert. (ohne den savedialog!). da müsste doch in einer variablen gespeichert werden, von wo die datei geöffnet wurde und wie sie heißt ==> und bei "normalem" speichern müsste er den savedialog weglassen. als dateipfad und dateiname springt dann die variable ein... geht das irgentwie so in der art? (oder auch anders) wenn ja, wie? Grüße, dopeline |
Das geht genauso, wie du es beschrieben hast. Warum programmierst du es nicht einfach und kuckst, was passiert? :roll:
|
ok habs hinbekommen. ich hab gesagt er soll beim öffnen die daten einlesen:
Code:
und beim "normalen" speichern guckt er, ob in "date" etwas drin steht.
datei:=opendialog1.filename;
wenn ja:
Code:
wenn nicht, kommt der saveialog.
SaveToFile(datei);
funktioniert super! |
wie mache ich es, wenn die datei erfolgreich (ohne savedialog) abgespeichert wurde, dass unten in der satusbar, für eine gewisse zeit, eine Meldung kommt (z.b."Das Dokument wurde erfolgreich gespeichert")?
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:35 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz