Что нового

[Элементы GUI] _GUICtrlListView вывод таблицы SQLite массивом

WR-e-D

Новичок
Сообщения
53
Репутация
3
Собственно более подробно отписал в комментариях к коду.
Нужна помощь в выводе таблицы массивом, а не построчно.
Возможно не там искал, но решение своей проблемы не нашел :(
Заранее благодарю.

Код:
#include <GUIListBox.au3> 
#Include <GuiListView.au3> 
#include <SQLite.au3> 
#include <SQLite.dll.au3> 
#include <ButtonConstants.au3>
#include <ComboConstants.au3>
#include <DateTimeConstants.au3>
#include <ListViewConstants.au3>
#include <StaticConstants.au3>
#include <TabConstants.au3>
#include <WindowsConstants.au3>
#include <File.au3>
#include <GUIConstantsEx.au3>
#include <EditConstants.au3>
#include <GUIConstants.au3>
#include <GDIPlus.au3>
#include <String.au3>
#Include <WinAPI.au3>
#include <array.au3>
#include <Misc.au3>
#include <IE.au3>
#include <Date.au3>
;Совершаем вход
;...
#cs
Вот и добрался до SQLite
Предыдущую часть поставленной задачи какое как решил, но дальше мозг уже плавиться )
Эта часть кода соснифена с какогото из много численных просмотренных форумов, возможно даже с этого, вторые сутки мучаюсь)
Но так как знаниея в данной области еще скудны нуждаюсь в помощи )
#ce
;работа с базой
Opt('MustDeclareVars', 1) 
Opt("GUICloseOnESC", 0) 
Global $GUI_Form, $SQLite_Data_Path, $GUI_ListBox 
Global $GUI_Input1, $GUI_Input2, $GUI_Input3, $GUI_Input4, $GUI_Input5 
Global $GUI_Button1, $GUI_Button2, $GUI_Button3, $GUI_Button4 
Global $Msg, $hQuery, $aRow 
Global $Temp, $a, $b, $c 

$SQLite_Data_Path = "vgm2.db" 
_SQLite_Startup ()
If Not FileExists($SQLite_Data_Path) Then 
    SQLCreate() 
EndIf 
$GUI_Form = GUICreate("VG_Tools", 300, 435, -1, -1) 
GUISetBkColor(0xECE9D8) ; will change background color 
$GUI_ListBox = GUICtrlCreateListView("", 2, 2, 296, 309, 0x0010) 
_GUICtrlListView_AddColumn($GUI_ListBox, "№ Add", 100, 0) ;Колонки не суть позже добавлю соответственно с колонками базы
_GUICtrlListView_AddColumn($GUI_ListBox, "№ Del", 80, 1) 
_GUICtrlListView_AddColumn($GUI_ListBox, "Данные", 80, 1) 
GUICtrlCreateLabel("Добавляем эти данные в базу", 34, 325, 210, 15) 
$GUI_Input1 = GUICtrlCreateInput("", 10, 341, 73, 20) 
$GUI_Input2 = GUICtrlCreateInput("", 88, 341, 73, 20) 
$GUI_Input3 = GUICtrlCreateInput("", 166, 341, 73, 20) 
$GUI_Input4 = GUICtrlCreateInput("", 88, 366, 73, 20) 
$GUI_Input5 = GUICtrlCreateInput("", 88, 391, 73, 20) 
$GUI_Button1 = GUICtrlCreateButton("Читаем", 246, 315, 48, 22, 0) 
$GUI_Button2 = GUICtrlCreateButton("Добавь", 246, 340, 48, 22, 0) 
$GUI_Button3 = GUICtrlCreateButton("Исключ", 246, 365, 48, 22, 0) 
$GUI_Button4 = GUICtrlCreateButton("Удалить", 246, 390, 48, 22, 0) 
GUICtrlCreateGroup("", 2, 307, 296, 107) 
GUICtrlCreateLabel("Текст какой-то:43848058блин", 32, 419, 240, 15) 
GUICtrlSetState(-1, $GUI_DISABLE) 
GUISetState() 
While 1 
$Msg = GUIGetMsg() 
Select 
   Case $Msg = $GUI_EVENT_CLOSE 
             _SQLite_Shutdown ()
    ExitLoop 
   Case $Msg = $GUI_Button1 ;Функция чтения и вывода базы
    SQLiteRead() 
   Case $Msg = $GUI_Button2 ;Запись
                SQLiteInsert(GUICtrlRead ($GUI_Input1), GUICtrlRead ($GUI_Input2), GUICtrlRead ($GUI_Input3)) 
                SQLiteRead() 
   Case $Msg = $GUI_Button3 ;Фильтр
                SQLiteSelect(GUICtrlRead ($GUI_Input4)) 
   Case $Msg = $GUI_Button4 ;Удаление
    SQLiteDelete(GUICtrlRead ($GUI_Input5)) 
                SQLiteRead() 
