line = escape(line)Your escape() function scans character-by-character across and when it encounters a ," combination, it enters a quoted content where escape will be valid. When it encounters a ", combination, it leaves quoted content where escape will not be valid. UPDATE: Also needs to check the beginning field. Code updated below.
FUNCTION escape LPARAMETERS tcLine LOCAL lnI, lcLine, llInQuote FOR lnI = 1 TO LEN(tcLine) DO CASE CASE NOT llInQuote AND (CHRTRAN(SUBSTR(tcLine, lnI, 2), CHR(32), SPACE(0)) = "," + CHR(34) ; OR (lnI = 1 AND CHRTRAN(SUBSTR(tcLine, lnI, 2), CHR(32), SPACE(0)) = CHR(34))) * We're entering a quote llInQuote = .t. * Skip past the double-quote FOR lnI = lnI to LEN(tcLine) lcLine = lcLine + SUBSTR(tcLine, lnI, 1) IF SUBSTR(tcLine, lnI, 1) = CHR(34) EXIT ENDIF NEXT CASE llInQuote AND CHRTRAN(SUBSTR(tcLine, lnI, 2), CHR(32), SPACE(0)) = CHR(34) + "," llInQuote = .f. lcLine = lcLine + SUBSTR(tcLine, lnI, 1) CASE llInQuote * See if it's a character we want to escape IF INLIST(SUBSTR(tcLine, lnI, 1), ",") * Escape it lcLine = lcLine + "%" + (ASC(SUBSTR(tcLine, lnI, 1))) + "%" ELSE * As-is lcLine = lcLine + SUBSTR(tcLine, lnI, 1) ENDIF OTHERWISE * As-is lcLine = lcLine + SUBSTR(tcLine, lnI, 1) ENDCASE NEXT RETURN lcLineAnd you can put m. in there where needed.
AAA,BBB,"XXX YYY%44% ZZZ",CCC,"X1%44% Y1%44% Z1",DDD,To undo, create an unescape() function which scans for %##% content, and replaces it with CHR(VAL(SUBSTR(tcLine, lnI + 1))). And you can use other characters than % to make it like html with nnn; and the like. It's your choice.