Jump to content

How to get StringSplit to output columns instead of rows?


kor
 Share

Recommended Posts

Eek, to use up to 64D you just need up to 64 neurons. I mean you don't need to master superstring theory to reach high dimensions.

Almost everyone uses objects having _much_ more than 3 or 4 dimensions:

country

region

zip code

city

street

street number

building

entrance

floor

appartment number

owner name

owner first name

destinee name

destinee first name

Of course all these 14 dimensions are not always needed for precise location of every destinee, but many of them are necessary for common shipments and all of them are eventually used.

Such a (theorical) array is extremely sparse due to lack of need for some components in most addresses, but that causes no problem for most people to understand the idea that all these dimensions are actually formally independant.

Nobody will object that for precise location of a part of an object placed in a given room of an address, one will clearly need more dimensions again. Like the ENTER key of the keyboard on the left bench in the second room at the first floor of my house...

But surely this is done in a 2D array where the first dimension is customer name, and the elements you quote are held in a series of data items in the second dimension:

$arrray[1][1] is customer 1, country

$arrray[1][2] is customer 1, region

$arrray[1][3] is customer 1, zip code

up to

$arrray[1][14] is customer 1, first name

then

$arrray[2][1] is customer 2, country

$arrray[2][2] is customer 2, region

$arrray[2][3] is customer 2, zip code

up to

$arrray[2][14] is customer 2, first name

and so on.

William

Link to comment
Share on other sites

Hi saywell,

No you don't have the right definition of dimension here.

One dimension is one degree of freedom independant of the other dimensions.

That you (and me) may find it practical to map 14-component adresses into a two-dimensionnal table is a completely distinct unicorn. You can as well store addresses in a 1D list (less efficient but still possible).

You're confusing the structure of some object with one representation of that object in storage.

You can as well say that a film image track is a 2D thing just because you can represent with a 2D array:

$film[0][0] = frame #

$film[0][1] = pixel Y

$film[0][2] = pixel X

$film[0][3] = pixel R

$film[0][4] = pixel G

$film[0][5] = pixel B

Here a given row is this array fully describes a precise pixel at a precise point in time. Just like the address example, every column in this fictionnal array is free (independant of the other in the same row).

You may feel it's different than in the customer address example, but it isn't the case. We don't have specific relationships with individual pixels in frames of a film, similar to personal/business relationships to a 14-component friend or customer address. Nonetheless that doesn't mean their own structure is the same as the structure you use to represent such objects in a computer.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

  • Moderators

Might start another thread guys, seems you're off on something a bit more complex than what the original poster is after.

----

I did a little playing with extracting separated value strings and regular expressions.

Below seems to work to extract even quoted data ( see notes after code for the bad news ):

#include <Array.au3>

Global $gs_dummydata = 'john,smith,12345,"happy",manager,,"abra,ca,da,br,a"'

Global $ga_test = _GetSeparatedValueArray($gs_dummydata, ",")
_ArrayDisplay($ga_test)

Func _GetSeparatedValueArray($s_data, $s_delim)

    Local $a_ret[1]
    If Not $s_data Then Return $a_ret
    Local $s_pattern = "(?:(?:^""|\Q" & $s_delim & "\E"")(?:.*?(?:"""".*?"""")*)*"
    $s_pattern &= "(?:\z|""\z|""(?=\Q" & $s_delim & "\E))|(?:^|\Q"
    $s_pattern &= $s_delim & "\E)(?:.*?)(?:/z|(?=\Q" & $s_delim & "\E)))"
    Local $a_sre = StringRegExp($s_data, $s_pattern, 3)
    If @error Then
        $a_ret[0] = $s_data
        Return $a_ret
    EndIf

    ; Need to work on pattern more, but for now; just strip bad data
    ; Clean up comma's and quotes
    For $i = 0 To UBound($a_sre) - 1
        If StringLeft($a_sre[$i], 2) = ',"' And _
            StringRight($a_sre[$i], 1) = '"' Then
            $a_sre[$i] = StringTrimLeft(StringTrimRight($a_sre[$i], 1), 2)
        ElseIf StringLeft($a_sre[$i], 1) = "," Then
            $a_sre[$i] = StringTrimLeft($a_sre[$i], 1)
        EndIf
    Next

    Return $a_sre
