大家好,所以我组织了一个活动,人们使用带有二维码的卡片来签入和签出,代码输入该人的姓名,所以我使用了我在网上找到的一个脚本来自动在其旁边插入时间戳 但问题是我想让脚本在同一个人下班时进行检查,并自动将他的名字移到同一行中,并在与第一个列不同的列上将其旁边的新时间戳移至该行。
这是我使用的代码 (如果标题有误导性,请见谅)
var s = SpreadsheetApp.getActiveSheet();
if( s.getName() == 'Sheet1' ) {
var r = s.getActiveCell();
if( r.getColumn() == 1 ) {
var nextCell = r.offset(0, 1);
if( nextCell.getValue() === '' )
nextCell.setValue(new Date());
}
if( r.getColumn() == 3 ) {
var nextCell = r.offset(0, 1);
if( nextCell.getValue() === '' )
nextCell.setValue(new Date());
}
if( r.getColumn() == 5 ) {
var nextCell = r.offset(0, 1);
if( nextCell.getValue() === '' )
nextCell.setValue(new Date());
}
if( r.getColumn() == 7 ) {
var nextCell = r.offset(0, 1);
if( nextCell.getValue() === '' )
nextCell.setValue(new Date());
}
}
我使用了上面的代码,但我找不到在同一行插入同一个人打卡上下班的方法,这是我第一次使用 Google Apps 脚本,所以如果这很简单,我再次道歉。
该脚本通过二维码捕获姓名并记录这些姓名的入住和退房时间。您的问题是脚本没有测试现有名称,测试该名称是否已签出,并更新 check-out 时间而不是签入时间。
假设
function updateCheckinOutTime() {
var s = SpreadsheetApp.getActiveSheet();
// get variables for currentName
var r = s.getActiveCell();
if( s.getName() != 'Sheet1' || r.isBlank() === true ) {
// not Sheet1 or the cell is blank, do nothing
// Logger.log("DEBUG: this is NOT sheet 1 or the cell is blank")
}
else{
// this is sheet 1
// Logger.log("DEBUG: this is sheet 1")
var curDate = Utilities.formatDate(new Date(), SpreadsheetApp.getActive().getSpreadsheetTimeZone(), "dd/MM/yyyy HH:mm:ss")
//Logger.log(curDate) // DEBUG
// get variables for currentName
var curName = r.getValue()
var curCol = r.getColumn()
var curRow = r.getRow()
// Logger.log("DEBUG: active cell = "+r.getA1Notation()+", value:"+curName+", column = "+curCol+", row:"+curRow)
// step#1 - look for the name in this column
var namesHstryLR = s.getLastRow()
// Logger.log("DEBUG: last row on names = "+namesHstryLR)
// adjust -1 to ignore the current name
var namesHstryRange = s.getRange(1,1,namesHstryLR-1)
// Logger.log("DEBUG: last row for names history = "+namesHstryLR+", so names history range = "+namesHstryRange.getA1Notation())
var namesHstry = namesHstryRange.getValues()
// Logger.log(namesHstry) // DEBUG
// convert namesHstry 2D array to 1D
names = namesHstry.map(function(e){return e[0];})
// Logger.log(names) // DEBUG
// Logger.log(curName) // DEBUG
// use lastIndexOf to find the last occurence of the current name in names history
// if result = -1 then no match
var result = names.lastIndexOf(curName);
// Logger.log("DEBUG: result:"+result+", current name = "+curName+", names:"+names)
if (result != -1){
// Found a match: assume that check-in time is not blank
// indexof is zero based so +1 to get row number
// Logger.log("DEBUG: found a match on row: "+(result+1))
// check check-out time
var hstryOutRange = s.getRange((result+1),3)
// if checkout time is blank, then update checkout time.
// if not blank, then this is a new checkin
if(hstryOutRange.isBlank() === true){
// if blank, then this is a user logging out, so
// log the time in the matched row and
// delete activecell
// Logger.log("DEBUG: Checkout time NOT found, cell "+hstryOutRange.getA1Notation()+" is blank")
hstryOutRange.setValue(curDate)
r.clear()
// Logger.log("DEBUG: updated the checkout time and cleared the current cell")
}
}
else{
// if result = -1 (no match found) OR checkout is not blank
// then this is a new checkin, update checkin date only.
r.offset(0, 1).setValue(curDate)
}
}
}
评论
该脚本有广泛的注释,并且包含 Logger 语句,使用户能够测试脚本各个阶段的值。
基于OP脚本的基本原则是:
lastIndexOf
documentation 测试活动单元格中的名称是否在活动单元格上方的名称列表中找到。
样品