注册 登录
编程论坛 VFP论坛

标注字段名问题

fdqzy 发布于 2021-09-20 14:21, 2882 次点击
吹水佬版主:
    在“动态字段排序”帖的“获取最大、次最大”代码中,解决了运行速度问题,谢谢!
但标注时字段名时遇到了小问题:
     代码条件中,是在遇上第1个字段符合标注条件后,就退出该轮字段的循环,进入下一个100行。
在下表中两个字段都符合条件,却标的是最后一个字段名:
只有本站会员才能查看附件,请 登录


程序代码:
USE bb IN 0
USE pmax IN 0
SELECT pmax
BLANK FIELDS mmax ALL

SELECT bb
COPY TO ARRAY a100 NEXT 100 && 第1个100行
pmax(@a100)
SELECT bb
SKIP
SCAN REST
    ** 下一个100行
    SCATTER TO a1  && 取bb一行存入a1
    ADEL(a100,1)   && 删除a100第1行
    ACOPY(a1, a100, 1, -1, AELEMENT(a100,100,1))  && 将a1写入a100最后一行
    pmax(@a100)
ENDSCAN

SELECT * FROM pmax
RETU


FUNCTION k2k3(k2,k3,n1)  && 最大值、最次大值
    IF n1 > k2
        k2 = n1
    ELSE
        IF n1 > k3
            k3 = n1
        ENDIF
    ENDIF
ENDFUN

FUNCTION pmax(a100)
    FOR nCol=2 TO ALEN(a100,2)
        n1 = 0
        k2 = 0
        k3 = 0
        krow = 0  &&非空行数
        FOR nRow=1 TO ALEN(a100,1)
            IF EMPTY(a100[nRow,nCol])
                n1 = n1 + 1
            ELSE
                k2k3(@k2,@k3,@n1)
                n1 = 0
                krow = krow + 1
            ENDIF
        ENDFOR
        k1 = n1  &&列最后行的值
        k2k3(@k2,@k3,@n1)
        IF k1==k2 AND k1>3 AND krow>20 AND k1<7     &&求第2大值,与最大值比较            
            IF k2-k3=1 &&在pmax对应行标注(条件有修改)
                SELECT pmax
                GO a100[100,1]
                REPLACE mmax WITH "MMAX"
                REPLACE maxm WITH FIELD(nCol,"bb") &&标注此列字段名
                EXIT
                              
            ENDIF
        ENDIF
    ENDFOR
ENDFUNC

请指教,谢谢!

[此贴子已经被作者于2021-9-20 14:31编辑过]

22 回复
#2
吹水佬2021-09-20 15:15
标注是第1个字段
只有本站会员才能查看附件,请 登录
#3
吹水佬2021-09-20 15:16
条件变了
IF k1==k2 AND k1>0 AND krow>20 AND k1<7     &&求第2大值,与最大值比较
IF k1==k2 AND k1>3 AND krow>20 AND k1<7     &&求第2大值,与最大值比较

IF INLIST(k2-k3,1,2) &&在pmax对应行标注
IF k2-k3=1 &&在pmax对应行标注(条件有修改)

只有本站会员才能查看附件,请 登录


[此贴子已经被作者于2021-9-20 15:25编辑过]

#4
fdqzy2021-09-20 16:20
回复 3楼 吹水佬
条件还原:
程序代码:
IF k1==k2 AND k1>0 AND krow>20 AND k1<7     &&求第2大值,与最大值比较
           
            IF INLIST(k2-k3,1,2) &&在pmax对应行标注
           
                SELECT pmax
                GO a100[100,1]
                REPLACE mmax WITH "MMAX"
                REPLACE maxm WITH FIELD(nCol,"bb")
                EXIT
                              
            ENDIF
        ENDIF

只有本站会员才能查看附件,请 登录


是我获取字段名的代码有问题?

[此贴子已经被作者于2021-9-20 16:25编辑过]

#5
吹水佬2021-09-20 18:15
原算法不合题意,要修改。
#6
fdqzy2021-09-20 18:40
回复 5楼 吹水佬
麻烦了!!!
#7
吹水佬2021-09-20 19:44
回复 6楼 fdqzy
原算法是逐行计算最大次大的值
n1 = n1 + 1
REPLACE (FIELD(lnj)) WITH TRANSFORM(n1)
修改结果:有4个符合条件的记录
只有本站会员才能查看附件,请 登录

只有本站会员才能查看附件,请 登录

程序代码:
use bb in 0
use pmax in 0
SELECT pmax
BLANK FIELDS mmax ALL
SELECT bb
COPY TO ARRAY a100 NEXT 100 && 第1个100行
pmax(@a100)
SELECT bb
SKIP
SCAN REST
    ** 下一个100行
    SCATTER TO a1  && 取bb一行存入a1
    ADEL(a100,1)   && 删除a100第1行
    ACOPY(a1, a100, 1, -1, AELEMENT(a100,100,1))  && 将a1写入a100最后一行
    pmax(@a100)
ENDSCAN
SELECT * FROM pmax
SELECT * FROM tt
RETURN

FUNCTION k2k3(k2,k3,n1)  && 最大值、最次大值
    IF n1 > k2
        k3 = k2
        k2 = n1
    ENDIF
ENDFUNC

FUNCTION pmax(a100)
    FOR nCol=2 TO ALEN(a100,2)
        n1 = 0
        k2 = 0
        k3 = 0
        krow = 0  &&非空行数
        FOR nRow=1 TO ALEN(a100,1)
            IF EMPTY(a100[nRow,nCol])
                n1 = n1 + 1
                k2k3(@k2,@k3,@n1)
            ELSE
                n1 = 0
                krow = krow + 1
            ENDIF
        ENDFOR
        k1 = n1  &&列最后行的值
        IF k1==k2 AND k1>0 AND krow>20 AND k1<7     &&求第2大值,与最大值比较
            IF INLIST(k2-k3,1,2) &&在pmax对应行标注
                SELECT pmax
                GO a100[100,1]
                REPLACE mmax WITH "MMAX", maxm WITH FIELD(nCol,"bb")
                EXIT
            ENDIF
        ENDIF
    ENDFOR
ENDFUNC
#8
fdqzy2021-09-20 22:06
谢谢!
请教,tt表在哪反映?
#9
吹水佬2021-09-20 22:27
以下是引用fdqzy在2021-9-20 22:06:29的发言:

谢谢!
请教,tt表在哪反映?

tt表测试用的:
CREATE TABLE tt (_jnh1 I,_jnh100 I,_maxm C(6),_k1 I,_k2 I,_k3 I,_krow I)
在标注时:
REPLACE mmax WITH "MMAX", maxm WITH FIELD(nCol,"bb")
INSERT INTO tt VALUES (a100[1,1], a100[100,1], FIELD(nCol,"bb"), k1, k2, k3, krow)  
EXIT
#10
fdqzy2021-09-21 02:21
回复 9楼 吹水佬
谢谢!
#11
吹水佬2021-09-21 08:53
要求 k1==k2 这个条件,应该不用算那么多
k1是最后的n1,就从最后的第100行起往前算n1就可以,算到非空时就可以结束。
#12
fdqzy2021-09-21 10:35
从测试和统计结果看:
在IF k1==k2 AND k1>0 AND krow>20 AND k1<7条件下,都是k3<k2,没有k3=k2的情况,
但我把  IF INLIST(k2-k3,1,2)
 改成:IF k2=k3
统计结果一样,这样 IF INLIST(k2-k3,1,2)就成多余的条件,
我的意图是在k3<k2的情况下标注,k3=k2就不标注。

可能是我这次提供的bb无这种情况,我把上次的bb试一下看.


[此贴子已经被作者于2021-9-21 10:49编辑过]

#13
fdqzy2021-09-21 11:08
老师:
只有本站会员才能查看附件,请 登录

此表放在IF k1==k2 AND k1>0 AND krow>20 AND k1<7,
在IF INLIST(k2-k3,1,2)之前(标注条件前)
测试结果显示无k3=k2的情况,且出现记录超范围的提示。
不满足:在k3<k2的情况下标注,k3=k2就不标注。

这样 IF INLIST(k2-k3,1,2)就成多余的条件,

