注册 登录
编程论坛 VFP论坛

各位大佬,什么方法最好,用时最少,盼赐教,谢谢。

凝聚双眼 发布于 2023-12-01 12:13, 1220 次点击
只有本站会员才能查看附件,请 登录



Create Cursor temp (F1 c(10),F2 c(10),F3 N(6,1))
For jj=1 To 999999
    Append Blank
Endfor

Replace All F1 With '序'+Padl(Alltrim(Str(Recno())),5,[00000])
Replace All F2 With [A]+Padl(Alltrim(Str(Recno())),5,[00000])
Replace All F3 With Recno()
*----------------------------------------------------*
t1=SECONDS()
*----------------------------------------------------*




[此贴子已经被作者于2023-12-1 12:15编辑过]

41 回复
#2
laowan0012023-12-13 10:43
把3句replace合并成一句还能快一点点
#3
easyppt2023-12-13 11:22
估计要结合你的实际业务场景了,例子本身可优化的空间很小,速度来去不会很大,也可以 Update 操作:

update temp set F1 = '序'+Padl(Alltrim(Str(Recno())),5,[00000]),;
F2 = [A]+Padl(Alltrim(Str(Recno())),5,[00000]),;
F3 = Recno()


#4
sostemp2023-12-13 13:04
以下是引用easyppt在2023-12-13 11:22:18的发言:

估计要结合你的实际业务场景了,例子本身可优化的空间很小,速度来去不会很大,也可以 Update 操作:

update temp set F1 = '序'+Padl(Alltrim(Str(Recno())),5,[00000]),;
F2 = [A]+Padl(Alltrim(Str(Recno())),5,[00000]),;
F3 = Recno()


2楼、3楼的朋友,估计是理解错了。那应该只是楼主给的是测试数据代码而已。
楼主应该是求续写的后面的代码,动态分栏、分页。

[此贴子已经被作者于2023-12-13 13:05编辑过]

#5
schtg2023-12-14 07:12
分组吧?
#6
凝聚双眼2023-12-14 11:14
回复 4楼 sostemp
是的。谢谢
#7
凝聚双眼2023-12-14 11:20
回复 5楼 schtg
对,对给定数据表,实现动态分组与动态分页,谢谢。
每组最多50。
比如,有 65条,分2组,那么左组 33,右组 32,一页
如有 99条,分2组,那么左组50,右组 49,一页
如有 101条,分2组,第一页左 50,右50,第二页左1。
只有本站会员才能查看附件,请 登录


[此贴子已经被作者于2023-12-17 14:37编辑过]

#8
sych2023-12-14 12:57
思路要转换,我们要的是实现目标,不是追求速度、高效(当然如果技术强悍,另当别论),别人一句实现的,我们分步能实现也区别不大
#9
凝聚双眼2023-12-14 13:52
回复 8楼 sych

能否附上您的调用函数代码,学习您的思路,谢谢。
#10
凝聚双眼2023-12-14 15:15
回复 2楼 laowan001
只有本站会员才能查看附件,请 登录

您误会了,我没讲清楚。
是对给定数据表,实现动态分组与动态分页,谢谢。
每组最多50。
组数不固定。
比如,有 65条,分2组,那么左组 33,右组 32,一页
如有 99条,分2组,那么左组50,右组 49,一页
如有 101条,分2组,第一页左 50,右50,第二页左1。

*===================================================================================
*作 用:对指定数据表分栏分组分页
*语 法:ColGroup_Convert(cTableMc,nNumber,cOutTableMc,nMaxColGroupRec)
*参数说明:cInTableMc 要转换的数据表,nNumber 分栏分组数,
*参数说明:cOutTableMc 分栏分组后的数据表,nMaxColGroupRec 每页每栏的最大记录数(默认为50)
*返 回 值:
*===================================================================================
Function ColGroup_Convert(cTableMc,nNumber,cOutTableMc,nMaxColGroupRec)  
    If Parameters()#4
        Messagebox('参数个数不对!',16,'错误')
        Return ''
    Endif
    If Vartype(cTableMc)#'C' Or Vartype(nNumber)#'N' Or Vartype(cOutTableMc)#'C' Or Vartype(nMaxColGroupRec)#'N'
        Messagebox('参数类型不对!',16,'错误')
        Return ''
    Endif
    Private All
    ....
    ....
    ....
    .....
