Jump to content
Sign in to follow this  
JLogan3o13

[Solved] Looking for a more efficient way to populate 2D array

Recommended Posts

JLogan3o13

I have been working on a project that pulls information from a sql database (Microsoft SCCM), and then presents a GUI to the end user to manipulate that data. On startup, the application pulls a list of collections of computers the user has access to. Currently I pull in a web report, save it as a .csv, and then convert the sheet to a 2d array. This works very well, but is a bit cumbersome. It adds 5-10 seconds onto the startup, which to the end user seems to be a lag, since I cannot create the GUI until this array is created.

I can query the database directly, and get the same information far more quickly in just a few lines of code (see below). I'm just unsure how to easily convert this into a 2d array any other way than the Excel trick I am using above. From the Help file, _ArrayAdd is for a 1D array only. Am I overlooking something obvious, or is the Excel method the best option?

I can easily pull the query, and use the $element.Name and $element.CollectionID properties, but would like to have them in an Array for use in the rest of the application.

$sServer = "SCCMP02"
$SCode = "P02"

$oLocator = ObjCreate("WbemScripting.SWbemLocator")
Global $oSMS = $oLocator.ConnectServer($sServer, "root\sms\site_" & $SCode)
If @error Then MsgBox(0, "", "Can't Connect")
$oSMS.Security_.ImpersonationLevel = 3
$oSMS.Security_.AuthenticationLevel = 6
$oResults = $oSMS.ExecQuery("SELECT * FROM SMS_Collection WHERE Comment LIKE '%Site License%' ORDER by Name")

For $element In $oResults
  $name = $element.Name
  $colID = $element.CollectionID
  MsgBox(0, $name, $colID)
Next
Edited by JLogan3o13

√-1 2^3 ∑ π, and it was delicious!

Share this post


Link to post
Share on other sites
water

Maybe something like this? I'm not sure if the name of the property where the recordcount is stored is count or recordcount

#include <Array.au3>
$sServer = "SCCMP02"
$SCode = "P02"

Global $oLocator = ObjCreate("WbemScripting.SWbemLocator")
Global $oSMS = $oLocator.ConnectServer($sServer, "root\sms\site_" & $SCode)
If @error Then MsgBox(0, "", "Can't Connect")
$oSMS.Security_.ImpersonationLevel = 3
$oSMS.Security_.AuthenticationLevel = 6
$oResults = $oSMS.ExecQuery("SELECT * FROM SMS_Collection WHERE Comment LIKE '%Site License%' ORDER by Name")

Global $aResult[$oResults.Count][2]
Global $iIndex = 1
For $element In $oResults
  $aResult[$iIndex][0] = $element.Name
  $aResult[$iIndex][1] = $element.CollectionID
Next
_ArrayDisplay($aResult)


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-01-27 - Version 1.3.3.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
JLogan3o13

Hi, Water. Thanks as always for the great suggestion. I tweaked what you have above just a little, and it is now displaying the array. Unfortunately, it displays only the last item in the array. I figure I have to find a way to increments the $iIndex variable but receive an error about the array dimensions being exceeded. Guess I'll be brushing up on UBound ;) Thanks again for the nudge in the right direction.

#include <Array.au3>
Local $oResults
$sServer = "SCCMP02"
$SCode = "P02"

$oLocator = ObjCreate("WbemScripting.SWbemLocator")
Global $oSMS = $oLocator.ConnectServer($sServer, "rootsmssite_" & $SCode)
If @error Then MsgBox(0, "", "Can't Connect")
$oSMS.Security_.ImpersonationLevel = 3
$oSMS.Security_.AuthenticationLevel = 6

$oResults = $oSMS.ExecQuery("SELECT * FROM SMS_Collection WHERE Comment LIKE '%Site License%' ORDER by Name")

Global $aResult[$oResults.Count][2]
Global $iIndex = 1

For $element In $oResults
   $name = $element.Name
   $col = $element.CollectionID
   $aResult[$iIndex][0] = $name
   $aResult[$iIndex][1] = $col
Next

_ArrayDisplay($aResult)

√-1 2^3 ∑ π, and it was delicious!

Share this post


Link to post
Share on other sites
water

My bad ;) The counter has to be incremented

#include <Array.au3>

$sServer = "SCCMP02"
$SCode = "P02"

Global $oLocator = ObjCreate("WbemScripting.SWbemLocator")
Global $oSMS = $oLocator.ConnectServer($sServer, "rootsmssite_" & $SCode)
If @error Then Exit MsgBox(0, "Error", "Can't Connect")
$oSMS.Security_.ImpersonationLevel = 3
$oSMS.Security_.AuthenticationLevel = 6

Global $oResults = $oSMS.ExecQuery("SELECT * FROM SMS_Collection WHERE Comment LIKE '%Site License%' ORDER by Name")

Global $aResult[$oResults.Count][2]
Global $iIndex = 0

For $element In $oResults
   $aResult[$iIndex][0] = $element.Name
   $aResult[$iIndex][1] = $element.CollectionID
   $iIndex += 1
