Jump to content

problem that repeats the same name when saving in txt


Go to solution Solved by pixelsearch,

Recommended Posts

Posted (edited)

Hello, I hope you can help me with this problem.

in which it repeats the same name when saving it in the test.txt.

 

#include <GuiConstantsEx.au3> 
#include <GuiListView.au3> 


$hGUI = GUICreate("Prueba", 800, 600) 

$hListView = GUICtrlCreateListView("#|Nombre del programa|", 10, 10, 680, 100) 

_GuiCtrlListView_SetColumnWidth($hListView,0,35) 
_GuiCtrlListView_SetColumnWidth($hListView,1,300) 


$OkButton = GUICtrlCreateButton("Aceptar", 50, 170, 75, 23) 

$AddButton = GUICtrlCreateButton("Agregar nueva ruta", 130, 170, 75, 23) 

$RemButton = GUICtrlCreateButton("Eliminar", 210, 170, 75, 23) 


GUISetState(@SW_SHOW, $hGUI) 

_FillList(@ScriptDir & "\test.txt") 

Mientras 1 
    $msg = GUIGetMsg(1) 
    Cambiar $msg[0] 
        Caso $GUI_EVENT_CLOSE 

                Salir 

        Caso $OkButton 
            $sData = "" 

            Para $i = 0 Hasta _GUICtrlListView_GetItemCount($hListView) - 1 
                $sData &= _GUICtrlListView_GetItemText($hListView, $i, 1) & @CRLF 

            Siguiente 

            $hFile = FileOpen(@ScriptDir & "\test.txt", 2) 
            FileWrite($hFile, $sData) 
            FileClose($hFile) 
            Salir 


        Caso $AddButton 
             $sFile = FileOpenDialog(@SCRIPTNAME,@WORKINGDIR,"(*.exe)") 

            Si $sFile = "" Entonces ContinueCase 
            $sFile = StringRegExpReplace($sFile, "^.*\\", "") 

            GUICtrlCreateListViewItem(_GUICtrlListView_GetItemCount($hListView) + 1 & "|" & $sFile , $hListView) 


        Caso $RemButton 
            _GUICtrlListView_DeleteItemsSelected($hListView) 

    FinCambiar 
WEnd 

Func _FillList($sFile) 
    Local $iRead = FileRead($sFile) 
    Local $aString = StringSplit(StringStripCR($iRead), @LF) 

    Para $i = 1 Hasta $aString[0] 
        Si $aString[$i] = "" Entonces ContinuarBucle 
        GUICtrlCreateListViewItem($i & "|" & StringRegExpReplace($aString[$i], "^.*\\", "") , $hListView) 

    Siguiente 
FinFunc

 

Edited by angel83
  • Developers
Posted (edited)

That script is full of syntax errors!  did you use some sort of translator from English to Spanish before posting?
Please try to use au3check and make a valid script first. 🙂 

Edited by Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Posted

If it was apparently translated into Spanish with the browser, I'm sorry. 
thank you jos
 who is in english

#include <GuiConstantsEx.au3>
#include <GuiListView.au3>


$hGUI = GUICreate("Test", 800, 600)

$hListView = GUICtrlCreateListView("#|Program name|", 10, 10, 680, 100)

_GuiCtrlListView_SetColumnWidth($hListView,0,35)
_GuiCtrlListView_SetColumnWidth($hListView,1,300)


$OkButton = GUICtrlCreateButton("Ok", 50, 170, 75, 23)

$AddButton = GUICtrlCreateButton("Add new path", 130, 170, 75, 23)

$RemButton = GUICtrlCreateButton("Remove", 210, 170, 75, 23)


GUISetState(@SW_SHOW, $hGUI)

_FillList(@ScriptDir & "\test.ini")