Endfunc

[此贴子已经被作者于2023-12-17 14:38编辑过]

#11
laowan0012023-12-14 16:59
回复 10楼 凝聚双眼
1. 是需要完善function中...的那部分吧?
2. 函数返回是个分组后的表吗?
3. 结果如果是个表,是需要在原表中标识分组,还是通过新建字段实现分组?
#12
schtg2023-12-14 17:01
回复 7楼 凝聚双眼
先用总记录数除以100判断,需要多少页,再用奇偶数判断最后一页的左侧多少、右侧多少吧。不要见笑,仅供参考
#13
sych2023-12-14 20:28
clea
CLOSE all
CREATE CURSOR 分组  (recn1 i,recn2 i)
use 表1 IN 0
SELECT 表1
SCAN
    if MOD(recn()-1,100)<50
        inse into 分组 (recn1) values(recn("表1"))
    ELSE
        go 50*INT((RECNO("表1")-1)/100)+MOD(RECNO("表1")-1,50)+1 IN 分组
        REPLACE recn2 WITH RECNO("表1") IN 分组
    ENDIF
ENDSCAN
SELECT 1
brow
#14
sdta2023-12-14 21:11
Replace All F1 With '序'+Padl(Recno(),6,[0]), F2 With [A]+Padl(Recno(),6,[0]), F3 With Recno()
#15
sdta2023-12-14 21:19
只要把要求说清楚,楼主的问题应该不难吧 

#16
凝聚双眼2023-12-14 22:05
以下是引用laowan001在2023-12-14 16:59:58的发言:

1. 是需要完善function中...的那部分吧?
2. 函数返回是个分组后的表吗?
3. 结果如果是个表,是需要在原表中标识分组,还是通过新建字段实现分组?


对,返回表。
返 回 值:返回生成后的新表(返回表的字段数=分栏数*原字段)

假设原表字段为 f1f2f3,分3栏,新表字段则为9个字段。当然啦,各字段类型与原表一样。

[此贴子已经被作者于2023-12-14 23:04编辑过]

#17
sych2023-12-14 22:15
clea
CLOSE all
CREATE CURSOR 分组  (recn1 i,recn2 i)
use 表1 IN 0
SELECT 表1
SCAN
    st=IIF(MOD(RECNO(),100)=1,RECNO(),st)
    fz=IIF(MOD(RECNO(),100)=1,IIF(RECCOUNT()-RECNO()<99,(RECCOUNT()-RECNO()-MOD(RECCOUNT()-RECNO(),2))/2+1,50),fz)
    if MOD(recn()-st,2*fz)<fz
        inse into 分组 (recn1) values(recn("表1"))
    ELSE
        go st/2+mod(RECNO("表1")-st-fz,2*fz)+1 IN 分组
        REPLACE recn2 WITH RECNO("表1") IN 分组
    ENDIF
ENDSCAN
SELECT 1
brow
#18
凝聚双眼2023-12-14 22:23
以下是引用sdta在2023-12-14 21:19:45的发言:

只要把要求说清楚,楼主的问题应该不难吧 

因论坛时好时坏,当时已无法编辑一楼了。是没有描述完,见谅。




[此贴子已经被作者于2023-12-14 22:34编辑过]

#19
凝聚双眼2023-12-14 22:33
回复 12楼 schtg
分栏数不固定的。道理大方向应该是对的。谢谢。
#20
凝聚双眼2023-12-14 22:35
回复 14楼 sdta
一楼代码是给定测试数据,IO万条,3字段,只是举例。
当然啦,表字段数不固定,返回表的字段数=分栏数*原字段

是对给定数据表,实现动态分组与动态分页,每组最多50,分栏组数不固定。
如3栏,则每页最多 150,如2栏,则每页最多 100。
不足一页时,不一定是 50。

比如,有 65条,分2组,那么左组 33,右组 32,一页
如有 99条,分2组,那么左组50,右组 49,一页

如有 101条,分2组,第一页左 50,右50,第二页左1。

