找回密码  加入

AUTOIT CN

搜索
查看: 1105|回复: 36

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

[复制链接]
发表于 2018-4-1 23:28:01 | 显示全部楼层 |阅读模式
本帖最后由 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. Opt( "MustDeclareVars", 1 )

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

  7. Global $hLV

  8. Example()


  9. Func Example()
  10.         _SQLite_Startup()

  11.         ; Check databases
  12.         Local $iRows1 = CheckDB( "Test1.db" )
  13.         Local $iRows2 = CheckDB( "Test2.db" )
  14.         Local $iRows3 = CheckDB( "Test3.db" )
  15.         Local $iRows

  16.         ; Create GUI
  17.         GUICreate( "Virtual ListViews", 850, 400 )

  18.         ; Create Tab
  19.         Local $idTab = GUICtrlCreateTab( 10, 10, 850-20, 400-20 )
  20.         GUICtrlCreateTabItem( "Test1.db: " & Format( $iRows1 ) & " rows" )
  21.         GUICtrlCreateTabItem( "Test2.db: " & Format( $iRows2 ) & " rows" )
  22.         GUICtrlCreateTabItem( "Test3.db: " & Format( $iRows3 ) & " rows" )
  23.         GUICtrlCreateTabItem( "" )

  24.         ; Create ListView
  25.         Local $idLV = GUICtrlCreateListView( "", 20, 40, 850-40, 400-60, $LVS_OWNERDATA, BitOR( $WS_EX_CLIENTEDGE, $LVS_EX_DOUBLEBUFFER, $LVS_EX_FULLROWSELECT ) )
  26.         $hLV = GUICtrlGetHandle( $idLV ) ;                               Virtual listview                          Reduces flicker
  27.         For $i = 0 To 9
  28.                 _GUICtrlListView_AddColumn( $hLV, "Col" & $i, 75 )
  29.         Next

  30.         GUIRegisterMsg( $WM_NOTIFY, "WM_NOTIFY" )
  31.         GUISetState( @SW_SHOW )

  32.         ; Data for first tab
  33.         $iRows = $iRows1
  34.         If $iRows Then _SQLite_Open( "Test1.db" )
  35.         GUICtrlSendMsg( $idLV, $LVM_SETITEMCOUNT, $iRows, 0 )

  36.         ; Message loop
  37.         While 1
  38.                 Switch GUIGetMsg()
  39.                         Case $idTab
  40.                                 If $iRows Then _SQLite_Close( -1 )
  41.                                 Switch GUICtrlRead( $idTab )
  42.                                         Case 0
  43.                                                 $iRows = $iRows1
  44.                                                 If $iRows Then _SQLite_Open( "Test1.db" )
  45.                                         Case 1
  46.                                                 $iRows = $iRows2
  47.                                                 If $iRows Then _SQLite_Open( "Test2.db" )
  48.                                         Case 2
  49.                                                 $iRows = $iRows3
  50.                                                 If $iRows Then _SQLite_Open( "Test3.db" )
  51.                                 EndSwitch
  52.                                 GUICtrlSendMsg( $idLV, $LVM_SETITEMCOUNT, $iRows, 0 )

  53.                         Case $GUI_EVENT_CLOSE
  54.                                 ExitLoop
  55.                 EndSwitch
  56.         WEnd

  57.         If $iRows Then _SQLite_Close( -1 )
  58.         _SQLite_Shutdown()
  59.         GUIDelete()
  60. EndFunc

  61. Func WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam )
  62.         Local Static $tText = DllStructCreate( "wchar[50]" )
  63.         Local Static $pText = DllStructGetPtr( $tText )
  64.         Local Static $aResult, $iRows, $iFrom

  65.         Local $tNMHDR, $hWndFrom, $iCode
  66.         $tNMHDR = DllStructCreate( $tagNMHDR, $lParam )
  67.         $hWndFrom = HWnd( DllStructGetData( $tNMHDR, "hWndFrom" ) )
  68.         $iCode = DllStructGetData( $tNMHDR, "Code" )

  69.         Switch $hWndFrom

  70.                 Case $hLV

  71.                         Switch $iCode

  72.                                 Case $LVN_GETDISPINFOW
  73.                                         Local $tNMLVDISPINFO = DllStructCreate( $tagNMLVDISPINFO, $lParam )
  74.                                         If BitAND( DllStructGetData( $tNMLVDISPINFO, "Mask" ), $LVIF_TEXT ) Then
  75.                                                 Local $iIndex = DllStructGetData( $tNMLVDISPINFO, "Item" ) - $iFrom + 1
  76.                                                 If $iIndex > 0 And $iIndex < $iRows + 1 Then
  77.                                                         Local $sItem = $aResult[$iIndex][DllStructGetData($tNMLVDISPINFO,"SubItem")]
  78.                                                         DllStructSetData( $tText, 1, $sItem )
  79.                                                         DllStructSetData( $tNMLVDISPINFO, "Text", $pText )
  80.                                                         DllStructSetData( $tNMLVDISPINFO, "TextMax", StringLen( $sItem ) )
  81.                                                 EndIf
  82.                                         EndIf

  83.                                 Case $LVN_ODCACHEHINT
  84.                                         Local $tNMLVCACHEHINT = DllStructCreate( $tagNMLVCACHEHINT, $lParam ), $iColumns
  85.                                         $iFrom = DllStructGetData( $tNMLVCACHEHINT, "iFrom" )
  86.                                         Local $sSQL = "SELECT * FROM lvdata WHERE item_id >= " & $iFrom & _
  87.                                                 " AND item_id <= " & DllStructGetData( $tNMLVCACHEHINT, "iTo" ) & ";"
  88.                                         _SQLite_GetTable2d( -1, $sSQL, $aResult, $iRows, $iColumns )

  89.                         EndSwitch

  90.         EndSwitch

  91.         Return $GUI_RUNDEFMSG
  92. EndFunc

  93. Func CheckDB( $sDBname )
  94.         Local $aRow, $iRows = 0
  95.         If FileExists( $sDBname ) Then
  96.                 _SQLite_Open( $sDBname )
  97.                 _SQLite_QuerySingleRow( -1, "SELECT max(item_id) FROM lvdata;", $aRow )
  98.                 _SQLite_Close( -1 )
  99.         EndIf
  100.         If IsArray( $aRow ) Then _
  101.                 $iRows = $aRow[0] + 1
  102.         Return $iRows
  103. EndFunc

  104. Func Format( $iInt )
  105.         Return StringRegExpReplace( $iInt, "(\A\d{1,3}(?=(\d{3})+\z)|\d{3}(?=\d))", "\1," )
  106. EndFunc
