お知らせ

電子会議

ライブラリ

パレット

Delphi FAQ検索

Delphi FAQ一覧

サンプル蔵





FDelphi FAQ
16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル

"汎用セパレータを扱うStringList"

この発言に対し以下のコメントが寄せられています
#01110 雪見酒 さん RE:汎用セパレータを扱うStringList

こんにちは、雪見酒です。 nifty:FDELPHI/MES/6/31418 で話題になった、TStringListの拡張です。 本田勝彦さんに教わった通り、Findを使うValuesプロパティを作ろうかと 思いましたが、ChildListに作業をさせることにしました。 で、Values,GetValue,SetValueを新たに作らずにChildList,SpalatedText プロパティを追加しました。 DUDEさんのStrTok関数を使っているので、セパレータ、デリミタの自由度が 正規表現ほどではないですが、非常に大きいです。(^^) 使用例は、この下のツリーに。 unit YzStrList; {Key Delim Value Sep Value... 形式の文字データを扱うクラス } interface uses Windows,classes,Dialogs,SysUtils; type TStrTokSeparator = set of Char; TStrTokRec = record Str:string; Pos:Integer; end; TYzStrList = class(TStringList) private FDelimiter,FSeparator:TStrTokSeparator; FOutSeparator:Char; FKey:string; FChildList:TStringList; FChildSorted:boolean; FChildDups:TDuplicates; function StrTokNext(const sep:TStrTokSeparator; var Rec:TStrTokRec;var S:string):string; procedure SetList(const Name:string;List:TStringList); function GetList(const Name:String):TStringList; procedure SetSpTxt(Index:integer;Value:string); function GetSpTxt(Index:integer):string; public destructor Destroy; override; function Add(const S: string): Integer;override; property Key:string read FKey write FKey; property Delimiter:TStrTokSeparator read FDelimiter write FDelimiter; property Separator:TStrTokSeparator read FSeparator write FSeparator; property OutSparator:Char read FOutSeparator write FOutSeparator; property ChildList[const Name:string]:TStringList read GetList write SetList; property SeparatedText[Index:integer]:string read GetSpTxt write SetSpTxt; property ChildSorted:boolean read FChildSorted write FChildSorted; property ChildDuplicates:TDuplicates read FChildDups write FChildDups; end; implementation function TYzStrList.StrTokNext(const sep:TStrTokSeparator; var Rec:TStrTokRec;var S:string):string; //これはDUDEさんのtoken切り出し関数 nifty:FDELPHI/MES/16/630 var Len, I: Integer; begin with Rec do begin Len := Length(Str); S:='';Result := ''; if Len >= Pos then begin while (Pos <= Len) and (Str[Pos] in sep) do begin Inc(Pos); end; I := Pos; while (Pos<= Len) and not (Str[Pos] in sep) do begin if IsDBCSLeadByte(Byte(Str[Pos])) then begin Inc(Pos); end; Inc(Pos); end; S := Copy(Str, I, Pos - I); Result:= S; while (Pos <= Len) and (Str[Pos] in sep) do begin Inc(Pos); end; end; end; end; procedure TYzStrList.SetList(const Name:string;List:TStringList); var Index:integer; begin if Find(Name,Index) then begin TStringList(Objects[index]).Clear; TStringList(Objects[index]).Assign(List); end; end; function TYzStrList.GetList(const Name:string):TStringList; var Index:integer; begin result:=nil; if Find(Name,Index) then begin Result:=TStringList(Objects[index]); end; end; procedure TYzStrList.SetSpTxt(Index:integer;Value:string); var Rec:TStrTokRec; SS:string; begin if Index < Count then begin Rec.Pos:=1; Rec.Str:=Value; TStringList(Objects[Index]).Clear; TStringList(Objects[Index]).Sorted:=FChildSorted; TStringList(Objects[Index]).Duplicates:=FChildDups; while StrTokNext(FSeparator,Rec,SS) <>'' do TStringList(Objects[Index]).Add(SS); end; end; function TYzStrList.GetSpTxt(Index:integer):string; var n:integer; begin result := ''; if TStringList(Objects[index])<>nil then begin for n:= 0 to TStringList(Objects[index]).Count-1 do begin if n = 0 then result:= TStringList(Objects[index])[n] else result:=result+FOutSeparator+TStringList(Objects[index])[n]; end; end; end; destructor TYzStrList.Destroy; var i:integer; begin for i:= 0 to Count-1 do begin TStringList(Objects[i]).Free; end; inherited Destroy; end; function TYzStrList. Add(const S: string): Integer ; // Duplicates の値で挙動を変える var index:integer; S1,SS:string; Rec:TStrTokRec; begin Rec.Str := S; Rec.Pos :=1; StrTokNext(FDelimiter,Rec,S1); if (Duplicates=dupIgnore) and Sorted then begin if not(Find(S1,index)) then begin FChildList:=TStringList.Create; while StrTokNext(FSeparator,Rec,SS) <>'' do begin FchildList.Sorted:=FChildSorted; FchildList.Duplicates:=FChildDups; FChildList.Add(SS); end; result := inherited Add(S1); Objects[result] := FChildList; end else begin while StrTokNext(FSeparator,Rec,SS) <>'' do begin TStringList(Objects[index]).Add(SS); end; result:=index end; end else begin result := inherited Add(S1); FChildList:=TStringList.Create; StrTokNext(FDelimiter,Rec,SS); FChildList.Add(SS); Objects[result] := FChildList; end end; end. Yukimi Sake GHE01746@nifty.ne.jp Original document by 雪見酒 氏 ID:(GHE01746)



ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。

Copyright 1996-2002 Delphi Users' Forum