第一次代码有k3=k2和k3<k2情况

[此贴子已经被作者于2021-9-21 11:11编辑过]

#14
吹水佬2021-09-21 11:38
k2是连续非空最多的,且按每行计算,k3是紧跟着k2,这样一定是 k2-k3==1,所以k3也是多余算的。

#15
fdqzy2021-09-21 12:11
以下是引用吹水佬在2021-9-21 11:38:04的发言:

k2是连续非空最多的,且按每行计算,k3是紧跟着k2,这样一定是 k2-k3==1,所以k3也是多余算的。

程序代码:
FUNCTION k2k3(k2,k3,n1)  && 最大值、最次大值
    IF n1 > k2
        k2 = n1
    ELSE
        IF n1 > k3
            k3 = n1
        ENDIF
    ENDIF
ENDFUNC

经测试:上一次的这段代码有k3=k2 和k3<k2两种情况。
只是标注时字段名不是第1个

满足:在k3<k2的情况下标注,k3=k2就不标注是主要条件

[此贴子已经被作者于2021-9-21 12:23编辑过]

#16
fdqzy2021-09-21 12:21
第一次的代码解决了在100行中有一个条件在k3<k2时标注,k3=k2时不标注的问题,只是标注时是最后一个字段名。
如果不管字段名,也算解决了问题.
#17
吹水佬2021-09-21 12:25
回复 15楼 fdqzy
7楼已解释过
#18
fdqzy2021-09-21 12:26
用上面的bb,用下面的pmax
只有本站会员才能查看附件,请 登录

否则显示记录超范围
#19
fdqzy2021-09-21 12:36
以下是引用吹水佬在2021-9-21 12:25:22的发言:

7楼已解释过

麻烦了,谢谢!
#20
吹水佬2021-09-21 14:52
回复 16楼 fdqzy
程序代码:
之前的代码
按连续非空整块比对
        FOR nRow=1 TO ALEN(a100,1)
            IF EMPTY(a100[nRow,nCol])
                n1 = n1 + 1
            ELSE
                k2k3(@k2,@k3,@n1)
                n1 = 0
                krow = krow + 1
            ENDIF
        ENDFOR

FUNCTION k2k3(k2,k3,n1)  && 最大值、最次大值
    IF n1 > k2
        k2 = n1
    ELSE
        IF n1 > k3     这个算法有问题,有可能 k2==k3 两个都是老大了
            k3 = n1
        ENDIF
    ENDIF
ENDFUN

后来的代码
按非空行比对
        FOR nRow=1 TO ALEN(a100,1)
            IF EMPTY(a100[nRow,nCol])
                n1 = n1 + 1
                k2k3(@k2,@k3,@n1)
            ELSE
                n1 = 0
                krow = krow + 1
            ENDIF
        ENDFOR

FUNCTION k2k3(k2,k3,n1)  && 最大值、最次大值
    IF n1 > k2    有新的最大时
        k3 = k2   原最大变次大
        k2 = n1   新的最大
    ENDIF
ENDFUNC
#21
fdqzy2021-09-21 18:01
以下是引用吹水佬在2021-9-21 14:52:19的发言:
FUNCTION k2k3(k2,k3,n1)  && 最大值、最次大值
    IF n1 > k2
        k2 = n1
    ELSE
        IF n1 > k3     这个算法有问题,有可能 k2==k3 两个都是老大了
            k3 = n1
        ENDIF
    ENDIF
ENDFUN
ENDFUNC

这个算法有可能呵,是我没讲清k3的来源:
k3是排除末行值时全列其他行中的最大值, k2是包括末行值(k1)的最大值,当k1<k2,k3=k2;
当k1=k2时,就有k3<=k2两种情况,我就是要找当k1=k2时,且k3<k2的情况.
(在对100行空白行填序数时就有这种情况的可能)
辛苦您了,谢谢!
#22
吹水佬2021-09-21 18:37
主要是算k1、k2、k3和n1,算法模块大体就是那两块,按要求改改就可以了。
#23
fdqzy2021-09-21 19:32
回复 22楼 吹水佬
谢谢!
1