Jump to content
Sign in to follow this  
Chimaera

Making Code into a Func()

Recommended Posts

Chimaera

Im having an issue making a piece of code into a func (many thanks to czardas for the original code)

guinness started me down the path of creating functions where i can but this one is doing my swede in...

#include <Array.au3>
#include <CSVSplit.au3>

Local $sFilePath = @ScriptDir & "\LineItem813.csv" ; Change this to your own csv file (in the same directory as the script)
Local $iColumn = 2 ; Columns are zero based
Local $sDelimiter = ","
Local $bColHeader = True
Local $iSortColumn = 4

Local $hFile = FileOpen($sFilePath)
If $hFile = -1 Then
    MsgBox(0, "", "Unable to open file")
    Exit
EndIf

Local $sCSV = FileRead($hFile)
If @error Then
    MsgBox(0, "", "Unable to read file")
    FileClose($hFile)
    Exit
EndIf
FileClose($hFile)

Local $aCSV = _CSVSplit($sCSV) ; Create the main array
;~ _ArrayDisplay($aCSV)
If @error Then
    ConsoleWrite("Main Array Creation Error = " & @error & @LF)
    Exit
EndIf
For $i = 1 To UBound($aCSV) -1 ; Or $i = 0 To UBound($aArray) -1
    $aCSV[$i][$iSortColumn] = Number($aCSV[$i][$iSortColumn])
Next
; Create an array of csv strings
Local $aSubItemCSV = _ArrayToSubItemCSV($aCSV, $iColumn, $sDelimiter, $bColHeader, $iSortColumn)
If @error Then
    ConsoleWrite("Sub Item Array Creation Error = " & @error & @LF)
    Exit
