** NORMAS DEL FORO **
Inicio del foro Inicio del foro > Access y VBA > Access y VBA
  Mensajes nuevos Mensajes nuevos RSS - Código cuenta letras portugués
  Preguntas frecuentes Preguntas frecuentes  Buscar en el foro   Eventos   Registro Registro  Iniciar sesion Iniciar sesion

Tema cerradoCódigo cuenta letras portugués

 Responder Responder
Autor
Mensaje
Adrianet Ver desplegable
Habitual
Habitual
Avatar

Unido: 26/Marzo/2015
Localización: Valencia
Estado: Sin conexión
Puntos: 92
Enlace directo a este mensaje Tema: Código cuenta letras portugués
    Enviado: 23/Septiembre/2022 a las 12:11
Hola amigos del foro,...
Sigo con mis códigos para recuentos, ... 
Navegando por internet tropecé con este código en portugués, sobre el asunto de obtener las repeticiones de un carácter en una frase.

Lo implanté en un formulario, pero al ejecutarlo, daba error 9, subíndice fuera de rango, ... (que significa que se intenta dar un valor imposible en una matriz, por la actual estructura de la matriz )
Sin embargo, él afirma que el código realiza perfectamente la extracción de letras repetidas y las muestra con el recuento de veces que se repite, ...

Pego a continuación las líneas ....

Contar caracteres repetidos en una frase.

Código extraído de la web de Carlos Macorati (macorati.net, en portugués). Para VB.

En un formulario tenemos:

un cuadro de texto (Txfrase)

un botón de comando (cmdContarLetras)

un cuadro de lista (Lista4)

 ‘-----------------------------------------------------------------------

Private Sub cmdContarLetras_Click()

Dim c As Long, caracter As Integer

Dim letras() As Variant

 

 For c = 1 To Len(TxFrase)

    caracter = Asc((Mid(TxFrase, c, 1)))          ‘ obtiene número de la letra (ascii)

    MsgBox carácter                                         ‘ esto para visualizar el código ascii de cada letra

    letras(caracter) = letras(caracter) + 1      ‘ esto no funciona, da error 9, subíndice fuera del intervalo

 Next c

End Sub

 

Private Sub Verlista_click()

 Dim i As Long

 For i = LBound(letras) To UBound(letras)

     If letras(i) > 1 Then

       Lista4.AddItem "Letra " & Chr(i) & " : " & letras(i)

     End If

 Next i

End Sub

 

Sin embargo se ofrece como resultado un cuadro de lista, con los resultados, parecido a esto:

Letra    :  5       ‘ es el recuento de los espacios en la frase

Letra  a : 8       ‘ total de veces que aparece la letra a en la frase

Letra b :  4

Letra u :  3

 

Por más vueltas que le doy no consigo corregir el error, ... y conseguir que funcione.

El ejemplo está muy bien, ... tenemos un texto o frase, del cual realiza un recuento por cada letra y luego se muestran en un cuadro de lista, ...

Bueno, amigos, agradecería vuestras sugerencias y/o correcciones para pulir el código.

Gracias y saludos a todos.
Adrián.


Arriba
xavi Ver desplegable
Administrador
Administrador
Avatar
Terrassa-BCN

Unido: 10/Mayo/2005
Localización: Catalunya ||||
Estado: Sin conexión
Puntos: 14322
Enlace directo a este mensaje Enviado: 23/Septiembre/2022 a las 13:01
El array que estás utilizando solo lo has declarado (Dim letras() As Variant) pero en ningún momento has dimensionado los elementos que contiene.

He intentado encontrar el código original pero no soy capaz (empezando porque es macoratti.net). Estaria bien el link al original para poder ver que te has dejado al transcribir (o que diferencias hay).

Se supone que en algún momento se ha hecho un ReDim con el numero de caracteres para poder saber cuantos elementos contiene el array y poder asignar valores a cada uno de ellos.

