Eu tenho uma pasta de trabalho do Excel com várias planilhas, algumas delas contendo um valor numérico na célula A1
:
'DATA_1' 'DATA_2' 'DATA_3'
A A A
1 1.6 1 -0.8 1
Eu quero determinar o número de A1
células por uma única fórmula em toda a pasta de trabalho que contém dados, portanto, o resultado para o exemplo acima deve ser 2
porque a célula na última planilha está em branco.
Como o número de planilhas pode variar, estou usando uma função definida pelo usuário (UDF) que retorna uma matriz contendo os nomes de todas as planilhas:
Function SHEET_NAMES() As Variant
' returns names of all sheets as an array
Dim idx As Long, retArray() As String
Application.Volatile True
With ThisWorkbook.Sheets
ReDim retArray(.Count)
For idx = 1& To .Count
retArray(idx) = .Item(idx).Name
Next idx
SHEET_NAMES() = retArray
End With
End Function
Esta UDF está funcionando bem, a fórmula {=SHEET_NAMES()}
retorna o array esperado ( {"DATA_1","DATA_2","DATA_3"}
). (Observe que a UDF precisa ser considerada não editável).
Minha ideia agora é usar o UDF junto com as funções ADDRESS()
e INDIRECT()
para fazer referência às células A1
de todas as planilhas disponíveis dinamicamente, para usar ISNUMBER()
para verificar se existe um número válido, convertendo o valor booleano FALSE
/ TRUE
para 0
/ 1
por N()
e finalmente, usar SUM()
para resumir todo o 0
/ 1
, como isso:
{=SUM(N(ISNUMBER(INDIRECT(ADDRESS(ROW(A1);COLUMN(A1);;;SHEET_NAMES())))))}
No entanto, o resultado é sempre 0
, mesmo se nenhuma planilha contiver uma célula vazia A1
.
Eu descobri que o ADDRESS()
function retorna o array correto de strings, representando as referências a todas as células A1
, qual é {"DATA_1!$A$1","DATA_2!$A$1","DATA_3!$A$1"}
.
INDIRECT()
devolve {#VALUE!,#VALUE!,#VALUE!}
como ele não suporta arrays aparentemente, no entanto, a função de contêiner ISNUMBER()
suporta arrays, então isso parece fazer a iteração sobre os elementos da matriz corretamente, e isso resulta em {TRUE,TRUE,FALSE}
.
o N()
função faz a conversão da maneira pretendida, daí resulta em {1,1,0}
.
Mas a final SUM()
sempre resulta em 0
, não importa quantas folhas existem e se algumas ou todas elas contêm números válidos em células A1
. (Apenas como um sidenote: se eu inserir a fórmula como uma função não matriz, o resultado dependerá apenas da primeira planilha.)
Eu tentei usar NOT(ISBLANK())
e NOT(ISERROR())
ao invés de ISNUMBER()
e eu tentei mudar SUM(N(ISNUMBER()))
para SUM(COUNT())
, mas sem sucesso (todos resultam em 0
, exceto NOT(ISBLANK())
que dá 3
).
(Também até tentei substituir ROW(A1)
e COLUMN(A1)
por ROWS($A$1:A1)
e COLUMNS($A$1:A1)
, respectivamente, pois isso deve superar uma questão relacionada à matriz de INDIRECT()
, de acordo com algumas páginas da Web, mas sem alterações também.
Então, você poderia me dizer o que estou fazendo de errado aqui e como superar o fracasso sem perder a flexibilidade?
(Se possível, eu preferiria uma solução sem usar COUNTIF()
ou SUMIF()
nem quaisquer outras funções que requeiram uma determinada condição para ser dada como uma string, para manter a portabilidade.)
=SUM(--(N(INDIRECT(ADDRESS(ROW(A1),COLUMN(A1),,,SHEET_NAMES())))<>0))
0
pode aparecer nas células também; a--
converte booleanos em números (semelhante aN()
), certo?-
converteFalse
para0
eTrue
para-1
, e o segundo-
converte-1
para1
.Respostas:
Você não precisa de todos os nomes das planilhas, apenas o primeiro e o último:
fonte
Você pode tentar com este código:
=SUMPRODUCT(SUBTOTAL(2;INDIRECT(ADDRESS(ROW();COLUMN();;;SHEET_NAMES))))
fonte
N()
obriga o resultado deINDIRECT()
para ser convertido em um valor numérico, então oISNUMBER()
retornaráTRUE
para cada célula, de modo aplicado no exemplo da pergunta, isso resulta em3
, embora eu espere2
(uma vez que uma das três células de interesse está em branco) ...