EndIf
; Now let's write each csv to file
Local $sFolderName = StringTrimRight(StringReplace($sFilePath, @ScriptDir & "\", ""), 4)
Local $sNewPath, $iSuccess

For $i = 0 To UBound($aSubItemCSV) -1
    If StringRegExp($aSubItemCSV[$i][0], '[\/\?<>\\\:\|"]') Then
        MsgBox(0, "Invalid file name", "You can not use the following characters in a file name" & @CRLF & '/ ? < > \ : | "')
        Exit
    EndIf
    $sNewPath = @ScriptDir & "\" & $sFolderName & "\" & $aSubItemCSV[$i][0] & ".csv"
    $hFile = FileOpen($sNewPath, BitOr(8,1))
    If $hFile = -1 Then
        MsgBox(0, "", "Unable to open file")
        Exit
    EndIf
    $iSuccess = FileWrite($hFile, $aSubItemCSV[$i][1])
    FileClose($hFile)
    If $iSuccess = 0 Then
        MsgBox(0, "", "Unable to write to file")
        Exit
    EndIf
Next

CSVSplit.au3

Ref: 

Thats the 2 bits im working with, if i run it as is like that it works, as soon as i mess it about it errors usual with the _ArrayToSubItemCSV part

what im trying to achieve is a gui start like this

#include <Array.au3>
#include <CSVSplit.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
; ------------------------------------------------------------------------------
Global $SplitButton, $OpenButton, $OpenLabel, $ColumnLabel, $iColumn, $gColumn, $FilterRead, $label2, $gSortColumn, $sProgress, $gDelimiter, $gColHeader,$sFilePath
; ------------------------------------------------------------------------------
Local $GUI_Start = GUICreate(" Simple CSV Split", 500, 400, -1, -1, BitXOR($GUI_SS_DEFAULT_GUI, $WS_MINIMIZEBOX))

$OpenButton = GUICtrlCreateButton(" Open CSV ", 20, 20, 130, 35)
GUICtrlSetFont(-1, 11, 550, -1, "Tahoma")
$OpenLabel = GUICtrlCreateLabel("No File Selected", 160, 30, 350, 60, $SS_LEFT)
GUICtrlSetFont(-1, 11, 550, -1, "Tahoma")
$ArrayViewButton = GUICtrlCreateButton(" View CSV ", 380, 70, 90, 35)
GUICtrlSetFont(-1, 11, 550, -1, "Tahoma")
$ColumnLabel = GUICtrlCreateLabel("Choose Column For Split", 20, 80, 240)
GUICtrlSetFont(-1, 11, 550, -1, "Tahoma")
$gColumn = GUICtrlCreateInput("", 240, 77, 60, 25)
GUICtrlSetFont(-1, 11, 550, -1, "Tahoma")
$DelimLabel = GUICtrlCreateLabel("Delimiter", 20, 120, 240)
GUICtrlSetFont(-1, 11, 550, -1, "Tahoma")
$gDelimiter = GUICtrlCreateInput(",", 240, 117, 60, 25)
GUICtrlSetFont(-1, 11, 550, -1, "Tahoma")
$HeaderLabel = GUICtrlCreateLabel("Column Header", 20, 160, 240)
GUICtrlSetFont(-1, 11, 550, -1, "Tahoma")
$gColHeader = GUICtrlCreateInput("True", 240, 157, 60, 25)
GUICtrlSetFont(-1, 11, 550, -1, "Tahoma")
$SortLabel = GUICtrlCreateLabel("Choose Column For Sort", 20, 220, 240)
GUICtrlSetFont(-1, 11, 550, -1, "Tahoma")
$gSortColumn = GUICtrlCreateInput("", 240, 227, 60, 25)
GUICtrlSetFont(-1, 11, 550, -1, "Tahoma")
$sProgress = GUICtrlCreateProgress(20, 260, 460)
$SplitButton = GUICtrlCreateButton(" Split CSV ", 20, 320, 130, 35)
GUICtrlSetFont(-1, 11, 550, -1, "Tahoma")
GUISetState()

Local $nMsg = 0
While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $OpenButton
;~          Local $sFilePath = @ScriptDir & "\LineItem813.csv" ; Change this to your own csv file (in the same directory as the script)
            Global $sChoosePath = FileOpenDialog("Choose A File To Split.", @ScriptDir & "\", "Csv (*.csv)")
;~      Case $ArrayViewButton
;~          $ViewCSV = _ParseCSV( $sFilePath, GUICtrlRead($gDelimiter))
;~          _ArrayDisplay($ViewCSV)
        Case $SplitButton
            Global $iColumn = GUICtrlRead($gColumn) ;<<<<<<<<<<<<<<<<<<<< This doesnt and causes error even though they are read correctly
            Global $sDelimiter = GUICtrlRead($gDelimiter)
            Global $bColHeader = GUICtrlRead($gColHeader)
            Global $iSortColumn = GUICtrlRead($gSortColumn)

;~          Local $iColumn = 2 ; Columns are zero based <<<<<<<<<<<<<<<<<<<< This works everytime
;~          Local $sDelimiter = ","
;~          Local $bColHeader = True
;~          Local $iSortColumn = 4
            _MyFunction()
            MsgBox(0,"", "Splitting Finished")
    EndSwitch
WEnd

Func _MyFunction()
Local $sFilePath = $sChoosePath

Local $hFile = FileOpen($sFilePath)
If $hFile = -1 Then
    MsgBox(0, "", "Unable to open file")
    Exit
EndIf

Local $sCSV = FileRead($hFile)
If @error Then
    MsgBox(0, "", "Unable to read file")
    FileClose($hFile)
    Exit
EndIf
FileClose($hFile)

Local $aCSV = _CSVSplit($sCSV) ; Create the main array
If @error Then
    ConsoleWrite("Error = " & @error & @LF)
    Exit
EndIf

;~ For $i = 1 To UBound($aCSV) -1 ; Or $i = 0 To UBound($aArray) -1   ; sort array with $iSortColumn
;~     $aCSV[$i][$iSortColumn] = Number($aCSV[$i][$iSortColumn])
;~ Next

; Create an array of csv strings
Local $aSubItemCSV = _ArrayToSubItemCSV($aCSV, $iColumn, $sDelimiter, $bColHeader, $iSortColumn)
If @error Then
    ConsoleWrite("Error = " & @error & @LF)
    Exit
EndIf

; Now let's write each csv to file
Local $sFolderName = StringTrimRight(StringReplace($sFilePath, @ScriptDir & "\", ""), 4)
Local $sNewPath, $iSuccess

For $i = 0 To UBound($aSubItemCSV) -1
    If StringRegExp($aSubItemCSV[$i][0], '[\/\?<>\\\:\|"]') Then
        MsgBox(0, "Invalid file name", "You can not use the following characters in a file name" & @CRLF & '/ ? < > \ : | "')
        Exit
    EndIf
    $sNewPath = @ScriptDir & "\" & $sFolderName & "\" & $aSubItemCSV[$i][0] & ".csv"
    $hFile = FileOpen($sNewPath, BitOr(8,1))
    If $hFile = -1 Then
        MsgBox(0, "", "Unable to open file")
        Exit
    EndIf

    $iSuccess = FileWrite($hFile, $aSubItemCSV[$i][1])
    FileClose($hFile)
    If $iSuccess = 0 Then
        MsgBox(0, "", "Unable to write to file")
        Exit
    EndIf
Next
EndFunc ;==>_MyFunction()

;~          Local $sFilePath = @ScriptDir & "\LineItem813.csv" ; Change this to your own csv file (in the same directory as the script)
;~          Local $sSourceSize = FileGetSize( $hFile)
;~          ConsoleWrite($sSourceSize & @crlf)
;~          Local $sFileSelect = _GetFileName( $hFile)
;~          Local $sFolderName = StringTrimRight( $sFileSelect, 4)
;~          If @error = 1 Or $sFileSelect = "" Then
;~              MsgBox(48, "Cancelled", "Cancelled By User", 4)
;~              Exit
;~          Else
;~              GUICtrlSetData( $OpenLabel, $sFileSelect)
;~          EndIf


Func _ParseCSV($sFile, $sDelimiters = ',;', $sQuote = '"', $iFormat = 0)
    Local Static $aEncoding[6] = [0, 0, 32, 64, 128, 256]
    If $iFormat < -1 Or $iFormat > 6 Then
        Return SetError(3, 0, 0)
    ElseIf $iFormat > -1 Then
        Local $hFile = FileOpen($sFile, $aEncoding[$iFormat]), $sLine, $aTemp, $aCSV[1], $iReserved, $iCount
        #forceref  $sLine, $aTemp, $aCSV, $iReserved, $iCount
        If @error Then Return SetError(1, @error, 0)
        $sFile = FileRead($hFile)
        FileClose($hFile)
    EndIf
    If $sDelimiters = "" Or IsKeyword($sDelimiters) Then $sDelimiters = ',;'
    If $sQuote = "" Or IsKeyword($sQuote) Then $sQuote = '"'
    $sQuote = StringLeft($sQuote, 1)
    Local $srDelimiters = StringRegExpReplace($sDelimiters, '[\\\^\-\[\]]', '\\\0')
    Local $srQuote = StringRegExpReplace($sQuote, '[\\\^\-\[\]]', '\\\0')
    Local $sPattern = StringReplace(StringReplace('(?m)(?:^|[,])\h*(["](?:[^"]|["]{2})*["]|[^,\r\n]*)(\v+)?', ',', $srDelimiters, 0, 1), '"', $srQuote, 0, 1)
    Local $aREgex = StringRegExp($sFile, $sPattern, 3)
    If @error Then Return SetError(2, @error, 0)
    $sFile = '' ; save memory
    Local $iBound = UBound($aREgex), $iIndex = 0, $iSubBound = 1, $iSub = 0
    Local $aResult[$iBound][$iSubBound]
    For $i = 0 To $iBound - 1
        Select
            Case StringLen($aREgex[$i]) < 3 And StringInStr(@CRLF, $aREgex[$i])
                $iIndex += 1
                $iSub = 0
                ContinueLoop
            Case StringLeft(StringStripWS($aREgex[$i], 1), 1) = $sQuote
                $aREgex[$i] = StringStripWS($aREgex[$i], 3)
                $aResult[$iIndex][$iSub] = StringReplace(StringMid($aREgex[$i], 2, StringLen($aREgex[$i]) - 2), $sQuote & $sQuote, $sQuote, 0, 1)
            Case Else
                $aResult[$iIndex][$iSub] = $aREgex[$i]
        EndSelect
        $aREgex[$i] = 0 ; save memory
        $iSub += 1
        If $iSub = $iSubBound Then
            $iSubBound += 1
            ReDim $aResult[$iBound][$iSubBound]
        EndIf
    Next
    If $iIndex = 0 Then $iIndex = 1
    ReDim $aResult[$iIndex][$iSubBound]
    Return $aResult
EndFunc   ;==>_ParseCSV

It would be nice to have the main array available to view after selection of the file

Ive tried putting the main array part in the top case but it makes the gui twitchy.

Could i have a suggestion or 2 plz so i can get this working

Edited by Chimaera

Share this post


Link to post
Share on other sites
ZacUSNYR

I'm out of time here at work to help out with an example. Personally I like on-event GUIs. Below is a quick GUI layout, you can mess around with it and see how you can implement what you're trying to accomplish.

After you generate the CSV file data you can populate the combos and then allow for the split button to function.

#include <Array.au3>
#include <CSVSplit.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
 
Opt("GUIOnEventMode", 1)
 
Global $sUserFileSelection, $hGUI_Label_FileSelection, $hGUI_Combo_SplitColumn, $hGUI_Input_Delimiter, $hGUI_Combo_ColumnHeader, $hGUI_Combo_SortColumn, $hGUI_Progress, $hGUI_Button_Split
 
$hGUI = GUICreate("GUI Title", 500, 400)
GUISetFont(11, 550, -1, "Tahoma", $hGUI)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
 
GUICtrlCreateButton(" Open CSV ", 20, 20, 130, 35)
GUICtrlSetOnEvent(-1, "_BUTTON_OpenCSV")
$hGUI_Label_FileSelection = GUICtrlCreateLabel("No File Selected", 160, 30, 350, 60, $SS_LEFT)
GUICtrlCreateButton(" View CSV ", 380, 70, 90, 35)
GUICtrlSetOnEvent(-1, "_BUTTON_ViewCSV")
GUICtrlCreateLabel("Choose Column For Split", 20, 80, 240)
$hGUI_Combo_SplitColumn = GUICtrlCreateCombo("", 240, 77, 60, 25)
GUICtrlCreateLabel("Delimiter", 20, 120, 240)
$hGUI_Input_Delimiter = GUICtrlCreateInput(",", 240, 117, 60, 25)
GUICtrlCreateLabel("Column Header", 20, 160, 240)
$hGUI_Combo_ColumnHeader = GUICtrlCreateCombo("", 240, 157, 60, 25)
GUICtrlSetData(-1, "True|False", "True")
GUICtrlCreateLabel("Choose Column For Sort", 20, 220, 240)
$hGUI_Combo_SortColumn = GUICtrlCreateCombo("", 240, 227, 60, 25)
$hGUI_Progress = GUICtrlCreateProgress(20, 260, 460)
$hGUI_Button_Split = GUICtrlCreateButton(" Split CSV ", 20, 320, 130, 35)
GUICtrlSetState(-1, $GUI_DISABLE)
GUICtrlSetOnEvent(-1, "_BUTTON_SplitCSV")
 
GUISetState(@SW_SHOW, $hGUI)
 
While 1
    Sleep(10)
WEnd
 
Func _BUTTON_OpenCSV()
Local $hUserSelection
Local $hUserSelection = FileOpenDialog("Please select a CSV file.", @DesktopDir, "Text (*.csv)")
If Not @error Then
GUICtrlSetData($hGUI_Label_FileSelection, $hUserSelection)
GUICtrlSetState($hGUI_Button_Split, $GUI_ENABLE)
$sUserFileSelection = $hUserSelection
EndIf
EndFunc
 
Func _BUTTON_ViewCSV()
If FileExists($sUserFileSelection) Then Run("notepad.exe " & $sUserFileSelection)
EndFunc
 
Func _BUTTON_SplitCSV()
 
EndFunc
 
Func _Exit()
    Exit
EndFunc

Share this post


Link to post
Share on other sites
Chimaera

Thx ill have a look at that, my problem is not the gui so much as i cant split the code into different functions because it errors.

Normally i can take a piece of code and make it work in a function but this one is tricky for some reason.

Ill keep trying

Share this post


Link to post
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
Sign in to follow this  

×