也不知道描述消楚没,谢谢大佬关注!


*===================================================================================
*作 用:对指定数据表分栏分组分页
*语 法:ColGroup_Convert(cTableMc,nNumber,cOutTableMc,nMaxColGroupRec)
*参数说明:cInTableMc 要转换的数据表,nNumber 分栏分组数,
*参数说明:cOutTableMc 分栏分组后的数据表,nMaxColGroupRec 每页每栏的最大记录数(默认为50)
*返 回 值:返回生成后的新表(返回表的字段数=分栏数*原字段)
*===================================================================================
Function ColGroup_Convert(cTableMc,nNumber,cOutTableMc,nMaxColGroupRec)  
    If Parameters()#4
        Messagebox('参数个数不对!',16,'错误')
        Return ''
    Endif
    If Vartype(cTableMc)#'C' Or Vartype(nNumber)#'N' Or Vartype(cOutTableMc)#'C' Or Vartype(nMaxColGroupRec)#'N'
        Messagebox('参数类型不对!',16,'错误')
        Return ''
    Endif
    Private All
    ....
    ....
    ....
    .....
Endfunc
#21
凝聚双眼2023-12-14 23:15
论坛可能还是有点bug,图片不能显示吗?
一楼举例分2组,3组的示例图,大家可以看到吗?
#22
凝聚双眼2023-12-15 09:29
只有本站会员才能查看附件,请 登录





[此贴子已经被作者于2023-12-15 15:43编辑过]

#23
sdta2023-12-15 11:50

每页最多几栏,每栏最多几条记录

[此贴子已经被作者于2023-12-15 11:58编辑过]

#24
凝聚双眼2023-12-15 13:47
回复 23楼 sdta
传入4个参数,原表名,分栏数,新表名,每栏最大记录数。
传入一个表,表字段数不固定。当然不会 原字段数*分栏数大于 254。
分栏数是不固定的,看传入数。
示例说明应该是很清晰,见 22楼图。谢谢大佬。
这个有点类 似 Vfp报表或标签的分列。
只有本站会员才能查看附件,请 登录


[此贴子已经被作者于2023-12-17 14:39编辑过]

#25
laowan0012023-12-15 15:09
以下是引用凝聚双眼在2023-12-14 23:15:45的发言:

论坛可能还是有点bug,图片不能显示吗?
一楼举例分2组,3组的示例图,大家可以看到吗?


看不到
#26
凝聚双眼2023-12-15 15:16
回复 25楼 laowan001
22楼的图呢,看得到吗
论坛图片可能还是有问题。

[此贴子已经被作者于2023-12-15 15:19编辑过]

#27
laowan0012023-12-15 15:18
程序代码:
*===================================================================================
*作 用:对指定数据表分栏分组分页
*语 法:ColGroup_Convert(cTableMc,nNumber,cOutTableMc,nMaxColGroupRec)
*参数说明:cInTableMc 要转换的数据表,nNumber 分栏分组数,
*参数说明:cOutTableMc 分栏分组后的数据表,nMaxColGroupRec 每页每栏的最大记录数(默认为50)
*返 回 值:返回生成后的新表(返回表的字段数=分栏数*原字段)
*===================================================================================

nMaxColGroupRec,这是每栏最大记录数,也是不确定的吧?
#28
凝聚双眼2023-12-15 15:21
回复 27楼 laowan001
传入默认50,函数里面可根据页数,自行判断。
99,做二栏,最多 100,故一页, 就50+49。表记录数 50
99,做三栏,最多150,故一页,则 33+33+33。表记录数33
160,做三栏,一页最多 150,所以为2页。150+10。  那么为 54+54+52。表记录数 54

有点类似报表或标签分列。



[此贴子已经被作者于2023-12-15 15:48编辑过]

#29
laowan0012023-12-15 16:00
以下是引用凝聚双眼在2023-12-15 15:21:07的发言:

传入默认50,函数里面可根据页数,自行判断。
99,做二栏,最多 100,故一页, 就50+49。表记录数 50
99,做三栏,最多150,故一页,则 33+33+33。表记录数33
160,做三栏,一页最多 150,所以为2页。150+10。  那么为 54+54+52。表记录数 54

