Autor Beitrag
bf109g.01
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 84



BeitragVerfasst: Di 23.08.11 15:19 
Hallo, ich habe ein Record-Array mit einer Eigenschaft "Beschreibung : Text".
In die Recordeigenschaft Beschreibung will ich nämlich einen längeren Textblock unterbringen.
Deshalb gibt es in der Eingabe-Maske ein Memo dafür. Speichern wollte ich das dann so:
ausblenden Delphi-Quelltext
1:
 ArrayF[Stelle].Beschreibung:=Fr_MLoesung.Lines.					

Das gibt Fehler. Wie kann ich das stattdessen anständig hinbekommen?

LG


Moderiert von user profile iconNarses: Topic aus Dateizugriff verschoben am Di 23.08.2011 um 15:45
bummi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: Di 23.08.11 15:44 
Der Datentyp Text ist Synonym für Textfile (Assign(f, dateiname), Reset(f) etc..)
Du benötigst den Typ String und ArrayF[Stelle].Beschreibung:=Fr_MLoesung.Lines.Text;

_________________
Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS

Für diesen Beitrag haben gedankt: bf109g.01
bf109g.01 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 84



BeitragVerfasst: Di 23.08.11 17:06 
user profile iconbummi hat folgendes geschrieben Zum zitierten Posting springen:
Du benötigst den Typ String

Dann hab ich aber nur 255 Zeichen frei. Soweit ich weiß lässt sich ein String ohne Einschränkung (=255) gar nicht speichern/laden, weils wohl nur ein Zeiger ist, oder irgendsowas....
Wie kann ich den Text länger machen? So 500 Zeichen wären fein... Muss ich da mit ner Stringlist arbeiten?
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 23.08.11 20:03 
Nein, du solltest dir lieber eine eigene Datenstruktur überlegen und in Klassen ablegen (Records geht auch, aber ich halte es mit Klassen für sinnvoller). Dann kannst du auch sehr einfach mehr als nur die selben Daten hintereinander speichern...

Kleines Beispiel, ungetestet...
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
uses
  ActiveX, ShlObj;


type
  TMyData = class
  strict private
    FMyDataExample: string;
  public
    constructor Create(const AMyDataExample: string = '');
    procedure LoadFromStream(AStream: TStream);
    procedure SaveToStream(AStream: TStream);
    property MyDataExample: string read FMyDataExample write FMyDataExample;
  end;

  TMyDataList = class(TObjectList<TMyData>)
  public
    constructor Create;
    procedure LoadFromStream(AStream: TStream);
    procedure SaveToStream(AStream: TStream);
    procedure LoadFromFile(const AFileName: string);
    procedure SaveToFile(const AFileName: string);
  end;

// ...

// aus: http://www.delphi-library.de/viewtopic.php?t=9428
// Gibt den Pfad des übergebenen Ordners zurück.
function GetSpecialFolder(AFolder: Integer): string;
var
  pIdL: PItemIDList;
  Path: array[0..Max_Path] of Char;
  Allocator: IMalloc;
begin
  // ItemIdList für den Ordner holen
  SHGetSpecialFolderLocation(0, aFolder, pIdL);
  // ItemIdList in String umwandeln lassen
  SHGetPathFromIDList(pIDL, Path);
  // Speicher wieder freigeben
  if Succeeded(SHGetMalloc (Allocator)) then
    Allocator.Free (pIdL);
  Result := Path;
end;

function LoadStringFromStream(AStream: TStream): String;
var
  ResultString: AnsiString;
  StringSize: Integer;
begin
  Result := '';
  if AStream.Size - AStream.Position < SizeOf(StringSize) then
    Exit;
  AStream.ReadBuffer(StringSize, SizeOf(StringSize));
  SetLength(ResultString, StringSize);
  if AStream.Size - AStream.Position < StringSize then
    Exit;
  AStream.ReadBuffer(Pointer(ResultString)^, StringSize);
  {$ifdef UNICODE} // ab Delphi 2009
  Result := Utf8ToString(ResultString);
  {$else}
  Result := Utf8Decode(ResultString);
  {$endif}
end;

