SoloCodigo

Programación General => Visual Basic 6.0 e inferiores => Visual Basic para principiantes => Mensaje iniciado por: Jimbenit en Viernes 12 de Septiembre de 2008, 20:45

Título: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: Jimbenit en Viernes 12 de Septiembre de 2008, 20:45
Aveces es necesario procesar cadenas de texto, sé que muchos de ustedes se han encontrado con que tienen que diseñar funciones o sub-procedimientos para poder procesar cadenas de texto de una manera muy especial.

Pues este post lo hice con la intencion para que publiquen sus funciones (esas que ustedes han diseñado) que trabajen con cadenas de TEXTO.
Empiezo yo.

En cierta ocasion tuve que diseñar una funcion que me pasara una cadena de texto en sus equivalentes ASCII, pero con un formato especial, por ejemplo:
"Hola mundo"
El resultado debia ser:


10,72,111,108,97,32,109,117,110,100,111


Donde el primer numero indica el numero de caracteres de la cadena y los demas numeros son sus equivalentes ASCII

La funcion es la siguiente:


Código: Text
  1. Function CadenaASCII(CadenaNormal As String) As String
  2. 'Esta funcion recibe una cadena y como resultado da
  3. 'El numero de caracteres con los caracteres pasados a sus valores
  4. 'de la tabla ASCII
  5. 'EJEMPLO:
  6. 'CadenaASCII("YAIR")
  7. 'da como resultado
  8. '4,89,65,73,82
  9. 'Donde el primer numero (4), es el numero de caracteres
  10. 'Y los siguientes numeros son las letras en sus valores ASCII
  11.  
  12. Dim NumLet As Long
  13. Dim LetrASCII As String
  14. Dim Cadena As String
  15. Cadena = CadenaNormal
  16. Cadena = Trim(Cadena)
  17. NumLet = Len(Cadena)
  18.  
  19. For i = 1 To NumLet
  20.     LetrASCII = Asc(Mid(Cadena, i, 1))
  21.    
  22.     If NumLet = 1 Then
  23.         CadenaASCII = LetrASCII
  24.     ElseIf i = 1 Then
  25.         CadenaASCII = LetrASCII & ","
  26.     ElseIf i = NumLet Then
  27.         CadenaASCII = CadenaASCII & LetrASCII
  28.     Else
  29.         CadenaASCII = CadenaASCII & LetrASCII & ","
  30.     End If
  31. Next i
  32.  
  33. CadenaASCII = NumLet & "," & CadenaASCII
  34.  
  35. End Function
  36.  


Copienla en un modulo y pruebenla en la ventana inmediato y luego me cuentan que les parece,
Publiquen las suyas!!

saludos.


Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: Nebire en Lunes 15 de Septiembre de 2008, 05:01
Esa misma función  puede optimizarse ... y no precisa señalar cuantos caracteres tiene.
el trim no deberías hacerlo ya que si la idea es convertir una cadena de texto a una equivalente numérica estarías eliminado información, si resultara necesario hacerlo entonces debe especificarse claramente 'quitar espacios a ambos lados y convertirla a....' pero entonces el nombre de la función habría que cambiarla ya que así se prestaría a confusión.

Por ejemplo:
Código: Visual Basic
  1.  
  2. Function CadenaASCII(CadenaNormal As String) As String
  3.      dim k as long, cadena as string
  4.    
  5.      on local error goto errorSobrepasa:
  6.      if cadenanormal="" then exit function
  7.      if len(cadenanormal)=1 then
  8.          CadenaASCII= asc(cadenanormal)
  9.         exit function
  10.      else
  11.           if len(cadenanormal)>16383 then
  12.                msgbox "Existen posibilidades de que se produzca un error..."
  13.           end if
  14.      end if
  15.          for k=1 to len(cadenanormal)-1  ' el último carácter lo quedamos fuera del bucle
  16.            cadenanormal=cadenanormal & asc(mid$(cadenanormal,k,1)) & ","
  17.          next ' al finalizar el bucle, k todavía aumenta en 1
  18.          cadenanormal=cadenanormal & asc(mid$(cadenanormal,k,1)) ' tras el último carácter no añadimos la coma
  19.  
  20.         CadenaASCII=cadenanormal
  21.         exit function
  22. errorSobrepasa:
  23.      msgbox "Cada carácter de entrada genera entre 2 y 4 caracteres de salida. en VB6 el tamaño máximo de una cadena son 65535 caracteres, dicho valor se ha alcanzado con el " & k " ésimo carácter de la cadena de entrada..." & vbcrlf & err.description
  24.      CadenaASCII=cadenanormal
  25. end sub
  26.  
  27.  
Simplemente quitamos las comprobaciones , enlentecen el trabajo y solo va a entrar en las comprobaciones 1 vez cuando es el primer carácter, pero se comprueba con cada carácter, en todo caso ese carácter hacerlo antes del bucle y para el último carácter lo mismo, sólo entrará en el último ciclo del bucle por tanto acortamos el ciclo en una unidad y al final añadimos el último carácter, pero ahorrándonos , las comprobaciones con cada carácter.

Por cierto tu función dará error cuando le pases una cadena de cierto tamaño... lee los msgbox que he puesto en el código.
En otro momento te pongo una función de esas que pides...
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: F_Tanori en Lunes 15 de Septiembre de 2008, 06:15
A ver prueba esta a ver si te funciona

Código: Visual Basic
  1. Function ConvertAscii(ByRef as_Cadena As String) As String
  2. On Error GoTo xError
  3.     Dim i As Integer, AsciiCode() As Byte
  4.     AsciiCode = as_Cadena
  5.     For i = LBound(AsciiCode) To UBound(AsciiCode) Step 2
  6.         ConvertAscii = ConvertAscii & Format(AsciiCode(i), ",00")
  7.     Next i
  8.     ConvertAscii = (i / 2) & ConvertAscii
  9.  
  10. xError:
  11.     If Err.Number > 0 Then
  12.         ConvertAscii = Err.Description
  13.         Err.Clear
  14.     End If
  15. End Function
  16.  
  17.  

Saludos
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: m0skit0 en Lunes 15 de Septiembre de 2008, 10:37
Estilo programación funcional:

Código: Visual Basic
  1.  
  2. Function ConvertAscii(ByRef as_Cadena As String) As String
  3.      If as_Cadena = vbNullString Then
  4.           ConvertAscii = vbNullString
  5.      Else
  6.           ConvertAscii = CStr(AscB(Left(as_Cadena,1))) & ConvertAscii(Right(as_Cadena,Len(as_Cadena) - 1))
  7.      End If
  8. End Function
  9.  
  10.  

No la he probado, así que es sólo teórico  ^_^
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: Jimbenit en Lunes 15 de Septiembre de 2008, 16:12
Moskito. Revisa el siguiente codigo, no esta bien.

Código: Text
  1. Function ConvertAscii(ByRef as_Cadena As String) As String
  2.       If as_Cadena = vbNullString Then
  3.            ConvertAscii = vbNullString
  4.       Else
  5.            ConvertAscii = CStr(AscB(Left(as_Cadena,1))) & ConvertAscii(Right(as_Cadena,Len(as_Cadena) - 1))
  6.       End If
  7.  End Function
  8.  
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: Jimbenit en Lunes 15 de Septiembre de 2008, 16:14
La funcion inversa de esta...