Next

_ArrayDisplay($aResult)
N.B. When an error occurres when connecting to the server I would exit the script because the following object related statements will crash. Edited by water

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-01-27 - Version 1.3.3.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
JLogan3o13

I knew what you meant ;) I actually tried the same thing, but I get the error $aResult[$iIndex][0] = $name >> "Array varuable has incorrect number of subscripts or subscript dimension range exceeded". I am thinking I would have to loop through it somehow in order to increment $iIndex. I tried this, but it just takes the last element in the array and puts it on every line. I just have to figure out how to loop through the elements in $oResults outside the second For loop.

#include <Array.au3>
Local $oResults
$sServer = "SCCMP02"
$SCode = "P02"

$oLocator = ObjCreate("WbemScripting.SWbemLocator")
Global $oSMS = $oLocator.ConnectServer($sServer, "rootsmssite_" & $SCode)
If @error Then MsgBox(0, "", "Can't Connect")
$oSMS.Security_.ImpersonationLevel = 3
$oSMS.Security_.AuthenticationLevel = 6
$oResults = $oSMS.ExecQuery("SELECT * FROM SMS_Collection WHERE Comment LIKE '%Site License%' ORDER by Name")
 
Global $aResult[$oResults.Count][2]
Global $iIndex = 1
 
For $element In $oResults
   For $x = 1 To UBound($aResult) - 1
     $name = $element.Name
     $col = $element.CollectionID
     $aResult[$iIndex][0] = $name
     $aResult[$iIndex][1] = $col
   Next
Next

_ArrayDisplay($aResult)

Counts the number of elements correctly (124), but produces this on every line:

[0]||
[1]|WoundPath Shortcut 1.0|P020009F
[2]|WoundPath Shortcut 1.0|P020009F
[3]|WoundPath Shortcut 1.0|P020009F
[4]|WoundPath Shortcut 1.0|P020009F
[5]|WoundPath Shortcut 1.0|P020009F
[6]|WoundPath Shortcut 1.0|P020009F
[7]|WoundPath Shortcut 1.0|P020009F
[8]|WoundPath Shortcut 1.0|P020009F
[9]|WoundPath Shortcut 1.0|P020009F
[10]|WoundPath Shortcut 1.0|P020009F
[11]|WoundPath Shortcut 1.0|P020009F
[12]|WoundPath Shortcut 1.0|P020009F
[13]|WoundPath Shortcut 1.0|P020009F
[14]|WoundPath Shortcut 1.0|P020009F
[15]|WoundPath Shortcut 1.0|P020009F
[16]|WoundPath Shortcut 1.0|P020009F
[17]|WoundPath Shortcut 1.0|P020009F
[18]|WoundPath Shortcut 1.0|P020009F
[19]|WoundPath Shortcut 1.0|P020009F
Edited by JLogan3o13

√-1 2^3 ∑ π, and it was delicious!

Share this post


Link to post
Share on other sites
water

Pleas test the (modified) code I posted above again. The index has to start with 0 not with 1 as we don't have the index in "row" 0 of the array.

Edited by water

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-01-27 - Version 1.3.3.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
JLogan3o13

D'oh! My turn ;) . That works perfectly. Thanks a ton, just cut my startup time in half with this.


√-1 2^3 ∑ π, and it was delicious!

Share this post


Link to post
Share on other sites
water

To make it (a bit) faster you can remove the unneccessary assigns (above code modified again) and alter the counter incrementing.


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-01-27 - Version 1.3.3.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
JLogan3o13

Thanks again, that helped more than I would have thought. From 5-10 seconds I'm down to less than 2 for launching the app. I'm sure the end users will appreciate that.


√-1 2^3 ∑ π, and it was delicious!

Share this post


Link to post
Share on other sites
water

Tell them to throw coffee, beer and wine at you if they are happy with the result ;)


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-01-27 - Version 1.3.3.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
guinness

Tell them to throw coffee, beer and wine at you if they are happy with the result ;)