Miralo y nos cuentas.

un saludo
Xavi, un minyó de Terrassa

Mi web
Arriba
Adrianet Ver desplegable
Habitual
Habitual
Avatar

Unido: 26/Marzo/2015
Localización: Valencia
Estado: Sin conexión
Puntos: 92
Enlace directo a este mensaje Enviado: 23/Septiembre/2022 a las 13:36
Hola Xavi, gracias por responder
Aquí pego el link ... 

https://www.macoratti.net/13/01/vb_cocr.htm

y a continuación lo que me guardé en word, ... para mis estudios de código.
CONTAR CARACTERES REPETIDOS EN UNA FRASE. Jose Carlos Macoratti.

Ningún evento Haga clic en el botón de comando incluido o siguiente código:

Private Sub Command1_Click()
   Llamar a ContarCaracteres(Text1.Text)
   Llamar a PreencherLista
End Sub

O código acima chama duas rotinas :

1.     ContarCaracteres(Text1.Text) - que contiene los caracteres de la cadena informada en la caja de texto Text1;

2.     PreencherLista - que preenche o controle ListBox - List1 - informando o caractere o número de ocorrências encontradas;

A seguir temos o código da rotina ContarCaracteres :

Private Sub ContarCaracteres(Texto As String)
Dim c As Long
Dim Caracter As Integer

For c = 1 To Len(Texto)
  Caractere = Asc(Mid$(Texto, c, 1))
  Letras(Caractere) = Letras(Caractere) + 1
Siguiente c
Finalizar Sub

 O código da rotatina PreencherLista é visto abaixo:

Private Sub PreencherLista()
Dim c As Long

List1.Clear
For c = LBound(Letras) To UBound(Letras)
  If Letras(c) > 1 Then
     List1.AddItem "Caractere" & Chr(c) & " : " & Letras( c)
   End If
Next c
End Sub


Executando o projeto e informando uma string qualquer iremos obter o resultado abaixo:

aquí va el cuadro de lista .... con los recuentos de cada letra 

Simples e prático como só o VB puede ser.



Saludos.
Adrian

Arriba
prga Ver desplegable
Moderador
Moderador


Unido: 16/Noviembre/2004
Localización: España
Estado: Sin conexión
Puntos: 3452
Enlace directo a este mensaje Enviado: 23/Septiembre/2022 a las 14:07
hola.
Sí lo he entendido bien( repeticiones de un carácter en una frase), creo que este código consigue lo previsto y aparentemente es mas sencillo

Public Sub cuentacaracteres(micadena As String, micaracter As String)
MsgBox (Len(micadena) - Len(Replace(micadena, micaracter, "")))
End Sub

Espero que sirve.
Un saludo a todos
Arriba
Adrianet Ver desplegable
Habitual
Habitual
Avatar

Unido: 26/Marzo/2015
Localización: Valencia
Estado: Sin conexión
Puntos: 92
Enlace directo a este mensaje Enviado: 23/Septiembre/2022 a las 16:04
Hola prga, gracias por participar en este post

Comentar que no se trata sólo contar las apariciones de una letra determinada en una frase, sino del recuento de cada una de los caracteres que están en la frase, (es decir, de todos), y como resultado mostrar el recuento de cada uno.

Un saludo.


Arriba
xavi Ver desplegable
Administrador
Administrador
Avatar
Terrassa-BCN

Unido: 10/Mayo/2005
Localización: Catalunya ||||
Estado: Sin conexión
Puntos: 14322
Enlace directo a este mensaje Enviado: 23/Septiembre/2022 a las 16:43
Hola,

No se muy bien como funciona VB pero parece que las matrices (que en el ejemplo ni declara ni dimensiona) permiten asignar elementos si necesidad de decir cuantos elementos se van a utilizar.

Es muy ingeniosa la forma de asignar los índices utilizando es ASCII... pero me temo que no funcikona en VBA.