While 1
    $msg = GUIGetMsg(1)
    Switch $msg[0]
        Case $GUI_EVENT_CLOSE

                Exit

        Case $OkButton
            $sData = ""

            For $i = 0 To _GUICtrlListView_GetItemCount($hListView) - 1
                $sData &= _GUICtrlListView_GetItemText($hListView, $i, 1)  & @CRLF

            Next

            $hFile = FileOpen(@ScriptDir & "\test.ini", 2)
            FileWrite($hFile, $sData)
            FileClose($hFile)
            Exit


        Case $AddButton
             $sFile = FileOpenDialog(@SCRIPTNAME,@WORKINGDIR,"(*.exe)")

            If $sFile = "" Then ContinueCase
            $sFile = StringRegExpReplace($sFile, "^.*\\", "")

            GUICtrlCreateListViewItem(_GUICtrlListView_GetItemCount($hListView) + 1 & "|" & $sFile , $hListView)


        Case $RemButton
            _GUICtrlListView_DeleteItemsSelected($hListView)

    EndSwitch
WEnd

Func _FillList($sFile)
    Local $iRead = FileRead($sFile)
    Local $aString = StringSplit(StringStripCR($iRead), @LF)

    For $i = 1 To $aString[0]
        If $aString[$i] = "" Then ContinueLoop
        GUICtrlCreateListViewItem($i & "|" & StringRegExpReplace($aString[$i], "^.*\\", "")  , $hListView)

    Next
EndFunc

 

Posted

I can't repeat the problem you describe, of it repeating a name when saving to "test.ini", all of that seems to work well. Is there specific steps you follow to make it happen?

When removing an item, and then adding an item, I can make it repeat a number in the first column.

But I do see another issue you will run into.

This line

If $sFile = "" Then ContinueCase

If you happen to have a program name selected when you click "add" and then you happen to cancel the file picker dialog, ContinueCase will jump to the next case, which is "Case $RemButton", which means the current selection will be removed.

As an alternative you might want to change this case

Case $AddButton
             $sFile = FileOpenDialog(@SCRIPTNAME,@WORKINGDIR,"(*.exe)")

            If $sFile = "" Then ContinueCase
            $sFile = StringRegExpReplace($sFile, "^.*\\", "")

            GUICtrlCreateListViewItem(_GUICtrlListView_GetItemCount($hListView) + 1 & "|" & $sFile , $hListView)

to something like this:

Case $AddButton
             $sFile = FileOpenDialog(@SCRIPTNAME,@WORKINGDIR,"(*.exe)")

            If $sFile <> "" Then
                $sFile = StringRegExpReplace($sFile, "^.*\\", "")

                GUICtrlCreateListViewItem(_GUICtrlListView_GetItemCount($hListView) + 1 & "|" & $sFile , $hListView)
            EndIf

 

 

LibreOffice UDF  ; Scite4AutoIt Spell-Checker Using LibreOffice

Spoiler

"Life is chiefly made up, not of great sacrifices and wonderful achievements, but of little things. It is oftenest through the little things which seem so unworthy of notice that great good or evil is brought into our lives. It is through our failure to endure the tests that come to us in little things, that the habits are molded, the character misshaped; and when the greater tests come, they find us unready. Only by acting upon principle in the tests of daily life can we acquire power to stand firm and faithful in the most dangerous and most difficult positions."

 

Posted

thanks donnyh13 for that information.  It's already resolved.


but I still have the problem that the same file name is repeated when saving it.
or with a MsgBox that tells me that the same name already exists in the test.ini and the same name cannot be added. 
Any way to prevent this from happening? thank you

Posted (edited)
5 hours ago, angel83 said:

Any way to prevent this from happening?

The easiest way to script it should be to use the function _GUICtrlListView_FindInText

When you click the AddButton, then the function will search through the ListView if $sFile already exists in any ListView row, something like this (untested) :

Case $AddButton
    $sFile = ...
    $iIndex = _GUICtrlListView_FindInText($hListView, $sFile)
    If $iIndex = -1 Then ; not found
         GUICtrlCreateListViewItem(...)
    Else ; found
        MsgBox(... "already exists" ...)
    EndIf

The 2 functions I know to search for text in a ListView are :
1) _GUICtrlListView_FindText but it searches only in 1st column
2) _GUICtrlListView_FindInText which searches in any column : this is your case as $sFile is placed in the 2nd column.