Código: Text
  1. Function CadenaNormal(CadenaASCII As String) As String
  2. 'Convierte una cadena de formato ASCII en formato normal legible
  3. 'EJEMPLO:
  4. 'considere la cadena "4,89,65,73,82"
  5. 'esta función devuelve "YAIR"
  6.  
  7.  
  8. Dim NroCaracteres As Long       'Cuenta el numero de caracteres de la cadena ASCII
  9. Dim Letr As String
  10. Dim NumLet As Long
  11. Dim PosComas() As Long
  12. Dim NrsASCII() As String
  13. Dim Cont As Long
  14. Dim ComaDemas As Long   'Si existe una comas demas, esta variable almacena suposicion para su posterior reemplazo
  15.  
  16. CadenaASCII = Trim(CadenaASCII)
  17. NroCaracteres = Len(CadenaASCII)
  18.  
  19. For i = 1 To NroCaracteres          'Obtiene el numero de letras de la cadena normal
  20.     Letr = Mid(CadenaASCII, i, 1)
  21.     If Asc(Letr) = 44 Then
  22.         NumLet = Val(Left(CadenaASCII, i - 1))
  23.         Exit For
  24.     End If
  25. Next i
  26.  
  27. ReDim PosComas(NumLet)
  28. Cont = 0
  29. For i = 1 To NroCaracteres          'Obtiene la posicion de las comas y las introduce en el vetor POSCOMAS
  30.     Letr = Mid(CadenaASCII, i, 1)
  31.     If Asc(Letr) = 44 Then
  32.         Cont = Cont + 1
  33.         If Cont > NumLet Then       'Si hay comas demas que no hacen parte de la palabra, sera eliminada
  34.             ComaDemas = InStr(PosComas(Cont - 1) + 1, CadenaASCII, ",")
  35.             CadenaASCII = Mid(CadenaASCII, 1, ComaDemas - 1)
  36.             Exit For
  37.         End If
  38.         PosComas(Cont) = i
  39.     End If
  40. Next i
  41.  
  42. 'Si se introduce un cero, se devuelve vacio ("")
  43. If NumLet = 0 Then CadenaNormal = ""
  44. 'If NumLet = 0 Then Exit Sub
  45. ReDim NrsASCII(NumLet)
  46.  
  47. If NumLet = 1 Then      'Introduce los numeros ASCII en el vector NrsASCII
  48.     NrsASCII(NumLet) = Mid(CadenaASCII, PosComas(NumLet) + 1)
  49. Else
  50.     For i = 1 To NumLet
  51.         If i = NumLet Then
  52.             NrsASCII(i) = Str(Val(Mid(CadenaASCII, PosComas(i) + 1)))
  53.         Else
  54.             NrsASCII(i) = Mid(CadenaASCII, PosComas(i) + 1, PosComas(i + 1) - PosComas(i) - 1)
  55.         End If
  56.     Next i
  57. End If
  58.  
  59. For i = 1 To NumLet
  60.     CadenaNormal = CadenaNormal & Chr(Val(NrsASCII(i)))
  61. Next i
  62.            
  63. End Function
  64.  
  65.  
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: Jimbenit en Lunes 15 de Septiembre de 2008, 16:42
Mokito, saludos desde Colombia, me gustaria que revisaras el codigo antes de envialo.  :good:

Cita de: "m0skit0"
Estilo programación funcional:
No la he probado, así que es sólo teórico  ^_^


F_Tanori, es excelente tu función.

Citar
Function ConvertAscii(ByRef as_Cadena As String) As String
On Error GoTo xError
    Dim i As Integer, AsciiCode() As Byte
    AsciiCode = as_Cadena
    For i = LBound(AsciiCode) To UBound(AsciiCode) Step 2
        ConvertAscii = ConvertAscii & Format(AsciiCode(i), ",00")
    Next i
    ConvertAscii = (i / 2) & ConvertAscii
 
xError:
    If Err.Number > 0 Then
        ConvertAscii = Err.Description
        Err.Clear
    End If
End Function




Citar
errorSobrepasa:
     msgbox "Cada carácter de entrada genera entre 2 y 4 caracteres de salida. en VB6 el tamaño máximo de una cadena son 65535 caracteres, dicho valor se ha alcanzado con el " & k " ésimo carácter de la cadena de entrada..." & vbcrlf & err.description
      CadenaASCII=cadenanormal

Nebire, si asi es... tienes razón, pero para cadenas cortas esta buena, no??
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: m0skit0 en Lunes 15 de Septiembre de 2008, 17:18
Cita de: "Nilson Yair"
Revisa el siguiente codigo, no esta bien.

Sip, cierto, había un 5 de más debido a vbNullString.

Código: Visual Basic
  1.  
  2. Function ConvertAscii(ByRef as_Cadena As String) As String
  3.  
  4.     If as_Cadena = vbNullString Then
  5.         ConvertAscii = ""
  6.     Else
  7.         ConvertAscii = CStr(AscB(Left(as_Cadena, 1))) & "," & ConvertAscii(Right(as_Cadena, Len(as_Cadena) - 1))
  8.     End If
  9.  
  10. End Function
  11.  
  12.  

Sí, tiene una coma de más al final  :P

Cita de: "Nilson Yair"
F_Tanori, es excelente tu función.

Tienes un juicio discutible...

En cuanto a tu función inversa es demasiado código para algo tan sencillo.

La inversa de la mía (donde la cadena lleva una coma al final):

Código: Visual Basic
  1.  
  2. Function ConvertString(ByRef str_Cadena As String) As String
  3.  
  4.     If str_Cadena = vbNullString Then
  5.         ConvertString = ""
  6.     Else
  7.         ConvertString = Chr(CInt(Left(str_Cadena, InStr(1, str_Cadena, ",") - 1))) & ConvertString(Right(str_Cadena, Len(str_Cadena) - InStr(1, str_Cadena, ",")))
  8.     End If
  9.  
  10. End Function
  11.  
  12.  

El problema de la coma es fácilmente solucionable fuera de las funciones, así que no lo considero un error. Saludos.
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: Jimbenit en Lunes 15 de Septiembre de 2008, 17:27
Citar
Sí, tiene una coma de más al final :P
Tienes un juicio discutible...


Bueno, mi funcion para pasar a ascii posee una coma demas al final cuando el resultado es un solo numero

Por ejemplo:
'En la ventana inmediato prueba esto:
Código: Text
  1. PRINT convertascii(""),,, cadenaascii("")
  2.  

La funcio de la izq. es la de F_tenori, y la mia es la de la derecha.

¿Ves la diferencia de la coma?, pero para propositos practicos, esta buena... (hey, me agradas, VEO QUE ESTAS MUY CONECTADO!!!,  B) )
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: Jimbenit en Lunes 15 de Septiembre de 2008, 17:37
Citar
En cuanto a tu función inversa es demasiado código para algo tan sencillo.

La inversa de la mía (donde la cadena lleva una coma al final):

Mostrar/Ocultar Número de línea | Expandir/Contraer | Seleccionar todo

   1.  
   2. Function ConvertString(ByRef str_Cadena As String) As String
   3.  
   4.     If str_Cadena = vbNullString Then
   5.         ConvertString = ""
   6.     Else
   7.         ConvertString = Chr(CInt(Left(str_Cadena, InStr(1, str_Cadena, ",") - 1))) & ConvertString(Right(str_Cadena, Len(str_Cadena) - InStr(1, str_Cadena, ",")))
   8.     End If
   9.  
  10. End Function
  11.  


Estas como que diciendo incoherencias...
Mira esta funcion que pusiste "La inversa", esta mala... ¿Otraves enviando funciones sin probarlas?.... <_<
copia este codigo en la ventana inmediato y prueba esto (con tu funcion inversa)
Código: Text
  1. PRINT convertstring("4,89,65,73,82")
  2.  
  3.  
El resultado deberia ser "YAIR" pero esto da un error, ¿¿estas practicando programacion funcional?? (cambia de manual)

Moskito, saludos amigo...  :good:
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: Jimbenit en Lunes 15 de Septiembre de 2008, 21:32
Citar
MOSKITO DICE:
Tienes un juicio discutible...
En cuanto a tu función inversa es demasiado código para algo tan sencillo.

Bueno mira, la coma del final en tu funcion esta como requisito indispensable, acuerdate que es la funcion inversa de la primera, la cual no tiene coma al final (excepto cuando el valor resultado es un solo numero, como en el caso de : "")
 ¿Acaso se te hace dificil quitar esta coma del final dentro de esta misma función?, eso es por tu amor por a la recursividad, cierto ?  <_<

y sobre lo de "demasiado codigo" (puede que sea cierto y tengas razón)


Me quede esperando las funciones de ustedes, me gustaria revisarlas  <_<
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: Jimbenit en Lunes 15 de Septiembre de 2008, 21:41
Citar
MOSKITO DICE:
El problema de la coma es fácilmente solucionable fuera de las funciones, así que no lo considero un error

Bien, y que me dices del primer caracter generado por tu funcion...?

Código: Text
  1. print  convertstring("4,89,65,73,82,")
  2. YAIR
  3.  
  4.  
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: Jimbenit en Lunes 15 de Septiembre de 2008, 21:53
Ya se , ya se, ya se que he puesto muchos post referentes a este tema, solo espero que los moderadores me tengan algo de paciencia.