En su lugar solo se me ha ocurrido crear una función un poco más larga. La he creado como una función que espera los nombres de los controles origen (el TextBox) y destino (el ListBox). 
Para hacer la prueba deberás copiar el código dentro del mismo formulario. Para llamar a la función la sintaxis es simple:

CuentaCaracteres "ComoSeLlameElCuadroDeTexto", "ComoSeLlameElListBox"

La función viene con suficientes comentarios de lo que hace cada paso (creo). Ejecuta paso a paso analizando los valores de cada una de las variables (ventana de locales va perfecto para esto) para entender su lógica.




Function CuentaCaracteres(strControlOrigen As String, strControlDestino As String)
    
    Dim ctlOrigen As Control
    Dim ctlDestino As Control
    Dim strLetra As String
    Dim strLetras As String
    Dim arrLetras() As Variant
    Dim arrVeces() As Variant
    Dim i As Integer
    Dim j As Integer
    
    ' Asignamos los controles de origen y destino
    Set ctlOrigen = Me.Controls(strControlOrigen)
    Set ctlDestino = Me.Controls(strControlDestino)
    
    ' Iteramos por los caracteres del texto
    For i = 1 To Len(ctlOrigen.value)
        strLetra = Mid(ctlOrigen.value, i, 1)
        ' En  cada caracter miramos si la letra está en la colección de letras
        If InStr(1, strLetras, strLetra) = 0 Then
            ' Al no existir la añadimos
            strLetras = strLetras & strLetra
        End If
    Next
    ' En este punto, strLetras contiene todos aquellos caracteres únicos
    
    ' Dimensionamos los 2 arrays(letras y veces) con tantos elementos como caracteres distintos haya en el texto
    ReDim arrLetras(Len(strLetras))
    ReDim arrVeces(Len(strLetras))
    
    ' Iteramos por las distintas letras
    For i = 0 To UBound(arrLetras)
        ' Asignamos a cada elemento del array la letra
        arrLetras(i) = Mid(strLetras, i + 1, 1)
        ' Iteramos por los caracteres del texto original
        For j = 1 To Len(ctlOrigen.value)
            ' Miramos si el caracter del texto original es el esperado
            If Mid(ctlOrigen.value, j, 1) = arrLetras(i) Then
                ' Cuando lo és, aumentamos el contador de veces para ese elemento
                arrVeces(i) = arrVeces(i) + 1
            End If
        Next j
        ' Una vez recorrido todo el texto, si el caracter aparece más de una vez, lo añadimos al ListBox
        If arrVeces(i) > 1 Then
            ctlDestino.AddItem "Caracter: " & arrLetras(i) & ": " & arrVeces(i)
        End If
    Next
End Function

Un saludo
Xavi, un minyó de Terrassa

Mi web
Arriba
prga Ver desplegable
Moderador
Moderador


Unido: 16/Noviembre/2004
Localización: España
Estado: Sin conexión
Puntos: 3452
Enlace directo a este mensaje Enviado: 23/Septiembre/2022 a las 17:33
Otra posible alternativa a falta de depurar, optimizar etc etc:

Public Function cuentacaracteres(micadena As String, ByRef mimatr())
Dim k As Long
Dim micar As String
Dim micad1 As String
Dim minum As Long
k = 0
Do While Len(micadena) > 0
  ReDim Preserve mimatr(2, k)
  micar = Left(micadena, 1)
  micad1 = Replace(micadena, micar, "")
  minum = Len(micadena) - Len(micad1)
  micadena = micad1
  mimatr(0, k) = micar
  mimatr(1, k) = minum
  k = k + 1
Loop
End Function

Public Sub prueba()
Dim mimatr()
Dim minum As Long
Dim mitexto As String
mitexto = " zAABAC Ñàû"
Call cuentacaracteres(mitexto, mimatr())
For minum = 0 To UBound(mimatr, 2)
  MsgBox ("Letra: " & mimatr(0, minum) & " Repetida: " & mimatr(1, minum) & " veces")
