回 帖 发 新 帖 刷新版面

主题:求教:如何整理这个档案

大家帮帮忙,看看这个问题怎么解决:

test.dbf
521    below    adv.part    aa1
521    below    prep    bb1
521    under    prep    cc1
521    under    prep    cc2

想要做成这种样子:
521    below    adv.part    aa1
521    below    prep    bb1
521    under    prep    cc1     cc2

也就是如果,第1,2,,3栏一样,就增加1栏,将重复记录的第4栏资料放入5栏中,前面3栏重复的记录最多有15条。


回复列表 (共9个回复)

沙发

这是我的程序,可是结果不对
Clear All
Select A
Use test Alias Epg
Go Top
Scan
    Wait Window Str(Recno('Epg'))+"/"+Str(Reccount('Epg')) Nowait
    Np=Recno()
    Scatter Fields Ant To myArray1
    Scatter Fields Pos To myArray2
    Skip
    If Ant==myArray1 And Pos==myArray2
        Scatter Fields Ant To myArray3
        Scatter Fields Pos To myArray4
        Scatter Fields Txt_v To myArray5
        Go Np
        If Empty(Ant1)
            Replace Ant1 With myArray3, ant1_pos With myArray4, ant1_expl With myArray5
        Else
            If Empty(Ant2)
                Replace Ant2 With myArray3, ant2_pos With myArray4, ant2_expl With myArray5
            Endif
Go Np
Endscan

板凳

研究出来一个SELECT-SQL语句一次性搞定(假设表文件名为T1,4个字段名是F1/2/3/4):

[color=FF0000]SELECT T1.F1,T1.F2,T1.F3,T1.F4,T1_a.F4 ;
   FROM T1 ;
   JOIN T1 T1_a ON T1.F1=T1_a.F1 AND T1.F2=T1_a.F2 AND T1.F3=T1_a.F3 AND ;
                    T1.F4<T1_a.F4 ;[/color]
UNION ;
[color=000080]SELECT T1.F1,T1.F2,T1.F3,T1.F4,"" ;
   FROM T1 ;
   WHERE T1.F1+T1.F2+T1.F3+T1.F4 !=ANY (SELECT T1.F1+T1.F2+T1.F3+T1.F4 ;
                                           FROM T1 ;
                                           JOIN T1 T1_a ON T1.F1=T1_a.F1 AND ;
                                                T1.F2=T1_a.F2 AND T1.F3=T1_a.F3 AND ;
                                                T1.F4<T1_a.F4) AND ;
         T1.F1+T1.F2+T1.F3+T1.F4 !=ANY (SELECT T1.F1+T1.F2+T1.F3+T1_a.F4 ;
                                           FROM T1 ;
                                           JOIN T1 T1_a ON T1.F1=T1_a.F1 AND ;
                                                T1.F2=T1_a.F2 AND T1.F3=T1_a.F3 AND ;
                                                T1.F4<T1_a.F4) ;[/color]
   INTO TABLE T2

    代码中的红色部分查询出前三个字段有重复需要处理的记录;蓝色部分查询出无重复的记录。两个查询结果用UNION关键字连接后,就形成你需要的完整结果。
    但这条语句仅测试了你帖子中给出的4条记录,你可以用这条语句试试完整的表文件,看看15对重复记录以及剩下的无重复记录是否正确被处理。如有疑问,或语句运行结果不正确,再跟帖告诉我,我研究研究。

你可以去下面的地址下载结果图片看看:
[url]http://d.1tpan.com/tp0309477694[/url]

3 楼


谢谢taifu945的回答,不过我运行的时候出现 "Operator/operand type mismatch" 的提示,无法正常运行。
我看了T1 的结果图,就是我要的结果。
我是 VFP 9.

我给你foxmail 的邮箱发送了邮件,请帮忙再看看,谢谢

4 楼

从给的出错信息来看,是字段类型与我假设的不同引发的(我假设4个字段都是字符型的)。你发给我的是Excel文件,无法判断字段的类型。你这样,把所有字段都改成字符型(C型),然后再把这条语句中的表文件名和字段名改成实际的名字,再试试。

PS:我测试的环境也是FoxPro 9.0 SP2。

5 楼