[LA PRUEBA DE FUEGO]

Recuerdan cuando uno estaba pequeño, aprendiendo la división?, cuando los profesores mandaban a uno a probar la división de dos cifras, el resultado (el cociente) se multiplicaba por el divisor y se le sumaba el residuo, este resultado debia ser el dividendo... recuerdan?

Pues bien, probemos las funciones de cadena para pasar a ascii y la funcion inversa


Código: Text
  1. Print CadenaNormal(CadenaASCII("YAIR"))
  2.  
[/color]


El resultado es "YAIR", si no da este resultado las funciones ( o una de las dos)estan malas.... ok?...

saludos.



 :good: Dificil???

Pues si... lo hacemos un poquito mas agradable.
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: F_Tanori en Lunes 15 de Septiembre de 2008, 22:07
Cita de: "Nilson Yair"
Citar
MOSKITO DICE:
El problema de la coma es fácilmente solucionable fuera de las funciones, así que no lo considero un error

Bien, y que me dices del primer caracter generado por tu funcion...?

Código: Text
  1. print  convertstring("4,89,65,73,82,")
  2. YAIR
  3.  
  4.  

Es por el numero 4 que tienes a iniciar la cadena ya que moskito no concidera el numero de caracteres de la cadena :P igual ocurrira un error sin una coma al final lo cual a mi si me parece un error :P

Incluso hay variacion de resultados (Nebire lo coloque al ultimo porque al parecer modifica la cadena y nos afecta al usarla byRef)

Código: Visual Basic
  1. Function Test(ByRef Text As String)
  2.     Debug.Print "Yair = " & Space(10) & CadenaASCII(Text)
  3.     Debug.Print "F_Tanori = " & Space(6) & ConvertAscii(Text)
  4.     Debug.Print "Moskito = " & Space(10) & ConvertAscii_Moskito(Text)
  5.     Debug.Print "Nebire = " & Space(8) & CadenaASCII_Nebire(Text)
  6. End Function
  7.  

Saludos
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: F_Tanori en Lunes 15 de Septiembre de 2008, 22:22
Esta es mi solucion inversa

Código: Visual Basic
  1. Function ConvertString_FTanori(ByRef as_Cadena As String) As String
  2. On Error GoTo xError
  3.     Dim i As Integer, AsciiCode
  4.    
  5.     AsciiCode = Split(as_Cadena, ",")
  6.    
  7.     For i = LBound(AsciiCode) + 1 To UBound(AsciiCode)
  8.         If AsciiCode(i) <> Empty Then
  9.             ConvertString_FTanori = ConvertString_FTanori & Format(Chr(AsciiCode(i)), " ")
  10.         End If
  11.     Next i
  12.  
  13. xError:
  14.     If Err.Number > 0 Then
  15.         ConvertString_FTanori = Err.Description
  16.         Err.Clear
  17.     End If
  18. End Function
  19.  

Asume que lleva la longitud al inicio de la cadena

Debug
Código: Text
  1. ?ConvertString_FTanori("4,89,65,73,82")
  2.  

Saludos
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: Jimbenit en Lunes 15 de Septiembre de 2008, 22:34
Moskito no se donde tiene la cabeza, su funcion tiene un error es el siguiente ejemplo:


Código: Text
  1. print convertstring("1")
  2.  


Parece que no acostumbra a verificar su funcion antes de postearla
Mi función tiene un error cuando el numero de caracteres sobrepasa cierto limite, como anoto Nebire
Citar
if len(cadenanormal)>16383 then
                msgbox "Existen posibilidades de que se produzca un error..."
          end if


Nuevamente, F_Tanori... muy bien por la función inversa.
 B)  :good:
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: Jimbenit en Lunes 15 de Septiembre de 2008, 22:44
Cuando digo:
Citar
Nuevamente, F_Tanori... muy bien por la función inversa.
No quiero decir que la de F_Tanori sea perfecta, de hecho no lo es...



miremos el siguiente codigo... comparemos.

Código: Text
  1. print ConvertString_FTanori("4,89,65,73,82,15,65"),,cadenanormal("4,89,65,73,82,15,65")
  2. YAIRA                      YAIR
  3.  
  4.  

A la izquierda la de Tanori;  a la derecha, la mia
¿Que paso?, parece que la de Tanori no usa el primer numero (4) como parametro de cantidad de lectura de la función

Ahora si ven por que no es perfecta?
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: Jimbenit en Lunes 15 de Septiembre de 2008, 22:49
Error Tanori

Miremos el sigueinte codigo:

Código: Text
  1. For i = LBound(AsciiCode) + 1 To UBound(AsciiCode)      'El limite superior no es el primer numero de la cadena?, o acaso es el numero de comas??
  2.  
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: F_Tanori en Lunes 15 de Septiembre de 2008, 23:02
Cita de: "Nilson Yair"
Cuando digo:
Citar
Nuevamente, F_Tanori... muy bien por la función inversa.
No quiero decir que la de F_Tanori sea perfecta, de hecho no lo es...



miremos el siguiente codigo... comparemos.

Código: Text
  1. print ConvertString_FTanori("4,89,65,73,82,15,65"),,cadenanormal("4,89,65,73,82,15,65")
  2. YAIRA                      YAIR
  3.  
  4.  

A la izquierda la de Tanori;  a la derecha, la mia
¿Que paso?, parece que la de Tanori no usa el primer numero (4) como parametro de cantidad de lectura de la función

Ahora si ven por que no es perfecta?

Por supuesto que ninguna  programacion es perfecta, ahora en mensajes anteriores quedo claro que
"4,89,65,73,82" daba como resultado YAIR (esta cadena incluye la longitud de la cadena en texto) y en el ejemplo de este mensaje estas colocando otra palabra

"4,89,65,73,82,15,65"
 
Aqui da como resultado YAIR
ConvertString_FTanori("4,89,65,73,82")

Aqui da como resultado YAIRA
ConvertString_FTanori("4,89,65,73,82,15,65") ' Ya que hay 2 caracteres de mas y el 15 "es el cuadrito" 65 es "A" que se ve al final

Arreglo (0) = 4
Arreglo (1) = 89
Arreglo (2) = 65
Arreglo (3) = 73
Arreglo (4) = 82
Arreglo (5) = 15
Arreglo (6) = 65

Estariamos hablando de una cadena de longitud 6 por lo tanto la posicion cero que es la longitud de la cadena miente porque dice 4

Tu funcion daria el mismo resultado de esta manera

cadenanormal("6,89,65,73,82,15,65")
YAIRA

Saludos
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: F_Tanori en Lunes 15 de Septiembre de 2008, 23:08
Cita de: "Nilson Yair"
Error Tanori

Miremos el sigueinte codigo:

Código: Text
  1. For i = LBound(AsciiCode) + 1 To UBound(AsciiCode)      'El limite superior no es el primer numero de la cadena?, o acaso es el numero de comas??
  2.  


Código: Text
  1. LBound(AsciiCode)
  2.  
Dara como resultado 0 que es la posicion que guarda la longitud de la cadena

Código: Visual Basic
  1. LBound(AsciiCode)  + 1
  2.  

Solo la posicion 0 y despues convierte los caracteres de la cadena pasada como parametro, pero si hay que generar solo la longitud que viene en la cadena  aqui esta el SP 1 :P

Código: Text
  1. Function ConvertString_FTanori(ByRef as_Cadena As String) As String
  2. On Error GoTo xError
  3.     Dim i As Integer, AsciiCode
  4.    
  5.     AsciiCode = Split(as_Cadena, ",")
  6.    
  7.     For i = LBound(AsciiCode) + 1 To AsciiCode(0)
  8.         If AsciiCode(i) <> Empty Then
  9.             ConvertString_FTanori = ConvertString_FTanori & Format(Chr(AsciiCode(i)), " ")
  10.         End If
  11.     Next i
  12.  
  13. xError:
  14.     If Err.Number > 0 Then
  15.         ConvertString_FTanori = Err.Description
  16.         Err.Clear
  17.     End If
  18. End Function
  19.  
  20.  

