Jump to content

Snippet Dump


czardas
 Share

Recommended Posts

No offense at all. :x That's why we do these tests; To find the fastest and most correct method. I found a some small errors in the fastest method and that led me to rewrite it like this by doing simple things like putting the checks in the right order:

Func _ArrayModalSpin(ByRef $av_Array, $iClicks)
    If $iClicks = 0 Then Return
    Local $iElements = UBound($av_Array)
    If $iClicks >= $iElements Then $iClicks = Mod($iClicks, $iElements)
    If $iClicks < 0 Then
        $iClicks *= -1
        $iStart = $iElements -$iClicks
        $iResume = $iClicks
    Else
        $iStart = $iClicks
        $iResume = $iElements -$iClicks
    EndIf
    Local $av_Temp[$iElements]
    For $i = 0 To $iResume -1
        $av_Temp[$i] = $av_Array[$iStart +$i]
    Next
    For $i = $iResume To $iElements -1
        $av_Temp[$i] = $av_Array[$i -$iResume]
    Next
    $av_Array = $av_Temp
EndFunc

( Didn't test this version )

I had a look at when the large arrays are created and destroyed again and those are of course these lines:

Local $av_Temp[$iElements]
For $i = 0 To $iResume -1
    $av_Temp[$i] = $av_Array[$iStart +$i]
Next
For $i = $iResume To $iElements -1
    $av_Temp[$i] = $av_Array[$i -$iResume]
Next
$av_Array = $av_Temp

but you can rewrite this part like this:

$av_Temp = $av_Array
For $i = 0 To $iResume -1
    $av_Array[$i] = $av_Temp[$iStart +$i]
Next
For $i = $iResume To $iElements -1
    $av_Array[$i] = $av_Temp[$i -$iResume]
Next

so you essentially do the same thing but you save 1 operator: Defining a large empty array. This is still done in the new version but it happens on the inside of AutoIt. This brings us this new version:

Func _ArrayModalSpin(ByRef $av_Array, $iClicks)
    If $iClicks = 0 Then Return
    Local $iElements = UBound($av_Array)
    If $iClicks >= $iElements Then $iClicks = Mod($iClicks, $iElements)
    If $iClicks < 0 Then
        $iClicks *= -1
        $iStart = $iElements -$iClicks
        $iResume = $iClicks
    Else
        $iStart = $iClicks
        $iResume = $iElements -$iClicks
    EndIf
    $av_Temp = $av_Array
    For $i = 0 To $iResume -1
        $av_Array[$i] = $av_Temp[$iStart +$i]
    Next
    For $i = $iResume To $iElements -1
        $av_Array[$i] = $av_Temp[$i -$iResume]
    Next
EndFunc

Which gives us roughly a 20% speed increase. 8) Not much, but noticeable enough.

Link to comment
Share on other sites

That's pretty cool, although I thought a problem might occur (I realize now that it still works). I believe the first check belongs after the Mod function. It may slow it down slightly otherwise. When $iClicks turns out to be either a multiple of $iElements or equal to zero, we want to quit the function at that point. It seems a bit silly to say spin the array zero clicks (or 360 degrees), so it's probably more useful to do it this way.

Func _ArrayModalSpin(ByRef $av_Array, $iClicks)
    Local $iElements = UBound($av_Array)
    $iClicks = Mod($iClicks, $iElements)
    If $iClicks = 0 Then Return
    If $iClicks > 0 Then
        $iStart = $iClicks
        $iResume = $iElements -$iClicks
    Else
        $iClicks *= -1
        $iStart = $iElements -$iClicks
        $iResume = $iClicks
    EndIf
    $av_Temp = $av_Array
    For $i = 0 To $iResume -1
        $av_Array[$i] = $av_Temp[$iStart +$i]
    Next
    For $i = $iResume To $iElements -1
        $av_Array[$i] = $av_Temp[$i -$iResume]
    Next
EndFunc

I never thought that copying an array would be faster than declaring an empty array of the same size, but if it's done internally, then I see why. 20% is a significant increase in speed.

Edited by czardas
Link to comment
Share on other sites

I have removed the conditional statement at line 3 (post 24). There was still one problem. In this particular script, it seems to be 'universally' better to go for using the Mod function every time (without the checks). Otherwise an additional conditional statement would be required, however the extra code offers no clear advantage.

Running the same speed test (post 22) with the new version (post 24) gives 2960.22036320259. That's a big improvement from the original. :x

Edited by czardas
Link to comment
Share on other sites

Also, I wanted to make a post why using only one array is not possible.

Are your sure about that "not possible" bit?

Granted this is only a test case. No actually spinning is done. But still, it looks possible.

CodeDump:

TestCase:

#AutoIt3Wrapper_AU3Check_Stop_OnWarning=y
#AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 6 -q

#cs
    Func test_X($av_Array, Const $iStep) ;; test case. (touch every array position one's, using given step value as base step.)
    Func CaseLoop() ;; walk trough different sized array's.
    Func SpinLoop($av_Array) ;; walk trough possible step values for given array.
    Func DebugOut($1 = '', $2 = '') ;; print to console.
    Func _DB_ArrayToString($av_Array) ;; 1D array only.
    Func _NumberArray($iSize) ;; [' 1',...,'99']
#ce

CaseLoop()
Exit

Func test_X($av_Array, Const $iStep)
    DebugOut('+ $av_Array', $av_Array) ;### Debug DebugOut.
    DebugOut('+ $iStep', $iStep) ;### Debug DebugOut.

    ;; target: Keep looping around a array untill all entries are processed. (one time only)
    ;; - assumes positive $iStep values only. (test case)

    ;; using absolute array position value.
    ;; (-1 them "when" modifing array elements. Array only intended/used for Debug output purpuse.)
    Local Const $iFirst = 1
    Local Const $iLast = UBound($av_Array, 1)

    If Not Mod($iStep, $iLast) Then
        DebugOut('> nothing to do') ;### Debug DebugOut.
        Return
    EndIf

    Local $iOffset1 = 0 ;; inside set-looping offset.
    Local $iOffset2 = 0 ;; global pre set-looping offset.
    Local $sLog = '|' ;; just to get the thing working.
    Local $iConter1 = 0 ;; [debug][array modivication feedback]
    While 1

        For $i = $iFirst + $iOffset1 + $iOffset2 To $iLast Step $iStep
            $sLog &= $i & '|'
;~          DebugOut('$sLog', $sLog) ;### Debug DebugOut.
            $av_Array[$i - $iFirst] = Chr(65 + $iConter1) & Chr(65 + $iConter1)
            $iConter1 += 1
            DebugOut('> $av_Array', $av_Array) ;### Debug DebugOut.
        Next

        $iOffset1 = $i - $iLast - 1 ;; set walked of the given ranges. loop it back to start.
        If StringInStr($sLog, '|' & String($iFirst + $iOffset1)) Then
            ;; set has looped back on itself. jump to next (posible) set.
            $iOffset2 += 1
            $iOffset1 = 0
            If StringInStr($sLog, '|' & String($iFirst + $iOffset1 + $iOffset2)) Then ExitLoop ;; next set allready processed, exit main loop.
        EndIf

    WEnd
EndFunc

Func CaseLoop()
    Local $av_Array
    For $i = 2 To 6
;~      DebugOut('> CaseLoop: $i', $i) ;### Debug DebugOut.
        $av_Array = _NumberArray($i)
        SpinLoop($av_Array)
    Next
EndFunc
Func SpinLoop($av_Array)
    Local $result
    For $i = 1 To UBound($av_Array, 1) - 1
;~      DebugOut('> SpinLoop: $i', $i) ;### Debug DebugOut.
        test_X($av_Array, $i)
    Next
EndFunc

Func DebugOut($1 = '', $2 = '')
    If IsString($2) And $2 Then $2 = '"' & StringReplace($2, "'", "''") & '"'
    If IsArray($2) Then $2 = _DB_ArrayToString($2)
    If $2 Or Not IsString($2) Then $1 &= ' = ' & String($2)
    ConsoleWrite($1 & @CRLF)
EndFunc
Func _DB_ArrayToString($av_Array)
    Local $sOut = ''
    For $e In $av_Array
;~      If IsString($e) Then $e = "'" & StringReplace($e, "'", "''") & "'"
        $sOut &= $e & ','
    Next
    Return '[' & StringTrimRight($sOut, 1) & ']'
EndFunc

Func _NumberArray($iSize)
    Local $aOut[$iSize]
    For $i = 1 To $iSize
        $aOut[$i - 1] = StringFormat('%2d', $i)
    Next
    Return $aOut
EndFunc
OutputSample:
+ $aTemp = [ 1, 2, 3]
+ $iStep = 2
> $aTemp = [AA, 2, 3]
> $aTemp = [AA, 2,BB]
> $aTemp = [AA,CC,BB]
+ $aTemp = [ 1, 2, 3, 4]
+ $iStep = 1
> $aTemp = [AA, 2, 3, 4]
> $aTemp = [AA,BB, 3, 4]
> $aTemp = [AA,BB,CC, 4]
> $aTemp = [AA,BB,CC,DD]
+ $aTemp = [ 1, 2, 3, 4]
+ $iStep = 2
> $aTemp = [AA, 2, 3, 4]
> $aTemp = [AA, 2,BB, 4]
> $aTemp = [AA,CC,BB, 4]
> $aTemp = [AA,CC,BB,DD]
+ $aTemp = [ 1, 2, 3, 4]
+ $iStep = 3
> $aTemp = [AA, 2, 3, 4]
> $aTemp = [AA, 2, 3,BB]
> $aTemp = [AA, 2,CC,BB]
> $aTemp = [AA,DD,CC,BB]

"Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions."
"The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014)

"Believing what you know ain't so" ...

Knock Knock ...
 

Link to comment
Share on other sites

Are your sure about that "not possible" bit?

Granted this is only a test case. No actually spinning is done. But still, it looks possible.

+ $aTemp = [ 1, 2, 3]
+ $iStep = 2
> $aTemp = [AA, 2, 3]
> $aTemp = [AA, 2,BB]
> $aTemp = [AA,CC,BB]
+ $aTemp = [ 1, 2, 3, 4]
+ $iStep = 1
> $aTemp = [AA, 2, 3, 4]
> $aTemp = [AA,BB, 3, 4]
> $aTemp = [AA,BB,CC, 4]
> $aTemp = [AA,BB,CC,DD]
+ $aTemp = [ 1, 2, 3, 4]
+ $iStep = 2
> $aTemp = [AA, 2, 3, 4]
> $aTemp = [AA, 2,BB, 4]
> $aTemp = [AA,CC,BB, 4]
> $aTemp = [AA,CC,BB,DD]
+ $aTemp = [ 1, 2, 3, 4]
+ $iStep = 3
> $aTemp = [AA, 2, 3, 4]
> $aTemp = [AA, 2, 3,BB]
> $aTemp = [AA, 2,CC,BB]
> $aTemp = [AA,DD,CC,BB]

I wish I knew what you were doing. Sure reversing the final output gives a spin of -1 (by my original definition), but I don't understand why $aTemp is not a modified copy of $av_Array. Perhaps the format is slightly different. It seems like an interesting technique none the less. :x

$aTemp = [AA,DD,CC,BB]
Edited by czardas
Link to comment
Share on other sites

1) "$aTemp":

