Issue:
- Undesirable addition of empty strings in all the available rows by traditional usage of
ARRAYFORMULA(IF(A:A="",...))
Solution:
-
Using
ARRAYFORMULA
properly withINDEX/COUNTA
(to determine the last row that’s needed) ensures formula is only filled upto the needed row instead of a camouflage -
INDEX/COUNTA
:INDEX
returns a value as well as a cell reference.A2:INDEX(A2:A,COUNTA(A2:A))
=> IfCOUNTA(...)
returns 10 =>A2:INDEX(A2:A,10)
=>A2:A11
is the final reference feeded to weeknum -
Assuming there are no blanks in between your data,
=ARRAYFORMULA(WEEKNUM(A2:INDEX(A2:A,COUNTA(A2:A)),2))
-
Another alternative is to use
ARRAY_CONSTRAIN/COUNTA
:=ARRAY_CONSTRAIN(ARRAYFORMULA(WEEKNUM(A2:A, 2)),COUNTA(A2:A))
-
The usage of
COUNTA
assumes there are no blank cells in between. If there are any, you may need to manually add a offset. If there are two blank cells, add 2 toCOUNTA
A2:INDEX(A2:A,COUNTA(A2:A)+2)
Unless Google does inbuilt optimizations, INDEX/COUNTA
is preferred over ARRAY_CONSTRAIN
.
It might be hard to fix those array formulas with INDEX/COUNTA
manually, so I made a script. This is just a proof of concept and alpha quality. So, test it in a copy of your spreadsheet rather than on the original. Having said that, I’m sure it’ll handle most common cases without trouble.
/**
* @see https://stackoverflow.com/a/46884012
*/
function fixArrayFormulas_so46884012() {
const ss = SpreadsheetApp.getActive()/*.getSheetByName('Sheet1')*/,
map = new Map([
[
// Normalize first part of range
/* A:F */ String.raw`([a-z]+):([a-z]+)`,
/* A1:F*/ String.raw`$11:$2`,
],
[
// Convert any previous index/counta to normal ranges
/* A1:INDEX(F:F,COUNTA(F:F)) */ String.raw`([a-z]+\d+):INDEX\(([a-z]+)\d*:\w+,COUNTA\(\w+:\w+\)\)`,
/*A1:F*/ String.raw`$1:$2`,
],
[
// Convert open ended ranges to index/counta ranges
/*A1:F*/ String.raw`([a-z]+\d+:)([a-z]+)`,
/* A1:INDEX(F:F,COUNTA(F:F)) */ `$1INDEX($2:$2,COUNTA($2:$2))`,
],
]);
map.forEach((v, k) =>
ss
.createTextFinder(k)
.matchFormulaText(true)
.useRegularExpression(true)
.replaceAllWith(v)
);
}