テキストファイルに下記のように保存しています。
kaj,09/07/06 17:15:30,yuo
tyu,09/07/07 12:01:01,lmn
ABC,09/07/08 20:21:00,XYZ
def,09/07/08 20:22:00,asd
この中で、今日の日付をカウントするにはどのように記述すればよいのでしょうか?
上の例ならカウント結果は「2」です。
どなたか教えてください。
よろしくお願いします。
1. テキストファイルを読む
2. 日付の部分を取り出す
3. 今日の日付と比べる
4. カウントを増やす
5. 以上を繰り返す
どこまでできていてどこがわからないんですか?
全部なんて勘弁さん、説明不足ですみません。
ご回答頂いた内容でいうと、2以降がわかりません。
初心者なもので、すみません。
どうぞよろしくお願いします。
ほとんど全部じゃん
順番に片付けていこうよ。ヘルプで文字列ルーチンって調べたら
PosとかCopyとか色々道具がそろってるから、それを組み合わせて
最初の「,」から次の「,」までの間を切り出す処理を書いてごらん。
その後の課題
・今日の日付を取り出す方法
・文字列を日付にする方法(あるいはその逆)
・日付を比較する方法、または文字列を比較する方法
ヒント:日付時刻ルーチン
よし、本を買おう。
検索は、手抜きをすれば、Pos ( 検索したい文字列, 検索対象文字列 )でも行けるんじゃないかな?
文の中に、指定の文字があれば、その位置を返すので0なら、位置がなし。
なので、
if Pos ( 検索したい文字列, 検索対象文字列 ) = 0 then
iCount := iCount+1; で
誤検索を避けたいのなら、区切り文字で切り取る必要があるけどー。
なんて関数だっけ?
個人的に。
考えてみると、別に勉強はしたくはないけど、そう言うソフトは必要・・・って場合もあるよな。(苦笑
このくらいなら、作ってもいいよ。
ソースは恥ずかしいので、未公開で。^^;
本気で勉強したいのなら、本を買うか、すこしはネットで調べないと。
調べて出てくる物ばかりだから。
手抜きバージョン(Posなら)30分もあれば出来そうだし。
ただし、出力の方法にもよるけど、DelphiのStringGridってあんまり使い勝手がよくないので、エクセルでマクロを組むか、オープンオフィスでif文条件でわかりやすくした方が、便利な気もする。
if とcountの両方の機能のある関数も合った気がするし。
ある程度検索文字列が長いのであれば、PosEx を使う事ができます。
uses
..., StrUtils;
function SubStrCount(aFileName: TFilename; aSubStr: String): Integer;
var
SL: TStringList;
Position: Integer;
begin
result := 0;
SL := TStringList.Create;
try
SL.LoadFromFile(aFileName);
Position := 1;
repeat
Position := PosEx(aSubStr, SL.Text, Position);
if Position > 0 then
begin
Inc(Position, Length(aSubStr));
Inc(result);
end;
until(Position = 0);
finally
SL.Free;
end;
end;
呼び出し方はこんな感じで。
procedure TForm1.Button1Click(Sender: TObject);
var
Cnt: Integer;
begin
Cnt := SubStrCount('C:\Test.txt', FormatDateTime('YY/MM/DD', Date));
ShowMessage(IntToStr(Cnt));
end;
これって
>kaj,09/07/06 17:15:30,yuo
>tyu,09/07/07 12:01:01,lmn
>ABC,09/07/08 20:21:00,XYZ
>def,09/07/08 20:22:00,asd
CSV形式!?ですよくゎ?。
もしそうなら・・・以下を引き続きどうぞ
もしそうでないなら・・・ここでさよなら
procedure TForm1.Button1Click(Sender: TObject);
var
SL1,SL2 :TStringList;
i :Integer;
begin
SL1 := TStringList.Create;
SL2 := TStringList.Create;
try
SL1.Clear;
SL1.LoadFromFile('c:\txt.txt');//テキストファイル読込み
if SL1.Count > 0 then
begin
for i := 0 to SL1.Count - 1 do
begin
SL2.CommaText := SL1.Strings[i] ;
//上記のTxtであれば
//SL2.Strings[1]に日付、SL2.Strings[2]に時刻が
//それぞれが格納される事でしょう。
//後は適当に比較などして今日の日付ならカウントします。
end;
end;
finally
SL1.Free;
SL2.Free;
end;
end;
余計なお世話ですが、CSVなら
"kaj","09/07/06 17:15:30","yuo"
"tyu","09/07/07 12:01:01","lmn"
の様に書き出してもらうのが良いでしょう。
これなら各文字列データ内に空白文字やcommaが
入っても分かれませんので、曖昧さがなくなります。
って、もう遅い。
> 余計なお世話ですが、CSVなら
> "kaj","09/07/06 17:15:30","yuo"
> "tyu","09/07/07 12:01:01","lmn"
> の様に書き出してもらうのが良いでしょう。
> これなら各文字列データ内に空白文字やcommaが
> 入っても分かれませんので、曖昧さがなくなります。
どっこい、世の中にはとんでもないCSVを吐いてくれるものが多いのです。
そして出力の設定を変えられないものも...。
空白を含むCSVを処理しなければならない場合には、
以下の投稿が参考になるでしょう。
https://www.petitmonte.com/bbs/answers?question_id=2926
> 空白を含むCSVを処理
お持ちの Delphi が 2006 以降であれば、StrictDelimiter プロパティを
True にする事で簡単に処理できます。
[TStrings.StrictDelimiter]
http://docs.embarcadero.com/products/rad_studio/radstudio2007/RS2007_helpupdates/HUpdate4/JA/html/delphivclwin32/Classes_TStrings_StrictDelimiter.html
この場合、CommaText ではなく、DelimitedText で処理する必要があります。
>kaj,09/07/06 17:15:30,yuo
>tyu,09/07/07 12:01:01,lmn
>ABC,09/07/08 20:21:00,XYZ
>def,09/07/08 20:22:00,asd
てことは改行されてて、他に日付らしいもん見つからんし
質問者は難しいことわかっとらんようなんで
目的を達成するだけやったら以下でええんちゃうか?
var
i: Integer;
StrList: TStringList;
Cnt: Integer;
begin
// ファイルを読み込んで文字列リストに入れる
StrList := TStringList.Create;
StrList.LoadFromFile('ファイル名');
// カウントの初期化
Cnt := 0;
// 1行ずつ処理するi行目の文字列はStrList.Strings[i-1]
for i := 1 to StrList.Count do begin
// Pos(D,S)はSの文字列にDの文字列があれば位置を返しよる
// なけりゃ0を返すんで0以上ならDの文字列があるということや
// 今日の日付はFormatDateTimeで求めるか
// やり方がわからなければEditボックスで手入力すればいい
if Pos('09/07/08', StrList.Strings[i-1]) > 0 then Cnt := Cnt + 1;
end;
ShowMessage('カウント=' + IntToStr(Cnt));
// CreateしたクラスはFreeで破棄する
StrList.Free;
end;
ちょっとずつ勉強して少しずつ機能ふやしていったらええんや。
ほな、がんばってや!
ツイート | ![]() |