EndFunc

Note:

My regular expression isn't perfect ( yes, even I get frustrated with them, bounded them, freed them, forward/back referenced them, and my condition (?(condition)true_pattern|false_pattern) kept failing, so I'm leaving the non-bound/non-capturing style up with a quick fix remedy until I can ( or someone else ) see what the issue is.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

@smoke, I'm not sure what your code is doing. If you look at my example

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#Include <GuiRichEdit.au3>
#include <Array.au3>

Example1()

Func Example1()
    Local $msg

    Global $maingui = GUICreate("My GUI", 200, 200) ; will create a dialog box that when displayed is centered
    
    $button = GUICtrlCreateButton("Bulk", 50, 50, 80, 30)
    GuiCtrlSetState($button, $GUI_FOCUS)

    GUISetState(@SW_SHOW) ; will display an empty dialog box

    ; Run the GUI until the dialog is closed
    While 1
        $msg = GUIGetMsg()
        Switch $msg
            Case $button
                _Create()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        EndSwitch
    WEnd
    GUIDelete()
EndFunc   ;==>Example1

Func _Create()
    Global $header = "FirstName,LastName,StaffID,Location"
    Local $msg
    $creategui = GUICreate("bulk create", 250, 290)
    Global $edit = _GUICtrlRichEdit_Create($creategui, $header & @CR, 10, 10, 230, 230, BitOr($ES_MULTILINE, $WS_VSCROLL, $ES_AUTOVSCROLL))
    $button1 = GUICtrlCreateButton("Ready", 70, 250, 80, 30)
    GUISetState()
    
        While 1
        $msg = GUIGetMsg()
        Switch $msg
            Case $button1
                _stuff()
            Case $GUI_EVENT_CLOSE
                GUIDelete()
                Exit
        EndSwitch
    WEnd
EndFunc

Func _stuff()
    Local $sTmp = ''
    $result = _GuiCtrlRichEdit_GetText($edit)
    $result = StringRegExpReplace($result, @CR, "|")


$rows = StringSplit($result, "|")
$cols = StringSplit($rows[1], ",")

Dim $table[$rows[0]][$cols[0]]

For $i = 1 To $rows[0]
    $cols = StringSplit($rows[$i], ",")
    For $j = 1 To $cols[0]
        $table[$i - 1][$j - 1] = $cols[$j]
    Next
Next

_ArrayDisplay($table)

For $x = 1 To UBound($rows) - 1
    If $rows[$x] == "" Then
        _ArrayDelete($table, $table[$x][0])
    EndIf
Next

_ArrayDisplay($table)

    Exit
EndFunc

You will see that the code works for splitting comma deliminated strings into the array columns like I need. The only problem I'm having is if you have blank rows when you input the data, the array crashes and burns in the second loop trying to delete the blank rows.

Link to comment
Share on other sites

  • Moderators

@smoke, I'm not sure what your code is doing. If you look at my example

Hmm, I commented the code, and made the variables pretty understandable, not sure if you ran my code where you're confused.

Anyway, I changed one of the functions just a bit, and put it in your example so maybe the light bulb will go off.

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#Include <GuiRichEdit.au3>
#include <Array.au3>

Example1()

Func Example1()
    Local $msg

    Global $maingui = GUICreate("My GUI", 200, 200) ; will create a dialog box that when displayed is centered

    $button = GUICtrlCreateButton("Bulk", 50, 50, 80, 30)
    GuiCtrlSetState($button, $GUI_FOCUS)

    GUISetState(@SW_SHOW) ; will display an empty dialog box

    ; Run the GUI until the dialog is closed
    While 1
        $msg = GUIGetMsg()
        Switch $msg
            Case $button
                _Create()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        EndSwitch
    WEnd
    GUIDelete()
