我一直在寻找这个问题的答案,但到目前为止还没能把答案拼凑起来。请以非常简单的方式解释您的任何答案,因为我对GAS和RegEx相当新。我已经掌握了大部分语法,但在GAS中执行它会给我带来困难。
基本上,我想编写一个脚本,在编辑电子表格时,检查哪些行尚未合并。然后,在这些行上创建模板Google Doc的副本,并根据电子表格数据命名文档。从那里(这是困难的部分),我需要它用模板中的数据替换模板中的合并标签。
我将使用的模板中的代码如下所示:<<mergeTag>>
我的想法是匹配整个代码,并将其替换为列中存在的电子表格中的数据,其名称与&#34; <<>>
&#34;中的内容相同。 。例如:<<FooBar>>
将替换为名为FooBar
的列中的数据。显然,它来自当前行需要合并。
之后,剩下的就是发送一封电子邮件(还有一些特定于行的个性化),附上该文件(有时是PDF格式),邮件正文来自其他地方的HTML文件该项目。
这是我到目前为止所做的全部事情(请注意我在这里和那里的占位符,我可以为我使用的每个电子表格进行个性化):
function onEdit() {
//SPREADSHEET GLOBAL VARIABLES
var ss = SpreadsheetApp.getActiveSpreadsheet();
//get only the merge sheet
var sheet = ss.getSheetByName("Merge Data");
//get all values for later reference
var range = sheet.getActiveRange();
var values = range.getValues();
var lastRow = range.getLastRow();
var lastColumn = range.getLastColumn();
//get merge checker ranges
var urlColumn = range.getLastColumn();
var checkColumn = (urlColumn - 1);
var checkRow = range.getLastRow();
var checkRange = sheet.getRange(2, checkColumn, checkRow);
var check = checkRange.getBackgrounds();
//get template determination range (unique to each project)
var tempConditionRange = sheet.getRange(row, column);
var tempConditionCheck = tempConditionRange.getValues();
//set color variables for status cell
var red = "#FF0000";
var yellow = "#FFCC00";
var green = "#33CC33";
//////////////////////////////////////////////////////////
//DOC GLOBAL VARIABLES
var docTemplate1 = DriveApp.getFileById(id);
var docTemplate2 = DriveApp.getFileById(id);
var docTemplate3 = DriveApp.getFileById(id);
var folderDestination = DriveApp.getFolderById(id);
//////////////////////////////////////////////////////////
//EMAIL GLOBAL VARIABLES
var emailTag = ss.getRangeByName("Merge Data!EmailTag");
var personalizers = "";
var subject = "" + personalizers;
var emailBody = HtmlService.createHtmlOutputFromFile("Email Template");
//////////////////////////////////////////////////////////
// MERGE CODE
for (i = 0; i < check.length; i++) {
//for rows with data, check if they have already been merged
if (check[i] == green) {
continue;
} else {
var statusCell = sheet.getRange((i+2), checkColumn, 1, 1);
var urlCell = sheet.getRange((i+2), urlColumn, 1, 1);
var dataRow = sheet.getRange((i+2), 1, lastRow, (lastColumn - 2))
statusCell.setBackground(red);
//for rows with data, but not yet merged, perform the merge code
//////////////////////////////////////////////////////////
//DOC CREATION
//Determine which template to use
if (tempConditionCheck[i] == "") {
var docToUse = docTemplate1;
}
if (tempConditionCheck[i] == "") {
var docToUse = docTemplate2;
}
if (tempConditionCheck[i] == "") {
var docToUse = docTemplate3;
}
//Create a copy of the template
//Rename the document using data from specific columns, at specific rows
//Move the doc to the correct folder
var docName = "";
var docCopy = docToUse.makeCopy(docName, folderDestination);
var docId = docCopy.getId();
var docURL = docCopy.getUrl();
var docToSend = DriveApp.getFileById(docId);
var docBody = DocumentApp.openById(docId).getBody();
这是我需要帮助的地方
//Locate the Merge Tags
//Match Merge Tags to the column headers of the same name
//Replace the Merge Tags with the data from the matched column, from the correct row
function tagReplace() {
var tagMatch = "/(<{2}(\w+)>{2})/g";
}
statusCell.setBackground(yellow);
urlCell.setValue(docURL);
其余的只是完成了这个过程
//////////////////////////////////////////////////////////
//EMAIL CREATION
//Create an email using an HTML template
//Use Merge Tags to personalize email
//Attach the doc we created to the email
//Send email to recipients based on data in the sheet
MailApp.sendEmail(emailTag, subject, emailBody, {
name: "Person McPerson",
attachments: [docToSend], //[docToSend.getAs(MIME.PDF)],
html: emailBody,
});
//////////////////////////////////////////////////////////
//CHECK ROW UPDATE
statusCell.setBackground(green);
}
}
}
我的工作表都有一个冻结的第一行作为标题行。我的所有列都将始终与标记完全相同(减去<<>>
)。
如何将标签与数据匹配?
修改
```````````````````
当我将其插入到我的代码中时,解决方案无法正常工作,如下所示:
function formMerge() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Merge Data");
var urlColumn = sheet.getMaxColumns();
var checkColumn = urlColumn - 1;
var lastRow = ss.getSheetByName("Form Responses").getLastRow();
var values = sheet.getDataRange().getValues();
var headers = values[0];
var urlRange = sheet.getRange(2, urlColumn, lastRow);
var checkRange = sheet.getRange(2, checkColumn, lastRow);
var check = checkRange.getBackgrounds();
var red = "#ff0404";
var yellow = "#ffec0a";
var green = "#3bec3b";
var docTemplate = DriveApp.getFileById(id);
var folderDestination = DriveApp.getFolderById(id);
// MERGE CODE
for (i = 0; i < check.length; i++) {
if (check[i] == green) {
continue;
} else {
var statusCell = sheet.getRange((i+2), checkColumn, 1, 1);
var urlCell = sheet.getRange((i+2), urlColumn, 1, 1);
var dataRow = sheet.getRange((i+2), 1, 1, (urlColumn - 2)).getValues();
var clientNameRange = sheet.getRange((i+2), 3);
var clientName = clientNameRange.getValue();
var dateRange = sheet.getRange((i+2), 2);
var datePreFormat = dateRange.getValue();
var timeZone = CalendarApp.getTimeZone();
var date = Utilities.formatDate(new Date(datePreFormat), timeZone, "MM/dd/yyyy");
statusCell.setBackground(red);
//EMAIL VARIABLES
var personalizers = clientName;
var subject = "Post Intake Report for " + personalizers;
var emailBody = "Please see the attached Google Doc for the Post Intake Report for " + clientName + ". The intake was performed on " + date + ".";
var emailTagRange = sheet.getRange((i+2), 24);
var emailTagValue = emailTagRange.getValue();
var emailTag = emailTagValue.split(", ");
//DOC CREATION
var docToUse = docTemplate;
var docName = "Post Intake Report - " + clientName + " [" + date + "]";
var docCopy = docToUse.makeCopy(docName, folderDestination);
var docId = docCopy.getId();
var docURL = docCopy.getUrl();
var docBody = DocumentApp.openById(docId).getBody().editAsText();
for (var j=0; j<headers.length; j++) {
var re = new RegExp("(<<"+headers[j]+">>)","g");
docBody.replaceText(re, dataRow[j]);
}
statusCell.setBackground(yellow);
urlCell.setValue(docURL);
//EMAIL CREATION
MailApp.sendEmail(emailTag, subject, emailBody, {
name: "Christopher Anderson",
attachments: [docCopy],
html: emailBody
});
statusCell.setBackground(green);
}
}
}
答案 0 :(得分:1)
使用电子表格中的标题值动态为每个标记构建RegExp。
使用Body.replaceText()
执行替换。
var values = sheet.getDataRange().getValues();
var headers = values[0];
...
// Loop over all columns. Use header names to search for tags.
for (var col=0; col<headers.length; col++) {
// Build RegExp using column header
var re = new RegExp("(<{2}"+headers[col]+">{2})","g");
// Replace tags with data from this column in dataRow
body.replaceText(re, dataRow[col]);
}
此代码段将在单行上运行;前几个声明应出现在行循环之外。然后在创建并打开新文档后完成列循环,并获取body
对象。
它遍历电子表格中的所有列,使用标题名称查找您定义的标记,并将其替换为当前行的相应单元格内容。