我试图找出一种方法,除了升序/降序之外,还按照特定顺序对Google电子表格中的数据进行排序。我可以通过使用Range.getValues()获取2D数组,对其进行排序,然后使用Range.setValues()来实现此目的。
但问题在于它只是复制数据,对数据进行排序,并将数据粘贴到旧数据上。因此,如果我将A1突出显示为红色,并且通过对范围值进行排序将数据移至B2,则不会将红色突出显示为红色,而使用放在其中的任何内容的A1将突出显示为红色。
是否有任何方法可以实际排序范围并使用格式移动行,并且所有内容仍然完好无损。
答案 0 :(得分:1)
强制使用Range.sort
进行任意排序的方法是在范围中附加临时列并将其用于排序。可以动态插入列,然后将其删除,以避免损坏正在排序的范围旁边的数据。
以下是按内容长度对A2:A7进行排序的示例。
function sortRangeByLength() {
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange("A2:A7");
sheet.insertColumnAfter(range.getLastColumn());
var keys = range.getValues().map(function(row) {
return [row[0].length];
});
range.offset(0, range.getNumColumns(), range.getNumRows(), 1).setValues(keys);
var extendedRange = range.offset(0, 0, range.getHeight(), range.getWidth() + 1);
extendedRange.sort({"column": extendedRange.getWidth(), "ascending": true});
range.offset(0, 1).clear();
sheet.deleteColumn(extendedRange.getLastColumn());
}
范围extendedRange
为range
,附加列,用于排序然后删除。在要删除的列上调用clear
可能看起来多余,但它可以防止不需要的格式化扩散到右侧的列(插入到范围右侧的列继承其格式)。
对于某些种类,可能没有明显的键,只有比较功能。在这种情况下,可以通过比较函数计算密钥,如下所示:
function sortRangeByLength() {
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange("A2:A7");
sheet.insertColumnAfter(range.getLastColumn());
// begin computing the keys
var indexed = range.getValues().map(function(row, i) {
return {"index": i, "content": row};
});
indexed.sort(function(a, b) {
return (a.content[0].length < b.content[0].length ? -1 : (a.content[0].length > b.content[0].length ? 1 : 0));
});
var keys = Array(indexed.length);
for (i in indexed) {
keys[indexed[i].index] = [i];
}
// proceed as before
range.offset(0, range.getNumColumns(), range.getNumRows(), 1).setValues(keys);
var extendedRange = range.offset(0, 0, range.getHeight(), range.getWidth() + 1);
extendedRange.sort({"column": extendedRange.getWidth(), "ascending": true});
range.offset(0, 1).clear();
sheet.deleteColumn(extendedRange.getLastColumn());
}
该方法是标准的:创建了一个“索引”数组,其中包含每行的数据和索引。根据您的算法对此数组进行排序。由此产生的索引排列显示了哪一行去了哪里。它需要被反转成为“按此升序排序”的关键列。此反转为keys[indexed[i].index] = [i];