Erm ... not sure what you main with $aTemp, although this might explain it.

local code:

Func testloop($aTemp, $iStep)
...
$aTemp[$i - $iFirst] = Chr(65 + $iConter1) & Chr(65 + $iConter1)
$iConter1 += 1
DebugOut('> $aTemp', $aTemp) ;### Debug DebugOut.
Seems I forgot to update the output to reflect the cleaned up posted version. :P

So $aTemp == $av_Array.

2) "not updated":

Well its a test case and I did not ByRef the $av_Array parameter in Func test_X($av_Array, Const $iStep) so I could keep feeding it the original $av_Array from SpinLoop(). That also made me not do anything else but updating the used array with debug information. :shifty:

3) "I wish I knew what you were doing."

Just playing around with a idea.

I did do a array processing function where I first took out one value/data to make a empty entry, so other data could be shuffled around whiteout having to temporary save one when swapping two data entries. (Think it was some randomize-array function.) Did the same thing here. At leased thats the base idea of the whole process. The rest is to fix the shortcomings and/or limitations of that process.

-a flip back to begin or array when the loop crosses the end of the array.

-b switch to next(unprocessed) entry in array when the loop loops back on the entry from which it started.)

-c continue until -b fails. :x

Note:

This will never be faster that your original code that uses 2 array's. Du(?) to the additional code needed to keep the looping under controle.

So the only real benefit is less memory use (for the duration of the spinning) ... but with a array so big that it needs this ... I will question the user for using such a big array. :nuke:

Hope it make some sens.

Edited by MvGulik

"Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions."
"The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014)

"Believing what you know ain't so" ...

Knock Knock ...
 

Link to comment
Share on other sites

@ MvGulik Ah Okay! In sound recording they call using an extra track 'bouncing' (or at least they used to). That's something similar to the empty array element you are using. :x


Now we have the modal string version. :P

; #FUNCTION# ============================================================================
; Name...........: _StringModalSpin
; Description ...: Rotates a string as if the string were a continuous modal loop.
; Syntax.........: _StringModalSpin($sString, $iShift)
; Parameters ....: $sString - Original string
;                 $iShift  - The number of characters to shift right (negative values shift characters to the left)
; Return values .: Success  - Returns the new modified string
;                 Failure  - Returns an empty string and sets @error to the following values:
;                 |@error = 1 : Invalid source string
;                 |@error = 2 : Invalid shift value
; Author ........: czardas
; Example .......: Yes
; ========================================================================================
 
Func _StringModalSpin($sString, $iShift)
    If $sString = "" Or (Not IsString($sString)) Then Return SetError(1, 0, "") ; Source string empty / not a string
    If Not IsInt($iShift) Then Return SetError(2, 0, "") ; Shift value is not an integer.
    Local $iStringLen = StringLen($sString)
    $iShift = Mod($iShift, $iStringLen)
    If $iShift = 0 Then Return $sString
    If $iShift > 0 Then
        Return StringRight($sString, $iShift) & StringLeft($sString, $iStringLen -$iShift)
    Else
        Return StringRight($sString, $iStringLen +$iShift) & StringLeft($sString, -$iShift)
    EndIf
EndFunc
 
; Example
Local $sScale = "CDEFGAB", $as_Mode[7] = ["Ionian","Dorian","Phrygian","Lydian","Mixolydian","Aeolian","Locrian"]
 
For $i = 0 To 6
    ConsoleWrite(_StringModalSpin($sScale, -$i) & StringMid($sScale, $i +1, 1) & " - " & $as_Mode[$i] & @LF)
Next

Edit

To demonstrate the use of this function, I have replaced the original example with one which some of you will find more familiar. If you are uncertain what the example is about, you may wish to refer to the following article: http://en.wikipedia.org/wiki/Musical_mode#Modern.

Edited by czardas
Link to comment
Share on other sites

MvGulik, you're probably right. You can spin the array by 1 or -1 without using 2 arrays: You only need one extra variable (not array) to hold the object being shifted (in an a=b and b=a sense you also need c). If you repeat that process several times you are still only using one array, but spinning the array multiple times. Good thinking.

Link to comment
Share on other sites

In addition to the spin effects, I have added two more modal functions. I have changed the definition of positive spin in _StringModalSpin (post 30) to comply with the other modal functions.

_ArrayModalSelect makes the job of looping round an array very simple. The beauty of this function is that you never have to worry about exceeding the number of array elements (error message) because the array is treated as having an infinite number of elements.

_StringModalSelect is similar to _StringModalSpin, however the return string can have any length.

Modal.au3

; #FUNCTION# ============================================================================
; Name...........: _ArrayModalSpin
; Description ...: Rotates a one dimensional array as if it were a continuous modal loop.
; Syntax.........: _ArrayModalSpin(ByRef $av_Array, $iShift)
; Parameters ....: $av_Array - Original array
;                  $iShift   - The number of elements to shift up (negative values shift elements down)
; Return values .: Success   - Returns a new modified array
;                  Failure   - Sets @error to the following values:
;                  |@error = 1 : The first parameter is not a one dimensional array
;                  |@error = 2 : Invalid shift value
; Author ........: czardas, Manadar
; Related .......: __ArrayModalSelect
; Example .......: Yes
; ========================================================================================

Func _ArrayModalSpin($av_Array, $iShift)
    If (Not IsArray($av_Array)) Or UBound($av_Array, 2) Then Return SetError(1)
    If Not IsInt($iShift) Then Return SetError(2)

    Local $iElements = UBound($av_Array)
    $iShift = Mod($iShift, $iElements)
    If $iShift = 0 Then Return $av_Array
    If $iShift > 0 Then
        $iStart = $iShift
        $iResume = $iElements -$iShift
    Else
        $iShift *= -1
        $iStart = $iElements -$iShift
        $iResume = $iShift
    EndIf
    $av_Temp = $av_Array
    For $i = 0 To $iResume -1
        $av_Array[$i] = $av_Temp[$iStart +$i]
    Next
    For $i = $iResume To $iElements -1
        $av_Array[$i] = $av_Temp[$i -$iResume]
    Next
    Return $av_Array
