I can import multiple ranges to a page using the following formula:
{{"Source","Date" ,"Amount" ,"Business" ,"Category" ,"TransactionID" ,"Account" ,"Status"};
Let(SheetID,B1,SheetName, A1, query(IMPORTRANGE(SheetID,"___Transactions"),"Select '"&SheetName&"', Col1, Col2, Col3, Col4, Col5, Col6, Col7 Where Col1 Is Not Null Label '"&SheetName&"' ''",0));
Let(SheetID,B2,SheetName, A2, query(IMPORTRANGE(SheetID,"___Transactions"),"Select '"&SheetName&"', Col1, Col2, Col3, Col4, Col5, Col6, Col7 Where Col1 Is Not Null Label '"&SheetName&"' ''",0));
Let(SheetID,B3,SheetName, A3, query(IMPORTRANGE(SheetID,"___Transactions"),"Select '"&SheetName&"', Col1, Col2, Col3, Col4, Col5, Col6, Col7 Where Col1 Is Not Null Label '"&SheetName&"' ''",0))
}
However I need to edit the function everytime a new sheet is added to the list.
Is there a way to simplify this formula using ARRAYFORMULA?
I tried different ways and got the following error:
"In ARRAY_LITERAL, an Array Literal was missing values for one or more rows."
This is the array formula version I used:
={{"Source","Date" ,"Amount" ,"Business" ,"Category" ,"TransactionID" ,"Account" ,"Status"};
ARRAYFORMULA( Let(SheetID,B1:B3,SheetName, A1:A3, query(IMPORTRANGE(SheetID,"___Transactions"),"Select '"&SheetName&"', Col1, Col2, Col3, Col4, Col5, Col6, Col7 Where Col1 Is Not Null Label '"&SheetName&"' ''",0)))
}
I also tried using MAP function as shown below:
=MAP(A1:A3,B1:B3,LAMBDA(SheetName,SheetID,query(IMPORTRANGE(SheetID,"___Transactions"),"Select '"&SheetName&"', Col1, Col2, Col3, Col4, Col5, Col6, Col7 Where Col1 Is Not Null Label '"&SheetName&"' ''",0)))
However, Got the following errors:
- Spreadsheet can not be found
- Result should be a single row.
Sample Data: (link to sample sheet
1) Sheet1-Data
Date | Amount | TransactionID |
---|---|---|
2023-02-02 | $ (94.50) | V57o5QN75bT0Kx97wQqAT0dXVEEBDEIzYBZ3z |
2023-02-02 | $ (9.62) | 0zE49vpJqQiOYdd9MQXBHgeQzvoPr6Fv9XL5M |
2023-02-02 | $ (14.21) | jxd6JDPr9AsdgjjazyQRCKg57Q4V3DFjvB4YZ |
2023-02-02 | $ (9.62) | xxyY5XAeQNujML760deKtNzzyAaVqdHKOQ78M |
2023-02-02 | $ (14.21) | Jzke7R3VD5ioqkyRZj1XCMqqvjdrneI7mvKRm |
2023-02-03 | $ (30.00) | 1jvOVvMp9yTNnaOLrRX8s0g9gPxbLKHg8LOV3 |
2023-02-03 | $ (1,472.60) | gM1ZM8N1Mdta76BP4n59Ca53dQQLkQcMaRdk6 |
2023-02-03 | $ (10.00) | 7VpqVKPpVZCN7jEAX93qSyKamNNX5NF4EN7J5 |
2023-02-03 | $ (3.50) | 9ON3OABNOnFJXm9roE85cYrLvJJ0wJiP4Q5qk |
I can import multiple ranges to a page using the following formula:
{{"Source","Date" ,"Amount" ,"Business" ,"Category" ,"TransactionID" ,"Account" ,"Status"};
Let(SheetID,B1,SheetName, A1, query(IMPORTRANGE(SheetID,"___Transactions"),"Select '"&SheetName&"', Col1, Col2, Col3, Col4, Col5, Col6, Col7 Where Col1 Is Not Null Label '"&SheetName&"' ''",0));
Let(SheetID,B2,SheetName, A2, query(IMPORTRANGE(SheetID,"___Transactions"),"Select '"&SheetName&"', Col1, Col2, Col3, Col4, Col5, Col6, Col7 Where Col1 Is Not Null Label '"&SheetName&"' ''",0));
Let(SheetID,B3,SheetName, A3, query(IMPORTRANGE(SheetID,"___Transactions"),"Select '"&SheetName&"', Col1, Col2, Col3, Col4, Col5, Col6, Col7 Where Col1 Is Not Null Label '"&SheetName&"' ''",0))
}
However I need to edit the function everytime a new sheet is added to the list.
Is there a way to simplify this formula using ARRAYFORMULA?
I tried different ways and got the following error:
"In ARRAY_LITERAL, an Array Literal was missing values for one or more rows."
This is the array formula version I used:
={{"Source","Date" ,"Amount" ,"Business" ,"Category" ,"TransactionID" ,"Account" ,"Status"};
ARRAYFORMULA( Let(SheetID,B1:B3,SheetName, A1:A3, query(IMPORTRANGE(SheetID,"___Transactions"),"Select '"&SheetName&"', Col1, Col2, Col3, Col4, Col5, Col6, Col7 Where Col1 Is Not Null Label '"&SheetName&"' ''",0)))
}
I also tried using MAP function as shown below:
=MAP(A1:A3,B1:B3,LAMBDA(SheetName,SheetID,query(IMPORTRANGE(SheetID,"___Transactions"),"Select '"&SheetName&"', Col1, Col2, Col3, Col4, Col5, Col6, Col7 Where Col1 Is Not Null Label '"&SheetName&"' ''",0)))
However, Got the following errors:
- Spreadsheet can not be found
- Result should be a single row.
Sample Data: (link to sample sheet
1) Sheet1-Data
Date | Amount | TransactionID |
---|---|---|
2023-02-02 | $ (94.50) | V57o5QN75bT0Kx97wQqAT0dXVEEBDEIzYBZ3z |
2023-02-02 | $ (9.62) | 0zE49vpJqQiOYdd9MQXBHgeQzvoPr6Fv9XL5M |
2023-02-02 | $ (14.21) | jxd6JDPr9AsdgjjazyQRCKg57Q4V3DFjvB4YZ |
2023-02-02 | $ (9.62) | xxyY5XAeQNujML760deKtNzzyAaVqdHKOQ78M |
2023-02-02 | $ (14.21) | Jzke7R3VD5ioqkyRZj1XCMqqvjdrneI7mvKRm |
2023-02-03 | $ (30.00) | 1jvOVvMp9yTNnaOLrRX8s0g9gPxbLKHg8LOV3 |
2023-02-03 | $ (1,472.60) | gM1ZM8N1Mdta76BP4n59Ca53dQQLkQcMaRdk6 |
2023-02-03 | $ (10.00) | 7VpqVKPpVZCN7jEAX93qSyKamNNX5NF4EN7J5 |
2023-02-03 | $ (3.50) | 9ON3OABNOnFJXm9roE85cYrLvJJ0wJiP4Q5qk |
2) Sheet2-Data
Date | Amount | TransactionID |
---|---|---|
2023-01-23 | $ (7.47) | 78paYk1VVYcMn7Vq3YgYTLjd5X7VJpC0bwBqb |
2023-01-23 | $ (4.80) | gE1q03aMM0fAM7K95bmbsmZ4kLB0MDC8rBxDd |
2023-01-23 | $ (6.07) | 5mQRYyLzzYtPJvDa9zgzU5OaXBeEo0SwryOKg |
2023-01-23 | $ (11.07) | J0j6KvRXXKuZnRNOdAgAtYqpLaKxwOhmK6BpD |
2023-01-23 | $ (20.16) | 4aRbY36VVYc1wV9aNXrXc5MpV8yedYSRaeMQ3 |
2023-01-23 | $ (2.10) | xM8On7XKKnU0w6QYNPgPsoz5b7Pkj6IO7YkvX |
2023-01-23 | $ (92.41) | 8ZXaYAPVVYu3g09B6bRbSnpawArv94FxopR9E |
2023-01-23 | $ (2.33) | aENw3LR553f5p3oP4gbgSbP6gmQae0U70RweM |
2023-01-23 | $ (6.59) | ZEMP6na556fmZzEbK5j5s8Qg0xdPZeIbeX3x5 |
3) Sheet3-Data
Date | Amount | TransactionID |
---|---|---|
2021-01-04 | $ (3.00) | YzARZZ8JdeCgdXKNEk57IdDaBqnvAoUQpXVKE |
2021-01-04 | $ (3.00) | ddoVnnEMKOCYgM8x4qorIVa5npDQNvfb16rbv |
2021-01-04 | $ 2,995.00 | z8gprr4xYbCqkj0aAQbEHKXJNPzEO4IOBDx6q |
2021-01-05 | $ 1,000.00 | ewom99REkOTjgPZdrvXqs1qNJxKLdOUdegV87 |
2021-01-06 | $ (999.52) | Xzk9QQJxepCA4jy7EKZOtgLzmDxEaqS4PLp36 |
2021-01-06 | $ (1,298.00) | NzZ988KyYpCXLrdn7wARF9VXm0Y1retRb7P1Q |
2021-01-08 | $ (207.00) | pkXjqqByZbhVxr14ZbA5UwLodzYvJOUJQxV9Q |
2021-01-08 | $ (15.00) | nyqVmmPBJNS5vnLBw7rdHYaZMbLkAJIAqvybM |
2021-01-12 | $ 100.00 | QzrmbbvAepC5oMLOYnj7Hk65AnMg4QFEbqnpz |
Expected Output:
Date | Amount | TransactionID |
---|---|---|
2023-02-02 | $ (94.50) | V57o5QN75bT0Kx97wQqAT0dXVEEBDEIzYBZ3z |
2023-02-02 | $ (9.62) | 0zE49vpJqQiOYdd9MQXBHgeQzvoPr6Fv9XL5M |
2023-02-02 | $ (14.21) | jxd6JDPr9AsdgjjazyQRCKg57Q4V3DFjvB4YZ |
2023-02-02 | $ (9.62) | xxyY5XAeQNujML760deKtNzzyAaVqdHKOQ78M |
2023-02-02 | $ (14.21) | Jzke7R3VD5ioqkyRZj1XCMqqvjdrneI7mvKRm |
2023-02-03 | $ (30.00) | 1jvOVvMp9yTNnaOLrRX8s0g9gPxbLKHg8LOV3 |
2023-02-03 | $ (1,472.60) | gM1ZM8N1Mdta76BP4n59Ca53dQQLkQcMaRdk6 |
2023-02-03 | $ (10.00) | 7VpqVKPpVZCN7jEAX93qSyKamNNX5NF4EN7J5 |
2023-02-03 | $ (3.50) | 9ON3OABNOnFJXm9roE85cYrLvJJ0wJiP4Q5qk |
2023-01-23 | $ (7.47) | 78paYk1VVYcMn7Vq3YgYTLjd5X7VJpC0bwBqb |
2023-01-23 | $ (4.80) | gE1q03aMM0fAM7K95bmbsmZ4kLB0MDC8rBxDd |
2023-01-23 | $ (6.07) | 5mQRYyLzzYtPJvDa9zgzU5OaXBeEo0SwryOKg |
2023-01-23 | $ (11.07) | J0j6KvRXXKuZnRNOdAgAtYqpLaKxwOhmK6BpD |
2023-01-23 | $ (20.16) | 4aRbY36VVYc1wV9aNXrXc5MpV8yedYSRaeMQ3 |
2023-01-23 | $ (2.10) | xM8On7XKKnU0w6QYNPgPsoz5b7Pkj6IO7YkvX |
2023-01-23 | $ (92.41) | 8ZXaYAPVVYu3g09B6bRbSnpawArv94FxopR9E |
2023-01-23 | $ (2.33) | aENw3LR553f5p3oP4gbgSbP6gmQae0U70RweM |
2023-01-23 | $ (6.59) | ZEMP6na556fmZzEbK5j5s8Qg0xdPZeIbeX3x5 |
2021-01-04 | $ (3.00) | YzARZZ8JdeCgdXKNEk57IdDaBqnvAoUQpXVKE |
2021-01-04 | $ (3.00) | ddoVnnEMKOCYgM8x4qorIVa5npDQNvfb16rbv |
2021-01-04 | $ 2,995.00 | z8gprr4xYbCqkj0aAQbEHKXJNPzEO4IOBDx6q |
2021-01-05 | $ 1,000.00 | ewom99REkOTjgPZdrvXqs1qNJxKLdOUdegV87 |
2021-01-06 | $ (999.52) | Xzk9QQJxepCA4jy7EKZOtgLzmDxEaqS4PLp36 |
2021-01-06 | $ (1,298.00) | NzZ988KyYpCXLrdn7wARF9VXm0Y1retRb7P1Q |
2021-01-08 | $ (207.00) | pkXjqqByZbhVxr14ZbA5UwLodzYvJOUJQxV9Q |
2021-01-08 | $ (15.00) | nyqVmmPBJNS5vnLBw7rdHYaZMbLkAJIAqvybM |
2021-01-12 | $ 100.00 | QzrmbbvAepC5oMLOYnj7Hk65AnMg4QFEbqnpz |
2 Answers
Reset to default 0I'm not sure If I missed something in the question, but the below basic and straightforward formula does the job. If there is a new sheet, you can update the query data {Sheet1!A2:C; Sheet2!A2:C; Sheet3!A2:C; etc..}
:
=QUERY(
{Sheet1!A2:C; Sheet2!A2:C; Sheet3!A2:C},
"select Col1, Col2, Col3 where Col1 is not null order by Col1 asc",
0
)
Regarding:
However I need to edit the function everytime a new sheet is added to the list.
To avoid updating your formula every time you add a sheet, you can create a custom function that automatically combines data from all sheets (regardless of their names) except those you want to ignore. For example, you can set up a sheet called Exception: where you list the names of sheets to ignore (like “Final
” and “Exception
”).
Exception Sheet:
Final Sheet:
Place in A1 this formula:
=getCombinedData(Exception!A2:A)
Open Extensions > Apps Script in your Google Sheet and paste in this code:
Code:
/**
* Combines data from all sheets (columns A:C starting at row 2) in the order they appear,
* excluding any sheets whose names are listed in the given exception range.
*
* @param {Range} exceptionRange A vertical range listing sheet names to ignore (for example, Final, Exception).
* @return {Array} A 2D array with a header row followed by the combined data.
* @customfunction
*/
function getCombinedData(exceptionRange) {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheets = ss.getSheets();
// Manually flatten the exceptionRange (it comes in as a 2D array)
let exValues = [];
if (exceptionRange && Array.isArray(exceptionRange)) {
if (Array.isArray(exceptionRange[0])) {
exValues = exceptionRange.reduce((acc, row) => acc.concat(row), []);
} else {
exValues = exceptionRange;
}
}
// Build a set of sheet names to ignore.
const exceptions = new Set();
exValues.forEach(name => {
if (name && typeof name === 'string') {
exceptions.add(name.trim());
}
});
const header = ["Date", "Amount", "TransactionID"];
let combinedData = [];
// Process sheets in the order they appear.
sheets.forEach(sheet => {
const sheetName = sheet.getName();
if (exceptions.has(sheetName)) return; // Skip this sheet.
const lastRow = sheet.getLastRow();
if (lastRow < 2) return; // No data.
// Get data from A2:C.
const data = sheet.getRange(2, 1, lastRow - 1, 3).getValues();
// Remove rows where Date is empty.
const validData = data.filter(row => row[0] !== "" && row[0] !== null);
if (validData.length > 0) {
combinedData = combinedData.concat(validData);
}
});
// Return the header row plus all the data.
return [header, ..binedData];
}
It's unclear whether your different sheets containing that month's transactions are located within the same spreadsheet or if they are indeed located in separate spreadsheets. I would advice that at a minimum, you keep at least 12 months for a year on the same spreadsheet...all of them if you can.
I've updated your sample spreadsheet with examples of how to handle both cases.
Template Sheet
To begin with, since each of your sheets appear to be structured the same, I recommend you make a Template sheet. Include a table for your transactions and any other summary or additional data tables that you want for each month. Assign Named Ranges to key ranges that you would like to access on each sheet later on. When you're ready to create a new month's sheet for transaction, right-click on this Template's tab and duplicate it. The named ranges will also be duplicated.
Separate Spreadsheets
If these sheets are in fact on separate spreadsheets, then REDUCE over the sheet names and the SpreadsheetIDs.
=REDUCE({"Date","Amount","TransactionID"},SEQUENCE(COUNTA(F:F)-1,1,2),LAMBDA(tot,i,
IF(LEN(INDEX(F:F,i)),
IFERROR(VSTACK(tot,
QUERY(IMPORTRANGE(INDEX(G:G,i),INDEX(F:F,i)&"!Transactions"),
"Select * Where Col1 Is Not Null label Col1 '', Col2 '', Col3 ''",1))),
tot)))
Different Sheets/Same Spreadsheet
If all of your monthly sheets are in the same spreadsheet, you don't need to use IMPORTRANGE or be concerned about the SpreadsheetID. To combine current and future month's sheets, be sure to have a naming scheme for each sheet. My naming scheme is Feb 25. Designate a start date to go along with your first month's sheet name.My start date is located in F1. Here's the modified version of rockinfreakshow's REDUCE formula. It goes month-by-month checking first to see if that month is a valid sheet name and stacks together the ones that are valid.
=REDUCE({"Date","Amount","TransactionID"},
SEQUENCE(DATEDIF(F1,TODAY(),"M")),
LAMBDA(tot,i,
IF(ISREF(INDIRECT(TEXT(EOMONTH(F1,i-1),"MMM YY")&"!Transactions")),
IFERROR(VSTACK(
tot,
QUERY(
INDIRECT(TEXT(EOMONTH(F1,i-1),"MMM YY")&"!Transactions"),
"Select * Where Col1 Is Not Null label Col1 '', Col2 '', Col3 ''",1))),
tot)))
map()
,reduce()
should do. similar Q&A here which you could improvise on... – rockinfreakshow Commented 2 days ago=Query( {Sheet1!A:Z ; Sheet2!A:Z ; Sheet3!A:Z },"Select * WHERE Col1 IS NOT NULL ")
– leylou Commented 23 hours ago