I'm trying to filter rows by if certain columns aren't empty. I am determining those "certain columns" with a control row of true or false values. How can I do this with formula only (not custom functions) for speed and to keep the images/formulas working when the data spreads through the sheet?
Continue reading for more context and better a wording of the question.
EDIT: Follow this link for a copy of the actual Spreadsheet.
I have a Google Spreadsheet with a sheet that has a table of characters in a video game. It looks something like this:
Name | Title | Uses Mana | Is Melee | Is Ranged | Assassin | Tank |
---|---|---|---|---|---|---|
Ezra | the Wanted | ⚔️ | 🛡️ | |||
Joel | the Priest | 💧 | 🏹 | |||
Kat | the Hidden | 💧 | ⚔️ | 🥷 |
Each of the icons used to indicate a true value, however, is a formula pointing to a cell with the appropriate image.
Name | Title | Uses Mana | Is Melee | Is Ranged | Assassin | Tank |
---|---|---|---|---|---|---|
=image(💧) |
=image(⚔️) |
=image(🏹) |
=image(🥷) |
=image(🛡️) |
||
Ezra | the Wanted | =icon above |
=icon above |
|||
Joel | the Priest | =icon above |
=icon above |
|||
Kat | the Hidden | =icon above |
=icon above |
=icon above |
The next sheet in the Spreadsheet is supposed to make it easy to filter rows by using checkboxes:
Name | Title | Uses Mana | Is Melee | Is Ranged | Assassin | Tank |
---|---|---|---|---|---|---|
=image(💧) |
=image(⚔️) |
=image(🏹) |
=image(🥷) |
=image(🛡️) |
||
Clear: | 🟦 | <⏹️> | 🟦 | 🟦 | 🟦 | 🟦 |
Joel | the Priest | =icon above |
=icon above |
|||
Kat | the Hidden | =icon above |
=icon above |
=icon above |
||
_ |
Note: Ezra is gone because Uses Mana was selected in the filters.
I got it to do what I want with a custom function, but it's very slow (there are a lot of characters in the game) and doesn't keep the images:
=filterRows("'Sheet 1'!A3:G", 'Sheet 2'!C3:G3, 2)
Note: I ignore the first two columns in the [filterrow] because I still need to include the Name and Title, but they'll never be filtered and the cells above can't just be left as "TRUE" checkboxes.
/**
* Filters rows in a range by a control row containing boolean values indicating whether or not to check that column of each row for data.
*
* @param {"A2:5"} rows A string in A1 notation indicating the desired range to filter.
* @param {A1:A5} filterrow A range containing a single row of boolean values.
* @param {2} offset The number of columns to ignore from the start of each row in [rows]. The first value will be compared with the first value in [filterrow].
* @param {1, 3, ...} ...ignorecolumns The values to always treat as true in [filterrow]. 1 is the first value in the row.
* @return The rows that had values in the matching true columns of [filterrow].
* @customfunction
*/
function filterRows(rows, filterrow, offset = 0, ...ignorecolumns) {
rows = SpreadsheetApp.getActiveSpreadsheet().getRange(rows);
let data = [];
for(var i = 1; i <= rows.getNumRows(); i++) {
let matches = 0
let match = 0;
filterrow[0].forEach((filter, n) => {
if(!ignorecolumns.includes(n+1) && filter) {
matches++;
if(rows.getCell(i, n+1+offset).getValue() != "") match++;
}
});
if(matches == match) {
let row = [];
for(var n = 1; n <= rows.getNumColumns(); n++) {
let cell = rows.getCell(i, n);
row.push(cell.getFormula() || cell.getValue());
}
data.push(row);
}
}
if(data.length == 0) return "No match";
return data;
}
Is it possible to achieve the same effect as the custom function above with formula only?
Basically, If I have two sheets like this:
Name | Title | Uses Mana | Is Melee | Is Ranged | Assassin | Tank |
---|---|---|---|---|---|---|
=image(💧) |
=image(⚔️) |
=image(🏹) |
=image(🥷) |
=image(🛡️) |
||
Ezra | the Wanted | =icon above |
=icon above |
|||
Joel | the Priest | =icon above |
=icon above |
|||
Kat | the Hidden | =icon above |
=icon above |
=icon above |
Name | Title | Uses Mana | Is Melee | Is Ranged | Assassin | Tank |
---|---|---|---|---|---|---|
=image(💧) |
=image(⚔️) |
=image(🏹) |
=image(🥷) |
=image(🛡️) |
||
Clear: | 🟦 | 🟦 | 🟦 | 🟦 | 🟦 | 🟦 |
=filter(...) |
||||||
_ | ||||||
_ |
How can I use formula, in cell A4 (=filter(...)
), instead of a custom function, to filter the rows in Sheet 1 by which columns, marked in the checkboxes of Sheet 2, aren't empty?
It's a very niche need, I know. Any help would be appreciated!