Next
End Sub

Espero que esta ayude a resolver la duda
Un saludo a todos
Arriba
pitxiku Ver desplegable
Colaborador
Colaborador
Avatar

Unido: 27/Septiembre/2017
Localización: En mi casa
Estado: Sin conexión
Puntos: 1389
Enlace directo a este mensaje Enviado: 23/Septiembre/2022 a las 23:35
Otra posibilidad: la tabla Numeros (o TNumeros) para tener todos los códigos ASCII (o Unicode) posibles y poder determinar cuáles son los distintos caracteres que hay en el texto, y después usar la función Len como hacía prga con cada uno de esos caracteres:

- https://1drv.ms/u/s!AsYMk9OS3HACzCtZtt3Wc7YaKyAa?e=z9bQvE

En la base de datos de ejemplo hay 2 tablas y una consulta, que es la que hace todos los cálculos:

- TNumeros, con los números desde 1 hasta 1.000.000 (millón), aunque creo que el mayor código Unicode ronda el 200.000

- TTexto, con un único registro que es el texto a destripar y contar caracteres.

- QContador: el primer campo calculado (Caracter), sirve para cambiar cada número al carácter Unicode. El segundo campo calculado (Contador), usa la fórmula de prga para contar las coincidencias. Y la tercera columna es el criterio para mostrar sólo los caracteres que hay en el texto. En la consulta, a las funciones de texto EnCad (InStr) y Replace (Reemplazar) se les pasa valores para que hagan una comparación binaria (E no es igual a e). Puedes modificar eso si quieres que E sea igual a e.


Arriba
pitxiku Ver desplegable
Colaborador
Colaborador
Avatar

Unido: 27/Septiembre/2017
Localización: En mi casa
Estado: Sin conexión
Puntos: 1389
Enlace directo a este mensaje Enviado: 24/Septiembre/2022 a las 09:49
Una cosa que se me olvidó: en vez de la tabla TTexto para guardar el texto a contar, puedes tener un parámetro en la consulta que lo pida cada vez que la abras, y una tabla que te ahorras. Lo que ocurre es que para la pruebas me es más cómodo tener el texto ya guardado y no tener que escribirlo cada vez.
Arriba
Adrianet Ver desplegable
Habitual
Habitual
Avatar

Unido: 26/Marzo/2015
Localización: Valencia
Estado: Sin conexión
Puntos: 92
Enlace directo a este mensaje Enviado: 24/Septiembre/2022 a las 18:58
Hola amigos, 
No he podido conectarme hasta ahora, ... pero ya había visto las respuestas en el móbil.
Gracias Xavi, prga y pitxiku por vuestra ayuda en el asunto de este post.

Los códigos de Xavi y prga son geniales, y resuelven el objetivo del recuento de letras de una frase de una manera sencilla y efectiva.

La propuesta de Pitxiku tengo que estudiarla un poco más, pero seguro que es también muy buena.
'----------------
Bueno yo por mi parte también he estado elaborando unas líneas de código para el tema, que ya he probado y funciona a la perfección.

Pego ahora dichas líneas, ... 

Contar las letras de una frase , mío

Private Sub cmdContarLetras_Click()

Dim frase As String, letra As String

Dim resultado As String

Dim i As Integer, x As Integer, contar As Boolean

Dim letras() As String

frase = UCase(TxFrase)

ReDim letras(0)

For i = 1 To Len(TxFrase)

    contar = True

    letra = Mid(frase, i, 1)

       For j = 0 To UBound(letras)

           If letras(j) = letra Then

           contar = False

           Exit For

           End If

        Next j

       

        If contar Then

        x = UBound(letras) + 1

        ReDim Preserve letras(x)

        letras(x) = letra

        ' aplico esta línea como opción para mostrar resultado en un msgbox

        resultado = resultado & "carácter:  " & letra & " : " &  cuentaLetras(frase, letra) & vbNewLine

        Me.Lista4.AddItem letra & " : " & cuentaLetras(frase, letra)

        End If

 Next i

   MsgBox resultado     ' esta línea es por si se quiere mostrar en cuadro de mensaje

