Google Sheets web app (rolling service) ยท Combining and checking data ยท Intermediate
Combine Google Sheets tabs with QUERY and keep one header
Build a monthly-tab report, preserve the first record, exclude rows without the required RecordID, and reconcile every tab before and after growth.
Official documentation reviewed; synthetic outputs independently calculated; not tested in Google Sheets. ยท Editorial standards
Keep the first tab’s header, start every later tab at row 2, and set QUERY’s final argument to 1. Then check the combined records against each source tab. A correct-looking heading does not prove that the first transaction survived.
This workflow builds a report from monthly tabs inside one Google Sheets file. It adds reconciliation and a growth test to the QUERY function reference, rather than relying on the header setting alone.
Before you start
Use a practice spreadsheet or a copy you are allowed to edit. Create tabs named Jan, Feb, and Report. Keep Report empty. These examples use English function names and comma argument separators. Use numeric values for Month and Amount; the RecordID values are text. The checks assume the sheet has recalculated after each edit.
The four columns must mean the same thing, in the same order, on both tabs. Stacking does not match fields by their headings. Decide which field identifies a real record: here RecordID is required, while Region is optional and Amount may legitimately be zero.
1. Enter the two source tables
Enter the following cells exactly. A dash in the table means leave the cell empty, not type a dash.
Jan!A1:D6
| Sheet row | A: RecordID | B: Month | C: Region | D: Amount |
|---|---|---|---|---|
| 1 | RecordID | Month | Region | Amount |
| 2 | J-101 | 1 | North | 120 |
| 3 | J-102 | 1 | South | 80 |
| 4 | โ | โ | โ | โ |
| 5 | J-103 | 1 | โ | 50 |
| 6 | J-104 | 1 | North | 0 |
Feb!A1:D6
| Sheet row | A: RecordID | B: Month | C: Region | D: Amount |
|---|---|---|---|---|
| 1 | RecordID | Month | Region | Amount |
| 2 | F-201 | 2 | South | 90 |
| 3 | F-202 | 2 | North | 60 |
| 4 | โ | โ | โ | โ |
| 5 | F-203 | 2 | South | 30 |
| 6 | โ | โ | โ | โ |
Alternatively, import the January CSV and February CSV into separate practice tabs, then rename them. CSV files contain values only, without tab names or formulas. Check that the intentional empty row remains at row 4; see Google’s CSV import instructions.
2. Assemble the report with an explicit header count
In Report!A1, enter:
=QUERY({Jan!A1:D6;Feb!A2:D5},"select Col1,Col2,Col3,Col4 where Col1 is not null order by Col2,Col1 label Col1 'Record ID',Col2 'Month',Col3 'Region',Col4 'Amount'",1)
Read the formula as a small data pipeline:
{Jan!A1:D6;Feb!A2:D5}creates one four-column input. Only January contributes a heading row. Google’s array documentation describes vertical range joining with the semicolon inside braces.- The final
1tells QUERY that one row at the top of that combined input is a header. It does not mean one header per tab. Omitting it permits inference. See Google’s QUERY header argument. Col1throughCol4address positions in the constructed array.where Col1 is not nullkeeps identified records. Filtering Region instead would wrongly remove J-103; filtering Amount for positive values would wrongly remove J-104.order by Col2,Col1makes the display order explicit. Thelabelclause sets output headings; it does not rescue input rows incorrectly classified as headers. Google query-language reference.
The complete expected output is eight rows by four columns, including the header:
| Record ID | Month | Region | Amount |
|---|---|---|---|
| J-101 | 1 | North | 120 |
| J-102 | 1 | South | 80 |
| J-103 | 1 | 50 | |
| J-104 | 1 | North | 0 |
| F-201 | 2 | South | 90 |
| F-202 | 2 | North | 60 |
| F-203 | 2 | South | 30 |
These are independently calculated expectations, not a captured Google Sheets result.
3. Reconcile the whole result
Use a separate Checks tab so diagnostic formulas cannot obstruct Report’s expanding output.
| Check | Formula | Expected |
|---|---|---|
| January source records | =COUNTA(Jan!A2:A) |
4 |
| January reported records | =COUNTIF(Report!B2:B,1) |
4 |
| February source records | =COUNTA(Feb!A2:A) |
3 |
| February reported records | =COUNTIF(Report!B2:B,2) |
3 |
| January source amount | =SUM(Jan!D2:D) |
250 |
| January reported amount | =SUMIF(Report!B2:B,1,Report!D2:D) |
250 |
| February source amount | =SUM(Feb!D2:D) |
180 |
| February reported amount | =SUMIF(Report!B2:B,2,Report!D2:D) |
180 |
| Overall reported amount | =SUM(Report!D2:D) |
430 |
These count checks assume the supplied literal IDs, not formulas returning empty strings. For your real data, choose a source count that follows your record-identification rule. COUNTIF and SUMIF explain the individual checks.
Inspect J-101, J-104 and F-203 as well as the totals. All seven IDs must appear once. Matching totals alone can conceal a missing zero-value record or two offsetting mistakes.
4. Make growth part of the test
Replace the report formula with this open-ended version:
=QUERY({Jan!A1:D;Feb!A2:D},"select Col1,Col2,Col3,Col4 where Col1 is not null order by Col2,Col1 label Col1 'Record ID',Col2 'Month',Col3 'Region',Col4 'Amount'",1)
Then enter F-204, 2, North, 45 into Feb!A6:D6. The report should now contain eight data records plus its header. F-204 is the last record, February has four records totaling 225, January remains 250, and the combined amount is 475. The original bounded formula stops February at row 5, so it would omit this new record. Open-ended ranges avoid that cut-off.
Open-ended ranges can cost more calculation work. For a large file, use a deliberate shared capacity such as Jan!A1:D5000 and Feb!A2:D5000. Ensure both tabs have that capacity and review the limit before it fills. Google’s performance guidance recommends closed ranges where practical. Every additional month must be added deliberately; neither formula discovers new tabs by itself.
Diagnose failures without discarding valid records
Run each negative case separately in a disposable copy, starting with the original seven-record fixture.
| Change | What it reveals | Safe repair |
|---|---|---|
Start both ranges at row 2 but leave the final argument at 1 |
J-101 is consumed as input header material. The data count becomes six and the amount total becomes 310. | Use 0 when the combined input has no heading row, or restore the first range to A1:D6. |
Include Feb!A1:D6 |
The second header is inside the data body. Its nonempty RecordID cell can survive the ID filter as a bogus record. | Exclude later header rows by range design. Do not increase the header count to two; those two headers are not adjacent at the top. |
| Swap February’s Region and Amount columns | Equal width does not guarantee matching meanings. | Restore the common column order before stacking. |
| Add an amount to a row with no RecordID | The row is excluded by this report’s stated policy, although the source amount check still counts it. | Investigate and assign the correct ID. If IDs are optional in your real process, design a different inclusion rule before using this formula. |
| An amount disappears while its ID survives | A source type problem may be involved. | Compare the original cell with the QUERY mixed-type diagnosis. Do not silently replace missing values with zero. |
For the no-input-header variant, the corrected formula is:
=QUERY({Jan!A2:D6;Feb!A2:D5},"select Col1,Col2,Col3,Col4 where Col1 is not null order by Col2,Col1 label Col1 'Record ID',Col2 'Month',Col3 'Region',Col4 'Amount'",0)
It should recover the same seven data records. If the error instead concerns array expansion, inspect the output area and move conflicting content somewhere safe. Do not erase source data to make room.
Locale, platform and testing scope
Google Sheets is a rolling service, not a numbered desktop edition. This workflow targets its web app. Formula argument separators can differ with locale; separators inside array braces have a separate role. Google documents a backslash column separator for decimal-comma locales. Keep the quoted query text intact. Review spreadsheet locale and function-language settings before adapting punctuation.
VSTACK is another way to construct the combined array, but it still needs the same column alignment, header choices and reconciliation. An Excel or other-program export is not evidence that this Google Sheets formula ran correctly.
Verification: First-party documentation checked October 16, 2026. All fixture rows, per-tab counts, totals and negative-case arithmetic were checked independently. Not tested in Google Sheets. The formulas and expected outcomes have not been verified in the application, and no application screenshots are presented. Test on a synthetic copy before applying the workflow to a live report.