返回列表 发帖

[AU3基础] 关于listview虚表直接读取数据库的方法,求助修改范例成MSSQL的!!

本帖最后由 kk_lee69 于 2018-4-1 23:48 编辑

关于listview虚表直接读取数据库的方法,求助修改范例成SQL的!!

官网有个范例 是listview虚表 直接拿SQLlite 的数据库 当作 listview虚表的数据 直接使用,这样的好处是 即使你的数据再多 也是分次 读取 就不会卡了
无奈 小弟 对于 SQLLITE的 UDF 实在没辙,我研究了半天 总是搞不懂原理
无法改成 把SQL DB 当作数据库来源的方法 ,所以上来求助

listview虚表 我已经很熟了  所以理论上不应该是我不会使用,只是以前的方法都是读进
数组  然后 利用数组 当作listview虚表 的数据源

只是最近遇到了 数据太多 读进数组太慢  想要改成 分次读取 分次秀出的方法

所以才把脑筋动到了 数据库上……

以下是 范例程序 与 数据库  麻烦 高手帮我改个范例

資料庫檔案如下:



或者 也可以利用 下面的檔案 建立資料庫





範例程式如下:

  1. #include <GUIConstants.au3>

  2. #include <WindowsConstants.au3>

  3. #include <GuiListView.au3>

  4. #include <SQLite.au3>

  5.  

  6. Opt( "MustDeclareVars", 1 )

  7.  

  8. Global Const $tagNMLVCACHEHINT = $tagNMHDR & ";int iFrom;int iTo"

  9.  

  10. Global $hLV

  11.  

  12. Example()

  13.  

  14.  

  15. Func Example()

  16.         _SQLite_Startup()

  17.  

  18.         ; Check databases

  19.         Local $iRows1 = CheckDB( "Test1.db" )

  20.         Local $iRows2 = CheckDB( "Test2.db" )

  21.         Local $iRows3 = CheckDB( "Test3.db" )

  22.         Local $iRows

  23.  

  24.         ; Create GUI

  25.         GUICreate( "Virtual ListViews", 850, 400 )

  26.  

  27.         ; Create Tab

  28.         Local $idTab = GUICtrlCreateTab( 10, 10, 850-20, 400-20 )

  29.         GUICtrlCreateTabItem( "Test1.db: " & Format( $iRows1 ) & " rows" )

  30.         GUICtrlCreateTabItem( "Test2.db: " & Format( $iRows2 ) & " rows" )

  31.         GUICtrlCreateTabItem( "Test3.db: " & Format( $iRows3 ) & " rows" )

  32.         GUICtrlCreateTabItem( "" )

  33.  

  34.         ; Create ListView

  35.         Local $idLV = GUICtrlCreateListView( "", 20, 40, 850-40, 400-60, $LVS_OWNERDATA, BitOR( $WS_EX_CLIENTEDGE, $LVS_EX_DOUBLEBUFFER, $LVS_EX_FULLROWSELECT ) )

  36.         $hLV = GUICtrlGetHandle( $idLV ) ;                               Virtual listview                          Reduces flicker

  37.         For $i = 0 To 9

  38.                 _GUICtrlListView_AddColumn( $hLV, "Col" & $i, 75 )

  39.         Next

  40.  

  41.         GUIRegisterMsg( $WM_NOTIFY, "WM_NOTIFY" )

  42.         GUISetState( @SW_SHOW )

  43.  

  44.         ; Data for first tab

  45.         $iRows = $iRows1

  46.         If $iRows Then _SQLite_Open( "Test1.db" )

  47.         GUICtrlSendMsg( $idLV, $LVM_SETITEMCOUNT, $iRows, 0 )

  48.  

  49.         ; Message loop

  50.         While 1

  51.                 Switch GUIGetMsg()

  52.                         Case $idTab

  53.                                 If $iRows Then _SQLite_Close( -1 )

  54.                                 Switch GUICtrlRead( $idTab )

  55.                                         Case 0

  56.                                                 $iRows = $iRows1

  57.                                                 If $iRows Then _SQLite_Open( "Test1.db" )

  58.                                         Case 1

  59.                                                 $iRows = $iRows2

  60.                                                 If $iRows Then _SQLite_Open( "Test2.db" )

  61.                                         Case 2

  62.                                                 $iRows = $iRows3

  63.                                                 If $iRows Then _SQLite_Open( "Test3.db" )

  64.                                 EndSwitch

  65.                                 GUICtrlSendMsg( $idLV, $LVM_SETITEMCOUNT, $iRows, 0 )

  66.  

  67.                         Case $GUI_EVENT_CLOSE

  68.                                 ExitLoop

  69.                 EndSwitch

  70.         WEnd

  71.  

  72.         If $iRows Then _SQLite_Close( -1 )

  73.         _SQLite_Shutdown()

  74.         GUIDelete()


  75.  

  76. Func WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam )

  77.         Local Static $tText = DllStructCreate( "wchar[50]" )

  78.         Local Static $pText = DllStructGetPtr( $tText )

  79.         Local Static $aResult, $iRows, $iFrom

  80.  

  81.         Local $tNMHDR, $hWndFrom, $iCode

  82.         $tNMHDR = DllStructCreate( $tagNMHDR, $lParam )

  83.         $hWndFrom = HWnd( DllStructGetData( $tNMHDR, "hWndFrom" ) )

  84.         $iCode = DllStructGetData( $tNMHDR, "Code" )

  85.  

  86.         Switch $hWndFrom

  87.  

  88.                 Case $hLV

  89.  

  90.                         Switch $iCode

  91.  

  92.                                 Case $LVN_GETDISPINFOW

  93.                                         Local $tNMLVDISPINFO = DllStructCreate( $tagNMLVDISPINFO, $lParam )

  94.                                         If BitAND( DllStructGetData( $tNMLVDISPINFO, "Mask" ), $LVIF_TEXT ) Then

  95.                                                 Local $iIndex = DllStructGetData( $tNMLVDISPINFO, "Item" ) - $iFrom + 1

  96.                                                 If $iIndex > 0 And $iIndex < $iRows + 1 Then

  97.                                                         Local $sItem = $aResult[$iIndex][DllStructGetData($tNMLVDISPINFO,"SubItem")]

  98.                                                         DllStructSetData( $tText, 1, $sItem )

  99.                                                         DllStructSetData( $tNMLVDISPINFO, "Text", $pText )

  100.                                                         DllStructSetData( $tNMLVDISPINFO, "TextMax", StringLen( $sItem ) )

  101.                                                 EndIf

  102.                                         EndIf

  103.  

  104.                                 Case $LVN_ODCACHEHINT

  105.                                         Local $tNMLVCACHEHINT = DllStructCreate( $tagNMLVCACHEHINT, $lParam ), $iColumns

  106.                                         $iFrom = DllStructGetData( $tNMLVCACHEHINT, "iFrom" )

  107.                                         Local $sSQL = "SELECT * FROM lvdata WHERE item_id >= " & $iFrom & _

  108.                                                 " AND item_id <= " & DllStructGetData( $tNMLVCACHEHINT, "iTo" ) & ";"

  109.                                         _SQLite_GetTable2d( -1, $sSQL, $aResult, $iRows, $iColumns )

  110.  

  111.                         EndSwitch

  112.  

  113.         EndSwitch

  114.  

  115.         Return $GUI_RUNDEFMSG


  116.  

  117. Func CheckDB( $sDBname )

  118.         Local $aRow, $iRows = 0

  119.         If FileExists( $sDBname ) Then

  120.                 _SQLite_Open( $sDBname )

  121.                 _SQLite_QuerySingleRow( -1, "SELECT max(item_id) FROM lvdata;", $aRow )

  122.                 _SQLite_Close( -1 )

  123.         EndIf

  124.         If IsArray( $aRow ) Then _

  125.                 $iRows = $aRow[0] + 1

  126.         Return $iRows


  127.  

  128. Func Format( $iInt )

  129.         Return StringRegExpReplace( $iInt, "(\A\d{1,3}(?=(\d{3})+\z)|\d{3}(?=\d))", "\1," )


