Jump to content

Recommended Posts

Posted

Autoit version v3.3.14.5 / SciTE version 3.5.4

Windows 10 Pro x64

 

I don't know if it's me.. or I'm badly using this function..

If someone can answer that, take a look at my example...

#include <DateTimeConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>


$hGUI = GUICreate("Log", 325, 384, -1, -1)


GUICtrlCreateLabel("Select Date : ", 5, 15)
$idDate = GUICtrlCreateDate(@YEAR, 85, 11, 100, 20, $DTS_SHORTDATEFORMAT)
Local $sStyle = "yyyy"
GUICtrlSendMsg($idDate, $DTM_SETFORMATW, 0, $sStyle)


$hGUIList = GUICtrlCreateListView("Item #|Qty for " & @YEAR, 5, 35, 310, 315, -1)
_GUICtrlListView_SetColumnWidth(-1, 0, 150)
_GUICtrlListView_SetColumnWidth(-1, 1, 135)

For $i = 0 To _GUICtrlListView_GetColumnCount(-1) - 1
    _GUICtrlListView_JustifyColumn(-1, $i, 2)
Next

ControlDisable($hGUI, "", HWnd(_GUICtrlListView_GetHeader(-1)))
_GUICtrlListView_SetExtendedListViewStyle(-1, BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_GRIDLINES, $LVS_EX_DOUBLEBUFFER))

Global $aArray[4][2] = [["000103268", "0"], ["00011864", "1"], ["00012452", "2"], ["000130014", "3"]]