EndSelect 
 
WEnd 
Func SQLCreate() ;Создаем базу и таблицы
    _SQLite_Open ($SQLite_Data_Path) 

_SQLite_Exec (-1, 'CREATE TABLE IF NOT EXISTS "tbMessages"([ID] varchar PRIMARY KEY UNIQUE NOT NULL,[StateIDC] INTEGER NOT NULL DEFAULT 0,[TypeIDC] INTEGER NOT NULL,[Read] INTEGER NOT NULL DEFAULT 0,[Deleted] INTEGER NOT NULL DEFAULT 0,[FlagIDC] INTEger,[Time] INTEGER NOT NULL,[From] varchar NOT NULL,[Subject] varchar NOT NULL,[Body] varchar,[Report] varchar);CREATE INDEX [idx_Messages_Deleted] ON [tbMessages] ([Deleted] ASC);CREATE INDEX [idx_Messages_Read] On [tbMessages] ([Read] );CREATE INDEX [idx_Messages_State] On [tbMessages] ([StateIDC] );CREATE INDEX [idx_Messages_Time] On [tbMessages] ([Time] );')
_SQLite_Exec (-1, 'CREATE TABLE IF NOT EXISTS "tbPlanets"([Coords] INTEGER PRIMARY KEY NOT NULL,[Name] varchar,[Allyance] varchar,[RankID] INTEGER REFERENCES [tbRanks] ([ID]) On Delete SET NULL On Update CASCADE,[VKontakteID] INTEGER,[Score] INTEGER,[Leave] INTEGER NOT NULL DEFAULT 0,[ResTitan] INTEGER,[ResSilicon] INTEGER,[ResAntimatery] INTEGER,[Energy] INTEGER,[OrbitTitan] INTEGER,[OrbitSilicon] INTEGER,[AttacksCount] INTEGER,[TitanLevel] INTEGER,[SiliconLevel] INTEGER,[AntimateryLevel] INTEGER,[MaxTemp] INTEGER,[Productivity] REAL,[AnnigReactorLevel] INTEGER,[PlanetScanLevel] integer,[BaseLevel] integer,[AttackLevel] INTEGER,[ShieldsLevel] INTEGER,[ArmourLevel] INTEGER,[BarionEngLevel] INTEGER,[AnnigilationEngLevel] INTEGER,[SubSpaceEngLevel] INTEGER,[Defence] varchar,[Fleet] varchar,[DefenceCostTitan] INTEGER,[DefenceCostSilicon] INTEGER,[FleetCostTitan] INTEGER,[FleetCostSilicon] INTEGER,[DefenceAttack] INTEGER,[FleetAttack] INTEGER,[FleetsInFlight] INTEGER,[MapDate] integer,[ReportDate] INTEGER,[FightDate] INTEGER,[Comment] varchar,[MyPlanet] INTEGER NOT NULL DEFAULT 0,[AutoRecalc] integer NOT NULL DEFAULT 1,[BGColor] varchar,[FontColor] varchar, CHECK(Leave IN (0, 1)), CHECK(Productivity BETWEEN 0.0 AND 1.0), CHECK(MyPlanet IN (0, 1)));CREATE INDEX [idx_Planets_Rank] On [tbPlanets] ([RankID] );CREATE INDEX [idx_Planets_MyPlanet] On [tbPlanets] ([MyPlanet] );CREATE UNIQUE INDEX [idx_Planets_Coords] On [tbPlanets] ([Coords] Collate BINARY ASC);')
_SQLite_Exec (-1, 'CREATE TABLE IF NOT EXISTS "tbRanks"([ID] INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL,[Title] varchar UNIQUE NOT NULL);')
_SQLite_Exec(-1, 'CREATE TABLE IF NOT EXISTS "tbReports"([ID] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,[Coords] INTEGER NOT NULL REFERENCES [tbPlanets] ([Coords]) On Delete CASCADE On Update RESTRICT,[Time] INTEGER NOT NULL,[TypeIDC] INTEGER NOT NULL,[Body] varchar NOT NULL);CREATE INDEX [idx_Reports_Type] ON [tbReports] ([TypeIDC]);CREATE INDEX [idx_tbRanks_Coords] On [tbReports] ([Coords] );')
_SQLite_Exec(-1, 'CREATE TABLE IF NOT EXISTS "tbUnits"([Coords] INTEGER NOT NULL REFERENCES [tbPlanets] ([Coords]) On Delete CASCADE On Update CASCADE,[VGID] INTEGER NOT NULL,[UnitCount] INTEger NOT NULL, Primary Key(VGID,Coords) , UNIQUE([VGID],[Coords]), CHECK(UnitCount > 0));CREATE INDEX [idx_Units_Coords] On [tbUnits] ([Coords] );') 	
_SQLite_Close () 
EndFunc 
Func SQLiteRead() ;Читаем
_GUICtrlListView_DeleteAllItems ( GUICtrlGetHandle ($GUI_ListBox) ) 
    _SQLite_Open ($SQLite_Data_Path) 
	