Gladly your ListView got only 2 columns so the search should be quick (hoping you don't have hundreds of rows)

Other ways to solve your question could be to place all data in an Array (or a Map) then search in them, but it will require more code.

Edit: on second thought, I'm not sure that the code I posted above will work for you in all cases, because the function _GUICtrlListView_FindInText uses StringInStr() for its search so it may retrieve "wrong" items sometimes. For example :

1) You pick from FileOpenDialog() a new $sFile named "Help.exe" (as your StringRegExpReplace deletes the whole path, keeping only the file name & its extension)

2) Imagine there is already a ListView row containing a file named "ThisIsHelp.exe"

3) Then the function _GUICtrlListView_FindInText() will tell you that "Help.exe" already exists in the ListView, which is "wrong" because only "ThisIsHelp.exe" exists in the ListView (tested) . It's just that StringInStr() did correctly its job, but it's not enough in your case because you need a complete match name and not a partial match name.

My advice ?
Just script a little function that will check each row (only column 2) and test in a loop if the text retrieved in each row / column 2 matches fully (or not) your new $sFile . It's short and simple to script, using :

_GUICtrlListView_GetItemCount for the number of existing rows.
_GUICtrlListView_GetItemText to retrieve the text of the subitem.

Good luck

Edited by pixelsearch
added the Edit part

"I think you are searching a bug where there is no bug... don't listen to bad advice."

Posted

THANK YOU pixelsearch
YOUR CODE HELPED ME A LOT AND I SOLVED IT WITH THIS

