This UDF is a good starting point. Though I wanted to comment that using FileReadLine in _CSVFileReadRecords is a bad idea if you care about performance. Even using an SSD drive with similar read and write times comparable to a 15000 RPM U320 SCSI HDD, trying to reading in a small 500KB CSV takes almost a minute (that's really bad). I'd recommend changing it to something like, $buffer = FileRead($lCVSFileHandle)
If @error = 1 Then ; Reading error, file open errors subsumed in FileOpen() above.
FileClose($lCVSFileHandle)
SetError(3)
$lRecords[0] = 0
Return 0
EndIf
$lRecords = StringSplit($buffer, @CRLF, 1) This dramatically improves load times. Later in functions like _CSVSearch(...). Then consider scanning the full string in the $pRecord and once you've identified a successful candidate. At that point do the _CSVRecordGetFields(). i.e. For $j = 1 To 1 ;UBound($lFields) - 1 Step 1 ;1
If $pMode = 1 Then
If Not _CSVConvertFieldToString($lFields[$j], $pEnclose) Then
SetError(3, @extended)
Return 0
EndIf
EndIf
;If StringInStr($lFields[$j], $pSearchStr, $pCaseSense) Then
If StringInStr($pRecords[$i], $pSearchStr, $pCaseSense) Then
ReDim $lResult[UBound($lResult) + 1][4]
Local $max = UBound($lResult)
$lResult[$max - 1][0] = $i ; record num
$lResult[$max - 1][1] = $j ; col num
$lResult[$max - 1][2] = $pRecords[$i] ; record
$lFields = _CSVRecordGetFields($pRecords[$i], $pDelimiter, $pEnclose)
If @error Then
SetError(2, @error)
Return 0
EndIf
$lResult[$max - 1][3] = $lFields[$j] ; field
;The following is useful for a person who just wants one record:
;ExitLoop 2
;Consider adding in another parameter specifying a hitcount
EndIf
Next I'm not trying to be a nit, just wanted to pass along some possible improvements. Thanks for sharing with us Ivan.