├── README.md ├── csv.ahk └── example.ahk /README.md: -------------------------------------------------------------------------------- 1 | # CSV - AutoHotkey library for working with CSV Files 2 | 3 | This CSV library was developed by trueski and Kdoske - the original source can be found here http://www.autohotkey.com/forum/viewtopic.php?p=329126#329126 and https://autohotkey.com/board/topic/51681-csv-library-lib/ 4 | (archived forum links, the code posted there is no longer valid due to errors caused by upgrading the forum software.) 5 | 6 | This version includes bugfixes from: 7 | 8 | * http://www.autohotkey.com/forum/viewtopic.php?p=400669#400669 and other(s) 9 | * http://www.autohotkey.com/board/topic/51681-csv-library-lib/page-4#entry596685 10 | 11 | and incorporated in this library are: 12 | 13 | * Format4CSV by Rhys - https://autohotkey.com/board/topic/24859-function-convert-string-for-csv-format4csv-beta-1/ 14 | * Delimiter Seperated Values by DerRaphael - https://autohotkey.com/board/topic/30102-how-can-i-parse-a-csv-file-with-multi-line-values/#entry191846 15 | 16 | ## CSV Functions 17 | 18 | * CSV_Load(FileName, CSV_Identifier, Delimiter) ; Load CSV file into memory, must complete first. 19 | * CSV_TotalRows(CSV_Identifier) ; Return total number of rows 20 | * CSV_TotalCols(CSV_Identifier) ; Return total number of columns 21 | * CSV_Delimiter(CSV_Identifier) ; Return the delimiter used 22 | * CSV_FileName(CSV_Identifier) ; Return the filename 23 | * CSV_Path(CSV_Identifier) ; Return the path 24 | * CSV_FileNamePath(CSV_Identifier) ; Return the filename with the full path 25 | * CSV_Save(FileName, CSV_Identifier, OverWrite?) ; Save CSV file 26 | * CSV_DeleteRow(CSV_Identifier, RowNumber) ; Delete a row 27 | * CSV_AddRow(CSV_Identifier, "Cell1,Cell2...") ; Add a row 28 | * CSV_DeleteColumn(CSV_Identifier, ColNumber) ; Delete a column 29 | * CSV_AddColumn(CSV_Identifier, "Cell1,Cell2...") ; Add a column 30 | * CSV_ModifyCell(CSV_Identifier, NewValue,Row, Col) ; Modify an existing cell 31 | * CSV_ModifyRow(CSV_Identifier, "NewValue1,NewValue2...", RowNumber) ; Modify an existing row 32 | * CSV_ModifyColumn(CSV_Identifier, "NewValue1,NewValue2...", ColNumber)) ; Modify an existing column 33 | * CSV_Search(CSV_Identifier, SearchText, Instance) ; Search for text within 34 | * CSV_SearchRow(CSV_Identifier, SearchText, RowNumber, Instance) ; Search for text within a cell within a specific row 35 | * CSV_SearchColumn(CSV_Identifier, SearchText, ColNumber, Instance) ; Search for text within a cell within a specific column 36 | * CSV_MatchCell(CSV_Identifier, SearchText, Instance) ; Search for a cell containing exactly the data specified 37 | * CSV_MatchCellColumn(CSV_Identifier, SearchText, ColNumber, Instance=1) ; Search for a cell containing exactly the data specified in a specific column 38 | * CSV_MatchCellRow(CSV_Identifier, SearchText, RowNumber, Instance=1) ; Search for a cell containing exactly the data specified in a specific row 39 | * CSV_MatchRow(CSV_Identifier, "SearchText1,SearchText2", Instance) ; Search for a row containing exactly the data specified 40 | * CSV_MatchCol(CSV_Identifier, "SearchText1, SearchText2", Instance) ; Search for a column containing exactly the data specified 41 | * CSV_ReadCell(CSV_Identifier, Row, Column) ; Read data from the specified cell 42 | * CSV_ReadRow(CSV_Identifier, RowNumber) ; Read data from the specified row 43 | * CSV_ReadCol(CSV_Identifier, ColNumber) ; Read data from the specified column 44 | * CSV_LVLoad(CSV_Identifier, Gui, x, y, w, h, header, Sort?, RowIdentification?, AutoAdjustCol?) ; Load data into a listview in the specified gui window, listviewname variablewill equal "CSV_Identifier" 45 | * CSV_LVSave(FileName, CSV_Identifier, Delimiter, OverWrite?, Gui) ; Save the specified listview as a CSV file, CSV_Identifier is the ListView's associated variable name. 46 | 47 | ### AutoHotkey forum discussion 48 | 49 | https://autohotkey.com/boards/viewtopic.php?f=6&t=34853 50 | -------------------------------------------------------------------------------- /csv.ahk: -------------------------------------------------------------------------------- 1 | ; ------------------------------------------------------------------------------------- 2 | ; Source: https://github.com/hi5/CSV/ 3 | ; AutoHotkey forum: https://autohotkey.com/boards/viewtopic.php?f=6&t=34853 4 | ; ------------------------------------------------------------------------------------- 5 | ; 6 | ; 7 | ; URL: http://www.autohotkey.com/board/topic/51681-csv-library-lib/ 8 | ; includes bugfixes from 9 | ; http://www.autohotkey.com/forum/viewtopic.php?p=400669#400669 and other(s) 10 | ; http://www.autohotkey.com/board/topic/51681-csv-library-lib/page-4#entry596685 11 | ; ------------------------------------------------------------------------------------- 12 | ; AutoHotkey Version: 1.0.48 13 | ; Author: Kdoske, trueski 14 | ; http://www.autohotkey.com/forum/viewtopic.php?p=329126#329126 15 | ;################################################## CSV FUNCTIONS ############################################### 16 | ;if A Functions Field requires commas do not use spaces after each comma example: 'text1,text2,text3,text,4' 17 | ;Encapsulation must be quotations, example: 'text1, "text, 2", text3, text4' 18 | ;When you CSV_Load a blank file you must specify the column count before adding new rows or columns with a command similar to: %CSV_Identifier%CSV_TotalCols := 'column count'. 19 | ;CSV_Load(FileName, CSV_Identifier, Delimiter) ;Load CSV file into memory, must complete first. 20 | ;CSV_TotalRows(CSV_Identifier) ;Return total number of rows 21 | ;CSV_TotalCols(CSV_Identifier) ;Return total number of columns 22 | ;CSV_Delimiter(CSV_Identifier) ;Return the delimiter used 23 | ;CSV_FileName(CSV_Identifier) ;Return the filename 24 | ;CSV_Path(CSV_Identifier) ;Return the path 25 | ;CSV_FileNamePath(CSV_Identifier) ;Return the filename with the full path 26 | ;CSV_Save(FileName, CSV_Identifier, OverWrite?) ;Save CSV file 27 | ;CSV_DeleteRow(CSV_Identifier, RowNumber) ;Delete a row 28 | ;CSV_AddRow(CSV_Identifier, "Cell1,Cell2...") ;Add a row 29 | ;CSV_DeleteColumn(CSV_Identifier, ColNumber) ;Delete a column 30 | ;CSV_AddColumn(CSV_Identifier, "Cell1,Cell2...") ;Add a column 31 | ;CSV_ModifyCell(CSV_Identifier, NewValue,Row, Col) ;Modify an existing cell 32 | ;CSV_ModifyRow(CSV_Identifier, "NewValue1,NewValue2...", RowNumber) ;Modify an existing row 33 | ;CSV_ModifyColumn(CSV_Identifier, "NewValue1,NewValue2...", ColNumber)) ;Modify an existing column 34 | ;CSV_Search(CSV_Identifier, SearchText, Instance) ;Search for text within 35 | ;CSV_SearchRow(CSV_Identifier, SearchText, RowNumber, Instance) ;Search for text within a cell within a specific row 36 | ;CSV_SearchColumn(CSV_Identifier, SearchText, ColNumber, Instance) ;Search for text within a cell within a specific column 37 | ;CSV_MatchCell(CSV_Identifier, SearchText, Instance) ;Search for a cell containing exactly the data specified 38 | ;CSV_MatchCellColumn(CSV_Identifier, SearchText, ColNumber, Instance=1) ;Search for a cell containing exactly the data specified in a specific column 39 | ;CSV_MatchCellRow(CSV_Identifier, SearchText, RowNumber, Instance=1) ;Search for a cell containing exactly the data specified in a specific row 40 | ;CSV_MatchRow(CSV_Identifier, "SearchText1,SearchText2", Instance) ;Search for a row containing exactly the data specified 41 | ;CSV_MatchCol(CSV_Identifier, "SearchText1, SearchText2", Instance) ;Search for a column containing exactly the data specified 42 | ;CSV_ReadCell(CSV_Identifier, Row, Column) ;Read data from the specified cell 43 | ;CSV_ReadRow(CSV_Identifier, RowNumber) ;Read data from the specified row 44 | ;CSV_ReadCol(CSV_Identifier, ColNumber) ;Read data from the specified column 45 | ;CSV_LVLoad(CSV_Identifier, Gui, x, y, w, h, header, Sort?, RowIdentification?, AutoAdjustCol?) ;Load data into a listview in the specified gui window, listviewname variable will equal "CSV_Identifier" 46 | ;CSV_LVSave(FileName, CSV_Identifier, Delimiter, OverWrite?, Gui) ;Save the specified listview as a CSV file, CSV_Identifier is the ListView's associated variable name. 47 | ;#################################################################################################################### 48 | ;CSV Functions 49 | ;#################################################################################################################### 50 | CSV_Load(FileName, CSV_Identifier="", Delimiter="`,") 51 | { 52 | Local Row 53 | Local Col 54 | temp := %CSV_Identifier%CSVFile 55 | FileRead, temp, %FileName% 56 | StringReplace, temp, temp, `r`n`r`n, `r`n, all ;Remove all blank lines from the CSV file 57 | 58 | ; // fix for last newline and not importing all columns 59 | StringRight,NewlineCheck,temp,1 60 | if (NewlineCheck == "`n") { 61 | StringTrimRight, temp, temp,1 62 | } ; // fix from http://www.autohotkey.com/board/topic/51681-csv-library-lib/page-4#entry596685 63 | 64 | Loop, Parse, temp, `n, `r 65 | { 66 | If (A_LoopField = "") ; added to skip empty lines 67 | Continue ; added 68 | Col := ReturnDSVArray(A_LoopField, CSV_Identifier . "CSV_Row" . A_Index . "_Col", Delimiter) 69 | Row := A_Index 70 | ; Loop, Parse, A_LoopReadLine, %Delimiter% ; 71 | ; { 72 | ; Col := A_Index 73 | ; %CSV_Identifier%CSV_Row%Row%_Col%Col% := A_LoopField 74 | ; } 75 | } 76 | %CSV_Identifier%CSV_TotalRows := Row 77 | %CSV_Identifier%CSV_TotalCols := Col 78 | %CSV_Identifier%CSV_Delimiter := Delimiter 79 | SplitPath, FileName, %CSV_Identifier%CSV_FileName, %CSV_Identifier%CSV_Path 80 | IfNotInString, FileName, `\ 81 | { 82 | %CSV_Identifier%CSV_FileName := FileName 83 | %CSV_Identifier%CSV_Path := A_ScriptDir 84 | } 85 | %CSV_Identifier%CSV_FileNamePath := %CSV_Identifier%CSV_Path . "\" . %CSV_Identifier%CSV_FileName 86 | } 87 | ;#################################################################################################################### 88 | CSV_Save(FileName, CSV_Identifier, OverWrite="1") 89 | { 90 | Local Row 91 | Local Col 92 | 93 | If OverWrite = 0 94 | IfExist, %FileName% 95 | Return 96 | 97 | FileDelete, %FileName% 98 | 99 | EntireFile = 100 | CurrentCSV_TotalRows := %CSV_Identifier%CSV_TotalRows 101 | CurrentCSV_TotalCols := %CSV_Identifier%CSV_TotalCols 102 | Loop, %currentcsv_totalrows% 103 | { 104 | Row := A_Index 105 | Loop, %currentCSV_TotalCols% 106 | { 107 | Col := A_Index 108 | EntireFile .= Format4CSV(%CSV_Identifier%CSV_Row%Row%_Col%Col%,CSV_Delimiter(CSV_Identifier)) 109 | If (Col <> %CSV_Identifier%CSV_TotalCols) 110 | EntireFile .= %CSV_Identifier%CSV_Delimiter 111 | } 112 | If (Row < %CSV_Identifier%CSV_TotalRows) 113 | EntireFile .= "`n" 114 | } 115 | StringReplace, temp, temp, `r`n`r`n, `r`n, all ;Remove all blank lines from the CSV file 116 | loop, 117 | { 118 | stringright, test, EntireFile, EntireFile, 1 119 | if (test = "`n") or (test = "`r") 120 | stringtrimright, EntireFile, EntireFile, 1 121 | Else 122 | break 123 | } 124 | FileAppend, %EntireFile%, %FileName% 125 | } 126 | ;#################################################################################################################### 127 | CSV_TotalRows(CSV_Identifier) 128 | { 129 | global 130 | CurrentCSV_TotalRows := %CSV_Identifier%CSV_TotalRows 131 | Return %CurrentCSV_TotalRows% 132 | } 133 | ;#################################################################################################################### 134 | CSV_TotalCols(CSV_Identifier) 135 | { 136 | global 137 | CurrentCSV_TotalCols := %CSV_Identifier%CSV_TotalCols 138 | Return %CurrentCSV_TotalCols% 139 | } 140 | ;#################################################################################################################### 141 | CSV_Delimiter(CSV_Identifier) 142 | { 143 | global 144 | CurrentCSV_Delimiter := %CSV_Identifier%CSV_Delimiter 145 | Return %CurrentCSV_Delimiter% 146 | } 147 | ;#################################################################################################################### 148 | CSV_FileName(CSV_Identifier) 149 | { 150 | global 151 | CurrentCSV_FileName := %CSV_Identifier%CSV_FileName 152 | Return %CurrentCSV_FileName% 153 | } 154 | ;#################################################################################################################### 155 | CSV_Path(CSV_Identifier) 156 | { 157 | global 158 | CurrentCSV_Path := %CSV_Identifier%CSV_Path 159 | Return %CurrentCSV_Path% 160 | } 161 | ;#################################################################################################################### 162 | CSV_FileNamePath(CSV_Identifier) 163 | { 164 | global 165 | CurrentCSV_FileNamePath := %CSV_Identifier%CSV_FileNamePath 166 | Return %CurrentCSV_FileNamePath% 167 | } 168 | ;#################################################################################################################### 169 | CSV_DeleteRow(CSV_Identifier, RowNumber) 170 | { 171 | Local Row 172 | Local Col 173 | Local NewRow 174 | CurrentCSV_TotalRows := %CSV_Identifier%CSV_TotalRows 175 | CurrentCSV_TotalCols := %CSV_Identifier%CSV_TotalCols 176 | Loop, %CurrentCSV_TotalRows% 177 | { 178 | Row := A_Index 179 | NewRow := Row + 1 180 | If Row < %RowNumber% 181 | Continue 182 | Else 183 | Loop, %CurrentCSV_TotalCols% 184 | { 185 | Col := A_Index 186 | %CSV_Identifier%CSV_Row%Row%_Col%Col% := %CSV_Identifier%CSV_Row%NewRow%_Col%Col% 187 | } 188 | } 189 | %CSV_Identifier%CSV_TotalRows -- 190 | } 191 | ;#################################################################################################################### 192 | CSV_AddRow(CSV_Identifier, RowData) 193 | { 194 | global 195 | %CSV_Identifier%CSV_TotalRows ++ 196 | CurrentCSV_TotalRows := %CSV_Identifier%CSV_TotalRows 197 | CurrentCSV_Delimiter := %CSV_Identifier%CSV_Delimiter 198 | ReturnDSVArray(RowData, CSV_Identifier . "CSV_Row" . CurrentCSV_TotalRows . "_Col", CurrentCSV_Delimiter) 199 | } 200 | ;#################################################################################################################### 201 | CSV_DeleteColumn(CSV_Identifier, ColNumber) 202 | { 203 | Local Row 204 | Local Col 205 | Local NewCol 206 | CurrentCSV_TotalRows := %CSV_Identifier%CSV_TotalRows 207 | CurrentCSV_TotalCols := %CSV_Identifier%CSV_TotalCols 208 | Loop, %currentCSV_TotalRows% 209 | { 210 | Row := A_Index 211 | Loop, %currentCSV_TotalCols% 212 | { 213 | Col := A_Index 214 | NewCol := Col + 1 215 | If Col < %ColNumber% 216 | Continue 217 | Else 218 | %CSV_Identifier%CSV_Row%Row%_Col%Col% := %CSV_Identifier%CSV_Row%Row%_Col%NewCol% 219 | } 220 | } 221 | %CSV_Identifier%CSV_TotalCols -- 222 | } 223 | ;#################################################################################################################### 224 | CSV_AddColumn(CSV_Identifier, ColData) 225 | { 226 | global 227 | %CSV_Identifier%CSV_TotalCols ++ 228 | CurrentCSV_TotalCols := %CSV_Identifier%CSV_TotalCols 229 | CurrentCSV_Delimiter := %CSV_Identifier%CSV_Delimiter 230 | _tmpColItems:=ReturnDSVArray(Coldata, "_tmpCOL", CurrentCSV_Delimiter) 231 | Loop, %_tmpColItems% 232 | { 233 | %CSV_Identifier%CSV_Row%A_Index%_Col%CurrentCSV_TotalCols% := _tmpCOL%A_Index% 234 | _tmpCOL%A_Index%:= ; clear mem 235 | } 236 | _tmpColItems= ; clear mem 237 | } 238 | ;#################################################################################################################### 239 | CSV_ModifyCell(CSV_Identifier, Value, Row, Col) 240 | { 241 | global 242 | %CSV_Identifier%CSV_Row%Row%_Col%Col% := Value 243 | } 244 | ;#################################################################################################################### 245 | CSV_ModifyRow(CSV_Identifier, Value, RowNumber) 246 | { 247 | CurrentCSV_Delimiter := %CSV_Identifier%CSV_Delimiter 248 | ReturnDSVArray(Value, CSV_Identifier . "CSV_Row" . RowNumber . "_Col", CurrentCSV_Delimiter) 249 | } 250 | ;#################################################################################################################### 251 | CSV_ModifyColumn(CSV_Identifier, Coldata, ColNumber) 252 | { 253 | global 254 | CurrentCSV_Delimiter := %CSV_Identifier%CSV_Delimiter 255 | _tmpColItems:=ReturnDSVArray(Coldata, "_tmpCOL", CurrentCSV_Delimiter) 256 | Loop, %_tmpColItems% 257 | { 258 | %CSV_Identifier%CSV_Row%A_Index%_Col%ColNumber% := _tmpCOL%A_Index% 259 | _tmpCOL%A_Index%:= ; clear mem 260 | } 261 | _tmpColItems= ; clear mem 262 | } 263 | ;#################################################################################################################### 264 | CSV_Search(CSV_Identifier, SearchText, Instance=1) 265 | { 266 | Local Row 267 | Local Col 268 | Local FoundInstance 269 | CurrentCSV_TotalRows := %CSV_Identifier%CSV_TotalRows 270 | CurrentCSV_TotalCols := %CSV_Identifier%CSV_TotalCols 271 | 272 | Loop, %CurrentCSV_TotalRows% 273 | { 274 | Row := A_Index 275 | Loop, %CurrentCSV_TotalCols% 276 | { 277 | Col := A_Index 278 | CurrentString := %CSV_Identifier%CSV_Row%Row%_Col%Col% 279 | IfInString, CurrentString, %SearchText% 280 | { 281 | FoundInstance ++ 282 | CurrentCell = %Row%`,%Col% 283 | If FoundInstance = %Instance% 284 | Return %CurrentCell% 285 | } 286 | } 287 | } 288 | Return 0 289 | } 290 | ;#################################################################################################################### 291 | CSV_SearchRow(CSV_Identifier, SearchText, RowNumber, Instance=1) 292 | { 293 | Local Col 294 | Local FoundInstance 295 | CurrentCSV_TotalCols := %CSV_Identifier%CSV_TotalCols 296 | 297 | Loop, %CurrentCSV_TotalCols% 298 | { 299 | Col := A_Index 300 | CurrentString := %CSV_Identifier%CSV_Row%RowNumber%_Col%Col% 301 | IfInString, CurrentString, %SearchText% 302 | { 303 | FoundInstance ++ 304 | If FoundInstance = %Instance% 305 | Return %Col% 306 | } 307 | } 308 | Return 0 309 | } 310 | ;#################################################################################################################### 311 | CSV_SearchColumn(CSV_Identifier, SearchText, ColNumber, Instance=1) 312 | { 313 | Local Row 314 | Local FoundInstance 315 | CurrentCSV_TotalRows := %CSV_Identifier%CSV_TotalRows 316 | 317 | Loop, %CurrentCSV_TotalRows% 318 | { 319 | Row := A_Index 320 | CurrentString := %CSV_Identifier%CSV_Row%Row%_Col%ColNumber% 321 | IfInString, CurrentString, %SearchText% 322 | { 323 | FoundInstance ++ 324 | If FoundInstance = %Instance% 325 | Return %Row% 326 | } 327 | } 328 | Return 0 329 | } 330 | ;#################################################################################################################### 331 | CSV_MatchCell(CSV_Identifier,SearchText, Instance=1) 332 | { 333 | Local Row 334 | Local Col 335 | Local FoundInstance 336 | CurrentCSV_TotalRows := %CSV_Identifier%CSV_TotalRows 337 | CurrentCSV_TotalCols := %CSV_Identifier%CSV_TotalCols 338 | 339 | Loop, %CurrentCSV_TotalRows% 340 | { 341 | Row := A_Index 342 | Loop, %CurrentCSV_TotalCols% 343 | { 344 | Col := A_Index 345 | CurrentString := %CSV_Identifier%CSV_Row%Row%_Col%Col% 346 | IfEqual, CurrentString, %SearchText% 347 | { 348 | FoundInstance ++ 349 | CurrentCell = %Row%`,%Col% 350 | If FoundInstance = %Instance% 351 | Return %CurrentCell% 352 | } 353 | } 354 | } 355 | Return 0 356 | } 357 | ;#################################################################################################################### 358 | CSV_MatchCellColumn(CSV_Identifier, SearchText, ColNumber, Instance=1) 359 | { 360 | Local Row 361 | Local FoundInstance 362 | CurrentCSV_TotalRows := %CSV_Identifier%CSV_TotalRows 363 | 364 | Loop, %CurrentCSV_TotalRows% 365 | { 366 | Row := A_Index 367 | CurrentString := %CSV_Identifier%CSV_Row%Row%_Col%ColNumber% 368 | IfEqual, CurrentString, %SearchText% 369 | { 370 | FoundInstance ++ 371 | If FoundInstance = %Instance% 372 | Return %Row% 373 | } 374 | } 375 | Return 0 376 | } 377 | ;#################################################################################################################### 378 | CSV_MatchCellRow(CSV_Identifier, SearchText, RowNumber, Instance=1) 379 | { 380 | Local Col 381 | Local FoundInstance 382 | CurrentCSV_TotalCols := %CSV_Identifier%CSV_TotalCols 383 | 384 | Loop, %CurrentCSV_TotalCols% 385 | { 386 | Col := A_Index 387 | CurrentString := %CSV_Identifier%CSV_Row%RowNumber%_Col%Col% 388 | IfEqual, CurrentString, %SearchText% 389 | { 390 | FoundInstance ++ 391 | If FoundInstance = %Instance% 392 | Return %Col% 393 | } 394 | } 395 | Return 0 396 | } 397 | ;#################################################################################################################### 398 | CSV_MatchRow(CSV_Identifier, SearchText, Instance=1) 399 | { 400 | Local Col 401 | Local Row 402 | Local CurrentRow 403 | Local FoundInstance 404 | CurrentCSV_TotalRows := %CSV_Identifier%CSV_TotalRows 405 | CurrentCSV_TotalCols := %CSV_Identifier%CSV_TotalCols 406 | Loop, %CurrentCSV_TotalRows% 407 | { 408 | Row := A_Index 409 | CurrentRow = 410 | Loop, %CurrentCSV_TotalCols% 411 | { 412 | Col := A_Index 413 | CurrentRow .= %CSV_Identifier%CSV_Row%Row%_Col%Col% 414 | If Col <> %CurrentCSV_TotalCols% 415 | CurrentRow .= "`," 416 | IfEqual, CurrentRow, %SearchText% 417 | { 418 | FoundInstance ++ 419 | If FoundInstance = %Instance% 420 | Return %Row% 421 | } 422 | } 423 | } 424 | Return 0 425 | } 426 | ;#################################################################################################################### 427 | CSV_MatchCol(CSV_Identifier, SearchText, Instance=1) 428 | { 429 | Local Col 430 | Local Row 431 | Local CurrentCol 432 | Local FoundInstance 433 | CurrentCSV_TotalRows := %CSV_Identifier%CSV_TotalRows 434 | CurrentCSV_TotalCols := %CSV_Identifier%CSV_TotalCols 435 | Loop, %CurrentCSV_TotalCols% 436 | { 437 | Col := A_Index 438 | CurrentCol = 439 | Loop, %CurrentCSV_TotalRows% 440 | { 441 | Row := A_Index 442 | CurrentCol .= %CSV_Identifier%CSV_Row%Row%_Col%Col% 443 | If Row <> %CurrentCSV_TotalRows% 444 | CurrentCol .= "`," 445 | IfEqual, CurrentCol, %SearchText% 446 | { 447 | FoundInstance ++ 448 | If FoundInstance = %Instance% 449 | Return %Col% 450 | } 451 | } 452 | } 453 | Return 0 454 | } 455 | ;#################################################################################################################### 456 | CSV_ReadCell(CSV_Identifier, Row, Col) 457 | { 458 | Local CellData 459 | CellData := %CSV_Identifier%CSV_Row%Row%_Col%Col% 460 | Return %CellData% 461 | } 462 | ;#################################################################################################################### 463 | CSV_ReadRow(CSV_Identifier, RowNumber) 464 | { 465 | Local CellData 466 | CurrentCSV_TotalCols := %CSV_Identifier%CSV_TotalCols 467 | RowData= 468 | Loop, %CurrentCSV_TotalCols% 469 | { 470 | RowData .= %CSV_Identifier%CSV_Row%RowNumber%_Col%A_Index% 471 | If A_Index <> %CurrentCSV_TotalCols% 472 | RowData .= "`," 473 | } 474 | Return %RowData% 475 | } 476 | ;#################################################################################################################### 477 | CSV_ReadCol(CSV_Identifier, ColNumber) 478 | { 479 | Local CellData 480 | CurrentCSV_TotalRows := %CSV_Identifier%CSV_TotalRows 481 | ColData= 482 | Loop, %CurrentCSV_TotalRows% 483 | { 484 | ColData .= %CSV_Identifier%CSV_Row%A_Index%_Col%ColNumber% 485 | If A_Index <> %CurrentCSV_TotalRows% 486 | ColData .= "`," 487 | } 488 | Return %ColData% 489 | } 490 | ;#################################################################################################################### 491 | CSV_LVLoad(CSV_Identifier, Gui=1, x=10, y=10, w="", h="", header="", Sort=0, AutoAdjustCol=1) 492 | { 493 | Local Row 494 | CurrentCSV_TotalRows := %CSV_Identifier%CSV_TotalRows 495 | CurrentCSV_TotalCols := %CSV_Identifier%CSV_TotalCols 496 | 497 | If %CSV_Identifier%CSV_LVAlreadyCreated = 498 | { 499 | Gui, %Gui%:Add, ListView, v%CSV_Identifier% x%x% y%y% w%w% h%h%, %header% 500 | %CSV_Identifier%CSV_LVAlreadyCreated = 501 | } 502 | ;Set GUI window, clear any existing data 503 | Gui, %Gui%:Default 504 | GuiControl, -Redraw, %CSV_Identifier% 505 | Sleep, 200 506 | LV_Delete() 507 | 508 | ;Add Data 509 | Loop, %currentcsv_totalrows% 510 | LV_Add("", "") 511 | Loop, %currentcsv_totalrows% 512 | { 513 | Row := A_Index 514 | Loop, %currentCSV_TotalCols% 515 | LV_Modify(Row, "Col" . A_Index, %CSV_Identifier%CSV_Row%Row%_Col%A_Index%) 516 | } 517 | ;Display Data 518 | If Sort <> 0 519 | LV_ModifyCol(Sort, "Sort") 520 | 521 | If AutoAdjustCol = 1 522 | LV_ModifyCol() 523 | GuiControl, +Redraw, %CSV_Identifier% 524 | } 525 | ;#################################################################################################################### 526 | CSV_LVSave(FileName, CSV_Identifier, Delimiter=",",OverWrite=1, Gui=1) 527 | { 528 | Gui, %Gui%:Default 529 | Gui, ListView, %CSV_Identifier% 530 | Rows := LV_GetCount() 531 | Cols := LV_GetCount("Col") 532 | 533 | IfExist,2 %FileName% 534 | If OverWrite = 0 535 | Return 0 536 | FileDelete, %FileName% 537 | 538 | Loop, %Rows% 539 | { 540 | FullRow = 541 | Row := A_Index 542 | Loop, %Cols% 543 | { 544 | LV_GetText(CellData, Row, A_Index) 545 | FullRow .= Format4CSV(CellData,CSV_Delimiter(CSV_Identifier)) 546 | If A_Index <> %Cols% 547 | FullRow .= Delimiter 548 | } 549 | stringreplace, checkforemptyrow, fullrow, %Delimiter%,,all ; xx 550 | If (checkforemptyrow = "") 551 | Continue ; /xx 552 | If Row <> %Rows% 553 | FullRow .= "`n" 554 | EntireFile .= FullRow 555 | } 556 | FileAppend, %EntireFile%, %FileName% 557 | } 558 | ;#################################################################################################################### 559 | ; Format4CSV by Rhys 560 | ; http://www.autohotkey.com/forum/topic27233.html 561 | ; adding Delimiter as reported here https://www.autohotkey.com/boards/viewtopic.php?p=482369#p482369 562 | Format4CSV(F4C_String,Delimiter="`,") 563 | { 564 | Reformat:=False ;Assume String is OK 565 | IfInString, F4C_String,`n ;Check for linefeeds 566 | Reformat:=True ;String must be bracketed by double quotes 567 | IfInString, F4C_String,`r ;Check for linefeeds 568 | Reformat:=True 569 | IfInString, F4C_String,%Delimiter% ;was check for commas, updated to Delimiter 2022-09-25 - called from CSV_Save() and CSV_LVSave() 570 | Reformat:=True 571 | IfInString, F4C_String, `" ;Check for double quotes 572 | { Reformat:=True 573 | StringReplace, F4C_String, F4C_String, `",`"`", All ;The original double quotes need to be double double quotes 574 | } 575 | If (Reformat) 576 | F4C_String=`"%F4C_String%`" ;If needed, bracket the string in double quotes 577 | Return, F4C_String 578 | } 579 | ;#################################################################################################################### 580 | ; Delimiter Separated Values by DerRaphael 581 | ; http://www.autohotkey.com/forum/post-203280.html#203280 582 | ; 583 | ; Proof of Concept to extract DSV (Delimiter Separator Values) 584 | ; - adapted for AHK by derRaphael / 21st July 2008 - 585 | ; derRaphael@oleco.net 586 | ; Following rules apply: 587 | ; You have to set a delimiter char and an encapsulation char. 588 | ; 1) If you're using the delimiter char within your value, the value has 589 | ; to be surrounded by your encapsulation char. One at beginning and one 590 | ; at its end. 591 | ; 2) If you're using your encapsulation char within your value you have to 592 | ; double it each time it occurs and surround your value as in rule 1. 593 | ; Remarks: 594 | ; The whole concept will break, when using same EOL (End Of Line) as LineBreaks 595 | ; in a value as in the entire file. Either you will have to escape these chars 596 | ; somehow or use a single linefeed (`n) in values and carriage return linefeed 597 | ; (`r`n) as EOL in your DSV file. 598 | ; Encapsulation and delimiter chars have to be single Chars. Strings containing 599 | ; more than one char are not supported by concept. 600 | ;CurrentDSVLine=a,b,c,"d,e","f"","",g",,i 601 | ; 602 | ;Loop, % ReturnDSVArray(CurrentDSVLine) 603 | ; MsgBox % A_Index ": " DSVfield%A_Index% 604 | 605 | ReturnDSVArray(CurrentDSVLine, ReturnArray="DSVfield", Delimiter=",", Encapsulator="""") 606 | { 607 | global 608 | if ((StrLen(Delimiter)!=1)||(StrLen(Encapsulator)!=1)) 609 | { 610 | return -1 ; return -1 indicating an error ... 611 | } 612 | SetFormat,integer,H ; needed for escaping the RegExNeedle properly 613 | local d := SubStr(ASC(delimiter)+0,2) ; used as hex notation in the RegExNeedle 614 | local e := SubStr(ASC(encapsulator)+0,2) ; used as hex notation in the RegExNeedle 615 | SetFormat,integer,D ; no need for Hex values anymore 616 | 617 | local p0 := 1 ; Start of search at char p0 in DSV Line 618 | local fieldCount := 0 ; start off with empty fields. 619 | CurrentDSVLine .= delimiter ; Add delimiter, otherwise last field 620 | ; won't get recognized 621 | Loop 622 | { 623 | Local RegExNeedle := "\" d "(?=(?:[^\" e "]*\" e "[^\" e "]*\" e ")*(?![^\" e "]*\" e "))" 624 | Local p1 := RegExMatch(CurrentDSVLine,RegExNeedle,tmp,p0) 625 | ; p1 contains now the position of our current delimiter in a 1-based index 626 | fieldCount++ ; add count 627 | local field := SubStr(CurrentDSVLine,p0,p1-p0) 628 | ; This is the Line you'll have to change if you want different treatment 629 | ; otherwise your resulting fields from the DSV data Line will be stored in AHK array 630 | if (SubStr(field,1,1)=encapsulator) 631 | { 632 | ; This is the exception handling for removing any doubled encapsulators and 633 | ; leading/trailing encapsulator chars 634 | field := RegExReplace(field,"^\" e "|\" e "$") 635 | StringReplace,field,field,% encapsulator encapsulator,%encapsulator%, All 636 | } 637 | Local _field := ReturnArray A_Index ; construct a reference for our ReturnArray name 638 | %_field% := field ; dereference _field and assign our value to it 639 | if (p1=0) 640 | { ; p1 is 0 when no more delimiter chars have been found 641 | fieldCount-- ; so correct fieldCount due to last appended delimiter 642 | Break ; and exit loop 643 | } Else 644 | p0 := p1 + 1 ; set the start of our RegEx Search to last result 645 | } ; added by one 646 | return fieldCount 647 | } 648 | ;#################################################################################################################### 649 | -------------------------------------------------------------------------------- /example.ahk: -------------------------------------------------------------------------------- 1 | #NoEnv 2 | #SingleInstance, force 3 | 4 | ; A basic example illustrating some functions to get an idea of how to use CSV 5 | ; Consult the library (csv.ahk) for all available functions and required parameters 6 | ; and the results of each function 7 | 8 | ; Creating an example CSV file 9 | FileDelete, ExampleCSVFile.csv 10 | FileAppend, 11 | ( 12 | Year,Make,Model,Description,Price 13 | 1997,Ford,E350,"ac, abs, moon",3000.00 14 | 1999,Chevy,"Venture ""Extended Edition""","",4900.00 15 | 1999,Chevy,"Venture ""Extended Edition, Very Large""",,5000.00 16 | 1996,Jeep,Grand Cherokee,"MUST SELL! air, moon roof, loaded",4799.00 17 | ), ExampleCSVFile.csv 18 | 19 | ; load a CSV file using CSV_Load(FileName, CSV_Identifier, Delimiter) 20 | ; "data" is the CSV_Identifier we are using to refer to the file we've loaded, you can give it any name you'd like 21 | CSV_Load("ExampleCSVFile.csv","data") 22 | 23 | ; Display how many rows we have using CSV_TotalRows() 24 | MsgBox % "There are " CSV_TotalRows("data") " rows in this CSV file." 25 | 26 | ; Assign this to a variable like so: 27 | Rows:=CSV_TotalRows("data") 28 | 29 | ; Reading a Cell using CSV_ReadCell(), should show "E350" 30 | MsgBox % "Contents of Cell in row number 2, and column 3: " CSV_ReadCell("data",2,3) 31 | 32 | ; Assign this to a variable like so: 33 | Model:=CSV_ReadCell("data",2,3) 34 | 35 | ; ModifyReading a Cell using CSV_ModifyCell() 36 | CSV_ModifyCell("data", "Mustang",2,3) ; change E350 to Mustang 37 | 38 | MsgBox % "Contents of Cell in row number 2, and column 3: " CSV_ReadCell("data",2,3) 39 | 40 | ; Search for a cell containing "find" with CSV_Search() 41 | MsgBox % CSV_Search("data", "large") ; row 4, cell 3 e.g. 4,3 42 | 43 | ; Assign this to a variable like so: 44 | Result:=CSV_Search("data", "large") 45 | 46 | ; Note: if you want to use the result of CSV_Search() later on you need to split the result into a ROW and COLUMN 47 | Result:=StrSplit(Result,",") ; Result[1]=Row, Result[2]=Column 48 | MsgBox % CSV_ReadCell("data",Result[1],Result[2]) 49 | 50 | ; Find all cells containing "find" with CSV_Search() using a loop 51 | 52 | Loop, % Rows 53 | { 54 | found:=CSV_Search("data","moon",A_Index) 55 | if found=0 56 | break 57 | Results .= found "`n" 58 | } 59 | 60 | MsgBox % Results 61 | 62 | ; Save the modified CSV data to a file using CSV_Save() 63 | CSV_Save("ExampleCSVFile.csv","data") 64 | 65 | ; Sample script on how to add a column to be able to write new data to a CSV 66 | ; https://www.autohotkey.com/boards/viewtopic.php?p=242250#p242250 67 | 68 | ; CSVSwapColumns() - https://www.autohotkey.com/boards/viewtopic.php?p=484029#p484029 69 | ; CSVMoveColumns() - https://www.autohotkey.com/boards/viewtopic.php?p=484035#p484035 70 | 71 | ; When using this CSV library the script will remain persistent (remain active in memory) 72 | ; so you need close the script when you are done to free the memory 73 | ExitApp 74 | --------------------------------------------------------------------------------