Case $AddButton
    $sFile = FileSaveDialog(@SCRIPTNAME,@WORKINGDIR,"(*.exe)")
    $sFile = StringMid($sFile,StringInStr($sFile,"\",2,-1) +1)
    $iIndex = _GUICtrlListView_FindInText($hListView, $sFile)
    If $iIndex = -1 Then ; not found
         GUICtrlCreateListViewItem(_GUICtrlListView_GetItemCount($hListView) + 1 & "|" & $sFile , $hListView)
    Else ; found
        MsgBox(0,"" "already exists" )
    EndIf

 

  • Solution
Posted (edited)

Glad I could help :)

But as explained in my preceding post, the solution you choosed is not 100% accurate.
In your case, what will always work to avoid duplicates is this :

Case $AddButton
    $sFile = FileSaveDialog(@SCRIPTNAME,@WORKINGDIR,"(*.exe)")
    $sFile = StringMid($sFile,StringInStr($sFile,"\",2,-1) +1)
    $iIndex = _SearchTextFullMatch($hListView, 1, $sFile) ; 1 = column of 1st subitem
    If $iIndex = -1 Then ; not found
        GUICtrlCreateListViewItem(_GUICtrlListView_GetItemCount($hListView) + 1 & "|" & $sFile , $hListView)
    Else ; found
        _GUICtrlListView_EnsureVisible($hListView, $iIndex)
        MsgBox(0, $sFile, "already exists")
    EndIf
    
...

Func _SearchTextFullMatch($hListView, $iCol, $sText)    
    Local $iItemsCount = _GUICtrlListView_GetItemCount($hListView)
    For $i = 0 To $iItemsCount - 1
        If $sText = _GUICtrlListView_GetItemText($hListView, $i, $iCol) Then Return $i ; found
    Next
    Return -1 ; not found   
EndFunc
Edited by pixelsearch
typo

"I think you are searching a bug where there is no bug... don't listen to bad advice."

Posted

thank pixelsearch it also works much better👍

My script now works fine, thanks friend.
Now what I'm trying is to put the path of the executable in another column.
 I keep trying but nothing

 

You will have some example. since for me it is somewhat complicated but I try to learn

Posted

This should do it for 3 columns. Now it will be easy for you to add a 4th, 5th colum etc...
Good luck

#include <GuiConstantsEx.au3>
#include <GuiListView.au3>

$hGUI = GUICreate("Test", 800, 600)

$hListView = GUICtrlCreateListView("#|Program name|Program path", 10, 10, 780, 100)

_GuiCtrlListView_SetColumnWidth($hListView,0,35)
_GuiCtrlListView_SetColumnWidth($hListView,1,300)
_GuiCtrlListView_SetColumnWidth($hListView,2,420)

$OkButton = GUICtrlCreateButton("Ok", 50, 170, 75, 23)
$AddButton = GUICtrlCreateButton("Add new file", 130, 170, 75, 23)
$RemButton = GUICtrlCreateButton("Remove", 210, 170, 75, 23)

GUISetState(@SW_SHOW, $hGUI)

_FillList(@ScriptDir & "\test.ini")

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit

        Case $OkButton
            $sData = ""
            For $i = 0 To _GUICtrlListView_GetItemCount($hListView) - 1
                $sData &= _GUICtrlListView_GetItemText($hListView, $i, 1) & "|" & _
                          _GUICtrlListView_GetItemText($hListView, $i, 2) & @CRLF ; note the "|" delimiter
            Next
            $hFile = FileOpen(@ScriptDir & "\test.ini", 2) ; 2 = overwrite
            FileWrite($hFile, $sData)
            FileClose($hFile)
            Exit

        Case $AddButton
            $sFile = FileSaveDialog(@SCRIPTNAME,@WORKINGDIR,"(*.exe)")
            $iPosBackSlash = StringInStr($sFile, "\", 2, -1) ; -1 search from the right the last backslash
            $sPath = StringLeft($sFile, $iPosBackSlash - 1)
            $sFile = StringMid($sFile, $iPosBackSlash + 1)
            $iIndex = _SearchTextFullMatch($hListView, 1, $sFile) ; 1 = column of 1st subitem
            If $iIndex = -1 Then ; not found
                GUICtrlCreateListViewItem(_GUICtrlListView_GetItemCount($hListView) + 1 & "|" & $sFile & "|" & $sPath, $hListView)
            Else ; found
                _GUICtrlListView_EnsureVisible($hListView, $iIndex)
                MsgBox(0, $sFile, "already exists")
            EndIf

        Case $RemButton
            _GUICtrlListView_DeleteItemsSelected($hListView)
    EndSwitch
WEnd

Func _FillList($sFile)
    Local $sRead = FileRead($sFile)
    Local $aString = StringSplit($sRead, @CRLF, 1) ; 1 = entire delimiter string is needed to mark the split
    For $i = 1 To $aString[0]
        If $aString[$i] = "" Then ContinueLoop
        GUICtrlCreateListViewItem($i & "|" & $aString[$i], $hListView)
    Next
EndFunc

Func _SearchTextFullMatch($hListView, $iCol, $sText)
    Local $iItemsCount = _GUICtrlListView_GetItemCount($hListView)
    For $i = 0 To $iItemsCount - 1
        If $sText = _GUICtrlListView_GetItemText($hListView, $i, $iCol) Then Return $i ; found
    Next
    Return -1 ; not found
EndFunc

 

"I think you are searching a bug where there is no bug... don't listen to bad advice."

Posted

That was wonderful friend pixelsearch 👍💪. thank you so much. Now I will try to separate to save in separate files.

in one it saves only the executable example (test.ini)

chrome.exe

in another it saves only the path of the executable (path.ini)

C:\Program Files\Google\Chrome\Application

Posted (edited)

I was wondering why there is no function in GuiListView.au3 that mimics the function I suggested in my last script, e.g. Func _SearchTextFullMatch() that searches for a full text match in a specific Listview column. It's a search that is often needed.

I just found a few minutes ago that there IS a native AutoIt function that does it perfectly, and as it is native, then it goes much faster (tested on a big listview) . This function is ControlListView when used like this (adapted to this thread)

$iIndex = ControlListView($hGUI, "", $idListView, "FindItem", $sFile, 1) ; 1 = 1st subitem

A return of -1 means the text to find ($sFile in this thread) has not been found in the desired column.
Instead of modifying the code of my preceding posts, I prefer to post below a revised version with 3 changes :

1) $hListView is a confusing variable name since post #1 (we see it as a handle when it's not, it's just the id of the control) so I change it to $idListView

2) One search line replaces another search line :

; $iIndex = _SearchTextFullMatch($idListView, 1, $sFile) ; 1 = 1st subitem
$iIndex = ControlListView($hGUI, "", $idListView, "FindItem", $sFile, 1) ; 1 = 1st subitem

3) No need of Func _SearchTextFullMatch() anymore, which leads to :

#include <GuiConstantsEx.au3>
#include <GuiListView.au3>

$hGUI = GUICreate("Test", 800, 600)
$idListView = GUICtrlCreateListView("#|Program name|Program path", 10, 10, 780, 100)

_GuiCtrlListView_SetColumnWidth($idListView,0,35)
_GuiCtrlListView_SetColumnWidth($idListView,1,300)
_GuiCtrlListView_SetColumnWidth($idListView,2,420)

$OkButton = GUICtrlCreateButton("Ok", 50, 170, 75, 23)
$AddButton = GUICtrlCreateButton("Add new file", 130, 170, 75, 23)
$RemButton = GUICtrlCreateButton("Remove", 210, 170, 75, 23)

GUISetState(@SW_SHOW, $hGUI)

_FillList(@ScriptDir & "\test.ini")

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit

        Case $OkButton
            $sData = ""
            For $i = 0 To _GUICtrlListView_GetItemCount($idListView) - 1
                $sData &= _GUICtrlListView_GetItemText($idListView, $i, 1) & "|" & _
                          _GUICtrlListView_GetItemText($idListView, $i, 2) & @CRLF ; note the "|" delimiter
            Next
            $hFile = FileOpen(@ScriptDir & "\test.ini", 2) ; 2 = overwrite
            FileWrite($hFile, $sData)
            FileClose($hFile)
            Exit

        Case $AddButton
            $sFile = FileSaveDialog(@SCRIPTNAME,@WORKINGDIR,"(*.exe)")
            $iPosBackSlash = StringInStr($sFile, "\", 2, -1) ; -1 search from the right the last backslash
            $sPath = StringLeft($sFile, $iPosBackSlash - 1)
            $sFile = StringMid($sFile, $iPosBackSlash + 1)
            $iIndex = ControlListView($hGUI, "", $idListView, "FindItem", $sFile, 1) ; 1 = 1st subitem
            If $iIndex = -1 Then ; not found
                GUICtrlCreateListViewItem(_GUICtrlListView_GetItemCount($idListView) + 1 & "|" & $sFile & "|" & $sPath, $idListView)
            Else ; found
                _GUICtrlListView_EnsureVisible($idListView, $iIndex)
                MsgBox(0, $sFile, "already exists")
            EndIf

        Case $RemButton
            _GUICtrlListView_DeleteItemsSelected($idListView)
    EndSwitch
WEnd

Func _FillList($sFile)
    Local $sRead = FileRead($sFile)
    Local $aString = StringSplit($sRead, @CRLF, 1) ; 1 = entire delimiter string is needed to mark the split
    For $i = 1 To $aString[0]
        If $aString[$i] = "" Then ContinueLoop
        GUICtrlCreateListViewItem($i & "|" & $aString[$i], $idListView)
    Next
EndFunc

 

15 hours ago, angel83 said:

Now I will try to separate to save in separate files.


I'm confident that you'll be able to script that part by yourself :)
Good luck

Edit: there are other interesting ways to use ControlListView, for example, in a loop with plenty of rows, this is slow...

For $i = 0 To _GUICtrlListView_GetItemCount($idListView) - 1
    $sData &= _GUICtrlListView_GetItemText($idListView, $i, 1) & "|" & _
              _GUICtrlListView_GetItemText($idListView, $i, 2) & @CRLF
Next

...while this is much faster (tested)

For $i = 0 To _GUICtrlListView_GetItemCount($idListView) - 1
    $sData &= ControlListView($hGUI, "", $idListView, "GetText", $i, 1) & "|" & _
              ControlListView($hGUI, "", $idListView, "GetText", $i, 2) & @CRLF
Next

... and this is the end :D

Edited by pixelsearch
added the Edit part

"I think you are searching a bug where there is no bug... don't listen to bad advice."

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
  • Recently Browsing   0 members

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