EndFunc   ;==>Example1

Func _Create()
    Global $header = "FirstName,LastName,StaffID,Location"
    Local $msg
    $creategui = GUICreate("bulk create", 250, 290)
    Global $edit = _GUICtrlRichEdit_Create($creategui, $header & @CR, 10, 10, 230, 230, BitOr($ES_MULTILINE, $WS_VSCROLL, $ES_AUTOVSCROLL))
    $button1 = GUICtrlCreateButton("Ready", 70, 250, 80, 30)
    GUISetState()

        While 1
        $msg = GUIGetMsg()
        Switch $msg
            Case $button1
                _stuff()
            Case $GUI_EVENT_CLOSE
                GUIDelete()
                Exit
        EndSwitch
    WEnd
EndFunc

Func _stuff()
    Local $sTmp = ''
    Local $result = _GuiCtrlRichEdit_GetText($edit)
    Local $a_Array = __myGetRows($result, 1)
    Local $a_NoEmptyLines = __ArrayExclude1D($a_Array, "", 1, True)
    Local $a_RowsCols2D = __myGetRowsCols($a_NoEmptyLines, 1, ",")

    _ArrayDisplay($a_RowsCols2D)

    Exit
EndFunc

Func __myGetRowsCols($a_rows, $i_base = 0, $s_col_delim = ",", $i_retbase = 0)

    If Not IsArray($a_rows) Then Return SetError(1, 0, 0)

    If Int($i_base) < 1 Then $i_base = 0
    If Int($i_retbase) < 1 Then $i_retbase = 0

    Local $i_row_max = UBound($a_rows) - 1
    Local $a_cols = StringSplit($a_rows[$i_row_max], $s_col_delim, 1)
    Local $i_col_max = $a_cols[0], $i_rownext = $i_retbase

    Local $a_rowcol[$i_row_max + 1][$i_col_max]

    For $irow = $i_base To $i_row_max
        $a_cols = StringSplit($a_rows[$irow], $s_col_delim, 1)

        ; protection in case one of the rows has more cols than the default
        If $a_cols[0] > $i_col_max Then
            $i_col_max = $a_cols[0]
            ReDim $a_rowcol[$i_row_max + 1][$i_col_max]
        EndIf

        For $icol = 1 To $a_cols[0]
            $a_rowcol[$i_rownext][$icol - 1] = $a_cols[$icol]
        Next

        $i_rownext += 1
    Next

    ReDim $a_rowcol[$i_rownext][$i_col_max]
    If $i_retbase <> 0 Then $a_rowcol[0][0] = $i_rownext - 1

    Return $a_rowcol
EndFunc

Func __myGetRows($s_data, $i_base = 1); $i_base if 1 then [0] holds row count

    If StringLen($s_data) = 0 Then Return SetError(1, 0, 0)

    If Int($i_base) <> 1 Then $i_base = 2

    ; Find row delimiter; assuming it's based on separate lines
    If StringInStr($s_data, @CRLF, 1) Then
        Return StringSplit(StringStripCR($s_data), @LF, $i_base)
    ElseIf StringInStr($s_data, @CR, 1) Then
        Return StringSplit($s_data, @CR, $i_base)
    ElseIf StringInStr($s_data, @LF, 1) Then
        Return StringSplit($s_data, @LF, $i_base)
    EndIf

    ; There are no line separators
    ;  Whole string is in array as a row
    Local $i_ub = 1
    If $i_base = 1 Then $i_ub = 2
    Local $a_lines[$i_ub]
    If $i_ub = 2 Then
        $a_lines[0] = 1
        $a_lines[1] = $s_data
    Else
        $a_lines[0] = $s_data
    EndIf

    Return $a_lines
EndFunc

; array to search ( mandatory param; must be an array )
; exclude value ( mandatory param )
; base to start ( if you use normal stringsplit to create the array, it will be 1 ) ( default is zero )
; if you want [0] index zero to contain the total indexes available ( default is no )
; the max bounds you want to search the array ( default is all of the indexes )
; case sensitive ( default is no )
Func __ArrayExclude1D(ByRef $a_arr, $s_excludeval, $i_base = 0, $f_zeroindextotal = False, $i_max = -1, $f_case = False)

    If Not IsArray($a_arr) Then Return SetError(1, 0, 0)

    If Int($i_max) < 1 Then $i_max = UBound($a_arr) - 1
    Local $a_ret[$i_max + 1], $i_add = 0
    If $f_zeroindextotal Then $i_add += 1

    If $f_case Then
        For $i = $i_base To $i_max
            If Not ($a_arr[$i] == $s_excludeval) Then
                $a_ret[$i_add] = $a_arr[$i]
                $i_add += 1
            EndIf
        Next
    Else
        For $i = $i_base To $i_max
            If $a_arr[$i] <> $s_excludeval Then
                $a_ret[$i_add] = $a_arr[$i]
                $i_add += 1
            EndIf
        Next
    EndIf

    If $i_add = 0 Or ($i_add = 1 And $f_zeroindextotal) Then
        Return SetError(2, 0, 0)
    EndIf

    ReDim $a_ret[$i_add]
    If $f_zeroindextotal Then $a_ret[0] = $i_add - 1

    Return $a_ret
EndFunc

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

@smoke, the reason I'm not understanding is because what is taking you over 100 lines of code I'm doing with 2 simple loops.

$rows = StringSplit($result, "|")
$cols = StringSplit($rows[1], ",")

Dim $table[$rows[0]][$cols[0]]

For $i = 1 To $rows[0]
    $cols = StringSplit($rows[$i], ",")
    For $j = 1 To $cols[0]
        $table[$i - 1][$j - 1] = $cols[$j]
    Next
Next

_ArrayDisplay($table)

For $x = 1 To UBound($rows) - 1
    If $rows[$x] == "" Then
        _ArrayDelete($table, $table[$x][0])
    EndIf
Next

_ArrayDisplay($table)

That code *almost* works. It will format how I need, the only part is getting the second loop to delete empty rows. Right now it deletes empty rows only if there is exactly 1 empty row. If there are more than 1 empty row, or row N is empty it fails with subscript errors. Can you look at my final loop and point out where I might be going wrong?

Link to comment
Share on other sites

When you use arraydelete in a loop, you have to go through the array backwards or else it will never delete anything correctly, except for the first delete.

;   This
For $x = 1 To UBound($rows) - 1

;   Should be written this way

For $x = UBound($rows) - 1 to 1 Step -1

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

When you use arraydelete in a loop, you have to go through the array backwards or else it will never delete anything correctly, except for the first delete.

;   This
For $x = 1 To UBound($rows) - 1

;   Should be written this way

For $x = UBound($rows) - 1 to 1 Step -1

I've tried that exact code too, with the same result. If row N is blank the script fails with array subscript errors.
Link to comment
Share on other sites

  • Moderators

@smoke, the reason I'm not understanding is because what is taking you over 100 lines of code I'm doing with 2 simple loops.

Bottom line, my method is efficient.

If you want think about "2 simple loops" + "lines of code" then you must never look at the #includes functions. You know that there are actual lines of code for functions like _ArrayDelete()? And in a loop, you ReDim your method every single loop.

You want to see it in only 3 - 4 lines of code?

Then put my functions in their own #include file, and just remove them from the main script, and add the #include.

Mine have safe guards to protect your code from blowing up ( for the most part ), they show you how to structure adding and removing data ( increasing array size and decreasing it ).

Your "few loops" are flawed as well as the approach, that's what I haven't bothered to show you how to fix it so it works. "Gift horse" + "mouth" comes to mind at the moment.

Edit:

BTW:

StringRegExpReplace($result, @CR, "|")
What exactly is this supposed to do?

Maybe you meant:

