Jump to content

array find


Queener
 Share

Go to solution Solved by kylomas,

Recommended Posts

ini file

[John]
ID=123
 
[James]
ID=234
 
[Jack]
ID=543

My code: (What my code does is, if $bArray[1]  or John is equal to whatever I type in $inputsearch2 (Used wildcard) then in $inputHost, it display $bArray[1] which is john. This method is used to do a search if the user exist. So if I search "hn" it will populate John because john has 'hn'.

 
                    ;-------------------------Array-----------------------;
            $aArray = IniReadSection($file, "John")
             If Not @error Then
        ; Enumerate through the array displaying the keys and their respective values.
        For $i = 1 To $aArray[0][0]
            $keys = IniRead($file, GUICtrlRead($InputHost), "ID", "")

            ;MsgBox($MB_SYSTEMMODAL, "", "Key: " & $aArray[$i][0] & @CRLF & "Value: " & $aArray[$i][1])
        Next

             EndIf

        $bArray = IniReadSectionNames($file)
        if not @error Then
            for $a = 1 to $bArray[0]
                    ;MsgBox($MB_SYSTEMMODAL, "", "Section: " & $bArray[$a])
                    ;MsgBox($MB_SYSTEMMODAL, "", "Section: " & $bArray[3])

            Next

    EndIf
;messagebox are used to do my testing purposes
;-----------------------------------------End of Array------------------------------------------
 
if StringRegExp($bArray[1], '(?i)' & GUICtrlRead($inputsearch2)) = 1 then
    GUICtrlSetData($InputHost, $bArray[1])
return
endif
return

My question is; Is there a better ways to search the ini file if it contain user I search for using wildcard and put that person name in the $inputhost so I don't have to write too many if statements. It's quite useless if I'm going to add users or delete users in the future.

So for example if one day I decided to delete Jack which leaves array down to 2.

if StringRegExp($bArray[3], '(?i)' & GUICtrlRead($inputsearch2)) = 1 then
    GUICtrlSetData($InputHost, $bArray[3])
return
endif

will populate an error of exceed array. Or if one day I decided to add a users; I would need to come back to this script and add another if statements just to search for the records that I just added which is time consuming...

Edited by asianqueen

Msgbox(0, "Hate", "Just hate it when I post a question and find my own answer after a couple tries. But if I don't post the question, I can't seem to resolve it at all.")
Link to comment
Share on other sites

  • Moderators

If you're needing to use wild card searches, date queries, or even conditional queries.  Then you're using the wrong type of storage file.

Not that it cannot be done, but you're going to lack proficiency as well as efficiency.

Please take a day or two and look at SQLite options in the help file.  You'll thank me for the suggestion when you have an understanding of all you can accomplish with it.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

  • Solution

asianqueen,

You are not really using any "wildcards" in your example.  You are using a partial pattern match however.

This will solve your problem with data dependency within the code...

#include <GUIConstantsEx.au3>
#include <array.au3>
#include <array.au3>
#include <GuiComboBox.au3>

#AutoIt3Wrapper_Add_Constants=n

local $inifile = @scriptdir & '\initest.ini'
local $aNames = IniReadSectionNames($inifile)   ;   read the section names to an array

local $gui010   =   guicreate('',170,150)
                    guictrlcreatelabel('Input Name', 20,20,100,20)
local $inp010   =   guictrlcreatecombo('',20,40,100,20)             ; use a combo box for more than 1 matching entry
local $Id       =   guictrlcreatelabel('',125,43,50,20)
local $btn010   =   guictrlcreatebutton('Find Name',20,120,130,20)

guisetstate()

while 1
    switch guigetmsg()
        case $gui_event_close
            Exit
        case $btn010
            _findname(guictrlread($inp010))
        case $inp010
            guictrlsetdata($Id,'ID = ' & inireadsection($inifile,guictrlread($inp010))[1][1])   ; populate ID field with selection change
    EndSwitch
WEnd

func _findname($sName)

    guictrlsetdata($Id,'')
    guictrlsetdata($inp010,'')

    for $1 = 1 to $aNames[0]
        if stringregexp($aNames[$1],'(?i)\Q' & $sName & '\E') then
            guictrlsetdata($inp010,$aNames[$1])
        endif
    next

    _GUICtrlComboBox_SetCurSel ( $inp010 , 0 )  ;   set edit box to 1st in list
    guictrlsetdata($Id,'ID = ' & inireadsection($inifile,guictrlread($inp010))[1][1])   ;   populate ID field

endfunc

I changed the input control to a combobox control so that multiple matching entries can be listed.  I added a display of the ID of the person currently selected.  This works for this simple example, however, like SmOke_N said, if you do want more sophisticated functionality SQLite is the way to go. 

Edited by kylomas

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Link to comment
Share on other sites

Thanks for the suggestion Smoke...

Once I'm done playing with this project, I'll play with sql and see the differences.

Thanks kylomas, that solves my headach... I was up trying different things and nothing came out right...

Msgbox(0, "Hate", "Just hate it when I post a question and find my own answer after a couple tries. But if I don't post the question, I can't seem to resolve it at all.")
Link to comment
Share on other sites

If you're interested this is a simple adaptation using SQLite...

#include <StaticConstants.au3>
#include <GUIConstantsEx.au3>
#include <array.au3>
#include <file.au3>
#include <sqlite.au3>
#include <GuiListView.au3>

; --------------------------------------------------------------------------------------------------------------------------------------

_SQLite_Startup()
Local $hDB = _SQLite_Open(@ScriptDir & '\INI.DB3')
If Not $hDB Then _fini()
OnAutoItExitRegister('_fini')
ConsoleWrite("_SQLite_LibVersion=" & _SQLite_LibVersion() & @CRLF)

If Not table_exists('Users') Then
    Local $ret = _SQLite_Exec(-1, 'CREATE TABLE [Users] ([UNAME], [UID]); ' & _
            'CREATE UNIQUE INDEX [IDX_UNAME_UID] ON [Users] ([UNAME], [UID]);')

    If $ret <> $SQLITE_OK Then Exit (MsgBox(0, 'SQLITE ERROR', '[USERS] Create Table Failed'))
    ConsoleWrite('Table USERS Created' & @CRLF)
EndIf

; --------------------------------------------------------------------------------------------------------------------------------------

#AutoIt3Wrapper_Add_Constants=n

local $gui010 = guicreate('User Management', 400,270)
local $aSize  = wingetclientsize($gui010)
local $lst010 = guictrlcreatelistview('User|ID',10, 30, 190, 200)
                _GUICtrlListView_SetColumnWidth($lst010,0,140)
                _GUICtrlListView_SetColumnWidth($lst010,1,50)
                guictrlcreategroup('Add User / ID',225,25, 160, 200)
                guictrlcreatelabel('Name',240,55,130,20)
local $userin = guictrlcreateinput('',240,70,130,20)
                guictrlcreatelabel('ID',240,105,50,20)
local $idin   = guictrlcreateinput('',240,120,50,20)
local $status = guictrlcreatelabel('',240,160,130,20)
                guictrlsetcolor($status,0xff0000)
local $add010 = guictrlcreatebutton('Add User',240,190,130,20)
local $del010 = guictrlcreatebutton('Delete Selected',40,240,130,20)

guisetstate()

_populate_listview()

while 1
    switch guigetmsg()
        case $gui_event_close
            Exit
        case $add010
            _add( guictrlread($userin),guictrlread($idin) )
        case $del010
            _del( guictrlread(guictrlread($lst010)) )
    EndSwitch
WEnd

func _add($name, $id)

    guictrlsetdata($status,'')

    if $name = '' or $id = '' then
        guictrlsetdata($status, 'Name and ID Required')
        Return
    endif

    local $arow
    _SQLite_QuerySingleRow($hDB,'select * from Users where uname = ' & _sqlite_fastescape($name) & _
        ' and uid = ' & _SQLite_FastEscape($id) & ';', $arow)
    if $arow[0] <> '' then
        guictrlsetdata($status,'Entry Exists')
        Return
    endif

    if _SQLite_Exec($hDB,'insert into Users values (' & _sqlite_fastescape($name) & ',' & _sqlite_fastescape($id) & ');') = $sqlite_ok then
        guictrlsetdata($status, 'User Added')
        _populate_listview()
        Return
    endif

endfunc

func _del($usr)

    ConsoleWrite($usr & @CRLF)

    _sqlite_exec($hDB,'Delete from Users where uName = ' & _
        _SQLite_FastEscape(stringsplit($usr,'|',2)[0]) & _
        ' and UID = ' & _
        _SQLite_FastEscape(stringsplit($usr,'|',2)[1]) & _
        ';')

    _GUICtrlListView_DeleteItemsSelected ( $lst010 )

endfunc

func _populate_listview()

    _GUICtrlListView_DeleteAllItems($lst010)

    local $aRows, $irows, $icols
    _SQLite_GetTable2d($hDB,'select * from Users',$aRows, $irows, $icols)

    for $1 = 1 to ubound($aRows) - 1
        guictrlcreatelistviewitem($aRows[$1][0] & '|' & $aRows[$1][1], $LST010)
    next

endfunc

Func _fini()
    ConsoleWrite('Total changes made = ' & _SQLite_TotalChanges($hDB) & @CRLF)
    _SQLite_Close($hDB)
    _SQLite_Shutdown()
    Exit
EndFunc   ;==>_fini

Func table_exists($tbl)
    Local $rows, $nbrows, $nbcols, $ret
    $ret = _SQLite_GetTable2d(-1, "select * from sqlite_master where name = " & "'" & $tbl & "';", $rows, $nbrows, $nbcols)
    Return ($nbrows > 0) ? True : False
EndFunc   ;==>table_exists

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Link to comment
Share on other sites

kylomas,

Thanks for the sql sample. Keep it live. Will need it soon.

---

The example you posted for the ini; I'm getting error on line

    guictrlsetdata($inputid,'ID = ' & inireadsection($inifile,guictrlread($inputsearch2))[1][1])   ;   populate ID field

If the user is not found.

Error:

(42) : ==> Subscript used on non-accessible variable.:
guictrlsetdata($inputid,'ID = ' & inireadsection($inifile,guictrlread($inputsearch2))[1][1])
guictrlsetdata($inputid,'ID = ' & inireadsection($inifile,guictrlread($inputsearch2))^ ERROR
Edited by asianqueen

Msgbox(0, "Hate", "Just hate it when I post a question and find my own answer after a couple tries. But if I don't post the question, I can't seem to resolve it at all.")
Link to comment
Share on other sites

asianqueen,

This should work better.  Added switch for no hit in ini file...

No need for a switch...

#include <GUIConstantsEx.au3>
#include <array.au3>
#include <array.au3>
#include <GuiComboBox.au3>

#AutoIt3Wrapper_Add_Constants=n

local $inifile = @scriptdir & '\ininametest.ini'
local $aNames = IniReadSectionNames($inifile)   ;   read the section names to an array

local $gui010   =   guicreate('',170,150)
                    guictrlcreatelabel('Input Name', 20,20,100,20)
local $inp010   =   guictrlcreatecombo('',20,40,100,20)             ; use a combo box for more than 1 matching entry
local $Id       =   guictrlcreatelabel('',125,43,50,20)
local $btn010   =   guictrlcreatebutton('Find Name',20,120,130,20)

guisetstate()

while 1
    switch guigetmsg()
        case $gui_event_close
            Exit
        case $btn010
            _findname(guictrlread($inp010))
        case $inp010
            guictrlsetdata($Id,'ID = ' & inireadsection($inifile,guictrlread($inp010))[1][1])   ; populate ID field with selection change
    EndSwitch
WEnd

func _findname($sName)

    guictrlsetdata($Id,'')
    guictrlsetdata($inp010,'')

    for $1 = 1 to $aNames[0]
        if stringregexp($aNames[$1],'(?i)\Q' & $sName & '\E') then
            guictrlsetdata($inp010,$aNames[$1])
            _GUICtrlComboBox_SetCurSel ( $inp010 , 0 )  ;   set edit box to 1st in list
            guictrlsetdata($Id,'ID = ' & inireadsection($inifile,guictrlread($inp010))[1][1])   ;   populate ID field
        endif
    next

endfunc

edit: modified code

Edited by kylomas

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Link to comment
Share on other sites

  • Moderators

The above solution only works if the ini is supposed to be static.

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

other words, you means if you change/modify the ini while this script is running then it'll crash? Anyways can we do a real-time reading the ini file?

Edited by asianqueen

Msgbox(0, "Hate", "Just hate it when I post a question and find my own answer after a couple tries. But if I don't post the question, I can't seem to resolve it at all.")
Link to comment
Share on other sites

  • Moderators

Did you try? That's what kylomas's comment in post 11 was about.  A hint is, it's a simple 1 liner in the function.

Edit:

Well, 2 lines if you add error checking, should always add error checking ;)

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...