【发布时间】:2014-09-18 14:55:01
【问题描述】:
我对 Google Script 不断发展的功能/限制感到沮丧。
每当他们编辑列中的单元格时,我想完成将时间戳和编辑用户名写入相邻单元格的看似简单的任务。
这是我目前尝试过的代码:
/**
* Get current user's name, by accessing their contacts.
*
* @returns {String} First name (GivenName) if available,
* else FullName, or login ID (userName)
* if record not found in contacts.
*/
function getOwnName(){
var email = Session.getEffectiveUser().getEmail();
var self = ContactsApp.getContact(email);
// If user has themselves in their contacts, return their name
if (self) {
// Prefer given name, if that's available
var name = self.getGivenName();
// But we will settle for the full name
if (!name)
name = self.getFullName();
return name;
}
// If they don't have themselves in Contacts, return the bald userName.
else {
var userName = Session.getEffectiveUser().getUsername();
return userName;
}
}
但是,getEffectiveUser 只获取我的用户名,而不是当前编辑器。 getActiveUser 什么都不返回。
替代方案并不漂亮。我看到了一些示例,当前用户在打开电子表格时会从所有编辑者的列表中选择他们的电子邮件。电子邮件将存储在草稿纸上的某处,并在用户进行编辑时以某种方式粘贴到单元格中,尽管示例中省略了电子邮件存储和检索。
作为一个可怕且极其缓慢/低效的黑客,我插入时间戳,然后弹出一个带有列表框和按钮的页面,从单元格范围中获取用户名,当编辑器选择他们的名称时,它应该将值粘贴到相邻的单元格中。然而,由于一些尚未确定的原因,这似乎随机遇到授权问题,更不用说速度非常慢:
function show() {
var doc = SpreadsheetApp.getActiveSpreadsheet();
var specialSheet = doc.getSheetByName("ADDL. INFO");
var app = UiApp.createApplication().setTitle('Select Name').setWidth(150).setHeight(150);
var panel = app.createVerticalPanel();
var lb = app.createListBox(true).setId('myId').setName('myLbName');
// add items to ListBox
lb.setVisibleItemCount(4);
// Getting a known named range from spreadsheet object.
empLocRange = specialSheet.getRange("A28:A32");
//.getRangeByName('EmployeeLocations');
empLocs = empLocRange.getValues();
empLocs.sort()
for (i=0; i < empLocs.length; ++i) {
empLoc = empLocs[i][0].toString().trim();
if (!(empLoc=='')) {
lb.addItem(empLoc);
}
}
panel.add(lb);
var button = app.createButton('Select');
var handler = app.createServerClickHandler('click').addCallbackElement(panel);
button.addClickHandler(handler);
panel.add(button);
app.add(panel);
doc.show(app);
}
function click(eventInfo) {
var app = UiApp.getActiveApplication();
// get values of ListBox
var value = eventInfo.parameter.myLbName;
// multi select box returns a comma separated string
var n = value.split(',');
var s = SpreadsheetApp.getActiveSheet();
var r = s.getActiveCell();
var p = r.getRow();
var nextCell = r.offset(0, 2);
var app = UiApp.getActiveApplication();
nextCell.setValue(value);
app.close();
return app;
}
我读到将脚本作为独立应用程序发布,您可以访问当前用户名,但这似乎不是正确的解决方案。我以为我可以为每个用户安装此脚本作为解决方案,但它似乎并没有以这种方式运行。
任何帮助或将不胜感激。
编辑。 忘记包含调用它的函数:
function timestamp() {
var s = SpreadsheetApp.getActiveSheet();
var r = s.getActiveCell();
var p = r.getRow();
if( r.getColumn() == 14 ) //checks the column
{
var nextCell = r.offset(0, 1);
nextCell.setValue(new Date());
//s.setActiveSelection(p + "15");
show();
//SpecialonOpen();
//nextCell = r.offset(0,2);
//nextCell.setValue(getOwnName());
}
}
我将上述时间戳功能设置为在编辑时触发 - 时间戳,来自电子表格,在编辑时。
更新:
我一直在努力反对这一点。
这就是结果,尽管有奇怪的、无法解释的行为。
我当前的脚本:
function getOwnName(){
var email = Session.getEffectiveUser().getEmail();
//Browser.msgBox("getOwnName");
//var self = ContactsApp.getContact(email);
var self = false;
// If user has themselves in their contacts, return their name
if (self) {
// Prefer given name, if that's available
var name = self.getGivenName();
// But we will settle for the full name
if (!name)
{
name = self.getFullName();
}
//Browser.msgBox(name);
return name;
}
// If they don't have themselves in Contacts, return the bald userName.
else {
var userName = Session.getEffectiveUser().getUsername();
//Browser.msgBox(userName);
return userName;
}
}
function onEdit() {
var s = SpreadsheetApp.getActiveSheet();
var r = s.getActiveCell();
var p = r.getRow();
if( r.getColumn() == 14 ) //checks the column
{
var nextCell = r.offset(0, 1);
nextCell.setValue(new Date());
//Browser.msgBox("hey!");
//s.setActiveSelection(p + "15");
//show();
//SpecialonOpen();
var nCell = r.offset(0,2);
//Browser.msgBox("olah:" + getOwnName());
nCell.setValue(getOwnName());
}
}
我注释掉了//var self = ContactsApp.getContact(email);,因为它似乎使脚本崩溃。
这样做之后,我去找我的一位用户并要求他们进行测试。仍然没有用户名写入单元格。我告诉他打开脚本并使用播放按钮执行该功能。这弹出了一条授权消息。他同意授权脚本,返回电子表格后,他的名字已成功插入到单元格中。
但是,当 onEdit 触发时,脚本仍然不会将他的用户名写入单元格。所以我真的不知道GS是怎么回事。我们都在同一个域中。
【问题讨论】:
-
函数getOwnName是否也被onEdit触发了?
-
原来是这样,你可以看到我把那行注释掉了(//nextCell.setValue(getOwnName());)。这是我最初的尝试,然而,getEffectiveUser 只会返回我的用户名或文档所有者的用户名,当我切换到 getActiveUser 函数时,它什么也不会返回。我希望该功能正常工作并返回触发 onEdit 触发器的编辑器的用户名。然而,这似乎不再可能,除非该功能是一个独立的应用程序。或者什么....
-
我有一个从下拉列表中设置为某个值的单元格:已完成、待处理和已取消。更改后,我想将相邻单元格设置为当前日期时间,并将其旁边的单元格设置为编辑器的用户名。我尝试过的其他事情是移动活动单元格(用户名单元格最初包含一个由一系列单元格填充的下拉列表),但显然该功能也被删除了。如果有某种方法可以在编辑时触发下拉菜单,这可能是目前最理想/实际能够实现的。
-
问题是可安装的触发器作为触发器的作者运行...而 getactiveUser 仅在域的上下文中工作...是您的情况吗?
-
是的,这是我遇到的问题之一。但是,我真的不明白为什么。本文档的所有编辑都在同一个域中(不是 gmail/google)。
标签: google-apps-script google-sheets