空白のあるcsvファイルをStringGridに取り込むには?

解決


マッキー  2005-06-20 05:53:51  No: 15794

お世話になっています。初めての投稿です、宜しくお願い致します。
空白項目のある、CSVファイルを取り込もうとしていますが
うまくいきません。
空白がある部分を強制的にダブルクォーテーションで
囲もうとしていますが、やはり思い通りに取り込めません。
どなたかご教授して頂きますと助かります。

例)
 品目 , 品目名称、オーダ
1TT1111,TEST 11  1111,D5ABCD111
2TT3333,TEST 33  4444,D5ABCD333

"1TT1111","TEST 11  1111","D5ABCD111"
に強制変換後、CommaTextを使って
StringGridに取り込めれば良いのですが
下記のソースだと
"1TT1111","TEST" "11" " 1111","D5ABCD111"
になります。
 var
   i,j:integer;
   f:TextFile;
   x:string;
   theList:TStringList;
  InputFile: TextFile;
  TmpStringList: TStringList;
  TxtLineData: String;
begin
   if OpenDialog1.Execute then
  begin
    I := 0;
    StringGrid1.RowCount := 1;
    StringGrid1.ColCount := 1;
    TmpStringList := TStringList.Create;
    AssignFile(InputFile, OpenDialog1.FileName);
    Reset(InputFile);
    try
      while not SeekEof(InputFile) do
      begin
        ReadLn(InputFile, TxtLineData);
//   空白があるデータをダブルクオーテーションで囲む
        for j := 0 to TmpStringList.Count -1 do
         begin
               //','を'","'に置換(a","b","","c)
              TmpStringList[j]:= StringReplace(TmpStringList[j],',' , '","' ,[rfReplaceAll]);
               //最初と最後に'"'を付ける("a","b"," ","c")
            TmpStringList[j] := '"'+TmpStringList[j]+'"';
              //'""'を'" "'に置換(a","b"," ","c)
              TmpStringList[j]:= StringReplace(TmpStringList[j], '""','" "', [rfReplaceAll]);
          end  ;

        TmpStringList.CommaText := TxtLineData;
        if TmpStringList.Count > StringGrid1.ColCount then
        begin
          StringGrid1.ColCount := TmpStringList.Count;
        end;
        TmpStringList.Insert(0,' ');
        StringGrid1.RowCount := I + 1;
        StringGrid1.Rows[I].Clear;  
        StringGrid1.Rows[I].Assign(TmpStringList);
        Inc(I);
      end;
      StringGrid1.FixedCols := 1;
      StringGrid1.FixedRows := 1;
    finally
      TmpStringList.Free;
      CloseFile(InputFile);
    end;
  end;


メラトニン  2005-06-20 09:28:19  No: 15795

下記リンクソースを使ってみてください。

https://www.petitmonte.com/bbs/answers?question_id=2891
>メラトニン 2005/06/14(火) 21:13:27
>なんか需要ありそうなので書いてみました。

