Please help me:
I have a sheet file with 2 columns
Column A is the keyword, column B is the link to insert the keyword. Eg:
Column A Column B
Key1 Link1
Key2 Link2
... ...
How to automatically find keywords in the DOCS file and then insert Link?
Here is my idea, but it doesn't work
function insertLink() {
var file,files,folder,folders,newestFileID;
var filethaythe = DriveApp.getFilesByName('Set Link');
var ss = SpreadsheetApp.open(filethaythe.next());//ID sheet thư viện thay thế
SpreadsheetApp.setActiveSpreadsheet(ss);
SpreadsheetApp.setActiveSheet(ss.getSheets()[0]);
var sh = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Trang tính1');
var sheet = ss.getSheetByName('Trang tính1');
var values = sheet.getDataRange().getValues();
folders = DriveApp.getFoldersByName('test3');
while (folders.hasNext()) {
folder = folders.next();
files = folder.getFilesByType("application/vnd.google-apps.document");
while (files.hasNext()){
file = files.next();
var newestFileID = file.getId();
Utilities.sleep(500);
var currentDoc = DocumentApp.openById(newestFileID);
var dongcuoi= sh.getLastRow();
var dc = dongcuoi +1;
var rgtxt = currentDoc.getBody();
var rgrep = ss.getSheets()[0].getRange("A1:B"+dc);
var repA = rgrep.getValues().filter(r => r.every(c => c.toString()));
repA.forEach(e => rgtxt.setLinkUrl(...e));
currentDoc.saveAndClose();
break
}
};
}
I believe your goal as follows.
You want to set the hyperlink to the word on Google Document.
The words and hyperlinks are retrieved from Google Spreadsheet.
In this case, how about the following modification?
Modified script:
function insertLink() {
// 1. Retrieve values from Spreadsheet.
var file,files,folder,folders,newestFileID;
var filethaythe = DriveApp.getFilesByName('Set Link');
var ss = SpreadsheetApp.open(filethaythe.next());
var sheet = ss.getSheetByName('Trang tính1');
var values = sheet.getDataRange().getValues();
// 2. Retrieve Google Document.
folders = DriveApp.getFoldersByName('test3');
while (folders.hasNext()) {
folder = folders.next();
files = folder.getFilesByType("application/vnd.google-apps.document");
while (files.hasNext()) {
file = files.next();
var newestFileID = file.getId();
// 3. Search words and set hyperlinks on Google Document.
var currentDoc = DocumentApp.openById(newestFileID);
var rgtxt = currentDoc.getBody();
values.forEach(([a, b]) => {
var s = rgtxt.findText(a);
while (s) {
var start = s.getStartOffset();
s.getElement().asText().setLinkUrl(start, start + a.length - 1, b);
s = rgtxt.findText(a, s);
}
});
currentDoc.saveAndClose();
break
}
}
}
In order to search the word, the method of findText is used. And, the method of setLinkUrl sets the hyperlink to the searched word.
References:
findText(searchPattern, from)
setLinkUrl(startOffset, endOffsetInclusive, url)
Related
I have multiple spreadsheets in a folder, for each spreadsheet and I would like to get the matching data from an external file.
For example if my spreadsheet is called 'iphone 7' I would like to get in that sheet all the records from my external file containing 'iphone 7'
Here is how far I got (I am pretty new to scripting !) :
function myfunction()
{
var root = DriveApp.getFoldersByName("Produits");
while (root.hasNext())
{
var folder = root.next(); //If the folder is available, get files in the folder
var files = folder.getFiles();
while(files.hasNext()) //For each file,
{
var spreadsheet = SpreadsheetApp.open(files.next());
//import data from URL
var csvUrl = "https://incensy.tempurl.host/test-ct-flux.csv";
var csvContent = UrlFetchApp.fetch(csvUrl).getContentText();
var csvData = Utilities.parseCsv(csvContent);
var sheets = spreadsheet.getSheets()
var sheetIndex=0
var sheet = sheets[sheetIndex]
sheet.getRange(2, 1, csvData.length, csvData[0].length).setValues(csvData);
//Only keep data that contains the file name
var name = spreadsheet.getName();
let range = sheet.getDataRange(),
maxRows = sheet.getMaxRows(),
srchCol_1 = 2,
srchPatt_1 = new RegExp(name, "i"),
newRangeVals = range.getValues().filter(r => r[0] && srchPatt_1.exec(r[srchCol_1])),
numRows = newRangeVals.length;
range.clearContent();
sheet.getRange(2,1, numRows, newRangeVals[0].length).setValues(newRangeVals);
console.log('myfunction')
sheet.deleteRows(numRows + 1, maxRows - numRows);
}
}
}
There is something wrong in the second part of the code I cannot figure out.
In your situation, how about the following modification?
Modified script:
function myfunction() {
var keywords = ["sample1", "sample2"]; // Please set the keywords you want to filter to the column "C".
// Retrieve CSV data.
var csvUrl = "https://incensy.tempurl.host/test-ct-flux.csv";
var csvContent = UrlFetchApp.fetch(csvUrl).getContentText();
var csvData = Utilities.parseCsv(csvContent, ";");
// Retrieve Spreadsheet and put the CSV data.
var root = DriveApp.getFoldersByName("Produits");
while (root.hasNext()) {
var folder = root.next();
var files = folder.getFiles();
while (files.hasNext()) {
var spreadsheet = SpreadsheetApp.open(files.next());
var name = spreadsheet.getName().toUpperCase();
var values = csvData.reduce((ar, r) => {
if (!keywords.some(e => r[2].includes(e)) && r.join("").toUpperCase().includes(name)) {
ar.push(r);
}
return ar;
}, []);
if (values.length == 0) continue;
var sheet = spreadsheet.getSheets()[0];
sheet.clearContents().getRange(1, 1, values.length, values[0].length).setValues(values);
}
}
}
In this modification, the CSV data is retrieved at the outside of the while loop. Using the retrieved CSV data and each Spreadsheet name, the data is put to the 1st tab of each Spreadsheet.
References:
reduce()
toUpperCase()
includes()
I am trying to import data from a specific URL into all sheets that are in a Google drive folder, then only keep the data that contains the name of the file.
Getting the files from the folder seems to be working but I cannot manage to have SpreasheetApp working (I think this is where the problem comes from). Maybe there is something wrong with how I manage to get ranges.
Here is what I have done so far :
function myfunction()
{
var root = DriveApp.getFoldersByName("Produits");
while (root.hasNext())
{
var folder = root.next(); //If the folder is available, get files in the folder
var files = folder.getFiles();
while(files.hasNext()) //For each file,
{
var spreadsheet = SpreadsheetApp.open(files.next());
//import data from URL
var csvUrl = "myURL";
var csvContent = UrlFetchApp.fetch(csvUrl).getContentText();
var csvData = Utilities.parseCsv(csvContent);
var activeSpreadSheet = SpreadsheetApp.open(files);
var sheets = activeSpreadSheet.getSheets();
var sheet = sheets[sheetIndex]
sheet.getRange(2, 1, csvData.length, csvData[0].length).setValues(csvData);
// Always show 3 decimal points
var cell = sheet.getRange("D2:D");
cell.setNumberFormat("00");
//Only keep data that contains the file name
var name = sheet.getName();
let range = sheet.getDataRange(),
maxRows = sheet.getMaxRows(),
srchCol_1 = 2,
srchPatt_1 = new RegExp(name)
newRangeVals = range.getValues().filter(r => r[0] && srchPatt_1.exec(r[srchCol_1])),
numRows = newRangeVals.length;
range.clearContent();
sheet.getRange(2,1, numRows, newRangeVals[0].length).setValues(newRangeVals);
sheet.deleteRows(numRows + 1, maxRows - numRows);
//Clean headers
var cell = sheet.getRange(1,1);
cell.setValue("Marchand");
var cell = sheet.getRange(1,2);
cell.setValue("Image");
var cell = sheet.getRange(1,3);
cell.setValue("Titre de l'offre");
var cell = sheet.getRange(1,4);
cell.setValue("Prix");
var cell = sheet.getRange(1,5);
cell.setValue("Lien");
var cell = sheet.getRange(1,6);
cell.setValue("Categorie");
}
}
}
Change
var activeSpreadSheet = SpreadsheetApp.open(files);
var sheets = activeSpreadSheet.getSheets();
to (spreadsheet has already been defined previously)
var sheets = spreadsheet.getSheets()
and give a value to sheetIndex, for instance
var sheets = spreadsheet.getSheets();
var sheetIndex=0
var sheet = sheets[sheetIndex]
I want to only copy the CSV attachment to google sheets from an email.
The email has multiple attachments, in different file formats.
The attachment I want to copy over is consistently the same name in csv format.
I am using this code but its not pulling the attachment I want to copy to google sheet.
Can someone help me with this.
function getCSV() {
var myLabel = GmailApp.getUserLabelByName("I-Data New"); // specify label in gmail
var threads = myLabel.getThreads(0,1);
var msgs = GmailApp.getMessagesForThreads(threads);
var attachments = msgs[0][0].getAttachments();
var csv = attachments[0].getDataAsString();
var data = Utilities.parseCsv(csv);
var a = data.length ;
var b = data[0].length;
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.openById('12ApSC0WVn1sZxb9VF6_CZR9L5xuGY5WHMLyyGMc').getSheetByName('IData');
sheet.getRange('A2:AM6026').clearContent();
var range = sheet.getRange(2,1, data.length,data[0].length);
range.setValues(data);
}
Loop over the attachments and get the filename. Quick edit to your existing code:
function getCSV() {
var myLabel = GmailApp.getUserLabelByName("I-Data New"); // specify label in gmail
var threads = myLabel.getThreads(0, 1);
var msgs = GmailApp.getMessagesForThreads(threads);
var attachments = msgs[0][0].getAttachments();
attachments.forEach(att => {
const name = att.getName()
if (name == "myFileName.csv") {
var data = Utilities.parseCsv(att.getDataAsString());
var sheet = SpreadsheetApp.openById('12ApSC0WVn1sZxb9VF6_CZR9L5xuGY5WHMLyyGMc').getSheetByName('IData');
sheet.getRange('A2:AM6026').clearContent();
var range = sheet.getRange(2, 1, data.length, data[0].length);
range.setValues(data);
}
})
}
I know there has been a lot said on the topic of a Master Sheet already. However as I haven't found the relevant answer to my question, I was hoping you could be so kind and help. The issue is very trivial I have a script that looks into the specific folder and grabs the data from those sheets. I just don't know how to modify it so that it doesn't retrieve the empty cells too ( due to the import range function sitting in the subfiles). So in the nutshell, it would be great if the code will only retrieve a range of data, for column "A" <> ""
function myFunction() {
var folder = DriveApp.getFolderById("xcv");
var filesInterator = folder.getFiles();
var file;
var fileType;
var ssID;
var combinedData = [];
var data;
while(filesInterator.hasNext()){
file = filesInterator.next();
fileType = file.getMimeType();
if(fileType === "application/vnd.google-apps.spreadsheet"){
ssID = file.getId();
data = getDataFromSpreadsheet(ssID);
combinedData = combinedData.concat(data);
} // if ends here
} // while loops ends here
Logger.log(combinedData.length);
var ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Master");
ws.getRange("A2:BK").clearContent();
ws.getRange(2,1,combinedData.length,combinedData[0].length).setValues(combinedData);
}
function getDataFromSpreadsheet(ssID) {
var ss = SpreadsheetApp.openById(ssID);
var ws = ss.getSheetByName("ABC");
var data = ws.getRange("A2:KB" + ws.getLastRow()).getValues();
return data;
}
Try this:
function getDataFromSpreadsheet(ssID) {
var ss = SpreadsheetApp.openById(ssID);
var ws = ss.getSheetByName("ABC");
var data = ws.getRange("A2:KB" + ws.getLastRow()).getValues().filter(r => r[0] != ''});
return data;
}
Array.filter()
I two spreadsheet Main and AddFiles wherein Add file has Two columns Subject and Attachments where under attachments is the list of excel file names with like file1.xlsx and file2.xlsx. Where I uploaded this file in my Google Drive under the Report folder.
I used the code below but always got an error on the last execution. It doesn't recognize the .getAs(MimeType.xlsx)
var sheet = SpreadsheetApp.getActiveSheet();
var dataRange = sheet.getRange(2,1,1,1)
data = dataRange.getValues()
var e = data[0][0]
for (var i = 0; i < (e-1); i++) {
draftmail();
}
function draftmail(){
var sheet = SpreadsheetApp.getActiveSheet();
var dataRange = sheet.getRange(1,1,1,1)
var data = dataRange.getValues()
var msg = data[0][0]
var sheet2 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("AddFiles");
var startRowx = 1
var numRowx = 1
var dataRangeTox = sheet.getRange(startRowx,3,numRowx,1)
var datax = dataRangeTox.getValues()
for (x in datax) {
var rowx = datax[x];
var to = rowx[0];
var Starta = 2 + i
var numRowa = 1
var dataRangeToa = sheet2.getRange(Starta,1,1,1)
var dataa = dataRangeToa.getValues()
for (a in dataa) {
var rowa = dataa[a];
var subject = rowa[0];
var Startb = 2 + i
var numRowb = 1
var dataRangeTob = sheet2.getRange(Startb,2,1,1)
var datab = dataRangeTob.getValues()
for (b in datab) {
var rowb = datab[b];
var datafile = rowb[0];
var file = DriveApp.getFilesByName(datafile)
var startRowy = 1
var numRowy = 1
var dataRangeToy = sheet.getRange(startRowy,4,numRowy,1)
var datay = dataRangeToy.getValues()
for (y in datay) {
var rowy = datay[y];
var carboncopy = rowy[0];
if (file.hasNext()){
GmailApp.createDraft(to,subject,msg,{ cc: carboncopy}, {
attachments: [file[0].getAs(MimeType.xlsx)],
})
}
}
}
}
}
}
Modification points:
Assuming that everything else works properly in your code, you should make the following changes:
cc and attachments should be passed as a single json object.
file[0] should be file.next().
MimeType.xlsx should be MimeType.MICROSOFT_EXCEL.
Solution:
GmailApp.createDraft(to,subject,msg,
{ cc: carboncopy,
attachments: [file.next().getAs(MimeType.MICROSOFT_EXCEL)]
})
References:
Class GmailApp
Google Apps Script: XLSX from Gmail to Google Sheets: invalid mime type. Content type seems to be application/octet?
Class FileIterator
When you call
file = DriveApp.getFilesByName(datafile)
it returns a FileIterator collection, which is not indexed like an array (file[0]) but rather requires you to call file.next() to get the next file.
In addition, the MimeType Enum for an .xlsx file is MimeType.MICROSOFT_EXCEL.
So change
attachments: [file[0].getAs(MimeType.xlsx)]
to this instead:
attachments: [file.next().getAs(MimeType.MICROSOFT_EXCEL)]