That's going to hurt!

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

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  

  • Similar Content

    • TrashBoat
      By TrashBoat
      So Im trying to make a simple 2d game and make some sort of collision detection so why not to make a 2 dimensional array but i have no clue how  to write it in multiple lines
      Global $map[5,5] = [0,0,0,0,0 _ [0,0,0,0,0 _ [0,0,0,0,0 _ [0,0,0,0,0 _ [0,0,0,0,0] something like this but it doesn't work
    • Zein
      By Zein
      #include "..\Include\Array.au3" #include "..\Include\File.au3" #include "..\Include\AutoItConstants.au3" Local $aRetArray Local $sFilePath = "n.csv" _FileReadToArray($sFilePath, $aRetArray, ",") ; _FileReadToArray($sFilePath, $aRetArray, $FRTA_COUNT, ",") _ArrayDisplay($aRetArray, "Original", Default, 8) The above code shows two versions of _FileReadToArray and both don't work as expected.
      The first one doesn't use the comma as a delimiter. (so I get a single column array)  I tried adding "Default" between $aRetArray and "," then it told me it had an incorrect number of parameters. 

      I looked again at the documentation:
       
      #include <File.au3> _FileReadToArray ( $sFilePath, ByRef $vReturn [, $iFlags = $FRTA_COUNT [, $sDelimiter = ""]] )
      And I with or without the flags params I should be getting a 2D array due to my file being a csv. 
      I then tried a regular flag, $FRTA_COUNT, and it tells me that I'm using a variable $FRTA_COUNT while it's not declared. Tried putting in 1 instead and it told me again, incorrect number of params. 

       
    • ternal
      By ternal
      Hi,
      Recently I have had the need to do a sort and then do a second sort while the item of the first sort stays the same ( double sorting , first on column x then while column x is the same sort column y).
      I did not put much efffort into error checking but so far I did not need it.
      For my applications so far it works perfectly however if someone is willing I want to test this extensivly.
      If anyone has big lists of random stuff to sort could you try this out please?
      #include <Array.au3> ; #FUNCTION# ==================================================================================================================== ; Name ..........: _ArraySort_Double ; Description ...: ; Syntax ........: _ArraySort_Double (Byref $array[, $first_index = Default[, $second_index = Default[, $ascending = Default]]]) ; Parameters ....: $array - 2d array to sort. ; $first_index - [optional] first column to sort. Default is 0. ; $second_index - [optional] second column to sort. Default is 1. ; $ascending - [optional] ascending/descending. Default is 1. ; Return values .: 1 if no errors occured , -1 if errors occured ; Author ........: Ternal ; Remarks .......: Needs excessive testing. ; Related .......: _arraysort() ; =============================================================================================================================== Func _ArraySort_Double (byref $array, $first_index = Default, $second_index = Default, $ascending = Default) Local $temp_value Local $counter = 1 If UBound($array, $UBOUND_DIMENSIONS) <> 2 Then MsgBox(0, "error", "error") return -1 EndIf If $first_index = Default Then $first_index = 0 If $second_index = Default Then $second_index = 1 If $ascending = Default Then $ascending = 1 _ArraySort($array, $ascending, 0, 0, $first_index); you can alter settings of primary sort here If @error Then MsgBox(0, "error", @error) return -1 EndIf $temp_value = $array[0][$first_index] For $x = 1 to UBound($array, 1) - 1 If Mod( $x, 10000) = 0 Then ConsoleWrite("at " & $x & " of a total : " & UBound($array, 1) & @CRLF) If $array[$x][$first_index] = $temp_value Then $counter+= 1 If $x = UBound($array, 1) - 1 Then; do last line here(if last line is not a new item) _ArraySort($array, $ascending, $x - $counter, $x, $second_index);you can alter settings of secondary sort here(don't forget to place line 34 the exact same) If @error Then MsgBox(0, "error", @error) return -1 EndIf EndIf Else If $counter > 0 Then ;at least 2 of the same _ArraySort($array, $ascending, $x - $counter, $x - 1, $second_index);you can alter settings of secondary sort here(don't forget to place line 29 the exact same) If @error Then MsgBox(0, "error", @error) return -1 EndIf $counter = 1 EndIf EndIf $temp_value = $array[$x][$first_index] Next Return 1 EndFunc Kind regards, Ternal
    • TrashBoat
      By TrashBoat
      So I've made this script that detects how long i have held down my left mouse button for and stores the information in an array and then sorts its using _ArraySort but the output is half sorted half broken.
      Here's my script:
      HotKeySet("{F1}","_exit") #include <Misc.au3> #include <Timers.au3> #include <Array.au3> Local $dll = DllOpen("user32.dll") $on = False Global $array[0] While(1) If _IsPressed(01,$dll) Then $timer = _Timer_Init() While _IsPressed(01,$dll) Sleep(1) WEnd $time = _Timer_Diff($timer) _ArrayAdd($array,"Time: " & Floor($time) & " ms") ;~ ConsoleWrite("Time: " & Floor($time) & " ms" & @CRLF) EndIf Sleep(50) WEnd Func _exit() _ArraySort($array) _ArrayDisplay($array) Exit EndFunc And the output:

      See how its not sorted?  What is the problem here?
    • MrCheese
      By MrCheese
      Hi guys,
      See attached for an array example.
      to simplify what i want to achieve,  I want to split this array into 9 different csv files.
      the first file would contain the list of "key" and the corresponding "ID1", the second would have "key" and the "ID2", the third would have "key" and "ID3"
      However, I want to remove all the rows that don't have an ID recorded in the respective ID2, ID3 4...5...6 etc, so the file only contains row items with a key and the ID.
      Would be the best way to loop through the rows and delete the row if the array field is blank - would I then need to repeat that row ID to check that the row that its replaced is also empty (ie the one after the one I just deleted)? I see this getting messy.
      or _arraySort, and delete everything below the last filled row? <-- this might be best?
      Or should I use the excel UDF, apply a filter (not selecting the blanks), then create/export to the array->csv?
       
      Super keen to hear your thoughts.
      thanks!
       
       
       
       
      IDArray.csv
×