TOP

Fuzzy Lookup para LibreOffice Calc

FUZZYLOOKUP() Descripción

Todos conocemos la conocida función VLOOKUP() que nos ayuda a combinar datos de diferentes tablas. Sin embargo, esta función tiene un inconveniente importante: no puede combinar valores similares, es decir, si hay un error en la palabra, no habrá coincidencia.

Para poder combinar valores aproximados, podemos crear nuestra propia función. Llamémoslo FuzzyLookup().

Imaginemos que tenemos dos listas. Ambos tienen aproximadamente los mismos elementos, pero pueden escribirse de forma ligeramente diferente. La tarea es encontrar para cada elemento de la primera lista el elemento más similar de la segunda lista, es decir implementar una búsqueda del texto máximamente similar más cercano.

La gran pregunta, en este caso, es qué considerar el criterio de “similitud”. ¿Solo el número de caracteres coincidentes? ¿Es el número de partidos consecutivos? ¿Deberían considerarse los caracteres en mayúsculas y minúsculas o los espacios? ¿Qué hacer con la diferente disposición de las palabras en una frase? Hay muchas opciones y no existe una solución única: para cada situación una u otra será mejor que otras.

En nuestro caso, implementamos la opción más simple: buscar por el número máximo de coincidencias de caracteres. No es perfecto, pero funciona bastante bien en la mayoría de situaciones.


BASIC código para la función FuzzyLookup

Para agregar la función FuzzyLookup, abra el menú Tools - Macros - Edit Macros..., seleccione Module1 y copie el siguiente texto en el módulo:


Function FuzzyLOOKUP(LookupValue As String, SrcTable As Variant, Optional SimThreshold As Single) As String 
  ' moonexcel.com.ua 
  Dim Str       As String  
  Dim CellArray As Variant
  Dim StrArray  As Variant
  
  If IsMissing(SimThreshold) Then SimThreshold  = 0
  
  Str      = LCase(LookupValue)
  StrArray = Split(Str)
  StrExt   = UBound(StrArray)  
            
  For Each Cell In SrcTable
                          
    CellArray = Split(LCase(Cell))
    CellExt   = UBound(CellArray)    	    
    CellRate  = 0
	
    ' Comprobamos cada palabra en la frase de búsqueda. 
    For x = 0 To StrExt 
    
      StrWord = StrArray(x)	  
      If Len(StrWord) = 0 Then GoTo continue_x
	  MaxStrWordRate = 0
	  
      ' Verificamos cada palabra en la siguiente celda de la tabla de valores original. 
      For i = 0 To CellExt
        
        CellWord = CellArray(i)
		If Len(CellWord) = 0 Then GoTo continue_i
   
        FindCharNum = OccurrenceNum(StrWord, CellWord)
        StrWordRate = FindCharNum / Max(Len(StrWord),Len(CellWord))
		
        If StrWordRate > MaxStrWordRate Then MaxStrWordRate = StrWordRate
		continue_i:
      Next i		    
		    		    
      CellRate = CellRate + MaxStrWordRate
	  continue_x:
    Next x               
        
    ' Mantenemos el mejor partido. 
    If CellRate > MaxCellRate Then    
      MaxCellRate = CellRate
      BestCell    = Cell          
       
      FindCharNum = OccurrenceNum(Str, Cell)
      SimRate     = FindCharNum / Max(Len(Str),Len(Cell))
    End If       
        
  Next Cell
    
  IF SimRate >= SimThreshold Then 
    IF SimThreshold = -1 Then
      ReturnValue = BestCell + " (" + Format(SimRate, "0.00") + ")"
    ElseIf SimThreshold = -2 Then
      ReturnValue = Format(SimRate, "0.00")
    Else
      ReturnValue = BestCell
    End If
  Else 
    ReturnValue = ""
  End If    
  
  FuzzyLOOKUP = ReturnValue
End Function


Function OccurrenceNum(ByVal SourceString As String, ByVal TargetString As String)
  For i = 1 To Len(SourceString)	         		        	        
    ' Buscamos la aparición de cada símbolo. 
    Position = InStr(1, TargetString, Mid(SourceString, i, 1), 1)  
    ' Aumentamos el contador de coincidencias. 
    If Position > 0 Then		  
      Count = Count + 1
      ' Eliminar el símbolo encontrado 
      TargetString = Left(TargetString, Position - 1) + Right(TargetString, Len(TargetString) - Position)   
    End If
  Next i    
  OccurrenceNum = Count
End Function


Function Max(ByVal value1 As Variant, ByVal value2 As Variant)  
  If value1 > value2 Then
	Result = value1
  Else
	Result = value2
  End If
  Max = Result
End Function

A continuación, cierre Macro Editor y regrese a la hoja de trabajo LibreOffice Calc; ahora puede usar nuestra nueva función FuzzyLookup().

Usando la extensión YouLibreCalc

También puedes usar la función FUZZYLOOKUP() configurando la extensión " YouLibreCalc.oxt ". Después de eso, esta función estará disponible en todos los archivos que se abrirán en LibreOffice Calc.