EndFunc ;==> _ArrayModalSpin

; #FUNCTION# ============================================================================
; Name...........: _StringModalSpin
; Description ...: Rotates a string as if the string were a continuous modal loop.
; Syntax.........: _StringModalSpin($sString, $iShift)
; Parameters ....: $sString - Original string
;                  $iShift  - The number of characters to shift left (negative values shift characters to the right)
; Return values .: Success  - Returns the new modified string
;                  Failure  - Returns an empty string and sets @error to the following values:
;                  |@error = 1 : Invalid source string
;                  |@error = 2 : Invalid shift value
; Author ........: czardas
; Related .......: _StringModalSelect
; Example .......: Yes
; ========================================================================================

Func _StringModalSpin($sString, $iShift)
    If $sString = "" Or (Not IsString($sString)) Then Return SetError(1, 0, "")
    If Not IsInt($iShift) Then Return SetError(2, 0, "")

    Local $iStringLen = StringLen($sString)
    $iShift = Mod($iShift, $iStringLen)
    If $iShift = 0 Then Return $sString
    If $iShift > 0 Then
        Return StringRight($sString, $iStringLen -$iShift) & StringLeft($sString, $iShift)
    Else
        Return StringRight($sString, -$iShift) & StringLeft($sString, $iStringLen +$iShift)
    EndIf
EndFunc ;==> _StringModalSpin

; #FUNCTION# ============================================================================
; Name...........: _ArrayModalSelect
; Description ...: Selects any element from a continuous modal array loop.
; Syntax.........: _ArrayModalSelect($av_Array, $iElement)
; Parameters ....: $av_Array - Infinite modal array
;                  $iElement - Element to select from the infinite array (negative values loop backwards)
; Return values .: Success   - Returns the array element
;                  Failure   - Sets @error to the following values:
;                  |@error = 1 : Parameter 1 is not a one dimensional array
;                  |@error = 2 : Element is not an integer
; Author ........: czardas
; Related .......: __ArrayModalSpin
; Example .......: Yes
; ========================================================================================

Func _ArrayModalSelect($av_Array, $iElement)
    If (IsArray($av_Array) = 0) Or UBound($av_Array, 2) Then Return SetError(1)
    If Not IsInt($iElement) Then Return SetError(2)

    $iElement = Mod($iElement, UBound($av_Array))
    If $iElement >= 0 Then
        Return $av_Array[$iElement]
    Else
        Return $av_Array[UBound($av_Array) +$iElement]
    EndIf
EndFunc ;==> _ArrayModalSelect

; #FUNCTION# ============================================================================
; Name...........: _StringModalSelect
; Description ...: Selects a number of characters from a continuous modal string loop.
; Syntax.........: _StringModalSelect( $sString [, $iShift [, $iChars]])
; Parameters ....: $sString - Original string
;                  $iShift  - The number of characters to shift left prior to selection (negative values shift characters right)
; Return values .: Success  - Returns the new string
;                  Failure  - Returns an empty string and sets @error to the following values:
;                  |@error = 1 : Invalid source string
;                  |@error = 2 : Invalid shift value
;                  |@error = 3 : Invalid number of characters
; Author ........: czardas
; Remarks .......: Return string can be any length
; Related .......: _StringModalSpin
; Example .......: Yes
; ========================================================================================

Func _StringModalSelect($sString, $iShift = 0, $iChars = 1)
    If $sString = "" Or (Not IsString($sString)) Then Return SetError(1, 0, "")
    If Not IsInt($iShift) Then Return SetError(2, 0, "")
    If (Not IsInt($iChars)) Or $iChars <= 0 Then Return SetError(3, 0, "")

    ; Get the current position of the first character for the new string
    Local $iStringLen = StringLen($sString)
    $iShift = Mod($iShift, $iStringLen)
    If $iShift >= 0 Then
        $iStart = $iShift +1
    Else
        $iStart = $iStringLen +$iShift +1
    EndIf

    Local $iEnd = $iStart +$iChars -1 ; Get the projected end character position
    If $iEnd <= $iStringLen Then
        Return StringMid($sString, $iStart, $iChars) ; The return string is contained within the original string
    Else
        $sTemp = $sString
        For $i = 1 To Int($iEnd/$iStringLen) -1
            $sTemp &= $sString ; repeat the modal string loop as required
        Next
        $sTemp = StringTrimLeft($sTemp, $iStart -1) ; remove surplus leading chars
        Return $sTemp & StringLeft($sString, Mod($iEnd, $iStringLen)) ; Add the final character sequence
    EndIf
EndFunc ;==> _StringModalSelect

Examples

#include 'Modal.au3'

ConsoleWrite("Example 1" & @LF & _StringModalSpin("round the other way ", -14) & @LF)

ConsoleWrite(@LF & "Example 2 - Every other day" & @LF)
Local $as_Days[7] = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]
For $i = -6 To 6 Step 2
    ConsoleWrite(_ArrayModalSelect($as_Days, $i) &@LF) ; Every other day
Next

ConsoleWrite(@LF & "Example 3 - Greek Modes" & @LF)
Local $as_Mode[7] = ["Aeolian","Locrian","Ionian","Dorian","Phrygian","Lydian","Mixolydian"]
$as_Mode = _ArrayModalSpin($as_Mode, 2) ; Spin the array