有点类似报表或标签分列。

如果nMaxColGroupRec是不确定的,那么页数就不确定,怎么“根据页数自行判断”?
“传入默认50”是什么意思,就是每次传递这个参数都是50?
#30
laowan0012023-12-15 16:09
返回表中的页数如何体现 ?
分栏时,记录按第一栏从上到下,然后第二栏从上到下,。。。,还是每一行从左到右

#31
sych2023-12-15 16:58
从左到右的是最简单,从上到下的稍显复杂

#32
sych2023-12-15 16:59
我发的代码就是从上到下的,不过好像没人关心这段代码
#33
凝聚双眼2023-12-15 19:54
回复 31楼 sych
谢谢您的代码。
您可以看到图片吗?1楼与 22楼,我发的举例图片吗?
好象论坛图片显示有问题。
#34
凝聚双眼2023-12-15 19:57
回复 30楼 laowan001
可惜论坛图片不能显示。我1楼与 22楼,上传的图片很清晰的表达了。

#35
凝聚双眼2023-12-15 20:01
以下是引用laowan001在2023-12-15 16:09:50的发言:

返回表中的页数如何体现 ?
分栏时,记录按第一栏从上到下,然后第二栏从上到下,。。。,还是每一行从左到右


分栏时,依次上到下,先左后右。
就是您说的前半部分。

第一栏从上到下,第二栏从上到下,第三栏从上到下……


有点类似报表与标签的分列。

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

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




[此贴子已经被作者于2023-12-17 14:41编辑过]

#36
凝聚双眼2023-12-15 20:07
那我再上传个22楼图片外链,不知道可以不可以打开看到。


https://99img.cc/images/2023/12/15/20231215_0c9a35d92a34bc7086f2jmAJawhhUaOB9c8cfc76a6bfa955.jpg

[此贴子已经被作者于2023-12-15 21:10编辑过]

#37
凝聚双眼2023-12-15 20:08
回复 30楼 laowan001
只有本站会员才能查看附件,请 登录
您看看,可以看到吗?

那我再上传个22楼图片外链,不知道可以不可以打开看到。


https://99img.cc/images/2023/12/15/20231215_0c9a35d92a34bc7086f2jmAJawhhUaOB9c8cfc76a6bfa955.jpg

[此贴子已经被作者于2023-12-17 14:31编辑过]

#38
laowan0012023-12-18 09:32
程序代码:
*===================================================================================
*作 用:对指定数据表分栏分组分页
*语 法:ColGroup_Convert(cTableMc,nNumber,cOutTableMc,nMaxColGroupRec)
*参数说明:cInTableMc 要转换的数据表,nNumber 分栏分组数,
*参数说明:cOutTableMc 分栏分组后的数据表,nMaxColGroupRec 每页每栏的最大记录数(默认为50)
*返 回 值:返回生成后的新表(返回表的字段数=分栏数*原字段)
*===================================================================================

LPARAMETERS cTableMc,nNumber,cOutTableMc,nMaxColGroupRec
LOCAL xfile,xmaxrec,ii,jj,xfieldupd[nNumber],xfields,xrec,xrow,xjs,xcount

LOCAL xtime
xtime = DATETIME()

xfile = SYS(2015)

xrec = ''    && 结果表结构字段
SELECT &cTableMc
FOR jj=1 TO nNumber
    xfields = ''
    FOR ii=1 TO FCOUNT()
        xfields = xfields + ',' + FIELD(ii) + ' F' + TRANSFORM(ii+(jj-1)*FCOUNT())
    ENDFOR
    xrec = xrec + xfields

    * 生成各栏替换语句xfieldupd[nNumber]
    xfields = ''
    FOR ii=1 TO FCOUNT()
        TEXT TO xfields ADDITIVE PRETEXT 7 NOSHOW TEXTMERGE
            ,F<<TRANSFORM(ii+(jj-1)*FCOUNT())>> WITH <<cTableMc>>.<<FIELD(ii)>>
        ENDTEXT
    ENDFOR
    xfieldupd[jj] = SUBSTR(xfields,2)
ENDFOR
xrec = SUBSTR(xrec,2)

