Jump to content
Sign in to follow this  
FrancescoDiMuro

Creation of ListView Items takes a lot of time...

Recommended Posts

Good evening everyone :)
I am building a management for the company I work with, and I just imported a real amount of rows ( about 29000 ), in my SQLite DB.
The thing I am not understanding, is the time that the script takes to build this amount of rows in the ListView.
I didn't measure it, but I think it took 2 minutes or so to create each ListView item...
It is normal that it takes so much time?
What can I do to improve the creation of the items?

Here's the code I am using to query and to create ListView items...

; Articles ListView:
Global $lvwArticles = GUICtrlCreateListView("ID|Fornitore|Codice|Descrizione|EU|Prezzo|Sconto Applicato|Note", 14, 87, 1507, 660, BitOR($GUI_SS_DEFAULT_LISTVIEW,$LVS_SORTASCENDING,$LVS_SORTDESCENDING), BitOR($WS_EX_CLIENTEDGE,$LVS_EX_GRIDLINES,$LVS_EX_FULLROWSELECT))

; Query
$strQuery = "SELECT * FROM ARTICOLI;"

; Query Execution
_SQLite_GetTable2d($objDatabase, $strQuery, $arrResult, $intRows, $intColumns)
If @error Then
    ; Error Handling
Else
    ; Cleaning the ListView
    _GUICtrlListView_DeleteAllItems($lvwArticles)
    If @error Then
        ; Error Handling
    Else
        ; No records in the Table
        If UBound($arrResult) < 2 Then
            ; Error Handling
        Else
            _GUICtrlListView_BeginUpdate($lvwArticles)

            For $intCounter = 1 To UBound($arrResult) - 1

                $strListViewItem = $arrResult[$intCounter][0] & "|" & _
                                   $arrResult[$intCounter][1] & "|" & _
                                   $arrResult[$intCounter][2] & "|" & _
                                   $arrResult[$intCounter][3] & "|" & _
                                   $arrResult[$intCounter][4] & "|" & _
                                   $arrResult[$intCounter][5] & "|" & _
                                   $arrResult[$intCounter][6] & "|" & _
                                   $arrResult[$intCounter][7]

                $objListViewItem = GUICtrlCreateListViewItem($strListViewItem, $lvwArticles)
            Next

            _GUICtrlListView_EndUpdate($lvwArticles)

        EndIf
    EndIf
EndIf

Thanks in advance :)


Best Regards.


Click here to see my signature:

Spoiler

ALWAYS GOOD TO READ:

 

Share this post


Link to post
Share on other sites

@AutoBert

I didn't watch closely in the Help file!

Didn't know about that function :)

I will try that tomorrow, and I'll let you know :)

Thanks for the suggestion.

PS: How could I measure the time since I start to create ListView Items and when the last ListView Item is displayed? 

Just for curiosity :)

Thanks again!

 

Best Regards.


Click here to see my signature:

Spoiler

ALWAYS GOOD TO READ:

 

Share this post


Link to post
Share on other sites
2 hours ago, FrancescoDiMuro said:

PS: How could I measure the time since I start to create ListView Items and when the last ListView Item is displayed? 

The example _GUICtrlListView_AddArray.au3 show this too, using TimerInit and TimerDiff for this.

Share this post


Link to post
Share on other sites

To get an idea of how fast you can insert the rows in a listview, try displaying the array with _ArrayDisplay(). The code in _ArrayDisplay() is optimized code and It can probably not be done faster.

If it's not fast enough, then there is an ultimate solution. This solution consists of using a virtual listview. In a virtual listview, data is not inserted in the listview. Instead, the virtual listview reads data directly from the source. In this case either the array or the SQLite database.

Virtual listviews are fully and completely supported by AutoIt code.

To get an idea of how fast you can show the array in a virtual listview, try displaying the array with _ArrayDisplayEx().

There is also a function _SQLite_Display() that can display data from a SQLite database directly in a virtual listview. This function is very very fast. The total time spent reading the 29,000 rows from the database and displaying the first page in the listview will probably be less than one second.

Use this example to create your own virtual listview.

Share this post


Link to post
Share on other sites

@AutoBert Thanks for your suggestions :) I will check them tomorrow in the morning.

@LarsJ Wow! Didn't know anything about that... :) Let me take a look and bring you a feedback :)

Another little question ( for me you are like Masters in this programming language ): I'd like to improve my knowledge about AutoIt... Where can I take a look? 

Thanks! 

 

Best Regards.

 


Click here to see my signature:

Spoiler

ALWAYS GOOD TO READ:

 

Share this post


Link to post
Share on other sites

@AutoBert
Now it takes about 19 seconds to "fill" the ListView, but the "bug" is, that the ListView is not filled correctly, because, in the ListView, it is displayed only the first and the last element of the array.
I don't know why...


I'm going to see what kind of things are Virtual ListViews :)


Best Regards.


Click here to see my signature:

Spoiler

ALWAYS GOOD TO READ:

 

Share this post


Link to post
Share on other sites

And you remembered to check the input parameters for _GUICtrlListView_AddArray() in the help file?