Local $scale = "ABCDEFG" ; Each output string will contain eight musical notes
For $i = 0 To 6
    ConsoleWrite(_StringModalSelect($scale, $i -5, 8) & " - " & $as_Mode[$i] & @LF)
Next

_StringModalSelect("test", 1, 4) == _StringModalSpin("test", 1)

At first I wasn't sure if I should have made the first post in help and support. But I think the discussion here has turned out to be a good example of finding ways to improve a script (which was already working). Whether anyone else will find these functions useful is unknown to me. I will definately make use of them myself. Please let me know your thoughts.

Edited by czardas
Link to comment
Share on other sites

  • 7 months later...

I started this thread for minor applications, or bits of code that may be of potential interest to anyone (perhaps someone just starting out will find something useful here). My more important projects seem to take for ever and occasionally I feel the need to write something really simple. So here's Log Dog - a very simple application which I made a while back. It's nothing more than an edit control which appends the time and date every time you press the enter key. The text is saved automatically in a file called logdog.log. You can use the enter key normally when you hold down the control key - don't know why though! :mellow:

The code also includes hotfixes for two (edit control) bugs which are known to affect some users of AutoIt. These issues could be related to each other, but the cause is a bit of a mystery. Thanks to the forum members who explained to me how to fix these issues using accelerators.

LogDog.au3

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiEdit.au3>

_RunLogDog()

Func _RunLogDog()
    Local $hLogDog = GUICreate(" Log Dog", 600, 400, Default, Default, $WS_OVERLAPPEDWINDOW)
    Local $hEdit = GUICtrlCreateEdit("", 0, 0, 600, 400, BitOr($GUI_SS_DEFAULT_EDIT, $ES_NOHIDESEL)), _
    $hEnter = GUICtrlCreateDummy(), _
    $hTab = GUICtrlCreateDummy(), _
    $hSelectAll = GUICtrlCreateDummy(), _
    $AccelKeys[3][2] = [["{ENTER}", $hEnter],[ @TAB, $hTab],["^a", $hSelectAll]]

    GUICtrlSetFont($hEdit, 12, 400, 1, "Lucida Console")
    GUISetAccelerators($AccelKeys)
    GUISetState()

    While 1
        $msg = GUIGetMsg()
        Switch $msg
            Case $GUI_EVENT_CLOSE
                _ExitLogDog($hEdit)
            Case $hEnter
                _LogEntry($hEdit)
            Case $hTab
                _TAB($hEdit)
            Case $hSelectAll
                _SelectAll($hEdit)
        EndSwitch
    WEnd
EndFunc ;==> _RunLogDog

Func _LogEntry($hEdit) ; Appends time and date on pressing enter
    Local $sLogEntry = @CRLF & "Logged on " & _GetDescriptiveDate() & _
    " at " & @HOUR & ":" & @MIN & ":" & @SEC & @CRLF & @CRLF
    _GUICtrlEdit_ReplaceSel($hEdit, $sLogEntry)
EndFunc ;==> _LogEntry

Func _GetDescriptiveDate()
    Local $WeekDay[7] = ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"], _
    $Month[12] = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"], _
    $MonthDay = Number(@MDAY), $sTag = "th"
    Switch Number(StringRight($MonthDay, 1))
        Case 1
            $sTag = "st"
        Case 2
            $sTag = "nd"
        Case 3
            $sTag = "rd"
    EndSwitch
    Return $WeekDay[@WDAY -1] &" " & $MonthDay & $sTag & " " & $Month[@MON -1] & " " &  @YEAR
EndFunc ;==> _GetDescriptiveDate

Func _TAB($hEdit) ; Bug Fix - unknown cause
    _GUICtrlEdit_ReplaceSel($hEdit, @TAB)
EndFunc ;==> _TAB

Func _SelectAll($hEdit) ; Bug Fix - unknown cause
    _GUICtrlEdit_SetSel($hEdit, 0, -1)
EndFunc ;==> _SelectAll

Func _ExitLogDog($hEdit)
    Local $EditText = GUICtrlRead($hEdit)
    If StringLen($EditText) Then FileWriteLine(@ScriptDir & "\logdog.log", $EditText)
    Exit
EndFunc ;==> _ExitLogDog
Edited by czardas
Link to comment
Share on other sites

logdog logs logdog.log logs in the last 53 hours. Try saying it quickly (including the dot).

Sample Output

Snippet Dump views = 2317
Logged on Sat 27th Aug 2011 at 00:30:59

Snippet Dump views = 2367
Logged on Sat 27th Aug 2011 at 06:46:12

Snippet Dump views = 2399
Logged on Sat 27th Aug 2011 at 10:47:34

Snippet Dump views = 2418
Logged on Sat 27th Aug 2011 at 20:19:53

Snippet Dump views = 2443
Logged on Sun 28th Aug 2011 at 10:57:17

Snippet Dump views = 2464
Logged on Mon 29th Aug 2011 at 05:35:29

More than 100 hits within 24 hours. Funny how something so simple can make you happy. :mellow:

Edited by czardas
Link to comment
Share on other sites

Well, AutoIt Snippets Database might also be a option. Not sure if its still working. But its still up. (But seems more suitable for final snippets.)

---

PS: Think sharing a snippets topic with multiple users is not such a good idea. As there is no general topic subject compared to

- Snippets + One user.

- Multiple users + Same code subject.

Edited by iEvKI3gv9Wrkd41u

"Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions."
"The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014)

"Believing what you know ain't so" ...

Knock Knock ...
 

Link to comment
Share on other sites

There are some interesting examples there, including _StringRotate - which is pretty much the same as

Funny coincidence!

Think sharing a snippets topic with multiple users is not such a good idea.

I didn't want to say don't post stuff in here, but indeed you are right about what you say. Edited by czardas
Link to comment
Share on other sites