End Sub

'------------

Public Function cuentaLetras(ByVal cadena As String, ByVal caracter As String) As Integer

  Dim c As Integer, num As Integer

 

     For c = 1 To Len(cadena)                              ‘ función para contar apariciones o repeticiones

        If Mid(cadena, c, 1) = caracter Then           ‘ de un caracter en una cadena de texto

        num = num + 1                                       ‘ actualizamos el contador de la letra

        End If

     Next c

  cuentaLetras = num                                     ‘ pasamos la variable a la función cuentaLetras

 End Function

'----------------------------------------

Como podéis ver he utilizado una forma distinta, ... pero es que "hay muchos caminos para llegar al destino", ... y lo bueno es eso precisamente, que haya diversidad de maneras de conseguir un resultado. De todas ellas uno aprende.

Como comentarios finales:
1.- en mi código falta que se realice un filtrado de los recuentos, cogiendo sólo las letras que se repiten (es decir, que haya más de una aparición de la letra (como ha hecho Xavi)).
2.- respecto al código que originó este asunto, el de Carlos Macoratti, el cual usa VB, me atrevería a decir que faltan líneas en primer sub, ya que no hace comparaciones para ver cual letra se repite ni tiene un bucle para contar las repeticiones. No sé nada de VB pero veo el código de Macoratti muy reducido, demasiado reducido.

Bueno amigos, de nuevo dar las gracias a los expertos que nos ayudan en nuestras dudas.
Para los que estamos en los principios del camino del VBA, es muy importante tener esta ayuda y participar en este excelente foro.

Saludos a todos.
Adrian.




Arriba
xavi Ver desplegable
Administrador
Administrador
Avatar
Terrassa-BCN

Unido: 10/Mayo/2005
Localización: Catalunya ||||
Estado: Sin conexión
Puntos: 14322
Enlace directo a este mensaje Enviado: 24/Septiembre/2022 a las 20:45
En el código original, si que cuenta las repeticiones.
Lo que hace es recorrer la cadena y, por cada caracter, aumentar el contador

Si la primera letra es "a", el obtiene el ASC (97) y es el valor que utiliza en la matriz Letras para incrementar

Letras(97) = Letras(97) + 1

Luego, en el segundo bucle, solo muestra aquellos Letras(x) > 1 para que muestre solo los caracteres duplicados.

Un saludo

Xavi, un minyó de Terrassa

Mi web
Arriba
Adrianet Ver desplegable
Habitual
Habitual
Avatar

Unido: 26/Marzo/2015
Localización: Valencia
Estado: Sin conexión
Puntos: 92
Enlace directo a este mensaje Enviado: 3 horas 22 minutos a las 12:38
Hola

Entonces, según comentas, el código original de Macoratti hace lo necesario para el ejemplo, y con muy pocas líneas de código (esto es porque usa VB)

Bueno, si no hay algún comentario más para añadir a este post, por mi parte pueden cerrar el hilo.

Saludos
Adrian





Arriba
xavi Ver desplegable
Administrador
Administrador
Avatar
Terrassa-BCN

Unido: 10/Mayo/2005
Localización: Catalunya ||||
Estado: Sin conexión
Puntos: 14322
Enlace directo a este mensaje Enviado: 2 horas 58 minutos a las 13:02
Efectivamente, el código de Macoratti hace lo que promete pero en VB que, por lo que se ve, permite algunas cosas que VBA no lo hace. Eso lo convierte en un código bastante más corto.

¡Cerrando!
Xavi, un minyó de Terrassa

Mi web
Arriba
 Responder Responder
  Compartir tema   

Ir al foro Permisos de foro Ver desplegable