Como fazer com que o VLOOKUP retorne a * última * correspondência?

12

Estou acostumado a trabalhar com o VLOOKUP, mas desta vez tenho um desafio. Não quero o primeiro valor correspondente, mas o último. Quão? (Estou trabalhando com o LibreOffice Calc, mas uma solução do MS Excel deve ser igualmente útil.)

O motivo é que tenho duas colunas de texto com milhares de linhas, digamos que uma seja uma lista de beneficiários de transações (Amazon, Ebay, empregador, supermercado etc.) e a outra é uma lista de categorias de gastos (salários, impostos, casa, aluguel, etc.). Algumas transações não têm a mesma categoria de gastos todas as vezes, e eu quero escolher a usada mais recentemente. Observe que a lista não está classificada por nenhuma coluna (de fato por data) e não quero alterar a ordem de classificação.

O que tenho (excluindo o tratamento de erros) é a fórmula usual de "primeira correspondência":

=VLOOKUP( 
[payee field] , [payee+category range] , [index of category column] , 
0 )

Eu já vi soluções como essa, mas recebo #DIV/0!erros:

=LOOKUP(2 , 1/( [payee range] = [search value] ) , [category range] )

A solução pode ser qualquer fórmula, não necessariamente VLOOKUP. Também posso trocar as colunas beneficiário / categoria. Apenas nenhuma alteração na coluna de classificação, por favor.


Pontos de bônus por uma solução que escolhe o valor mais frequente do que o último!

Torben Gundtofte-Bruun
fonte

Respostas:

3

Você pode usar uma fórmula de matriz para obter dados do último registro correspondente.

=INDEX(IF($A$1:$A$20="c",$B$1:$B$20),MAX(IF($A$1:$A$20="c",ROW($A$1:$A$20))))

Digite a fórmula usando Ctrl+ Shift+ Enter.

Isso funciona como a INDEX/ MATCHconstrução de a VLOOKUP, mas com uma condicional MAXusada em vez de MATCH.

Observe que isso pressupõe que sua tabela comece na linha 1. Se seus dados começarem em uma linha diferente, você precisará ajustar a ROW(...)parte subtraindo a diferença entre a linha superior e 1.

Excellll
fonte
Estou confuso com o literal "c" - acho que a avaliação é sempre falsa, então o que ela realmente faz?
Torben Gundtofte-Bruun
Testei sua sugestão (e verifiquei se ela era aceita como uma fórmula de matriz). Eu suponho que Col A é beneficiário e B é categoria, certo? Infelizmente, o LibreOffice retorna "ERR: 502", que se traduz em "Argumento inválido: o argumento da função não é válido. Por exemplo, um número negativo para a função SQRT (), para isso, use IMSQRT ()". Eu verifiquei se todas as funções existem com esse nome no LibreOffice, mas me pergunto se o LibreOffice IFnão pode lidar com matrizes.
Torben Gundtofte-Bruun
Desculpe, o literal "c" era apenas o nome do beneficiário que você queria corresponder. Essa foi uma relíquia dos meus dados de amostra com os quais estava brincando. Presumo que será substituído por uma referência de célula em sua planilha.
11153 Excellll
@ TorbenGundtofte-Bruun Cuidado para compartilhar a fórmula que você está usando? Talvez eu consiga solucioná-lo se conseguir vê-lo. Além disso, você sempre pode tentar percorrer a fórmula com Evaluate Formulapara ver qual parte da fórmula está gerando o erro. Esse recurso existe no Excel, e eu ficaria surpreso se o LibreOffice Calc não tivesse o mesmo recurso.
11154 Excellll
Minha fórmula original é simples, é por isso que não é adequado :-) =VLOOKUP(J1061;$J$2:$K$9999;2;0)onde a coluna J contém beneficiários e a coluna K as categorias. Retorna a primeira correspondência conforme o esperado.
Torben Gundtofte-Bruun
2

(Respondendo aqui como nenhuma pergunta separada para dados classificados.)

Se os dados foram classificados, você pode usar VLOOKUPo range_lookupargumento TRUE(ou omitido, já que é o padrão), que é descrito oficialmente no Excel como "pesquisa por correspondência aproximada".

Em outras palavras, para dados classificados:

  • definir o último argumento para FALSEretornar o primeiro valor e
  • definir o último argumento para TRUEretornar o último valor.

Isso é em grande parte indocumentado e obscuro, mas data de VisiCalc (1979) e hoje é válido pelo menos no Microsoft Excel, LibreOffice Calc e Google Sheets. Em última análise, é devido à implementação inicial do LOOKUPVisiCalc (e daí VLOOKUPe HLOOKUP), quando não havia um quarto parâmetro. O valor é encontrado pela pesquisa binária , usando o limite esquerdo inclusivo e o limite direito exclusivo (uma implementação comum e elegante), o que resulta nesse comportamento.

