30 noviembre, 2023

ELIMINAR DUPLICADOS EN UNA CADENA DE TEXTO Y ORDENAR INFORMACIÓN

Hola de nuevo a todos:

Llevo varios post tratando la eliminación de elementos duplicados, en los ejemplos anteriores buscamos la forma de hacerlo en un rango de celdas y aprovechamos también para introducir un proceso que nos ordenase los datos en caso de ser necesario (por ejemplo en un cuadro de lista o un cuadro combinado).

Pues bien, han sido varias las peticiones para que aplicase el mismo método pero para eliminar duplicados en una cadena de texto (string). O lo que es lo mismo, en la información contenida en una celda.

Pues bien, para contestar a estas dudas y cerrar por ahora esta temática os voy a dejar tres funciones personalizadas (UDF) que hacen precisamente lo que se pide, es decir lograremos conservar solo los elementos únicos en una cadena de texto. Adicionalemente os dejaré también otra función con los elementos necesarios para ordenar el texto final.

En primer lugar, hay que tener en cuenta que una cadena de texto puede estar delimitada por multitud de caracteres, siendo los más habituales: la coma «,» el punto y coma «;» el punto «.» y finalmente el espacio en blanco » «.

Vamos a comenzar con la función para extraer únicos en una cadena de texto delimitada por espacios en blanco:

Function F_UNICOS(ByVal Micelda As String)
'Declaramos las variables
Dim oDic As Object, palabra As Variant
Dim ipalabra As String, matriz As Variant
Dim sCadena As String, i As Long
'Trabajamos con la hoja
With ActiveSheet
Set oDic = CreateObject("scripting.dictionary")
'Por cada celda con datos en el rango rango componemos un string
For Each palabra In Split(Micelda, " ")
ipalabra = ipalabra & " " & palabra
Next palabra
'Eliminamos posibles espacios en blanco
sCadena = Trim(ipalabra)
'Comprobamos que cada palabra que incluimos en la matriz no existe en la cadena
matriz = Split(sCadena, " ")
For i = 0 To UBound(matriz)
If Not oDic.Exists(matriz(i)) Then oDic.Add matriz(i), matriz(i)
Next i
'Creamos una nueva cadena sin duplicados
UNICOS = Join(oDic.Keys, " ")
'Liberamos memoria
Set oDic = Nothing
End With
End Function

Si la aplicamos en un sencillo ejemplo con nombres de animales o de comunidades autónomas y ciudades, este sería el resultado.

ELIMINAR DUPLICADOS EN UNA CADENA DE TEXTO Y ORDENAR INFORMACION

Ahora sería interesante realizar el mismo planteamiento pero con delimitadores diferentes al espacio en blanco, por ejemplo una coma:

Function UNICOS_DELIMITADOR(ByVal Micelda As String)
'Declaramos las variables
Dim oDic As Object, palabra As Variant
Dim ipalabra As String, matriz As Variant
Dim sCadena As String, i As Long
'Trabajamos con la hoja
With ActiveSheet
Set oDic = CreateObject("scripting.dictionary")
'Por cada celda con datos en el rango rango componemos un string
For Each palabra In Split(Micelda, ", ")
ipalabra = ipalabra & ", " & palabra
Next palabra
'Eliminamos posibles espacios en blanco
sCadena = Trim(Mid(ipalabra, 2, Len(ipalabra)))
'Comprobamos que cada palabra que incluimos en la matriz no existe en la cadena
matriz = Split(sCadena, ", ")
For i = 0 To UBound(matriz)
If Not oDic.Exists(matriz(i)) Then oDic.Add matriz(i), matriz(i)
Next i
'Creamos una nueva cadena sin duplicados
UNICOS_DELIMITADOR = Join(oDic.Keys, ", ")
'Liberamos memoria
Set oDic = Nothing
End With
End Function

Sobra decir, que si tenéis otro delimitador, solo tenéis que sustituirlo donde aparece la coma «, » por otro.

Siguiendo el ejemplo anterior, este sería el resultado:

ELIMINAR DUPLICADOS EN UNA CADENA DE TEXTO Y ORDENAR INFORMACION1

Y por último, partiendo del mismo delimitador, vamos a incluir la posibilidad de ordenar la cadena de texto, utilizaremos esta función:

Function UNICOS_DELIMITADOR_ORDENADO(ByVal Micelda As String)
'Declaramos las variables
Dim oDic As Object, palabra As Variant, npalabra As String
Dim ipalabra As String, matriz As Variant, matriz1 As Variant
Dim sCadena As String, sCadena1 As String, i As Long, alfadato As Variant
'Trabajamos con la hoja
With ActiveSheet
Set oDic = CreateObject("scripting.dictionary")
'Por cada celda con datos en el rango rango componemos un string
For Each palabra In Split(Micelda, ", ")
ipalabra = ipalabra & ", " & palabra
Next palabra
'Eliminamos la primera coma del string
sCadena = Mid(ipalabra, 2, Len(ipalabra))
Set matriz = CreateObject("System.Collections.ArrayList")
'Y ordenamos las palabras
For Each palabra In Split(sCadena, ",")
matriz.Add palabra
Next palabra
matriz.Sort
'Pasamos de nuevo las palabras ordenadas a un string
For Each alfadato In matriz
npalabra = npalabra & "," & alfadato
Next alfadato
sCadena1 = Trim(Mid(npalabra, 2, Len(npalabra)))
'Comprobamos que cada palabra que incluimos en la matriz no existe en la cadena
matriz1 = Split(sCadena1, ", ")
For i = 0 To UBound(matriz1)
If Not oDic.Exists(matriz1(i)) Then oDic.Add matriz1(i), matriz1(i)
Next i
'Creamos una nueva cadena ordenada y sin duplicados
UNICOS_DELIMITADOR_ORDENADO = Join(oDic.Keys, ", ")
'Liberamos memoria
Set oDic = Nothing
Set matriz = Nothing

End With
End Function

Simplemente pasamos los datos por una matriz y los ordenamos. El resultado es este:

ELIMINAR DUPLICADOS EN UNA CADENA DE TEXTO Y ORDENAR INFORMACION2

Y con estas sencillas funciones tenemos bastante comentado el tema de los registros duplicados y su tratamiento, y también la posibilidad de ordenar esos datos alfabéticamente.

Es importante tener muy en cuenta los espacios en blanco, incluso el que se deja delante de la coma antes de escribir la palabra siguiente. Por eso, si tenéis espacios en blanco únicamente utilizar la primera función, si existen comas, puntos, etc, la segunda función será la más adecuada.

Es fundamental saber tratar este tipo de necesidades en cadenas de texto, pensad que al fin y al cabo es información que vais a pasar a multitud de plataformas, herramientas, etc.

Pues eso es todo, espero que os sea de utilidad.

Descarga el archivo de ejemplo pulsando en: ELIMINAR DUPLICADOS EN UNA CADENA DE TEXTO Y ORDENAR INFORMACIÓN

¿Te ha resultado de interés?, puedes apoyar a Excel Signum con una pequeña donación.


Donate Button with Credit Cards

¡¡Muchas gracias!!

Comparte este post

6 comentarios en «ELIMINAR DUPLICADOS EN UNA CADENA DE TEXTO Y ORDENAR INFORMACIÓN»

  1. Hola! Lo primero, muchas gracias Segu por compartir esto. Yo estoy manipulando un excel donde la solución sería la que aplicas con el delimitador de las comas (Ej: una celda donde ponga 2008, 2009, 2008). El problema es que tengo celdas donde se aplica que haya espacio después de la coma (ej. 2008, 2009, 2008. En este caso tu fórmula funciona muy bien), y cedas donde no hay espacio (Ej. 2008,2009,2008), en este caso tu fórmula no sirve.

    ¿Sabrías unir los dos casos para solucionar mi problema?. Gracias!

    1. Así?:

      Function UNICOS_DELIMITADOR_ORDENADO(ByVal Micelda As String)
      'Declaramos las variables
      Dim oDic As Object, palabra As Variant, npalabra As String
      Dim ipalabra As String, matriz As Variant, matriz1 As Variant
      Dim sCadena As String, sCadena1 As String, i As Long, alfadato As Variant
      'Trabajamos con la hoja
      With ActiveSheet
      Set oDic = CreateObject("scripting.dictionary")
      'Por cada celda con datos en el rango rango componemos un string
      For Each palabra In Split(Micelda, ",")
      ipalabra = ipalabra & ", " & Trim(palabra)
      Next palabra
      'Eliminamos la primera coma del string
      sCadena = Mid(ipalabra, 2, Len(ipalabra))
      Set matriz = CreateObject("System.Collections.ArrayList")
      'Y ordenamos las palabras
      For Each palabra In Split(sCadena, ",")
      matriz.Add palabra
      Next palabra
      matriz.Sort
      'Pasamos de nuevo las palabras ordenadas a un string
      For Each alfadato In matriz
      npalabra = npalabra & "," & alfadato
      Next alfadato
      sCadena1 = Trim(Mid(npalabra, 2, Len(npalabra)))
      'Comprobamos que cada palabra que incluimos en la matriz no existe en la cadena
      matriz1 = Split(sCadena1, ", ")
      For i = 0 To UBound(matriz1)
      If Not oDic.Exists(matriz1(i)) Then oDic.Add matriz1(i), matriz1(i)
      Next i
      'Creamos una nueva cadena ordenada y sin duplicados
      UNICOS_DELIMITADOR_ORDENADO = Join(oDic.Keys, ", ")
      'Liberamos memoria
      Set oDic = Nothing
      Set matriz = Nothing
      End With
      End Function

Si te ha gustado o tienes alguna duda, puedes dejar aquí tu comentario.

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información.plugin cookies

ACEPTAR
Aviso de cookies