procedure SaveStringToStream(AStream: TStream; AString: String);
var
  StringSize: Integer;
  StringToSave: AnsiString;
begin
  StringToSave := Utf8Encode(AString);
  StringSize := Length(StringToSave);
  AStream.WriteBuffer(StringSize, SizeOf(StringSize));
  AStream.WriteBuffer(Pointer(StringToSave)^, StringSize);
end;

constructor TMyData.Create(const AMyDataExample: string);
begin
  FMyDataExample := AMyDataExample;
end;

procedure TMyData.LoadFromStream(AStream: TStream);
begin
  FMyDataExample := LoadStringFromStream(AStream);
end;

procedure TMyData.SaveToStream(AStream: TStream);
begin
  SaveStringToStream(AStream, FMyDataExample);
end;

constructor TMyDataList.Create;
begin
  inherited Create(True);
end;

procedure TMyDataList.LoadFromFile(const AFileName: string);
var
  FileContents: TFileStream;
begin
  FileContents := TFileStream.Create(AFileName, fmOpenRead);
  try
    LoadFromStream(FileContents);
  finally
    FileContents.Free;
  end;
end;

procedure TMyDataList.LoadFromStream(AStream: TStream);
var
  i, DataCount: LongInt;
  NewData: TMyData;
begin
  AStream.ReadBuffer(DataCount, SizeOf(DataCount));
  for i := 1 to DataCount do
  begin
    NewData := TMyData.Create;
    NewData.LoadFromStream(AStream);
    Add(NewData);
  end;
end;

procedure TMyDataList.SaveToFile(const AFileName: string);
var
  FileContents: TFileStream;
begin
  FileContents := TFileStream.Create(AFileName, fmCreate);
  try
    SaveToStream(FileContents);
  finally
    FileContents.Free;
  end;
end;

procedure TMyDataList.SaveToStream(AStream: TStream);
var
  i, DataCount: LongInt;
  CurrentData: TMyData;
begin
  DataCount := Count;
  AStream.WriteBuffer(DataCount, SizeOf(DataCount));
  for CurrentData in Self do
    CurrentData.SaveToStream(AStream);
end;

// Beispiel:
var
  MyDataList: TMyDataList;
  CurrentData: TMyData;
  DataFileName: string;
begin
  MyDataList := TMyDataList.Create;
  try
    // bestehende Daten laden
    DataFileName := IncludeTrailingPathDelimiter(GetSpecialFolder(CSIDL_LOCAL_APPDATA)) + 'Test.txt';
    if FileExists(DataFileName) then
      MyDataList.LoadFromFile(DataFileName);

    // alle ausgeben
    for CurrentData in MyDataList do
      ShowMessage(CurrentData.MyDataExample);

    // neue Einträge erzeugen
    MyDataList.Add(TMyData.Create('Ein kleiner Test'));
    MyDataList.Add(TMyData.Create('Noch ein Test'));
    MyDataList.Add(TMyData.Create('Das ist ein Satz!'));

    // alle ausgeben
    for CurrentData in MyDataList do
      ShowMessage(CurrentData.MyDataExample);

    // alle speichern
    MyDataList.SaveToFile(DataFileName);
  finally
    MyDataList.Free;
  end;
end;
bummi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: Di 23.08.11 22:48 
user profile iconbf109g.01 hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconbummi hat folgendes geschrieben Zum zitierten Posting springen:
Du benötigst den Typ String

Dann hab ich aber nur 255 Zeichen frei. Soweit ich weiß lässt sich ein String ohne Einschränkung (=255) gar nicht speichern/laden, weils wohl nur ein Zeiger ist, oder irgendsowas....
Wie kann ich den Text länger machen? So 500 Zeichen wären fein... Muss ich da mit ner Stringlist arbeiten?


Wieso, wie alt ist Deine Delphiversion?
Ich meine alle nicht uralten Versionen haben bei String keine nennenswerte Grenze > 2GB

_________________
Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 23.08.11 23:10 
ShortStrings für die Billigvariante des Speicherns von Records als Datenpakete haben die Beschränkung auch in Delphi XE und werden sie immer haben. ;-)