复制代码

本帖子中包含更多资源

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

x
发表于 2018-4-3 13:05:46 | 显示全部楼层
回复 1# kk_lee69



本帖子中包含更多资源

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

x
发表于 2018-4-3 16:14:33 | 显示全部楼层
最近一直用MYsql ,感觉很方便 。mssql还不会
 楼主| 发表于 2018-4-7 17:06:47 | 显示全部楼层
既然這題 沒辦法改成 MSSQL  那有沒有人 可以 改變一下 不要一次取的一筆資料  我希望一次可以讀取一 百筆資料  當作緩衝呢???
 楼主| 发表于 2018-4-7 17:32:32 | 显示全部楼层
回复 2# chzj589

就用SQL LISTE 好了 能否將範例中 每次讀取一筆到兩筆的緩衝   改成每次讀取100筆嗎??
发表于 2018-4-7 17:41:23 | 显示全部楼层
回复 5# kk_lee69
你有看一下 CreateDB.au3吗?
範例程式,是读取三个数据库

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

数据库里有几笔,就读几笔,不是吗?
 楼主| 发表于 2018-4-7 17:55:54 | 显示全部楼层
回复 6# chzj589

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

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

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

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


我不要一次 只讀取一筆資料  這樣對資料庫來說  重複的讀取 負擔太重  
我希望一次 可以讀取 100筆資料
发表于 2018-4-7 18:27:07 | 显示全部楼层
回复 7# kk_lee69
哪个範例程式?
 楼主| 发表于 2018-4-7 19:42:10 | 显示全部楼层
回复 8# chzj589

就是上面的範例程式
发表于 2018-4-7 20:24:23 | 显示全部楼层
回复 9# kk_lee69
不理解。
上面的範例程式历,不就是读取三个数据库?
我没安装SQL LISTE数据库编辑器,不知道建立的"Test1.db"是什么结构。
 楼主| 发表于 2018-4-7 20:43:02 | 显示全部楼层
回复 10# chzj589

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

執行後  切換到 第三個 TAB  你就會知道
发表于 2018-4-7 21:27:32 | 显示全部楼层
回复 11# kk_lee69
还是不理解,有什么不同

本帖子中包含更多资源

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

x
 楼主| 发表于 2018-4-7 21:44:59 | 显示全部楼层
本帖最后由 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



你每按往下  它就會從資料庫裡面抓一筆資料出來
所以上面的程式 才能做到  資料庫裡面幾十萬筆資料  但是都不會卡頓
因為它一次  只抓一筆資料

本帖子中包含更多资源

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

x
发表于 2018-4-8 09:34:24 | 显示全部楼层
回复 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 尺寸
发表于 2018-4-8 10:03:36 | 显示全部楼层
回复 14# chzj589
我的理解是本来己经全部读取,只是控制显示条目而己。
不知对不?
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|小黑屋|手机版|AUTOIT CN ( 鲁ICP备15028933号-3 )谷歌 百度

GMT+8, 2018-8-15 23:43 , Processed in 0.099095 second(s), 15 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表