Jump to content

Txt split to ini file


Recommended Posts

@mucitbey If you choose the reusable template way, then this part of code will not work anymore :

#cs
If IniRead(@ScriptDir & "\" & $sDate & ".ini", $user, "Value03", "Non-existing key") = "Non-existing key" Then
    IniWrite(@ScriptDir & "\" & $sDate & ".ini", $user, "Value01", $aTemp[1])
    IniWrite(@ScriptDir & "\" & $sDate & ".ini", $user, "Value02", $aTemp[3])
    IniWrite(@ScriptDir & "\" & $sDate & ".ini", $user, "Value03", $aTemp[4])
Else ; key already exists
    IniWrite(@ScriptDir & "\" & $sDate & ".ini", $user, "Value04", $aTemp[4])
EndIf
#ce

It should be replaced with the following code, which seems to do the job nicely (ok, but there is better code in my next post +++)

If $user = "" Or $user = "Undefined ID" Then $user = $aTemp[1] ; username becomes ID (this should never happen, according to mucitbey)

$sKey = IniRead(@ScriptDir & "\" & $sDate & ".ini", $user, "Value03", "Undefined ID")

; $sKey has now 3 meanings :
; 1) "null" means we need to update "Value03" (1st entry for this user in Datalar.txt for this day)
; 2) "07:01:00" (for example) means we need to update "Value04" (2nd entry for this user in Datalar.txt for this day)
; 3) "Undefined ID" means... what it says (sabotage in Users.txt) then we add a new section like this, for example if ID 00000059 :
; [00000059]
;  Value01=Undefined ID
;  Value02=13.04.2023
;  Value03=07:01:00
;  Value04=null

Select
    Case $sKey = "null"
        IniWrite(@ScriptDir &"\" & $sDate & ".ini", $user, "Value03", $aTemp[4]) ; in-time

    Case StringRegExp($sKey, '\d\d:\d\d:\d\d') ; ex. '07:01:00'
        IniWrite(@ScriptDir & "\" & $sDate & ".ini", $user, "Value04", $aTemp[4]) ; out-time

    Case Else ; $sKey = "Undefined ID"
        IniWrite(@ScriptDir & "\" & $sDate& ".ini", $aTemp[1], "Value01", "Undefined ID")
        IniWrite(@ScriptDir & "\" & $sDate& ".ini", $aTemp[1], "Value02", $sDate)
        IniWrite(@ScriptDir & "\" & $sDate& ".ini", $aTemp[1], "Value03", $aTemp[4])
        IniWrite(@ScriptDir & "\" & $sDate& ".ini", $aTemp[1], "Value04", "null")
EndSelect

Edited by pixelsearch
Link to comment
Share on other sites

21 hours ago, ioa747 said:

I fixed it ,  I await comments :)

 

I haven't had a chance to try it extensively yet, but I didn't encounter any problems in my first attempts. Your code does its job just fine. :thumbsup:

Link to comment
Share on other sites

I also adapted the extended version

; https://www.autoitscript.com/forum/topic/210069-txt-split-to-ini-file/?do=findComment&comment=1517679
#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 ;-w 5 -w 6 -w 7
#include <Misc.au3>
#include <File.au3>
#include <Date.au3>
#include <Array.au3>
#include <GuiComboBox.au3>
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>

_Singleton(@ScriptName, 0)

Global $nMsg, $hGui, $idCombo, $lv, $CurUser

Global $aUsers = WriteAllUserData()
Global $aData = FindAllIniFile(@ScriptDir & "\Data\")

AddAbsentUser()
MakeMyGuiList()

HotKeySet("{HOME}", "MyArrayDisplay")

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $idCombo
            _GUICtrlComboBox_GetLBText($idCombo, _GUICtrlComboBox_GetCurSel($idCombo), $CurUser)
            UpDadeMyGuiList($CurUser)
        Case $GUI_EVENT_CLOSE
            GUIDelete()
            Exit
    EndSwitch
WEnd

;----------------------------------------------------------------------------------------
Func WriteAllUserData()  ; Make all ini files
    Local $aDatalar, $aUsers, $UserName, $aTemp, $IniFile, $aSpl, $sDate

    _FileReadToArray("Datalar.txt", $aDatalar, $FRTA_NOCOUNT)
    _FileReadToArray("Users.txt", $aUsers, $FRTA_COUNT, "=")

    Local $iLines = UBound($aDatalar)

    $sDate = ''

    For $i = 0 To $iLines - 1
        $aTemp = StringSplit($aDatalar[$i], ", ", $STR_NOCOUNT)
        $UserName = GetUserName($aUsers, $aTemp[1])

        ; if no user skip
        If $UserName <> "" Then
            If $sDate <> $aTemp[3] Then $sDate = $aTemp[3]

;~          ; format date 00.00.0000 for ini FileName
;~          $aSpl = StringSplit($sDate, ".")
;~          If StringLen($aSpl[1]) = 1 Then $aSpl[1] = "0" & $aSpl[1]
;~          $IniFile = $aSpl[1] & "." & $aSpl[2] & "." & $aSpl[3] & ".ini"
            $IniFile = $sDate & ".ini"

            ;write ini
            If IniRead(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value01", "Non-existing key") = "Non-existing key" Then
                IniWrite(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value01", $aTemp[1])
                IniWrite(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value02", $aTemp[3])
                IniWrite(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value03", $aTemp[4])
            Else
                If IniRead(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value03", "<UNKNOWN>") <> $aTemp[4] Then
                    IniWrite(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value04", $aTemp[4])
                EndIf
            EndIf
        EndIf
    Next
    Return $aUsers
EndFunc   ;==>WriteAllUserData
;----------------------------------------------------------------------------------------
Func GetUserName($aUsers, $ID)  ; ID to User Name
    Local $iIndex = _ArraySearch($aUsers, $ID)
    If $iIndex <> -1 Then
        Return StringStripWS($aUsers[$iIndex][1], $STR_STRIPLEADING + $STR_STRIPTRAILING + $STR_STRIPSPACES)
    Else
        Return ""
    EndIf
EndFunc   ;==>GetUserName
;----------------------------------------------------------------------------------------
Func FindAllIniFile($sStartPath = "")  ; Find All Ini File
    If $sStartPath = "" Then $sStartPath = @ScriptDir
    Local $aArray[1][8]
    $aArray[0][0] = 0 ; "index"
    $aArray[0][1] = "UserID"
    $aArray[0][2] = "UserName"
    $aArray[0][3] = "Date"
    $aArray[0][4] = "Start"
    $aArray[0][5] = "End"
    $aArray[0][6] = "Time"
    $aArray[0][7] = "idItem"

    Local $ArraySrtfiles = _FileListToArrayRec($sStartPath, "*.ini", $FLTAR_FILES, $FLTAR_RECUR)
    If Not IsArray($ArraySrtfiles) Then
        ConsoleWrite($sStartPath & " = Invalid input path" & @CRLF)
        Return
    Else
        For $x = 1 To $ArraySrtfiles[0]
            ;ConsoleWrite($sStartPath & $ArraySrtfiles[$x]& @CRLF)
            ReadIniToArray($aArray, $sStartPath & $ArraySrtfiles[$x])
        Next
        Return $aArray
    EndIf
EndFunc   ;==>FindAllIniFile
;----------------------------------------------------------------------------------------
Func ReadIniToArray(ByRef $aArray, $TxtFile)  ; Read Ini To Array

    Local $index

    ;Read the INI section names. This will return a 1 dimensional array.
    Local $aSections = IniReadSectionNames($TxtFile)
    ;Check if an error occurred.
    If Not @error Then
        ;Enumerate through the array displaying the section names.
        For $i = 1 To $aSections[0]
            ReDim $aArray[UBound($aArray) + 1][8]
            $aArray[0][0] += 1
            $index = $aArray[0][0]

            $aArray[$index][0] = $index ;"index"
            $aArray[$index][1] = IniRead($TxtFile, $aSections[$i], "Value01", "Null") ;"UserID"
            $aArray[$index][2] = $aSections[$i] ;"UserName"
            $aArray[$index][3] = IniRead($TxtFile, $aSections[$i], "Value02", "Null") ;"Date"
            $aArray[$index][4] = IniRead($TxtFile, $aSections[$i], "Value03", "Null") ;"Start"
            $aArray[$index][5] = IniRead($TxtFile, $aSections[$i], "Value04", "Null") ;"End"
            $aArray[$index][6] = "" ;"Time"
        Next
    EndIf

EndFunc   ;==>ReadIniToArray
;----------------------------------------------------------------------------------------
Func MakeMyGuiList()  ; GUI Create
    $hGui = GUICreate("_ank_ File Splitting", 510, 560, -1, -1)

    $lv = GUICtrlCreateListView("CART ID  |DATE  |START  |END  |TIME|NAME AND SURNAME", 10, 30, 490, 520)
    Local $sLine
    For $i = 1 To $aData[0][0]
        $sLine = $aData[$i][1] & "|" & $aData[$i][3] & "|" & $aData[$i][4] & "|"
        $sLine &= $aData[$i][5] & "|" & TimeDiff($aData[$i][4], $aData[$i][5]) & "|" & $aData[$i][2]
        $aData[$i][7] = GUICtrlCreateListViewItem($sLine, $lv)
        If $aData[$i][4] > "08:10:00" And $aData[$i][4] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
        If $aData[$i][5] > "08:10:00" And $aData[$i][5] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
        If $aData[$i][4] = "Null" Or $aData[$i][5] = "Null" Then GUICtrlSetBkColor(-1, 0xFFE5FF)
    Next

    $idCombo = GUICtrlCreateCombo("Select User", 10, 1, 490, 25, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL))
    GUICtrlSetFont(-1, 12, 400, 0, "MS Sans Serif")
    For $i = 1 To $aUsers[0][0]
        _GUICtrlComboBox_AddString($idCombo, $aUsers[$i][1])
    Next

    GUISetState(@SW_SHOW)
EndFunc   ;==>MakeMyGuiList
;----------------------------------------------------------------------------------------
Func UpDadeMyGuiList($Filter)

    ; delete items
    Local $hlv = GUICtrlGetHandle($lv)
    _GUICtrlListView_DeleteAllItems($hlv)

    Local $sLine
    ; ReMake items
    For $i = 1 To $aData[0][0]
        If $Filter = "Select User" Then
            $sLine = $aData[$i][1] & "|" & $aData[$i][3] & "|" & $aData[$i][4] & "|"
            $sLine &= $aData[$i][5] & "|" & TimeDiff($aData[$i][4], $aData[$i][5]) & "|" & $aData[$i][2]
            $aData[$i][7] = GUICtrlCreateListViewItem($sLine, $lv)
            If $aData[$i][4] > "08:10:00" And $aData[$i][4] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
            If $aData[$i][5] > "08:10:00" And $aData[$i][5] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
            If $aData[$i][4] = "Null" Or $aData[$i][5] = "Null" Then GUICtrlSetBkColor(-1, 0xFFE5FF)
            ContinueLoop
        Else
            If $aData[$i][2] = $Filter Then
                $sLine = $aData[$i][1] & "|" & $aData[$i][3] & "|" & $aData[$i][4] & "|"
                $sLine &= $aData[$i][5] & "|" & TimeDiff($aData[$i][4], $aData[$i][5]) & "|" & $aData[$i][2]
                $aData[$i][7] = GUICtrlCreateListViewItem($sLine, $lv)
                If $aData[$i][4] > "08:10:00" And $aData[$i][4] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
                If $aData[$i][5] > "08:10:00" And $aData[$i][5] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
                If $aData[$i][4] = "Null" Or $aData[$i][5] = "Null" Then GUICtrlSetBkColor(-1, 0xFFE5FF)
            Else
                $aData[$i][7] = ""
            EndIf
        EndIf
    Next

EndFunc   ;==>UpDadeMyGuiList
;----------------------------------------------------------------------------------------
Func AddAbsentUser()

    Local $sLine, $IniFile, $aSpl, $aArray = $aData

    ;*[Add Absent User to $aData Array
    Local $aDateUnique = _ArrayUnique($aArray, 3, 1)
    For $d = 1 To $aDateUnique[0]
        For $i = 1 To $aUsers[0][0]
            If _GetThis($aUsers[$i][0] & "-" & $aDateUnique[$d]) = -1 Then
                $aData[0][0] += 1
                $sLine = $aData[0][0] & "|" & $aUsers[$i][0] & "|" & $aUsers[$i][1] & "|" & $aDateUnique[$d] & "|Null|Null"
                _ArrayAdd($aData, $sLine)
            EndIf
        Next
    Next
    ;Add Absent User to $aData Array]*

    ;*[proper Array Sort order
    For $i = 1 To $aData[0][0]
        ; format date YYYY.MM.DD.HH.MM.SS
        $aSpl = StringSplit($aData[$i][3], ".")
        If StringLen($aSpl[1]) = 1 Then $aSpl[1] = "0" & $aSpl[1]
        $sLine = $aSpl[3] & "." & $aSpl[2] & "." & $aSpl[1] & "." & $aData[$i][4]
        $aData[$i][0] = $sLine
    Next
    _ArraySort($aData, 0, 1)
    For $i = 1 To $aData[0][0]
        $aData[$i][0] = $i
    Next
    ;proper Array Sort order]*

    ;*[Write $aData Array to ini
    For $i = 1 To $aData[0][0]
;~      ; format date 00.00.0000 for ini FileName
;~      $aSpl = StringSplit($aData[$i][3], ".")
;~      If StringLen($aSpl[1]) = 1 Then $aSpl[1] = "0" & $aSpl[1]
;~      $IniFile = $aSpl[1] & "." & $aSpl[2] & "." & $aSpl[3] & ".ini"
        $IniFile = $aData[$i][3] & ".ini"

        ;write ini
        IniWrite(@ScriptDir & "\Data\" & $IniFile, $aData[$i][2], "Value01", $aData[$i][1])
        IniWrite(@ScriptDir & "\Data\" & $IniFile, $aData[$i][2], "Value02", $aData[$i][3])
        IniWrite(@ScriptDir & "\Data\" & $IniFile, $aData[$i][2], "Value03", $aData[$i][4])
        IniWrite(@ScriptDir & "\Data\" & $IniFile, $aData[$i][2], "Value04", $aData[$i][5])
    Next
    ;Write $aData Array to ini]*

EndFunc   ;==>AddAbsentUser
;----------------------------------------------------------------------------------------
Func _GetThis($Txt)
    Local $sIndex
    For $i = 1 To $aData[0][0]
        $sIndex = -1
        If $aData[$i][1] & "-" & $aData[$i][3] = $Txt Then
            $sIndex = $i
            ExitLoop
        EndIf
    Next
    Return $sIndex
EndFunc   ;==>_GetThis
;----------------------------------------------------------------------------------------
Func TimeDiff($sStartTime, $sEndTime)
    Local $H, $M, $sDiff, $aSpl1, $aSpl2
    $aSpl1 = StringSplit($sStartTime, ":")
    $aSpl2 = StringSplit($sEndTime, ":")
    If $aSpl1[0] + $aSpl2[0] <> 6 Then
        ;ConsoleWrite("! Error No valid time format" & @CRLF)
        Return SetError(1, 0, "")
    EndIf
    ; ** 2020/01/01 ** since all the results are from the same date
    $M = _DateDiff('n', "2020/01/01 " & $sStartTime, "2020/01/01 " & $sEndTime)
    $H = Floor($M / 60)
    $M = Mod($M, 60)
    $sDiff = StringFormat("%i:%02i", $H, $M)
    Return $sDiff
EndFunc   ;==>TimeDiff
;----------------------------------------------------------------------------------------
Func MyArrayDisplay()
    _ArrayDisplay($aData, "$aData")
EndFunc   ;==>MyArrayDisplay
;----------------------------------------------------------------------------------------

 

Edited by ioa747
corection for proper coloring

I know that I know nothing

Link to comment
Share on other sites

@mucitbey Please try the script below to see if it does what is expected, with the corresponding Users.txt and Datalar.txt found below. Just place the 3 files in a new folder and run the script, it should display the same listview as in the pic below.

In this example, Gisele Bündchen is absent on 12.04.2023 , Candice Swanepoel is absent on 13.04.2023 , an unknown ID 999 checked on 13.04.2023 (red background). The lines with blue background got the usual meaning (user checked after 8h10 and before 17h00). A blank line separates each new day in the listview. Please have a look at the 2 daily ini files created in the new folder, everything seems to be correct. Good luck :)

With-Absents-and-Undefined-ID-s.png
#include <File.au3>
#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>

Global $aData, $aUser, $aUser_Backup

_FileReadToArray(@ScriptDir & "\" & "Datalar.txt", $aData, $FRTA_NOCOUNT) ; 1D array
If @error Then Exit MsgBox($MB_TOPMOST, "_FileReadToArray error = " & @error, "Datalar.txt")
$iLinesData = UBound($aData)

_FileReadToArray(@ScriptDir & "\" & "Users.txt", $aUser, $FRTA_NOCOUNT, "=") ; 2D array
If @error Then Exit MsgBox($MB_TOPMOST, "_FileReadToArray error = " & @error, "Users.txt")
$iLinesUser = UBound($aUser)
ReDim $aUser[$iLinesUser][3] ; add one empty column 2 at the right (to remember users who were present daily)
$aUser_Backup = $aUser ; keep a copy with last column 2 empty for all users. Reuse this backup when date changes.

$hTemplate = FileOpen(@ScriptDir & "\" & "Users template.ini", $FO_OVERWRITE + $FO_UNICODE) ; $FO_ANSI also worked.
If $hTemplate = -1 Then Exit MsgBox($MB_TOPMOST, "FileOpen error", "Users template.ini")
For $i = 0 To $iLinesUser - 1
    FileWriteLine($hTemplate, _
        "[" & $aUser[$i][1] & "]" & @crlf & _
        "Value01=" & $aUser[$i][0] & @crlf & _
        "Value02=" & @crlf & "Value03=" & @crlf & "Value04=" & @crlf)
Next
FileClose($hTemplate)

GUICreate("_ank_ File Splitting", 430, 500, -1, -1)
$lv = GUICtrlCreateListView("CART ID  |DATE  |TIME-1  |NAME AND SURNAME     ", 10, 10, 410, 480)
$sDate = ''

For $li = 0 To $iLinesData - 1
    $aTemp = StringSplit(StringStripWS($aData[$li], 1+2), ", ", $STR_NOCOUNT) ; strip leading (1) and trailing (2) eventual white space
    If @error Then ContinueLoop ; eliminate accidental blank lines. Help file StringSplit: "@error = 1 when no delimiters were found"

    If $sDate <> $aTemp[3] Then ; $sDate is the old date, $aTemp[3] is the new date.
        If $sDate Then ; always False when $li = 0 (first data line processed)
            Add_Absents($sDate) ; add eventual absents AFTER a day has been processed.
            $aUser = $aUser_Backup ; blank column 2 in $aUser, for all users, when the date changes.
            GUICtrlCreateListViewItem("", $lv) ; 1 empty line between each day processed (sort of vertical separator)
        EndIf
        $sIniFile = @ScriptDir & "\" & $aTemp[3] & ".ini"
        $iRet = FileCopy(@ScriptDir & "\" & "Users template.ini", $sIniFile, $FC_OVERWRITE) ; date changes => new ini file (based on ini template)
        If $iRet = 0 Then Exit MsgBox($MB_TOPMOST, "FileCopy error", $sIniFile) ; maybe existed read-only => overwrite fails
        $sDate = $aTemp[3] ; old date = new date
    EndIf

    $user = GetUser($aTemp[1]) ; user name
    GUICtrlCreateListViewItem($aTemp[1] &"|"& $aTemp[3] &"|"& $aTemp[4] &"|"& $user, $lv)
    If $aTemp[4] > "08:10:00" And $aTemp[4] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF) ; light blue

    If $user = "Undefined ID" Then
        $user = $aTemp[1] ; user name becomes ID (this should never happen, according to mucitbey)
        GUICtrlSetBkColor(-1, 0xFF0000) ; red
    EndIf

    $sKey = IniRead($sIniFile, $user, "Value03", "Undefined ID") ; remember Value03 = in-time
    ; $sKey has 3 possible values :
    ; 1) "" means we need to update "Value03" (1st entry for this user in Datalar.txt for this day)
    ; 2) "07:01:00" (for example) means we need to update "Value04" (2nd entry for this user in Datalar.txt for this day)
    ; 3) "Undefined ID" means... what it says (sabotage in Users.txt) then we add a new section in daily ini file, based on ID

    Select
        Case $sKey = ""
            IniWrite($sIniFile, $user, "Value02", $aTemp[3]) ; date
            IniWrite($sIniFile, $user, "Value03", $aTemp[4]) ; in-time

        Case StringRegExp($sKey, '\d\d:\d\d:\d\d') ; ex. '07:01:00'
            IniWrite($sIniFile, $user, "Value02", $aTemp[3]) ; date
            IniWrite($sIniFile, $user, "Value04", $aTemp[4]) ; out-time

        Case Else ; $sKey = "Undefined ID"
            IniWrite($sIniFile, $aTemp[1], "Value01", "Undefined ID")
            IniWrite($sIniFile, $aTemp[1], "Value02", $sDate) ; date
            IniWrite($sIniFile, $aTemp[1], "Value03", $aTemp[4]) ; in-time
            IniWrite($sIniFile, $aTemp[1], "Value04", "") ; out-time
    EndSelect
Next

If $sDate Then Add_Absents($sDate) ; add eventual absents for the last day processed.
GUISetState(@SW_SHOW)

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

Func GetUser($ID)
    For $iIndex = 0 To $iLinesUser - 1
        If $aUser[$iIndex][0] = $ID Then ExitLoop
    Next
    If $iIndex < $iLinesUser Then ; user ID found in $aUser (e.g "Users.txt")
        $aUser[$iIndex][2] = 1 ; user worked that day. Column 2 will be blanked by reusing $aUser_Backup when date changes.
        Return $aUser[$iIndex][1] ; user name
    Else ; user ID not found in "Users.txt" (this can't happen, according to mucitbey)
        Return "Undefined ID" ; do not change this line (+++)
    EndIf
EndFunc

Func Add_Absents($sDate)
    For $i = 0 To $iLinesUser - 1
        If Not $aUser[$i][2] Then ; user was absent that day
            ; add 1 line in ListView for the absent user (with a blank time)
            GUICtrlCreateListViewItem($aUser[$i][0] &"|"& $sDate &"|"& "" &"|"& $aUser[$i][1], $lv)
            ; update 1 line in ini file for the absent user (update the date line, e.g. Value02)
            IniWrite($sIniFile, $aUser[$i][1], "Value02", $sDate) ; date
        EndIf
    Next
EndFunc


Users.txt
00000001=Adriana Francesca Lima
00000010=Candice Swanepoel
00000017=Gisele Bündchen
00000020=Kendall Jenner

Datalar.txt
001,00000001,00,12.04.2023 07:01:00
001,00000010,00,12.04.2023 07:10:00
001,00000001,00,12.04.2023 16:01:00
001,00000010,00,12.04.2023 16:10:00
001,00000020,00,12.04.2023 19:20:00
001,00000020,00,13.04.2023 06:20:00
001,00000999,00,13.04.2023 06:59:00
001,00000001,00,13.04.2023 07:01:00
001,00000017,00,13.04.2023 07:17:00
001,00000001,00,13.04.2023 16:01:00
001,00000017,00,13.04.2023 16:17:00

Edited by pixelsearch
improved code
Link to comment
Share on other sites

17 hours ago, pixelsearch said:

@mucitbey Please try the script below to see if it does what is expected, with the corresponding Users.txt and Datalar.txt found below. Just place the 3 files in a new folder and run the script, it should display the same listview as in the pic below.

In this example, Gisele Bündchen is absent on 12.04.2023 , Candice Swanepoel is absent on 13.04.2023 , an unknown ID 999 checked on 13.04.2023 (red background). The lines with blue background got the usual meaning (user checked after 8h10 and before 17h00). A blank line separates each new day in the listview. Please have a look at the 2 daily ini files created in the new folder, everything seems to be correct. Good luck :)

With-Absents-and-Undefined-ID-s.png

 

 

#include <File.au3>
#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>

Global $aData, $aUser, $aUser_Backup

_FileReadToArray(@ScriptDir & "\" & "Datalar.txt", $aData, $FRTA_NOCOUNT) ; 1D array
If @error Then Exit MsgBox($MB_TOPMOST, "_FileReadToArray error = " & @error, "Datalar.txt")
$iLinesData = UBound($aData)

_FileReadToArray(@ScriptDir & "\" & "Users.txt", $aUser, $FRTA_NOCOUNT, "=") ; 2D array
If @error Then Exit MsgBox($MB_TOPMOST, "_FileReadToArray error = " & @error, "Users.txt")
$iLinesUser = UBound($aUser)
ReDim $aUser[$iLinesUser][3] ; add one empty column 2 at the right (to remember users who were present daily)
$aUser_Backup = $aUser ; keep a copy with last column 2 empty for all users. Reuse this backup when date changes.

$hTemplate = FileOpen(@ScriptDir & "\" & "Users template.ini", $FO_OVERWRITE + $FO_UNICODE) ; $FO_ANSI also worked.
If $hTemplate = -1 Then Exit MsgBox($MB_TOPMOST, "FileOpen error", "Users template.ini")
For $i = 0 To $iLinesUser - 1
    FileWriteLine($hTemplate, _
        "[" & $aUser[$i][1] & "]" & @crlf & _
        "Value01=" & $aUser[$i][0] & @crlf & _
        "Value02=" & @crlf & "Value03=" & @crlf & "Value04=" & @crlf)
Next
FileClose($hTemplate)

GUICreate("_ank_ File Splitting", 430, 500, -1, -1)
$lv = GUICtrlCreateListView("CART ID  |DATE  |TIME-1  |NAME AND SURNAME     ", 10, 10, 410, 480)
$sDate = ''

For $li = 0 To $iLinesData - 1
    $aTemp = StringSplit(StringStripWS($aData[$li], 1+2), ", ", $STR_NOCOUNT) ; strip leading (1) and trailing (2) eventual white space
    If @error Then ContinueLoop ; eliminate accidental blank lines. Help file StringSplit: "@error = 1 when no delimiters were found"

    If $sDate <> $aTemp[3] Then ; $sDate is the old date, $aTemp[3] is the new date.
        If $sDate Then ; always False when $li = 0 (first data line processed)
            Add_Absents($sDate) ; add eventual absents AFTER a day has been processed.
            $aUser = $aUser_Backup ; blank column 2 in $aUser, for all users, when the date changes.
            GUICtrlCreateListViewItem("", $lv) ; 1 empty line between each day processed (sort of vertical separator)
        EndIf
        $sIniFile = @ScriptDir & "\" & $aTemp[3] & ".ini"
        $iRet = FileCopy(@ScriptDir & "\" & "Users template.ini", $sIniFile, $FC_OVERWRITE) ; date changes => new ini file (based on ini template)
        If $iRet = 0 Then Exit MsgBox($MB_TOPMOST, "FileCopy error", $sIniFile) ; maybe existed read-only => overwrite fails
        $sDate = $aTemp[3] ; old date = new date
    EndIf

    $user = GetUser($aTemp[1]) ; user name
    GUICtrlCreateListViewItem($aTemp[1] &"|"& $aTemp[3] &"|"& $aTemp[4] &"|"& $user, $lv)
    If $aTemp[4] > "08:10:00" And $aTemp[4] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF) ; light blue

    If $user = "Undefined ID" Then
        $user = $aTemp[1] ; user name becomes ID (this should never happen, according to mucitbey)
        GUICtrlSetBkColor(-1, 0xFF0000) ; red
    EndIf

    $sKey = IniRead($sIniFile, $user, "Value03", "Undefined ID") ; remember Value03 = in-time
    ; $sKey has 3 possible values :
    ; 1) "" means we need to update "Value03" (1st entry for this user in Datalar.txt for this day)
    ; 2) "07:01:00" (for example) means we need to update "Value04" (2nd entry for this user in Datalar.txt for this day)
    ; 3) "Undefined ID" means... what it says (sabotage in Users.txt) then we add a new section in daily ini file, based on ID

    Select
        Case $sKey = ""
            IniWrite($sIniFile, $user, "Value02", $aTemp[3]) ; date
            IniWrite($sIniFile, $user, "Value03", $aTemp[4]) ; in-time

        Case StringRegExp($sKey, '\d\d:\d\d:\d\d') ; ex. '07:01:00'
            IniWrite($sIniFile, $user, "Value02", $aTemp[3]) ; date
            IniWrite($sIniFile, $user, "Value04", $aTemp[4]) ; out-time

        Case Else ; $sKey = "Undefined ID"
            IniWrite($sIniFile, $aTemp[1], "Value01", "Undefined ID")
            IniWrite($sIniFile, $aTemp[1], "Value02", $sDate) ; date
            IniWrite($sIniFile, $aTemp[1], "Value03", $aTemp[4]) ; in-time
            IniWrite($sIniFile, $aTemp[1], "Value04", "") ; out-time
    EndSelect
Next

If $sDate Then Add_Absents($sDate) ; add eventual absents for the last day processed.
GUISetState(@SW_SHOW)

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

Func GetUser($ID)
    For $iIndex = 0 To $iLinesUser - 1
        If $aUser[$iIndex][0] = $ID Then ExitLoop
    Next
    If $iIndex < $iLinesUser Then ; user ID found in $aUser (e.g "Users.txt")
        $aUser[$iIndex][2] = 1 ; user worked that day. Column 2 will be blanked by reusing $aUser_Backup when date changes.
        Return $aUser[$iIndex][1] ; user name
    Else ; user ID not found in "Users.txt" (this can't happen, according to mucitbey)
        Return "Undefined ID" ; do not change this line (+++)
    EndIf
EndFunc

Func Add_Absents($sDate)
    For $i = 0 To $iLinesUser - 1
        If Not $aUser[$i][2] Then ; user was absent that day
            ; add 1 line in ListView for the absent user (with a blank time)
            GUICtrlCreateListViewItem($aUser[$i][0] &"|"& $sDate &"|"& "" &"|"& $aUser[$i][1], $lv)
            ; update 1 line in ini file for the absent user (update the date line, e.g. Value02)
            IniWrite($sIniFile, $aUser[$i][1], "Value02", $sDate) ; date
        EndIf
    Next
EndFunc

 

 

 

Users.txt
00000001=Adriana Francesca Lima
00000010=Candice Swanepoel
00000017=Gisele Bündchen
00000020=Kendall Jenner

Datalar.txt
001,00000001,00,12.04.2023 07:01:00
001,00000010,00,12.04.2023 07:10:00
001,00000001,00,12.04.2023 16:01:00
001,00000010,00,12.04.2023 16:10:00
001,00000020,00,12.04.2023 19:20:00
001,00000020,00,13.04.2023 06:20:00
001,00000999,00,13.04.2023 06:59:00
001,00000001,00,13.04.2023 07:01:00
001,00000017,00,13.04.2023 07:17:00
001,00000001,00,13.04.2023 16:01:00
001,00000017,00,13.04.2023 16:17:00

pixelsearch.png

     #pixelsearch I did as you said, the result is as you said. Good luck with your spirit. It's nice that #ioa747 shows the check-in time and check-out time in the same column. I like this look a little more.

     Is it possible to change the time(input) time(output) in the listview for this script of yours?

Edited by mucitbey
Addition
Link to comment
Share on other sites

21 hours ago, ioa747 said:

I also adapted the extended version

; https://www.autoitscript.com/forum/topic/210069-txt-split-to-ini-file/?do=findComment&comment=1517679
#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 ;-w 5 -w 6 -w 7
#include <Misc.au3>
#include <File.au3>
#include <Date.au3>
#include <Array.au3>
#include <GuiComboBox.au3>
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>

_Singleton(@ScriptName, 0)

Global $nMsg, $hGui, $idCombo, $lv, $CurUser

Global $aUsers = WriteAllUserData()
Global $aData = FindAllIniFile(@ScriptDir & "\Data\")

AddAbsentUser()
MakeMyGuiList()

HotKeySet("{HOME}", "MyArrayDisplay")

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $idCombo
            _GUICtrlComboBox_GetLBText($idCombo, _GUICtrlComboBox_GetCurSel($idCombo), $CurUser)
            UpDadeMyGuiList($CurUser)
        Case $GUI_EVENT_CLOSE
            GUIDelete()
            Exit
    EndSwitch
WEnd

;----------------------------------------------------------------------------------------
Func WriteAllUserData()  ; Make all ini files
    Local $aDatalar, $aUsers, $UserName, $aTemp, $IniFile, $aSpl, $sDate

    _FileReadToArray("Datalar.txt", $aDatalar, $FRTA_NOCOUNT)
    _FileReadToArray("Users.txt", $aUsers, $FRTA_COUNT, "=")

    Local $iLines = UBound($aDatalar)

    $sDate = ''

    For $i = 0 To $iLines - 1
        $aTemp = StringSplit($aDatalar[$i], ", ", $STR_NOCOUNT)
        $UserName = GetUserName($aUsers, $aTemp[1])

        ; if no user skip
        If $UserName <> "" Then
            If $sDate <> $aTemp[3] Then $sDate = $aTemp[3]

;~          ; format date 00.00.0000 for ini FileName
;~          $aSpl = StringSplit($sDate, ".")
;~          If StringLen($aSpl[1]) = 1 Then $aSpl[1] = "0" & $aSpl[1]
;~          $IniFile = $aSpl[1] & "." & $aSpl[2] & "." & $aSpl[3] & ".ini"
            $IniFile = $sDate & ".ini"

            ;write ini
            If IniRead(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value01", "Non-existing key") = "Non-existing key" Then
                IniWrite(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value01", $aTemp[1])
                IniWrite(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value02", $aTemp[3])
                IniWrite(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value03", $aTemp[4])
            Else
                If IniRead(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value03", "<UNKNOWN>") <> $aTemp[4] Then
                    IniWrite(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value04", $aTemp[4])
                EndIf
            EndIf
        EndIf
    Next
    Return $aUsers
EndFunc   ;==>WriteAllUserData
;----------------------------------------------------------------------------------------
Func GetUserName($aUsers, $ID)  ; ID to User Name
    Local $iIndex = _ArraySearch($aUsers, $ID)
    If $iIndex <> -1 Then
        Return StringStripWS($aUsers[$iIndex][1], $STR_STRIPLEADING + $STR_STRIPTRAILING + $STR_STRIPSPACES)
    Else
        Return ""
    EndIf
EndFunc   ;==>GetUserName
;----------------------------------------------------------------------------------------
Func FindAllIniFile($sStartPath = "")  ; Find All Ini File
    If $sStartPath = "" Then $sStartPath = @ScriptDir
    Local $aArray[1][8]
    $aArray[0][0] = 0 ; "index"
    $aArray[0][1] = "UserID"
    $aArray[0][2] = "UserName"
    $aArray[0][3] = "Date"
    $aArray[0][4] = "Start"
    $aArray[0][5] = "End"
    $aArray[0][6] = "Time"
    $aArray[0][7] = "idItem"

    Local $ArraySrtfiles = _FileListToArrayRec($sStartPath, "*.ini", $FLTAR_FILES, $FLTAR_RECUR)
    If Not IsArray($ArraySrtfiles) Then
        ConsoleWrite($sStartPath & " = Invalid input path" & @CRLF)
        Return
    Else
        For $x = 1 To $ArraySrtfiles[0]
            ;ConsoleWrite($sStartPath & $ArraySrtfiles[$x]& @CRLF)
            ReadIniToArray($aArray, $sStartPath & $ArraySrtfiles[$x])
        Next
        Return $aArray
    EndIf
EndFunc   ;==>FindAllIniFile
;----------------------------------------------------------------------------------------
Func ReadIniToArray(ByRef $aArray, $TxtFile)  ; Read Ini To Array

    Local $index

    ;Read the INI section names. This will return a 1 dimensional array.
    Local $aSections = IniReadSectionNames($TxtFile)
    ;Check if an error occurred.
    If Not @error Then
        ;Enumerate through the array displaying the section names.
        For $i = 1 To $aSections[0]
            ReDim $aArray[UBound($aArray) + 1][8]
            $aArray[0][0] += 1
            $index = $aArray[0][0]

            $aArray[$index][0] = $index ;"index"
            $aArray[$index][1] = IniRead($TxtFile, $aSections[$i], "Value01", "Null") ;"UserID"
            $aArray[$index][2] = $aSections[$i] ;"UserName"
            $aArray[$index][3] = IniRead($TxtFile, $aSections[$i], "Value02", "Null") ;"Date"
            $aArray[$index][4] = IniRead($TxtFile, $aSections[$i], "Value03", "Null") ;"Start"
            $aArray[$index][5] = IniRead($TxtFile, $aSections[$i], "Value04", "Null") ;"End"
            $aArray[$index][6] = "" ;"Time"
        Next
    EndIf

EndFunc   ;==>ReadIniToArray
;----------------------------------------------------------------------------------------
Func MakeMyGuiList()  ; GUI Create
    $hGui = GUICreate("_ank_ File Splitting", 510, 560, -1, -1)

    $lv = GUICtrlCreateListView("CART ID  |DATE  |START  |END  |TIME|NAME AND SURNAME", 10, 30, 490, 520)
    Local $sLine
    For $i = 1 To $aData[0][0]
        $sLine = $aData[$i][1] & "|" & $aData[$i][3] & "|" & $aData[$i][4] & "|"
        $sLine &= $aData[$i][5] & "|" & TimeDiff($aData[$i][4], $aData[$i][5]) & "|" & $aData[$i][2]
        $aData[$i][7] = GUICtrlCreateListViewItem($sLine, $lv)
        If $aData[$i][4] > "08:10:00" And $aData[$i][4] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
        If $aData[$i][5] > "08:10:00" And $aData[$i][5] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
        If $aData[$i][4] = "Null" Or $aData[$i][5] = "Null" Then GUICtrlSetBkColor(-1, 0xFFE5FF)
    Next

    $idCombo = GUICtrlCreateCombo("Select User", 10, 1, 490, 25, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL))
    GUICtrlSetFont(-1, 12, 400, 0, "MS Sans Serif")
    For $i = 1 To $aUsers[0][0]
        _GUICtrlComboBox_AddString($idCombo, $aUsers[$i][1])
    Next

    GUISetState(@SW_SHOW)
EndFunc   ;==>MakeMyGuiList
;----------------------------------------------------------------------------------------
Func UpDadeMyGuiList($Filter)

    ; delete items
    Local $hlv = GUICtrlGetHandle($lv)
    _GUICtrlListView_DeleteAllItems($hlv)

    Local $sLine
    ; ReMake items
    For $i = 1 To $aData[0][0]
        If $Filter = "Select User" Then
            $sLine = $aData[$i][1] & "|" & $aData[$i][3] & "|" & $aData[$i][4] & "|"
            $sLine &= $aData[$i][5] & "|" & TimeDiff($aData[$i][4], $aData[$i][5]) & "|" & $aData[$i][2]
            $aData[$i][7] = GUICtrlCreateListViewItem($sLine, $lv)
            If $aData[$i][4] > "08:10:00" And $aData[$i][4] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
            If $aData[$i][5] > "08:10:00" And $aData[$i][5] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
            If $aData[$i][4] = "Null" Or $aData[$i][5] = "Null" Then GUICtrlSetBkColor(-1, 0xFFE5FF)
            ContinueLoop
        Else
            If $aData[$i][2] = $Filter Then
                $sLine = $aData[$i][1] & "|" & $aData[$i][3] & "|" & $aData[$i][4] & "|"
                $sLine &= $aData[$i][5] & "|" & TimeDiff($aData[$i][4], $aData[$i][5]) & "|" & $aData[$i][2]
                $aData[$i][7] = GUICtrlCreateListViewItem($sLine, $lv)
                If $aData[$i][4] > "08:10:00" And $aData[$i][4] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
                If $aData[$i][5] > "08:10:00" And $aData[$i][5] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
                If $aData[$i][4] = "Null" Or $aData[$i][5] = "Null" Then GUICtrlSetBkColor(-1, 0xFFE5FF)
            Else
                $aData[$i][7] = ""
            EndIf
        EndIf
    Next

EndFunc   ;==>UpDadeMyGuiList
;----------------------------------------------------------------------------------------
Func AddAbsentUser()

    Local $sLine, $IniFile, $aSpl, $aArray = $aData

    ;*[Add Absent User to $aData Array
    Local $aDateUnique = _ArrayUnique($aArray, 3, 1)
    For $d = 1 To $aDateUnique[0]
        For $i = 1 To $aUsers[0][0]
            If _GetThis($aUsers[$i][0] & "-" & $aDateUnique[$d]) = -1 Then
                $aData[0][0] += 1
                $sLine = $aData[0][0] & "|" & $aUsers[$i][0] & "|" & $aUsers[$i][1] & "|" & $aDateUnique[$d] & "|Null|Null"
                _ArrayAdd($aData, $sLine)
            EndIf
        Next
    Next
    ;Add Absent User to $aData Array]*

    ;*[proper Array Sort order
    For $i = 1 To $aData[0][0]
        ; format date YYYY.MM.DD.HH.MM.SS
        $aSpl = StringSplit($aData[$i][3], ".")
        If StringLen($aSpl[1]) = 1 Then $aSpl[1] = "0" & $aSpl[1]
        $sLine = $aSpl[3] & "." & $aSpl[2] & "." & $aSpl[1] & "." & $aData[$i][4]
        $aData[$i][0] = $sLine
    Next
    _ArraySort($aData, 0, 1)
    For $i = 1 To $aData[0][0]
        $aData[$i][0] = $i
    Next
    ;proper Array Sort order]*

    ;*[Write $aData Array to ini
    For $i = 1 To $aData[0][0]
;~      ; format date 00.00.0000 for ini FileName
;~      $aSpl = StringSplit($aData[$i][3], ".")
;~      If StringLen($aSpl[1]) = 1 Then $aSpl[1] = "0" & $aSpl[1]
;~      $IniFile = $aSpl[1] & "." & $aSpl[2] & "." & $aSpl[3] & ".ini"
        $IniFile = $aData[$i][3] & ".ini"

        ;write ini
        IniWrite(@ScriptDir & "\Data\" & $IniFile, $aData[$i][2], "Value01", $aData[$i][1])
        IniWrite(@ScriptDir & "\Data\" & $IniFile, $aData[$i][2], "Value02", $aData[$i][3])
        IniWrite(@ScriptDir & "\Data\" & $IniFile, $aData[$i][2], "Value03", $aData[$i][4])
        IniWrite(@ScriptDir & "\Data\" & $IniFile, $aData[$i][2], "Value04", $aData[$i][5])
    Next
    ;Write $aData Array to ini]*

EndFunc   ;==>AddAbsentUser
;----------------------------------------------------------------------------------------
Func _GetThis($Txt)
    Local $sIndex
    For $i = 1 To $aData[0][0]
        $sIndex = -1
        If $aData[$i][1] & "-" & $aData[$i][3] = $Txt Then
            $sIndex = $i
            ExitLoop
        EndIf
    Next
    Return $sIndex
EndFunc   ;==>_GetThis
;----------------------------------------------------------------------------------------
Func TimeDiff($sStartTime, $sEndTime)
    Local $H, $M, $sDiff, $aSpl1, $aSpl2
    $aSpl1 = StringSplit($sStartTime, ":")
    $aSpl2 = StringSplit($sEndTime, ":")
    If $aSpl1[0] + $aSpl2[0] <> 6 Then
        ;ConsoleWrite("! Error No valid time format" & @CRLF)
        Return SetError(1, 0, "")
    EndIf
    ; ** 2020/01/01 ** since all the results are from the same date
    $M = _DateDiff('n', "2020/01/01 " & $sStartTime, "2020/01/01 " & $sEndTime)
    $H = Floor($M / 60)
    $M = Mod($M, 60)
    $sDiff = StringFormat("%i:%02i", $H, $M)
    Return $sDiff
EndFunc   ;==>TimeDiff
;----------------------------------------------------------------------------------------
Func MyArrayDisplay()
    _ArrayDisplay($aData, "$aData")
EndFunc   ;==>MyArrayDisplay
;----------------------------------------------------------------------------------------

 

Thanks for sharing, the design and visuality are very nice, it is very useful in the updates you add. But after a short trial, I detected two errors. In the Users.txt file I am using now (as 00000104=Diego MARADONA), only the data with the registration number is written to the Date ini file with the username "2". Also, Select USER shows only 29 records in the ComboBox. There are more than 100 data in the Users.txt file that I am currently using as an example.

001.png

002.png

Link to comment
Share on other sites

@mucitbey  The fact that the combination doesn't show all the names has to do with _FileReadToArray Users.txt
                          (which doesn't match well, check the Users.txt for the right format)

as for Maradona, I registered it, it showed me normally, in the sample data I have,
(username "2" comes from first row (0 index) of table "Users.txt" for 2 columns)

I added 2 hotkeys to the script so you can check arrays

HotKeySet("{HOME}", "aDataDisplay") ;Display the $aData Array
HotKeySet("{END}", "aUsersDisplay") ;Display the $aUsers Array

I also changed the function Func GetUserName($aUsers, $ID)  ; ID to User Name

; https://www.autoitscript.com/forum/topic/210069-txt-split-to-ini-file/?do=findComment&comment=1517679
#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 ;-w 5 -w 6 -w 7
#include <Misc.au3>
#include <File.au3>
#include <Date.au3>
#include <Array.au3>
#include <GuiComboBox.au3>
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>

_Singleton(@ScriptName, 0)

Global $nMsg, $hGui, $idCombo, $lv, $CurUser

Global $aUsers = WriteAllUserData()
Global $aData = FindAllIniFile(@ScriptDir & "\Data\")

AddAbsentUser()
MakeMyGuiList()

HotKeySet("{HOME}", "aDataDisplay") ;Display the $aData Array
HotKeySet("{END}", "aUsersDisplay") ;Display the $aUsers Array

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $idCombo
            _GUICtrlComboBox_GetLBText($idCombo, _GUICtrlComboBox_GetCurSel($idCombo), $CurUser)
            UpDadeMyGuiList($CurUser)
        Case $GUI_EVENT_CLOSE
            GUIDelete()
            Exit
    EndSwitch
WEnd

;----------------------------------------------------------------------------------------
Func WriteAllUserData()  ; Make all ini files
    Local $aDatalar, $aUsers, $UserName, $aTemp, $IniFile, $aSpl, $sDate

    _FileReadToArray("Datalar.txt", $aDatalar, $FRTA_NOCOUNT)
    _FileReadToArray("Users.txt", $aUsers, $FRTA_COUNT, "=")

    Local $iLines = UBound($aDatalar)

    $sDate = ''

    For $i = 0 To $iLines - 1
        $aTemp = StringSplit($aDatalar[$i], ", ", $STR_NOCOUNT)
        $UserName = GetUserName($aUsers, $aTemp[1])

        ; if no user skip
        If $UserName <> "" Then
            If $sDate <> $aTemp[3] Then $sDate = $aTemp[3]

;~          ; format date 00.00.0000 for ini FileName
;~          $aSpl = StringSplit($sDate, ".")
;~          If StringLen($aSpl[1]) = 1 Then $aSpl[1] = "0" & $aSpl[1]
;~          $IniFile = $aSpl[1] & "." & $aSpl[2] & "." & $aSpl[3] & ".ini"
            $IniFile = $sDate & ".ini"

            ;write ini
            If IniRead(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value01", "Non-existing key") = "Non-existing key" Then
                IniWrite(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value01", $aTemp[1])
                IniWrite(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value02", $aTemp[3])
                IniWrite(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value03", $aTemp[4])
            Else
                If IniRead(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value03", "<UNKNOWN>") <> $aTemp[4] Then
                    IniWrite(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value04", $aTemp[4])
                EndIf
            EndIf
        EndIf
    Next
    Return $aUsers
EndFunc   ;==>WriteAllUserData
;----------------------------------------------------------------------------------------
Func GetUserName($aUsers, $ID)  ; ID to User Name
    Local $sName
    For $i = 1 To $aUsers[0][0]
        $sName = ""
        If $aUsers[$i][0] = $ID Then
            $sName = $aUsers[$i][1]
            ExitLoop
        EndIf
    Next
    Return $sName
EndFunc   ;==>GetUserName
;----------------------------------------------------------------------------------------
Func FindAllIniFile($sStartPath = "")  ; Find All Ini File
    If $sStartPath = "" Then $sStartPath = @ScriptDir
    Local $aArray[1][8]
    $aArray[0][0] = 0 ; "index"
    $aArray[0][1] = "UserID"
    $aArray[0][2] = "UserName"
    $aArray[0][3] = "Date"
    $aArray[0][4] = "Start"
    $aArray[0][5] = "End"
    $aArray[0][6] = "Time"
    $aArray[0][7] = "idItem"

    Local $ArraySrtfiles = _FileListToArrayRec($sStartPath, "*.ini", $FLTAR_FILES, $FLTAR_RECUR)
    If Not IsArray($ArraySrtfiles) Then
        ConsoleWrite($sStartPath & " = Invalid input path" & @CRLF)
        Return
    Else
        For $x = 1 To $ArraySrtfiles[0]
            ;ConsoleWrite($sStartPath & $ArraySrtfiles[$x]& @CRLF)
            ReadIniToArray($aArray, $sStartPath & $ArraySrtfiles[$x])
        Next
        Return $aArray
    EndIf
EndFunc   ;==>FindAllIniFile
;----------------------------------------------------------------------------------------
Func ReadIniToArray(ByRef $aArray, $TxtFile)  ; Read Ini To Array

    Local $index

    ;Read the INI section names. This will return a 1 dimensional array.
    Local $aSections = IniReadSectionNames($TxtFile)
    ;Check if an error occurred.
    If Not @error Then
        ;Enumerate through the array displaying the section names.
        For $i = 1 To $aSections[0]
            ReDim $aArray[UBound($aArray) + 1][8]
            $aArray[0][0] += 1
            $index = $aArray[0][0]

            $aArray[$index][0] = $index ;"index"
            $aArray[$index][1] = IniRead($TxtFile, $aSections[$i], "Value01", "Null") ;"UserID"
            $aArray[$index][2] = $aSections[$i] ;"UserName"
            $aArray[$index][3] = IniRead($TxtFile, $aSections[$i], "Value02", "Null") ;"Date"
            $aArray[$index][4] = IniRead($TxtFile, $aSections[$i], "Value03", "Null") ;"Start"
            $aArray[$index][5] = IniRead($TxtFile, $aSections[$i], "Value04", "Null") ;"End"
            $aArray[$index][6] = "" ;"Time"
        Next
    EndIf

EndFunc   ;==>ReadIniToArray
;----------------------------------------------------------------------------------------
Func MakeMyGuiList()  ; GUI Create
    $hGui = GUICreate("_ank_ File Splitting", 510, 560, -1, -1)

    $lv = GUICtrlCreateListView("CART ID  |DATE  |START  |END  |TIME|NAME AND SURNAME", 10, 30, 490, 520)
    Local $sLine
    For $i = 1 To $aData[0][0]
        $sLine = $aData[$i][1] & "|" & $aData[$i][3] & "|" & $aData[$i][4] & "|"
        $sLine &= $aData[$i][5] & "|" & TimeDiff($aData[$i][4], $aData[$i][5]) & "|" & $aData[$i][2]
        $aData[$i][7] = GUICtrlCreateListViewItem($sLine, $lv)
        If $aData[$i][4] > "08:10:00" And $aData[$i][4] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
        If $aData[$i][5] > "08:10:00" And $aData[$i][5] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
        If $aData[$i][4] = "Null" Or $aData[$i][5] = "Null" Then GUICtrlSetBkColor(-1, 0xFFE5FF)
    Next

    $idCombo = GUICtrlCreateCombo("Select User", 10, 1, 490, 25)
    GUICtrlSetFont(-1, 12, 400, 0, "MS Sans Serif")
    For $i = 1 To $aUsers[0][0]
        _GUICtrlComboBox_AddString($idCombo, $aUsers[$i][1])
    Next

    GUISetState(@SW_SHOW)
EndFunc   ;==>MakeMyGuiList
;----------------------------------------------------------------------------------------
Func UpDadeMyGuiList($Filter)

    ; delete items
    Local $hlv = GUICtrlGetHandle($lv)
    _GUICtrlListView_DeleteAllItems($hlv)

    Local $sLine
    ; ReMake items
    For $i = 1 To $aData[0][0]
        If $Filter = "Select User" Then
            $sLine = $aData[$i][1] & "|" & $aData[$i][3] & "|" & $aData[$i][4] & "|"
            $sLine &= $aData[$i][5] & "|" & TimeDiff($aData[$i][4], $aData[$i][5]) & "|" & $aData[$i][2]
            $aData[$i][7] = GUICtrlCreateListViewItem($sLine, $lv)
            If $aData[$i][4] > "08:10:00" And $aData[$i][4] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
            If $aData[$i][5] > "08:10:00" And $aData[$i][5] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
            If $aData[$i][4] = "Null" Or $aData[$i][5] = "Null" Then GUICtrlSetBkColor(-1, 0xFFE5FF)
            ContinueLoop
        Else
            If $aData[$i][2] = $Filter Then
                $sLine = $aData[$i][1] & "|" & $aData[$i][3] & "|" & $aData[$i][4] & "|"
                $sLine &= $aData[$i][5] & "|" & TimeDiff($aData[$i][4], $aData[$i][5]) & "|" & $aData[$i][2]
                $aData[$i][7] = GUICtrlCreateListViewItem($sLine, $lv)
                If $aData[$i][4] > "08:10:00" And $aData[$i][4] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
                If $aData[$i][5] > "08:10:00" And $aData[$i][5] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
                If $aData[$i][4] = "Null" Or $aData[$i][5] = "Null" Then GUICtrlSetBkColor(-1, 0xFFE5FF)
            Else
                $aData[$i][7] = ""
            EndIf
        EndIf
    Next

EndFunc   ;==>UpDadeMyGuiList
;----------------------------------------------------------------------------------------
Func AddAbsentUser()

    Local $sLine, $IniFile, $aSpl, $aArray = $aData

    ;*[Add Absent User to $aData Array
    Local $aDateUnique = _ArrayUnique($aArray, 3, 1)
    For $d = 1 To $aDateUnique[0]
        For $i = 1 To $aUsers[0][0]
            If _GetThis($aUsers[$i][0] & "-" & $aDateUnique[$d]) = -1 Then
                $aData[0][0] += 1
                $sLine = $aData[0][0] & "|" & $aUsers[$i][0] & "|" & $aUsers[$i][1] & "|" & $aDateUnique[$d] & "|Null|Null"
                _ArrayAdd($aData, $sLine)
            EndIf
        Next
    Next
    ;Add Absent User to $aData Array]*

    ;*[proper Array Sort order
    For $i = 1 To $aData[0][0]
        ; format date YYYY.MM.DD.HH.MM.SS
        $aSpl = StringSplit($aData[$i][3], ".")
        If StringLen($aSpl[1]) = 1 Then $aSpl[1] = "0" & $aSpl[1]
        $sLine = $aSpl[3] & "." & $aSpl[2] & "." & $aSpl[1] & "." & $aData[$i][4]
        $aData[$i][0] = $sLine
    Next
    _ArraySort($aData, 0, 1)
    For $i = 1 To $aData[0][0]
        $aData[$i][0] = $i
    Next
    ;proper Array Sort order]*

    ;*[Write $aData Array to ini
    For $i = 1 To $aData[0][0]
;~      ; format date 00.00.0000 for ini FileName
;~      $aSpl = StringSplit($aData[$i][3], ".")
;~      If StringLen($aSpl[1]) = 1 Then $aSpl[1] = "0" & $aSpl[1]
;~      $IniFile = $aSpl[1] & "." & $aSpl[2] & "." & $aSpl[3] & ".ini"
        $IniFile = $aData[$i][3] & ".ini"

        ;write ini
        IniWrite(@ScriptDir & "\Data\" & $IniFile, $aData[$i][2], "Value01", $aData[$i][1])
        IniWrite(@ScriptDir & "\Data\" & $IniFile, $aData[$i][2], "Value02", $aData[$i][3])
        IniWrite(@ScriptDir & "\Data\" & $IniFile, $aData[$i][2], "Value03", $aData[$i][4])
        IniWrite(@ScriptDir & "\Data\" & $IniFile, $aData[$i][2], "Value04", $aData[$i][5])
    Next
    ;Write $aData Array to ini]*

EndFunc   ;==>AddAbsentUser
;----------------------------------------------------------------------------------------
Func _GetThis($Txt)
    Local $sIndex
    For $i = 1 To $aData[0][0]
        $sIndex = -1
        If $aData[$i][1] & "-" & $aData[$i][3] = $Txt Then
            $sIndex = $i
            ExitLoop
        EndIf
    Next
    Return $sIndex
EndFunc   ;==>_GetThis
;----------------------------------------------------------------------------------------
Func TimeDiff($sStartTime, $sEndTime)
    Local $H, $M, $sDiff, $aSpl1, $aSpl2
    $aSpl1 = StringSplit($sStartTime, ":")
    $aSpl2 = StringSplit($sEndTime, ":")
    If $aSpl1[0] + $aSpl2[0] <> 6 Then
        ;ConsoleWrite("! Error No valid time format" & @CRLF)
        Return SetError(1, 0, "")
    EndIf
    ; ** 2020/01/01 ** since all the results are from the same date
    $M = _DateDiff('n', "2020/01/01 " & $sStartTime, "2020/01/01 " & $sEndTime)
    $H = Floor($M / 60)
    $M = Mod($M, 60)
    $sDiff = StringFormat("%i:%02i", $H, $M)
    Return $sDiff
EndFunc   ;==>TimeDiff
;----------------------------------------------------------------------------------------
Func aDataDisplay()
    _ArrayDisplay($aData, "$aData")
EndFunc   ;==>MyArrayDisplay
;----------------------------------------------------------------------------------------
Func aUsersDisplay()
    _ArrayDisplay($aUsers, "$aUsers")
EndFunc

 

Edited by ioa747

I know that I know nothing

Link to comment
Share on other sites

38 minutes ago, ioa747 said:

@mucitbey  The fact that the combination doesn't show all the names has to do with _FileReadToArray Users.txt
                          (which doesn't match well, check the Users.txt for the right format)

as for Maradona, I registered it, it showed me normally, in the sample data I have,
(username "2" comes from first row (0 index) of table "Users.txt" for 2 columns)

I added 2 hotkeys to the script so you can check arrays

HotKeySet("{HOME}", "aDataDisplay") ;Display the $aData Array
HotKeySet("{END}", "aUsersDisplay") ;Display the $aUsers Array

I also changed the function Func GetUserName($aUsers, $ID)  ; ID to User Name

; https://www.autoitscript.com/forum/topic/210069-txt-split-to-ini-file/?do=findComment&comment=1517679
#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 ;-w 5 -w 6 -w 7
#include <Misc.au3>
#include <File.au3>
#include <Date.au3>
#include <Array.au3>
#include <GuiComboBox.au3>
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>

_Singleton(@ScriptName, 0)

Global $nMsg, $hGui, $idCombo, $lv, $CurUser

Global $aUsers = WriteAllUserData()
Global $aData = FindAllIniFile(@ScriptDir & "\Data\")

AddAbsentUser()
MakeMyGuiList()

HotKeySet("{HOME}", "aDataDisplay") ;Display the $aData Array
HotKeySet("{END}", "aUsersDisplay") ;Display the $aUsers Array

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $idCombo
            _GUICtrlComboBox_GetLBText($idCombo, _GUICtrlComboBox_GetCurSel($idCombo), $CurUser)
            UpDadeMyGuiList($CurUser)
        Case $GUI_EVENT_CLOSE
            GUIDelete()
            Exit
    EndSwitch
WEnd

;----------------------------------------------------------------------------------------
Func WriteAllUserData()  ; Make all ini files
    Local $aDatalar, $aUsers, $UserName, $aTemp, $IniFile, $aSpl, $sDate

    _FileReadToArray("Datalar.txt", $aDatalar, $FRTA_NOCOUNT)
    _FileReadToArray("Users.txt", $aUsers, $FRTA_COUNT, "=")

    Local $iLines = UBound($aDatalar)

    $sDate = ''

    For $i = 0 To $iLines - 1
        $aTemp = StringSplit($aDatalar[$i], ", ", $STR_NOCOUNT)
        $UserName = GetUserName($aUsers, $aTemp[1])

        ; if no user skip
        If $UserName <> "" Then
            If $sDate <> $aTemp[3] Then $sDate = $aTemp[3]

;~          ; format date 00.00.0000 for ini FileName
;~          $aSpl = StringSplit($sDate, ".")
;~          If StringLen($aSpl[1]) = 1 Then $aSpl[1] = "0" & $aSpl[1]
;~          $IniFile = $aSpl[1] & "." & $aSpl[2] & "." & $aSpl[3] & ".ini"
            $IniFile = $sDate & ".ini"

            ;write ini
            If IniRead(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value01", "Non-existing key") = "Non-existing key" Then
                IniWrite(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value01", $aTemp[1])
                IniWrite(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value02", $aTemp[3])
                IniWrite(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value03", $aTemp[4])
            Else
                If IniRead(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value03", "<UNKNOWN>") <> $aTemp[4] Then
                    IniWrite(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value04", $aTemp[4])
                EndIf
            EndIf
        EndIf
    Next
    Return $aUsers
EndFunc   ;==>WriteAllUserData
;----------------------------------------------------------------------------------------
Func GetUserName($aUsers, $ID)  ; ID to User Name
    Local $sName
    For $i = 1 To $aUsers[0][0]
        $sName = ""
        If $aUsers[$i][0] = $ID Then
            $sName = $aUsers[$i][1]
            ExitLoop
        EndIf
    Next
    Return $sName
EndFunc   ;==>GetUserName
;----------------------------------------------------------------------------------------
Func FindAllIniFile($sStartPath = "")  ; Find All Ini File
    If $sStartPath = "" Then $sStartPath = @ScriptDir
    Local $aArray[1][8]
    $aArray[0][0] = 0 ; "index"
    $aArray[0][1] = "UserID"
    $aArray[0][2] = "UserName"
    $aArray[0][3] = "Date"
    $aArray[0][4] = "Start"
    $aArray[0][5] = "End"
    $aArray[0][6] = "Time"
    $aArray[0][7] = "idItem"

    Local $ArraySrtfiles = _FileListToArrayRec($sStartPath, "*.ini", $FLTAR_FILES, $FLTAR_RECUR)
    If Not IsArray($ArraySrtfiles) Then
        ConsoleWrite($sStartPath & " = Invalid input path" & @CRLF)
        Return
    Else
        For $x = 1 To $ArraySrtfiles[0]
            ;ConsoleWrite($sStartPath & $ArraySrtfiles[$x]& @CRLF)
            ReadIniToArray($aArray, $sStartPath & $ArraySrtfiles[$x])
        Next
        Return $aArray
    EndIf
EndFunc   ;==>FindAllIniFile
;----------------------------------------------------------------------------------------
Func ReadIniToArray(ByRef $aArray, $TxtFile)  ; Read Ini To Array

    Local $index

    ;Read the INI section names. This will return a 1 dimensional array.
    Local $aSections = IniReadSectionNames($TxtFile)
    ;Check if an error occurred.
    If Not @error Then
        ;Enumerate through the array displaying the section names.
        For $i = 1 To $aSections[0]
            ReDim $aArray[UBound($aArray) + 1][8]
            $aArray[0][0] += 1
            $index = $aArray[0][0]

            $aArray[$index][0] = $index ;"index"
            $aArray[$index][1] = IniRead($TxtFile, $aSections[$i], "Value01", "Null") ;"UserID"
            $aArray[$index][2] = $aSections[$i] ;"UserName"
            $aArray[$index][3] = IniRead($TxtFile, $aSections[$i], "Value02", "Null") ;"Date"
            $aArray[$index][4] = IniRead($TxtFile, $aSections[$i], "Value03", "Null") ;"Start"
            $aArray[$index][5] = IniRead($TxtFile, $aSections[$i], "Value04", "Null") ;"End"
            $aArray[$index][6] = "" ;"Time"
        Next
    EndIf

EndFunc   ;==>ReadIniToArray
;----------------------------------------------------------------------------------------
Func MakeMyGuiList()  ; GUI Create
    $hGui = GUICreate("_ank_ File Splitting", 510, 560, -1, -1)

    $lv = GUICtrlCreateListView("CART ID  |DATE  |START  |END  |TIME|NAME AND SURNAME", 10, 30, 490, 520)
    Local $sLine
    For $i = 1 To $aData[0][0]
        $sLine = $aData[$i][1] & "|" & $aData[$i][3] & "|" & $aData[$i][4] & "|"
        $sLine &= $aData[$i][5] & "|" & TimeDiff($aData[$i][4], $aData[$i][5]) & "|" & $aData[$i][2]
        $aData[$i][7] = GUICtrlCreateListViewItem($sLine, $lv)
        If $aData[$i][4] > "08:10:00" And $aData[$i][4] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
        If $aData[$i][5] > "08:10:00" And $aData[$i][5] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
        If $aData[$i][4] = "Null" Or $aData[$i][5] = "Null" Then GUICtrlSetBkColor(-1, 0xFFE5FF)
    Next

    $idCombo = GUICtrlCreateCombo("Select User", 10, 1, 490, 25)
    GUICtrlSetFont(-1, 12, 400, 0, "MS Sans Serif")
    For $i = 1 To $aUsers[0][0]
        _GUICtrlComboBox_AddString($idCombo, $aUsers[$i][1])
    Next

    GUISetState(@SW_SHOW)
EndFunc   ;==>MakeMyGuiList
;----------------------------------------------------------------------------------------
Func UpDadeMyGuiList($Filter)

    ; delete items
    Local $hlv = GUICtrlGetHandle($lv)
    _GUICtrlListView_DeleteAllItems($hlv)

    Local $sLine
    ; ReMake items
    For $i = 1 To $aData[0][0]
        If $Filter = "Select User" Then
            $sLine = $aData[$i][1] & "|" & $aData[$i][3] & "|" & $aData[$i][4] & "|"
            $sLine &= $aData[$i][5] & "|" & TimeDiff($aData[$i][4], $aData[$i][5]) & "|" & $aData[$i][2]
            $aData[$i][7] = GUICtrlCreateListViewItem($sLine, $lv)
            If $aData[$i][4] > "08:10:00" And $aData[$i][4] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
            If $aData[$i][5] > "08:10:00" And $aData[$i][5] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
            If $aData[$i][4] = "Null" Or $aData[$i][5] = "Null" Then GUICtrlSetBkColor(-1, 0xFFE5FF)
            ContinueLoop
        Else
            If $aData[$i][2] = $Filter Then
                $sLine = $aData[$i][1] & "|" & $aData[$i][3] & "|" & $aData[$i][4] & "|"
                $sLine &= $aData[$i][5] & "|" & TimeDiff($aData[$i][4], $aData[$i][5]) & "|" & $aData[$i][2]
                $aData[$i][7] = GUICtrlCreateListViewItem($sLine, $lv)
                If $aData[$i][4] > "08:10:00" And $aData[$i][4] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
                If $aData[$i][5] > "08:10:00" And $aData[$i][5] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
                If $aData[$i][4] = "Null" Or $aData[$i][5] = "Null" Then GUICtrlSetBkColor(-1, 0xFFE5FF)
            Else
                $aData[$i][7] = ""
            EndIf
        EndIf
    Next

EndFunc   ;==>UpDadeMyGuiList
;----------------------------------------------------------------------------------------
Func AddAbsentUser()

    Local $sLine, $IniFile, $aSpl, $aArray = $aData

    ;*[Add Absent User to $aData Array
    Local $aDateUnique = _ArrayUnique($aArray, 3, 1)
    For $d = 1 To $aDateUnique[0]
        For $i = 1 To $aUsers[0][0]
            If _GetThis($aUsers[$i][0] & "-" & $aDateUnique[$d]) = -1 Then
                $aData[0][0] += 1
                $sLine = $aData[0][0] & "|" & $aUsers[$i][0] & "|" & $aUsers[$i][1] & "|" & $aDateUnique[$d] & "|Null|Null"
                _ArrayAdd($aData, $sLine)
            EndIf
        Next
    Next
    ;Add Absent User to $aData Array]*

    ;*[proper Array Sort order
    For $i = 1 To $aData[0][0]
        ; format date YYYY.MM.DD.HH.MM.SS
        $aSpl = StringSplit($aData[$i][3], ".")
        If StringLen($aSpl[1]) = 1 Then $aSpl[1] = "0" & $aSpl[1]
        $sLine = $aSpl[3] & "." & $aSpl[2] & "." & $aSpl[1] & "." & $aData[$i][4]
        $aData[$i][0] = $sLine
    Next
    _ArraySort($aData, 0, 1)
    For $i = 1 To $aData[0][0]
        $aData[$i][0] = $i
    Next
    ;proper Array Sort order]*

    ;*[Write $aData Array to ini
    For $i = 1 To $aData[0][0]
;~      ; format date 00.00.0000 for ini FileName
;~      $aSpl = StringSplit($aData[$i][3], ".")
;~      If StringLen($aSpl[1]) = 1 Then $aSpl[1] = "0" & $aSpl[1]
;~      $IniFile = $aSpl[1] & "." & $aSpl[2] & "." & $aSpl[3] & ".ini"
        $IniFile = $aData[$i][3] & ".ini"

        ;write ini
        IniWrite(@ScriptDir & "\Data\" & $IniFile, $aData[$i][2], "Value01", $aData[$i][1])
        IniWrite(@ScriptDir & "\Data\" & $IniFile, $aData[$i][2], "Value02", $aData[$i][3])
        IniWrite(@ScriptDir & "\Data\" & $IniFile, $aData[$i][2], "Value03", $aData[$i][4])
        IniWrite(@ScriptDir & "\Data\" & $IniFile, $aData[$i][2], "Value04", $aData[$i][5])
    Next
    ;Write $aData Array to ini]*

EndFunc   ;==>AddAbsentUser
;----------------------------------------------------------------------------------------
Func _GetThis($Txt)
    Local $sIndex
    For $i = 1 To $aData[0][0]
        $sIndex = -1
        If $aData[$i][1] & "-" & $aData[$i][3] = $Txt Then
            $sIndex = $i
            ExitLoop
        EndIf
    Next
    Return $sIndex
EndFunc   ;==>_GetThis
;----------------------------------------------------------------------------------------
Func TimeDiff($sStartTime, $sEndTime)
    Local $H, $M, $sDiff, $aSpl1, $aSpl2
    $aSpl1 = StringSplit($sStartTime, ":")
    $aSpl2 = StringSplit($sEndTime, ":")
    If $aSpl1[0] + $aSpl2[0] <> 6 Then
        ;ConsoleWrite("! Error No valid time format" & @CRLF)
        Return SetError(1, 0, "")
    EndIf
    ; ** 2020/01/01 ** since all the results are from the same date
    $M = _DateDiff('n', "2020/01/01 " & $sStartTime, "2020/01/01 " & $sEndTime)
    $H = Floor($M / 60)
    $M = Mod($M, 60)
    $sDiff = StringFormat("%i:%02i", $H, $M)
    Return $sDiff
EndFunc   ;==>TimeDiff
;----------------------------------------------------------------------------------------
Func aDataDisplay()
    _ArrayDisplay($aData, "$aData")
EndFunc   ;==>MyArrayDisplay
;----------------------------------------------------------------------------------------
Func aUsersDisplay()
    _ArrayDisplay($aUsers, "$aUsers")
EndFunc

 

Congratulations #ioa747 both problems solved. You're really great, I can't fault it for now. :thumbsup:

Link to comment
Share on other sites

I'm embedding the time difference calculation in the array to improve the gui redraw speed

; https://www.autoitscript.com/forum/topic/210069-txt-split-to-ini-file/?do=findComment&comment=1517679
#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 ;-w 5 -w 6 -w 7
#include <Misc.au3>
#include <File.au3>
#include <Date.au3>
#include <Array.au3>
#include <GuiComboBox.au3>
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>

_Singleton(@ScriptName, 0)
ToolTip("  File Splitting ", @DesktopWidth / 2, @DesktopHeight / 5, "Please wait...", 1)
Global $nMsg, $hGui, $idCombo, $lv, $CurUser

Global $aUsers = WriteAllUserData()
Global $aData = FindAllIniFile(@ScriptDir & "\Data\")

AddAbsentUser()
MakeMyGuiList()

HotKeySet("{HOME}", "aDataDisplay") ;Display the $aData Array
HotKeySet("{END}", "aUsersDisplay") ;Display the $aUsers Array

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $idCombo
            _GUICtrlComboBox_GetLBText($idCombo, _GUICtrlComboBox_GetCurSel($idCombo), $CurUser)
            UpDadeMyGuiList($CurUser)
        Case $GUI_EVENT_CLOSE
            GUIDelete()
            Exit
    EndSwitch
WEnd

;----------------------------------------------------------------------------------------
Func WriteAllUserData()  ; Make all ini files
    Local $aDatalar, $aUsers, $UserName, $aTemp, $IniFile, $aSpl, $sDate

    _FileReadToArray("Datalar.txt", $aDatalar, $FRTA_NOCOUNT)
    _FileReadToArray("Users.txt", $aUsers, $FRTA_COUNT, "=")

    Local $iLines = UBound($aDatalar)

    $sDate = ''

    For $i = 0 To $iLines - 1
        $aTemp = StringSplit($aDatalar[$i], ", ", $STR_NOCOUNT)
        $UserName = GetUserName($aUsers, $aTemp[1])

        ; if no user skip
        If $UserName <> "" Then
            If $sDate <> $aTemp[3] Then $sDate = $aTemp[3]

;~          ; format date 00.00.0000 for ini FileName
;~          $aSpl = StringSplit($sDate, ".")
;~          If StringLen($aSpl[1]) = 1 Then $aSpl[1] = "0" & $aSpl[1]
;~          $IniFile = $aSpl[1] & "." & $aSpl[2] & "." & $aSpl[3] & ".ini"
            $IniFile = $sDate & ".ini"

            ;write ini
            If IniRead(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value01", "Non-existing key") = "Non-existing key" Then
                IniWrite(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value01", $aTemp[1])
                IniWrite(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value02", $aTemp[3])
                IniWrite(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value03", $aTemp[4])
            Else
                If IniRead(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value03", "<UNKNOWN>") <> $aTemp[4] Then
                    IniWrite(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value04", $aTemp[4])
                EndIf
            EndIf
        EndIf
    Next
    Return $aUsers
EndFunc   ;==>WriteAllUserData
;----------------------------------------------------------------------------------------
Func GetUserName($aUsers, $ID)  ; ID to User Name
    Local $sName
    For $i = 1 To $aUsers[0][0]
        $sName = ""
        If $aUsers[$i][0] = $ID Then
            $sName = $aUsers[$i][1]
            ExitLoop
        EndIf
    Next
    Return $sName
EndFunc   ;==>GetUserName
;----------------------------------------------------------------------------------------
Func FindAllIniFile($sStartPath = "")  ; Find All Ini File
    If $sStartPath = "" Then $sStartPath = @ScriptDir
    Local $aArray[1][8]
    $aArray[0][0] = 0 ; "index"
    $aArray[0][1] = "UserID"
    $aArray[0][2] = "UserName"
    $aArray[0][3] = "Date"
    $aArray[0][4] = "Start"
    $aArray[0][5] = "End"
    $aArray[0][6] = "Time"
    $aArray[0][7] = "idItem"

    Local $ArraySrtfiles = _FileListToArrayRec($sStartPath, "*.ini", $FLTAR_FILES, $FLTAR_RECUR)
    If Not IsArray($ArraySrtfiles) Then
        ConsoleWrite($sStartPath & " = Invalid input path" & @CRLF)
        Return
    Else
        For $x = 1 To $ArraySrtfiles[0]
            ;ConsoleWrite($sStartPath & $ArraySrtfiles[$x]& @CRLF)
            ReadIniToArray($aArray, $sStartPath & $ArraySrtfiles[$x])
        Next
        Return $aArray
    EndIf
EndFunc   ;==>FindAllIniFile
;----------------------------------------------------------------------------------------
Func ReadIniToArray(ByRef $aArray, $TxtFile)  ; Read Ini To Array

    Local $index

    ;Read the INI section names. This will return a 1 dimensional array.
    Local $aSections = IniReadSectionNames($TxtFile)
    ;Check if an error occurred.
    If Not @error Then
        ;Enumerate through the array displaying the section names.
        For $i = 1 To $aSections[0]
            ReDim $aArray[UBound($aArray) + 1][8]
            $aArray[0][0] += 1
            $index = $aArray[0][0]

            $aArray[$index][0] = $index ;"index"
            $aArray[$index][1] = IniRead($TxtFile, $aSections[$i], "Value01", "Null") ;"UserID"
            $aArray[$index][2] = $aSections[$i] ;"UserName"
            $aArray[$index][3] = IniRead($TxtFile, $aSections[$i], "Value02", "Null") ;"Date"
            $aArray[$index][4] = IniRead($TxtFile, $aSections[$i], "Value03", "Null") ;"Start"
            $aArray[$index][5] = IniRead($TxtFile, $aSections[$i], "Value04", "Null") ;"End"
            $aArray[$index][6] = "" ;"Time"
        Next
    EndIf

EndFunc   ;==>ReadIniToArray
;----------------------------------------------------------------------------------------
Func MakeMyGuiList()  ; GUI Create
    $hGui = GUICreate("_ank_ File Splitting", 510, 560, -1, -1)

    $lv = GUICtrlCreateListView("CART ID  |DATE  |START  |END  |TIME|NAME AND SURNAME", 10, 30, 490, 520)
    Local $sLine
    For $i = 1 To $aData[0][0]
        $sLine = $aData[$i][1] & "|" & $aData[$i][3] & "|" & $aData[$i][4] & "|"
        $sLine &= $aData[$i][5] & "|" & $aData[$i][6] & "|" & $aData[$i][2]
        $aData[$i][7] = GUICtrlCreateListViewItem($sLine, $lv)
        If $aData[$i][4] > "08:10:00" And $aData[$i][4] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
        If $aData[$i][5] > "08:10:00" And $aData[$i][5] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
        If $aData[$i][4] = "Null" Or $aData[$i][5] = "Null" Then GUICtrlSetBkColor(-1, 0xFFE5FF)
    Next

    $idCombo = GUICtrlCreateCombo("Select User", 10, 1, 490, 25)
    GUICtrlSetFont(-1, 12, 400, 0, "MS Sans Serif")
    For $i = 1 To $aUsers[0][0]
        _GUICtrlComboBox_AddString($idCombo, $aUsers[$i][1])
    Next

    GUISetState(@SW_SHOW)
    ToolTip("")
EndFunc   ;==>MakeMyGuiList
;----------------------------------------------------------------------------------------
Func UpDadeMyGuiList($Filter)

    ; delete items
    Local $hlv = GUICtrlGetHandle($lv)
    _GUICtrlListView_DeleteAllItems($hlv)

    Local $sLine
    ; ReMake items
    For $i = 1 To $aData[0][0]
        If $Filter = "Select User" Then
            $sLine = $aData[$i][1] & "|" & $aData[$i][3] & "|" & $aData[$i][4] & "|"
            $sLine &= $aData[$i][5] & "|" & $aData[$i][6] & "|" & $aData[$i][2]
            $aData[$i][7] = GUICtrlCreateListViewItem($sLine, $lv)
            If $aData[$i][4] > "08:10:00" And $aData[$i][4] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
            If $aData[$i][5] > "08:10:00" And $aData[$i][5] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
            If $aData[$i][4] = "Null" Or $aData[$i][5] = "Null" Then GUICtrlSetBkColor(-1, 0xFFE5FF)
            ContinueLoop
        Else
            If $aData[$i][2] = $Filter Then
                $sLine = $aData[$i][1] & "|" & $aData[$i][3] & "|" & $aData[$i][4] & "|"
                $sLine &= $aData[$i][5] & "|" & $aData[$i][6] & "|" & $aData[$i][2]
                $aData[$i][7] = GUICtrlCreateListViewItem($sLine, $lv)
                If $aData[$i][4] > "08:10:00" And $aData[$i][4] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
                If $aData[$i][5] > "08:10:00" And $aData[$i][5] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
                If $aData[$i][4] = "Null" Or $aData[$i][5] = "Null" Then GUICtrlSetBkColor(-1, 0xFFE5FF)
            Else
                $aData[$i][7] = ""
            EndIf
        EndIf
    Next

EndFunc   ;==>UpDadeMyGuiList
;----------------------------------------------------------------------------------------
Func AddAbsentUser()

    Local $sLine, $IniFile, $aSpl, $aArray = $aData

    ;*[Add Absent User to $aData Array
    Local $aDateUnique = _ArrayUnique($aArray, 3, 1)
    For $d = 1 To $aDateUnique[0]
        For $i = 1 To $aUsers[0][0]
            If _GetThis($aUsers[$i][0] & "-" & $aDateUnique[$d]) = -1 Then
                ConsoleWrite("- AddAbsentUser: " & $aDateUnique[$d] & "  " & $aUsers[$i][0] & "-" & $aUsers[$i][1]  & @CRLF)
                $aData[0][0] += 1
                $sLine = $aData[0][0] & "|" & $aUsers[$i][0] & "|" & $aUsers[$i][1] & "|" & $aDateUnique[$d] & "|Null|Null"
                _ArrayAdd($aData, $sLine)
            EndIf
        Next
    Next
    ;Add Absent User to $aData Array]*

    ;*[proper Array Sort order
    For $i = 1 To $aData[0][0]
        $aData[$i][6] = TimeDiff($aData[$i][4], $aData[$i][5])
        ; format date YYYY.MM.DD.HH.MM.SS
        $aSpl = StringSplit($aData[$i][3], ".")
        If StringLen($aSpl[1]) = 1 Then $aSpl[1] = "0" & $aSpl[1]
        $sLine = $aSpl[3] & "." & $aSpl[2] & "." & $aSpl[1] & "." & $aData[$i][4]
        $aData[$i][0] = $sLine
    Next
    _ArraySort($aData, 0, 1)
    For $i = 1 To $aData[0][0]
        $aData[$i][0] = $i
    Next
    ;proper Array Sort order]*

    ;*[Write $aData Array to ini
    For $i = 1 To $aData[0][0]
;~      ; format date 00.00.0000 for ini FileName
;~      $aSpl = StringSplit($aData[$i][3], ".")
;~      If StringLen($aSpl[1]) = 1 Then $aSpl[1] = "0" & $aSpl[1]
;~      $IniFile = $aSpl[1] & "." & $aSpl[2] & "." & $aSpl[3] & ".ini"
        $IniFile = $aData[$i][3] & ".ini"

        ;write ini
        IniWrite(@ScriptDir & "\Data\" & $IniFile, $aData[$i][2], "Value01", $aData[$i][1])
        IniWrite(@ScriptDir & "\Data\" & $IniFile, $aData[$i][2], "Value02", $aData[$i][3])
        IniWrite(@ScriptDir & "\Data\" & $IniFile, $aData[$i][2], "Value03", $aData[$i][4])
        IniWrite(@ScriptDir & "\Data\" & $IniFile, $aData[$i][2], "Value04", $aData[$i][5])
    Next
    ;Write $aData Array to ini]*

EndFunc   ;==>AddAbsentUser
;----------------------------------------------------------------------------------------
Func _GetThis($Txt)
    Local $sIndex
    For $i = 1 To $aData[0][0]
        $sIndex = -1
        If $aData[$i][1] & "-" & $aData[$i][3] = $Txt Then
            $sIndex = $i
            ExitLoop
        EndIf
    Next
    Return $sIndex
EndFunc   ;==>_GetThis
;----------------------------------------------------------------------------------------
Func TimeDiff($sStartTime, $sEndTime)
    Local $H, $M, $sDiff, $aSpl1, $aSpl2
    $aSpl1 = StringSplit($sStartTime, ":")
    $aSpl2 = StringSplit($sEndTime, ":")
    If $aSpl1[0] + $aSpl2[0] <> 6 Then
        ;ConsoleWrite("! Error No valid time format" & @CRLF)
        Return SetError(1, 0, "")
    EndIf
    ; ** 2020/01/01 ** since all the results are from the same date
    $M = _DateDiff('n', "2020/01/01 " & $sStartTime, "2020/01/01 " & $sEndTime)
    $H = Floor($M / 60)
    $M = Mod($M, 60)
    $sDiff = StringFormat("%i:%02i", $H, $M)
    Return $sDiff
EndFunc   ;==>TimeDiff
;----------------------------------------------------------------------------------------
Func aDataDisplay()
    _ArrayDisplay($aData, "$aData")
EndFunc   ;==>MyArrayDisplay
;----------------------------------------------------------------------------------------
Func aUsersDisplay()
    _ArrayDisplay($aUsers, "$aUsers")
EndFunc

 

I know that I know nothing

Link to comment
Share on other sites

1 hour ago, ioa747 said:

I'm embedding the time difference calculation in the array to improve the gui redraw speed

; https://www.autoitscript.com/forum/topic/210069-txt-split-to-ini-file/?do=findComment&comment=1517679
#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 ;-w 5 -w 6 -w 7
#include <Misc.au3>
#include <File.au3>
#include <Date.au3>
#include <Array.au3>
#include <GuiComboBox.au3>
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>

_Singleton(@ScriptName, 0)
ToolTip("  File Splitting ", @DesktopWidth / 2, @DesktopHeight / 5, "Please wait...", 1)
Global $nMsg, $hGui, $idCombo, $lv, $CurUser

Global $aUsers = WriteAllUserData()
Global $aData = FindAllIniFile(@ScriptDir & "\Data\")

AddAbsentUser()
MakeMyGuiList()

HotKeySet("{HOME}", "aDataDisplay") ;Display the $aData Array
HotKeySet("{END}", "aUsersDisplay") ;Display the $aUsers Array

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $idCombo
            _GUICtrlComboBox_GetLBText($idCombo, _GUICtrlComboBox_GetCurSel($idCombo), $CurUser)
            UpDadeMyGuiList($CurUser)
        Case $GUI_EVENT_CLOSE
            GUIDelete()
            Exit
    EndSwitch
WEnd

;----------------------------------------------------------------------------------------
Func WriteAllUserData()  ; Make all ini files
    Local $aDatalar, $aUsers, $UserName, $aTemp, $IniFile, $aSpl, $sDate

    _FileReadToArray("Datalar.txt", $aDatalar, $FRTA_NOCOUNT)
    _FileReadToArray("Users.txt", $aUsers, $FRTA_COUNT, "=")

    Local $iLines = UBound($aDatalar)

    $sDate = ''

    For $i = 0 To $iLines - 1
        $aTemp = StringSplit($aDatalar[$i], ", ", $STR_NOCOUNT)
        $UserName = GetUserName($aUsers, $aTemp[1])

        ; if no user skip
        If $UserName <> "" Then
            If $sDate <> $aTemp[3] Then $sDate = $aTemp[3]

;~          ; format date 00.00.0000 for ini FileName
;~          $aSpl = StringSplit($sDate, ".")
;~          If StringLen($aSpl[1]) = 1 Then $aSpl[1] = "0" & $aSpl[1]
;~          $IniFile = $aSpl[1] & "." & $aSpl[2] & "." & $aSpl[3] & ".ini"
            $IniFile = $sDate & ".ini"

            ;write ini
            If IniRead(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value01", "Non-existing key") = "Non-existing key" Then
                IniWrite(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value01", $aTemp[1])
                IniWrite(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value02", $aTemp[3])
                IniWrite(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value03", $aTemp[4])
            Else
                If IniRead(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value03", "<UNKNOWN>") <> $aTemp[4] Then
                    IniWrite(@ScriptDir & "\Data\" & $IniFile, $UserName, "Value04", $aTemp[4])
                EndIf
            EndIf
        EndIf
    Next
    Return $aUsers
EndFunc   ;==>WriteAllUserData
;----------------------------------------------------------------------------------------
Func GetUserName($aUsers, $ID)  ; ID to User Name
    Local $sName
    For $i = 1 To $aUsers[0][0]
        $sName = ""
        If $aUsers[$i][0] = $ID Then
            $sName = $aUsers[$i][1]
            ExitLoop
        EndIf
    Next
    Return $sName
EndFunc   ;==>GetUserName
;----------------------------------------------------------------------------------------
Func FindAllIniFile($sStartPath = "")  ; Find All Ini File
    If $sStartPath = "" Then $sStartPath = @ScriptDir
    Local $aArray[1][8]
    $aArray[0][0] = 0 ; "index"
    $aArray[0][1] = "UserID"
    $aArray[0][2] = "UserName"
    $aArray[0][3] = "Date"
    $aArray[0][4] = "Start"
    $aArray[0][5] = "End"
    $aArray[0][6] = "Time"
    $aArray[0][7] = "idItem"

    Local $ArraySrtfiles = _FileListToArrayRec($sStartPath, "*.ini", $FLTAR_FILES, $FLTAR_RECUR)
    If Not IsArray($ArraySrtfiles) Then
        ConsoleWrite($sStartPath & " = Invalid input path" & @CRLF)
        Return
    Else
        For $x = 1 To $ArraySrtfiles[0]
            ;ConsoleWrite($sStartPath & $ArraySrtfiles[$x]& @CRLF)
            ReadIniToArray($aArray, $sStartPath & $ArraySrtfiles[$x])
        Next
        Return $aArray
    EndIf
EndFunc   ;==>FindAllIniFile
;----------------------------------------------------------------------------------------
Func ReadIniToArray(ByRef $aArray, $TxtFile)  ; Read Ini To Array

    Local $index

    ;Read the INI section names. This will return a 1 dimensional array.
    Local $aSections = IniReadSectionNames($TxtFile)
    ;Check if an error occurred.
    If Not @error Then
        ;Enumerate through the array displaying the section names.
        For $i = 1 To $aSections[0]
            ReDim $aArray[UBound($aArray) + 1][8]
            $aArray[0][0] += 1
            $index = $aArray[0][0]

            $aArray[$index][0] = $index ;"index"
            $aArray[$index][1] = IniRead($TxtFile, $aSections[$i], "Value01", "Null") ;"UserID"
            $aArray[$index][2] = $aSections[$i] ;"UserName"
            $aArray[$index][3] = IniRead($TxtFile, $aSections[$i], "Value02", "Null") ;"Date"
            $aArray[$index][4] = IniRead($TxtFile, $aSections[$i], "Value03", "Null") ;"Start"
            $aArray[$index][5] = IniRead($TxtFile, $aSections[$i], "Value04", "Null") ;"End"
            $aArray[$index][6] = "" ;"Time"
        Next
    EndIf

EndFunc   ;==>ReadIniToArray
;----------------------------------------------------------------------------------------
Func MakeMyGuiList()  ; GUI Create
    $hGui = GUICreate("_ank_ File Splitting", 510, 560, -1, -1)

    $lv = GUICtrlCreateListView("CART ID  |DATE  |START  |END  |TIME|NAME AND SURNAME", 10, 30, 490, 520)
    Local $sLine
    For $i = 1 To $aData[0][0]
        $sLine = $aData[$i][1] & "|" & $aData[$i][3] & "|" & $aData[$i][4] & "|"
        $sLine &= $aData[$i][5] & "|" & $aData[$i][6] & "|" & $aData[$i][2]
        $aData[$i][7] = GUICtrlCreateListViewItem($sLine, $lv)
        If $aData[$i][4] > "08:10:00" And $aData[$i][4] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
        If $aData[$i][5] > "08:10:00" And $aData[$i][5] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
        If $aData[$i][4] = "Null" Or $aData[$i][5] = "Null" Then GUICtrlSetBkColor(-1, 0xFFE5FF)
    Next

    $idCombo = GUICtrlCreateCombo("Select User", 10, 1, 490, 25)
    GUICtrlSetFont(-1, 12, 400, 0, "MS Sans Serif")
    For $i = 1 To $aUsers[0][0]
        _GUICtrlComboBox_AddString($idCombo, $aUsers[$i][1])
    Next

    GUISetState(@SW_SHOW)
    ToolTip("")
EndFunc   ;==>MakeMyGuiList
;----------------------------------------------------------------------------------------
Func UpDadeMyGuiList($Filter)

    ; delete items
    Local $hlv = GUICtrlGetHandle($lv)
    _GUICtrlListView_DeleteAllItems($hlv)

    Local $sLine
    ; ReMake items
    For $i = 1 To $aData[0][0]
        If $Filter = "Select User" Then
            $sLine = $aData[$i][1] & "|" & $aData[$i][3] & "|" & $aData[$i][4] & "|"
            $sLine &= $aData[$i][5] & "|" & $aData[$i][6] & "|" & $aData[$i][2]
            $aData[$i][7] = GUICtrlCreateListViewItem($sLine, $lv)
            If $aData[$i][4] > "08:10:00" And $aData[$i][4] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
            If $aData[$i][5] > "08:10:00" And $aData[$i][5] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
            If $aData[$i][4] = "Null" Or $aData[$i][5] = "Null" Then GUICtrlSetBkColor(-1, 0xFFE5FF)
            ContinueLoop
        Else
            If $aData[$i][2] = $Filter Then
                $sLine = $aData[$i][1] & "|" & $aData[$i][3] & "|" & $aData[$i][4] & "|"
                $sLine &= $aData[$i][5] & "|" & $aData[$i][6] & "|" & $aData[$i][2]
                $aData[$i][7] = GUICtrlCreateListViewItem($sLine, $lv)
                If $aData[$i][4] > "08:10:00" And $aData[$i][4] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
                If $aData[$i][5] > "08:10:00" And $aData[$i][5] < "17:00:00" Then GUICtrlSetBkColor(-1, 0xC0FFFF)
                If $aData[$i][4] = "Null" Or $aData[$i][5] = "Null" Then GUICtrlSetBkColor(-1, 0xFFE5FF)
            Else
                $aData[$i][7] = ""
            EndIf
        EndIf
    Next

EndFunc   ;==>UpDadeMyGuiList
;----------------------------------------------------------------------------------------
Func AddAbsentUser()

    Local $sLine, $IniFile, $aSpl, $aArray = $aData

    ;*[Add Absent User to $aData Array
    Local $aDateUnique = _ArrayUnique($aArray, 3, 1)
    For $d = 1 To $aDateUnique[0]
        For $i = 1 To $aUsers[0][0]
            If _GetThis($aUsers[$i][0] & "-" & $aDateUnique[$d]) = -1 Then
                ConsoleWrite("- AddAbsentUser: " & $aDateUnique[$d] & "  " & $aUsers[$i][0] & "-" & $aUsers[$i][1]  & @CRLF)
                $aData[0][0] += 1
                $sLine = $aData[0][0] & "|" & $aUsers[$i][0] & "|" & $aUsers[$i][1] & "|" & $aDateUnique[$d] & "|Null|Null"
                _ArrayAdd($aData, $sLine)
            EndIf
        Next
    Next
    ;Add Absent User to $aData Array]*

    ;*[proper Array Sort order
    For $i = 1 To $aData[0][0]
        $aData[$i][6] = TimeDiff($aData[$i][4], $aData[$i][5])
        ; format date YYYY.MM.DD.HH.MM.SS
        $aSpl = StringSplit($aData[$i][3], ".")
        If StringLen($aSpl[1]) = 1 Then $aSpl[1] = "0" & $aSpl[1]
        $sLine = $aSpl[3] & "." & $aSpl[2] & "." & $aSpl[1] & "." & $aData[$i][4]
        $aData[$i][0] = $sLine
    Next
    _ArraySort($aData, 0, 1)
    For $i = 1 To $aData[0][0]
        $aData[$i][0] = $i
    Next
    ;proper Array Sort order]*

    ;*[Write $aData Array to ini
    For $i = 1 To $aData[0][0]
;~      ; format date 00.00.0000 for ini FileName
;~      $aSpl = StringSplit($aData[$i][3], ".")
;~      If StringLen($aSpl[1]) = 1 Then $aSpl[1] = "0" & $aSpl[1]
;~      $IniFile = $aSpl[1] & "." & $aSpl[2] & "." & $aSpl[3] & ".ini"
        $IniFile = $aData[$i][3] & ".ini"

        ;write ini
        IniWrite(@ScriptDir & "\Data\" & $IniFile, $aData[$i][2], "Value01", $aData[$i][1])
        IniWrite(@ScriptDir & "\Data\" & $IniFile, $aData[$i][2], "Value02", $aData[$i][3])
        IniWrite(@ScriptDir & "\Data\" & $IniFile, $aData[$i][2], "Value03", $aData[$i][4])
        IniWrite(@ScriptDir & "\Data\" & $IniFile, $aData[$i][2], "Value04", $aData[$i][5])
    Next
    ;Write $aData Array to ini]*

EndFunc   ;==>AddAbsentUser
;----------------------------------------------------------------------------------------
Func _GetThis($Txt)
    Local $sIndex
    For $i = 1 To $aData[0][0]
        $sIndex = -1
        If $aData[$i][1] & "-" & $aData[$i][3] = $Txt Then
            $sIndex = $i
            ExitLoop
        EndIf
    Next
    Return $sIndex
EndFunc   ;==>_GetThis
;----------------------------------------------------------------------------------------
Func TimeDiff($sStartTime, $sEndTime)
    Local $H, $M, $sDiff, $aSpl1, $aSpl2
    $aSpl1 = StringSplit($sStartTime, ":")
    $aSpl2 = StringSplit($sEndTime, ":")
    If $aSpl1[0] + $aSpl2[0] <> 6 Then
        ;ConsoleWrite("! Error No valid time format" & @CRLF)
        Return SetError(1, 0, "")
    EndIf
    ; ** 2020/01/01 ** since all the results are from the same date
    $M = _DateDiff('n', "2020/01/01 " & $sStartTime, "2020/01/01 " & $sEndTime)
    $H = Floor($M / 60)
    $M = Mod($M, 60)
    $sDiff = StringFormat("%i:%02i", $H, $M)
    Return $sDiff
EndFunc   ;==>TimeDiff
;----------------------------------------------------------------------------------------
Func aDataDisplay()
    _ArrayDisplay($aData, "$aData")
EndFunc   ;==>MyArrayDisplay
;----------------------------------------------------------------------------------------
Func aUsersDisplay()
    _ArrayDisplay($aUsers, "$aUsers")
EndFunc

 

     Thanks again for your interest and support. I ran into a little problem when I ran it integrated with my other programs.
While your code divides in ini format, when it converts to day.month.year.ini format, it divides as (8.05.2023). Is it possible to change it to call it (08.05.2023) (ie "0" at the beginning of the day digit)? My other programs all generate the filename as (08.05.2023.ini).

Link to comment
Share on other sites

in the beginning I also did it like this for better alignment. but I changed it because in the Datalar.txt it has 1 digit

it's still there, just as a comment on line 55 and 231

change from

;~          ; format date 00.00.0000 for ini FileName
;~          $aSpl = StringSplit($sDate, ".")
;~          If StringLen($aSpl[1]) = 1 Then $aSpl[1] = "0" & $aSpl[1]
;~          $IniFile = $aSpl[1] & "." & $aSpl[2] & "." & $aSpl[3] & ".ini"
            $IniFile = $sDate & ".ini"

to

; format date 00.00.0000 for ini FileName
            $aSpl = StringSplit($sDate, ".")
            If StringLen($aSpl[1]) = 1 Then $aSpl[1] = "0" & $aSpl[1]
            $IniFile = $aSpl[1] & "." & $aSpl[2] & "." & $aSpl[3] & ".ini"
;~          $IniFile = $sDate & ".ini"

 

Edited by ioa747

I know that I know nothing

Link to comment
Share on other sites

9 minutes ago, ioa747 said:

in the beginning I also did it like this for better alignment. but I changed it because in the Datalar.txt it has 1 digit

if you still see, it's just there as comment  in line 55,  and 231

change from

;~          ; format date 00.00.0000 for ini FileName
;~          $aSpl = StringSplit($sDate, ".")
;~          If StringLen($aSpl[1]) = 1 Then $aSpl[1] = "0" & $aSpl[1]
;~          $IniFile = $aSpl[1] & "." & $aSpl[2] & "." & $aSpl[3] & ".ini"
            $IniFile = $sDate & ".ini"

to

; format date 00.00.0000 for ini FileName
            $aSpl = StringSplit($sDate, ".")
            If StringLen($aSpl[1]) = 1 Then $aSpl[1] = "0" & $aSpl[1]
            $IniFile = $aSpl[1] & "." & $aSpl[2] & "." & $aSpl[3] & ".ini"
;~          $IniFile = $sDate & ".ini"

 

You're right, it's my fault I didn't read any of the descriptions as I got excited and immediately started testing the innovations. :oops:

Link to comment
Share on other sites

@mucitbey You asked me in your last post if it was possible to have the time(input) time(output) on the same row in the listview, for each user. I did that in the script below. Hope it will help you at your work :bye:

With-Time-1-and-Time-2-on-same-row.png
#include <File.au3>
#include <GuiListView.au3>
#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>

Global $aData, $aUser, $aUser_Backup

_FileReadToArray(@ScriptDir & "\" & "Datalar.txt", $aData, $FRTA_NOCOUNT) ; 1D array
If @error Then Exit MsgBox($MB_TOPMOST, "_FileReadToArray error = " & @error, "Datalar.txt")
$iLinesData = UBound($aData)

_FileReadToArray(@ScriptDir & "\" & "Users.txt", $aUser, $FRTA_NOCOUNT, "=") ; 2D array
If @error Then Exit MsgBox($MB_TOPMOST, "_FileReadToArray error = " & @error, "Users.txt")
$iLinesUser = UBound($aUser)
ReDim $aUser[$iLinesUser][3] ; add one empty column 2 at the right (to remember users who were present daily)
$aUser_Backup = $aUser ; keep a copy with last column 2 empty for all users. Reuse this backup when date changes.

$hTemplate = FileOpen(@ScriptDir & "\" & "Users template.ini", $FO_OVERWRITE + $FO_UNICODE) ; more reliable than $FO_ANSI
If $hTemplate = -1 Then Exit MsgBox($MB_TOPMOST, "FileOpen error", "Users template.ini")
For $i = 0 To $iLinesUser - 1
    FileWriteLine($hTemplate, _
        "[" & $aUser[$i][1] & "]" & @crlf & _
        "Value01=" & $aUser[$i][0] & @crlf & _
        "Value02=" & @crlf & "Value03=" & @crlf & "Value04=" & @crlf)
Next
FileClose($hTemplate)

GUICreate("_ank_ File Splitting", 470, 500, -1, -1)
$lv = GUICtrlCreateListView("CART ID  |   DATE|TIME-1  |TIME-2  |NAME AND SURNAME     ", 10, 10, 450, 480)
$sDate = ''

For $li = 0 To $iLinesData - 1
    $aTemp = StringSplit(StringStripWS($aData[$li], 1+2), ", ", $STR_NOCOUNT) ; strip leading (1) and trailing (2) eventual white space
    If @error Then ContinueLoop ; eliminate accidental blank lines. Help file StringSplit: "@error = 1 when no delimiters were found"

    If StringLen($aTemp[3]) < 10 Then $aTemp[3] = "0" & $aTemp[3] ; days "1" to "9" will become "01" to "09" everywhere in the script.

    If $sDate <> $aTemp[3] Then ; $sDate is the old date, $aTemp[3] is the new date.
        If $sDate Then ; always False when $li = 0 (first data line processed)
            Add_Absents($sDate) ; add eventual absents AFTER a day has been processed.
            $aUser = $aUser_Backup ; blank column 2 in $aUser, for all users, when the date changes.
            $iLinesUser = UBound($aUser) ; as it may have increased in Func GetUserIndex (if an eventual ID wasn't found in $aUser)
            GUICtrlCreateListViewItem("", $lv) ; 1 empty line between each day processed (sort of vertical separator)
        EndIf
        $sIniFile = @ScriptDir & "\" & $aTemp[3] & ".ini"
        $iRet = FileCopy(@ScriptDir & "\" & "Users template.ini", $sIniFile, $FC_OVERWRITE) ; date changes => new ini file (based on ini template)
        If $iRet = 0 Then Exit MsgBox($MB_TOPMOST, "FileCopy error", $sIniFile) ; maybe existed read-only => overwrite fails
        $sDate = $aTemp[3] ; old date = new date
    EndIf

    $UserIndex = GetUserIndex($aTemp[1]) ; user index (row) in $aUser
    $UserName = $aUser[$UserIndex][1]

    $sKey = IniRead($sIniFile, $Username, "Value03", "Impossible error") ; remember Value03 = in-time
    ; $sKey has 3 possible values :
    ; 1) "" means we need to update "Value03" (1st entry for this user in Datalar.txt for this day)
    ; 2) "07:01:00" (for example) means we need to update "Value04" (2nd entry for this user in Datalar.txt for this day)
    ; 3) "Impossible error" will never happen, because an unknown ID has already updated $aUser and $sIniFile in Func GetUserIndex()
    ; 4) Nothing else should be found in $sKey . If this ever happens, Case Else will be triggered below.

    Select
        Case $sKey = ""
            IniWrite($sIniFile, $UserName, "Value02", $aTemp[3]) ; date
            IniWrite($sIniFile, $UserName, "Value03", $aTemp[4]) ; in-time
            $iLVrow = GUICtrlCreateListViewItem($aTemp[1] &"|"& $aTemp[3] &"|"& $aTemp[4] &"|"& "" &"|"& $UserName, $lv)
            $aUser[$UserIndex][2] = String($iLVrow) ; String() to force "0" (when 1st row in LV) to allow testing  If Not $aUser[$i][2]

        Case StringRegExp($sKey, '\d\d:\d\d:\d\d') ; ex. '07:01:00'
            IniWrite($sIniFile, $UserName, "Value02", $aTemp[3]) ; date
            IniWrite($sIniFile, $UserName, "Value04", $aTemp[4]) ; out-time
            ; update out-time (iSubItem 3) in a preceding LV row : retrieve its index via _GUICtrlListView_FindParam()
            $iRet = _GUICtrlListView_SetItemText($lv, _GUICtrlListView_FindParam($lv, $aUser[$UserIndex][2]), $aTemp[4], 3)
            If $iRet = 0 Then Exit MsgBox($MB_TOPMOST, "_GUICtrlListView_SetItemText", $sIniFile) ; impossible error

        Case $sKey = "Impossible error" ; this will never happen
            Exit MsgBox($MB_TOPMOST, "Impossible error", $sIniFile) ; this will never happen

        Case Else ; this should never happen
            Exit MsgBox($MB_TOPMOST, "Case Else", $sIniFile & @crlf & "$sKey = " & $sKey)
    EndSelect

    Color_Row($aUser[$UserIndex][2]) ; LV native Item ID
Next

If $sDate Then Add_Absents($sDate) ; add eventual absents for the last day processed.
GUISetState(@SW_SHOW)

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

;=====================================================
Func GetUserIndex($ID)
    For $iIndex = 0 To $iLinesUser - 1
        If $aUser[$iIndex][0] = $ID Then Return $iIndex ; regular user found => no problem.
    Next

    ; Below, user ID was not found in $aUser (e.g "Users.txt") and $iIndex is correct for this Undefined ID
    ; Add 1 line in $aUser for this Undefined ID
    $iLinesUser += 1
    ReDim $aUser[$iLinesUser][3]
    $aUser[$iIndex][0] = $ID
    $aUser[$iIndex][1] = "Undefined ID " & $ID ; this creates a unique "name" (+++)

    ; Add 1 section in $sIniFile for this Undefined ID
    ; Use @lf as indicated by help-file, because @cr will also be automatically added by the function, ending in @crlf everywhere !)
    Local $sSectionContent = _
        "Value01=" & $ID & @lf & _
        "Value02=" & @lf & _
        "Value03=" & @lf & _
        "Value04=" ; & @lf (optional last @lf, same result with or without it => @crlf will be added at the end)
    IniWriteSection($sIniFile, "Undefined ID " & $ID, $sSectionContent) ; note the unique section name : "Undefined ID " & $ID

    Return $iIndex ; of this Undefined ID
EndFunc

;=====================================================
Func Add_Absents($sDate)
    For $i = 0 To $iLinesUser - 1
        If Not $aUser[$i][2] Then ; user was absent that day
            ; add 1 line in ListView for the absent user (with a blank time)
            GUICtrlCreateListViewItem($aUser[$i][0] &"|"& $sDate &"|"& "" &"|"& "" &"|"& $aUser[$i][1], $lv)
            ; update 1 line in ini file for the absent user (update the date line, e.g. Value02)
            IniWrite($sIniFile, $aUser[$i][1], "Value02", $sDate) ; date
        EndIf
    Next
EndFunc

;=====================================================
Func Color_Row($iItem) ; $iItem is a LV native Item ID
    If StringLeft($UserName, 12) = "Undefined ID" Then
        GUICtrlSetBkColor($iItem, 0xFF0000) ; red
    ElseIf $aTemp[4] > "08:10:00" And $aTemp[4] < "17:00:00" Then
        GUICtrlSetBkColor($iItem, 0xC0FFFF) ; light blue
    EndIf
EndFunc

Edited by pixelsearch
typo
Link to comment
Share on other sites

@ioa747 I tried to improve the processing time of the script, in case there are plenty of users (100, 500 you name it) and a big datalar.txt file, like the one provided by mucitbey last year, which had 6.535 lines and generated 75 ini files (from 30/05/2022 to 12/08/2022 included)

In my precedent script (and probably yours) I found the 2 instructions that slowed the damn thing :
* IniWrite is slow, when there are plenty of sections, probably because the file is opened and closed for each Iniwrite, idk.

* _ArraySearch is slow too (e.g GetUserIndex)
Retrieving constantly a user name (while providing his ID) is slow when we have to loop through all rows of an array, again and again. _ArrayBinarySearch would certainly retrieve the name faster

So, this is what I did to get super quick results, even on thousands of lines in Datalar.txt
* No more IniWrite, but FileWriteLine, as you will notice in the script below.
* Scripting.Dictionary object (instead of _ArraySearch) which retrieves a username at the speed of light. Also, Scripting.Dictionary can be used for other interesting purposes (like $oData in the script)

Here are some notes concerning the 2 major arrays and 2 dictionaries objects found in the script below :

$aUser[ ][4]
============
$aUser[ ][0] = User ID (unique)
$aUser[ ][1] = User Name (unique, as Name is also, unfortunately, a unique section in daily .ini files)
$aUser[ ][2] = Time1 (if empty, then user was absent this day, this will be useful to add absents in LV)
$aUser[ ][3] = Time2 (if filled, then Time1 is already filled, e.g user ID found twice in $adata for same day)


$oUser()
========
Key = User ID (unique) . Same number of Keys as $aUser number of rows
Item = Index of this User in $aUser, it will allow an immediate search in $aUser, instead of slow _ArraySearch


$aData[ ][5]
============
$aData[ ][0] = unused
$aData[ ][1] = User ID (not unique, usually same ID found twice each day)
$aData[ ][2] = unused
$aData[ ][3] = Date (same date on contiguous rows, processed day by day)
$aData[ ][4] = Time1 OR Time2 (this column is already sorted for same day)


$oData()
========
Key = User ID (unique). Used when day changes, to add at once in LV all daily workers, sorted by day & time.
Item = Index of this User in $aUser, it will allow an immediate search in $aUser, instead of slow _ArraySearch

#include <File.au3>
#include <MsgBoxConstants.au3>
#include <SendMessage.au3>

Opt("MustDeclareVars", 1)
Global $g_iLinesUser, $g_idListview
Main()

Func Main()
    Local $aUser, $aUserBackup, $oUser, $aData, $oData
    Local $WM_SETREDRAW = 0x000B, $LVM_GETITEMCOUNT = 0X1004, $GUI_EVENT_CLOSE = -3

    _FileReadToArray(@ScriptDir & "\" & "Users.txt", $aUser, $FRTA_NOCOUNT, "=") ; 2D array
    If @error Then Exit MsgBox($MB_TOPMOST, "_FileReadToArray error = " & @error, "Users.txt")
    $g_iLinesUser = UBound($aUser)
    ReDim $aUser[$g_iLinesUser][4] ; add 2 empty columns at the right (to update time1 and time2 per user for 1 working day)
    $aUserBackup = $aUser ; keep a copy with last 2 empty columns for all users. Reuse this backup when date changes.

    $oUser = ObjCreate("Scripting.Dictionary")
    Fill_oUser($aUser, $oUser)

    _FileReadToArray(@ScriptDir & "\" & "Datalar.txt", $aData, $FRTA_NOCOUNT) ; 1D array
    If @error Then Exit MsgBox($MB_TOPMOST, "_FileReadToArray error = " & @error, "Datalar.txt")

    $oData = ObjCreate("Scripting.Dictionary")

    Local $hGUI = GUICreate("", 470, 500, -1, -1) ; title later, to include number of rows in it
    $g_idListview = GUICtrlCreateListView("CART ID  |   DATE|TIME-1  |TIME-2  |NAME AND SURNAME     ", 10, 10, 450, 480)
    Local $hListview = GUICtrlGetHandle($g_idListview)
    _SendMessage($hListview, $WM_SETREDRAW, False) ; _GUICtrlListView_BeginUpdate . False = don't redraw after a change

    Local $sDate = "", $aTemp, $iEmptyRows, $UserIndex
    For $li = 0 To UBound($aData) - 1
        $aTemp = StringSplit(StringStripWS($aData[$li], 1+2), ", ", $STR_NOCOUNT) ; strip leading (1) and trailing (2) eventual white space
        If @error Then ContinueLoop ; eliminate accidental blank lines. Help file StringSplit: "@error = 1 when no delimiters were found"

        If StringLen($aTemp[3]) < 10 Then $aTemp[3] = "0" & $aTemp[3] ; days "1" to "9" will become "01" to "09" everywhere in the script.

        If $sDate <> $aTemp[3] Then ; $sDate is the old date, $aTemp[3] is the new date.
            If $sDate Then ; always False when $li = 0 (first data line processed)
                ; Update LV : add all working users for 1 day, then add all absents for 1 day . Prepare ini file for 1 day (all users)
                DayChange($sDate, $aUser, $oData)

                ; Reuse $aUserBackup (before processing a new date)
                $aUser = $aUserBackup ; reuse backup, e.g. blank columns 2 & 3 in $aUser, for all users, when date changes.
                $g_iLinesUser = UBound($aUser) ; as it may have increased in Func GetUserIndex (if an eventual ID wasn't found in $aUser)

                ; If undefined ID's had been added to $oUser, then re-generate $oUser (this shouldn't happen, according to mucitbey)
                If $oUser.Count <> $g_iLinesUser Then
                    $oUser.RemoveAll()
                    Fill_oUser($aUser, $oUser)
                EndIf

                ; remove all keys in $oData (before processing a new date)
                $oData.RemoveAll()

                ; add 1 empty line between each day processed in LV (sort of vertical separator)
                GUICtrlCreateListViewItem("", $g_idListview)
                $iEmptyRows += 1 ; don't count this line in the total number of lines in LV (displayed later in GUI title)
            EndIf
            $sDate = $aTemp[3] ; old date = new date
        EndIf

        $UserIndex = GetUserIndex($aTemp[1], $aUser, $oUser) ; user index (row) in $aUser

        If Not $oData.Exists($aTemp[1]) Then ; 1st entry for this ID (will update column Time1 in $aUser)
            $aUser[$UserIndex][2] =  $aTemp[4] ; time1
            $oData.Add($aTemp[1], $UserIndex) ; key = User ID, item = User index in $aUser
        Else ; 2nd entry for this ID  (it will update column Time2 in $aUser)
            $aUser[$UserIndex][3] =  $aTemp[4] ; time2
        EndIf
    Next

    If $sDate Then DayChange($sDate, $aUser, $oData)
    _SendMessage($hListview, $WM_SETREDRAW, True) ; _GUICtrlListView_EndUpdate . True = redraw after a change

    Local $iNbRows = GUICtrlSendMsg($g_idListview, $LVM_GETITEMCOUNT, 0, 0)
    WinSetTitle($hGUI, "", "_ank_ File Splitting (" & ($iNbRows - $iEmptyRows) & " rows)")
    GUISetState(@SW_SHOW, $hGUI)

    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    ; Cleaning (not really necessary but ok)
    $oUser = 0 ; force Object deletion (AutoIt help file, topic "Obj/COM Reference")
    $oData = 0 ; ditto
    GUIDelete($hGUI)
EndFunc   ;==>Main

;================================================
Func GetUserIndex($ID, ByRef $aUser, ByRef $oUser)

    If $oUser.Exists($ID) Then
        Local $iIndex = $oUser.Item($ID) ; $iIndex in $aUser of regular ID
    Else ; this should never happen (mucitbey) but better prevent it, just in case...
        Local $iIndex = $g_iLinesUser ; $iIndex in $aUser of Undefined ID
        ; add the Undefined ID in $aUser
        $g_iLinesUser += 1
        ReDim $aUser[$g_iLinesUser][4] ; not really fast but as it should never happen...
        $aUser[$iIndex][0] = $ID
        $aUser[$iIndex][1] = "Undefined ID " & $ID ; this creates a unique "name" (+++)
        ; add the Undefined ID in $oUser
        $oUser.Add($ID, $iIndex) ; key = User Undefined ID, item = User index in $aUser
    EndIf
    Return $iIndex ; 0+
EndFunc   ;==>GetUserIndex

;================================================
Func DayChange($sDate, ByRef $aUser, ByRef $oData)

    ; Update LV : add all working users for 1 day
    ; Color eventually background of LV rows
    Local $aPresent = $oData.Keys(), $iIndex
    For $i = 0 To Ubound($aPresent) - 1
        $iIndex = $oData.Item($aPresent[$i]) ; $iIndex in $aUser of an ID
        GUICtrlCreateListViewItem($aUser[$iIndex][0] &"|"& $sDate &"|"& _
            $aUser[$iIndex][2] &"|"& $aUser[$iIndex][3] &"|"& $aUser[$iIndex][1], $g_idListview)
        ; color eventually background of this LV row
        If StringLeft($aUser[$iIndex][1], 12) = "Undefined ID" Then
                GUICtrlSetBkColor(-1, 0xFF0000) ; red
        ElseIf ($aUser[$iIndex][2] > "08:10:00" And $aUser[$iIndex][2] < "17:00:00") _
            OR ($aUser[$iIndex][3] > "08:10:00" And $aUser[$iIndex][3] < "17:00:00") Then
                GUICtrlSetBkColor(-1, 0xC0FFFF) ; light blue
        EndIf
    Next

    ; Prepare .ini file for 1 day (all users)
    ; Update LV : add all absents for 1 day
    Local $sIniFile = @ScriptDir & "\" & $sDate & ".ini"
    Local $hIni = FileOpen($sIniFile, $FO_OVERWRITE + $FO_UNICODE) ; more reliable than $FO_ANSI
    If $hIni = -1 Then Exit MsgBox($MB_TOPMOST, "FileOpen error", $sIniFile)
    For $i = 0 To $g_iLinesUser - 1
        FileWriteLine($hIni, _
            "[" & $aUser[$i][1] & "]" & @crlf & _   ; ini section = [User Name]
            "Value01=" & $aUser[$i][0] & @crlf & _  ; User ID
            "Value02=" & $sDate & @crlf & _           ; Date
            "Value03=" & $aUser[$i][2] & @crlf & _  ; Time1
            "Value04=" & $aUser[$i][3] & @crlf)     ; Time2

        If Not $aUser[$i][2] Then ; user was absent that day (as he got no time1)
            ; add 1 line in ListView for the absent user (with blank time1 & time2)
            GUICtrlCreateListViewItem($aUser[$i][0] &"|"& $sDate &"|"& "" &"|"& "" &"|"& $aUser[$i][1], $g_idListview)
        EndIf
    Next
    FileClose($hIni)
EndFunc   ;==>DayChange

;================================================
Func Fill_oUser(ByRef $aUser, ByRef $oUser)

    For $i = 0 To $g_iLinesUser - 1
        $oUser.Add($aUser[$i][0], $i) ; key = User ID, item = User index in $aUser (immediate retrieve of a user in $aUser, instead of slow _ArraySearch)
    Next
EndFunc   ;==>Fill_oUser

My only regret ?
I wish I used the Scripting.Dictionary Object a long time ago, it's damn quick and easy to use :)
Edited by pixelsearch
minor change in code (arrays & dictionaries are not global variables anymore)
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...