Saludos
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: Jimbenit en Lunes 15 de Septiembre de 2008, 23:12
Al principio de este post dije:
Citar
En cierta ocasion tuve que diseñar una funcion que me pasara una cadena de texto en sus equivalentes ASCII, pero con un formato especial, por ejemplo:
"Hola mundo"
El resultado debia ser:


10,72,111,108,97,32,109,117,110,100,111


Donde el primer numero indica el numero de caracteres de la cadena y los demas numeros son sus equivalentes ASCII

Cierto???
Pues bien, el numero de caracteres leidos esta especificado por el primer numero que aparece en la cadena, por que si no es asi entonces ¿De que serviría estar en la cadena?

Con lo anterior quiero decir que no importa cuantos numeros aparezcan en esta cadena, solo seran leidos la cantidad de caracteres que se especifiquen en el primer numero de la cadena.


 B) Pero... me impresiona mucho la capacidad de este codigo... en serio....

Muy bien.... muy bien hecho... de verdad..
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: Jimbenit en Lunes 15 de Septiembre de 2008, 23:17
B) Excelente Tanori... excelente :good:

 :lol: Fue divertido, no???
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: Jimbenit en Lunes 15 de Septiembre de 2008, 23:56
[INICIANDO NUEVA FUNCION]

Ya que ninguno publica sus funciones de procesamientos de texto, el cual es el objetivo principal de este post, yo publicaré otra de mis funciones de procesamiento de texto

En cierta ocasión una vez tuve que diseñar un codigo que me permitiera guardar datos en un bloc de notas pero con un formato muy especial , este formato es el siguiente:

El bloc de notas debia ser organizado por filas y columnas, y guardar los datos de acuerdo a esta posición.
Ejemplo:
Código: Text
  1. Call EscribirDatoMATRIZ(3, 10, "Cadena guardada en (F= 10, C=3)", "C:BlocMio.txt")
  2.  
Lo anterior guarda "Cadena guardada en (F= 10, C=3)" en la posicion : fila 10 , columna 3 del orden que se invento en esta función[/color], las comas separan las COLUMNAS y las filas del bloc de notas separan las FILAS de este formato


Si quisiera guardar el numero 20, de acuerdo al orden aqui descrito en la posicion Fila = 4, Columna = 3: el codigo seria el siguiente:


Código: Text
  1. Call EscribirDatoMATRIZ(3, 4, 20, "C:BlocMio.txt")
  2.  
"C:BlocMio.txt" es la ruta donde este archivo se guarda.
[/color]


El proceso es el siguiente:
Código: Text
  1. Sub EscribirDatoMATRIZ(Colum As Long, Fila As Long, Dato As Variant, RutaArchivo As String)
  2. 'Guarda datos en un bloc notas en forma de comas... utiliza el bloc
  3. 'como una matriz ordenada por filas y columnas... [Mayo 5 / 2008]
  4.  
  5. Dim Contador As Double
  6. Dim Vector() As Variant
  7. Dim Caracter As String
  8. Dim Max As Double
  9. Dim Linea As Long
  10. Dim Cadena As String
  11. Dim NumLet As Long
  12. Dim Letr As String
  13. Dim Cont As Long
  14. Dim PosComas() As Long
  15. Dim Pedazo1 As String
  16. Dim Pedazo2 As String
  17. Dim Comas_Add As Long
  18.  
  19. If Dir(RutaArchivo) = "" Then           'Comprueba si existe archivo, en caso de no existir, lo crea.
  20.     Open RutaArchivo For Output As #1
  21.     Print #1, " "
  22.     Close #1
  23. End If
  24.  
  25. Linea = Fila
  26.  
  27. For j = 1 To 2          'Introduce todas las lineas del Bloc notas en un Vector llamado Vector()
  28.     Open RutaArchivo For Input As #1
  29.     While Not EOF(1)                'Cuenta las lineas del Bloc Notas
  30.         Line Input #1, Caracter
  31.         i = i + 1
  32.         If j = 1 Then
  33.             Contador = i
  34.         ElseIf j = 2 Then       'Si j = 2 , se escriben las lineas dentro del vector
  35.             Vector(i) = Caracter
  36.         End If
  37.     Wend
  38.     Close #1
  39.     If j = 1 Then
  40.         If Linea > Contador Then        'Define el tamaño del vector
  41.             ReDim Vector(1 To Linea)
  42.             Max = Linea
  43.         Else
  44.             ReDim Vector(1 To Contador)
  45.             Max = Contador
  46.         End If
  47.         i = 0
  48.     End If
  49. Next j
  50.  
  51.  
  52. For i = 1 To Max        'Obtiene la fila en string separada por comas
  53.     If i = Fila Then
  54.         Cadena = Vector(i)
  55.     End If
  56. Next i
  57.  
  58.             'Obtención de las posiciones de las comas
  59. '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  60.         NumLet = Len(Cadena)
  61.         For i = 1 To NumLet     'Cuenta las comas dentro de la cadena
  62.             Letr = Mid(Cadena, i, 1)
  63.             If Asc(Letr) = 44 Then
  64.                 Cont = Cont + 1
  65.             End If
  66.         Next i
  67.  
  68.         If Colum > Cont + 1 Then        'Columna vacia
  69.             Comas_Add = Colum - (Cont + 1)
  70.             For i = 1 To Comas_Add
  71.                 Cadena = Cadena & ", "
  72.             Next i
  73.             Cont = Colum - 1
  74.         End If
  75.        
  76.         NumLet = Len(Cadena)
  77.         ReDim PosComas(Cont)
  78.         Cont = 0
  79.         For i = 1 To NumLet     'Coloca las posiciones de las comas dentro del vector
  80.             Letr = Mid(Cadena, i, 1)
  81.             If Asc(Letr) = 44 Then
  82.                 Cont = Cont + 1
  83.                 PosComas(Cont) = i
  84.             End If
  85.         Next i
  86. '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  87.  
  88. 'Añadiendo el dato a la cadena [Elimina el dato anterior en esa posición]
  89. If Cont = 0 Then
  90.     Cadena = Dato
  91. ElseIf Colum = 1 Then                           'Coloca el dato al principio
  92.     Cadena = Dato & Mid(Cadena, PosComas(1))
  93. ElseIf Colum = UBound(PosComas()) + 1 Then      'Coloca el dato al final
  94.     Cadena = Mid(Cadena, 1, PosComas(Colum - 1)) & Dato
  95. Else
  96.     Pedazo1 = Mid(Cadena, 1, PosComas(Colum - 1))
  97.     Pedazo2 = Mid(Cadena, PosComas(Colum))
  98.     Cadena = Pedazo1 & Dato & Pedazo2
  99. End If
  100.  
  101. 'Escribiendo en el Bloc Notas
  102. Open RutaArchivo For Output As #1
  103. For i = 1 To Max
  104.     If i = Linea Then
  105.         Vector(i) = Cadena
  106.         Print #1, Vector(i)
  107.     Else
  108.         Print #1, Vector(i)
  109.     End If
  110. Next i
  111. Close #1
  112.  
  113.  
  114.  
  115. End Sub
  116.  
  117.  
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: m0skit0 en Martes 16 de Septiembre de 2008, 08:55
Interesante discusión, chavales. Aunque os falta un poco de experiencia en programación  ^_^ (es broma, no se piquen)

¿Para qué quieres poner la longitud al principio? Me parece una perdida de tiempo, aunque acepto que sea el enunciado. De todas formas, se puede quitar antes de llamar a la función.

Ay, Nilson, a ver si leemos

Cita de: "Nilson Yair"
Moskito no se donde tiene la cabeza, su funcion tiene un error es el siguiente ejemplo:


Mostrar/Ocultar Número de línea | Expandir/Contraer | Seleccionar todo

   1. print convertstring("1")

Cita de: "m0skit0"
La inversa de la mía (donde la cadena lleva una coma al final):

En cuanto a F_tanori...

Cita de: "F_Tanori"
ocurrira un error sin una coma al final lo cual a mi si me parece un error

Otra tontería. Si consigues una función que haga un determinado trabajo de la forma más sencilla, me parece absurdo tirarla por la borda porque falte o deje de faltar una coma al final. Hay que subdividir los problemas hasta lo más sencillo posible y luego unirlos ¿Habéis oído hablar de Right() y Left() y concatenación? :P

