Fallo de la función BUSCARH en Excel
22/12/2009, 16:23 -
Informática,
VBA para ExcelPosted by Administrator

Siempre he sido un ferviente defensor de
Microsoft Excel, ya que es un software tremendamente estable,
pero hoy he descubierto un fallo en una de sus funciones. Concretamente en las funciones BUSCARV y BUSCARH (VLOOKUP y HLOOKUP).
Estas funciones buscan un valor en un rango de celdas y devuelven el valor asociado a la celda encontrada. Es decir, supongamos las siguientes celdas:
A B C
1 Manolo 12 Negro
2 Maria 3 Rojo
3 Pepe 4 Verde
4 Juan 5 Azul
5 Maria 56 Blanco
Pues la función BUSCARV("Pepe";A1:C5;3) buscaría en la primera columna del rango A1:C5 el texto "Manolo" y devolvería el valor de su misma fila pero en la tercera columna. Es decir, devolvería el texto Verde.
El
bug concretamente afecta a las búsquedas que realizan estas funciones, ya que si se buscan textos, se producen resultados impredecibles. Veamos el siguiente ejemplo:
A B C
1 C.A. C.B. C.C.
2 Maria Pepe Juan
3 Azul Rojo Verde
4 35 50 42
Si buscamos en la primera fila utilizando la función BUSCARH, veremos que se producen incongruencias. Hay veces que el resultado devuelto no se corresponde con el valor asociado a esa celda.
Para resolver esto yo he utilizado VBA y me he construido mi propia función que aquí os dejo por si es de utilidad:
'/**************************************************************************
'* Function: LOOKUPH : Version on HLOOKUP function with text search method *
'* *
'* Author: Ruben Alvarez *
'* Date: 23/12/2009 *
'* *
'* Description: Search a reference text into a range of cells and returns *
'* the row value associated to the found column. *
'**************************************************************************/
Public Function LOOKUPH(RefText As String, LookupRange As String, ReturnRow As Integer) As String
Dim r As Integer
Dim c As Integer
s = Split(LookupRange, ":", , vbTextCompare)
If UBound(s) = 1 Then
start_cell_col = CInt(CNumber(Left(s(0), 1)))
start_cell_row = CInt(Right(s(0), 1))
final_cell_col = CInt(CNumber(Left(s(1), 1)))
final_cell_row = CInt(Right(s(1), 1))
Else
LOOKUPH = "#ERROR#"
Exit Function
End If
For col = start_cell_col To final_cell_col
If Cells(start_cell_row, col).Text = RefText Then
If ((start_cell_row + ReturnRow - 1) <= final_cell_row And ReturnRow >= 2) Then
LOOKUPH = Cells(start_cell_row + ReturnRow - 1, col)
Exit For
Else
LOOKUPH = "#ERROR#"
Exit For
End If
End If
Next col
End Function
Public Function CLetter(v As Long) As String
CLetter = Left(Cells(1, v).Address(1, 0), InStr(1, Cells(1, v).Address(1, 0), "$") - 1)
End Function
Public Function CNumber(v As String) As Integer
CNumber = Range(v & "1").Column
End Function