martes, julio 15, 2008

Quitar acentos (tildes) de un texto en Excel.

Un lector me consulta cómo quitar los acentos (tildes) de un texto en una celda de Excel. Por ejemplo, si en la celda A1 tenemos el texto "María Angélica Esdrújula", nuestra tarea es transformar el texto en "Maria Angelica Esdrujula".

Coincidamos que ésta no es una tarea corriente en Excel. Pero la solución nos permitirá mostrar algunas técnicas útiles para construir funciones definidas por el usuario (UDF).

Empecemos por el caso más sencillo. Supongamos que en la celda A1 tenemos el texto "María". Queremos quitar el acento y transformar el texto en "Maria". En este caso sencillo podemos usar la función SUSTITUIR de la siguiente manera

=SUSTITUIR(A1,"í","i")



El problema con esta solución surge si tenemos varias palabras con acentos en distintas vocales.
En ese caso tendremos que usar una función definida por el usuario (UDF). Es decir, tendremos que escribir por nuestra cuenta el código de la función.

Empecemos por definir el problema. En castellano ponemos acentos sólo sobre vocales. Esto significa que tendremos cinco casos: á, é, í, ó y ú.
Lo primero que tenemos que saber es cuál es el código ASCII de estás vocales acentuadas, y cuáles son los códigos de las vocales sin acento. Para esto podemos usar la función CODIGO



Nuestra función tendrá que descomponer le texto en cuestión y reemplazar las vocales acentuadas por vocales sin acentos.
Empecemos por el final mostrando el código de la función:


Function txtNoAcc(texto) As String
Dim largoTexto As Long, iX As Long
Dim Lett As Long

txtNoAcc = ""

largoTexto = Len(texto)

For iX = 1 To largoTexto
Lett = Asc(Mid(texto, iX, 1))
Select Case Lett
Case Is = 225
txtNoAcc = txtNoAcc & Chr(97)
Case Is = 233
txtNoAcc = txtNoAcc & Chr(101)
Case Is = 237
txtNoAcc = txtNoAcc & Chr(105)
Case Is = 243
txtNoAcc = txtNoAcc & Chr(111)
Case Is = 250
txtNoAcc = txtNoAcc & Chr(117)
Case Else
txtNoAcc = txtNoAcc & Mid(texto, iX, 1)
End Select
Next iX
End Function


Nuestra función tiene un solo argumento: "texto", que es el texto contenido en la celda cuyo contenido queremos transformar. Hemos definido tres variables, cuya función será evidente más adelante.

La sentencia
"largoTexto = Len(texto)"
define cuantas letras y espacios hay en la celda.

Luego usamos la construcción For Next para descomponer el texto en sus componentes, los cuales analizamos para ver si hay alguna vocal con acento.
Para esto hemos definido la variable

Lett = Asc(Mid(texto, iX, 1))

que nos da el número de código de cada una de las letras del texto. Una vez que tenemos el número de código ASCII de cada letra, lo sometemos al examen de la construcción Select Case. En el caso que se trate de alguno de los cinco casos de letras con acento, ésta será reemplazada por la letra sin acento. En caso contrario, dejaremos la letra original.
Todo esto se va concatenando en la variable " txtNoAcc", el nombre de la función.

Para usar la función copiamos el código en un módulo del editor de VBa (preferentemente en el cuaderno Personal.xls, de manera que la función esté a nuestra disposición cualquiera sea el cuaderno abierto).
Luego, abrimos el asistente de funciones en la categoría "Definidas por el usuario"




y elegimos la función que acabamos de definir



El resultado será el esperado





Technorati Tags:

27 comentarios:

  1. Hola, amigo Jorge. Aprovechando el contenido de tu entrada de hoy, quisiera proponer una solución alternativa para los usuarios poco amigos de escribir código directamente, aunque si el número de caracteres a sustituir se disparara, evidentemente sería mejor la propuesta por tí. Mi solución sería la siguiente:

    +SUSTITUIR(SUSTITUIR(SUSTITUIR(SUSTITUIR(SUSTITUIR(A1;"á";"a");"é";"e");"í";"i");"ó";"o");"ú";"u")

    Como siempre, gracias por tu dedicación a esta tarea tan agradecida por todos nosotros. Un saludo desde Bilbao.

    Natxo

    ResponderBorrar
  2. Hola Natxo

    gracias por el excelente aporte

    Saludos

    ResponderBorrar
  3. Yo tengo otra propuesta para evitar una formula y tener que copiarla en una celda auxiliar. Mi solucion lo que hace es sustituir directamente los acentos alli donde se encuentren, modificando el texto original.

    Se crea una macro con las siguientes lineas:

    Sub sin_acentos()

    With Selection
    .Replace What:=Chr(193), Replacement:=Chr(65), LookAt:=xlPart, _
    SearchOrder:=xlByRows, MatchCase:=True ' cambia Á por A
    .Replace What:=Chr(201), Replacement:=Chr(69), LookAt:=xlPart, _
    SearchOrder:=xlByRows, MatchCase:=True ' cambia É por E
    .Replace What:=Chr(205), Replacement:=Chr(73), LookAt:=xlPart, _
    SearchOrder:=xlByRows, MatchCase:=True ' cambia Í por I
    .Replace What:=Chr(211), Replacement:=Chr(79), LookAt:=xlPart, _
    SearchOrder:=xlByRows, MatchCase:=True ' cambia Ó por O
    .Replace What:=Chr(218), Replacement:=Chr(85), LookAt:=xlPart, _
    SearchOrder:=xlByRows, MatchCase:=True ' cambia Ú por U
    .Replace What:=Chr(225), Replacement:=Chr(97), LookAt:=xlPart, _
    SearchOrder:=xlByRows, MatchCase:=True ' cambia á por a
    .Replace What:=Chr(233), Replacement:=Chr(101), LookAt:=xlPart, _
    SearchOrder:=xlByRows, MatchCase:=True ' cambia é por e
    .Replace What:=Chr(237), Replacement:=Chr(105), LookAt:=xlPart, _
    SearchOrder:=xlByRows, MatchCase:=True ' cambia í por i
    .Replace What:=Chr(243), Replacement:=Chr(111), LookAt:=xlPart, _
    SearchOrder:=xlByRows, MatchCase:=True ' cambia ó por o
    .Replace What:=Chr(250), Replacement:=Chr(117), LookAt:=xlPart, _
    SearchOrder:=xlByRows, MatchCase:=True ' cambia ú por u
    End With

    Lo unico que hay que hacer es seleccionar las celdas que se quieran modificar y se modifican las vocales acentuadas por las mismas sin acentos, y ademas lo hace con las minusculas y mayusculas.

    Gracias por este magnifico blog.

    Carlos

    ResponderBorrar
  4. Ole que bueno esa Macro, Carlos

    ResponderBorrar
  5. Pedazo de macro, me ha solucionado casi 8 horas de trabajo
    gracias

    ResponderBorrar
  6. EXCELENTE, ME HAN AHORRADO MUCHO TIEMPO Y ESTRES LABORAL,

    GRACIAS AMIGO ANÓNIMO

    ResponderBorrar
  7. Efectivamente este ayuda mucho y desde ya probare las 3 soluciones, Carlos queria preguntarte si podrias agregar alguna linea para modificar la ñ porque por ej. en Lotus Notes crean muchos problemas.

    Gracias a todos !

    ResponderBorrar
  8. El código de la ñ es 63. ¿Con que letra querés reemplazarla? La n es 110. Podés agregar la línea en el código.

    ResponderBorrar
  9. Muchas gracias me sirvió mucho, la modifiqué para que elimine masyusculas con acentos también.

    Espero les sirva:

    Sub NoAcentos()
    Function txtNoAcc(texto) As String
    Dim largoTexto As Long, iX As Long
    Dim Lett As Long

    txtNoAcc = ""

    largoTexto = Len(texto)

    For iX = 1 To largoTexto
    Lett = Asc(Mid(texto, iX, 1))
    Select Case Lett
    Case Is = 225
    txtNoAcc = txtNoAcc & Chr(97)
    Case Is = 233
    txtNoAcc = txtNoAcc & Chr(101)
    Case Is = 237
    txtNoAcc = txtNoAcc & Chr(105)
    Case Is = 243
    txtNoAcc = txtNoAcc & Chr(111)
    Case Is = 250
    txtNoAcc = txtNoAcc & Chr(117)
    Case Is = 193
    txtNoAcc = txtNoAcc & Chr(65)
    Case Is = 201
    txtNoAcc = txtNoAcc & Chr(69)
    Case Is = 205
    txtNoAcc = txtNoAcc & Chr(73)
    Case Is = 211
    txtNoAcc = txtNoAcc & Chr(79)
    Case Is = 218
    txtNoAcc = txtNoAcc & Chr(85)
    Case Is = 32
    txtNoAcc = txtNoAcc & Chr(95)
    Case Else
    txtNoAcc = txtNoAcc & Mid(texto, iX, 1)
    End Select
    Next iX
    End Function

    ResponderBorrar
  10. Hola Jorge,

    Soy una Fan tuya porque me parece genial lo que haces y la ayuda desinteresada que nos brindas, siempre que busco algo complejo lo encuentro y me encuentro con otros temas muy útiles y prácticos, gracias. Además porque te llamas como mi novio que también es argentino, así que las tienes todas de tu parte. ;)

    Mi comentario es porque humildemente modifique un poco el código que nos has brindado con lo adicional de uno de tus lectores para hacer una macro que cambie los acentos tanto en mayúsculas como en minúsculas dentro de la selección.

    Te doy mi aporte:

    Sub SinTildes()


    Dim largoTexto As Long, iX As Long
    Dim Lett As Long
    Dim Texto, TxtSinTilde As String


    For Each cell In Selection

    largoTexto = Len(cell.Value)

    Texto = cell.Value 'Variable que guarda el contenido de la celda

    TxtSinTilde = cell.Value 'Variable para borrar el contenido de la celda

    TxtSinTilde = "" 'Borra contenido de la celda

    For iX = 1 To largoTexto

    Lett = Asc(Mid(Texto, iX, 1))
    Select Case Lett
    Case Is = 225
    TxtSinTilde = TxtSinTilde & Chr(97)
    Case Is = 233
    TxtSinTilde = TxtSinTilde & Chr(101)
    Case Is = 237
    TxtSinTilde = TxtSinTilde & Chr(105)
    Case Is = 243
    TxtSinTilde = TxtSinTilde & Chr(111)
    Case Is = 250
    TxtSinTilde = TxtSinTilde & Chr(117)
    Case Is = 193
    TxtSinTilde = TxtSinTilde & Chr(65)
    Case Is = 201
    TxtSinTilde = TxtSinTilde & Chr(69)
    Case Is = 205
    TxtSinTilde = TxtSinTilde & Chr(73)
    Case Is = 211
    TxtSinTilde = TxtSinTilde & Chr(79)
    Case Is = 218
    TxtSinTilde = TxtSinTilde & Chr(85)
    Case Is = 32
    TxtSinTilde = TxtSinTilde & Chr(95)
    Case Else
    TxtSinTilde = TxtSinTilde & Mid(Texto, iX, 1)
    End Select
    Next iX

    cell.Value = TxtSinTilde 'Volvemos a ingresar el mismo contenido pero sin acentos o tíldes

    Next

    End Sub

    ResponderBorrar
  11. Aquí me encontré otra opción.

    http://www.o-cruzg.blogspot.com/2011/11/f-para-eliminar-acentos-udfotra-f.html

    ResponderBorrar
  12. Sé que es un tema añejo pero con excel 2007 puedes simplemente buscar y reemplazar cada vocal acentuda por una sin acento.

    ResponderBorrar
  13. y si nada mas usas el comando Reemplazar del menu edicion y lo aplicas una vez por vocal ?

    ResponderBorrar
  14. Omar Alejandro Rodríguez Márquez22 junio, 2012 18:20

    Concuerdo con anónimo, soy programador pero muchas veces lo mas sencillo es lo conveniente. Usen buscar y reemplazar

    ResponderBorrar
  15. Sin ánimo de ofender...
    las personas que ofrecen como alternativa utilizar el buscar y remplazar se nota que no utilizan el excel habitualmente: ¿si son datos vinculados pierdo la actualización?¿sustituyo el valor?
    Y ya que un "programador" prefiera un método manual que se tiene que repetir frente a un método programado para ahorrar trabajo es que me deja sin palabras.

    vivir para ver

    ResponderBorrar
  16. la entrada es vieja, pero si a alguien aun le sirve...

    MAYUSC(SUSTITUIR(SUSTITUIR(SUSTITUIR(SUSTITUIR(SUSTITUIR(MINUSC(G2);"á";"a");"é";"e");"í";"i");"ó";"o");"ú";"u"))

    solo al buscar el campo asegurense de pasar el texto a minusculas (Á != á)

    ResponderBorrar
  17. Me encanto la opcion de Naxto
    SUSTITUIR(SUSTITUIR(SUSTITUIR(SUSTITUIR(SUSTITUIR(A1;"á";"a");"é";"e");"í";"i");"ó";"o");"ú";"u")

    ResponderBorrar
  18. ME ENCANTO EN VERDAD!!!!!
    Me encanto la opcion de Naxto
    SUSTITUIR(SUSTITUIR(SUSTITUIR(SUSTITUIR(SUSTITUIR(A1;"á";"a");"é";"e");"í";"i");"ó";"o");"ú";"u")

    ResponderBorrar
  19. Fenomenal todas las opciones, me sirvio mucho la opción del usario de Anonimo con el comando With, gracias a todos por compartir sus conocimientos.

    ResponderBorrar
  20. Genial el aporte. Muchas gracias.
    Por otro lado, me he topado con una pregunta que no encuentro respuesta.

    Tengo la cadena "Hola mundo" quiero que me sea devuelta sin las comillas: Hola mundo

    He probado a usar la función SUSTITUIR pero no logro pasar las comillas como caracter a sustituir

    =SUSTITUIR(A1;""";"")

    ¿Cómo se pasan las comillas dobles?

    Saludos!

    ResponderBorrar
  21. Hola Eduardo

    =SUSTITUIR(A1,CARACTER(34),"")

    ResponderBorrar
  22. Jorge muchas gracias por tu solución, me ha servido bastante y la he modificado para todos los problemas de tildes, acentos y caracteres especiales. La estoy usando para crear usuarios en el directorio activo, el cual es muy sensible con los acentos y caracteres especiales; por lo anterior, he hecho unas modificaciones que pueden serle de utilidad a quien se encuentre en la misma situación, sobre todo cuando se desea que un usuario escriba los nombres y apellidos de las nuevas cuentas.

    Function txtNoAcc(texto) As String
    Dim largoTexto As Long, iX As Long
    Dim Lett As Long

    txtNoAcc = ""

    largoTexto = Len(texto)

    For iX = 1 To largoTexto
    Lett = Asc(Mid(texto, iX, 1))
    Select Case Lett
    Case Is = 224, 225, 226, 227, 228, 229, 192, 193, 194, 195, 196, 197
    txtNoAcc = txtNoAcc & Chr(97)
    Case Is = 232, 233, 234, 235, 200, 201, 202, 203
    txtNoAcc = txtNoAcc & Chr(101)
    Case Is = 236, 237, 238, 239, 204, 205, 206, 207
    txtNoAcc = txtNoAcc & Chr(105)
    Case Is = 240, 242, 243, 244, 245, 246, 210, 211, 212, 213, 214
    txtNoAcc = txtNoAcc & Chr(111)
    Case Is = 249, 250, 251, 252, 217, 218, 219, 220
    txtNoAcc = txtNoAcc & Chr(117)
    Case Is = 241, 209
    txtNoAcc = txtNoAcc & Chr(110)
    Case Is = 253, 221
    txtNoAcc = txtNoAcc & Chr(121)
    Case Is = 231, 199
    txtNoAcc = txtNoAcc & Chr(99)
    Case Is = 46
    txtNoAcc = txtNoAcc & Chr(46)
    Case 48 To 57
    txtNoAcc = txtNoAcc & Mid(texto, iX, 1)
    Case 65 To 90
    txtNoAcc = txtNoAcc & Mid(texto, iX, 1)
    Case 97 To 122
    txtNoAcc = txtNoAcc & Mid(texto, iX, 1)
    Case Else
    txtNoAcc = txtNoAcc
    End Select
    Next iX
    End Function


    el "Case Else" es el encargado de no dejar pasar los caracteres especiales ni los espacios.

    Para los que no estamos muy familiarizados con la creación de funciones me encontré el siguiente link (directo de la página de MSFT):
    http://office.microsoft.com/es-es/excel-help/crear-funciones-de-hoja-de-calculo-propias-HA001054846.aspx

    Un dato adicional: Hace uno o dos años, con el lanzamiento de las nuevas versiones de Office, oí a un funcionario de Microsoft decir que las nuevas versiones de Office buscan simplificar la vida de los usuarios finales, tratando de dar más recursos para evitarle al usuario tener que desarrollar macros y programas, esa es la razón por la que han ido escondiendo los botones de macros y de programación. Trabajando con Office 2010 no encontré el botón para programar en Visual Basic, con el fin de seguir las instrucciones que en el link anterior indicaban, de manera que me tocó entrar a "Opciones de Excel" y "Personalizar cinta de opciones", allí me fui a la ficha de "Vista" y agregué un "Nuevo grupo" para poder en este adicionar el botón de "Visual Basic", el cual me tocó buscar en "Comandos disponibles en:"+"Todos los comandos". Posiblemente haya una forma abreviada de hacerlo pero bueno, esa me funcionó y con ella pude crear un módulo en la hoja donde poner el código, modificarlo y hacerlo funcionar.

    El comando de buscar y reemplazar seguirá siendo útil pero cuando tienes un volumen grande de datos y no sabes con que salió la persona que digitó la información, no sabrías que buscar y reemplazar, con el programa planteado puedes:
    1. cambiar las tildes y acentos en las simples vocales equivalentes, eso incluye las tildes en la y y en la n y la cedilla.
    2. Elimina los espacios para los nombres y apellidos compuestos.
    3. Elimina los caracteres especiales, solo deja el punto (.) para permitir la separación de nombre y apellido en las cuentas.

    Nuevamente, muchas gracias.

    ResponderBorrar
  23. ¡Excelente post!
    Me ayudó mucho.

    ResponderBorrar
  24. Tengo una matriz de datos de diferentes indole y tengo espacios, cuadros, caracteres y simbolos sobrantes. Como hago para eliminar esas cosas¨? ya que he encontrado es para eliminar celdas y tengo una matriz de 66 mil filas y 55 columnas

    ResponderBorrar
  25. ¿Qué cuadros, caracteres y símbolos?
    Como supongo que los datos los importas de una base de datos, lo ideal sería eliminar esos problemas antes o durante el proceso de importación.

    ResponderBorrar
  26. Muchas gracias a todos por compartir sus ideas, me ahorraron muchas horas de trabajo.

    ResponderBorrar

Nota: sólo los miembros de este blog pueden publicar comentarios.