StringRegExpReplace($result, "\v+", "|")
? Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Try this if you're going to insist on using your code.

_ArrayDelete($table, $x)

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

May I ask you whether my version works also for you?

If not, what is not working? It's for improvements. :)

Br,

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Your Version works very well. My only comment would be not to declare variables in the For Loop as this slows it down :) I updated it a little and now it doesn't fail under Au3Check.

Function by UEZ:

#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
Func StringSplitW($sString, $iDelimiter)
    Local $aStringSplit = StringSplit($sString, @LF), $aArray[$aStringSplit[0]][0xFFFF]
    Local $C = 1, $iLength, $iMaximum, $iWidth
    If $sString = "" Or $iDelimiter = "" Then
        Return SetError(1, 0, 0)
    EndIf

    Local $iCount = 0
    For $A = 1 To $aStringSplit[0]
        $iLength = StringLen($aStringSplit[$A])
        If $iLength > 1 Then
            StringReplace($aStringSplit[$A], $iDelimiter, $iDelimiter)
            $iWidth = @extended
            If $iWidth > $iMaximum Then
            $iMaximum = $iWidth + 1
            Endif
            Switch $iWidth
                Case 0
                    $aArray[$iCount][0] = $aStringSplit[$A]
                Case Else
                    Local $aPosition[$iWidth * 2 + 2]
                    $aPosition[0] = 1
                    For $B = 0 To $iWidth - 1
                        $aPosition[$C] = StringInStr($aStringSplit[$A], $iDelimiter, 0, $B + 1) - 1
                        $aPosition[$C + 1] = $aPosition[$C] + 2
                        $C += 2
                    Next
                    $aPosition[UBound($aPosition) - 1] = StringLen($aStringSplit[$A])
                    $C = 0
                    For $B = 0 To UBound($aPosition) - 1 Step 2
                        $aArray[$iCount][$C] = StringMid($aStringSplit[$A], $aPosition[$B], $aPosition[$B + 1] - $aPosition[$B] + 1)
                        $C += 1
                    Next
            EndSwitch
            $iCount += 1
        EndIf
    Next
    ReDim $aArray[$iCount][$iMaximum]
    Return $aArray
EndFunc   ;==>StringSplitW
Edited by guinness

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Link to comment
Share on other sites

Thank you guinness for your tests!

Last step is optimizing the code when there are no bugs left! :)

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

I know that you know that :) But for anyone else who is learning it might come as a surprise!!!

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Link to comment
Share on other sites

  • 6 years later...
On 2011-03-31 at 8:41 PM, UEZ said:

Here my version:

 

 

#include <Array.au3>

$gs_dummydata = ""
$gs_dummydata &= "john,smith,12345" & @CRLF
$gs_dummydata &= "josh,jones,34556,supervisor" & @CRLF
$gs_dummydata &= "" & @CRLF ; empty line
$gs_dummydata &= "zach,marks,98222,worker,extra column not expected" & @CRLF
$gs_dummydata &= "jake,warren,10984,worker" & @CRLF ; (last line will actually be empty because of CRLF)

$aS = StringSplitW($gs_dummydata, ",")
_ArrayDisplay($aS)

