我的代码有问题。看起来不错,但是不起作用,我真的不知道为什么。我尝试了一切。
我想将我的google excel与我的google日历同步。一切正常,但现在我只编辑空白单元格时想在日历中创建事件:
if (e.oldValue == null) { // also tried if(e.oldValue == undefinded)
var date = new Date(dayRange);
cal.createAllDayEvent(
e.value,
date,
)
}
它工作正常。但是接下来我要在删除单元格时从日历中删除事件(因此它再次为空):
else if(e.value==null){
var events = cal.getEvents(date, {
search: ss.getRange(row,2)
});
for (i in events){
events[i].deleteEvent();
}
在我“删除”日历中的单元格之后,我得到了带有闪烁标题的下一个事件,但我不知道为什么会创建此事件。似乎这种“否则”无效。我真的不知道为什么我阅读了所有示例,代码看起来还可以。
这是我创建触发器的方式:
function createEditTrigger() {
var ss = SpreadsheetApp.getActive();
ScriptApp.newTrigger('ToCalendar')
.forSpreadsheet(ss)
.onEdit()
.create();
}
我将非常感谢所有建议。
编辑
完整代码:
function ToCalendar(e) {
var ss = SpreadsheetApp.getActiveSheet();
var cal = CalendarApp.getCalendarById("myID");
var range = e.range;
var column = range.getColumn();
var row = range.getRow();
var day = ss.getRange(1,column);
var dayRange = day.getValues();
if ((e.value != null) && (e.oldValue == null)) {
var date = new Date(dayRange);
cal.createAllDayEvent(
ss.getRange(row,2).getValue(),
date,
{
description: e.value,//ss.getRange(row, column).getValue(),
}
)
}
//If we edit cell:
else if(e.oldValue!=undefined){
var events= cal.getEventsForDay(date,{search: e.oldValue});
var ev= events[0];
Logger.log(ev);
ev.deleteEvent();
cal.createAllDayEvent(ss.getRange(row,2).getValue(),date,
{description: ss.getRange(row, column).getValue()})
// If we delete cell
else if((e.value == null) && (e.oldValue != null)){
var events = cal.getEvents(date, {
search: ss.getRange(row,2)
});
for (i in events){
events[i].deleteEvent();
}
}
创建触发器:
function createEditTrigger() {
var ss = SpreadsheetApp.getActive();
ScriptApp.newTrigger('ToCalendar')
.forSpreadsheet(ss)
.onEdit()
.create();
}
答案 0 :(得分:2)
您要针对编辑空单元格和删除单元格值的情况运行每个功能。如果我的理解是正确的,该解决方法如何?我认为可能有几种解决方法。因此,请将此视为其中之一。在这种解决方法中,假设您正在使用onEdit(e)
。更改单元格后,e
中的onEdit(e)
如下更改。
在将值编辑为空单元格的情况下
e.value
包含在e
中。e.oldValue
未包含在e
中。在用一个值覆盖其他值的单元格的情况下
e.value
中包含e.oldValue
和e
。从具有值的单元格中删除值
e.value
不包含e.oldValue
和e
。使用以上结果,为了运行用于编辑空白单元格和删除单元格值的案例的每个功能,可以使用以下示例脚本。
function onEdit(e) {
if (("value" in e) && !("oldValue" in e)) {
Logger.log("In the case for editing a value to empty cell")
}
if (!("value" in e) && !("oldValue" in e)) {
Logger.log("In the case for deleting a value from a cell with a value")
}
}
当然,您也可以使用以下脚本。
function onEdit(e) {
if ((e.value != null) && (e.oldValue == null)) {
Logger.log("In the case for editing a value to empty cell")
}
if ((e.value == null) && (e.oldValue == null)) {
Logger.log("In the case for deleting a value from a cell with a value")
}
}
onEdit()
上安装一个触发器。如果我误解了你的问题,对不起。
已删除语法错误并修改了脚本。在此修改后的脚本中,
if ((e.value != null) && (e.oldValue == null)) { script }
中的脚本。else if(e.oldValue!=undefined) { script }
中的脚本。else if((e.value == null) && (e.oldValue == null)) { script }
中的脚本。function ToCalendar(e) {
var ss = SpreadsheetApp.getActiveSheet();
var cal = CalendarApp.getCalendarById("myID");
var range = e.range;
var column = range.getColumn();
var row = range.getRow();
var day = ss.getRange(1,column);
var dayRange = day.getValues();
if ((e.value != null) && (e.oldValue == null)) { // When the empty cell is edited, this becomes true.
var date = new Date(dayRange);
cal.createAllDayEvent(ss.getRange(row,2).getValue(),date,{
description: e.value,//ss.getRange(row, column).getValue(),
})
// In your situation, this might not be required.
} else if(e.oldValue!=undefined) { // When the cell with a value is overwritten by a value, this becomes true.
//If we edit cell:
var events= cal.getEventsForDay(date,{search: e.oldValue});
var ev= events[0];
Logger.log(ev);
ev.deleteEvent();
cal.createAllDayEvent(ss.getRange(row,2).getValue(),date,{description: ss.getRange(row, column).getValue()})
} else if((e.value == null) && (e.oldValue == null)) { // When the value of cell with a value is removed, this becomes true.
// If we delete cell
var events = cal.getEvents(date, {
search: ss.getRange(row,2)
});
for (i in events){
events[i].deleteEvent();
}
}
}
已确认事件对象的规范已更改。确认了以下修改。 @I'-'I提到了这一点。
e.value
不包含e.oldValue
和e
。e.value
和e.oldValue
包含在e
中。
e.value
是{"oldValue":"deleted value"}
之类的对象。e.oldValue
是类似于"deleted value"
的字符串。通过此修改,当从具有该值的单元格中删除该值时,可以通过以下脚本进行检查。
if (e.value.oldValue) {
// value was removed from cell.
} else {
// value is NOT removed from cell.
}
答案 1 :(得分:1)
您遇到的问题是您处于中间状况if(e.oldValue!=undefined)
,这将找出e.value也未定义但e.oldValue未定义的情况,并创建一个事件。因此,您永远都不会遇到希望新擦除的单元删除事件的最终情况。
我认为您想要的逻辑是if(e.oldValue!=undefined && e.value!=undefined)
我认为混淆的部分原因是null和undefined的混合。
从OnEdit触发器接收到时,空单元格的值为undefined
,而不是null
。
由于javascript将undefined评估为false,因此只需检查if(!e.value)
(如果没有值)就足够了,但是如果要明确,则可以检查if(e.value === undefined)
。
因为javascript就JavaScript而言,其null也为false null == undefined
。为了清楚起见,我建议将所有检查都更改为if(!e.value)或if(!e.oldValue),或删除对null
的引用并在各处使用undefined
。这将使脚本更具可读性,因为当前代码使null和undefined看起来表现出不同的行为。
答案 2 :(得分:0)
从2019年10月21日起,我不再发现这些变通办法可以正常工作。当一个单元格有一个值,然后用退格键删除该值或删除击键时,google会按预期返回e.oldvalue,但是e.value中有一个奇数对象,而不是虚假的响应。这是一个非常令人困惑的错误,对于那些尝试使用gSheets进行自动化的人来说确实令人困惑。现在,新的解决方法包括检查数据类型。这是link to the new issue的完整文档,包括新的解决方法。
答案 3 :(得分:0)
使用新的V8
引擎的最新结果(2020)建议,在删除单元格或后退空格或逐个删除每个字符时,始终包含e.oldValue
。
以下动作被一个接一个地执行,并且事件对象被记录在每个动作上,
const onEdit = e => console.log(JSON.stringify(e));
| | B(Value) | Action taken |
|---+---------------+----------------------------|
| 3 | deletedValue1 | deleteFromPC/insertValue |
| 4 | deletedValue2 | backspaceFromPC |
| 5 | deletedValue3 | deleteCharacter1by1PC |
| 6 | deletedValue4 | clearFromMOBILE |
| 7 | deletedValue5 | deleteCharacter1By1MOBILE |
| 8 | deletedValue6 | overwriteValue6To6.1MOBILE |
| 9 | deletedValue7 | overwriteValue7To7.1PC |
insertValue
:将文本“ deletedValue1”插入B3
中。
autofillInsertedValue
:B3
中的文本自动填充到B9
。 B3:B9
包含“ deletedValue1”到“ deletedValue7”
deleteFromPC
:使用 Delete 按钮删除B3
。
backspaceFromPC
:已选择B4
,并按下了 Backspace 按钮。这会完全清除B4
。
deleteCharacter1by1PC
:选择B5
>按下 Enter 进入编辑模式>每个字符被一个个清除> Enter 再次按kbd>退出编辑模式。
clearFromMOBILE
:在移动应用中,长按输入选项,然后按下 clear 。(在B6
上)
deleteCharacter1By1MOBILE
:与上面相同,但来自Mobile。(在B7
上)
overwriteValue6To6.1MOBILE
:B8
的值从“ deletedValue6”覆盖为“ deletedValue6.1”
overwriteValue7To7.1PC
:与上述相同,但从PC上的B9
。
以下json提供了上述每个event object
记录的action
。 action
用作此结果对象的键,而值是实际记录的event object
。
{
"insertValue": {
"authMode": "LIMITED",
"range": { "columnEnd": 2, "columnStart": 2, "rowEnd": 3, "rowStart": 3 },
"source": {},
"user": { "email": "", "nickname": "" },
"value": "deletedValue1"
},
"autofillInsertedValue": {
"authMode": "LIMITED",
"range": { "columnEnd": 2, "columnStart": 2, "rowEnd": 9, "rowStart": 4 },
"source": {},
"user": { "email": "", "nickname": "" }
},
"deleteFromPC": {
"authMode": "LIMITED",
"oldValue": "deletedValue1",
"range": { "columnEnd": 2, "columnStart": 2, "rowEnd": 3, "rowStart": 3 },
"source": {},
"user": { "email": "", "nickname": "" }
},
"backspaceFromPC": {
"authMode": "LIMITED",
"oldValue": "deletedValue2",
"range": { "columnEnd": 2, "columnStart": 2, "rowEnd": 4, "rowStart": 4 },
"source": {},
"user": { "email": "", "nickname": "" }
},
"deleteCharacter1by1PC": {
"authMode": "LIMITED",
"oldValue": "deletedValue3",
"range": { "columnEnd": 2, "columnStart": 2, "rowEnd": 5, "rowStart": 5 },
"source": {},
"user": { "email": "", "nickname": "" }
},
"clearFromMOBILE": {
"authMode": "LIMITED",
"oldValue": "deletedValue4",
"range": { "columnEnd": 2, "columnStart": 2, "rowEnd": 6, "rowStart": 6 },
"source": {},
"user": { "email": "", "nickname": "" }
},
"deleteCharacter1By1MOBILE": {
"authMode": "LIMITED",
"oldValue": "deletedValue5",
"range": { "columnEnd": 2, "columnStart": 2, "rowEnd": 7, "rowStart": 7 },
"source": {},
"user": { "email": "", "nickname": "" }
},
"overwriteValue6To6.1MOBILE": {
"authMode": "LIMITED",
"oldValue": "deletedValue6",
"range": { "columnEnd": 2, "columnStart": 2, "rowEnd": 8, "rowStart": 8 },
"source": {},
"user": { "email": "", "nickname": "" },
"value": "deletedValue6.1"
},
"overwriteValue7To7.1PC": {
"authMode": "LIMITED",
"oldValue": "deletedValue7",
"range": { "columnEnd": 2, "columnStart": 2, "rowEnd": 9, "rowStart": 9 },
"source": {},
"user": { "email": "", "nickname": "" },
"value": "deletedValue7.1"
}
}
e.oldValue
键:
e.value
键:
如果单元格是自动填充的,则value
和oldValue
都不存在。
答案 4 :(得分:0)
对于@Tanaike 提到的使用 Google 表格上的删除或退格键删除单元格时无法让 e.oldValue 返回旧值的任何人:
<块引用>我无法让 e.oldValue 返回“未定义”以外的任何内容,我在这里找不到答案,但 @Tanaike 解释了 solution in more detail here:
e.oldValue 的结果取决于您是否对编辑的单元格应用了格式(单元格边框、背景阴影等)。
如果您将默认格式应用于单元格 A1 并在单元格中使用文本“示例”,并且您使用删除或退格键(Mac 或 PC)从单元格中删除文本,您将获得以下结果:
e.oldValue === 未定义。
*注意:如果你没有得到这个结果,你可能应用了不明显的格式,所以使用格式>清除格式选项并重试。
如果您将格式应用于单元格 A1,例如边框、背景颜色或字体(我已经测试了这 3 个,但不是所有其他可能的选项),并且单元格中的文本为“示例”,并且您使用删除或退格键(Mac 或 PC)从单元格中删除文本,您将得到以下结果:
e.oldValue === 示例
因此,通过以某种方式设置单元格、列或整个工作表的格式,您可以在删除之前返回并根据已编辑单元格的值进行测试。
可以使用以下代码在空白的 Google Sheet 上测试此行为:
function onEdit(e) {
console.log("This is the current value in e: " + e.value);
console.log("This is the Old Value in e: " + e.oldValue);
if (e.value) {
console.log("There is a value in e");
}
if (e.oldValue) {
console.log("There is an old value in e");
}
if (!e.value) {
console.log("There is NOT a value in e");
}
if (!e.oldValue) {
console.log("There is NOT an old value in e");
}
}