假设有这么一个工程,需要在数据窗口中,新建 150 × 150 个文本框, 效果图如下:
这个时候,我们可以使用传统的方法,即双循环来建立 modify 语句,代码如下:
long ll_k,ll_c,ll_x1,ll_y1 = -1, ll_width = 5, ll_height = 5, r, r1, l_row ll_k=5 ll_c=5 string ls_height , ls_width , ls_syn, ls_str, ls_x, ls_y, ls_name dw_1.reset() dw_1.insertrow(0) for r= 1 to ll_k ll_y1=ll_y1+ll_height + 1 ll_x1=-1 for r1 = 1 to ll_c l_row=l_row+1 ll_x1=ll_x1+ll_width + 1 ls_x=String(ll_x1) ls_y=String(ll_y1) ls_height=String(ll_height) ls_width=String(ll_width) ls_name = 't_l' +string(l_row) // border="0" 不带黑边 // border="2"带黑边 ls_str = 'text(band=detail alignment="0" text="" border="2" color="33554432" ' ls_str = ls_str+' x="'+ls_x+'" y="'+ls_y+'" height="'+ls_height+'" width="'+ls_width+'" html.valueishtml="0" ' //background.mode="2" 1:背景透明 ls_str = ls_str+' name='+ls_name+' visible="1" font.face="Arial" font.height="-12" font.weight="400" font.family="1" font.pitch="2" font.charset="0" background.mode="1" background.color="536870912" )' ls_str = '~r~ncreate '+ ls_str ls_syn=ls_syn+ls_str next next dw_1.Modify(ls_syn)
这个代码是很好理解的,由上及下,从左到右,依次生成22500行create text 语句,但是这样的效率是很头疼的,整个代码的运行时间大约需要230秒(电脑配置不同,时间不同),也就是说需要大约4分钟的等待时间,才能绘出上图,这显然是不可接受的。
对于这个工程,我们可以清晰的看到,它是有规律的,每个文本框无论是左右还是上下,间距都是很有规律的,这种间距规律可以通过数据窗口中的每一行数据的 getrow() 值的不同来构建。再看看最终要生成的modify语句:“22500行create text 语句”,回想平时通过object.datawindow.data语句取出来的数据串的格式:“每一行数据就是一行字符串”。把这些思路串联在一起,不免要蹦出以数据窗口来解决问题的想法。
首先,建立数据窗口对象 d_d : d_d 中包含4个long型数据列x、y、w、h,分别表示要create到dw_1中的text对象的x、y、width、height;同时包含两个计算列com和s_create,com是用来进行赋值的,表达式随便填,s_create用来存create语句的,表达式为:'create text(band=detail alignment="0" text="" border="2" color="33554432" x="' + string(x) + '" y="' + string(y) + '" height="' + string(w) + '" width="' + string(h) + '" html.valueishtml="0" name=t_l' + string(getrow()) + ' visible="1" font.face="Arial" font.height="-12" font.weight="400" font.family="1" font.pitch="2" font.charset="0" background.mode="1" background.color="536870912" )'
其次,建立数据窗口对象 d_c : d_c 中仅包含1个char(4000)的数据列s_create,用来存储 d_d 中的计算列s_create
接着,建立数据窗口对象 d_s : freeform 类型, 用来显示最终的效果图。
做了这些前期准备后,既可以开始实行我们想要的功能了, 新增窗口,插入数据窗口,设置dataobject 为 d_s ; 插入一个按钮,在按钮的 clicked 事件写如下代码:
dw_1.reset() dw_1.insertrow(0) long ll_width = 5,ll_height = 5 //每个控件的宽和高(像素) string ls_syn long ll_c=150, ll_k=150//长与宽的控件个数 long ll_sx = 10,ll_sy = 10 //第一个框的起始坐标(像素) datastore lds_s lds_s = create datastore lds_s.dataobject = 'd_d' lds_s.reset() wf_insertrow(lds_s, ll_c * ll_k) //快速插入多行 //宽度 lds_s.object.com.expression = string(ll_width) lds_s.object.w.primary = lds_s.object.com.primary //高度 lds_s.object.com.expression = string(ll_height) lds_s.object.h.primary = lds_s.object.com.primary //x lds_s.object.com.expression = string(ll_sx) + " + mod(getrow() - 1, " + string(ll_c) + ") * (w + 1)" lds_s.object.x.primary = lds_s.object.com.primary //y lds_s.object.com.expression = string(ll_sy) + " + int((getrow() - 1) / " + string(ll_k) + ") * (h + 1)" lds_s.object.y.primary = lds_s.object.com.primary datastore lds lds = create datastore lds.dataobject = 'd_c' lds.reset() lds.object.s_create[1,lds_s.rowcount()] = lds_s.object.s_create[1,lds_s.rowcount()] ls_syn = lds.object.datawindow.data //调整detail的高度 ls_syn += "~r~ndatawindow.detail.height = " + string(ll_sy * 2 + ll_k * (ll_height + 1) ) destroy lds destroy lds_s dw_1.Modify(ls_syn)
代码中的 wf_insertrow(lds_s, ll_c * ll_k) 函数,可以参考我写的另一篇博文:pb数据窗口快速插入空行的方法
运行代码试试效果吧,用时大约2秒,效率是不是有了大幅提高!所耗费的2秒主要用在 modify 语句上, 这方面暂时没有找到提高效率的方法。
也许我所举例的这个工程在实际开发项目上,使用意义不大,但是在日后开发过程中,对于需要通过多重循环构建的字符串,可以按照代码所提供的思路来进行。