我有以下脚本从电子表格中取一行a,如果列名匹配,则替换文档中的占位符。我使用%placeHolder%
格式。 replaceText()
方法工作正常,但如果该字段为空,我怎样才能将占位符替换为空白或“N / A”?我尝试过几条不同的路线,但可能会遗漏一些简单的路线。
function formatTemplate(){
var postFlightTemplate = DocsList.getFileById('templateKey').makeCopy().getId();
var template = DocumentApp.openById(postFlightTemplate);
var templateHeader = template.getHeader();
var templateBody = template.getActiveSection();
var flightLog = SpreadsheetApp.openById('spreadsheetKey');
var sheet = flightLog.getSheetByName('Flight Tracking');
var data = ScriptsLib.getRowsData(sheet, sheet.getRange('A2:2'), 1);
var keys = ScriptsLib.getKeys(data[0]);
for (var key in keys){
Logger.log('key:'+keys[key]+' / value:'+data[0][keys[key]]);
if (data[0][keys[key]] != null || data[0][keys[key]] != ''){
templateHeader.replaceText('%'+keys[key]+'%', data[0][keys[key]]);
templateBody.replaceText('%'+keys[key]+'%', data[0][keys[key]]);
}else{
Logger.log('empty key:'+keys[key]+' / value:'+data[0][keys[key]]);
templateBody.replaceText('%'+keys[key]+'%', 'N/A');
}
}
template.setName('RR-'+data[0].incidentNumber+'-'+data[0].flightNumber);
template.saveAndClose();
MailApp.sendEmail('email@email.com', 'Post Flight Report','See Run Report', {name: 'P1AR Flight Log', attachments: template});
}
答案 0 :(得分:2)
您可以查看代码的以下部分,并在几行末尾添加两条评论:
for (var key in keys){
Logger.log('key:'+keys[key]+' / value:'+data[0][keys[key]]);
if (data[0][keys[key]] != null || data[0][keys[key]] != undefined){ // I changed this to undefined
templateHeader.replaceText('%'+keys[key]+'%', data[0][keys[key]]);
templateBody.replaceText('%'+keys[key]+'%', data[0][keys[key]]);
}else{
Logger.log('empty key:'+keys[key]+' / value:'+data[0][keys[key]]);
templateHeader.replaceText('%'+keys[key]+'%', 'N/A'); // I added this row
templateBody.replaceText('%'+keys[key]+'%', 'N/A');
}
}
答案 1 :(得分:2)
你没有说,但显然你正在使用一个库,“ScriptsLib”。我已完成搜索,但无法找到同时使用getRowsData
和getKeys
方法的公共代码,因此它可能是私有库。
我需要猜测这两个函数的作用。如果您可以从ScriptsLib中为它们提供源代码,那么将有助于验证或修改我的猜测,其中包括:
getKeys
类似于function of the same name in Class UserProperties。 getRowsData
方法通过调用getObjects
创建一个对象数组。 getObjects
方法迭代给定范围,创建一个具有每行命名属性的对象数组。 如果一行中有空白单元格,则不会有该列名称的属性。
在代码中,循环遍历data[0]
中包含的密钥,当源数据中存在空白时,由于getObjects
的工作方式,这些密钥将不完整(缺少属性)。这意味着您永远不会真正处理空白,并且没有机会用“N / A”替换相关的键。
您需要做的是循环模板文档中的键值 - 这些可能由电子表格中的标题表示。 (......归一化到camelCase之后,就是这样)。
var keys = ScriptsLib.normalizeHeaders(sheet.getRange('A1:1').getValues()[0]);
这将为我们提供迭代的完整密钥列表。但是我们还没有完成。
你的逻辑中有一个错误,检查你是否有财产。看看这一行:
if (data[0][keys[key]] != null || data[0][keys[key]] != ''){
在那里使用OR运算符,最终将执行IF块
data[0][keys[key]]
为空。你已经编写了一个else子句,它应该用“N / A”代替一个键,但它不会被执行。
:: when data[0][keys[key]] == null
data[0][keys[key]] != null :: false
data[0][keys[key]] != '' :: true (because null != '')
您可能打算使用AND。
if (data[0][keys[key]] != null && data[0][keys[key]] != ''){
应该让事情按照你想要的方式运作。但我建议明确处理数据对象不具有具有特定键名的属性的可能性,并同时解决该问题和/或错误。 JavaScript为我们提供了hasOwnProperty()
。
if (data[0].hasOwnProperty(keys[key])) // property is present
重构的代码变为:
function formatTemplate(){
var postFlightTemplate = DocsList.getFileById('templateKey').makeCopy().getId();
var template = DocumentApp.openById(postFlightTemplate);
var templateHeader = template.getHeader();
var templateBody = template.getActiveSection();
var flightLog = SpreadsheetApp.openById('spreadsheetKey');
var sheet = flightLog.getSheetByName('Flight Tracking');
var data = ScriptsLib.getRowsData(sheet, sheet.getRange('A2:2'), 1);
var keys = ScriptsLib.normalizeHeaders(sheet.getRange('A1:1').getValues()[0]);
for (var key in keys){
if (data[0].hasOwnProperty(keys[key])) { // property is present
Logger.log('key:'+keys[key]+' / value:'+data[0][keys[key]]);
templateHeader.replaceText('%'+keys[key]+'%', data[0][keys[key]]);
templateBody.replaceText('%'+keys[key]+'%', data[0][keys[key]]);
}else{
Logger.log('empty key:'+keys[key]+' / value:'+data[0][keys[key]]);
templateBody.replaceText('%'+keys[key]+'%', 'N/A');
}
}
template.setName('RR-'+data[0].incidentNumber+'-'+data[0].flightNumber);
template.saveAndClose();
MailApp.sendEmail('email@email.com', 'Post Flight Report','See Run Report', {name: 'P1AR Flight Log', attachments: template});
}