Fuzzy Logic Date Extraction

Many people prefer to have a date written out in full, but that can mean a number of different formats. This code is intended to recognize a date in a variety of commonly used formats. The written date is converted to DD/MM/YYYY or DD/MM/YY, depending on input. While it may never be perfect, it's perhaps something that could be useful for some applications.

Requires revision

_Run()
 
Func _Run() ; Convert a date to standard digit date format
    $sDate = "Monday the 31st of October 2011"
    $ret = _ExtractDateInfo($sDate, "/")
    If @error Then
        MsgBox(0, "ERROR", "Error occured on line " & @extended)
    Else
        MsgBox(0, $sDate, "Converts to" & @CRLF & @CRLF & $ret)
    EndIf
EndFunc
 
Func _ExtractDateInfo($sDate, $sDelim)
    If (Not IsString($sDate)) Or (Not IsString($sDelim)) Then Return SetError(1, 14, "")
    While StringRegExp($sDate, "[^[:alnum:]\s]| in | the | year | of | our | lord ") ; Remove these
        $sDate = StringRegExpReplace($sDate, "[^[:alnum:]\s]| in | the | year | of | our | lord ", " ")
    WEnd
    $sDate = StringStripWS($sDate, 7)
    $sDate = _RemoveWeekDay($sDate) ; Remove the weekday (sun, mon etc...) if present
    If @error Then Return SetError(2, @extended, "")
    $sDate = _RemoveDigitSuffix($sDate) ; Remove 'st', 'nd', 'rd', 'th'
    If @error Then Return SetError(3, @extended, "")
    $sArray = StringRegExp($sDate , _ ; This regexp is for personal reference (See next comment)
    "(?i)(\d+\s)(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[[:alpha:]]*(\s\d+)", 1)
    ; A different solution is to just use StringSplit => $sArray = StringSplit($sDate, " ", 2)
    If UBound($sArray) <> 3 Then Return SetError(3, 26, "")
    $sArray[0] = _PrefixZero(StringStripWS($sArray[0], 2)) ; Day minimum digits = 2
    If @error Then Return SetError(4, @extended, "")
    $sArray[1] = _MonthToDigits($sArray[1]) ; Replace the name of the month with 2 digits
    $sArray[2] = _PrefixZero(StringStripWS($sArray[2], 1)) ; Year minimum digits = 2
    If @error Then Return SetError(5, @extended, "")
    Return $sArray[0] & $sDelim & $sArray[1] & $sDelim & $sArray[2]
EndFunc
 
Func _RemoveWeekDay($string)
    If (Not IsString($string)) Or (StringLen($string) < 3) Then Return SetError(1, 36, $string)
    $string = StringRegExpReplace($string, "(?i)(Sun|Mon|Tue|Wed|Thu|Fri|Sat)[[:alpha:]]*", "")
    Return StringStripWS($string, 1)
EndFunc
 
Func _RemoveDigitSuffix($string)
    If (Not IsString($string)) Or (StringLen($string) < 3) Then Return SetError(1, 42, $string)
    Return StringRegExpReplace($string, "(\d)(st|nd|rd|th)", "$1")
EndFunc
 
Func _MonthToDigits($string)
    If (Not IsString($string)) Or (StringLen($string) < 3) Then Return SetError(1, 47, "")
    Local $ret, $aMonth[12] = _
    ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]
    For $ret = 0 To 11
        If StringLeft($string, 3) = $aMonth[$ret] Then ExitLoop
    Next
    If $ret = 12 Then Return SetError(2, 53, "")
    $ret +=1
    Return _PrefixZero($ret)
EndFunc
 
Func _PrefixZero($sDigit, $iLen = 2)
    If Not IsInt(Number($sDigit)) Then Return SetError(1, 59, $sDigit)
    While StringLen(String($sDigit)) < $iLen
        $sDigit = "0" & $sDigit
    WEnd
    Return $sDigit
EndFunc

Here are some example date formats it will successfully convert.

mon|31|oct|2011
monday 31/october/2011
31st-oct-2011
31st october 11
mon the 31st october 2011
Monday the 31st of October in the year 2011
Monday the 31st of October in the year of our lord 2011
Monkey the 31nd of Octopus ^_^ in the year of our lord 2011 :)
Edited by czardas
Link to comment
Share on other sites

  • 4 weeks later...

Three new functions to be added to Modal.au3, which incidentally I could no longer live without. These are simple and somewhat limited numeric base conversion functions:

_DecToNumBase

_NumBaseToDec

_NumBaseToNumBase

Negative numeric input values values are supported. The following list gives the decimal equivalent max value limitations on all supported numeric bases

Binary - 32767

Ternary - 14348906

Quaternary - 1073741823

Quinary - 30517578124

Senary - 470184984575

Septenary. - 4747561509942

Octal. - 35184372088831

Nonary - 205891132094648

Decimal - 999999999999999

; #FUNCTION# ============================================================================
; Name...........: _DecToNumBase
; Description ...: Converts a decimal integer to a new numeric base
; Syntax.........: _DecToNumBase($iDecimal, $iBase)
; Parameters ....: $iDecimal - Decimal input value
;                  $iBase   - The numeric base to convert to
; Return values .: Success   - Returns the numeric base equivalent of the decimal
;                  Failure   - Sets @error to the following values:
;                  |@error = 1 Invalid base value
;                  |@error = 2 Invalid decimal value
;                  |@error = 3 Float output limitation
; Author ........: czardas, iEvKI3gv9Wrkd41u
; Comments ......; Max input of 15 digits, and numeric base limitations from number bases 2 through 10
; Related .......: _NumBaseToDec, _NumBaseToNumBase
; Example .......: Yes
; ========================================================================================
 
