我希望运行一个Google脚本,在一个(30多个)Google表格上标准化一个小区范围。或者更准确地说,我希望(技术较少的)用户能够做到这一点。我似乎找不到合理的工作流程。
我能看到的选项是:
这很麻烦,因为那时脚本有很多副本,通常不会再次运行,而且还有很多开销和点击来为每一个安装宏。
我可以将代码的主体放在库中,然后复制/粘贴只是一个存根(就像接受的答案here)。
然而,这对于用户体验仍然同样糟糕,加上各种报道库都很难处理。
“正确的方法”似乎是创建一个用户可以为每个电子表格启用的附加组件。但是,附加组件似乎仍处于“开发人员预览”模式,授权周期不确定且可能很慢。谷歌还希望该脚本已经过多个活跃用户的测试。这很难 - 当我对它进行彻底的测试时,这个工作基本上就完成了。如何在不发布插件的情况下测试它呢?
还有其他方法,也许使用非绑定脚本?由于需要一些用户输入(电子表格中的范围等),因此无法运行单个脚本并使其迭代所有电子表格。
有没有办法让用户可以安装未绑定的脚本,运行它,然后它会询问运行它的电子表格?
openByUrl()
非常接近,但实际上并没有打开电子表格用户界面,因此我无法使用getActiveRange()
等功能。
如果它是相关的,这是脚本:
/*function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Normalize')
.addItem('Normalize Crosstab', 'normalizeCrossTab')
.addToUi();
}*/
function onOpen() {
var ss = SpreadsheetApp.getActive();
var items = [
{name: 'Normalize Crosstab', functionName: 'normalizeCrosstab'},
];
ss.addMenu('Normalize', items);
}
/* Converts crosstab format to normalized form. Given columns abcDE, the user puts the cursor somewhere in column D.
The result is a new sheet, NormalizedResult, like this:
a b c Field Value
a1 b1 c1 D D1
a1 b1 c1 E E1
a2 b2 c2 D D2
a2 b2 c2 E E2
...
*/
function normalizeCrosstab() {
var sheet = SpreadsheetApp.getActiveSheet();
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
var firstDataCol = SpreadsheetApp.getActiveRange().getColumn();
var dataCols = values[0].slice(firstDataCol-1);
if (Browser.msgBox("This will create a new sheet, NormalizedResult. Place your cursor is in the first data column.\\n\\n" +
"These will be your data columns: " + dataCols,Browser.Buttons.OK_CANCEL) == "cancel") {
return;
}
var resultssheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("NormalizedResult");
if (resultssheet != null) {
SpreadsheetApp.getActive().deleteSheet(resultssheet);
}
var header = values[0].slice(0, firstDataCol - 1);
var newRows = [];
header.push("Field");
header.push("Value");
newRows.push(header);
for (var i = 1; i <= numRows - 1; i++) {
var row = values[i];
for (var datacol = 0; datacol < dataCols.length; datacol ++) {
newRow = row.slice(0, firstDataCol - 1); // copy repeating portion of each row
newRow.push(values[0][firstDataCol - 1 + datacol]); // field name
newRow.push(values[i][firstDataCol - 1 + datacol]); // field value
newRows.push(newRow);
}
}
var newSheet = SpreadsheetApp.getActiveSpreadsheet().insertSheet("NormalizedResult");
var r = newSheet.getRange(1,1,newRows.length, header.length);
r.setValues(newRows);
};
答案 0 :(得分:1)
您可以检索用户提供URL的工作表,用简单的HTML展示它们,在另一个工作表下面一个工作表,然后附加一个按钮列,它将为该ROW调用normalizeCrosstab()。这是一个已发布的HTML解决方案,任何人都可以在不登录的情况下使用。
如果有定义数量的工作表,您也可以使用名称旁边的按钮在HTML中生成它们,它将生成TABLE HTML。
或者使用图书馆,我怀疑你有什么需要和不能做的,答案很老(12')。
我正在使用图书馆并且没有任何问题,对所有事情都非常方便,所有工作表必须具有这3个功能才能像脚本本身一样工作:
function onOpen() {
library.onInitialize();
}
function onEdit(celEd) {
library.onMakeEdit(celEd);
}
function libraryFuncs( funcName, args ){ // Needed for sideBars to use library functions
if(args)
args = args.split("\!|"); // Predefined separation of args
else
args = [];
return library[ funcao ]().apply(this, args);
}
答案 1 :(得分:1)
第一个问题是:&#34;谁是这些床单的所有者?&#34;如果您是所有这些工作表的所有者,则您有权远程访问它们。如果您不拥有它们,则所有者需要共享,并为尝试修改其文件的任何代码授予编辑权限。
如果您拥有所有电子表格,则可以创建一个独立应用程序从中心点执行所有处理。然后,您只需将Stand Alone App的链接通过电子邮件发送给每个人,或让每个用户在其电子表格中输入一个链接到Stand Alone App。正如您所提到的,对于该选项,您无法使用getActiveSheet()
等方法。
无论您使用何种选项,您都需要让人们在其电子表格中添加内容,或者创建一些新的集中式界面。您最好的选择可能归结为所有权和设置权限。
我猜测如果电子表格的用户是所有者,并且不想给你许可,他们就需要使用前三个选项中的一个。我首先从图书馆开始。
如果您可以轻松获取电子表格的文件ID,则可以创建一个将用户与FileID匹配的对象。
var objUserToFileID = {"user1":"abc34ciu89384u", "user2":"FileID_Two", "user3":"FileID_Three"};
然后让用户从列表中选择他们的名字,(下拉列表)然后运行代码。这是Stand Alone App的用武之地。当然,如果用户为其他人的电子表格选择fileID,您需要弄清楚会发生什么。然后,您需要有办法确定应用程序的用户是谁。