我记得delphi的一本书中讲过格式化文本,就是类似把结构存入到文本中,不知道可不可以把这样的文本导入到一个结构数组中,然后排序,计算。
还有一种思路就是windows有一种给文本内容排序的功能,你可以利用一下,直接在文本中计算。不要问我具体怎么做,我也不懂,只是替你出出主意。

解决方案 »

  1.   

    可以看看DELPHI中的文件型数据库的DEMO,然后修改其中的读取方法,就可以用数据集的方式进行统计了。
      

  2.   

    看看下面的例子對你有沒有幫助?
    取出
    var
      s:tstrings;
    begin
      s:=tstringlist.Create;
      s.LoadFromFile('c:\1.txt');
      ExtractStrings([' '],[],pchar(s.Text),s);
      edit1.text:=s[1];
      edit2.text:=s[2];
      edit3.text:=s[3];
    end;
    保存
    var
      s:tstrings;
    begin
      s:=tstringlist.Create;
      s.add(edit1.text+' '+edit2.text+' '+edit3.text);
      s.savetofile('c:\1.txt');
    end;
      

  3.   

    在保存文件的时候,用记录类型的字符串保存。
    例如:
    type
      filekind=record
        tel:string[12];
        date:string[20];
        time:string[10];
      end;recordfile:file of filekind;
    在读文件的时候,在把读出来的每个记录要判断的值统计一下,在程序中表示出来。  只是个人的意见。  
      

  4.   

    把她读到memo里 在进行计算,统计,统计完再写入.txt中
    //=====================================================
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, DB, DBTables, Grids, DBGrids, Buttons, ComCtrls,
      ExtCtrls, ADODB, DBClient, MConnect, DBCtrls,comobj;
    Const
      Space=',';
    type
      TForm1 = class(TForm)
        StatusBar1: TStatusBar;
        PageControl1: TPageControl;
        TabSheet1: TTabSheet;
        TabSheet2: TTabSheet;
        Edit1: TEdit;
        BitBtn2: TBitBtn;
        BitBtn1: TBitBtn;
        BitBtn3: TBitBtn;
        Table1: TTable;
        DataSource1: TDataSource;
        Timer1: TTimer;
        Label1: TLabel;
        GroupBox1: TGroupBox;
        m: TMemo;
        GroupBox2: TGroupBox;
        DBGrid1: TDBGrid;
        GroupBox3: TGroupBox;
        DBGrid2: TDBGrid;
        Edit2: TEdit;
        Label2: TLabel;
        BitBtn5: TBitBtn;
        BitBtn4: TBitBtn;
        GroupBox4: TGroupBox;
        GroupBox5: TGroupBox;
        ProgressBar1: TProgressBar;
        Label3: TLabel;
        procedure FormCreate(Sender: TObject);
        procedure Timer1Timer(Sender: TObject);
        procedure BitBtn2Click(Sender: TObject);
        procedure BitBtn3Click(Sender: TObject);
        procedure BitBtn5Click(Sender: TObject);
        procedure BitBtn1Click(Sender: TObject);
      private
          // Function Regulate(aString,Sepchar:string):string;//去掉多余的分割符,规范字符串
        // Function GetSubStr(varsString:string;SepChar:String):String;//得到字符串中一个子串,因要改变参数aString的值,所以将它用var定义。
        // Function GetSubStrNum(aString,SepChar:String):Integer;//计算一个字符串要被分割成几个字段。
          procedure printme;
          { Private declarations }
      public
        function GetExePath: String;    { Public declarations }
      end;var
      Form1: TForm1;implementationuses Unit2;{$R *.dfm}function TForm1.GetExePath:String;
    begin
      Result:=ExtractFilePath(ParamStr(0));
      if Result[Length(Result)]<>'\' then
        Result:=Result+'\';
    end;
    Function RegulateStr(aString:String;Sepchar:String):String;
    var
    i,Num:Integer;
    Flag:Boolean;
    MyStr,TempStr:String;
    begin
      Flag:=False;//进行标志,去除多余的分割符
      Num:=Length(aString);//计算aString串的长度
      for i:=1 to Num do
          begin
            TempStr:=Copy(aString,i,1);//取aString串中的一字符
            if TempStr <> SepChar then
               begin
                 MyStr:=MyStr+TempStr;
                 Flag:=True;
               end
           else
               if(Flag=True)then
                  begin
                    Mystr:=Mystr+TempStr;
                    Flag:=False;
                  end;
          end;
       if  MyStr[Length(MyStr)] <> SepChar then
           MyStr:=MyStr+SepChar;
           RegulateStr:=MyStr;
    end;
    Function GetSubStr(var aString:String;SepChar:String):String;
    var
    Mystr:String;
    StrLen:Integer;
    SepCharPos:Integer;
    begin
    StrLen:=Length(aString);
    SepCharPos:=Pos(SepChar,aString);//计算分割符在子串中的位置
    MyStr:=Copy(aString,1,SepCharPos-1); //将分割符前所有字符放到mystr串中
    Delete(aString,1,SepCharPos);//除去分割符和分割符前的子串
    GetSubStr:=MyStr;//返回一个字段
    end;
    Function GetSubStrNum(aString:String;SepChar:String):Integer;
    var
    i:Integer;
    StrLen:Integer;
     Num:Integer;
    begin
      StrLen:=Length(aString);
      Num:=0;
      for i:=1 to StrLen do
          if Copy(aString,i,1)=SepChar then
             Num:=Num+1;
             result:=Num;
    end;
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      dm.cdsadq.Close;
      dm.cdsadq.CommandText:='select * from conv';
      dm.cdsadq.Open;  dm.adtconv.Open;  Table1.DatabaseName:=Form1.GetExePath+'mdb';
      Table1.TableName:='a.DB';
     //Query1.DatabaseName:=myForm.GetExePath+'mdb';
      //AllRec;
      table1.Open;
      //+++++++++++++++++++++++++++++++++++++++++++++++++
      m.Lines.LoadFromFile('a.txt');
    end;procedure TForm1.Timer1Timer(Sender: TObject);
    begin
     //ProgressBar1.Position:=ProgressBar1.Position+1
     StatusBar1.Panels[1].Text:='系统当前时间:'+formatdatetime('yyyy-mm-dd  hh:nn:ss',now);
    end;procedure TForm1.BitBtn2Click(Sender: TObject);
    begin
      dm.cdsadq.Close;
      dm.cdsadq.CommandText:='delete  from conv';
      dm.cdsadq.Execute;
      //cdsadq.Open;
      dm.cdsadq.Close;
      dm.cdsadq.CommandText:='select * from conv';
      dm.cdsadq.Open;
      
      dm.adtconv.ApplyUpdates(0);
      dm.adtconv.Refresh;
      dm.adtconv.close;
      //
      ///////////////////////////////////////
      table1.Close;
      table1.EmptyTable;
      table1.Open;
      dm.adtconv.Open;
    end;procedure TForm1.BitBtn3Click(Sender: TObject);
    var
      a,b,c,d,e,i,j:Integer;
      MyLine:String;
     num:integer;
    begin
      if messagedlg('确实要转换数据吗?',mtConfirmation, [mbYes, mbNo],0)=mrYes then
     begin
     BitBtn3.Enabled:=false;
     num:=8;
     a:=0;
     b:=0;
     c:=0;
     try
      with dm.adtconv do
           begin //table1end
             StatusBar1.Panels[0].Text:='数据正在转化......';
             Open;
             edit;
              ProgressBar1.Max:=m.Lines.Count-1;     ///
             //showmessage('0');
             for i:=0 to m.Lines.Count-1 do
                 begin //00
                   Application.ProcessMessages;
                   edit1.Text:=inttostr(i);
                   ProgressBar1.Position:=ProgressBar1.Position+1 ;
                   MyLine:=RegulateStr(m.Lines[i],Space);
                   append;
                   //insert;
                   for j:=1 to Num  do
                       begin
                          open;
                          edit;
                          fields[j-1].asString:=GetSubStr(MyLine,Space);
                      end;
                   post;
                   dm.adtconv.ApplyUpdates(0);
                  end; //00
              open;
           end; //table1end
           edit1.Text:=inttostr(m.Lines.Count-1);  
           StatusBar1.Panels[0].Text:='数据转化完毕';
           ProgressBar1.Position:=0;
           BitBtn3.Enabled:=true;
           dm.cdsadq.Close;
           dm.cdsadq.CommandText:='select * from conv';
           dm.cdsadq.Open;
           showmessage('数据库转化完毕!');
      except
        showmessage('error');
      end;
     end;
    end;
      

  5.   

    自己动手写,把文本文件变成rtf文件,也就是在两列中间加逗号变成这种形式
    V01,95006000,5382107,20000903 00:01:24,69             
    V01,95006114,3319364,20000903 00:03:15,106             
    V01,95006000,5382107,20000903 00:02:41,250             
    V00,95006114,5382107,20000903 00:07:00,58             
    然后到EXCEL中去处理
    EXCEL好象很灵活,可以随便你怎么统计了
      

  6.   

    用Excel打开文本,再处理计算
      

  7.   

    用TStringList导入,然后用Pos函数看出现了几次, 速度很快!
      

  8.   

    你還是可以把這個文本導入access數據庫,再sql就可以了
      

  9.   

    我现在就是不要用数据库,用数据库对以后不太好,非要机子上有SQL才能用程序,扩张性差!
      

  10.   

    如果你想更簡單一些的話,我倒是有辦法.這又不是經常要作的事情.用EXCL來作好了.具体做法是:用EXCL來剖析文本檔案成EXCL檔,然后再按電話號碼小計,不但能知道每個號碼通話次數,還能計算金額.不知道對你有沒有用.不過這种方法一定是可以的.如果你覺得這樣太沒有檔次的話,也可以用程式將文本內容轉入數据庫然后再處理.這樣要看你的分隔符,寫個function給你參考一下.
      FUNC READLINE  && 讀取文字檔一行文字                             
    PARA FP, BEGADDR, MAXBYTE  && 傳入檔案指標, 開始位置, 一行最大字元數 
    PRIV LN,CRAT
    LN='' 
    =FSEEK(FP,BEGADDR,0)  && 移動 位置指標  到行首           
    IF !FEOF(FP)   
        LN=FREAD(FP,MAXBYTE)    && 由檔案讀入變數                  
        CRAT=AT(CHR(13),LN)      && 定換行符號位置                  
        IF   CRAT>0                                                         
          LN=SUBS(LN,1,CRAT-1)   && 截取一行文字到換行符號為止      
          =FSEEK(FP,BEGADDR+CRAT+1,0)  && 移動 位置指標 到下一          
       ENDIF                         
    ENDI                                      
    RETU LN                &&傳回一行文字 
      這是foxpro語法,不過用到的函數可都是通用的哦,
    你可以參照這种寫法都每一個字段到你想要的數据庫里.