我无法上传附件,只能用邮件发送测试结果。
确实如你所说,我的有个字段类型不一样,改正后可以运行了,但结果有问题。
邮件中附档是我测试的结果。至于新增的域名无所谓,最后我统一修改就可以了
谢谢

6 楼

我仔细对比了一下原始数据和你要的结果数据,发现原始数据远比你开篇帖描述的要复杂,可能光一句SELECT-SQL语句解决不了。因为你不是两两重复,而是有N条记录前三个字段相同。我研究一把... ...

7 楼

有劳 taifu945 兄了,谢谢
我也再研究研究我的程序。

8 楼

CLOSE ALL
SET SAFETY OFF
SET TALK OFF
SET DELETED ON

IF !FILE("T1_B.DBF")
   USE T1
   COPY TO T1_B [color=C0C0C0]&&为了调试程序时原始数据的安全性,做个备份[/color]
ELSE
   COPY FILE T1_B.DBF TO T1.DBF
   USE T1
ENDIF
INDEX ON Ahead_id+Ant+Pos TAG AAP
GO TOP
PrepRecno=RECNO()
PrepAAP=Ahead_id+Ant+Pos
FieldsAdded=0  [color=C0C0C0]&&该变量用于计算增加的字段数[/color]
已填充=.F.  [color=C0C0C0]&&用来判断是否已经填充过重复记录的Txt_v字段值[/color]
DO WHILE !EOF()
   SKIP
   CurrentAAP=Ahead_id+Ant+Pos
   CurrentRecno=RECNO()  [color=C0C0C0]&&记录下当前记录号[/color]
   IF CurrentAAP=PrepAAP [color=C0C0C0]&&如果当前记录的此三个字段与上一条的相同[/color]
      CurrentTxt_v=Txt_v  [color=C0C0C0]&&记下当前的Txt_v字段值准备填充到新加字段中[/color]
      DELETE FOR RECNO()=CurrentRecno [color=C0C0C0]&&删除刚才那一条重复记录[/color]
      GO PrepRecno  [color=C0C0C0]&&转到原来的记录上准备填充新字段[/color]
      FOR I=1 TO FieldsAdded
         IF EMPTY(Txt_v&FieldsAdded2)
            REPLACE Txt_v&FieldsAdded2 WITH CurrentTxt_v  [color=C0C0C0]&&填充新字段[/color]
            已填充=.T.
            EXIT
         ELSE
            已填充=.F.
         ENDIF
      NEXT
      IF !已填充
         FieldsAdded=FieldsAdded+1
         FieldsAdded2=ALLTRIM(STR(FieldsAdded,2,0))
         ALTER TABLE T1 ADD Txt_v&FieldsAdded2 C(120) [color=C0C0C0]&&新加字段[/color]
         SET ORDER TO AAP
         GO PrepRecno
         REPLACE Txt_v&FieldsAdded2 WITH CurrentTxt_v
      ENDIF
   ELSE
      PrepRecno=RECNO()  [color=C0C0C0]&&若与上一条不重复,重置标志[/color]
      PrepAAP=Ahead_id+Ant+Pos
      已填充=.F.
   ENDIF
ENDDO
PACK  [color=C0C0C0]&&清除掉所有重复记录[/color]

CLOSE ALL
SET SAFETY ON
SET TALK ON
SET DELETED OFF

RETURN

程序有点复杂,你慢慢研究。不过,经过反复测试,可以达到你的要求。

9 楼

呵呵,谢谢你的无私帮助,我的程序也Ok 了,附上共同进步吧。
Use ant04a Alias Epg
Go Top
Scan
    Wait Window Str(Recno('Epg'))+"/"+Str(Reccount('Epg')) Nowait
    Np=Recno()
    Scatter Fields Ant To myArray1
    Scatter Fields Pos To myArray2
    Skip
    Do While Ant==myArray1 And Pos==myArray2 And !Eof()
        Scatter Fields Txt_v To myArray3
        Delete
        Go Np
        If Empty(ant1_expl)
            Replace ant1_expl With myArray3
            Go Np+2
            Loop
        Else
            If Empty(ant2_expl)
                Replace ant2_expl With myArray3
                Go Np+3
                Loop
            Else
.... (根据重复的多少增加类似结构)
            Endif
        Endif
    Enddo
    Skip -1
Endscan
Close All

我来回复

您尚未登录,请登录后再回复。点此登录或注册