我正在编写一个用于谷歌电子表格的脚本。我希望脚本循环显示URL的电子表格。当它循环时,该函数应调用一个UI实例,该UI实例显示url链接并接收有关url为'current'或'expired'的用户输入,并将其标记为电子表格。
理想情况下,在用户选择一个选项后,单击“下一步”按钮,该URL的对话框将关闭,下一个URL的对话框将打开。
代码如下。
function getUrlsToCheck(){
/**
* Asks user to input range of urls to check.
*/
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getSheets()[0];
// Prompt the user for the range with the starting row and ending row.
var rowStart = Browser.inputBox('Starting Entry',
'Please enter the starting row of the urls you want to check' +
' (for example, "1"):',
Browser.Buttons.OK_CANCEL);
if (rowStart == 'cancel') {
return;
}
var rowNumber1 = Number(rowStart);
if (isNaN(rowNumber1) || rowNumber1 < 2 ||
rowNumber1 > spreadsheet.getLastRow()) {
Browser.msgBox('Error',
Utilities.formatString('Row "%s" is not a valid starting point.', rowStart),
Browser.Buttons.OK);
return;
}
var rowEnd = Browser.inputBox('Ending Entry',
'Please enter the ending row of the urls you want to check' +
' (for example, "56"):',
Browser.Buttons.OK_CANCEL);
if (rowEnd == 'cancel') {
return;
}
var rowNumber2 = Number(rowEnd);
if (isNaN(rowNumber2) || rowNumber2 < rowNumber1 || rowNumber1 == rowNumber2) {
Browser.msgBox('Error',
Utilities.formatString('Row "%s" is not a valid ending point.', rowEnd),
Browser.Buttons.OK);
return;
}
var numOfRowsToCheck = (rowNumber2 - rowNumber1);
var range = sheet.getRange(rowNumber1, 1, (numOfRowsToCheck + 1), 1);
var data = range.getValues();
/*
*Loop to retrieve URLs and show a link in the Ui instance
*/
for(var i = 0; i < data.length; i++) {
var activeRow = (Number(i) + rowNumber1);
var range4 = sheet.getRange(activeRow, 4);
var range5 = sheet.getRange(activeRow, 5);
var app = UiApp.createApplication().setHeight(150).setWidth(250);
app.setTitle("Check URL");
var link1 = app.createAnchor('Check', data[i]);
var panel = app.createVerticalPanel();
var infoLabel = app.createLabel(Utilities.formatString('Check the link for entry %s', activeRow)).setId('infoLabel');
var infoLabel1 = app.createLabel('').setId('infoLabel1');
var current = app.createRadioButton("group", "Current").setName('current').setId('current');
var expired = app.createRadioButton("group", "Expired").setName('expired').setId('expired');
var hidden = app.createHidden("yourObject", Utilities.jsonStringify(activeRow));
var handler = app.createServerChangeHandler('current');
handler.addCallbackElement(panel).addCallbackElement(hidden);
current.addClickHandler(handler);
var handler2 = app.createServerChangeHandler('expired');
handler2.addCallbackElement(panel).addCallbackElement(hidden);
expired.addClickHandler(handler2);
var next = app.createButton('Next').setId('next');
var handler3 = app.createServerHandler('next');
handler3.addCallbackElement(panel);
next.addClickHandler(handler3);
panel.setSpacing(5);
panel.add(infoLabel);
panel.add(link1);
panel.add(current);
panel.add(expired);
panel.add(infoLabel1);
panel.add(next);
app.add(panel);
spreadsheet.show(app);
}
}
function next(e){
var app = UiApp.getActiveApplication();
app.close();
return app;
}
function current(e){
var app = UiApp.getActiveApplication();
app.getElementById('expired').setValue(false);
var yourObj = Utilities.jsonParse(e.parameter.yourObject);
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getSheets()[0];
var range4 = sheet.getRange(yourObj, 4);
var range5 = sheet.getRange(yourObj, 5);
range4.setValue('x');
range5.setValue('');
app.getElementById('infoLabel1').setText('This link has been marked current');
return app;
}
function expired(e){
var app = UiApp.getActiveApplication();
app.getElementById('current').setValue(false);
var yourObj = Utilities.jsonParse(e.parameter.yourObject);
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getSheets()[0];
var range4 = sheet.getRange(yourObj, 4);
var range5 = sheet.getRange(yourObj, 5);
range4.setValue('');
range5.setValue('x');
app.getElementById('infoLabel1').setText('This link has been marked expired');
return app;
}
我遇到的问题是循环循环,没有足够的时间来接受加载用户信息的对话框;所以你只能看到最后一个网址的对话框。
我尝试了几件事,因为他们没有工作,我必须做错了。
我尝试插入系统暂停。
我也试过让函数成为生成函数,但是 yield命令没有正确编译。
我也尝试过使用do while循环而不是for循环。该
条件是否与下一个按钮是否相关
禁用。
关于如何在循环结束前让函数的每一步都执行的任何建议?
答案 0 :(得分:1)
此代码的问题在于,它会同时创建所有对话框,但只有在完成第一个对话框后才能创建对话框。重写很多东西可能会更好,但是对于这个演示,我只是将你的代码转换为能够同步运行。
因此,您不必在for
中的getUrlsToCheck
循环中,而是在回调处理程序next
中创建对话框。这确实意味着我们必须基本上做出recursive call种类。我们还必须跟踪i
并传递它。为了使对代码的编辑最小化,我将getUrlsToCheck
中的大部分代码移出到一个函数,该函数从参数i
,rowNumber1
和rowNumber2
初始化所需的数据,打开对话框。
我还在verify
中添加了一些代码,用于将数据i+1
,rowNumber1
和rowNumber
传递给next
处理程序。在next
中,我们使用传递的处理程序的已解析JSON调用verify
。
最后,为了开始循环,我们通过verify
,getUrlsToCheck
和rowNumber1
传递rowNumber2
中的i=0
。
所以代码看起来像
function getUrlsToCheck() {
/**
* Asks user to input range of urls to check.
*/
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getSheets()[0];
// Prompt the user for the range with the starting row and ending row.
var rowStart = Browser.inputBox('Starting Entry',
'Please enter the starting row of the urls you want to check' +
' (for example, "1"):',
Browser.Buttons.OK_CANCEL);
if (rowStart == 'cancel') {
return;
}
var rowNumber1 = Number(rowStart);
if (isNaN(rowNumber1) || rowNumber1 < 2 ||
rowNumber1 > spreadsheet.getLastRow()) {
Browser.msgBox('Error',
Utilities.formatString('Row "%s" is not a valid starting point.', rowStart),
Browser.Buttons.OK);
return;
}
var rowEnd = Browser.inputBox('Ending Entry',
'Please enter the ending row of the urls you want to check' +
' (for example, "56"):',
Browser.Buttons.OK_CANCEL);
if (rowEnd == 'cancel') {
return;
}
var rowNumber2 = Number(rowEnd);
if (isNaN(rowNumber2) || rowNumber2 < rowNumber1 || rowNumber1 == rowNumber2) {
Browser.msgBox('Error',
Utilities.formatString('Row "%s" is not a valid ending point.', rowEnd),
Browser.Buttons.OK);
return;
}
var numOfRowsToCheck = (rowNumber2 - rowNumber1);
/*
*Moved everything to function verify();
*/
verify({
i: 0,
rowNumber1: rowNumber1,
rowNumber2: rowNumber2
})
}
function verify(myObj) {
//gets variable from passed json obj
var i = myObj.i
var rowNumber1 = myObj.rowNumber1
var rowNumber2 = myObj.rowNumber2
//mostly the same
var activeRow = (Number(i) + rowNumber1);
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getSheets()[0];
var numOfRowsToCheck = (rowNumber2 - rowNumber1);
var range = sheet.getRange(rowNumber1, 1, (numOfRowsToCheck + 1), 1);
var data = range.getValues();
var range4 = sheet.getRange(activeRow, 4);
var range5 = sheet.getRange(activeRow, 5);
if (i < data.length) {
var app = UiApp.createApplication().setHeight(150).setWidth(250);
app.setTitle("Check URL");
var link1 = app.createAnchor('Check', data[i]);
var panel = app.createVerticalPanel();
var infoLabel = app.createLabel(Utilities.formatString('Check the link for entry %s', activeRow)).setId('infoLabel');
var infoLabel1 = app.createLabel('').setId('infoLabel1');
var current = app.createRadioButton("group", "Current").setName('current').setId('current');
var expired = app.createRadioButton("group", "Expired").setName('expired').setId('expired');
var hidden = app.createHidden("yourObject", Utilities.jsonStringify(activeRow));
var handler = app.createServerChangeHandler('current');
handler.addCallbackElement(panel).addCallbackElement(hidden);
current.addClickHandler(handler);
var handler2 = app.createServerChangeHandler('expired');
handler2.addCallbackElement(panel).addCallbackElement(hidden);
expired.addClickHandler(handler2);
//added this to pass state to next()
var hidden = app.createHidden("yourObject", Utilities.jsonStringify({
i: i + 1, //increment i
rowNumber1: rowNumber1,
rowNumber2: rowNumber2
}));
var next = app.createButton('Next').setId('next');
var handler3 = app.createServerHandler('next');
handler3.addCallbackElement(panel);
handler3.addCallbackElement(panel).addCallbackElement(hidden);
next.addClickHandler(handler3);
panel.setSpacing(5);
panel.add(infoLabel);
panel.add(link1);
panel.add(current);
panel.add(expired);
panel.add(infoLabel1);
panel.add(next);
app.add(panel);
spreadsheet.show(app);
}
}
function next(e) {
var app = UiApp.getActiveApplication();
app.close();
//parse string to json and call verify to open next dialog
verify(Utilities.jsonParse(e.parameter.yourObject));
return app;
}
function current(e) {
var app = UiApp.getActiveApplication();
app.getElementById('expired').setValue(false);
var yourObj = Utilities.jsonParse(e.parameter.yourObject);
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getSheets()[0];
var range4 = sheet.getRange(yourObj, 4);
var range5 = sheet.getRange(yourObj, 5);
range4.setValue('x');
range5.setValue('');
app.getElementById('infoLabel1').setText('This link has been marked current');
return app;
}
function expired(e) {
var app = UiApp.getActiveApplication();
app.getElementById('current').setValue(false);
var yourObj = Utilities.jsonParse(e.parameter.yourObject);
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getSheets()[0];
var range4 = sheet.getRange(yourObj, 4);
var range5 = sheet.getRange(yourObj, 5);
range4.setValue('');
range5.setValue('x');
app.getElementById('infoLabel1').setText('This link has been marked expired');
return app;
}
我们可能会做得更好,但这可以用于测试。