10万笔(55万笔)数据 汇入 LISTVIEW 实测……. 只要15秒(LISTVIE汇数据最佳写法)
本帖最后由 kk_lee69 于 2012-8-20 13:39 编辑因为工作上的需要经常要与 数据库沟通….所以做了个小测试 把心得整理出来…….
传统方法是一笔一笔的汇数据 如下所示….但是数据量一大的时候 就会变很慢……10万笔数据 实际测试大约 需要500秒
Dim $Server = "DBSERVERSQL"
Dim $Company = "Z100A01001"
DIM $array
#include <GuiConstantsEx.au3>
#include <GuiListView.au3>
#include <array.au3>
#include <Date.au3>
#include <GuiConstants.au3>
#include <WindowsConstants.au3>
#include <Constants.au3>
#RequireAdmin
$WinMain = GuiCreate('TEST',800,600)
$menu2 = GuiCtrlCreateButton('RUN', 210, 30, 150, 30);
GUICtrlSetFont(-1,10)
$ListView1 = GUICtrlCreateListView("a|b|c |d|e|f|g", 32, 100, 705, 401)
$conn = ObjCreate("ADODB.Connection")
$RS = ObjCreate("ADODB.Recordset")
$conn.Open ("driver={SQL Server};server="&$Server&";uid=sa;pwd=123;database="&$Company);
$RS.ActiveConnection = $conn;
GuiSetState()
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
Exit
Case $menu2
$iTimer = TimerInit()
$RS.open ("SELECTLA001,LA004,LA006,LA007,LA008,LA009,LA010 FROM INVLA Where LA010 like 'AMB%'");
While (Not $RS.eof And Not $RS.bof);
GUICtrlCreateListViewItem($RS.Fields(0).value&"|"&$RS.Fields(1).value&"|"&$RS.Fields(2).value&"|"&$RS.Fields(3).value&"|"&$RS.Fields(4).value&"|"&$RS.Fields(5).value&"|"&$RS.Fields(6).value, $ListView1 )
$RS.movenext;
WEnd;
$RS.close;
MsgBox(4160, "Information", "Load time: " & TimerDiff($iTimer) / 1000 & " seconds")
EndSwitch
WEnd
如果改成先将 取得的数据 放入到数组里面…. 在一次汇入 LISTVIEW 这样就大约 只需要15秒 如果数据是55万笔 也只要 85秒左右 如下所示:
Dim $Server = "DBSERVERSQL"
Dim $Company = "Z100A01001"
DIM $array
#include <GuiConstantsEx.au3>
#include <GuiListView.au3>
#include <array.au3>
#include <Date.au3>
#include <GuiConstants.au3>
#include <WindowsConstants.au3>
#include <Constants.au3>
#RequireAdmin
$WinMain = GuiCreate('TEST',800,600)
$menu2 = GuiCtrlCreateButton('RUN', 210, 30, 150, 30);
GUICtrlSetFont(-1,10)
$ListView1 = GUICtrlCreateListView("a|b|c |d|e|f|g", 32, 100, 705, 401)
$conn = ObjCreate("ADODB.Connection")
$RS = ObjCreate("ADODB.Recordset")
$conn.Open ("driver={SQL Server};server="&$Server&";uid=sa;pwd=123;database="&$Company);
$RS.ActiveConnection = $conn;
GuiSetState()
; 顯示視窗
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
Exit
Case $menu2
$RS.open ("SELECT COUNT(*) FROM INVLA Where LA010 like 'AMB%'");
While (Not $RS.eof And Not $RS.bof);
$P=$RS.Fields(0).value
$RS.movenext;
WEnd;
$RS.close;
Dim $APP[$P]
$i=0
$iTimer = TimerInit()
$RS.open ("SELECTLA001,LA004,LA006,LA007,LA008,LA009,LA010 FROM INVLA Where LA010 like 'AMB%'");
While (Not $RS.eof And Not $RS.bof);
$APP[$i]=$RS.Fields(0).value
$APP[$i]=$RS.Fields(1).value
$APP[$i]=$RS.Fields(2).value
$APP[$i]=$RS.Fields(3).value
$APP[$i]=$RS.Fields(4).value
$APP[$i]=$RS.Fields(5).value
$APP[$i]=$RS.Fields(6).value
$i=$i+1
;GUICtrlSetState($SETDATA,$GUI_ENABLE)
$RS.movenext;
WEnd;
$RS.close;
_GUICtrlListView_AddArray($ListView1, $APP)
MsgBox(4160, "Information", "Load time: " & TimerDiff($iTimer) / 1000 & " seconds")
EndSwitch
WEnd
这是 目前 发现最好的写法了欢迎 有更好写法的朋友 提出来讨论 如果数据量大。。我一般会采用分段方式 本帖最后由 athland5013 于 2012-8-23 06:50 编辑
回复 1# kk_lee69
;$P = Number($conn.Execute("SELECT COUNT(*) FROM INVLA Where aa").GetString)
;_GUICtrlListView_SetItemCount($ListView1, $P)
$APP = $conn.Execute("SELECTid,bb,cc,dd,ee,ff,gg FROM INVLA").GetRows
_GUICtrlListView_AddArray($ListView1, $APP)
基本上 Case $menu2那段代码可以写成这样, .GetRows 就是返回一个二维数组,效率比添加.Fields高很多
如果 $ListView1 是句柄而不是ID的话,这两句就显得有必要了
;$P = Number($conn.Execute("SELECT COUNT(*) FROM INVLA Where aa").GetString)
;_GUICtrlListView_SetItemCount($ListView1, $P)
如果要求极致的话,可以修改_GUICtrlListView_AddArray函数,减少不必要的判断
但_GUICtrlListView_AddArray不能用_GUICtrlListView_SortItems排序
要排序需要
修改 DllStructSetData($tItem, "Mask", BitOR($LVIF_TEXT, $LVIF_PARAM))
添加 DllStructSetData($tItem, "Param", _SendMessage($hWnd, $LVM_GETITEMCOUNT) + 11111111) 本帖最后由 kk_lee69 于 2012-8-23 09:45 编辑
回复 4# athland5013
感謝回復受益良多... 現在在上班晚點來研究您提到的部分...多謝指正
但_GUICtrlListView_AddArray不能用_GUICtrlListView_SortItems排序
要排序需要
修改 DllStructSetData($tItem, "Mask", BitOR($LVIF_TEXT, $LVIF_PARAM))
添加 DllStructSetData($tItem, "Param", _SendMessage($hWnd, $LVM_GETITEMCOUNT) + 11111111)
這個部份我不懂呢 ?? DllStructSetData 要在哪修改呢能寫個範例嗎?? 谢谢楼主提供,支持你 没看懂,值得学习 这个是很有用的程序,谢谢 正在学习数组在AU3脚本代码中的应用知识,感觉这方面的初学资料很少,但又很重要。尤其是多维数组在脚本中的使用方法,感觉一下子很难吃透,要是多一些这样的资料指引就好了。 嗯,分析的不错,研究下 这个支持,我也是这样弄的,都读到数组再写LISTVIEW 谢谢楼主分享。 慢慢消化,谢谢分享 谢谢楼主提供 回复 5# kk_lee69
4#说的是要修改下_guictrllistview_Addarray 这个UDF 现在还没有碰到这么大的数据量,先记录!