Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 12/27/2024 in all areas

  1. @argumentum pointed out the main issue in the script : it's the $Button control created twice with the same variable name : 1) First time, outside a function, it is created as an implicit Global variable : all variables not created inside functions are Global, as explained in this wiki link By default, AutoIt scopes any variables declared in the main body of a script (that is not between a Func and EndFunc pair) as Global and any variables declared within function declarations as Local. But it is a good idea to explicitly declare your variables to make sure that you get what you want [...] If you use the AutoItSetOption("MustDeclareVars", 1) directive you must declare the scope of your variables or you will get error messages [...] AutoIt even allows you to use the same name for Global and Local variables, although this is not recommended as it could easily lead to confusion [...] The value of the $Button variable in main body is 3 (when it is first declared) 2) Second time, inside function _form2() , $Button is declared again (with a value of 4 this time) Because you used the same variable name, then you just changed the value of the Global variable $Button in main body from 3 to 4, as displayed in the Console when you add 2 ConsoleWrite lines to your script : ... $Form1 = GUICreate("", 95, 45) $Button = GUICtrlCreateButton("Launch Me", 10, 10, 75, 25) ConsoleWrite("In Main : $Button = " & $Button & @crlf) ; <============= added line (displays 3) GUISetState(@SW_SHOW) ; ----------------------------------------------- While 1 $nMsg = GUIGetMsg() ; ----------------- Switch $nMsg Case $GUI_EVENT_CLOSE ConsoleWrite("In Main : $Button = " & $Button & @crlf) ; <============= added line (displays 4 if you called _form2() Exit ... That's why your $Button in Form1 is not active anymore after you called _form2() , it was created in main body with a value of 3, not 4, so it won't react when you press it again in Form1 Here is the console output, after you called _form2() , closed it then exited the script from Form1 : In Main : $Button = 3 In Main : $Button = 4
    2 points
  2. use #AutoIt3Wrapper_Au3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 Don't call every button $Button.
    2 points
  3. Good day, I hope that all is having a great day thus far? I hope, as always, that I am asking the appropriate questions here? I have the following script which provides the ability to launch and to exit notepad. However, the GUI "appears" sluggish! Here is the script: ; ----------------------------------------------- #include <ButtonConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> ; ----------------------------------------------- $Form1 = GUICreate("", 95, 45) $Button = GUICtrlCreateButton("Launch Me", 10, 10, 75, 25) GUISetState(@SW_SHOW) ; ----------------------------------------------- While 1 $nMsg = GUIGetMsg() ; ----------------- Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $Button _LaunchTAC() _form2() EndSwitch WEnd ; ----------------------------------------------- Func _LaunchTAC() Local $sSrcAppPath = "C:\Windows\System32\notepad.exe" ; ----------------------------------------------- Run($sSrcAppPath) ; ----------------------------------------------- Sleep(500) ; ----------------- WinMove("[CLASS:Notepad]", "", 150, 250, 250, 250) EndFunc ;==>_LaunchTAC ; ----------------------------------------------- Func _form2() $Form2 = GUICreate("", 95, 45, 215, 340) $Button = GUICtrlCreateButton("Exit Me", 10, 10, 75, 25) ; ----------------- GUISetState(@SW_SHOW) ; ----------------- While 2 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $Button _ExitMe() GUIDelete($Form2) GUISetState(@SW_ENABLE, $Form1) Return EndSwitch WEnd EndFunc ;==>_form2 ; ----------------------------------------------- Func _ExitMe() Local $sAppTitle = "[CLASS:Notepad]" ; ----------------------------------------------- WinClose($sAppTitle) EndFunc ;==>_ExitTac ; ----------------------------------------------- Also, I am not able to execute the first button command a second time! Any ideas|suggestions would be greatly appreciated.
    1 point
  4. I've worked with RTF files and rich edit controls for years. But recently I needed to simply extract the text from an RTF file (i.e., without any of the formatting). I found a few suggested methods, but none were as simple as what I would like. A short investigation revealed that although all the necessary pieces are in the standard Au3 function set, there is no macro Extract Text function. What I'm providing below is a working tool for ferreting out and tuning any subtle aspects to any processing you might need. THE IMPORTANT THING TO KNOW IS THIS: the file's ENCODING is key to everything. If you're certain of the file's encoding, then just specify it in your _GUICtrlRichEdit_StreamFromFile() call. If you don't know it, use FileGetEncoding() and use the result in your StreamFrom call. BUT HERE'S THE CAVEAT: determining a file's encoding is tricky. There's a wide range of programs writing RTFs ... and the specification(s) for a file's encoding can be rather loosely implemented. As a result, there's a note in the Au3 function that it will return Binary (code = 16) if the encoding isn't clear. But you can never specify Binary in your StreamFrom call or you will get gibberish. A fairly reliable "rule" is that if your don't get a clear encoding indication—like UTF-8 or UTF-16—then it's pretty safe to assume ANSI for an RTF file on a windows PC ... so replace any code=16 with code=512. Feel free to suggest alternatives ... or ways to make the process more robust. For anyone who's interested, I found this related discussion on StackExchange: link #include <GUIConstantsEx.au3> #include <GuiRichEdit.au3> #include <WindowsConstants.au3> #include <WinAPISysWin.au3> #include <String.au3> #include <Array.au3> #include <File.au3> Global $watch = "C:\path\to\file.rtf" ; path to RTF file $hGui = GUICreate("Extract text from RTF", 660, 320, -1, -1) $lblMask = GUICtrlCreateLabel("", 10, 10, 300, 220) GUICtrlSetBkColor($lblMask, $GUI_BKCOLOR_TRANSPARENT) $hRichEdit = _GUICtrlRichEdit_Create($hGui, "This is a test.", 10, 20, 300, 220, BitOR($ES_MULTILINE, $WS_VSCROLL)) $normal = GUICtrlCreateEdit("initial text", 330, 20, 320, 240) $cButton = GUICtrlCreateButton("Process the file", 80, 270, 180, 30) $eButton = GUICtrlCreateButton("Examine first 500", 400, 270, 180, 30) GUICtrlSetState($cButton, $GUI_FOCUS) GUISetState(@SW_SHOW) While True $iMsg = GUIGetMsg() Select Case $iMsg = $GUI_EVENT_CLOSE _GUICtrlRichEdit_Destroy($hRichEdit) ; needed unless script crashes Exit Case $iMsg = $cButton $encoding = FileGetEncoding($watch) If $encoding = 16 Then $encoding = 512 ; MsgBox(0, "Encoding is ", $encoding) _GUICtrlRichEdit_StreamFromFile($hRichEdit, $watch, $encoding) GUICtrlSetData($normal, _GUICtrlRichEdit_GetText($hRichEdit, True)) ConsoleWrite("Processed" & @CRLF) Case $iMsg = $eButton $readText = StringLeft(GUICtrlRead($normal), 500) MsgBox(0, "2: ", $readText & @CRLF & _StringRepeat("-", 80) & @CRLF & _StringToHex($readText)) EndSelect WEnd
    1 point
  5. You're welcome, glad that it worked If you don't mind, a few words concerning the variable $ButtonF1a 1) No need to make it Global : Global $ButtonF1a Local is enough : ; $ButtonF1a = GUICtrlCreateButton("Launch Me", 10, 10, 125, 25) Local $ButtonF1a = GUICtrlCreateButton("Launch Me", 10, 10, 125, 25) 2) Re-enable it at a place that gives a better readability of the script, by moving its enable line from Func _Form2() to Func _Form1() Case $ButtonF1a GUICtrlSetState($ButtonF1a, $GUI_DISABLE) _LaunchNP() _Form2() GUICtrlSetState($ButtonF1a, $GUI_ENABLE) By the way, what happened to the following useful line that you were using in all your scripts ? Opt("MustDeclareVars", 1)
    1 point
  6. One final comment... Having got it working, I find that OpenOffice Calc copies a sheet but leaves the chart links still pointing to the original sheet data, so it's not the right solution for me. I have another approach which has all of the items on one sheet, so I'll go there. Thanks again for your time
    1 point
  7. pixelsearch, So, here is the completed scripts...all is now "appearing" to work as expected... #cs As Example3e, but employing notepad again. Status: Date: 12/28/24 #ce ; ----------------------------------------------- #include <ButtonConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> ; ----------------------------------------------- #AutoIt3Wrapper_Au3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 ; ----------------------------------------------- Global $Form1 Global $Form2 Global $ButtonF1a ; ----------------------------------------------- _Form1() ; ----------------------------------------------- Func _Form1() $Form1 = GUICreate("Form1", 145, 45) GUISetFont(14, 800, 0, "Calibri") ; ----------------------------------------------- $ButtonF1a = GUICtrlCreateButton("Launch Me", 10, 10, 125, 25) ; ----------------------------------------------- GUISetState(@SW_SHOW) ; ----------------------------------------------- While 1 Local $nMsg = GUIGetMsg() ; ----------------- Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $ButtonF1a GUICtrlSetState($ButtonF1a, $GUI_DISABLE) _LaunchNP() _Form2() EndSwitch WEnd EndFunc ;==>_Form1 ; ----------------------------------------------- Func _Form2() $Form2 = GUICreate("", 40, 35, 640, 280, $WS_POPUP, $WS_EX_TOPMOST) GUISetFont(14, 800, 0, "Calibri") ;GUISetBkColor(0x505050) ; ----------------------------------------------- Local $ButtonF2 = GUICtrlCreateLabel("Exit", 5, 5, 25, 25, $SS_CENTER) ;GUICtrlSetColor(-1, 0xFFFFFF) ; ----------------------------------------------- GUISetState(@SW_SHOW) ; ----------------------------------------------- While 1 Local $nMsg = GUIGetMsg() ; ----------------- Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $ButtonF2 GUIDelete($Form2) _ExitNP() GUICtrlSetState($ButtonF1a, $GUI_ENABLE) ExitLoop EndSwitch WEnd EndFunc ;==>_Form2 ; ----------------------------------------------- Func _LaunchNP() Local $sSrcAppPath = "C:\Windows\System32\notepad.exe" ; ----------------------------------------------- Run($sSrcAppPath) ; ----------------------------------------------- WinMove("[CLASS:Notepad]", "", 535, 210, 792, 590) EndFunc ;==>_LaunchNP ; ----------------------------------------------- Func _ExitNP() Local $sAppTitle = "[CLASS:Notepad]" ; ----------------------------------------------- WinClose($sAppTitle) EndFunc ;==>_ExitNP ; ----------------------------------------------- Thanks again for ALL of your efforts and input!!
    1 point
  8. Just add a single line to your 2nd script : Case $ButtonF2 _ExitNP() ExitLoop
    1 point
  9. @donnyh13 thanks for the prompt reply. I emulated this approach using the native LibreOffice controls (copying the cells and pasting) and it didn't bring the links between the charts and the cells over properly. What I did (and should have done before asking) was to read the link information in the UDF. By changing very few lines of code, I have modified _OOoCalc_SheetMove() and created _OOoCalc_SheetCopy() to do exactly what I need to do. The key is $oObj.Sheets.moveByName(). Calling $oObj.Sheets.copyByName() instead, with the additional parameter, does the trick. I do need to tidy up the error checking on the new parameter but I can now move on! Thanks for your help John ; #FUNCTION# ==================================================================================================================== ; Name ..........: _OOoCalc_SheetCopy ; Description ...: Copy the specified sheet to another specified position. ; Syntax ........: _OOoCalc_SheetMove(ByRef $oObj, $sSheet, $sNewSheet, $iPosition) ; _OOoCalc_SheetCopy(ByRef $oObj, $iPosition, $sNewSheet, $vSheet = -1) ; Parameters ....: $oObj - Calc object opened by a preceding call to _OOoCalc_BookOpen, _OOoCalc_BookNew, or ; _OOoCalc_BookAttach ; $sSheet - Name of the sheet to move ; $sNewSheet - New sheet name ; $iPosition - Position in which to move sheet. ; $vSheet - [optional] Worksheet, either by index (0-based) or name. ; Default is -1, which would use the active worksheet. ; Return values .: On Success - Returns 1 ; On Failure - Returns 0 and sets @error: ; |@error - 0 ($_OOoCalcStatus_Success) = No Error ; | - 3 ($_OOoCalcStatus_InvalidDataType) = Invalid Data Type ; | - 5 ($_OOoCalcStatus_NoMatch) = No Match ; |@extended - Contains Invalid Parameter Number ; Author ........: GMK ; Modified ......: g0gcd 27/12/2024 ; Remarks .......: Modification of _OOoCalc_SheetMove(). No error checking on $NewSheet ; Related .......: _OOoCalc_SheetAddNew, _OOoCalc_SheetDelete, _OOoCalc_SheetNameGet, _OOoCalc_SheetNameSet, _OOoCalc_SheetList, _OOoCalc_SheetActivate, _OOoCalc_SheetMove ; Link ..........: http://www.openoffice.org/api/docs/common/ref/com/sun/star/sheet/XSpreadsheets.html#moveByName ; http://www.openoffice.org/api/docs/common/ref/com/sun/star/sheet/XSpreadsheets.html#copyByName ; Example .......: No ; =============================================================================================================================== Func _OOoCalc_SheetCopy(ByRef $oObj, $iPosition, $sNewSheet, $vSheet = -1) Local $oOOoCalc_COM_ErrorHandler = ObjEvent("AutoIt.Error", __OOoCalc_ComErrorHandler_InternalFunction) #forceref $oOOoCalc_COM_ErrorHandler If Not IsObj($oObj) Then Return SetError($_OOoCalcStatus_InvalidDataType, 1, 0) If Not IsInt($iPosition) Then Return SetError($_OOoCalcStatus_InvalidDataType, 2, 0) If Not IsInt($vSheet) And Not IsString($vSheet) Then Return SetError($_OOoCalcStatus_InvalidDataType, 3, 0) If $vSheet > -1 And Not __OOoCalc_WorksheetIsValid($oObj, $vSheet) Then Return SetError($_OOoCalcStatus_NoMatch, 3, 0) If IsInt($vSheet) Then $vSheet = ($vSheet < 0) ? (_OOoCalc_SheetNameGet($oObj)) : ($oObj.getSheets.getByIndex($vSheet).name) $oObj.Sheets.copyByName($vSheet, $sNewSheet, $iPosition) Return SetError($_OOoCalcStatus_Success, 0, 1) EndFunc ;==>_OOoCalc_SheetCopy
    1 point
  10. czardas

    CSVSplit

    This UDF introduces one or two small tweaks to the functions I posted in Snippet Dump (nothing major). Terminating the CSV with a break is now the default behaviour (although I think it's just a lazy convention). The inclusion of a new function _ArrayToSubItemCSV() got me excited. Thanks for an awesome idea Chimaera. I have included the option to sort the returned CSV formatted strings ascending using any column. ; #include-once #include <Array.au3> ; #INDEX# ======================================================================================================================= ; Title .........: CSVSplit ; AutoIt Version : 3.3.8.1 ; Language ......: English ; Description ...: CSV related functions ; Notes .........: CSV format does not have a general standard format, however these functions allow some flexibility. ; The default behaviour of the functions applies to the most common formats used in practice. ; Author(s) .....: czardas ; =============================================================================================================================== ; #CURRENT# ===================================================================================================================== ;_ArrayToCSV ;_ArrayToSubItemCSV ;_CSVSplit ; =============================================================================================================================== ; #INTERNAL_USE_ONLY#============================================================================================================ ; __GetSubstitute ; =============================================================================================================================== ; #FUNCTION# ==================================================================================================================== ; Name...........: _ArrayToCSV ; Description ...: Converts a two dimensional array to CSV format ; Syntax.........: _ArrayToCSV ( $aArray [, $sDelim [, $sNewLine [, $bFinalBreak ]]] ) ; Parameters ....: $aArray - The array to convert ; $sDelim - Optional - Delimiter set to comma by default (see comments) ; $sNewLine - Optional - New Line set to @LF by default (see comments) ; $bFinalBreak - Set to true in accordance with common practice => CSV Line termination ; Return values .: Success - Returns a string in CSV format ; Failure - Sets @error to: ; |@error = 1 - First parameter is not a valid array ; |@error = 2 - Second parameter is not a valid string ; |@error = 3 - Third parameter is not a valid string ; |@error = 4 - 2nd and 3rd parameters must be different characters ; Author ........: czardas ; Comments ......; One dimensional arrays are returned as multiline text (without delimiters) ; ; Some users may need to set the second parameter to semicolon to return the prefered CSV format ; ; To convert to TSV use @TAB for the second parameter ; ; Some users may wish to set the third parameter to @CRLF ; =============================================================================================================================== Func _ArrayToCSV($aArray, $sDelim = Default, $sNewLine = Default, $bFinalBreak = True) If Not IsArray($aArray) Or Ubound($aArray, 0) > 2 Or Ubound($aArray) = 0 Then Return SetError(1, 0 ,"") If $sDelim = Default Then $sDelim = "," If $sDelim = "" Then Return SetError(2, 0 ,"") If $sNewLine = Default Then $sNewLine = @LF If $sNewLine = "" Then Return SetError(3, 0 ,"") If $sDelim = $sNewLine Then Return SetError(4, 0, "") Local $iRows = UBound($aArray), $sString = "" If Ubound($aArray, 0) = 2 Then ; Check if the array has two dimensions Local $iCols = UBound($aArray, 2) For $i = 0 To $iRows -1 For $j = 0 To $iCols -1 If StringRegExp($aArray[$i][$j], '["\r\n' & $sDelim & ']') Then $aArray[$i][$j] = '"' & StringReplace($aArray[$i][$j], '"', '""') & '"' EndIf $sString &= $aArray[$i][$j] & $sDelim Next $sString = StringTrimRight($sString, StringLen($sDelim)) & $sNewLine Next Else ; The delimiter is not needed For $i = 0 To $iRows -1 If StringRegExp($aArray[$i], '["\r\n' & $sDelim & ']') Then $aArray[$i] = '"' & StringReplace($aArray[$i], '"', '""') & '"' EndIf $sString &= $aArray[$i] & $sNewLine Next EndIf If Not $bFinalBreak Then $sString = StringTrimRight($sString, StringLen($sNewLine)) ; Delete any newline characters added to the end of the string Return $sString EndFunc ;==> _ArrayToCSV ; #FUNCTION# ==================================================================================================================== ; Name...........: _ArrayToSubItemCSV ; Description ...: Converts an array to multiple CSV formated strings based on the content of the selected column ; Syntax.........: _ArrayToSubItemCSV($aCSV, $iCol [, $sDelim [, $bHeaders [, $iSortCol [, $bAlphaSort ]]]]) ; Parameters ....: $aCSV - The array to parse ; $iCol - Array column used to search for unique content ; $sDelim - Optional - Delimiter set to comma by default ; $bHeaders - Include csv column headers - Default = False ; $iSortCol - The column to sort on for each new CSV (sorts ascending) - Default = False ; $bAlphaSort - If set to true, sorting will be faster but numbers won't always appear in order of magnitude. ; Return values .: Success - Returns a two dimensional array - col 0 = subitem name, col 1 = CSV data ; Failure - Returns an empty string and sets @error to: ; |@error = 1 - First parameter is not a 2D array ; |@error = 2 - Nothing to parse ; |@error = 3 - Invalid second parameter Column number ; |@error = 4 - Invalid third parameter - Delimiter is an empty string ; |@error = 5 - Invalid fourth parameter - Sort Column number is out of range ; Author ........: czardas ; Comments ......; @CRLF is used for line breaks in the returned array of CSV strings. ; ; Data in the sorting column is automatically assumed to contain numeric values. ; ; Setting $iSortCol equal to $iCol will return csv rows in their original ordered sequence. ; =============================================================================================================================== Func _ArrayToSubItemCSV($aCSV, $iCol, $sDelim = Default, $bHeaders = Default, $iSortCol = Default, $bAlphaSort = Default) If Not IsArray($aCSV) Or UBound($aCSV, 0) <> 2 Then Return SetError(1, 0, "") ; Not a 2D array Local $iBound = UBound($aCSV), $iNumCols = UBound($aCSV, 2) If $iBound < 2 Then Return SetError(2, 0, "") ; Nothing to parse If IsInt($iCol) = 0 Or $iCol < 0 Or $iCol > $iNumCols -1 Then Return SetError(3, 0, "") ; $iCol is out of range If $sDelim = Default Then $sDelim = "," If $sDelim = "" Then Return SetError(4, 0, "") ; Delimiter can not be an empty string If $bHeaders = Default Then $bHeaders = False If $iSortCol = Default Or $iSortCol == False Then $iSortCol = -1 If IsInt($iSortCol) = 0 Or $iSortCol < -1 Or $iSortCol > $iNumCols -1 Then Return SetError(5, 0, "") ; $iSortCol is out of range If $bAlphaSort = Default Then $bAlphaSort = False Local $iStart = 0 If $bHeaders Then If $iBound = 2 Then Return SetError(2, 0, "") ; Nothing to parse $iStart = 1 EndIf Local $sTestItem, $iNewCol = 0 If $iSortCol <> -1 And ($bAlphaSort = False Or $iSortCol = $iCol) Then ; In this case we need an extra Column for sorting ReDim $aCSV [$iBound][$iNumCols +1] ; Populate column If $iSortCol = $iCol Then For $i = $iStart To $iBound -1 $aCSV[$i][$iNumCols] = $i Next Else For $i = $iStart To $iBound -1 $sTestItem = StringRegExpReplace($aCSV[$i][$iSortCol], "\A\h+", "") ; Remove leading horizontal WS If StringIsInt($sTestItem) Or StringIsFloat($sTestItem) Then $aCSV[$i][$iNumCols] = Number($sTestItem) Else $aCSV[$i][$iNumCols] = $aCSV[$i][$iSortCol] EndIf Next EndIf $iNewCol = 1 $iSortCol = $iNumCols EndIf _ArraySort($aCSV, 0, $iStart, 0, $iCol) ; Sort on the selected column Local $aSubItemCSV[$iBound][2], $iItems = 0, $aTempCSV[1][$iNumCols + $iNewCol], $iTempIndex $sTestItem = Not $aCSV[$iBound -1][$iCol] For $i = $iBound -1 To $iStart Step -1 If $sTestItem <> $aCSV[$i][$iCol] Then ; Start a new csv instance If $iItems > 0 Then ; Write to main array ReDim $aTempCSV[$iTempIndex][$iNumCols + $iNewCol] If $iSortCol <> -1 Then _ArraySort($aTempCSV, 0, $iStart, 0, $iSortCol) If $iNewCol Then ReDim $aTempCSV[$iTempIndex][$iNumCols] $aSubItemCSV[$iItems -1][0] = $sTestItem $aSubItemCSV[$iItems -1][1] = _ArrayToCSV($aTempCSV, $sDelim, @CRLF) EndIf ReDim $aTempCSV[$iBound][$iNumCols + $iNewCol] ; Create new csv template $iTempIndex = 0 $sTestItem = $aCSV[$i][$iCol] If $bHeaders Then For $j = 0 To $iNumCols -1 $aTempCSV[0][$j] = $aCSV[0][$j] Next $iTempIndex = 1 EndIf $iItems += 1 EndIf For $j = 0 To $iNumCols + $iNewCol -1 ; Continue writing to csv $aTempCSV[$iTempIndex][$j] = $aCSV[$i][$j] Next $iTempIndex += 1 Next ReDim $aTempCSV[$iTempIndex][$iNumCols + $iNewCol] If $iSortCol <> -1 Then _ArraySort($aTempCSV, 0, $iStart, 0, $iSortCol) If $iNewCol Then ReDim $aTempCSV[$iTempIndex][$iNumCols] $aSubItemCSV[$iItems -1][0] = $sTestItem $aSubItemCSV[$iItems -1][1] = _ArrayToCSV($aTempCSV, $sDelim, @CRLF) ReDim $aSubItemCSV[$iItems][2] Return $aSubItemCSV EndFunc ;==> _ArrayToSubItemCSV ; #FUNCTION# ==================================================================================================================== ; Name...........: _CSVSplit ; Description ...: Converts a string in CSV format to a two dimensional array (see comments) ; Syntax.........: CSVSplit ( $aArray [, $sDelim ] ) ; Parameters ....: $aArray - The array to convert ; $sDelim - Optional - Delimiter set to comma by default (see 2nd comment) ; Return values .: Success - Returns a two dimensional array or a one dimensional array (see 1st comment) ; Failure - Sets @error to: ; |@error = 1 - First parameter is not a valid string ; |@error = 2 - Second parameter is not a valid string ; |@error = 3 - Could not find suitable delimiter replacements ; Author ........: czardas ; Comments ......; Returns a one dimensional array if the input string does not contain the delimiter string ; ; Some CSV formats use semicolon as a delimiter instead of a comma ; ; Set the second parameter to @TAB To convert to TSV ; =============================================================================================================================== Func _CSVSplit($string, $sDelim = ",") ; Parses csv string input and returns a one or two dimensional array If Not IsString($string) Or $string = "" Then Return SetError(1, 0, 0) ; Invalid string If Not IsString($sDelim) Or $sDelim = "" Then Return SetError(2, 0, 0) ; Invalid string $string = StringRegExpReplace($string, "[\r\n]+\z", "") ; [Line Added] Remove training breaks Local $iOverride = 63743, $asDelim[3] ; $asDelim => replacements for comma, new line and double quote For $i = 0 To 2 $asDelim[$i] = __GetSubstitute($string, $iOverride) ; Choose a suitable substitution character If @error Then Return SetError(3, 0, 0) ; String contains too many unsuitable characters Next $iOverride = 0 Local $aArray = StringRegExp($string, '\A[^"]+|("+[^"]+)|"+\z', 3) ; Split string using double quotes delim - largest match $string = "" Local $iBound = UBound($aArray) For $i = 0 To $iBound -1 $iOverride += StringInStr($aArray[$i], '"', 0, -1) ; Increment by the number of adjacent double quotes per element If Mod ($iOverride +2, 2) = 0 Then ; Acts as an on/off switch $aArray[$i] = StringReplace($aArray[$i], $sDelim, $asDelim[0]) ; Replace comma delimeters $aArray[$i] = StringRegExpReplace($aArray[$i], "(\r\n)|[\r\n]", $asDelim[1]) ; Replace new line delimeters EndIf $aArray[$i] = StringReplace($aArray[$i], '""', $asDelim[2]) ; Replace double quote pairs $aArray[$i] = StringReplace($aArray[$i], '"', '') ; Delete enclosing double quotes - not paired $aArray[$i] = StringReplace($aArray[$i], $asDelim[2], '"') ; Reintroduce double quote pairs as single characters $string &= $aArray[$i] ; Rebuild the string, which includes two different delimiters Next $iOverride = 0 $aArray = StringSplit($string, $asDelim[1], 2) ; Split to get rows $iBound = UBound($aArray) Local $aCSV[$iBound][2], $aTemp For $i = 0 To $iBound -1 $aTemp = StringSplit($aArray[$i], $asDelim[0]) ; Split to get row items If Not @error Then If $aTemp[0] > $iOverride Then $iOverride = $aTemp[0] ReDim $aCSV[$iBound][$iOverride] ; Add columns to accomodate more items EndIf EndIf For $j = 1 To $aTemp[0] If StringLen($aTemp[$j]) Then If Not StringRegExp($aTemp[$j], '[^"]') Then ; Field only contains double quotes $aTemp[$j] = StringTrimLeft($aTemp[$j], 1) ; Delete enclosing double quote single char EndIf $aCSV[$i][$j -1] = $aTemp[$j] ; Populate each row EndIf Next Next If $iOverride > 1 Then Return $aCSV ; Multiple Columns Else For $i = 0 To $iBound -1 If StringLen($aArray[$i]) And (Not StringRegExp($aArray[$i], '[^"]')) Then ; Only contains double quotes $aArray[$i] = StringTrimLeft($aArray[$i], 1) ; Delete enclosing double quote single char EndIf Next Return $aArray ; Single column EndIf EndFunc ;==> _CSVSplit ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name...........: __GetSubstitute ; Description ...: Searches for a character to be used for substitution, ie one not contained within the input string ; Syntax.........: __GetSubstitute($string, ByRef $iCountdown) ; Parameters ....: $string - The string of characters to avoid ; $iCountdown - The first code point to begin checking ; Return values .: Success - Returns a suitable substitution character not found within the first parameter ; Failure - Sets @error to 1 => No substitution character available ; Author ........: czardas ; Comments ......; This function is connected to the function _CSVSplit and was not intended for general use ; $iCountdown is returned ByRef to avoid selecting the same character on subsequent calls to this function ; Initially $iCountown should be passed with a value = 63743 ; =============================================================================================================================== Func __GetSubstitute($string, ByRef $iCountdown) If $iCountdown < 57344 Then Return SetError(1, 0, "") ; Out of options Local $sTestChar For $i = $iCountdown To 57344 Step -1 $sTestChar = ChrW($i) $iCountdown -= 1 If Not StringInStr($string, $sTestChar) Then Return $sTestChar EndIf Next Return SetError(1, 0, "") ; Out of options EndFunc ;==> __GetSubstitute ; See examples in post #8 below. ;
    1 point
  11. @Irios if you're looking for both the property name and the value in a single pass I would do something like this: Local $oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2") Local $oItems = $oWMI.ExecQuery("Select * FROM Win32_PerfRawData_Tcpip_NetworkInterface") For $sItem In $oItems For $sProperty In $sItem.Properties_ ConsoleWrite($sProperty.Name & ": " & $sProperty.Value & @CRLF) Next Next Just be aware that some properties may return an array rather than a string. So you might have to code a For loop to gather all the values.
    1 point
×
×
  • Create New...