kk_lee69 发表于 2012-8-20 13:36:48

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







这是 目前 发现最好的写法了欢迎 有更好写法的朋友 提出来讨论

yeqing880 发表于 2012-8-20 18:15:51

如果数据量大。。我一般会采用分段方式

athland5013 发表于 2012-8-23 06:46:40

本帖最后由 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:32:13

本帖最后由 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 要在哪修改呢能寫個範例嗎??

ojoojo 发表于 2012-9-4 23:41:12

谢谢楼主提供,支持你

lsxuri 发表于 2013-7-21 23:04:36

没看懂,值得学习

compubusin 发表于 2013-8-16 15:02:02

这个是很有用的程序,谢谢

pccp 发表于 2013-8-16 16:18:35

正在学习数组在AU3脚本代码中的应用知识,感觉这方面的初学资料很少,但又很重要。尤其是多维数组在脚本中的使用方法,感觉一下子很难吃透,要是多一些这样的资料指引就好了。

mountain 发表于 2013-8-20 19:47:49

嗯,分析的不错,研究下

fcurrk 发表于 2013-9-10 09:27:30

这个支持,我也是这样弄的,都读到数组再写LISTVIEW

fatalzero4 发表于 2013-9-10 10:53:41

谢谢楼主分享。

jabilyang 发表于 2013-9-12 18:46:31

慢慢消化,谢谢分享

huangwei 发表于 2013-10-4 13:02:47

谢谢楼主提供

zhoujinshi 发表于 2013-12-25 17:55:38

回复 5# kk_lee69


4#说的是要修改下_guictrllistview_Addarray 这个UDF

58fly 发表于 2014-2-13 06:38:01

现在还没有碰到这么大的数据量,先记录!
页: [1] 2 3
查看完整版本: 10万笔(55万笔)数据 汇入 LISTVIEW 实测……. 只要15秒(LISTVIE汇数据最佳写法)