; #FUNCTION# ======================================================================================
; Name ................:     StringSplitW()
; Version .............:    v0.80 build 2011-05-05 beta
; Description .......:    Splits  a string into columns instead of rows as it is done by SplitString(), like a csv file to a 2d array ;-)
; Syntax ..............:    StringSplitW($string, $delimiter, $max_width)
; Parameters ........:    $string - string to split
;                                  $delimiter - the delimter how to split the string
; Return values ....:     Success - 2d array
;                                  Failure 1 - either $string or $delimter is not set
;                                  Failure 2 - array width exceeded
;                                  Failure 3 - 2D array memory exceeded -> width + height > 0x5EFA
; Author ..............:    UEZ
; Modified ............:
; Remarks ............:
; Related ..............:    StringSplit()
; =================================================================================================
Func StringSplitW($string, $delimiter)
    If $string = "" Or $delimiter = "" Then Return SetError(1, 0, 0)
    Local $chk, $width, $i, $j, $k, $len, $max = 1, $max_width
    Local $aPos[1], $l = 0
    Local $aSplit =  StringSplit($string, @LF)
    $max_width = 0x5EFA - $aSplit[0]
    If $max_width < 1 Then Return SetError(3, 0, 0)
    Local $aVertical[$aSplit[0]][$max_width]
    For $k = 1 To $aSplit[0]
        $len = StringLen($aSplit[$k])
        If $len > 1 Then
            $chk = StringReplace($aSplit[$k], $delimiter, $delimiter)
            $width = @extended
            If $width > $max_width Then Return SetError(2, 0, 0)
            If $width > $max Then $max = $width + 1
            Switch $width
                Case 0
                    $aVertical[$l][0] = $aSplit[$k]
                Case Else
                    Dim $aPos[$width * 2 + 2]
                    $j = 1
                    $aPos[0] = 1
                    For $i = 0 To $width - 1
                        $aPos[$j] = StringInStr($aSplit[$k], $delimiter, 0, $i + 1) - 1
                        $aPos[$j + 1] = $aPos[$j] + 2
                        $j += 2
                    Next
                    $aPos[UBound($aPos) - 1] = StringLen($aSplit[$k])
                    $j = 0
                    For $i = 0 To UBound($aPos) - 1 Step 2
                        $aVertical[$l][$j] = StringMid($aSplit[$k], $aPos[$i], $aPos[$i + 1] - $aPos[$i] + 1)
                        $j += 1
                    Next
                EndSwitch
                $l += 1
        EndIf
    Next
    ReDim $aVertical[$l][$max]
    Return $aVertical
EndFunc

 

Br,

UEZ

Hey!
It seems that it crashes when over 1000 rows? No errors. Got around 1400 rows that I need to split, got any suggestions? 

Thanks! 

Link to comment
Share on other sites

@Fredricz

Try this version

