pixelsearch Posted May 8, 2023 Share Posted May 8, 2023 (edited) @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 May 10, 2023 by pixelsearch mucitbey 1 Link to comment Share on other sites More sharing options...
mucitbey Posted May 9, 2023 Author Share Posted May 9, 2023 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. Link to comment Share on other sites More sharing options...
ioa747 Posted May 9, 2023 Share Posted May 9, 2023 (edited) I also adapted the extended version expandcollapse popup; 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 May 10, 2023 by ioa747 corection for proper coloring mucitbey 1 I know that I know nothing Link to comment Share on other sites More sharing options...
pixelsearch Posted May 9, 2023 Share Posted May 9, 2023 (edited) @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 expandcollapse popup #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 May 10, 2023 by pixelsearch improved code mucitbey 1 Link to comment Share on other sites More sharing options...
ioa747 Posted May 10, 2023 Share Posted May 10, 2023 On 5/8/2023 at 11:47 AM, ioa747 said: corection for proper coloring I know that I know nothing Link to comment Share on other sites More sharing options...
mucitbey Posted May 10, 2023 Author Share Posted May 10, 2023 (edited) 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 expandcollapse popup#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 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 May 10, 2023 by mucitbey Addition pixelsearch 1 Link to comment Share on other sites More sharing options...
mucitbey Posted May 10, 2023 Author Share Posted May 10, 2023 21 hours ago, ioa747 said: I also adapted the extended version expandcollapse popup; 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. Link to comment Share on other sites More sharing options...
ioa747 Posted May 10, 2023 Share Posted May 10, 2023 (edited) @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 expandcollapse popup; 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 May 10, 2023 by ioa747 mucitbey 1 I know that I know nothing Link to comment Share on other sites More sharing options...
mucitbey Posted May 10, 2023 Author Share Posted May 10, 2023 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 expandcollapse popup; 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. Link to comment Share on other sites More sharing options...
ioa747 Posted May 11, 2023 Share Posted May 11, 2023 I'm embedding the time difference calculation in the array to improve the gui redraw speed expandcollapse popup; 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 mucitbey and pixelsearch 1 1 I know that I know nothing Link to comment Share on other sites More sharing options...
mucitbey Posted May 11, 2023 Author Share Posted May 11, 2023 1 hour ago, ioa747 said: I'm embedding the time difference calculation in the array to improve the gui redraw speed expandcollapse popup; 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 More sharing options...
ioa747 Posted May 11, 2023 Share Posted May 11, 2023 (edited) 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 May 11, 2023 by ioa747 mucitbey 1 I know that I know nothing Link to comment Share on other sites More sharing options...
mucitbey Posted May 11, 2023 Author Share Posted May 11, 2023 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. Link to comment Share on other sites More sharing options...
pixelsearch Posted May 11, 2023 Share Posted May 11, 2023 (edited) @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 expandcollapse popup #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 May 12, 2023 by pixelsearch typo mucitbey 1 Link to comment Share on other sites More sharing options...
pixelsearch Posted May 17, 2023 Share Posted May 17, 2023 (edited) @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 _ArraySearchexpandcollapse popup #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 May 18, 2023 by pixelsearch minor change in code (arrays & dictionaries are not global variables anymore) Zedna, ioa747 and mucitbey 3 Link to comment Share on other sites More sharing options...
mucitbey Posted May 21, 2023 Author Share Posted May 21, 2023 He really noticed the speed in both converting and creating files. It took 2-3 seconds to convert about 850 rows of data, Great. Thanks again for your hard work. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now