Another little answer: You can take a look in the Microsoft documentation.

Share this post


Link to post
Share on other sites
27 minutes ago, LarsJ said:

And you remembered to check the input parameters for _GUICtrlListView_AddArray() in the help file?

Sure :)

Isn't a Result array from _SQLite_GetTable2() already formatted in that way ( as _GUICtrlListView_ArrayAdd requests )? :)

The Help file is my Guide :D

 

Best Regards.


Click here to see my signature:

Spoiler

ALWAYS GOOD TO READ:

 

Share this post


Link to post
Share on other sites

Yes, It's just a normal 2D array. And _GUICtrlListView_AddArray() is pretty simple code. And therefore it should work. And when simpel code isn't working, it should not be ignored. You have to investigate the problem.

Share this post


Link to post
Share on other sites

@LarsJ

I'll do some screenshot in order to let you see what is the issue I reported to AutoBert.

I didn't investigate on this, but If I use _SQLite_Display2DResult() or _ArrayDisplay, it works correctly.

Today, I spent my time studying on how Virtual ListView controls work, but, there were a lot information provided by your code, and not so much experience about that by my side.

So, I had to start from a previous step, or:

Since Virtual ListViews are created capturing WM_NOTIFY Windows Message, I had/have to understand how all Notification Codes and Structs and so on work.

So, I was asking where I can find those information.

I am 22 yo, with a big willingness to learn...

Every suggest is really appreciated.

Thanks again for your help :)

 

Best Regards.

Edited by FrancescoDiMuro

Click here to see my signature:

Spoiler