; #FUNCTION# ========================================================================================================================================
; Name .................:   StringSplit2D()
; Description ..........:   Splits  a string into columns instead of rows as it is done by SplitString(), like a csv file to a 2d array ;-)
; Syntax ...............:   StringSplit2D($sString[, $sDelimiter = ";"[, $bStripWS = True[, $sQuotationMark = '"'[, $sDummy = "¦"[, $iWidthLen = 256]]]]])
; Parameters ...........:   $sString             - A string value.
;                           $sDelimiter          - [optional] A string value. Default is ";".
;                           $bStripWS            - [optional] A binary value. Default is True.
;                           $sQuotationMark      - [optional] A string value. Default is '"'.
;                           $sDummy              - [optional] A string value. Default is "¦".
;                           $iWidthLen           - [optional] An integer value. Default is 256.
; Return values .......:    Success - 2d array
;                           Error 1 - $sStringis not set
;                           Error 2 - $delimter is not set
;                           Error 3 - error splitting string
;                           Error 4 - array width exceeded
;
; Version .............:    v0.97 build 2015-03-03 beta
; Author ..............:    UEZ
; Modified ............:
; Comment .............:    former StringSplitW
; Remarks .............:    RegEx taken from http://stackoverflow.com/questions/4476812/regular-expressions-how-to-replace-a-character-within-quotes
; Related .............:    StringSplit, StringReplace, StringRegExpReplace, StringLen, StringStripCR
; ===================================================================================================================================================
Func StringSplit2D($sString, $sDelimiter = ";", $bStripWS = False, $sQuotationMark = '"', $sDummy = "¦", $iWidthLen = 256)
    If $sString = "" Then Return SetError(1, 0, 0)
    If $sDelimiter = "" Then Return SetError(2, 0, 0)
    Local $aSplit =  StringSplit(StringStripCR($sString), @LF)
    If @error Then Return SetError(3, 0, 0)
    Local $chk, $iWidth, $i, $j, $k, $iLen, $iMax = 1, $iSum = 0
    Local $aPos[1], $l = 0
    Local $aVertical[$aSplit[0]][$iWidthLen], $iDelimiterLen = StringLen($sDelimiter) - 1, $sLine
    For $k = 1 To $aSplit[0]
        $iLen = StringLen($aSplit[$k])
        If $iLen > 1 Then
            Switch $bStripWS
                Case True
                    $sLine = StringRegExpReplace($aSplit[$k], '(?m)\' & $sDelimiter & '(?=[^' & $sQuotationMark & ']*' & $sQuotationMark & '(?:[^' & $sQuotationMark & '\r\n]*' & $sQuotationMark & '[^' & $sQuotationMark & ']*' & $sQuotationMark & ')*[^' & $sQuotationMark & '\r\n]*$)', $sDummy)
                Case Else ;      ,(?=[^"]*"(?:[^"\r\n]*"[^"]*")*[^"\r\n]*$)
                    $sLine = StringRegExpReplace(StringStripWS($aSplit[$k], 4), '(?m)\' & $sDelimiter & '(?=[^' & $sQuotationMark & ']*' & $sQuotationMark & '(?:[^' & $sQuotationMark & '\r\n]*' & $sQuotationMark & '[^' & $sQuotationMark & ']*' & $sQuotationMark & ')*[^' & $sQuotationMark & '\r\n]*$)', $sDummy)
            EndSwitch
            $chk = StringReplace($sLine, $sDelimiter, $sDelimiter)
            $iWidth = @extended
            $iSum += $iWidth
            If $iWidth > $iWidthLen Then Return SetError(4, 0, 0)
            If $iWidth >= $iMax Then $iMax = $iWidth + 1
            Switch $iWidth
                Case 0
                    $aVertical[$l][0] = $sLine
                Case Else
                    Dim $aPos[$iWidth * 2 + 2]
                    $j = 1
                    $aPos[0] = 1
                    For $i = 0 To $iWidth - 1
                        $aPos[$j] = StringInStr($sLine, $sDelimiter, 0, $i + 1) - 1
                        $aPos[$j + 1] = $aPos[$j] + 2 + $iDelimiterLen
                        $j += 2
                    Next
                    $aPos[UBound($aPos) - 1] = StringLen($sLine)
                    $j = 0
                    For $i = 0 To UBound($aPos) - 1 Step 2
                        $aVertical[$l][$j] = StringReplace(StringMid(StringReplace($sLine, $sDummy, $sDelimiter), $aPos[$i], $aPos[$i + 1] - $aPos[$i] + 1), '""', "")
;~                      ConsoleWrite($aVertical[$l][$j] & @CRLF)
                        $j += 1
                    Next
                EndSwitch
                $l += 1
        EndIf
    Next
    ReDim $aVertical[$l][$iMax]
    Return $aVertical
EndFunc

 

or try czardas' _CSVSplit

 

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

22 minutes ago, UEZ said:

@Fredricz

Try this version

; #FUNCTION# ========================================================================================================================================
; Name .................:   StringSplit2D()
; Description ..........:   Splits  a string into columns instead of rows as it is done by SplitString(), like a csv file to a 2d array ;-)
; Syntax ...............:   StringSplit2D($sString[, $sDelimiter = ";"[, $bStripWS = True[, $sQuotationMark = '"'[, $sDummy = "¦"[, $iWidthLen = 256]]]]])
; Parameters ...........:   $sString             - A string value.
;                           $sDelimiter          - [optional] A string value. Default is ";".
;                           $bStripWS            - [optional] A binary value. Default is True.
;                           $sQuotationMark      - [optional] A string value. Default is '"'.
;                           $sDummy              - [optional] A string value. Default is "¦".
;                           $iWidthLen           - [optional] An integer value. Default is 256.
; Return values .......:    Success - 2d array
;                           Error 1 - $sStringis not set
;                           Error 2 - $delimter is not set
;                           Error 3 - error splitting string
;                           Error 4 - array width exceeded
;
; Version .............:    v0.97 build 2015-03-03 beta
; Author ..............:    UEZ
; Modified ............:
; Comment .............:    former StringSplitW
; Remarks .............:    RegEx take from http://stackoverflow.com/questions/4476812/regular-expressions-how-to-replace-a-character-within-quotes
; Related .............:    StringSplit, StringReplace, StringRegExpReplace, StringLen, StringStripCR
; ===================================================================================================================================================
Func StringSplit2D($sString, $sDelimiter = ";", $bStripWS = False, $sQuotationMark = '"', $sDummy = "¦", $iWidthLen = 256)
    If $sString = "" Then Return SetError(1, 0, 0)
    If $sDelimiter = "" Then Return SetError(2, 0, 0)
    Local $aSplit =  StringSplit(StringStripCR($sString), @LF)
    If @error Then Return SetError(3, 0, 0)
    Local $chk, $iWidth, $i, $j, $k, $iLen, $iMax = 1, $iSum = 0
    Local $aPos[1], $l = 0
    Local $aVertical[$aSplit[0]][$iWidthLen], $iDelimiterLen = StringLen($sDelimiter) - 1, $sLine
    For $k = 1 To $aSplit[0]
        $iLen = StringLen($aSplit[$k])
        If $iLen > 1 Then
            Switch $bStripWS
                Case True
                    $sLine = StringRegExpReplace($aSplit[$k], '(?m)\' & $sDelimiter & '(?=[^' & $sQuotationMark & ']*' & $sQuotationMark & '(?:[^' & $sQuotationMark & '\r\n]*' & $sQuotationMark & '[^' & $sQuotationMark & ']*' & $sQuotationMark & ')*[^' & $sQuotationMark & '\r\n]*$)', $sDummy)
                Case Else ;      ,(?=[^"]*"(?:[^"\r\n]*"[^"]*")*[^"\r\n]*$)
                    $sLine = StringRegExpReplace(StringStripWS($aSplit[$k], 4), '(?m)\' & $sDelimiter & '(?=[^' & $sQuotationMark & ']*' & $sQuotationMark & '(?:[^' & $sQuotationMark & '\r\n]*' & $sQuotationMark & '[^' & $sQuotationMark & ']*' & $sQuotationMark & ')*[^' & $sQuotationMark & '\r\n]*$)', $sDummy)
            EndSwitch
            $chk = StringReplace($sLine, $sDelimiter, $sDelimiter)
            $iWidth = @extended
            $iSum += $iWidth
            If $iWidth > $iWidthLen Then Return SetError(4, 0, 0)
            If $iWidth >= $iMax Then $iMax = $iWidth + 1
            Switch $iWidth
                Case 0
                    $aVertical[$l][0] = $sLine
                Case Else
                    Dim $aPos[$iWidth * 2 + 2]
                    $j = 1
                    $aPos[0] = 1
                    For $i = 0 To $iWidth - 1
                        $aPos[$j] = StringInStr($sLine, $sDelimiter, 0, $i + 1) - 1
                        $aPos[$j + 1] = $aPos[$j] + 2 + $iDelimiterLen
                        $j += 2
                    Next
                    $aPos[UBound($aPos) - 1] = StringLen($sLine)
                    $j = 0
                    For $i = 0 To UBound($aPos) - 1 Step 2
                        $aVertical[$l][$j] = StringReplace(StringMid(StringReplace($sLine, $sDummy, $sDelimiter), $aPos[$i], $aPos[$i + 1] - $aPos[$i] + 1), '""', "")
;~                      ConsoleWrite($aVertical[$l][$j] & @CRLF)
                        $j += 1
                    Next
                EndSwitch
                $l += 1
        EndIf
    Next
    ReDim $aVertical[$l][$iMax]
    Return $aVertical
EndFunc

 

or try czardas' _CSVSplit

 

Awesome! Worked perfect (your solution)! Thanks

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