Código: Visual Basic
  1.  
  2. aux = ConvertAscii("Vaya códigos")
  3. 'aux sin coma al final
  4. aux = Left(aux, Len(aux) - 1)
  5. [...]
  6. a_convertir = "55,56,57,58"
  7. 'necesitamos una coma al final
  8. aux = ConvertString(a_convertir & ",")
  9.  
  10.  

¡Vaya complicación, no?  :lol:
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: F_Tanori en Martes 16 de Septiembre de 2008, 10:43
Cita de: "m0skit0"
En cuanto a F_tanori...

Cita de: "F_Tanori"
ocurrira un error sin una coma al final lo cual a mi si me parece un error


Otra tontería. Si consigues una función que haga un determinado trabajo de la forma más sencilla, me parece absurdo tirarla por la borda porque falte o deje de faltar una coma al final. Hay que subdividir los problemas hasta lo más sencillo posible y luego unirlos ¿Habéis oído hablar de Right() y Left() y concatenación?  :P  

Tirarla por la borda? de que hablas willy?

A que hora dije que "no servia", el fin de esto era "resolver el problema" , todos tenemos formas programacion diferente, asi como la resolucion de problemas  y jamas dije que tu funcion no sirviera, pero creo que en todo el hilo tus funciones no cumplian (por eso es un error lo de la coma) con lo que tenian que hacer segun el problema planteado (que era solo un ejercicio) puedes hacer la funcion mas optimizada para sumar y decir que se ejecuta en el menor tiempo posible , pero tiene un problema cuando agregas mas de 2 numeros no suma, pero no es un error porque se puede arreglar   :o   :)  

en fin...

y si he oido de lo que me preguntas ? tienes algun problema para comprenderlo ? ocupas alguna explicacion ? :P


Saludos
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: m0skit0 en Martes 16 de Septiembre de 2008, 11:41
¿Hay algun problema en utilizar más de una función, o tiene que ser una y sólo una? Pues entonces no veo donde está el error...  -_-

Cita de: "F_Tanori"
pero tiene un problema cuando agregas mas de 2 numeros no suma

Bueno, no exageres, en todo caso sería que devuelve el número en real y no en entero  :lol:

P.D: Pido disculpas por lo de la longitud de la cadena, no me había dado cuenta en un principio...
P.D(2): No sé quién es Willy...  :D
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: F_Tanori en Martes 16 de Septiembre de 2008, 17:30
Cita de: "m0skit0"
P.D(2): No sé quién es Willy...  :D

Era una serie de television de ya hace algunos años se llamaba Blanco y Negro o Diff'rent Strokes la frase es "un poco famosa" :P

http://www.youtube.com/watch?v=Qw9oX-kZ_9k (http://www.youtube.com/watch?v=Qw9oX-kZ_9k" onclick="window.open(this.href);return false;)


Saludos
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: Jimbenit en Martes 16 de Septiembre de 2008, 17:42
Ya no quieren seguir jugando a las funciones de texto???

Nota:
Esto les serviría mucho a los novatos (como yo)  B)
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: m0skit0 en Jueves 18 de Septiembre de 2008, 13:06
Yo sigo con mi programación funcional en VB ( :lol:  :lol: )

Código: Visual Basic
  1.  
  2. Public Function InvertirCadena(ByVal str As String) As String
  3.     If Len(str) <= 1 Then
  4.         InvertirCadena = str
  5.     Else
  6.         InvertirCadena = Right(str, 1) & InvertirCadena(Left(Right(str, Len(str) - 1), Len(str) - 2)) & Left(str, 1)
  7.     End If
  8. End Function
  9.  
  10.  

Cuidado con quedarse sin pila XD
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: F_Tanori en Jueves 18 de Septiembre de 2008, 22:55
Cita de: "m0skit0"
Otra tontería. Si consigues una función que haga un determinado trabajo de la forma más sencilla, me parece absurdo tirarla por la borda ...

Exacto ya que en VB6 ya existe esa funcion se llama strreverse(str)

Cita de: "m0skit0"
Yo sigo con mi programación funcional en VB ( :lol:  :lol: )

Código: Visual Basic
  1.  
  2. Public Function InvertirCadena(ByVal str As String) As String
  3.     If Len(str) <= 1 Then
  4.         InvertirCadena = str
  5.     Else
  6.         InvertirCadena = Right(str, 1) & InvertirCadena(Left(Right(str, Len(str) - 1), Len(str) - 2)) & Left(str, 1)
  7.     End If
  8. End Function
  9.  
  10.  

Cuidado con quedarse sin pila XD


 aunque como ejercio esta bien; solo que deberias de usar el parametro ByRef para utilizarlo como "puntero" y no estarlo pasando como copia a cada llamado de la funcion

Saludos
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: Jimbenit en Jueves 18 de Septiembre de 2008, 23:21
^_^Vaya palabras has citado F_Tanori.
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: Nebire en Viernes 19 de Septiembre de 2008, 02:53
Bueno comentaros que el otro día respondí, pero era hora de cenar y no había terminado el mensaje después al enviar no me di cuenta de que habría caducado la sesión, me deslogó y me dió pereza reconstruir el mensaje (porqué estos foros no pueden recuperar el mensaje, hace 10 años se entiiende pero hoy día esto es intolerable, en fin...)

Mencionaba que yo no considero un error una coma al final, de más o de menos ya que de hecho la función que presentaba ilson quedaba 'guarreada' precisamente por querer mantener esa coma y por lo del númerito delante que 'pa qué ?'. La coma no estorba porque a menudo debe concatenarse un resultado con otro y por tanto suele tenerse que meter cuando en la función se lo extrajo.

También os presentaba otra manera de resolver la función sencilla y con mucha claridad aunque ligeramente más lenta.

Señalaba que la función de Nilson puede mejorarse a lo siguiente (prescindiendo del numerito que no sirve para nada y que lleva siempre coma al final excepto que sólo haya un carácter.)

Código: Visual Basic
  1.  
  2. Function CadenaASCII(CadenaNormal As String) As String
  3.     Dim k As Long, cadena As String
  4.    
  5.     On Local Error GoTo errorSobrepasa:
  6.    
  7.         cadena = ""
  8.         'If CadenaNormal = "" Then Exit Function
  9.         If Len(CadenaNormal) > 16383 Then
  10.              MsgBox "Existen posibilidades de que se produzca un error..."
  11.         End If
  12.        
  13.         For k = 1 To Len(CadenaNormal)  ' el último carácter lo quedamos fuera del bucle
  14.           cadena = cadena & Asc(Mid$(CadenaNormal, k, 1)) & ","
  15.         Next ' al finalizar el bucle, k todavía aumenta en 1
  16.  
  17.     CadenaASCII = cadena
  18.     Exit Function
  19.    
  20. errorSobrepasa:
  21.      MsgBox ("Cada carácter de entrada genera entre 2 y 4 caracteres de salida. en VB6 el tamaño máximo de una cadena son 65535 caracteres, dicho valor se ha alcanzado con el " & " k ésimo carácter de la cadena de entrada..." & vbCrLf & Err.Description)
  22.      CadenaASCII = cadena
  23. End Function
  24.  
  25.  
  26.  


Yo proponía la siguiente función ligeramente más lenta que esta anterior pero bastante más clara y breve
Código: Visual Basic
  1.  
  2. ' bytes con comas
  3. Private sub Cadena_A_BytesCC(byref cadena As String, optional concat as string=",")  ' nótese el byref puesto a propósito
  4.          Dim s() As String
  5.        
  6.         ReDim s(0 To Len(cadena))
  7.         For k = 1 To Len(cadena)
  8.             s(k) = Asc(Mid$(cadena, k, 1))
  9.         Next
  10.        
  11.         cadena= Join(s, concat)
  12. End Function
  13.  
  14.  
De esta fnción decir que la coma en vez de aparecer al final aparecerá al principo, para el caso es lo mismo siempre que se tenga en cuenta.
Como puede verse a esta función le he añadido un parámetro opcional que sirve para 'meter'  cualquier cadena y no sólo comas, lo que le daría más versatilidad sin apenas código adicional.