ALWAYS GOOD TO READ:

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By benners
      I am trying to normalise a database to remove duplicate info. I am using SQLite Expert to design the database and test sql queries.
      The database is going to store information about setup installers, such as paths, installer specific info, users to install for, type and category of installer blah, blah.
      I have attached the database thus far and the tables function are as follows:-
      category - stores text describing the general usage the installer comes under, such as Browser, Compression etc. installer - this is the main table that has relationships with the other tables and stores info about the installer file, install order etc. installer_user - a link table. Stores the user or computer to install the program for or on. package - stores the type of installer, NSIS, Inno  Nullsoft etc. platform - the OS architecture the installer file is compiled for. postinstall - a list of activities to perform when the main install has finished. postinstall_user - a link table. Stores the users\computers that are allowed to run the post install actions user - a list of computers or usernames. I might separate into two tables, undecided yet. Now there wil be one program that deals with the installation side and another that acts as a front end for editing the database suchs as adding new files, removing old files etc.
      The idea with the editing side is to be able to delete an installer from the installer table say with the id of 1 and all other pertinent information in the other tables will also be deleted. The same goes for deleting a user. All the fields relating to that user will be removed.
      I have managed to get that part working for the most part. If I delete either a user or installer, the related info in the installer_user and postinstall tables are removed but since I added the postinstall_user table to link usernames to the postinstall action, this is where I get the foreign key error. If someone can explain why, I am sure it is an obvious reason for someone who knows what they are doing 😄
      Cheers
      Installer - Copy.db
    • By UEZ
      This project has been discontinued!
       
      Here a small tool I wrote to update my Sysinternal tools collection without the need to download always the whole package or visiting the site to check for updates. I know that there are several tools available (also some tools written in AutoIt) but here another one for the collection. It was good exercise for me to code it.
       
       
        
       
       
      Some files from the live web site cannot be downloaded although they are visible!
       
      Here the download link of the source code only: AutoIt Sysinternal Tools Synchronizer v0.99.6 build 2020-09-23 beta.7z  (1557 downloads previously)
      -=> Requires AutoIt version 3.3.13.20 or higher / tested on Win8.1 real machine and some VMs: Win7 / Vista / Win10
       
      Compiled exe only: @MediaFire
       
      Just select the Sysinternal Tools folder or create one and press the synchronize button to download the selected items. Click on AutoIt label (near to left upper corner) to open menu.
       
      Special thanks to LarsJ, Melba23 and mesale0077 for their help. 
       
      I've still some ideas to implement which are more gimmick related, so it is not finished yet...
      If you want to add your language please check out #Region Language. Thanks. 
       
      Please report any bug or if you have any suggestions.
       
      The language of the tool tip from each of the executable in the left list view were automatically created using Google translator and weren't checked for correctness.
       
      Br,
      UEZ
    • By Cengokill
      Hi everyone,
      I have created a ListView that is in a tab, and I want to display an image in that tab, with the ListView on top.
      However, the image still appears on top of my ListView.
      If I remove the tabs everything works. 
      I looked at the autoit documentation and the <GuiListView.au3> documentation , I can't figure out how to display a background image, and put on top a ListView, inside a tab. 😥
      Here is the code:
      Opt("GUIOnEventMode", 1) $Form1 = GUICreate($Titre, 700, 627, $Form1Width, $Form1Height); main window $tabulation = GUICtrlCreateTab(148,0,700,580); creating tabs $tab1=GUICtrlCreateTabItem("Tab 1"); first tab GUICtrlSetState(-1, $GUI_SHOW); this tab is selected by default $Pic1 = GUICtrlCreatePic("image.jpg", 0, 30, 700, 627) GUICtrlSetState(-1, $GUI_DISABLE). $idListview = GUICtrlCreateListView("list 1|list 2|list 3", 200, 50, 390, 200) GUISetState(@SW_SHOW) While 1     Sleep(100) WEnd Thank you in advance.

    • By DrJohn
      Hello all.  It's me again.
      I've got a ListView with an associated ImageList to display icons.  What I seem to be hung up on is how to keep the ImageList updated to match the ListView as the latter changes.  I thought it was the case that the indices of the items in the ListView and those in the ImageList just needed to match.  So, for example, if I:
      Delete an item from the ListView [_GUICtrlListView_DeleteItem()], and also delete the image at the matching index in the ImageList [_GUIImageList_Remove()]. Then add a new item to the end of the ListView [_GUICtrlListView_AddItem()], and correspondingly add an image at the end of the ImageList [_GUIImageList_AddIcon()] Shouldn't everything stay in sync?
      Here's the code I thought would work:
      #include <GUIConstantsEx.au3> #include <GuiListView.au3> #include <FontConstants.au3> #include <WindowsConstants.au3> #include <GuiImageList.au3> Test() func Test() $gui = GUICreate("Test", 400, 300) ; Create ListView $lv = _GUICtrlListView_Create($gui, "", 10, 10, 380, 240, $LVS_DEFAULT) _GUICtrlListView_AddColumn($lv, "Col1", 50) _GUICtrlListView_AddColumn($lv, "Col2", 50) for $i = 0 to 2 $s = StringFormat("%d,1", $i+1) _GUICtrlListView_AddItem($lv, $s, $i) $s = StringFormat("%d,2", $i+1) _GUICtrlListView_AddSubItem($lv, $i, $s, 1) next ; Add ImageList $img_list = _GUIImageList_Create(16, 16, 5, 3) for $i = 0 to 2 $ico = StringFormat("%d.ico", $i+1) _GUIImageList_AddIcon($img_list, $ico) next _GUICtrlListView_SetImageList($lv, $img_list, 1) ; $btn = GUICtrlCreateButton("Test", 10, 260, 60, 30) GUISetState(@SW_SHOW) HotKeySet("^q", Quit) ; Loop until the user exits. while True switch GUIGetMsg() case $GUI_EVENT_CLOSE Exit case $btn ; Remove 2nd list item and image _GUICtrlListView_DeleteItem($lv, 1) _GUIImageList_Remove($img_list, 1) ; Add new item to end of ListView $idx = _GUICtrlListView_AddItem($lv, "foo") _GUICtrlListView_AddSubItem($lv, $idx, "bar", 1) ; Add new image to end of ImageList _GUIImageList_AddIcon($img_list, "5.ico") endswitch wend GUIDelete() endfunc func Quit() Exit endfunc What seems to happen is that when the new item is added to the ListView, its icon is 1.ico (the first item in the ImageList), rather than 5.ico (the newly added item that should be at the end of the ImageList).
      Or do I need to re-create the whole ImageList any time the ListView changes?
      A zip file is attached that contains the script and also the .ico files, for easier testing.
      Thanks!
      /John
      test.zip
    • By dmob
      So I am trying to implement an archive system of sorts for my (SQLite) DB app. I wrote a function to attach a separate (archive) DB and
      sync the columns with main DB. If archive DB file does not exist, create file with _SQLiteOpen then close the file (and thus connection) with SQLite_Close.
      This works as intended, however, after the create operation, all subsequent _SQLite_* functions returned a "Library misuse error".
      After a little digging I found the problem in the _SQLite_Close function: it clears the "last opened database" handle even when there still is a live
      DB connection open. All other functions then "think" there is no DB connection active. I hacked two functions in the UDF for a quick fix:

      In _SQLite_Close: Change
      ... $__g_hDB_SQLite = 0 __SQLite_hDel($__g_ahDBs_SQLite, $hDB) Return $iRval[0] to:
      $__g_hDB_SQLite = __SQLite_hDel($__g_ahDBs_SQLite, $hDB) Return $iRval[0] and in Func __SQLite_hDel changed
      Func __SQLite_hDel(ByRef $ahLists, $hGeneric) Local $iElement = _ArraySearch($ahLists, $hGeneric) If $iElement > 0 Then _ArrayDelete($ahLists, $iElement) EndFunc ;==>__SQLite_hDel to:
      Func __SQLite_hDel(ByRef $ahLists, $hGeneric) Local $iElement = _ArraySearch($ahLists, $hGeneric) If $iElement > 0 Then _ArrayDelete($ahLists, $iElement) Return $ahLists[UBound($ahLists)-1] ; Return last opened db EndIf Return 0 EndFunc ;==>__SQLite_hDel so it preserves last opened DB again.
       
      My archive function now works great
      I'm not sure if this should be classified as a bug, but I believe so...
      Hope this helps someone before
×
×
  • Create New...