0

I'm currently importing CSV data from gmail emails automatically using the following script:

 function importsearchresultsCSVFromGmail2() {

var threads = GmailApp.search("Scheduled report (********** **** *******)");
var messages = threads[0].getMessages();
var message = messages[messages.length - 1];
var attachment = message.getAttachments()[0];

// Is the attachment a CSV file

attachment.setContentType('text/csv');
//attachment.setContentTypeFromExtension();

if (attachment.getContentType() === "text/csv") {

var sheet = SpreadsheetApp.getActiveSpreadsheet();
var sh0 = sheet.getSheetByName("Sheet1")
var csvData = Utilities.parseCsv(attachment.getDataAsString(), ",");


// Remember to clear the content of the sheet before importing new data
sh0.getRange(1, 1, csvData.length, csvData[0].length).setValues(csvData);
GmailApp.markMessageRead(message);

}
}

However, some address fields in the csv are formatted in the entire cell of the csv to be:

Address Layout 1

and some will be shown as "123 New Road, London, NE3 1RD". < These display correctly in the import, however the formatted version above is spread across a number of cells and messes up the original layout of the csv.

Is there a way to ensure the imported cell (that contains the formatted address cell) wont spread across to other cells?

Current CSV File Example Current Google Sheet Result

Thanks in advance.

Tom

2 Answers2

1

Here is a variant (not so elegant as Yuri solution)

function importCSVFromGoogleDrive() {
  var file = DriveApp.getFilesByName("CSV TEST.csv").next();
  var csvString = file.getBlob().getDataAsString().replace(/\n/g, '♥').replace(/\r♥/g, '\r\n')
  var csvData = Utilities.parseCsv(csvString);
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('mySheet');
  sheet.clear();
  sheet.getRange(1, 1, csvData.length, csvData[0].length).setValues(csvData);
  SpreadsheetApp.flush()
  let ranges = SpreadsheetApp.getActive()
    .createTextFinder("♥")
    .matchEntireCell(false)
    .matchCase(true)
    .matchFormulaText(false)
    .ignoreDiacritics(true)
    .findAll();
  ranges.forEach(function (range) {
    range.setValue(range.getValue().replace(/♥/g,"\n"));
  });
}

enter image description here

adapted to your situation

  var csvData = Utilities.parseCsv(attachment.getDataAsString().replace(/\n/g, '♥').replace(/\r♥/g, '\r\n'), ",");
  sh0.getRange(1, 1, csvData.length, csvData[0].length).setValues(csvData);
  SpreadsheetApp.flush()
  let ranges = sh0
    .createTextFinder("♥")
    .matchEntireCell(false)
    .matchCase(true)
    .matchFormulaText(false)
    .ignoreDiacritics(true)
    .findAll();
  ranges.forEach(function (range) {
    range.setValue(range.getValue().replace(/♥/g, "\n"));
  });
Mike Steelson
  • 14,650
  • 2
  • 5
  • 20
  • It happens again. Looks like yet another asker wasn't able to implement any of solutions and preferred to disappear in the fog. A neverending sad story. ( – Yuri Khristich Aug 04 '22 at 08:34
  • I'm still here guys, sorry got two kids and the misses is away so trying to juggle! I'm working on both suggestions! (As well as trying not to lose my mind!) – Tom Barrett Aug 04 '22 at 13:33
  • Thank you both Mike and @Yuri for your solutions, for some crazy reason Yuri I couldn't get your solution to work. But this variant seemed to worked lovely. Thanks for your patience! – Tom Barrett Aug 04 '22 at 15:09
0

It would be better if you show your CSV as a text.

I think there are \r and \n inside a quote marks ". You can try to replace them with spaces if you change this line:

var csvData = Utilities.parseCsv(attachment.getDataAsString(), ",");

to this:

var s = attachment.getDataAsString().replace(/"[^"]+?"/, x => x.replace(/[\r\n]+/g, ' '));
var csvData = Utilities.parseCsv(s, ',');

Output:

enter image description here

Update

Here is the variant of about the same function. It does the same thing: replaces \r and \n within quote marks. But it replaces them with the special symbol. And replaces this symbol back to \n after the data is pasted on the sheet:

function get_csv() {
  var threads = GmailApp.search("Scheduled report"); // subject
  var message = threads[0].getMessages().pop(); // get last message from first thread
  var attachment = message.getAttachments()[0]; // first attachment
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sh = ss.getSheetByName("Sheet1");

  // get the csv string and replace \n with the symbol ¶
  var s = attachment.getDataAsString().replace(/"[^"]+?"/g, x => x.replace(/[\r\n]+/g, '¶'));
  var csvData = Utilities.parseCsv(s, ',');

  sh.getRange(1, 1, csvData.length, csvData[0].length).setValues(csvData);
  sh.getDataRange().createTextFinder('¶').replaceAllWith('\n'); // restore \n inside cells

  GmailApp.markMessageRead(message);
}

Result:

enter image description here

Here is the CSV data (not sure if the \r\n are intact after copy and paste):

Activity date & time,Status change,Postcode,Introducer,Marketing source,Assigned user,Lead reference,Lead date,Signed Date,Offered Date,Completed Date,Title,First name,Last name,Lead type,Lead group,Site,Product,"Security Address, if different from above"
01/02/2022,Signed,NE3 1RD,Me,,Me,172312026,15/11/2021,None,None,None,Mr.,John,Smith,Band A,Type 1,Leads.com,Fixed 5,"123 New Road, LONDON, NE3 1RD"
01/02/2022,Signed,NE3 1RD,Me,,Me,172312026,15/11/2021,None,None,None,Mr.,John,Smith,Band A,Type 1,Leads.com,Fixed 5,"123 New Road
LONDON
NE3 1RD"
Yuri Khristich
  • 13,448
  • 2
  • 8
  • 23
  • Hi Yuri, your code changes seem to hang a lot but also isn't giving me the desired effect, in most cases it's making the separation worse. I've added a couple of screenshots to my original questions to show what the data looks like and what the inccorrect result looks like. – Tom Barrett Aug 03 '22 at 12:40
  • It's impossible to fix without a fragment of your real CSV file. I can't even guess what do you mean 'making the separation worse'. – Yuri Khristich Aug 03 '22 at 12:59
  • Happy to send across an example csv file, what's the best way for me to provide it to you? – Tom Barrett Aug 03 '22 at 13:29
  • You could just paste it in the question. But if you want to sent you can use for example this: https://www.transferxl.com As a remedy you can right now to change in my code `replace(/\n/g, ' ')` with `replace(/[\r\n]+/g, ' ')` – Yuri Khristich Aug 03 '22 at 14:00
  • I've removed my first variant from my answer. I'm sure the second will work fine. – Yuri Khristich Aug 03 '22 at 14:06
  • https://www.transferxl.com/download/08P3q5cxyFCzC This is the example file, cell S3 shows how some of the address cells are causing a problem. When you run the code against that test file it shows the address in S3 across other cells as a result. – Tom Barrett Aug 03 '22 at 14:10
  • Your csv works fine with the code in my answer. Try to change `/\n/g` to `/[\r\n]+/g` – Yuri Khristich Aug 03 '22 at 14:20
  • https://stackoverflow.com/questions/1552749/difference-between-cr-lf-lf-and-cr-line-break-types here is the info about `\n` and `\r` trouble – Yuri Khristich Aug 03 '22 at 14:23
  • If you want to restore back the line breaks in cells, it can be done. Let me know if you need it. – Yuri Khristich Aug 03 '22 at 14:29
  • Still no luck. I'm on a mac (if that matters). I have: var sheet = SpreadsheetApp.getActiveSpreadsheet(); var sh0 = sheet.getSheetByName("Sheet1") var s = attachment.getDataAsString().replace(/"[^"]+?"/, x => x.replace(/[\r\n]+/g, ' ')); var csvData = Utilities.parseCsv(s, ','); But the result i'm after is for the second line of data to look like the first when I import the csv to google sheets? I'm still showing LONDON in cell A4 and NE3 1RD" in cell A5 after the import. – Tom Barrett Aug 03 '22 at 14:34
  • It's extremely weird. I just tried it on Mac. Still works fine. I send the mail with the subject 'Scheduled report', with attachment (your CSV file as is). Run the code (exactly like in the answer and in your comment) and got the correct result in my spreadsheet: https://imgur.com/TNa9xZ6.png I have no idea what could be wrong out there. Just in case I'll post another variant of the function, you can try it. – Yuri Khristich Aug 03 '22 at 14:52