_ArrayDisplay($aArray)
;~ <------ Array Display is OK (the 0 at the beginning in the item # are there)


For $j = 0 To UBound($aArray, $UBOUND_ROWS) - 1
    $sFill = $aArray[$j][0] & "|" & $aArray[$j][1]
    GUICtrlCreateListViewItem($sFill, $hGUIList)
Next


Global $g_bSortSense = True
_GUICtrlListView_SimpleSort($hGUIList, $g_bSortSense, 1)
;~ <------ After the SimpleSort, all the 0 at the beginning of the item # are missing in the GUI ???
;~ <------ if you commented the SimpleSort line, all the 0 are in the item # in the GUI ???

GUISetState(@SW_SHOW, $hGUI)

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ExitLoop

    EndSwitch
WEnd

GUIDelete($hGUI)

 

thank you and if it's me, sorry to have bothered you :)

Posted (edited)

@Resiak1811

just replace :

_GUICtrlListView_SimpleSort($hGUIList, $g_bSortSense, 1)

with to be in order:

_GUICtrlListView_SimpleSort($hGUIList, $g_bSortSense, 4)

or:

Global $g_bSortSense = False
_GUICtrlListView_SimpleSort($hGUIList, $g_bSortSense, 1,True)

 

Edited by ad777

none

Posted

_GUICtrlListView_SimpleSort ( $hWnd, ByRef $vSortSense, $iCol [, $bToggleSense = True] )

 

since the 1 is the $iCol ...

I don't have 4 col. in the listview but whatever... I have tried and same result

Posted

@Resiak1811

_GUICtrlListView_SimpleSort

Sorts a list-view control (limited)

#include <GuiListView.au3>
_GUICtrlListView_SimpleSort ( $hWnd, ByRef $vSortSense, $iCol [, $bToggleSense = True] )

Parameters

$hWnd Handle to the control
$vSortSense Sets the defined sort order
    True - Sort Descending
    False - Sort Ascending
Use a simple variable for a single column ListView
Use an array for multicolumn ListViews:
    $aArray[0] - Order for first Column
    $aArray[1] - Order for second Column
    $aArray[n] - Order for last Column
$iCol Column number
$bToggleSense [optional] Toggle sort sense
    True - Toggle sort sense after sort (default)
    False - Sort sense unchanged after sort

 

use false for Sort Ascending

 

the script will be:

Global $g_bSortSense = False
_GUICtrlListView_SimpleSort($hGUIList, $g_bSortSense, 1,True)

 

none

Posted

I want a order by Qty (col 1)

and of course, I want the real item # (with all the 0 at the beginning)

 

and I have tested your last suggestion, adding & "0" to the $hGUIList restore the leading 0 ... but does not sort anymore

Posted

I found the problem ...


In GuiListView.au3

the line 4502 --> $aListViewItems[$i][$j] = Number($sItemText)

"Number" remove the 0 at the beginning of the item #...


Can I expect any fix from the dev. ?


Otherwise I will modify this part:

In GuiListView.au3, line 4501 to 4505 :
    If (StringIsFloat($sItemText) Or StringIsInt($sItemText)) Then
        $aListViewItems[$i][$j] = Number($sItemText)
    Else
        $aListViewItems[$i][$j] = $sItemText
    EndIf


to be only :

$aListViewItems[$i][$j] = $sItemText

 

Posted

@Resiak1811: glad you made some research and found the cause.
I was searching too and I found the same cause, but it could be patched differently.

The behavior you described is caused by the function _GUICtrlListView_SimpleSort() found in the include file GuiListView.au3. Here is an excerpt of the function :

For $j = 0 To $iColumnCount - 1 ; Columns
    $sItemText = StringStripWS(_GUICtrlListView_GetItemText($hWnd, $i, $j), $STR_STRIPTRAILING)
    If (StringIsFloat($sItemText) Or StringIsInt($sItemText)) Then
        $aListViewItems[$i][$j] = Number($sItemText)
    Else
        $aListViewItems[$i][$j] = $sItemText
    EndIf
Next

The question is : why should all columns be concerned by this For...Next loop, altering possible values in columns that has nothing to do with the sort ? (that's your case)

If we replace the preceding For... Next loop by the following, it should solve the issue :

For $j = 0 To $iColumnCount - 1 ; Columns
    If $j = $iCol Then ; $iCol = column to sort (3rd param. of the function)
        $sItemText = StringStripWS(_GUICtrlListView_GetItemText($hWnd, $i, $j), $STR_STRIPTRAILING)
        If (StringIsFloat($sItemText) Or StringIsInt($sItemText)) Then
            $aListViewItems[$i][$j] = Number($sItemText)
        Else
            $aListViewItems[$i][$j] = $sItemText
        EndIf
    Else
        $aListViewItems[$i][$j] = _GUICtrlListView_GetItemText($hWnd, $i, $j) ; unaltered
    EndIf
Next

Let's not forget that there is a chain of functions called during the sorting, for example :
_GUICtrlListView_SimpleSort() => _ArraySort() => __ArrayQuickSort2D() etc...

So, one has to make sure that patching _GUICtrlListView_SimpleSort() in this way won't create new issues in the chained functions.

After a quick look, I don't think there should be other issues but it's much safer to let the developers decide.
 

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

Posted
23 minutes ago, Resiak1811 said:

works great for my case but if anyone else need something like that (but sort by col.0) .. the problem is still there

But at least it will solve many cases.

That's the eternal problem of letting the computer decide by itself if 0033456789 should be treated like a number (33456789) or a string (maybe a phone number 0033456789 where 00 are important)

As there are no parameters indicating what exactly represents this column of "numbers", then the problem can't be easily solved in many scripts ( except the * in the next beta version of _Arraydisplay, hi jpm :bye: )

If there was an additional parameter to indicate if the user wants his column to be treated as numbers or strings, then the problem would always be solved... but it would require a lot of changes in plenty of functions, not counting many users won't like that (i.e. forced to pass an extra parameter)

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

Posted

it looks like the Excel cell problem ...

if you don't change the cell format ... 000123 will be 123 ... I hate Excel for that hehe

and now I found the same problem with Autoit... luckly I'm not using the SimpleSort often lol

 

thank for understanding the problem I had and...

confirming that I'm not the problem hehe :)

Posted (edited)

You can fix it without modifying UDF by using

https://www.autoitscript.com/autoit3/docs/libfunctions/_GUICtrlListView_RegisterSortCallBack.htm

then you can modify the sorting to your own implementation

In beta I see same behavior so maybe log it in issue tracker so you get feedback if its a feature or bug

Edited by junkew
Posted (edited)

@Resiak1811

Yout meant sort By Number:

#include <Array.au3>
#include <MsgBoxConstants.au3>

Local $aArray_2dR[6][2] = [["000103268", Number("100")], ["00011864", Number("221")], ["00012452", Number("3")], ["020140014", Number("5")], ["000130014", Number("24")], ["000130014", Number("214")]]
$ByNumber = 100 ;
$NumberCol = 6 ;
_SortArrayByOrder($aArray_2dR, $NumberCol, $ByNumber)
Func _SortArrayByOrder($aArray_2D, $NCol, $NChoic)
    Global $Ad_string
    Global $add, $add_2, $add_3, $inc, $inc_change, $string_add
    For $i = 0 To UBound($aArray_2D) - 1
        For $i2 = 0 To UBound($aArray_2D) - 1
            If $aArray_2D[$i][1] < $aArray_2D[$i2][1] Then
                If $aArray_2D[$i2][1] = $aArray_2D[$i][1] Then
                Else
                    $add &= "1"
                EndIf
            Else
                If $aArray_2D[$i2][1] = $aArray_2D[$i][1] Then
                Else
                    For $i3 = 1 To UBound($aArray_2D) * 2
                        Global $str = StringInStr($inc, $aArray_2D[$i2][1])
                        $mid = StringMid($inc, $str, $i3)
                        $string_add = $mid
                        If $mid = $aArray_2D[$i2][1] Then ExitLoop
                    Next
                    If $string_add = $aArray_2D[$i2][1] Then
                    Else
                        $add &= "0"
                    EndIf
                EndIf
            EndIf
        Next
        If StringInStr($add, "1") And StringInStr($add, "0") And $i2 = $NCol - 1 Or StringInStr($add, "0") Then
        Else
            $Ad_string &= $aArray_2D[$i][0] & "|" & $aArray_2D[$i][1] & ","
            $inc &= $aArray_2D[$i][1] & ","
            $add_2 = $aArray_2D[$i][1]
            $add_3 &= $add_2 & ","
            $add_2 = ""
        EndIf
        $add = ""
        If $i = $NCol - 1 Then
            $i = 0 - 1
            $i2 = 0 - 1
            If StringLen($add_3) > UBound($aArray_2D) * 4 - 1 Then
                ;;;;;;;;;;;;;;;eeee
                Global $SSnum = "on"
                If $SSnum = "on" Then
                    For $i = 0 To 100
                        _ArrayDelete($aArray_2D, 0)
                    Next
                    $SSnum = "off"
                EndIf
                Global $in, $state_1 = "on", $prev_num, $prev_rat, $state_2 = "on", $state_3 = "on", $ine, $in2, $str_add, $inc3
                $num = $Ad_string
                For $i = 1 To 200
                    If $i = 200 Then
                        $inc3 = $inc3 + 1
                        If $inc3 > 1 Then
                            $in2 = $in2 - 1
                        EndIf
                        $ine = $in2 + 2
                        $in2 = $ine
                        $i = $ine
                        $state_3 = "on"
                        $state_1 = "on"
                        $state_2 = "on"
                        $in = 0
                    EndIf
                    If StringMid($num, $i, 1) = "," Then
                        $state_3 = "off"
                        $prev_rat2 = StringMid($num, $prev_num, $in)
                        $str_add &= StringLeft($num, $prev_num - 1)
                        If $prev_rat <> $prev_rat2 Then
                            If StringInStr($str_add, $prev_rat2) Then
                            Else

                                $inc_change = $inc_change + 1
                                If $inc_change > $NCol Then
                                    ExitLoop
                                Else
                                    If StringMid($prev_rat2, StringInStr($prev_rat2, "|") + 1, -1) > $NChoic Then
                                        _ArrayAdd($aArray_2D, $prev_rat2)
                                    EndIf
                                EndIf
                                ;   EndIf
                            EndIf
                        EndIf
                        If $state_2 = "on" Then
                            $prev_rat = ""
                            $prev_rat = StringMid($num, $prev_num, $in)
                            $i = 0
                            $state_2 = "off"
                        EndIf
                        $state_1 = "on"
                        $in = 0
                    Else
                        If $state_1 = "on" Then
                            $prev_num = $i
                            $state_1 = "off"
                        EndIf
                        $in = $in + 1
                        If $state_3 = "on" Then
                            $in2 = $in2 + 1
                            $SSnum = $in2
                        EndIf
                    EndIf
                Next
            EndIf
        EndIf
    Next
    _ArrayDisplay($aArray_2D, "! Header separator", 0, Default, Default, "EE!FF!eee|#EE")

EndFunc   ;==>_SortArrayByOrder

 

Edited by ad777

none

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...