* 生成结果表
SELECT &xrec FROM &cTableMc WHERE 1=2 INTO CURSOR &cOutTableMc READWRITE

SELECT * FROM &cOutTableMc WHERE 1=2 INTO CURSOR &xfile READWRITE     && 每页的表,处理结束插入到结果表

xmaxrec = nNumber*nMaxColGroupRec

xjs = 1
xrec = 1
xcount = 0
SELECT &cTableMc
SCAN
    IF xjs=1 AND xcount=0    && 计算下一页最大行数
        xmaxrec = MIN(xmaxrec,RECCOUNT()-RECNO()+1)
        xrow = INT(xmaxrec/nNumber) + IIF(MOD(xmaxrec,nNumber)=0,0,1)    && 每页行数
    ENDIF
    xcount = xcount + 1
   
    SELECT &xfile
    IF xjs=1    && 首栏插入
        APPEND BLANK
    ENDIF
    xfields = xfieldupd[xjs]
    REPLACE &xfields
    SKIP
   
    IF xcount=xrow        && 完成一栏
        xcount = 0
        xjs = xjs + 1
        GO TOP
    ENDIF
   
    IF xjs>nNumber OR RECNO(cTableMc)=RECCOUNT(cTableMc)        && 完成一页或者结束了
        SELECT &cOutTableMc
        APPEND FROM DBF(xfile)
        
        SELECT * FROM &xfile WHERE 1=2 INTO CURSOR &xfile READWRITE
        xjs = 1
    ENDIF
    SELECT &cTableMc
ENDSCAN
USE IN &xfile

messagebox( DATETIME()-xtime)

RETURN
#39
schtg2023-12-19 07:25
回复 38楼 laowan001
高!
#40
sych2023-12-19 21:14
把我原来的代码稍加修改
CLOSE all
Create Cursor temp (序号 c(10),品名 c(10), 数量 N(6, 1))
For jj=1 To 133
    Append Blank
ENDFOR
Replace ALL 序号 With '序'+PADL(Alltrim(Str(RECNo())), 5, [00000])
Replace All 品名 With [A]+Padl(Alltrim (Str (RECNo())), 5, [00000])
Replace all 数量 With RECNO()
=ColGroup_Convert("temp","tempbl",3,50)  &&第一个参数可以是工作区编号或表别名
SELECT * FROM tempbl
retu

PROCEDURE ColGroup_Convert(cTableMc,cOutTableMc,nNumber,nMaxColGroupRec)
LOCAL i,j,st,fz
=AFIELDS(fn,cTableMc)
COPY STRUCTURE extended TO ltemp
SELECT 0
USE ltemp
LOCAL aa(nNumber)
FOR i=2 TO nNumber
    APPEND FROM array fn
    FOR j=1 TO FCOUNT(cTableMc)
        aa(i)=IIF(j=1,"F"+TRANSFORM(i*FCOUNT(cTableMc)-2),aa(i)+","+"F"+TRANSFORM(i*FCOUNT(cTableMc)-3+j))
    next
NEXT
REPLACE ALL field_name WITH "F"+TRANSFORM(RECNO())
CREATE (cOutTableMc) from ltemp
SELECT (cTableMc)
SCAN
    st=IIF(MOD(RECNO(),nNumber*nMaxColGroupRec)=1,RECNO(),st)
    fz=IIF(MOD(RECNO(),nNumber*nMaxColGroupRec)=1,CEILING(MIN(RECCOUNT()-RECNO()+1,nNumber*nMaxColGroupRec)/nNumber),fz)
    SCATTER TO tempa
    if MOD(recn()-st,nNumber*fz)<fz
        INSERT INTO (cOutTableMc) FROM ARRAY tempa
    ELSE
        SELECT (cOutTableMc)
        go st/nNumber+mod(RECNO(cTableMc)-st,fz)+1
        GATHER FROM tempa FIELDS &aa(INT((RECNO(cTableMc)-st)/fz)+1)
        SELECT (cTableMc)
    ENDIF
ENDSCAN
retu
#41
schtg2023-12-20 06:28
回复 40楼 sych
非常好!谢谢!
#42
laowan0012023-12-20 10:16
回复 40楼 sych
高!
1