我正在开发一个简单的电子表格应用程序,供用户(工作同事)在年底提交绩效评估。我对他们能够通过一个按钮编辑电子表格A并将数据提交到电子表格B(数据库)感兴趣。问题在于电子表格B中的数据是私人/敏感的,因此必须与所有人共享才能解决。
我已经使代码正常工作,但是用户提交数据时收到警报。我猜这是因为他们没有共享电子表格B。他们正在收到此消息:“缺少文档X(也许它已被删除,或者您没有读取权限?)。”
//Displays spreadsheet use instructions.
function showInstructions() {
var ui = SpreadsheetApp.getUi().alert('IMPORTANTE: Haz una copia del documento marcado como (Template) y trabaja sobre ella. \n \n Instrucciones: \n 1. Renombra la copia que creaste como “RecursosHumanos-EvaluadorDeDesempeno-TuNombre. \n 2. Lee los comentarios de cada rubro a evaluar desplazando el cursor/mouse por su encabezado. \n 3. Evalúa a tus colegas. \n 4. Ingresa los datos en el menú BIMmx > Submit.');
}
//Displays thanks banner after submitting form.
function showThanks() {
var ui = SpreadsheetApp.getUi().alert('¡Gracias por participar!');
}
//Pops instructions and creates menus.
function onOpen() {
showInstructions();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menuButtons = [ {name: "Submit", functionName: "submit"} ];
ss.addMenu("BIMmx", menuButtons);
}
function submit() {
askName();
copyData();
showThanks();
clear();
}
//Asks for user name before submitting data to master sheet.
function askName() {
var ui = SpreadsheetApp.getUi();
//Display prompt.
var result;
var text = "";
while (text == ""){
result = ui.prompt(
'¡Completa la evaluación!',
'Ingresa tu nombre:',
ui.ButtonSet.OK_CANCEL);
// Process user's response.
var button = result.getSelectedButton();
text = result.getResponseText();
if (text == "")
ui.alert('Nombre no puede estar vacío.');
else if (button == ui.Button.OK) {
// User clicked "OK".
ui.alert('Tu nombre es ' + text + '.');
} else if (button == ui.Button.CANCEL) {
// User clicked "Cancel".
ui.alert('No entendí eso.');
} else if (button == ui.Button.CLOSE) {
// User clicked X in the title bar.
ui.alert('Cerraste el diálogo.');
}
}
fillUser(text);
}
//Fills rows with submitting username.
function fillUser(result) {
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
ss.getRange("K2").setValue(result);
var lr = ss.getLastRow();
var lc = ss.getLastColumn();
var fillDownRange = ss.getRange(2, lc, lr-1);
ss.getRange("K2").copyTo(fillDownRange);
}
//Backup data to master spreadsheet.
function copyData(result) {
var sss=SpreadsheetApp.getActive();
var dss=SpreadsheetApp.openByUrl('InsertYourURL'); //I would just open by id
var sh=sss.getSheetByName('Input');
var rg=sh.getRange(2,1,sh.getLastRow()-1,11);
var sData=rg.getValues();
var dsh=dss.getSheetByName('Output');
dsh.getRange(dsh.getLastRow()+1,1,sData.length,sData[0].length).setValues(sData);
}
//Clean sheet once submission is done.
function clear() {
var sheet = SpreadsheetApp.getActive().getSheetByName('Input');
sheet.getRange('A2:H').clearContent();
}
}
我正在完全复制该代码,可能与该问题无关。
很想听听有关如何解决此问题的任何想法。非常感谢!
答案 0 :(得分:1)
您可以创建一个实现了doPost()函数的Web应用程序[1],该脚本可以像对待您一样操作电子表格。发布Web应用程序时,需要将“将应用程序执行为:”选项设置为“我”。
在源电子表格的脚本中,您可以使用fetch()函数[2]发出发布请求,将请求从源工作表将数据作为字符串发送到Web应用程序,您只需将copyData函数更改为此:
function copyData(result) {
var sss=SpreadsheetApp.getActive();
var sh=sss.getSheetByName('Input');
var rg=sh.getRange(2,1,sh.getLastRow()-1,11);
var sData=rg.getValues().join(";");
var options = {
'method' : 'post',
'payload' : sData
};
UrlFetchApp.fetch('[Web App URL]', options);
}
在Web App脚本中,您将处理接收到的数据,首先将字符串转换为2D数组,然后编辑目标工作表。 doPost函数将如下所示:
function doPost(e) {
//Get the data from the fetch call
var sData = e.postData.contents;
//Convert string to a 1D array
var sData = sData.split(";");
//Convert 1D array to 2D array
for(var i=0; i<sData.length ; i++) {
sData[i] = sData[i].split(",");
}
//Use your spreadsheetID to get Output Sheet
var dss=SpreadsheetApp.openById('SPREADSHEET-ID'); //I would just open by id
var dsh=dss.getSheetByName('Output');
//Use setValues() function to put the 2D array into Sheet
dsh.getRange(dsh.getLastRow()+1,1,sData.length,sData[0].length).setValues(sData);
return ContentService.createTextOutput('');
}
我通过上述更改测试了您的代码,并在没有目标电子表格权限的情况下按预期工作了用户。
[1] https://developers.google.com/apps-script/guides/web
[2] https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app#fetch(String,Object)
答案 1 :(得分:0)
最后,在我的一个好朋友,显然是@AndresDuarte的帮助下,完成了它。谢谢!
答案是:构建一个Web应用程序,通过该应用程序发送数据,以便可以像仅由一个帐户发送数据一样对其进行标记(这样,它就不需要每个用户的编辑权限),并且包括一些JSON和Array解析以将字符串转换为矩阵。
这是脚本。
电子表格脚本
//Displays spreadsheet use instructions.
function showInstructions() {
var ui = SpreadsheetApp.getUi().alert('IMPORTANTE: Haz una copia del documento marcado como (Template) y trabaja sobre ella. \n \n Instrucciones: \n 1. Renombra la copia que creaste como “RecursosHumanos-EvaluadorDeDesempeno-TuNombre. \n 2. Lee los comentarios de cada rubro a evaluar desplazando el cursor/mouse por su encabezado. \n 3. Evalúa a tus colegas. \n 4. Ingresa los datos en el menú BIMmx > Submit.');
}
//Displays thanks banner after submitting form.
function showThanks() {
var ui = SpreadsheetApp.getUi().alert('¡Gracias por participar!');
}
//Pops instructions and creates menus.
function onOpen() {
showInstructions();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menuButtons = [ {name: "Submit", functionName: "submit"} ];
ss.addMenu("X", menuButtons);
}
function submit() {
askName();
copyData();
showThanks();
clear();
}
//Asks for user name before submitting data to master sheet.
function askName() {
var ui = SpreadsheetApp.getUi();
//Display prompt.
var result;
var text = "";
while (text == ""){
result = ui.prompt(
'¡Completa la evaluación!',
'Ingresa tu nombre:',
ui.ButtonSet.OK_CANCEL);
// Process user's response.
var button = result.getSelectedButton();
text = result.getResponseText();
if (text == "")
ui.alert('Nombre no puede estar vacío.');
else if (button == ui.Button.OK) {
// User clicked "OK".
ui.alert('Tu nombre es ' + text + '.');
} else if (button == ui.Button.CANCEL) {
// User clicked "Cancel".
ui.alert('No entendí eso.');
} else if (button == ui.Button.CLOSE) {
// User clicked X in the title bar.
ui.alert('Cerraste el diálogo.');
}
}
fillUser(text);
}
//Fills rows with submitting username.
function fillUser(result) {
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
ss.getRange("K2").setValue(result);
var lr = ss.getLastRow();
var lc = ss.getLastColumn();
var fillDownRange = ss.getRange(2, lc, lr-1);
ss.getRange("K2").copyTo(fillDownRange);
}
//Backup data to master spreadsheet.
function copyData() {
var sss=SpreadsheetApp.getActive();
var sh=sss.getSheetByName('Input');
var rg=sh.getRange(2,1,sh.getLastRow()-1,11);
var sData=rg.getValues().join(";");
//This is the Web App URL.
var url = "Enter you URL here";
var payload = {
"sData" : JSON.stringify(sData),
}
var options = {
"method" : "POST",
"payload" : payload,
"followRedirects" : true,
"muteHttpExceptions" : true,
};
var result = UrlFetchApp.fetch(url, options);
//Logger.log(JSON.parse(result));
}
//Clean sheet once submission is done.
function clear() {
var sheet = SpreadsheetApp.getActive().getSheetByName('Input');
sheet.getRange('A2:K').clearContent();
}
网络应用脚本
function doPost(e) {
var sData = JSON.parse(e.parameters.sData);
var response = {
"status" : "FAILED",
"sData" : sData,
};
sData = sData.split(";");
//Convert 1D array to 2D array
for(var i = 0; i < sData.length ; i++) {
sData[i] = sData[i].split(",");
}
//Use your spreadsheetID to get Output Sheet
var dss=SpreadsheetApp.openById('Enter your ID here.');
var dsh=dss.getSheetByName('Output');
//Use setValues() function to put the 2D array into Sheet
dsh.getRange(dsh.getLastRow()+1,1,sData.length,sData[0].length).setValues(sData);
MailApp.sendEmail("Enter your email here","New Response","A new response has been registered.");
var response = {
"status" : "SUCCESS",
"sData" : sData,
};
return ContentService.createTextOutput(JSON.stringify(response));
}