#cs
	
	И тут проблемы - вывод просиходит построчно (он как бы и нужен построчный для дальнейшего действия с каждой из строк, но допустим у меня база из 300к строк на это уйдет больше часа, поддерживает ли функция _GUICtrlListView вывод сразу массивом ?

#ce
    _SQLite_Query(-1, "SELECT * FROM tbPlanets ORDER BY Coords DESC;",$hQuery) 
	While _SQLite_FetchData ($hQuery, $aRow) = $SQLITE_OK 
        _GUICtrlListView_AddItem($GUI_ListBox, $aRow[0]) 
        _GUICtrlListView_AddSubItem($GUI_ListBox, _GUICtrlListView_FindInText($GUI_ListBox, $aRow[0]), $aRow[1], 1) 
        _GUICtrlListView_AddSubItem($GUI_ListBox, _GUICtrlListView_FindInText($GUI_ListBox, $aRow[0]), $aRow[2], 2) 
    WEnd 
    _SQLite_Close () 
EndFunc 

;Дальше пока мало важно
Func SQLiteInsert($a, $b, $c) 
    _SQLite_Open ($SQLite_Data_Path) 
_SQLite_QuerySingleRow(-1, "SELECT IDs FROM TestTable WHERE IDs = '" & $a & "';", $aRow) 
    $Temp = $aRow[0] 
If $Temp = "" Then 
_SQLite_Exec(-1, "Insert into TestTable (IDs) values ('" & $a & "');") 
EndIf 
_SQLite_Exec(-1, "UPDATE TestTable SET Name = '" & $b & "' WHERE IDs = '" & $a & "';") 
    _SQLite_Exec(-1, "UPDATE TestTable SET Age = '" & $c & "' WHERE IDs = '" & $a & "';") 
    _SQLite_Close () 
EndFunc 
Func SQLiteSelect($a) 
    _SQLite_Open ($SQLite_Data_Path) 
_SQLite_QuerySingleRow(-1, "SELECT * FROM TestTable WHERE Name = '" & $a & "';", $aRow) 
    $Temp = $aRow[0] 
If $Temp = "" Then 
MsgBox(262208, "Сообщение...", "Нет таких данных [" & $a & "] блин!") 
    Else 
_GUICtrlListView_DeleteAllItems ( GUICtrlGetHandle ($GUI_ListBox) ) 
        _GUICtrlListView_AddItem($GUI_ListBox, $aRow[0]) 
        _GUICtrlListView_AddSubItem($GUI_ListBox, _GUICtrlListView_FindInText($GUI_ListBox, $aRow[0]), $aRow[1], 1) 
        _GUICtrlListView_AddSubItem($GUI_ListBox, _GUICtrlListView_FindInText($GUI_ListBox, $aRow[0]), $aRow[2], 2) 
        MsgBox(262208, "Сообщение...", "Оставлено: 1=[" & $aRow[0] & "] 2=[" & $aRow[1] & "] 3=[" & $aRow[2] & "] !") 
EndIf 
    _SQLite_Close () 
EndFunc 
Func SQLiteDelete($a) 
    _SQLite_Open ($SQLite_Data_Path) 
    _SQLite_Exec(-1, "DELETE FROM TestTable WHERE Name = '" & $a & "';") 
    _SQLite_Close () 
MsgBox(262208, "Сообщение...", "Удаляем ячейку [" & $a & "] и обновляем данные в списке.") 
EndFunc
 

Redline

AutoIT Гуру
Сообщения
506
Репутация
375
Код:
While _SQLite_FetchData ($hQuery, $aRow) = $SQLITE_OK
        _GUICtrlListView_AddItem($GUI_ListBox, $aRow[0])
        _GUICtrlListView_AddSubItem($GUI_ListBox, _GUICtrlListView_FindInText($GUI_ListBox, $aRow[0]), $aRow[1], 1)
        _GUICtrlListView_AddSubItem($GUI_ListBox, _GUICtrlListView_FindInText($GUI_ListBox, $aRow[0]), $aRow[2], 2)
WEnd

От самого цикла избавиться здесь не выйдет, т.к. на выходе получен не массив, а сырые данные, которые нужно построчно обрабатывать через _SQLite_FetchData
Но в вашем случае можно ускорить вывод, если отказаться от _GUICtrlListView_AddItem, и сделать подобие этого:
Код:
#include <SQLite.au3>
_SQLite_Startup()
_SQLite_Open('c:\base.db')
Global $hQuery, $aR, $iRows, $iColumns

_SQLite_Query(-1, 'SELECT * FROM `tbl` LIMIT 5000;', $hQuery)

$hGUI = GUICreate('1', 1000, 800)

$hList = GUICtrlCreateListView('0|1|2|3|4|5', 0, 0, 1000, 800)

While _SQLite_FetchData ($hQuery, $aR) = $SQLITE_OK
	GUICtrlCreateListViewItem($aR[0] & '|' & $aR[1] & '|' & $aR[2] & '|' & $aR[3] & '|' & $aR[4] & '|' & $aR[5], $hList)
WEnd
GUISetState(@SW_SHOW)

While 1
	If GUIGetMsg() = -3 Then Exit
WEnd

или так:
Код:
#include <SQLite.au3>
_SQLite_Startup()
_SQLite_Open('c:\base.db')
Global $hQuery, $aR, $iRows, $iColumns

_SQLite_GetTable2d(-1, 'SELECT * FROM `tbl` LIMIT 5000;', $aR, $iRows, $iColumns)

$hGUI = GUICreate('1', 640, 480)

$hList = GUICtrlCreateListView('0|1|2|3|4|5', 0, 0, 640, 480)

For $i = 1 To UBound($aR) -1
	GUICtrlCreateListViewItem($aR[$i][0] & '|' & $aR[$i][1] & '|' & $aR[$i][2] & '|' & $aR[$i][3] & '|' & $aR[$i][4] & '|' & $aR[$i][5], $hList)
Next
GUISetState(@SW_SHOW)

While 1
	If GUIGetMsg() = -3 Then Exit
WEnd

По скорости скрипты почти одинаковы (первый на 4-5% быстрее), но в первом дольше происходит вывод из-за построчного fetch_data, а во втором дольше происходит запрос , т.к. на выходе получается готовый массив _SQLite_GetTable2d и его получение связано с fetch_data ;)

У меня вывод из 27 000 строк происходит за 52 секунды.

PS: выводить сразу 300 000 строк не советую, лучше организовать постраничный интерфейс с выводом 10 000 строк на странице через LIMIT.
 
Автор
WR-e-D

WR-e-D

Новичок
Сообщения
53
Репутация
3
Спасибо за помощь, решил проблемы немного другим способом из за недостатка времени, но в дальнейшем сного вернусь к переделке )
 
Верх