<!-- m -->https://ahknet.autoh...k% ... CSV.zip<!-- m -->
Preview:-
Since I'm a no0b myself, I've commented on each line so other no0bs like me have no trouble understanding the flow
Script
CSV_SET("Demo csv file.csv",1) ;if your csv file is in the script dir, then no need to write %A_workingdir% totalrows:=CSV_totalRows()-1 ; otherwise it'll read one more row and give blank RUN=hence error when launching menu filedelete,%A_workingdir%\tempmenufile.ahk ;because Only God knows how to write (,) comma in a file append so I'm going to use @ instead of comma in this fileappend loop and later i'll replace the @ with comma via regex Loop,%Totalrows% ; in first Loop we write the menu part { name:=CSV_readCell(A_index,1) ;this will read entire 1st column i.e the menu names fileappend,Menu@tempmenu@add@%name%@Label%A_index%`n,%A_workingdir%\tempmenufile.ahk ;write Tray instead of tempmenu if you want a traymenu. } ;you need to change following line as per your requirement to change how and when to 'show' the menu! fileappend,Menu@tempmenu@Show`nreturn`n,%A_workingdir%\tempmenufile.ahk ;this is how the menu will be shown, you can write hotkey like #z etc Loop,%Totalrows% ; in second loop now we write the Label and action part { runthis:=CSV_readCell(A_index,2) ;this will read entire column #2 of csv file i.e the 'Run this' fileappend,Label%A_index%:`nRun@%runthis%`nreturn`n,%A_workingdir%\tempmenufile.ahk } ;Now I'm going to replace @ with comma via regex so we can see Menu fileread,needtoreplaceatwithcomma,%A_workingdir%\tempmenufile.ahk removedatandaddedcomma:=RegExReplace(needtoreplaceatwithcomma,"@",",") ;here Regex replaces @ with comma so your AHK file can udnerstand commands like "Menu,tray,add,this,that "whatever filedelete,%A_workingdir%\tempmenufile.ahk ; since there is no way to 'update' the lines of an existing file via fileappend so we delete old file and create new one fileappend,%removedatandaddedcomma%,%A_workingdir%\tempmenufile.ahk run,%A_workingdir%\tempmenufile.ahk ;this launches the created menu file and you'll see a big menu ;===thanks Mr.neXt's thread named simplified csv operations for following part" ;+--------------+ ;|function list.| ;+--------------+ /* CSV_SET(r_file, r_header=0, r_delimiter=",") CSV_FINAL(copy=0) CSV_totalRows() CSV_totalCols() CSV_readCell(row = 1, column = 1) XLS_readCell(range) CSV_find(value, row=0, column=0, offset_x=0, offset_y=0) CSV_exists(value) CSV_sort(column=1, order="asc") CSV_writeCell(row, column, value) XLS_writeCell(range, value) CSV_fileName() CSV_filePath() CSV_fullName() */ setBatchLines -1 CSV_SET(r_file, r_header=0, r_delimiter=",") { global r_delimiter = %r_delimiter% r_header = %r_header% r_row = 0 r_col = 0 if r_delimiter = , r_delimiter = CSV SplitPath r_file, r_name, r_path, r_ext, r_nameNoExt if(r_path = "") r_path = %A_WorkingDir% fileRead r_file, %r_file% if (errorLevel) { MsgBox unable to read the file return %errorLevel% } loop parse, r_file, `n { r_row++ loop parse, A_LoopField, %r_delimiter% { ;if(r_row = 1) ;r_col++ __matrix%r_row%_%A_Index% := regExReplace(A_LoopField, "\R?$") if r_delimiter = CSV { if (A_Index = 1) __line%r_row% := Format4CSV(__matrix%r_row%_%A_Index%) else __line%r_row% := __line%r_row% . "," . Format4CSV(__matrix%r_row%_%A_Index%) } else { if (A_Index = 1) __line%r_row% := Format4CSV(__matrix%r_row%_%A_Index%) else __line%r_row% := __line%r_row% . r_delimiter . Format4CSV(__matrix%r_row%_%A_Index%) } } } r_fullName := CSV_fullName() CSV_totalRows() CSV_totalCols() return } CSV_totalRows() { global r_lastRow := r_row return %r_lastRow% } CSV_totalCols() { global r_lastCol = %r_col% return %r_lastCol% } CSV_readCell(row = 1, column = 1) { global if (r_header) row++ return % __matrix%row%_%column% ;% } XLS_readCell(range) { global if (r_header) row++ StringLeft column, range, 1 StringReplace row, range, %column% StringUpper column, column column := ASC(column) - 64 return % __matrix%row%_%column% ;% } CSV_writeCell(row, column, value) { global if (r_header) row++ __line%row% := regExReplace(__line%row%, __matrix%row%_%column%, Format4CSV(value)) __matrix%row%_%column% := Format4CSV(value) r_updated := true return } XLS_writeCell(range, value) { global if r_header = 1 row++ StringLeft column, range, 1 StringReplace row, range, %column% StringUpper column, column column := ASC(column) - 64 __line%row% := regExReplace(__line%row%, __matrix%row%_%column%, Format4CSV(value)) __matrix%row%_%column% := Format4CSV(value) r_updated := true return } CSV_fileName() { global return %r_name% } CSV_filePath() { global return % r_path . "\" ;% } CSV_fullName() { global return % r_path . "\" . r_name ;% } CSV_find(value, row=0, column=0, offset_x=0, offset_y=0) { global local i = 0 ;full search if (row = 0 && column = 0) { loop %r_lastRow% { i++ loop %r_lastCol% { if (__matrix%i%_%A_Index% = value) return % i + offset_x . "," . A_Index + offset_y ;% } } } ;search specified row if (row != 0 && column = 0) { loop %r_lastCol% { if (value = __matrix%row%_%A_Index%) return % A_Index + offset_y ;% } } ;search specified column if (row = 0 && column != 0) { loop %r_lastRow% { if (value = __matrix%A_Index%_%column%) return % A_Index + offset_x ;% } } return false } CSV_exists(value) { global if (InStr(r_file, value . "`,")) return true else return false } CSV_sort(column=1, order="") { global r_file = local i = 0 if (order = "desc") order = R loop %r_lastRow% { If __matrix%A_Index%_%column% is not number { StringUpper sortBy, __matrix%A_Index%_%column% sortBy := ASC(sortBy) + 1000000000000 } else sortBy := __matrix%A_Index%_%column% __line%A_Index% := sortBy . r_delimiter . __line%A_Index% . "`n" r_file := r_file . __line%A_Index% } Sort r_file, N %order% ;reload the array loop parse, r_file, `n { i++ x = 0 loop parse, A_LoopField, %r2_delimiter% { if (A_Index = 1) continue x++ __matrix%i%_%x% := A_LoopField if (x = 1) __line%i% := Format4CSV(__matrix%i%_%x%) else __line%i% := __line%i% . r_delimiter . Format4CSV(__matrix%i%_%x%) } } r_file = loop %r_lastRow% r_file := r_file . __line%A_Index% . "`n" r_updated := true return } CSV_FINAL(copy=0) { global if(r_updated) { if (copy = 1) { r_fullName = %r_path%\%r_nameNoExt%_copy.%r_ext% ifExist %r_fullName% fileDelete %r_fullName% } else fileDelete %r_fullName% loop %r_lastRow% r_file := r_file . __line%A_Index% . "`n" } fileAppend %r_file%, %r_fullName% return } ;author Rhys. ;[Function] Convert String for CSV - Format4CSV() beta 1 ;can be found at http://www.autohotkey.com/forum/viewtopic.php?t=27233 Format4CSV(F4C_String) { Reformat:=False ;Assume String is OK IfInString F4C_String,`n ;Check for linefeeds Reformat:=True ;String must be bracketed by double quotes IfInString F4C_String,`r ;Check for linefeeds Reformat:=True IfInString F4C_String,`, ;Check for commas Reformat:=True IfInString F4C_String, `" ;Check for double quotes { Reformat:=True StringReplace, F4C_String, F4C_String, `",`"`", All ;The original double quotes need to be double double quotes } If (Reformat) F4C_String=`"%F4C_String%`" ;If needed, bracket the string in double quotes return F4C_String }
Limitation:-
[*:3bvndj05]can't create submenus
[*:3bvndj05]creates menu only with 'Run' command
[*:3bvndj05]I checked only on AHK_Lexico's version. so this might give "unsupported use of "." error on the default one.
I would request the Legendary script creators like Majkinteor, SKAN and others to upgrade and improve it.
Thanks everyone, especially the Man who wrote the thread named "simplified CSV operations".