复制代码 高亮切换
附件: 您需要登录才可以下载或查看附件。没有帐号?加入

回复 1# kk_lee69



附件: 您需要登录才可以下载或查看附件。没有帐号?加入

TOP

最近一直用MYsql ,感觉很方便 。mssql还不会

TOP

既然這題 沒辦法改成 MSSQL  那有沒有人 可以 改變一下 不要一次取的一筆資料  我希望一次可以讀取一 百筆資料  當作緩衝呢???

TOP

回复 2# chzj589

就用SQL LISTE 好了 能否將範例中 每次讀取一筆到兩筆的緩衝   改成每次讀取100筆嗎??

TOP

回复 5# kk_lee69
你有看一下 CreateDB.au3吗?
範例程式,是读取三个数据库

Local $iRows1 = CheckDB( "Test1.db" )
Local $iRows2 = CheckDB( "Test2.db" )
Local $iRows3 = CheckDB( "Test3.db" )

数据库里有几笔,就读几笔,不是吗?

TOP

回复 6# chzj589

當然數據庫有幾筆 就讀取幾筆

但是這個虛擬表的概念是  先決定資料庫有 幾筆  假設有1萬筆 就先設定 有一萬筆資 料

然後  第一次 讀取 0-15 資料  往後 你往下滑一格  它就往後讀取資料庫裡面的下一筆資料

