How to sorting sheet by cell's background color - 有代码,但是看不懂报错
How to sort sheet by cell's background color - have the code, but don't understand the error
我正在努力完成这个项目,但最后一部分现在让我耽搁了 2 天。我有一个 Google Sheet,非常简单,我只需要它按单元格的背景颜色自动排序。我有 7 种颜色需要按此顺序排列,并且我尝试使用 Sort Range Plus 扩展,它确实有效,但我不知道如何在编辑 sheet 时使用预先确定的参数调用它。然后我找到了一个 Apps 脚本,它应该完全满足我的需要,我想我首先启用了 Sheets API,就像论坛上说的那样,我必须在我相信有两个地方,但是当我 运行 以下代码时,我仍然在第 25/26 行出现错误:
Error: Exception: Object is not of type RgbColor.
(anonymous) @ SortByColor.gs:26
(SortByColor) @ SortByColor.gs:25
我不确定如何解决这个问题,因为它 运行s 并获取颜色然后出错。我以前没有用过javascript,所以我希望更熟悉的人可以帮助我。也许问题是我错误地启用了它还是什么?如果其他人对相同的代码没有问题,我想我可能做错了。这也是我第一次使用 Google Apps 脚本。
这是我一直在尝试的代码。请原谅注释掉的部分 - 我正在使用我在 2 个不同线程中找到的代码。
function SortByColor() {
const sheetName = "Patient Progress"; // Please set the sheet name.
//const a1Notation = "A1:A1099"; // Please set the sort range as a1Notation.
// 1. Retrieve the background colors from the cells.
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName(sheetName);
//const range = sheet.getRange(a1Notation);
var range = sheet.getRange(2, 1, ss.getLastRow(), ss.getLastColumn());
const backgrounds = range.getBackgroundObjects();
// 2. Create the request body for using the batchUpdate method of Sheets API.
/**
const startRow = range.getRow() - 1;
const startColumn = range.getColumn() - 1;
const srange = {
sheetId: sheet.getSheetId(),
startRowIndex: startRow,
endRowIndex: startRow + range.getNumRows(),
startColumnIndex: startColumn,
endColumnIndex: startColumn + range.getNumColumns(),
};**/
const sortColorOrder = ['#ea9999', '#f9cb9c', '#fff2cc', 'd9ead3', '#cfe2f3', '#d9d2e9',
'#fffff' ]; // This means that "red", "orange", "yellow", "green", "blue", "purple",
"white" in order.
const backgroundColorObj = backgrounds.reduce((o, [a]) => {
const rgb = a.asRgbColor()
return Object.assign(o, { [rgb.asHexString()]: { red: rgb.getRed() / 255, green:
rgb.getGreen() / 255, blue: rgb.getBlue() / 255 } })
}, {});
const backgroundColors = sortColorOrder.map(e => backgroundColorObj[e]);
const requests = [
{
sortRange: {
range: srange,
sortSpecs: [{ dimensionIndex: 0, sortOrder: "ASCENDING" }],
},
},
{
sortRange: {
range: srange,
//sortSpecs: [{backgroundColor: '#d9d2e9'}, {backgroundColor: '#d9ead3'},
{backgroundColor: '#fff2cc'}]
sortSpecs: backgroundColors.map((rgb) => ({ backgroundColor: rgb })),
},
},
];
// 3. Request to Sheets API using the request body.
Sheets.Spreadsheets.batchUpdate({ requests: requests }, ss.getId());
}
从你的展示脚本来看,我觉得你可能用到了我的答案 and ,下面的修改怎么样?
修改点:
- 在您的脚本中,
srange
未声明。
"white" in order.
和 {backgroundColor: '#fff2cc'}]
行用作脚本行而不是注释。
- 您设置了
'#fffff'
的十六进制颜色。在这种情况下,我认为它是 '#ffffff'
。如果使用'#fffff'
,则白色背景不排序。请注意这一点。
关于var range = sheet.getRange(2, 1, ss.getLastRow(), ss.getLastColumn());
,Rubén的评论已经提到了。
将这些点反映到示例脚本中,就变成了下面的样子。
我无法知道您实际电子表格中单元格的背景颜色。所以在这个修改中,我假设你在“A”列使用 ['#ea9999', '#f9cb9c', '#fff2cc', 'd9ead3', '#cfe2f3', '#d9d2e9', '#ffffff']
的背景颜色。请注意这一点。
修改后的脚本:
请再次确认 Sheets API 是否已经启用。
function myFunction() {
const sheetName = "Patient Progress"; // Please set the sheet name.
// 1. Retrieve the background colors from the cells.
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName(sheetName);
const range = sheet.getRange(2, 1, ss.getLastRow() - 1, ss.getLastColumn());
const backgrounds = range.getBackgroundObjects();
// 2. Create the request body for using the batchUpdate method of Sheets API.
const sortColorOrder = ['#ea9999', '#f9cb9c', '#fff2cc', 'd9ead3', '#cfe2f3', '#d9d2e9', '#ffffff']; // This means that "red", "orange", "yellow", "green", "blue", "purple", "white" in order.
const backgroundColorObj = backgrounds.reduce((o, [a]) => {
const rgb = a.asRgbColor();
const hex = rgb.asHexString();
return Object.assign(o, { [hex == "#ffffffff" ? "#ffffff" : hex]: { red: rgb.getRed() / 255, green: rgb.getGreen() / 255, blue: rgb.getBlue() / 255 } });
}, {});
const backgroundColors = sortColorOrder.map(e => backgroundColorObj[e] || "").filter(String);
if (backgroundColors.length == 0) return;
const startRow = range.getRow() - 1;
const startColumn = range.getColumn() - 1;
const srange = {
sheetId: sheet.getSheetId(),
startRowIndex: startRow,
endRowIndex: startRow + range.getNumRows(),
startColumnIndex: startColumn,
endColumnIndex: startColumn + range.getNumColumns()
};
const requests = [
{ sortRange: { range: srange, sortSpecs: [{ dimensionIndex: 0, sortOrder: "ASCENDING" }] } },
{ sortRange: { range: srange, sortSpecs: backgroundColors.map(rgb => ({ backgroundColor: rgb })) } }
];
// 3. Request to Sheets API using the request body.
Sheets.Spreadsheets.batchUpdate({ requests: requests }, ss.getId());
}
注:
遗憾的是,我不知道您的实际电子表格中的背景颜色。因此,在您的实际电子表格中,当使用 ['#ea9999', '#f9cb9c', '#fff2cc', 'd9ead3', '#cfe2f3', '#d9d2e9', '#ffffff']
颜色以外的背景颜色时,这些颜色将被忽略。请注意这一点。
作为重点,在使用getBackgroundObjects()
时,我确认了白底的十六进制值为#ffffffff
。我不确定这是错误还是当前规范。所以在这种情况下,#ffffffff
被修改为#ffffff
.
参考文献:
- 相关线程。
- Sort values by color in Google Sheets by using google APP Script
函数随机为行分配颜色,并根据每行的颜色对数据集进行排序。
代码:
function colorSort0() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Sheet0");
let vs = sh.getRange(2, 1, sh.getLastRow() - 1, 20).getValues();
let bs = sh.getRange(2, 1, sh.getLastRow() - 1, 20).getBackgrounds();
const colors = {};
const idx = {};
sh.getRange("X1:X8").getBackgrounds().flat().forEach((b, i) => { colors[i] = b; idx[b] = i; });
bs.forEach((r, i) => {
let color = colors[Math.floor(Math.random() * Object.keys(colors).length)];//assigned colors randomyly
sh.getRange(i + 2, 1, 1, 20).setBackground(color);
SpreadsheetApp.flush();//Display all assigned colors in the spreadsheet
});
vs = sh.getRange(2, 1, sh.getLastRow() - 1, 20).getValues();
bs = sh.getRange(2, 1, sh.getLastRow() - 1, 20).getBackgrounds();//pickup assigned colors
let A = vs.map((r, i) => {
return { values: r, color: bs[i] };
});
A.sort((a, b) => {
return idx[a.color[0]] - idx[b.color[0]];//sort by assigned color
});
A.forEach((e, i) => {
sh.getRange(i + 2, 1, 1, A[i].values.length).setValues([A[i].values]);
sh.getRange(i + 2, 1, 1, A[i].color.length).setBackgrounds([A[i].color]);
})
}
运行之前的原始电子表格:
颜色分配后:
颜色排序后:
我正在努力完成这个项目,但最后一部分现在让我耽搁了 2 天。我有一个 Google Sheet,非常简单,我只需要它按单元格的背景颜色自动排序。我有 7 种颜色需要按此顺序排列,并且我尝试使用 Sort Range Plus 扩展,它确实有效,但我不知道如何在编辑 sheet 时使用预先确定的参数调用它。然后我找到了一个 Apps 脚本,它应该完全满足我的需要,我想我首先启用了 Sheets API,就像论坛上说的那样,我必须在我相信有两个地方,但是当我 运行 以下代码时,我仍然在第 25/26 行出现错误:
Error: Exception: Object is not of type RgbColor.
(anonymous) @ SortByColor.gs:26
(SortByColor) @ SortByColor.gs:25
我不确定如何解决这个问题,因为它 运行s 并获取颜色然后出错。我以前没有用过javascript,所以我希望更熟悉的人可以帮助我。也许问题是我错误地启用了它还是什么?如果其他人对相同的代码没有问题,我想我可能做错了。这也是我第一次使用 Google Apps 脚本。
这是我一直在尝试的代码。请原谅注释掉的部分 - 我正在使用我在 2 个不同线程中找到的代码。
function SortByColor() {
const sheetName = "Patient Progress"; // Please set the sheet name.
//const a1Notation = "A1:A1099"; // Please set the sort range as a1Notation.
// 1. Retrieve the background colors from the cells.
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName(sheetName);
//const range = sheet.getRange(a1Notation);
var range = sheet.getRange(2, 1, ss.getLastRow(), ss.getLastColumn());
const backgrounds = range.getBackgroundObjects();
// 2. Create the request body for using the batchUpdate method of Sheets API.
/**
const startRow = range.getRow() - 1;
const startColumn = range.getColumn() - 1;
const srange = {
sheetId: sheet.getSheetId(),
startRowIndex: startRow,
endRowIndex: startRow + range.getNumRows(),
startColumnIndex: startColumn,
endColumnIndex: startColumn + range.getNumColumns(),
};**/
const sortColorOrder = ['#ea9999', '#f9cb9c', '#fff2cc', 'd9ead3', '#cfe2f3', '#d9d2e9',
'#fffff' ]; // This means that "red", "orange", "yellow", "green", "blue", "purple",
"white" in order.
const backgroundColorObj = backgrounds.reduce((o, [a]) => {
const rgb = a.asRgbColor()
return Object.assign(o, { [rgb.asHexString()]: { red: rgb.getRed() / 255, green:
rgb.getGreen() / 255, blue: rgb.getBlue() / 255 } })
}, {});
const backgroundColors = sortColorOrder.map(e => backgroundColorObj[e]);
const requests = [
{
sortRange: {
range: srange,
sortSpecs: [{ dimensionIndex: 0, sortOrder: "ASCENDING" }],
},
},
{
sortRange: {
range: srange,
//sortSpecs: [{backgroundColor: '#d9d2e9'}, {backgroundColor: '#d9ead3'},
{backgroundColor: '#fff2cc'}]
sortSpecs: backgroundColors.map((rgb) => ({ backgroundColor: rgb })),
},
},
];
// 3. Request to Sheets API using the request body.
Sheets.Spreadsheets.batchUpdate({ requests: requests }, ss.getId());
}
从你的展示脚本来看,我觉得你可能用到了我的答案
修改点:
- 在您的脚本中,
srange
未声明。 "white" in order.
和{backgroundColor: '#fff2cc'}]
行用作脚本行而不是注释。- 您设置了
'#fffff'
的十六进制颜色。在这种情况下,我认为它是'#ffffff'
。如果使用'#fffff'
,则白色背景不排序。请注意这一点。 关于var range = sheet.getRange(2, 1, ss.getLastRow(), ss.getLastColumn());
,Rubén的评论已经提到了。
将这些点反映到示例脚本中,就变成了下面的样子。
我无法知道您实际电子表格中单元格的背景颜色。所以在这个修改中,我假设你在“A”列使用 ['#ea9999', '#f9cb9c', '#fff2cc', 'd9ead3', '#cfe2f3', '#d9d2e9', '#ffffff']
的背景颜色。请注意这一点。
修改后的脚本:
请再次确认 Sheets API 是否已经启用。
function myFunction() {
const sheetName = "Patient Progress"; // Please set the sheet name.
// 1. Retrieve the background colors from the cells.
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName(sheetName);
const range = sheet.getRange(2, 1, ss.getLastRow() - 1, ss.getLastColumn());
const backgrounds = range.getBackgroundObjects();
// 2. Create the request body for using the batchUpdate method of Sheets API.
const sortColorOrder = ['#ea9999', '#f9cb9c', '#fff2cc', 'd9ead3', '#cfe2f3', '#d9d2e9', '#ffffff']; // This means that "red", "orange", "yellow", "green", "blue", "purple", "white" in order.
const backgroundColorObj = backgrounds.reduce((o, [a]) => {
const rgb = a.asRgbColor();
const hex = rgb.asHexString();
return Object.assign(o, { [hex == "#ffffffff" ? "#ffffff" : hex]: { red: rgb.getRed() / 255, green: rgb.getGreen() / 255, blue: rgb.getBlue() / 255 } });
}, {});
const backgroundColors = sortColorOrder.map(e => backgroundColorObj[e] || "").filter(String);
if (backgroundColors.length == 0) return;
const startRow = range.getRow() - 1;
const startColumn = range.getColumn() - 1;
const srange = {
sheetId: sheet.getSheetId(),
startRowIndex: startRow,
endRowIndex: startRow + range.getNumRows(),
startColumnIndex: startColumn,
endColumnIndex: startColumn + range.getNumColumns()
};
const requests = [
{ sortRange: { range: srange, sortSpecs: [{ dimensionIndex: 0, sortOrder: "ASCENDING" }] } },
{ sortRange: { range: srange, sortSpecs: backgroundColors.map(rgb => ({ backgroundColor: rgb })) } }
];
// 3. Request to Sheets API using the request body.
Sheets.Spreadsheets.batchUpdate({ requests: requests }, ss.getId());
}
注:
遗憾的是,我不知道您的实际电子表格中的背景颜色。因此,在您的实际电子表格中,当使用
['#ea9999', '#f9cb9c', '#fff2cc', 'd9ead3', '#cfe2f3', '#d9d2e9', '#ffffff']
颜色以外的背景颜色时,这些颜色将被忽略。请注意这一点。作为重点,在使用
getBackgroundObjects()
时,我确认了白底的十六进制值为#ffffffff
。我不确定这是错误还是当前规范。所以在这种情况下,#ffffffff
被修改为#ffffff
.
参考文献:
- 相关线程。
- Sort values by color in Google Sheets by using google APP Script
函数随机为行分配颜色,并根据每行的颜色对数据集进行排序。
代码:
function colorSort0() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Sheet0");
let vs = sh.getRange(2, 1, sh.getLastRow() - 1, 20).getValues();
let bs = sh.getRange(2, 1, sh.getLastRow() - 1, 20).getBackgrounds();
const colors = {};
const idx = {};
sh.getRange("X1:X8").getBackgrounds().flat().forEach((b, i) => { colors[i] = b; idx[b] = i; });
bs.forEach((r, i) => {
let color = colors[Math.floor(Math.random() * Object.keys(colors).length)];//assigned colors randomyly
sh.getRange(i + 2, 1, 1, 20).setBackground(color);
SpreadsheetApp.flush();//Display all assigned colors in the spreadsheet
});
vs = sh.getRange(2, 1, sh.getLastRow() - 1, 20).getValues();
bs = sh.getRange(2, 1, sh.getLastRow() - 1, 20).getBackgrounds();//pickup assigned colors
let A = vs.map((r, i) => {
return { values: r, color: bs[i] };
});
A.sort((a, b) => {
return idx[a.color[0]] - idx[b.color[0]];//sort by assigned color
});
A.forEach((e, i) => {
sh.getRange(i + 2, 1, 1, A[i].values.length).setValues([A[i].values]);
sh.getRange(i + 2, 1, 1, A[i].color.length).setBackgrounds([A[i].color]);
})
}
运行之前的原始电子表格:
颜色分配后:
颜色排序后: