问题
I am making a spreadsheet that is to be used for booking equipment for a club I am part of. I am looking for a way for all the cells in a selected area of a spreadsheet to be moved one to the left at midnight, and ones all the way to the left deleted. I understand that I can just use a trigger to execute this, however I am not sure how to go about writing the function to do this.
Any help or suggestions would be appreciated.
回答1:
This would be simple if you had a function that could left-shift the contents of a two-dimensional array. With that, you could do something like the following. Refer to the documentation for method details.
Define the range you want shifted, using Sheet.getRange().
Use Range.getValues() to get an array with all the data you want to shift.
Shift the array contents.
var result = []; for (var r=0; r<array2d.length; r++) { var row = array2d[r].slice(0); var rotVal = row.shift(); row.push(''); // preserve row width by adding a blank value result.push(row); }
Write the shifted array values out to the previous range, using Range.setValues().
Note: Only values will be preserved this way, no formulas, no formatting. If you want formatting, you could get arrays of it and manipulate it in a similar fashion. Formulas are trickier, due to the effect of relative references.
shiftArray Function
That snippet above is an excerpt of this function, which can shift an array left, right, up or down, and also supports the "rotate" concept (where a value pulled from one end of a row or column is placed at the other end, instead of a blank). To ensure that the source array is left untouched, it relies on a deepCopy()
function.
/**
* Shift the contents of a two-dimensional array in given direction,
* with rotate option. Can be used as a spreadsheet custom function.
* Dimensions of resulting array correspond to input array.
*
* Written for http://stackoverflow.com/questions/17404787 by Mogsdad
*
* @param {Array} array2d Two-dimensional array input
* @param {String} direction One of {'left', 'right', 'up', 'down'},
* defaults to 'left'.
* @param {Boolean} rotate Set true if shifted value should be
* rotated to other end, default false.
*
* @returns {Array} Two-dimensional array result
*/
function shiftArray( array2d, direction, rotate ) {
direction = direction || 'left';
rotate = rotate || false;
var result = [];
switch (direction) {
case 'left':
for (var r=0; r<array2d.length; r++) {
var row = array2d[r].slice(0);
var rotVal = row.shift();
row.push(rotate ? rotVal : '');
result.push(row);
}
break;
case 'right':
for (var r=0; r<array2d.length; r++) {
var row = array2d[r].slice(0);
var rotVal = row.pop();
row.unshift(rotate ? rotVal : '');
result.push(row);
}
break;
case 'up':
result = deepCopy(array2d);
var rotRow = result.shift();
if (!rotate)
// empty all elements in rotRow
for (var c=0; c<rotRow.length; c++)
rotRow[c]='';
result.push(rotRow);
break;
case 'down':
result = deepCopy(array2d);
var rotRow = result.pop();
if (!rotate)
// empty all elements in rotRow
for (var c=0; c<rotRow.length; c++)
rotRow[c]='';
result.unshift(rotRow);
break;
default:
throw new Error( "Unknown direction '"+direction+"'" );
}
return result;
}
/**
* Return a deep copy of the given object.
*
* From: http://james.padolsey.com/javascript/deep-copying-of-objects-and-arrays/#comment-10679
*/
function deepCopy(o) {
var copy = o,k;
if (o && typeof o === 'object') {
copy = Object.prototype.toString.call(o) === '[object Array]' ? [] : {};
for (k in o) {
copy[k] = deepCopy(o[k]);
}
}
return copy;
}
来源:https://stackoverflow.com/questions/17404787/shift-values-in-google-spreadsheet