![](/img/trans.png)
[英]Can I create a function in Google Sheets and use it from a web app Google Apps Script?
[英]How can I update a progress meter in Google Apps script in a Google Sheets project after running another function that the meter is supposed to track
我有一個從 Google 表格調用的 Google Apps 腳本。 .GS 文件調用 .HTML 表單。 我試圖測試一個 forLoop 和一個異步函數可以一個接一個地運行。 我有一個先前的問題,但它被標記為重復數據刪除來此,即使這個問題不解決我的問題,也沒有解決實際問題,其實只是指還沒有回答這個問題的鏈接。
我的 gs 文件按原樣調用該函數。 表格向我們展示了它應該的樣子,但它沒有打印出警報。
有沒有辦法做到這一點?
如果沒有,我們如何在 Google Sheets 中擁有一個 Google Apps 腳本,它可以運行一個函數並通過像 flow-meter.js 這樣的 JavaScript 庫顯示所述函數的進度表( fiddle here )fluid-meter.js 的教程是這里
此外,它確實有效,只是在其他一切都運行之后; 我希望它與另一個函數異步運行。
function callForm() { //Call the HTML file and set the width and height //var html = HtmlService.createHtmlOutputFromFile("tracker_form") var html = HtmlService.createHtmlOutputFromFile("test_async") .setWidth(450) .setHeight(300); //Display the dialog var dialog = SpreadsheetApp.getUi().showModalDialog(html, "Select the relevant draft"); }
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <link href="https://fonts.googleapis.com/css?family=Oxygen|Raleway&display=swap" rel="stylesheet"> <base target="_top"> <!--<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">--> <link rel="stylesheet" href="https://drive.google.com/uc?export=view&id=1iKnmVGSAh70SSwzLERkTdcYT85cpJeWH"> <!-- <script src="https://code.jquery.com/jquery-1.12.4.js"></script> --> <script src="https://drive.google.com/uc?export=view&id=1iFtElfW5_mtWZpEDHdoE9zPYRaMmGO1y"></script> </head> <body> <br> <h3>This is the body</h3> </body> <script> async function calc2(i, j) { return i + j; } async function useForLoop() { let total = 0; for (let i = 0; i <= 10000; i++) { for (let j = i; j > 0; j--) { total += await calc2(i, j); } } alert("total is: "+total); return total; } </script> </html>
信不信由你,我終於成功了……這是我的工作代碼。
控制台中的輸出是這樣的——
calc2 is: 106
total is: 509535
calc2 is: 105
total is: 509640
calc2 is: 104
total is: 509744
...
在 .gs 文件中:
function callForm() { //Call the HTML file and set the width and height //var html = HtmlService.createHtmlOutputFromFile("tracker_form") var html = HtmlService.createHtmlOutputFromFile("test_async") .setWidth(450) .setHeight(300); //Display the dialog var dialog = SpreadsheetApp.getUi().showModalDialog(html, "Select the relevant draft"); }
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <link href="https://fonts.googleapis.com/css?family=Oxygen|Raleway&display=swap" rel="stylesheet"> <base target="_top"> <!--<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">--> <link rel="stylesheet" href="https://drive.google.com/uc?export=view&id=1iKnmVGSAh70SSwzLERkTdcYT85cpJeWH"> <!-- <script src="https://code.jquery.com/jquery-1.12.4.js"></script> --> <script src="https://drive.google.com/uc?export=view&id=1iFtElfW5_mtWZpEDHdoE9zPYRaMmGO1y"></script> </head> <body > <br> <h3 >This is the body</h3> <button type="button" onclick="printRestults();">test</button> </body> <script> var returntotal async function calc2(i, j) { var x = i + j; console.log("calc2 is: "+x); return i + j; } async function useForLoop() { let total = 0; for (let i = 0; i <= 100; i++) { for (let j = i; j > 0; j--) { total += await calc2(i, j); console.log("total is: "+total); } } returntotal = total; } function printRestults(){ useForLoop(); console.log("returntotal is: "+returntotal); } </script> </html>
更新:此答案僅適用於未嵌套的函數。 以這種方式,我不能將它用於我的原始項目。 下面是——
GS。 文件 -
function showDraftResults(passingbackinfo){
passingbackinfo = passingbackinfo.replace(/\\/g, "");
passingbackinfo = passingbackinfo.replace(/"/g, '\'');
passingbackinfo = passingbackinfo.replace(/''/g, '\'');
passingbackinfo = passingbackinfo.replace(/'/g, "");
var mydraftId='';
var mysendEmail='';
var mysendname='';
var myreplytoemail='';
passingbackinfo = passingbackinfo.split(';');
for(var a in passingbackinfo ) {
mydraftId = passingbackinfo[a-3];
mysendEmail = passingbackinfo[a-2];
mysendname = passingbackinfo[a-1];
myreplytoemail = passingbackinfo[a]
};
sendMail(mydraftId,mysendEmail,mysendname,myreplytoemail,'UA-123456789-1');
}
function sendMail(draftId,sendEmail,sendName,replyTo,analyticsID) {
var sendName = sendName;
var replyTo = replyTo;
var analyticsID = analyticsID;
var draft = GmailApp.getMessageById(draftId);
var draftCC = draft.getCc();
var draftBCC = draft.getBcc()
var subject = draft.getSubject();
var body = draft.getBody();
var email_to_send = sendEmail;
formattedEmails (email_to_send,subject,body,analyticsID,sendName,replyTo,draftCC,draftBCC);
}
function formattedEmails (email_to_send,subject,body,analyticsID,sendName,replyTo,draftCC,draftBCC){
var newbody = '';
var imgURL = "https://ssl.google-analytics.com/collect?"
+ "v=1&t=event"
+ "&tid=" + analyticsID
+ "&z=" + Math.round((new Date()).getTime()/1000).toString()
+ "&cid=" + Utilities.getUuid()
+ "&ec=" + encodeURIComponent("Email Open")
+ "&ea=" + encodeURIComponent(subject.replace(/'/g, ""))
+ "&el=" + encodeURIComponent(email_to_send);
var imgLink = "<img src='" + imgURL + "' width='1' height='1'/>";
newbody = body;
newbody += imgLink
GmailApp.sendEmail(
email_to_send,
subject,
newbody,
{htmlBody: newbody, cc: draftCC, bcc: draftBCC, name: sendName, replyTo: replyTo}
);
newbody = '';
//console. clear();
}
html文件——
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link href="https://fonts.googleapis.com/css?family=Oxygen|Raleway&display=swap" rel="stylesheet">
<base target="_top">
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<style>
fieldset {
border: 0;
}
label {
display: block;
margin: 30px 0 0 0;
}
.overflow {
height: 200px;
}
</style>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script>
$( function() {
$( "#List" ).selectmenu();
$( "#groupList").selectmenu();
$( "#sendname").autocomplete();
$( "#replyto").autocomplete();
$( "#fluid-meter-3" ).text;
} );
</script>
</head>
<body onload="addList();addGroupList();">
<div>
<form id="Form" action="#" >
<fieldset>
<div class="masterForm">
<select id="List" name="draftList">
<option>...</option>
</select>
<h3 id="result">Choose a Draft</h3>
<br/>
<br/>
<select id="groupList" name="groupdraftList">
<option>...</option>
</select>
<h3 id="groupresult">Choose a Group</h3>
<br/>
<br/>
<input type="text" id="sendname" name="sendname" title="type "a"" class="ui-autocomplete-input" autocomplete="off" value="Team">
<h3 style="height:10px;">Enter Send As Name</h3>
<hr style="height:10px; visibility:hidden;" />
<br/>
<br/>
<input type="text" id="replyto" name="replyto" title="type "a"" class="ui-autocomplete-input" autocomplete="off" value="team@team.com">
<h3 style="height:10px;">Enter Reply To EMail</h3>
<hr style="height:10px; visibility:hidden;" />
<br/>
<br/>
<button class="ui-button ui-corner-all ui-widget" type="button" onclick="updateAndSend();">Send Email to Selected Group</button>
</div>
<br/>
<br/>
<div class="container" >
<div class="row">
<div class="col text-center">
<div class="col text-center">
<div id="fluid-meter-3"></div>
</div>
</div>
</div>
</div>
</fieldset>
</form>
</div>
</body>
<script src="https://bootstrap-4-1-1.min.css"></script>
<script src="js/js-fluid-meter.js"></script>
<script>
var returnsendasname;
var returnreplyto;
var returndraftid;
var returngroupid;
var returnemails_split = [];
var returncountemails;
var fluidpercent = 0;
function GetSelectedDraft(){
var e = document.getElementById("List");
var selectedOption = e.options[e.selectedIndex];
document.getElementById("result").innerHTML = selectedOption.text;
returndraftid = selectedOption.value;
}
function GetSelectedGroup(){
var e = document.getElementById("groupList");
var selectedOption = e.options[e.selectedIndex];
document.getElementById("groupresult").innerHTML = selectedOption.text;
returngroupid = selectedOption.value;
}
function GetSendAsName(){
var name = document.getElementById("sendname");
returnsendasname = name.value;
}
function GetReplyToEmail(){
var emailname = document.getElementById("replyto");
returnreplyto = emailname.value;
}
function addList()
{
google.script.run.withSuccessHandler(writeList).withFailureHandler(onFailure).getDraftId();
}
function addGroupList()
{
google.script.run.withSuccessHandler(writeGroupList).withFailureHandler(onFailure).getGroups();
}
function writeList(options)
{
options = options.sort(function(a, b){
if(a.subject < b.subject) return -1;
if(a.subject == b.subject) return 0;
return 1;
});
var dropdown = $("#List");
dropdown.empty();
for(var i = 0, numOptions = options.length; i < numOptions; ++i)
{
dropdown.append('<option value="' + options[i].id + '">' + options[i].subject + '</option>');
}
}
function writeGroupList(options)
{
options = options.sort(function(a, b){
if(a.group < b.group) return -1;
if(a.group == b.group) return 0;
return 1;
});
var groupdropdown = $("#groupList");
groupdropdown.empty();
for(var i = 0, numOptions = options.length; i < numOptions; ++i)
{
groupdropdown.append('<option value="' + options[i].emails + '">' + options[i].group + '</option>');
}
}
var fm3 = new FluidMeter();
fm3.init({
targetContainer: document.getElementById("fluid-meter-3"),
fillPercentage: fluidpercent,
options: {
fontSize: "30px",
drawPercentageSign: false,
drawBubbles: false,
size: 300,
borderWidth: 19,
backgroundColor: "#0C0C0C",
foregroundColor: "#EBEBEB",
foregroundFluidLayer: {
fillStyle: "#0F98DC",
angularSpeed: 30,
maxAmplitude: 8,
frequency: 30,
horizontalSpeed: -20
},
backgroundFluidLayer: {
fillStyle: "#0061AC",
angularSpeed: 100,
maxAmplitude: 7,
frequency: 22,
horizontalSpeed: 20
}
}
});
function sleep(milliseconds) {
const date = Date.now();
let currentDate = null;
do {
currentDate = Date.now();
} while (currentDate - date < milliseconds);
}
function GetEmailCount(){
var emails_to_send = returngroupid;
var emails_split = emails_to_send.split(',');
let count_Emails = 0;
for (let j = 0; j < emails_split.length; j++) {
count_Emails++;
}
returncountemails = count_Emails;
}
function GetEmailsToSend(){
var emails_to_send = returngroupid;
var emails_split = emails_to_send.split(',');
returnemails_split = emails_split;
//alert('Getting Emails to Send: '+returnemails_split);
}
function updateAndSend(){
// sets the returngroupid
GetSelectedGroup();
// sets the returnemails_split
GetEmailsToSend();
//alert('returnemails_split: '+returnemails_split[0]);
returnemails_split.forEach(myFunction);
function myFunction(item, index, arr){
packageupresults(item);
alert('SetPercentage Index: '+index);
fm3.setPercentage(Math.floor((index/returnemails_split.length) * 100));
}
alert('Emails Sent, you can close the app');
}
function packageupresults(details)
{
// sets the returnsendasname
GetSendAsName();
// sets the returnreplyto
GetReplyToEmail();
// sets the returndraftid
GetSelectedDraft();
// sets the returncountemails
GetEmailCount();
var emails_split = details;
emails_split = emails_split.replace(/^\s*/, "").replace(/\s*$/, "");
var mysendname = JSON.stringify(returnsendasname);
var myreplytoemail= JSON.stringify(returnreplyto);
var mydraftid = JSON.stringify(returndraftid);
var mysendemail = JSON.stringify(emails_split)
var passingbackinfo = mydraftid+';'+mysendemail+';'+mysendname+';'+myreplytoemail
passingbackinfo = JSON.stringify(passingbackinfo)
google.script.run.showDraftResults(passingbackinfo)
return true;
}
function onFailure(err)
{
alert('There was an error!' + err.message);
}
addList();
</script>
<html>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.