一次只讀取一筆  然後 你往上了 捲動了 就從資料庫裡 再往前 讀取 一筆 資料


我不要一次 只讀取一筆資料  這樣對資料庫來說  重複的讀取 負擔太重  
我希望一次 可以讀取 100筆資料

TOP

回复 7# kk_lee69
哪个範例程式?

TOP

回复 8# chzj589

就是上面的範例程式

TOP

回复 9# kk_lee69
不理解。
上面的範例程式历,不就是读取三个数据库?
我没安装SQL LISTE数据库编辑器,不知道建立的"Test1.db"是什么结构。

TOP

回复 10# chzj589

你沒有實際跑資料庫....你下載 資料庫3 就好  跟我的範例程式  放在一起

執行後  切換到 第三個 TAB  你就會知道

TOP

回复 11# kk_lee69
还是不理解,有什么不同

附件: 您需要登录才可以下载或查看附件。没有帐号?加入

TOP

本帖最后由 kk_lee69 于 2018-4-7 21:48 编辑

回复 12# chzj589

你有注意到
WM_NOTIFY 裡面的  $LVN_ODCACHEHINT 這個變化嗎??

你在 $LVN_ODCACHEHINT 下面 加上

ConsoleWrite($iFrom&" "&DllStructGetData( $tNMLVCACHEHINT, "iTo" )&@CRLF)

你就會看到  一開始是
0  15
15 16
16 17
17 18



你每按往下  它就會從資料庫裡面抓一筆資料出來
所以上面的程式 才能做到  資料庫裡面幾十萬筆資料  但是都不會卡頓
因為它一次  只抓一筆資料
附件: 您需要登录才可以下载或查看附件。没有帐号?加入

TOP

回复 13# kk_lee69
主要控制是这里:
                                Case $LVN_ODCACHEHINT
                                        Local $tNMLVCACHEHINT = DllStructCreate($tagNMLVCACHEHINT, $lParam), $iColumns
                                        $iFrom = DllStructGetData($tNMLVCACHEHINT, "iFrom")
                                        Local $sSQL = "SELECT * FROM lvdata WHERE item_id >= " & $iFrom & _
                                                        " AND item_id <= " & DllStructGetData($tNMLVCACHEHINT, "iTo") & ";"
                                        GUICtrlSendMsg($hLV, $LVM_DELETEALLITEMS, 0, 0)
                                        _SQLite_GetTable2d(-1, $sSQL, $aResult, $iRows, $iColumns)
                                        Local $iFromg = ConsoleWrite($iFrom & " " & DllStructGetData($tNMLVCACHEHINT, "iTo") & @CRLF)
;------------------------------------------------
_SQLite_GetTable2d
传递包含执行查询的列名和数据的 2 维数组.

#include <SQLite.au3>
_SQLite_GetTable2d ( $hDB, $sSQL, ByRef $aResult, ByRef $iRows, ByRef $iColumns [, $iCharSize = -1 [, $bSwichDimensions = False]] )

参 数
$hDB 打开的数据库, 如为 -1, 则使用最后打开的数据库
$sSQL 要执行的 SQL 语句
$aResult 传递的结果
$iRows 传递的数据行数
$iColumns 传递的列数
$iCharSize [可选] 指定数据字段的最大尺寸
$bSwichDimensions [可选] 切换 $aResult 尺寸

TOP

回复 14# chzj589
我的理解是本来己经全部读取,只是控制显示条目而己。
不知对不?

TOP

返回列表