Попробуйте это:
function onEdit(e) {
var rg=e.range;
var sh=e.range.getSheet();
var name=sh.getName();
if(name=="CHECK OUT" || name== "CHECK IN" || name== "MISC OUT" || name=="MISC IN"){
if(rg.columnStart==1) {
var vA=rg.getValues();
for(var i=0;i<vA.length;i++){
if(vA[i][0]) {
sh.getRange(rg.rowStart + i,8).setValue(new Date());
}else{
sh.getRange(rg.rowStart + i,8).setValue('');
}
}
}
}
}
Я не уверен, что это удивительно... выдерживают сравнение с тем же для свойств по сравнению с полями (так как свойства перед той же функцией как события: инкапсуляция через средства доступа):
.field public string Foo // public field
.property instance string Bar // public property
{
.get instance string MyType::get_Bar()
.set instance void MyType::set_Bar(string)
}
Также - события ничего не упоминают о полях; они только определяют средства доступа (добавляют/удаляют). Покровитель делегата является деталью реализации; это именно так происходит, что поле как события объявляет поле как отступающего участника - таким же образом, что auto-implemented-properties объявляют поле как отступающего участника. Другие реализации возможны (и очень распространены, особенно в формах и т.д.).
Другие общие реализации:
Редкие события (Средства управления, и т.д.) - EventHandlerList (или подобный):
// only one instance field no matter how many events;
// very useful if we expect most events to be unsubscribed
private EventHandlerList events = new EventHandlerList();
protected EventHandlerList Events {
get { return events; } // usually lazy
}
// this code repeated per event
private static readonly object FooEvent = new object();
public event EventHandler Foo
{
add { Events.AddHandler(FooEvent, value); }
remove { Events.RemoveHandler(FooEvent, value); }
}
protected virtual void OnFoo()
{
EventHandler handler = Events[FooEvent] as EventHandler;
if (handler != null) handler(this, EventArgs.Empty);
}
(вышеупомянутое является в значительной степени магистралью событий форм победы),
Фасад (хотя это путает "отправителя" немного; некоторый посреднический код часто полезен):
private Bar wrappedObject; // via ctor
public event EventHandler SomeEvent
{
add { wrappedObject.SomeOtherEvent += value; }
remove { wrappedObject.SomeOtherEvent -= value; }
}
(вышеупомянутое может также использоваться для эффективного переименования события),
Точка наличия событий, которые являются парой, добавляет, удаляет, методы инкапсуляция.
Большую часть времени события использованы как есть, но другие времена, Вы не хотите хранить делегатов, присоединенных к событию в поле, или Вы хотите сделать, дополнительная обработка на добавляет или удаляет методы события.
Например, один способ реализовать память, эффективные события должны сохранить делегатов в словаре, а не частном поле, потому что поля всегда выделяются, в то время как словарь только увеличивается в размере, когда объекты добавляются. Эта модель является похожей с тем, что делают Winforms и использование WPF, делают эффективное использование памяти (winforms и использование WPF включенные словари для хранения делегатов не списки)
События не являются тем же как делегатами. События инкапсулируют добавление/удаление обработчика для события. Обработчик представлен с делегатом.
Вы могли просто записать AddClickHandler/RemoveClickHandler и т.д. для каждого события - но это будет относительно болезненно, и не помогло бы инструментам как VS выделить события от чего-либо еще.
Это точно так же, как свойства действительно - Вы могли записать GetSize/SetSize и т.д. (как Вы делаете в Java), но путем выделения свойств, существуют синтаксические ярлыки доступная и лучшая поддержка инструмента.