La función inversa resulta igualmente breve:
Código: Visual Basic
  1.  
  2.   ' nota la cadena puede empezar tanto con coma como con cifras, pero si empieza con coma debe ir detrás números, la cadena no puede acabar en coma, esta función es la pareja de la anterior, que deja cadenas con comas delante, no es pareja de una función que deje comas detrás.
  3.   Private Function convertir(cadena As String) As String
  4.       Dim s() As String, ini As Byte
  5.      
  6.      on local error goto errorChr
  7.       s = Split(cadena, ",")
  8.       ini = IIf(Left$(cadena, 1) = ",", 1, 0)
  9.    
  10.       For k = ini To UBound(s)
  11.           s(k) = Chr$(s(k))
  12.       Next
  13.       convertir = Join(s, "")
  14.      exit function
  15. errorChr:
  16.      msgbox "La cifra ' " & s(k) & " ' no está dentro del rango 0-255 (byte)" & err.description
  17.    End Function
  18.  
  19.  
se supone que nunca habría de ocurrir chr$(23456) si se creó usando la otra función.... pero bueno se ha incluído un tratamiento de error...
Y en otro momento os coloco una función que totaliza las palabras que hay en un texto, para lo que pide nuestro amigo Nilson...
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: m0skit0 en Viernes 19 de Septiembre de 2008, 09:23
Citar
solo que deberias de usar el parametro ByRef para utilizarlo como "puntero" y no estarlo pasando como copia a cada llamado de la funcion

Entonces, ¿para qué queremos ByVal?  :lol:  :lol:

En teoría, no tienes razón: debería pasarse ByVal (por valor) porque no se va a modificar dicho parámetro, así el código queda más claro y entendible (aparte de poder cambiar de valor el parámetro sin que se modifique en el código llamante).

En la práctica, tienes razón, porque el código corre más deprisa pasando sólo un puntero (ByRef, por referencia) en vez de hacer la copia de la variable.

Lo que me lleva a preguntarles:
¿Qué creen que compensa más: que el código se ejecute más rápido o que sea más legible?  <_<
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: Jimbenit en Viernes 19 de Septiembre de 2008, 15:43
La conversación ahora gira entorno a la legibilidad y a la rapidez...  
Pero pensando bien... esto es lo que realmente importa de un codigo...  B), pero para el nivel de principiante (para lo que este foro fue creado), creo que esta bien.... pero es muy, muy interesante ver los codigos de programadores EXPERTOS (como ustedes) <_<  resolviendo aquello que los chiquillos hacen (como yo), sin lugar a dudas es fantastico poder interactuar con ustedes  :good:

Saludos y gracias por lo que me enseñan... (como podré agradecerles esto???)
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: F_Tanori en Sábado 20 de Septiembre de 2008, 04:24
Algunas teorias indican que hay que darle prioridad , al lector (del codigo) es decir que sea mas entendible,pero en lo personal creo que es mas importante la rapidez y eficientación de recursos , y quien no lo entienda debera informarse un poco mas :P

* En este caso aun usando ByRef no se modifica la variable

Código: Text
  1. ... InvertirCadena(ByRef str As String) ...
  2.  

Saludos
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: Nebire en Sábado 20 de Septiembre de 2008, 11:39
Cita de: "m0skit0"
Lo que me lleva a preguntarles:
¿Qué creen que compensa más: que el código se ejecute más rápido o que sea más legible?  <_<
Interesante pregunta. A título personal (porque de forma general dudo que pueda darse una respuesta exacta.... y que todo el mundo esté de acuerdo) creo que uno tiene que hacer un balance en su código.

Esto es, si tu programa vuela entonces puedes darle más importancia a la legibilidad y la brevedad (a menudo están reñidos otras no), en cambio si el programa adolece de lento, no es plan pretender ser tan legible. a menudo la falta de claridad en un programa la acabamos supliendo con comentarios. También cuenta si tu código ha de pasar por otras manos distintas a las tuyas, ahí la claridad tiene más importancia. Por otro lado a medida que los procesadores son más rápidos y las memorias más grandes tiene menos relevancia la velocidad. Lo importante es que uno sepa fijar el límite.

Por ejemplo uno puede escribir un código denso y oscuro en 5000 líneas y ser muy veloz en cambio quizás puede hacer lo mismo con sólo 500 líneas pero recurriendo por ejemplo a librerías externas. El caso es que 500 líneas será un código más fácil de seguir pero por otro lado al ser las librerías externas implican cierto oscurantismo porque requiere estudiarse esas librerías, si son de uso frecuente como las API de windows, se hace mucho más llevadero pero cuando son de diferentes programas y un puñado de cada uno, tienes menos libertad vas a veces forzado por las limitaciones de las librerías y por la manera en que fueron programadas. entonces comparativamente quizás esas 5000 líneas densas y oscuras quizás compensen sobre esas 500. Pero como digo cada uno en su caso debe sopesarlo. dudo que pueda generalizarse si no es diviiidiendo en grupos e indicar si uno pertenece a ese grupo a tal vez al otro.
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: Nebire en Sábado 20 de Septiembre de 2008, 12:50
Aprovechando que tengo un rato libre voy a exponer una función que es posible que la tengais parecida o muy distinta, nunca se sabe.

La función como comentaba más arriba trata de contar las palabras que tiene un texto. Por comparativa (nuca se me ha ocurrido verificar antes el potencial de esta función) he realizado otra equivalente que al hilo de lo que venimos hablando es más breve pero tiene un rendimiento bastante menor.
A ambas funciones, como se aprecia se han 'inyectado' dentro de un bucle de 1000 reps. para comprobar diferencias ya que si no resulta difícil apreciarlo en su justa medida.

Código: Visual Basic
  1.  
  2.  
  3. Public Function Contar_Palabras1(texto As String) As Long
  4.     Dim txt() As String
  5.     Dim k As Long ' contador
  6.     Dim i As Long ' contador del bucle
  7.    
  8.     ti = Timer
  9.     For A = 1 To 1000
  10.         txt = Split(texto, " ")
  11.         If texto <> "" Then
  12.             If UBound(txt) = 0 Then
  13.                 If Trim$(txt(0)) <> "" Then
  14.                     Contar_Palabras1 = 0: GoTo salir ' Exit Function
  15.                 Else
  16.                     Contar_Palabras1 = 1: GoTo salir ' Exit Function
  17.                 End If
  18.             End If
  19.         End If
  20.        
  21.         For i = 0 To UBound(txt)
  22.             If txt(i) <> "" Then
  23.                 k = k + 1
  24.             End If
  25.         Next
  26.     Next
  27.     Contar_Palabras1 = k
  28.  
  29. salir:
  30.     MsgBox Timer - ti
  31.  End Function
  32.  
  33.  


La siguiente función es bastante menos lógica en cuanto a idearla, sirve de  contraste para la comparativa, usa un bucle do

Código: Visual Basic
  1.  
  2. Public Function Contar_Palabras2(texto As String) As Long
  3.     Dim k As Long  ' contador
  4.     Dim p As Long ' posición en la cadena
  5.     Dim txt As String '
  6.    
  7.     ti = Timer
  8.    
  9.         For A = 1 To 1000
  10.  
  11.         txt = Trim$(texto)
  12.         If txt = "" Then Contar_Palabras1 = 0: Exit Function
  13.        
  14.         Do
  15.             p = InStr(txt, " ") ' espacio entre comillas
  16.             If p > 0 Then       ' mientras haya espacio entrará aquí...
  17.                 k = k + 1
  18.                 txt = Trim$(Mid$(txt, p + 1)) ' elimino la palabra más a la izquierda y quito los espacios extras hasta la siguiente palabra.
  19.             Else                  ' cuando no haya más espacios, ya no quedan más palabras, devolvemos el resultado
  20.                k = k + 1
  21.                Exit Do
  22.             End If
  23.         Loop
  24.     Next
  25.     Contar_Palabras2 = k
  26.     MsgBox Timer - ti
  27. End Function
  28.  
  29.  

Puede notarse que si declaamos el parámetro byval la misma variable del parámetro podría usarse en vez de 'txt', que por otro lado ha sido forzado por el bucle de repetición externo.
Aunque parezcan muy similares, lo cierto es que los resultados son bastante diferenciados.

El texto empleado fue un archivo en la carpeta de windows, concretamente el de 'wmsetup.log' que en mi caso pesa 9'13kb. y contiene 1.056 palabras, con el bucle de 1000 repeticiones halló:

1.056.000 ----- 3'7 sg   funcion 1
1.056.000 -----16'01 sg. función 2

El resto del código para probarlo son 2 botones de llamada uno para cada función un label indicando las palabras encontradas y un richtextbox donde se carga el fichero y cuyo texto es el empleado.
El código 'extra' para probarlo es el siguiente:
Código: Visual Basic
  1.  
  2.     Private Sub Form_Load()
  3.     Rtxt.FileName = "C:WINDOWSwmsetup.log"
  4. End Sub
  5.  
  6. Private Sub Command1_Click()
  7.     Label1.Caption = "Palabras totales= " & Contar_Palabras1(Rtxt.Text)
  8. End Sub
  9.  
  10. Private Sub Command2_Click()
  11.     Label1.Caption = "Palabras totales= " & Contar_Palabras2(Rtxt.Text)
  12. End Sub
  13.  
  14.  
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: ferhn en Sábado 20 de Septiembre de 2008, 17:07
Aca les dejo algo interesante para hacer casi de todo con texto

Esto lo hice dentro de un clase
Código: Text
  1.  
  2. Dim cTexto As String
  3. Dim dLetras As Integer
  4.  
  5. Dim i, SB, J As Integer
  6. Dim P() As String
  7. Dim POriginal As String
  8.  
  9. 'para las palabras
  10. Dim dPalabra As Integer
  11. Dim wordCount As Integer            ' Número de palabras en el documento
  12. 'Dim sourceText As String            ' Contiene el texto del documento para examinarlo
  13. Dim startFound, endFound As Integer ' Banderas para seguir la pista de las palabras encontradas
  14. Dim thisChar As String
  15. 'mayuscula
  16. Dim Mayu As String
  17. Dim Minus As String
  18. Dim DNormal As String
  19. Dim LetraSin As String
  20. Dim TextoReves As String
  21. Dim Fechas As Date
  22. Dim Hora As Date
  23.  
  24. Public Property Get CuentaLetras() As String
  25.     CuentaLetras = dLetras
  26. End Property
  27.  
  28. Public Property Let CuentaLetras(ByVal vNewTexto As String)
  29.     cTexto = vNewTexto
  30.     dLetras = Len(cTexto)
  31. End Property
  32.  
  33.  
  34. Public Property Get CuentaPalabra() As String
  35.     CuentaPalabra = wordCount
  36. End Property
  37.  
  38. Public Property Let CuentaPalabra(ByVal vNewValue As String)
  39.     ' Inicializar wordCount, offSet, y las banderas "Found"
  40.     wordCount = 0: offSet = 1: startFound = False: endFound = False
  41.     ' Copiar documento en variable (para examinarlo más rápidamente)
  42.    
  43.    
  44.     ' Examina cada carácter hasta llegar al final del documento.
  45.     Do Until offSet > Len(cTexto)
  46.         thisChar = Mid$(cTexto, offSet, 1)
  47.         If Not startFound Then
  48.             ' Buscar principio de palabra
  49.             startFound = isAlphaNumeric(thisChar)
  50.             If startFound Then wordCount = wordCount + 1
  51.         Else
  52.             ' Buscar final de palabra.
  53.             endFound = Not isAlphaNumeric(Mid$(cTexto, offSet, 1))
  54.             If endFound Then startFound = False: endFound = False
  55.         End If
  56.         offSet = offSet + 1
  57.     Loop
  58.        
  59.     'Visualizar el número de palabras
  60.     'MsgBox "Este documento contiene " & wordCount & " palabras."
  61. End Property
  62.  
  63. Private Function isAlphaNumeric(anyChar) As Integer
  64.     Select Case Asc(anyChar)
  65.         Case 65 To 90   'A a Z
  66.             isAlphaNumeric = True
  67.         Case 97 To 122  'a a z
  68.             isAlphaNumeric = True
  69.         Case 48 To 57   '0 a 9
  70.             isAlphaNumeric = True
  71.         Case 193, 225, 201, 233, 205, 237, 211, 243, 218, 250 'Á, É, Í, Ó, Ú, á, é, í, ó, ú
  72.             isAlphaNumeric = True
  73.         Case 220, 252   'Ü, ü
  74.             isAlphaNumeric = True
  75.         Case 209, 241   'Ñ, ñ
  76.             isAlphaNumeric = True
  77.         Case Else
  78.             isAlphaNumeric = False
  79.     End Select
  80. End Function
  81.  
  82. Public Property Get TodoMayus() As String
  83.     Mayu = StrConv(cTexto, vbUpperCase)
  84.     TodoMayus = Mayu
  85. End Property
  86.  
  87.  
  88. Public Property Get TodoMinus() As String
  89.     Minus = StrConv(cTexto, vbLowerCase)
  90.     TodoMinus = Minus
  91. End Property
  92.  
  93.  
  94. Public Property Get Normal() As String
  95.     Normal = DNormal
  96. End Property
  97.  
  98. Public Property Let Normal(ByVal vNewValue As String)
  99.     DNormal = vNewValue
  100. End Property
  101.  
  102.  
  103. Public Property Get PalabraExtraida(Text1 As TextBox, Numero As Integer)
  104.     Dim SB, J As Integer
  105.         SB = 1
  106.         For i = 1 To Len(Text1)
  107.                 If Mid(Text1, i, 1) <> " " Then
  108.                     ReDim Preserve P(SB)
  109.                     P(SB) = P(SB) & Mid(Text1, i, 1)
  110.                     J = i
  111.                 Else
  112.                     Do While Mid(Text1, i, 1) = " "
  113.                        i = i + 1
  114.                     Loop
  115.                     i = i - 1
  116.                     SB = SB + 1
  117.                 End If
  118.         Next i
  119.         If Numero <= SB Then
  120.             PalabraExtraida = P(Numero)
  121.             For i = 0 To SB - 1
  122.                 P(i) = ""
  123.             Next i
  124.         Else
  125.             MsgBox "No existe la palabra " & Numero, vbCritical, "Mensaje"
  126.             Text1.Text = ""
  127.         End If
  128. End Property
  129.  
  130. Property Get CantLetras(txtTexto As TextBox)
  131. Dim J As Integer
  132. Dim SB As Integer
  133. Dim S As String
  134.        
  135.         If Len(txtTexto.Text) <= 255 Then
  136.             For i = 1 To Len(txtTexto)
  137.                 S = Mid(txtTexto, i, 1)
  138.                 If S <> Chr(32) Then
  139.                     J = J + 1
  140.                 End If
  141.             Next i
  142.             CantLetras = J
  143.        End If
  144.  
  145.     CantLetras = CantLetras
  146. End Property
  147.  
  148. 'PARA TEXTO REVERSO
  149. Public Property Get TextReverso() As Variant
  150. TextoReves = StrReverse(cTexto)
  151.     TextReverso = TextoReves
  152. End Property
  153.  
  154. Public Property Get Fecha() As Date
  155. Fechas = Time(Label7.Caption)
  156. Fecha = Fechas
  157. End Property
  158.  
  159. Public Property Get Horas() As Date
  160. Hora = Time(LblHora.Caption)
  161. Horas = Hora
  162. End Property
  163.  
  164.  
Título: Re: Podrian Publicar funciones para procesar Cadena de texto
Publicado por: Nebire en Miércoles 8 de Octubre de 2008, 12:12
Bueno ferhn, tu 'texto' admite varios comentarios....

Primero 2 incisos, el primero es que resulta visiblemente difícil de leer, acostúmbrate a usar el ( quitando las comillas simples)  '['code=vb']'  en vez de '['code=text']'... al colorear se ve mejor donde empizan y acaban las funciones, etc...

El 2º es que parece que has copiado el código de alguien y le has dado unos toques personales, al respecto te señalo que cuando hagas así o dejas todo en 'inglis' o lo cambias todo al español pero eso de tener un 'espanglis' a mi me produce cierta repulsión... encontrasem 'startFound' y 'TextoReves' me parece estar comunicando con un alien que oye cosas no las entiende pero confía en que el que lo reciba si. Esto es sólo una cuestión de estilo, no es algo grave pero da una indicación de el respeto hacia los demás si se adecúa el código, copiar y pegar sólo es señal de dejadez...

y ahora los comentarios...

Cita de: "ferhn"