やっぱ需要あったな。 (w


ミスコード  2005-06-20 18:03:52  No: 15796

>囲もうとしていますが、やはり思い通りに取り込めません。
思い通りに取り込めないのは、単なるコード記述のミス。
これ↓ならいける。

procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
  InputFile: TextFile;
  TmpStringList: TStringList;
  TxtLineData: String;
begin
  ForceCurrentDirectory := True;
  if OpenDialog1.Execute then begin
    I := 0;
    StringGrid1.FixedCols := 1;
    StringGrid1.FixedRows := 1;
    AssignFile(InputFile, OpenDialog1.FileName);
    Reset(InputFile);
    TmpStringList := TStringList.Create;
    try
      while not SeekEof(InputFile) do begin
        ReadLn(InputFile, TxtLineData);
        // 空白があるデータをダブルクオーテーションで囲む
        TxtLineData := StringReplace(TxtLineData,',' , '","' ,[rfReplaceAll]);
        // 最初と最後に'"'を付ける("a","b"," ","c")
        TxtLineData := '"'+ TxtLineData +'"';
        // '""'を'" "'に置換(a","b"," ","c)
        TxtLineData := StringReplace(TxtLineData, '""','" "', [rfReplaceAll]);
        TmpStringList.CommaText := TxtLineData;
        TmpStringList.Insert(0,' ');
        StringGrid1.ColCount := TmpStringList.Count;
        StringGrid1.RowCount := I + 1;
        StringGrid1.Rows[I].Assign(TmpStringList);
        Inc(I);
      end;
    finally
      TmpStringList.Free;
      CloseFile(InputFile);
    end;
  end;
end;


deldel  2005-06-20 18:18:39  No: 15797

StringReplace で空白を、使用しない文字(@など)に
変換した後グリッドに表示し、その後 @ を空白に
変換しなおすのはどう?


平蔵  2005-06-20 18:44:57  No: 15798

StlingListとExtractHTTPFieldsを使って、簡単にCSVを読み込む方法があります。

usesにHttpAppを追加して、

var
   Lista : TStringList;
   Listb : TStringList;
   s,w: TSysCharSet;
   i  : Integer;
begin
   if OpenDialog1.Execute = false then exit;
   Lista := TStringList.Create;  
   Lista.LoadFromFile(OpenDialog1.FileName); //一旦Listaに読み込む
   
   Listb := TStringList.Create;
   s := [','];
   w := ['"'];
   
   for i := 0 to Lista.Count-1 do begin
      ExtractHTTPFields(s,w,PChar(Lista[i]),Listb);//Listbに格納
   end;
   Lista.Free;

   :
   ://Listbを使用してコード化
   :
   Listb.free;


HttpAppが欲しいけど  2005-06-20 19:12:04  No: 15799

>usesにHttpAppを追加して、

D6 Personalには、HttpApp.pasがないです。
どのバージョンならあるんですか?


くりりんノコトカー!  2005-06-20 19:57:59  No: 15800

横ヤリ失敬

別の方法
半角スペースを、区切りとしないで読み込む関数
中身は、ほとんどTStrings.CommaTextと同じ;-)
TStrings.CommaTextのかわりに使う。

例)
StringList.CommaText := HogeHoge;
  ↓
SetCommaTextToStrings(StringList, HogeHoge);

procedure SetCommaTextToStrings(aStrings: TStrings;
                        const aValue: String);        {','区切り文字列}
var
  p, p1: PChar;
  s: string;
begin
  aStrings.BeginUpdate;
  try
    aStrings.Clear;
    p := PChar(aValue);
    while p^ in [#1..#$1F] do p := CharNext(p);
    while p^ <> #0 do begin
      if p^ = '"' then
        s := AnsiExtractQuotedStr(p, '"')
      else begin
        p1 := p;
        while (p^ > #$1F) and (p^ <> ',') do p := CharNext(p);
        SetString(s, p1, p - p1);
      end;
      aStrings.Add(s);
      while p^ in [#1..#$1F] do p := CharNext(p);
      if p^ = ',' then begin
        repeat
          p := CharNext(p);
        until not (p^ in [#1..#$1F]);
      end;
    end;
  finally
    aStrings.EndUpdate;
  end;
end;


平蔵  2005-06-20 21:22:57  No: 15801

HttpAppはprofessional版以上でしか使えないようです。
Personal版の場合はだめですね。


マッキー  2005-06-21 01:39:16  No: 15802

メラトニンさん、ミスコードさん、deldelさん 
平蔵 さん、HttpAppが欲しいけどさん
くりりんノコトカー!さん  たくさんのご回答ありがとうございました。
ミスコードさんのご指摘の通りに行ったところ、問題なくできた!!
と思ったのもつかの間、CSVファイルに、元々ダブルクォーテーションが
入っているデータがありました。
例)"1,999,999"   
例)"dddeEA V/I 1111 (256V/250m,100V/2A 2CH)"  などなどです。
私の確認ミスです、申し訳ございません。
この部分をクリアーできないと正常に取り込めないようです。
申し訳ございませんが、再度ご教授頂く様お願い致します。


マッキー  2005-06-21 01:53:41  No: 15803

くりりんノコトカー! さんの関数を使わせてもらったところ
>例)"1,999,999"   
>例)"dddeEA V/I 1111 (256V/250m,100V/2A 2CH)"  
のケースも正常に取り込めました。
本当に助かりました。
また、半日の間にこんないっぱい回答がつきまして、感謝感激です。
FDELPHI亡き後、途方に暮れていた私には地獄に仏です。
また何か有りましたら、よろしくお願い致します。


※返信する前に利用規約をご確認ください。








  このエントリーをはてなブックマークに追加