Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Компоненты Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 29.01.2015, 15:51   #1
bro
Пользователь
 
Аватар для bro
 
Регистрация: 02.12.2010
Сообщений: 29
По умолчанию Дописал TJvStringGrid (JVCL) так, чтобы можно было выбирать Encoding в LoadFromCSV и SaveToCSV

Всем привет. По своей необходимости написал юнит, который расширяет возможности TJvStringGrid так, чтобы можно было выбирать Encoding в LoadFromCSV и SaveToCSV. Может, кому полезно будет.

Код:
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.
По аналогии можно сделать так и с другими компонентами, которые имеют функцию LoadFromCSV/SaveToCSV.
bro вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Загрузить приложение на сайт так, чтобы можно было открыть на ipad Violet_Shell PHP 5 17.07.2012 13:56
Как расположить дочернее окно поверх родительского, но так, чтобы можно было работать с родительским окном? ivan.tiran Общие вопросы Delphi 2 17.05.2012 23:46
Ввод - сделать так, чтобы в Edit можно было вводить только цифры, или на оборот, только буквы BastAngel Общие вопросы Delphi 7 27.04.2012 01:15
Как сделать так, чтобы форму можно было тостать не только за заголовок? Никки Общие вопросы Delphi 1 04.09.2008 14:34
Подскажите, как сделать так, чтобы тест можно было повторно пройти не перезагружая пр Kamikadze_666 Помощь студентам 2 23.05.2007 02:48