Tecnicamente, isso significa que se inicia a pesquisa com o intervalo candidato [0, n), onde nestá o comprimento da matriz, e a condição invariante do loop é que A[imin] <= key && key < A[imax](o limite esquerdo é <= o destino, o limite direito, que inicia um após o final, é > a meta; para validar, verifique os valores nos pontos de extremidade antes ou verifique o resultado depois) e divida e escolha sucessivamente o lado que preservar esse invariante: por exclusão, um lado o fará, até que você atinja um intervalo com 1 termo [k, k+1), e o algoritmo então retorna k. Não precisa ser uma correspondência exata (!): É apenas a correspondência mais próxima abaixo. No caso de correspondências duplicadas, isso resulta em retornar a última correspondência, pois exige que o próximo valor seja maiordo que a chave (ou o final da matriz). No caso de duplicatas, você precisa de algum comportamento, e isso é razoável e fácil de implementar.

Esse comportamento é explicitamente explicado neste artigo antigo da Base de Dados de Conhecimento da Microsoft (ênfase adicionada): "XL: Como retornar a primeira ou a última correspondência em uma matriz" ( Q214069 ):

Você pode usar a função LOOKUP () para procurar um valor em uma matriz de dados classificados e retornar o valor correspondente contido nessa posição em outra matriz. Se o valor da pesquisa for repetido na matriz, ele retornará a última correspondência encontrada . Esse comportamento é verdadeiro para as funções VLOOKUP (), HLOOKUP () e LOOKUP ().

Segue documentação oficial para algumas planilhas; em nenhum dos casos o comportamento de "última correspondência" é declarado, mas está implícito na documentação do Planilhas Google:

  • Microsoft Excel

    TRUE assume que a primeira coluna da tabela está classificada numericamente ou alfabeticamente e, em seguida, procurará o valor mais próximo .

  • Planilhas Google :

    Se is_sortedfor TRUEou omitido, a correspondência mais próxima ( menor ou igual à chave de pesquisa) será retornada

Nils von Barth
fonte
Aquela coisa de partida mais próxima estava me deixando louco!
dukedave
1

Se os valores na matriz de pesquisa são seqüenciais (ou seja, você está procurando o maior valor, como a data mais recente), você nem precisa usar a função INDIRETO. Experimente este código simples:

=MAX(IF($A$1:$A$20="c",$B$1:$B$20,)

Novamente, insira a fórmula usando CTRL + SHIFT + ENTER

The Stich
fonte
0

Eu tentei o valor mais frequente. Não tenho certeza se funcionaria no libreOffice, mas parece funcionar no excel

= ÍNDICE ($ B $ 2: $ B $ 9, CORRESPONDÊNCIA (MÁX (- ($ A $ 2: $ A $ 9 = D2) * CONTÍCULOS ($ B $ 2: $ B $ 9, $ B $ 2: $ B $ 9, $ A $ 2 : $ A $ 9, D2)), - ($ A $ 2: $ A $ 9 = D2) * PAÍSES ($ B $ 2: $ B $ 9, $ B $ 2: $ B $ 9, $ A $ 2: $ A $ 9, D2 ), 0))

A coluna A seria o beneficiário, a coluna B seria a categoria, D2 é o beneficiário pelo qual você deseja filtrar. Não sei por que está colocando quebras de linha extras na função acima.

Minha função para encontrar a última célula seria a seguinte:

= INDIRETO ("B" e MÁX. (- ($ A $ 2: $ A $ 9 = D2) * ROW ($ A $ 2: $ A $ 9)))

Indireto permite-me especificar a coluna que quero retornar e encontrar a linha diretamente (para que não precise subtrair o número de linhas de cabeçalho).

Ambas as funções precisam ser inseridas usando Ctrl + shift + enter

gtwebb
fonte
0
=LOOKUP([payee field] , [payee range] , [category range])

Isso te dará o último valor

Recebo pontos de bônus por estar 3 anos atrasado?

DavePenn
fonte
-1

Você obteve #DIV/0!erros porque prefere escrever sua fórmula como:

=LOOKUP(2;IF(([payee range] = [search value]);1;"");[category range])

isso funcionará e será encontrado na última partida.

([payee range] = [search value]) : matriz booleana TRUE / FALSE

IF(([payee range] = [search value]);1;"") : matriz pseudo-booleana 1 / ""

=LOOKUP(2; {pseudo-boolean matrix 1/""} );[category range]): sempre retornar última 1posição

Samuel
fonte
LOOKUPfunciona apenas na lista classificada, a saída do seu confronto resultará em uma lista de se 1espaços de maneira não classificada, portanto, não dará o resultado correto.
Máté Juhász