unit uJVStringGridMod; interface uses Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids, JvExGrids, System.Classes, System.SysUtils, JvStringGrid; type // Запиливаем настройку кодировки TJvStringGridMod = class(TJvStringGrid) public procedure LoadFromCSV(const FileName: string{$IFDEF UNICODE}; Encoding: TEncoding{$ENDIF}; Separator: Char = ';'; QuoteChar: Char = '"'; StripQuotes: Boolean = True); procedure SaveToCSV(const FileName: string{$IFDEF UNICODE}; Encoding: TEncoding{$ENDIF}; Separator: Char = ';'; QuoteChar: Char = '"'); end; implementation procedure TJvStringGridMod.LoadFromCSV(const FileName: string{$IFDEF UNICODE}; Encoding: TEncoding{$ENDIF}; Separator: Char = ';'; QuoteChar: Char = '"'; StripQuotes: Boolean = True); var I: Longint; Lines, Fields: TStringList; procedure SplitLine(const Line: string; Result: TStrings; Delimiter, QuoteChar: Char; StripQuotes: Boolean); var I, SLen, QuoteCount: Integer; S: string; IgnoreDelim: Boolean; QuotedStr: PChar; begin S := ''; SLen := Length(Line); IgnoreDelim := False; QuoteCount := 0; Result.Clear; for I := 1 to SLen do begin if Line[I] = QuoteChar then begin Inc(QuoteCount); { * A Delimiter surrounded by a pair of QuoteChar has to be ignored. See example above: "FirstName, LastName" therefor: * } IgnoreDelim := QuoteCount mod 2 <> 0; end; if IgnoreDelim then S := S + Line[I] else if Line[I] <> Delimiter then S := S + Line[I] else begin if S <> '' then begin if StripQuotes and (S[1] = QuoteChar) then begin QuotedStr := PChar(S); Result.Add(AnsiExtractQuotedStr(QuotedStr, QuoteChar)); end else Result.Add(S); end else Result.Add(S); S := ''; end; end; if S <> '' then begin if StripQuotes and (S[1] = QuoteChar) then begin QuotedStr := PChar(S); Result.Add(AnsiExtractQuotedStr(QuotedStr, QuoteChar)); end else Result.Add(S); end else Result.Add(S); end; begin Lines := TStringList.Create; Fields := TStringList.Create; try Lines.LoadFromFile(FileName{$IFDEF UNICODE}, Encoding{$ENDIF}); DoLoadProgress(0, Lines.Count); RowCount := Lines.Count; ColCount := FixedCols + 1; for I := 0 to Lines.Count - 1 do begin { * added John * } SplitLine(Lines[I], Fields, Separator, QuoteChar, StripQuotes); DoLoadProgress(I, Lines.Count); if Fields.Count > ColCount then ColCount := Fields.Count; Rows[I].Assign(Fields); end; DoLoadProgress(Lines.Count, Lines.Count); finally Fields.Free; Lines.Free; end; end; procedure TJvStringGridMod.SaveToCSV(const FileName: string{$IFDEF UNICODE}; Encoding: TEncoding{$ENDIF}; Separator: Char = ';'; QuoteChar: Char = '"'); var I, J: Longint; BufStr, Value: string; Lines: TStringList; begin Lines := TStringList.Create; DoSaveProgress(0, RowCount); try Lines.Clear; for I := 0 to RowCount - 1 do begin BufStr := ''; DoSaveProgress(I, RowCount); for J := 0 to ColCount - 1 do begin Value := Cells[J, I]; if Pos(Separator, Value) > 0 then Value := AnsiQuotedStr(Value, QuoteChar); BufStr := BufStr + Value; if J <> (ColCount - 1) then BufStr := BufStr + Separator; end; Lines.Add(BufStr); end; DoSaveProgress(RowCount, RowCount); Lines.SaveToFile(FileName{$IFDEF UNICODE}, Encoding{$ENDIF}); finally Lines.Free; end; end; end.