分享:SQL2000 异步查询数据带进度条。
*!* 斑竹aaaaaa提供代码,VFP9.0+SQL2000,外网数据库,8900条记录,测试11秒左右。*!* 方法一:用 Wait window
*!* SQL Query 使用过程条,SQLExec 必须异步模式。
Local loTherm,lnRes ,lcQueryTB ,lcQueryYB
*!* Sql查询语句,同步查记录总数
TEXT TO lcQueryTB TEXTMERGE NOSHOW PRETEXT 4
SELECT COUNT(*) as SqlCount
from wy_sdb
where fyqj>='2015-10-01'
ENDTEXT
*!* Sql查询语句,异步查记录内容
TEXT TO lcQueryYB TEXTMERGE NOSHOW PRETEXT 4
SELECT bh,fyqj,df,sf,hj,sjh
from wy_sdb
where fyqj>='2015-10-01'
ENDTEXT
*!* Sql连接句柄
csql = [ driver=sql server;server=]+cServer+[;uid=]+cUid+[;pwd=]+cPwd+[;database=]+cdbs
sqlHandler = Sqlstringconnect(csql)
IF sqlHandler < 0
MESSAGEBOX("连接数据库失败!",16,"连接错误")
ELSE
t1=SECONDS()
*!* 首先使用同步方式获取总记录数(不要异步方式):
LOCAL lnFetchSize ,lnMaxWait ,lnSqlCount ,lcWait
SQLSetprop(sqlHandler, "Asynchronous", .F.) && 同步方式
lnRes=SQLExec(m.sqlHandler, lcQueryTB, "SqlQueryTB")
lnSqlCount = 0
lnFetchSize = 1
lnMaxWait = 20 && 满进度显示“■”的个数,可以自己设置,20个左右合适
IF lnRes < 0
MESSAGEBOX("读取记录总数出错!",16,"读取错误")
RETURN
ELSE
lnSqlCount = IIF(ISNULL(SqlQueryTB.SqlCount),0,SqlQueryTB.SqlCount) && 合理设置 lnFetchSize
IF lnSqlCount>lnMaxWait
lnFetchSize=INT(lnSqlCount / lnMaxWait) && 自动计算异步查询步长,每个“■”代表的记录数
ENDIF
lcWait = Replicate("■", 1)+SPACE(lnMaxWait*2-1*2)
Wait Window (lcWait) Nowait && 刷新过程条
Endif
*!* 然后使用异步方式做查询:
SQLSetprop(sqlHandler, "Asynchronous", .T.) && 异步方式
CursorSetProp("FetchSize", lnFetchSize, 0) && FetchSize 属性,设置每次异步查询返回的记录数 lnFetchSize
lnRes=SQLExec(sqlHandler, lcQueryYB,"SqlQueryYB")
If lnRes < 0
MESSAGEBOX("读取记录进程出错!",16,"读取错误")
WAIT CLEAR
RETURN
Endif
*!* 更新过程条的显示,显示格式为:总共 lnMaxWait 个“■”
LOCAL lnCnt
Do While SQLExec(sqlHandler) = 0
DoEvents
lnCnt = CursorGetProp("RecordsFetched") && 当前返回的记录数
lcWait = Replicate("■", INT(lnCnt/lnFetchSize))+SPACE(lnMaxWait*2-INT(lnCnt/lnFetchSize)*2)
Wait Window (lcWait) Nowait && 刷新过程条
Enddo
*!* 当总记录数少于lnMaxWait时,可能是出现不满过程条,补满过程条
lcWait = Replicate("■", lnMaxWait)
Wait Window (lcWait) Nowait && 刷新过程条
?lnCnt,SECONDS()-t1
ENDIF
*!* 斑竹aaaaaa提供代码,VFP9.0+SQL2000,外网数据库,8900条记录,测试11秒左右。
*!* 方法二:用类 _Therm.Vcx
*!* SQL Query 使用过程条,SQLExec 必须异步模式。
*!* 下面是一个使用 VFP FFC _Therm.Vcx 过程条例子:
Local loTherm,lnRes ,lcQueryTB ,lcQueryYB
*!* 使用 VFP FFC 自带的 _Therm.Vcx 过程条:
loTherm = Newobject("_thermometer", Home() + "ffc/_therm", "", "正在查询数据,请稍候...")
loTherm.Show
loTherm.Update(0, "正在查询...")
DoEvents Force
*!* Sql查询语句,同步查记录总数
TEXT TO lcQueryTB TEXTMERGE NOSHOW PRETEXT 4
SELECT COUNT(*) as SqlCount
from wy_sdb
where fyqj>='2015-10-01'
ENDTEXT
*!* Sql查询语句,异步查记录内容
TEXT TO lcQueryYB TEXTMERGE NOSHOW PRETEXT 4
SELECT bh,fyqj,df,sf,hj,sjh
from wy_sdb
where fyqj>='2015-10-01'
ENDTEXT
*!* Sql连接句柄
csql = [ driver=sql server;server=]+cServer+[;uid=]+cUid+[;pwd=]+cPwd+[;database=]+cdbs
sqlHandler = Sqlstringconnect(csql)
IF sqlHandler < 0
MESSAGEBOX("连接数据库失败!",16,"连接错误")
Release loTherm
ELSE
t1=SECONDS()
*!* 首先使用同步方式获取总记录数(不要异步方式):
LOCAL lnFetchSize ,lnSqlCount
SQLSetprop(sqlHandler, "Asynchronous", .F.) && 同步方式
lnRes=SQLExec(m.sqlHandler, lcQueryTB, "SqlQueryTB")
lnSqlCount=0
lnFetchSize=1
IF lnRes < 0
MESSAGEBOX("读取记录总数出错!",16,"读取错误")
Release loTherm
RETURN
ELSE
lnSqlCount = IIF(ISNULL(SqlQueryTB.SqlCount),0,SqlQueryTB.SqlCount) && 合理设置 lnFetchSize
IF lnSqlCount>100
lnFetchSize=INT(lnSqlCount / 100) && 自动计算异步查询步长
ENDIF
lotherm.iBasis = SqlQueryTB.SqlCount && SqlCount 游标中的总记录数
Endif
*!* 然后使用异步方式做查询:
SQLSetprop(sqlHandler, "Asynchronous", .T.) && 异步方式
CursorSetProp("FetchSize", lnFetchSize, 0) && FetchSize 属性,设置每次异步查询返回的记录数 lnFetchSize
lnRes=SQLExec(sqlHandler, lcQueryYB,"SqlQueryYB")
If lnRes < 0
MESSAGEBOX("读取记录进程出错!",16,"读取错误")
Release loTherm
RETURN
Endif
*!* 更新过程条的显示,显示格式为:当前记录数 N / 总记录数 M:
LOCAL lnCnt
Do While SQLExec(sqlHandler) = 0
DoEvents
lnCnt = CursorGetProp("RecordsFetched")
loTherm.Update(m.lnCnt, Transform(m.lnCnt) + "/" + Transform(loTherm.iBasis))
Enddo
Release loTherm
?lnCnt,SECONDS()-t1
ENDIF
** 多个表共用1个进度条的方法,已经解决,在第10楼
[此贴子已经被作者于2016-4-9 20:09编辑过]