Func _DecToNumBase($iDecimal, $iBase)
    If IsInt($iBase) = 0 Or $iBase < 2 Or $iBase > 10 Then Return SetError(1, 0, 0) ; invalid base value
    If IsInt($iDecimal) = 0 Then Return SetError(2, 0, 0) ; invalid decimal value
    Local $iSign = 1, $iRet = 0
    If $iDecimal < 0 Then $iSign = -1
    $iDecimal *= $iSign ; force positive value
    If $iDecimal < $iBase Or $iBase = 10 Then Return $iDecimal*$iSign ; nothing to do
    If Floor(Log($iDecimal)/Log($iBase)) > 15 Then Return SetError(2, 0, 0) ; float output limitation
    __DecToNumBase($iDecimal, $iBase, $iRet)
    Return $iRet*$iSign
EndFunc ;=> _DecToNumBase
 
 
; #FUNCTION# ============================================================================
; Name...........: _NumBaseToDec
; Description ...: Converts a numeric base value to its decimal equivalent
; Syntax.........: _DecToNumBase($iDecimal, $iBase)
; Parameters ....: $iNumber - Numeric input
;                  $iBase   - The numeric base to convert from
; Return values .: Success   - Returns the decimal  equivalent of the numeric base input value
;                  Failure   - Sets @error to the following values:
;                  |@error = 1 Invalid base value
;                  |@error = 2 Invalid numeric input
;                  |@error = 3 Float input limitation
; Author ........: czardas
; Comments ......; Max input of 15 digits, and numeric base limitations from number bases 2 through 10
; Related .......: _NumBaseToDec , _NumBaseToNumBase
; Example .......: Yes
; ========================================================================================
 
Func _NumBaseToDec($iNumber, $iBase)
    If IsInt($iBase) = 0 Or $iBase < 2 Or $iBase > 10 Then Return SetError(1, 0, 0) ; invalid base value
    If IsInt($iNumber) = 0 Then Return SetError(2, 0, 0) ; invalid numeric input
    If $iBase = 10 Then Return $iNumber ; nothing to do
    _ValidateNumBase($iNumber, $iBase)
    If @error Then Return SetError(2, 0, 0) ; invalid digits
    Local $aBaseDigit, $iExponent, $iSign = 1, $iRet = 0
    If $iNumber < 0 Then $iSign = -1
    $iNumber *= $iSign ; force positive value
    $iExponent = StringLen($iNumber) -1
    If $iExponent > 14 Then Return SetError(3, 0, 0) ; float input limitation
    $aBaseDigit = StringSplit($iNumber, "", 2)
    For $i = 0 To $iExponent
        $iRet += $aBaseDigit[$i]*($iBase^($iExponent - $i))
    Next
    Return $iRet*$iSign
EndFunc ;==> _NumBaseToDec
 
 
; #FUNCTION# ============================================================================
; Name...........: _NumBaseToNumBase
; Description ...: Converts a numeric expression from one base to another
; Syntax.........: _NumBaseToNumBase($iNumber, $iBase, $iNewBase)
; Parameters ....: $iNumber - Numeric input
;                  $iBase   - The numeric base to convert from
;                  $iNewBase - The numeric base to convert to
; Return values .: Success   - Returns the new numeric base equivalent of the input value
;                  Failure   - Sets @error to the following values:
;                  |@error = 1 Invalid base value
;                  |@error = 2 Invalid numeric input
;                  |@error = 3 Float input limitation
;                  |@error = 4 Invalid new base value
; Author ........: czardas
; Comments ......; Max input of 15 digits, and numeric base limitations from number bases 2 through 10
; Related .......: _NumBaseToDec , _DecToNumBase
; Example .......: Yes
; ========================================================================================
 
Func _NumBaseToNumBase($iNumber, $iBase, $iNewBase)
    _ValidateNumBase($iNumber, $iBase)
    If @error Then Return SetError(2, 0, 0)
    $iNumber = _NumBaseToDec($iNumber, $iBase)
    If @error Then Return SetError(@error, 0, 0)
    $iNumber = _DecToNumBase($iNumber, $iNewBase)
    If @error Then Return SetError(@error +3, 0, 0)
    Return $iNumber
EndFunc ;==> _NumBaseToNumBase
 
 
; #FUNCTION# ============================================================================
; Name...........: __DecToNumBase
; Description ...: Internal function to convert from decimal to a new numeric base
; Syntax.........: __DecToNumBase($iDecimal, $iBase, ByRef $iRet)
; Parameters ....: $iDecimal - Decimal input value
;                  $iBase   - The numeric base to convert to
;                  $iRet     - Recursive return value
; Return values .: Returns the numeric base value equivalent of the decimal integer
; Author ........: czardas, iEvKI3gv9Wrkd41u
; ========================================================================================
 
Func __DecToNumBase($iDecimal, $iBase, ByRef $iRet)
    Local $iPower = Floor(Log($iDecimal) / Log($iBase)) ; excellent suggestion from iEvKI3gv9Wrkd41u
    Local $iDigit = Int($iDecimal/($iBase^$iPower))
    $iRet += $iDigit*(10^$iPower)
    $iDecimal -= $iDigit*($iBase^$iPower)
    If $iDecimal < $iBase Then
        $iRet += $iDecimal
    Else
        __DecToNumBase($iDecimal, $iBase, $iRet)
    EndIf
EndFunc ;==> __DecToNumBase
 
 
; #FUNCTION# ============================================================================
; Name...........: _ValidateNumBase
; Description ...: Internal function to check input only contains digits within the numeric mode
; Syntax.........: _ValidateNumBase($iNumber, $iBase)
; Parameters ....: $iNumber - Numeric input value
;                  $iBase   - The numeric base to check
; Return values .: Sets @error to 1 if validation fails
; Author ........: czardas
; ========================================================================================
 