Public Property Get CuentaLetras() As String
    CuentaLetras = dLetras
End Property
 
Public Property Let CuentaLetras(ByVal vNewTexto As String)
    cTexto = vNewTexto
    dLetras = Len(cTexto)
End Property
Esto carece de sentido la función len(texto) resuelve el caso,  no necesita por tanto travestirse de propiedad.

Cita de: "ferhn"

Public Property Get CuentaPalabra() As String
    CuentaPalabra = wordCount
End Property
 
Public Property Let CuentaPalabra(ByVal vNewValue As String)
Aquí varios comentarios, comentario 1 en la parte 'GET' puede verse también en el anterior. Si cuentapalabra suponemos que es una cifra a qué leches viene poner un 'string' ????. Yo te lo digo... a que haces algo impropio, algo impropio es asignar un valor a allgo que realmente no le pertenece, es como vestir a un mono de santo o como poner un remolque a un Formula-1. Al parecer no sabes cuando algo debe ser una propiedad y cuando una función. Yo te lo explico: si cuando introduces un dato es un tipo de datos y cuando debe devolver un dato devuelve un tipo de datos distinto al que se pedía como parámetro, eso es lo que describe una función. si el tipo de datos pasado por parámetro se ha de retener y en otra ocasión se puede pedir y es el mismo tipo de datos, eso es para usar como propiedad... si el parámetro se pasa e inmediatamente hace algo y ese dato no ha de quedar retenido eso es un método...

Por tanto comentario 2: (en la parte LET)  CuentaPalabraS (con S al final porque es plural cuanta muchas no una) debe ser una función... Te voy a decir que puede ocurrir si lo dejas como propiedad... si le pasamos como parámetro un texto de 30 mb. una vez que haya terminado de precesarlo como propiedad que es, guardaría el parámetro hasta que se inroduzca otro, o lo que es lo mismo, estarías reteniendo en memoria inútilmente datos que no se necesitan ya... tampoco hace falta que sea  30 Mb. para que esto sea una estupidez, pongo 30Mb. para que se vea claramente que lo es.

comentario: 3 Una propiedad debe retener 'memorizado' uno de sus parámetros, si se le pasa x parámetros y lo que retiene no es ninguno de ellos realmente no es una propiedad, es nuevamente una función si yo tengo la propiedad: Color_de_Pelo lo lógico es que el parámetros sea un color y adicionalmente otro u otros parámetros si fueran necesarios, pero la propiedad alamcenará el color tal como indica su nombre y al rescatar la propiedad será dicho valor el que he de devolver, si la propiedad es color_de_Pelo y le paso como parámetros 5 dedos, 2 pies y 3 camisas pero nunca el color del pelo, habrá alguien que sepa utilizar esa 'propiedad' ...?  realmente habría que llamarle monstruosidad...

comentario 4 el uso que se hace de esa función (CuentaPalabras) es dudoso y te explico porqué, recurre a la función 'isAlphaNumeric', para determinar ciertos casos, esto es algo relativo, es decir si exponemos un criterio para definir palabras distinto que estar separado blanco lo podremos utilizar perfectamente pero ya no podremos darle el carácter 'universal' de contar palabras, sino dado que es un caso relativo , relativizarlo así el nombre debería ser cambiado a por ejemplo 'ContarMisPalabras' lo cual ya hace referencia a un modo exclusivo y particular de realizar la cuenta. Y esto sin siquiera entrar a evaluar lo que sea que haga dicha función 'isAlphaNumeric'. Realmente una función de contar palabras podría ser tan simple como:

Código: Visual Basic
  1.  
  2. public function Contar_Palabras(texto as string) as long
  3.     dim s() as string, n as long
  4.  
  5.     if len(texto)=0 then
  6.            Contar_Palabras=0
  7.    else
  8.          if instr(texto," ")<>0 then
  9.              s=split(texto)
  10.             ' este bucle es necesario porque split corta por 1 espacio, es decir después de encontrar un espacio el siguiente carácter lo interpreta como una cadena
  11.              for k=0 to  ubound(s )          
  12.                   if s(k)<>"" then n=n +1
  13.              next
  14.              Contar_Palabras=  n
  15.         else
  16.              Contar_Palabras=1
  17.         end if
  18.     end if
  19. end function
  20.  
  21.  

Desde luego esto de contar palabras sigue siendo relativo, me explico esto es aplicable desde el punto de vista de la programación, pero para otros propósitos la lista debe volver a filtrarse, por ejemplo un retorno de carro (enter) puede aparecer unido al final de la apalabra anterior y la primera palabra de la siguiente línea sio no se dejó espacio al final de la misma. También, interpretamos una coma o un punto como una palabra ?, y los signos =,<,(, etc... y si una palabra está unida a operadores? por ejemplo: 'Velocidad=e/t' daría un valor diferente de 'Velocidad =e/t' y diferente de 'Velocidad = e / t', por eso para casos reales, contar plabaras es siempre una rutina complaja y que debe llevar aparejado un método a usar como parámetros donde en dicho/s parámetro/s se especifican las condiciones de lo que es una plabara y lo que no. En dicho caso el código presentado anteriormente presenta la 1ª fase, una vez determinado que el texto tiene más de una palabras, la matriz obtenida debe filtrarse sucesivamente por otra/s rutina/s específicas, lo ideal es que no haya que pasar la matriz para cada caso si no que una misma función analice varios casos relativos a un mismo tema en el mismo bucle... pero en general la rutina que presentas no debe inferirse como lo que su nombre indica, por las razones explicadas.


comentario 5 La función isAlphaNumeric (cada uno debe acomodarlo a como le valga) puede simplicarse mucho más, tanto como reducirlo todo a sólo 2 casos, pués sólo existen 2 casos, TRUE-FALSE, usando el mismo código te lo resumo:
Código: Visual Basic
  1.  
  2. Private Function isAlphaNumeric(anyChar) As Integer
  3.     Select Case Asc(anyChar)
  4.         Case 48 - 57,  65 - 90, 97-122, 193, 225, 201, 233, 205, 237, 211, 243, 218, 250, 220, 252 , 209, 241  
  5.             isAlphaNumeric = True
  6.        case else
  7.             isAlphaNumeric=false
  8.    end select
  9.  end function  
  10.  
  11.  

te ahorras montón de líneas inútiles y queda más claro, al hacer varios case, a primera vista parece que en cada uno hará una cosa distinta, y eso confunde.

comentario 6 estas funciones:
Cita de: "ferhn"
Public Property Get TodoMayus() As String ...   End Property
Public Property Get TodoMinus() As String ... End Property
Son inútiles por redundantes, como ya se dijo antes una función que resuleve un caso no debe trasvestirse, para hacer lo mismo pero ralentizándolo...


comentario 7  Esto creo que debo llevarlo a un laboratorio a analizar.... yo aún no he sido capaz de encontrarle sentido.
Citar
Public Property Get Normal() As String
    Normal = DNormal
End Property
 
Public Property Let Normal(ByVal vNewValue As String)
    DNormal = vNewValue
End Property

comentario 8
Cita de: "ferhn"

Public Property Get PalabraExtraida(Text1 As TextBox, Numero As Integer)
Te complicas en exceso, para eso existe la función INSTR . Con instr vas comprobando donde empiza y terminan las palabras... ya que leer carácter a carácter es bastante lento, conviene delegar en una función más potente o recurrir a la API, para textos de pocas palabras puede valerte pero si por ejemplo tratas de buscar una texto en un dado número de ficheros la búsqueda sería muy lenta.

comentario 9 como ya dije anteriormente trasvestir una función es perder tiempo y tratar de convertirlo en una propiedad una aberración.
Cita de: "ferhn"

Public Property Get TextReverso() As Variant
TextoReves = StrReverse(cTexto)
    TextReverso = TextoReves
End Property

en cuanto a las fechas,  :wub:  sin comentarios...

Así que por favor en cuanto puedas corrige todo el texto o retíralo,  :hitcomp:  ya que no es precisamente un ejemplo sino de mala programación. La frase:
Cita de: "ferhn"
   Aca les dejo algo interesante para hacer casi de todo con texto
francamente resulta desacertada aparte de queen cuanto a completitud no representa nada.
 
Espero que no te lo tomes a mal sino como una orientación de que no se debe hacer   :beer: