我对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发生了什么。我们俩都在同一个域中。
实际上这是可行的,正确的方法是Session.getActiveUser()。getEmail()
Google在文档中指出:
如果安全策略不允许访问用户的身份,则User.getEmail()返回空字符串。可用的电子邮件地址的情况各不相同:例如,在任何允许未经用户授权运行脚本的上下文中,用户的电子邮件地址都不可用,例如简单的onOpen(e)或onEdit(e)触发器
虽然我们有这个工作。对我来说,这还行不通,但是我添加了一个菜单项,调用与onEdit相同的功能,然后关闭并打开Spreadsheet后,我收到了授权请求,此后它就起作用了。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句