Func _ValidateNumBase($iNumber, $iBase)
    If $iBase = 10 Then Return
    For $i = $iBase To 9
        If StringInStr($iNumber, $i) Then Return SetError(1)
    Next
EndFunc ; _ValidateNumBase

Examples

$ret = _DecToNumBase(7687,3)
MsgBox(0, "Ternary to Decimal", $ret &@LF & _NumBaseToDec($ret, 3))
$ret = _NumBaseToNumBase(71543, 8, 7)
MsgBox(0, "71543 Octal to Septenary", $ret)
Edited by czardas
Link to comment
Share on other sites

  • 3 weeks later...

Creating an Array from CSV

This has been done thousands of times before, but here's my take on it anyway,

CSVSplit.au3

; #FUNCTION# ============================================================================
; Name...........: _CSVSplit
; Description ...: Converts a string in CSV format to a two dimensional array (see comments)
; Syntax.........: _ArrayToCSV ( $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
    Local $iOverride = 255, $asDelim[3] ; $asDelim => replacements for comma, new line and double quote
    For $i = 0 To 2
        $asDelim[$i] = _GetSubstitute($string, $iOverride, $sDelim) ; Choose a suitable substitution character
        If @error Then Return SetError(3, 0, 0) ; String contains too much variety
    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
 
 
; #FUNCTION# ============================================================================
; Name...........: _ArrayToCSV
; Description ...: Converts a two dimensional array to CSV format
; Syntax.........: _ArrayToCSV ( $aArray [, $sDelim [, $sNewLine ]] )
; 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)
; 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
; 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 = ",", $sNewLine = @LF)
    If (Not IsArray($aArray)) Or (Ubound($aArray, 0) > 2) Then Return SetError(1, 0 ,"")
    If Not IsString($sDelim) Then Return SetError(2, 0 ,"")
    If Not IsString($sNewLine) Then Return SetError(3, 0 ,"")
 
    Local $iRows = UBound($aArray), $string = ""
    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], '["' & $sDelim & ']') Then
                    $aArray[$i][$j] = '"' & StringReplace($aArray[$i][$j], '"', '""') & '"'
                EndIf
                $string &= $aArray[$i][$j] & $sDelim
            Next
            $string = StringTrimRight($string, StringLen($sDelim)) & $sNewLine
        Next
    Else ; The delimiter is not needed
        For $i = 0 To $iRows -1
            If StringInStr($aArray[$i], '"') Then
                $aArray[$i] = '"' & StringReplace($aArray[$i], '"', '""') & '"'
            EndIf
            $string &= $aArray[$i] & $sNewLine
        Next
    EndIf
    Return StringTrimRight($string, StringLen($sNewLine)) ; Delete any newline characters added to the end of the string
EndFunc ;==> _ArrayToCSV
 
 
; #FUNCTION# ============================================================================
; Name...........: _GetSubstitute
; Description ...: Searches for an AscII char to be used for substitution, ie one not contained within the string
; Syntax.........: _GetSubstitute($string, ByRef $iCountdown)
; Parameters ....: $string   - The string of characters to avoid
;                  $iCountdown - The AscII number to begin checking => Best set to 255 on the first run
;                  $sAvoid   - Optional string of characters to avoid
; 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
; ========================================================================================
 
Func _GetSubstitute($string, ByRef $iCountdown, $sAvoid = "")
    If $iCountdown < 1 Then Return SetError(1, 0, "") ; Out of options
    Local $sTestChar
    For $i = $iCountdown To 1 Step -1
        $sTestChar = Chr($i)
        $iCountdown -= 1
        If Not StringInStr($string, $sTestChar, 2) Then ; Some characters may interfere with parsing =>
            If ($i = 34) Or ($i = 13) Or ($i = 10) Or StringInStr($sAvoid, $sTestChar) Then ContinueLoop
            Return $sTestChar
        EndIf
    Next
    Return SetError(1, 0, "") ; Out of options
EndFunc ;==> _GetSubstitute

Example

#include <CSVSplit.au3>
#include <Array.au3> ; For _ArrayDisplay
 
_Example()
 
Func _Example()
    Local $aCSV = _CSVSplit( _ ; csv example taken from en.wikipedia.org/wiki/Comma-separated_values#Example
    'Year,Make,Model,Description,Price' & @LF & _
    '1997,Ford,E350,"ac, abs, moon",3000.00' & @LF & _
    '1999,Chevy,"Venture ""Extended Edition""","",4900.00' & @LF & _
    '1999,Chevy,"Venture ""Extended Edition, Very Large""","",5000.00' & @LF & _
    '1996,Jeep,Grand Cherokee,"MUST SELL!' & @LF &  _
    'air, moon roof, loaded",4799.00')
 
    If Not @error Then
        _ArrayDisplay($aCSV)
        MsgBox(0, "Converted back to CSV", _ArrayToCSV($aCSV))
    ElseIf @error = 1 Then
        MsgBox(0, "Error Code " & @error, "1st parameter - Invalid string")
    ElseIf @error = 2 Then
        MsgBox(0, "Error Code " & @error, "2nd parameter - Delimiter not a valid string")
    ElseIf @error = 3 Then
        MsgBox(0, "Error Code " & @error, "Failed to find suitable delimiter replacements")
    EndIf
EndFunc

You have the option to set the delimiter, so you can convert from CSV to TSV etc... The function should be able to handle all csv formats. Make sure your CSV, (or TSV) is correctly formatted.

NOTE

When converting from array to CSV, double quotes will not be added to any fields unless absolutely necessary. This means that double quotes enclosing an empty field in an original CSV will dissapear after conversion. I didn't see it as being necessary to enclose all fields, but it's easy enough to make such changes when required.

Edited by czardas
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

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