Foros del Web » Programación para mayores de 30 ;) » Programación General » Visual Basic clásico »

Un Reto: Mensaje de texto rotativo

Estas en el tema de Un Reto: Mensaje de texto rotativo en el foro de Visual Basic clásico en Foros del Web. Hola amigos, Necesito un pequeño programa para generar mensajes "rotativos". El programa deberá tomar un texto, analizarlo y generar todas las combinaciones posibles. Un sencillo ...
  #1 (permalink)  
Antiguo 02/12/2009, 21:55
hugui
Invitado
 
Mensajes: n/a
Puntos:
Un Reto: Mensaje de texto rotativo

Hola amigos,

Necesito un pequeño programa para generar mensajes "rotativos".
El programa deberá tomar un texto, analizarlo y generar todas las combinaciones posibles.

Un sencillo ejemplo, sobre el formato del texto:

El {gran|inmenso} árbol, es muy {viejo|antiguo}.
A partir del anterior ejemplo, estas son todas las combinaciones:
A. El gran árbol, es muy viejo.
B. El inmenso árbol, es muy viejo.
C. El gran árbol, es muy antiguo.
D. El inmenso árbol, es muy antiguo.

Si notan, en este sencillo ejemplo, los datos variantes son solo palabras; separadas por "|" y encerradas entre "{}".

Lo que necesito es algo así, pero que soporte parrafos; y dentro de los párrafos, debe soportar palabras; como el ejemplo anterior.


Por ejemplo, a partir de este mensaje...

Cita:
Estimado amigo,

{Muy buenos días|Hola como andas|Hola como andas}, espero que {sigas|estes} bien.
Te escribo para {invitarte|que vengas|que no faltes} a mi fiesta de fin de año, que se realizará el proximo domingo, en casa.
{No es necesario que traigas nada, simplemente ven y trae a la {familia|flia|family}|Ven y trae a la familia}.

{Los esperamos|Te envio un abrazo|Un saludo}

...estas son solo dos combinaciones posibles...



Ejemplo 1

Cita:
Estimado amigo,

Muy buenos días, espero que sigas bien.
Te escribo para que vengas a mi fiesta de fin de año, que se realizará el proximo domingo, en casa.
No es necesario que traigas nada, simplemente ven y trae a la familia.

Los esperamos
Ejemplo 2
Cita:
Estimad amigo,

Hola como andas, espero que estes bien.
Te escribo para invitarte a mi fiesta de fin de año, que se realizará el proximo domingo, en casa.
Ven y trae a la familia.

Te envio un abrazo


Entonces, eso es lo que necesito, con exactamente esta forma de identificar los "pedazos de textos variantes".


Espero se entienda
¿Quién lo puede hacer?


Muchas gracias,
Hugui

PD: Si algunos de los capos que andan por este foro, me puede ayudar personalmente, estoy dispuesto a pagar...
  #2 (permalink)  
Antiguo 03/12/2009, 04:31
Avatar de pkj
pkj
 
Fecha de Ingreso: julio-2006
Ubicación: Órbita sincrónica
Mensajes: 899
Antigüedad: 17 años, 9 meses
Puntos: 29
Respuesta: Un Reto: Mensaje de texto rotativo

Si me pagas te lo pinto y doy cera

A ver si esto te sirve esto:

He puesto un listbox oculto (List1) para no complicarme. Asegurate de agregarlo.

Código :
Ver original
  1. Function AutoTexto(ByVal TextoBase As String) As String
  2.   Dim PosicionInicio As Long
  3.   Dim PosicionFin As Long
  4.   List1.Clear
  5. Repite:
  6.   PosicionInicio = InStr(PosicionInicio + 1, TextoBase, "{")
  7.   If PosicionInicio <> 0 Then
  8.     PosicionFin = InStr(PosicionInicio + 1, TextoBase, "}")
  9.     If PosicionFin > PosicionInicio Then
  10.       List1.AddItem Mid$(TextoBase, PosicionInicio + 1, PosicionFin - PosicionInicio - 1)
  11.       TextoBase = Left$(TextoBase, PosicionInicio - 1) & "TextoVariable" & List1.ListCount & Mid$(TextoBase, PosicionFin + 1)
  12.       PosicionInicio = 0      
  13.       GoTo Repite
  14.     End If
  15.   End If
  16.   Dim Opciones() As String
  17.   Dim Eleccion As String
  18.   Dim F As Long
  19.   Randomize Timer
  20.   For F = 0 To List1.ListCount - 1
  21.     Opciones = Split(List1.List(F), "|")
  22.     Eleccion = Opciones(Rnd * UBound(Opciones))
  23.     TextoBase = Replace(TextoBase, "TextoVariable" & F + 1, Eleccion)
  24.   Next F
  25.   AutoTexto = TextoBase
  26. End Function


Para usarlo en un command button pongo el texto origen en un textbox (Text1) y el resultado lo muestro en un msgbox:

Lo ejecuto varias veces para notar los cambios.

Código :
Ver original
  1. Private Sub Command1_Click()
  2.   MsgBox AutoTexto(Text1.Text) & vbCrLf & AutoTexto(Text1.Text) & vbCrLf & AutoTexto(Text1.Text) & vbCrLf & AutoTexto(Text1.Text) & vbCrLf & AutoTexto(Text1.Text)
  3. End Sub

El tema de incluir opciones dentro de opciones no lo he visto hasta que me ha dado problemas en las pruebas. De momento no se permite.

PD: Este es el texto origen que he usado en las pruebas (dentro del Text1):
Código :
Ver original
  1. {Muy buenos días|Hola como andas|Hola como estás}, espero que {sigas|estes} bien.
  2. Te escribo para {invitarte|que vengas|que no faltes} a mi fiesta de fin de año, que se realizará el proximo domingo, en casa.
  3. {No es necesario que traigas nada, simplemente ven y trae a la familia|Ven y trae a la familia}.
  4.  
  5. {Los esperamos|Te envio un abrazo|Un saludo}

Que se dé bien.
__________________
No hay preguntas tontas, solo gente estup..., ¡No!, ¿como era? No hay gente que pregunte a tontos... ¡Nooo!... ¡Vaya cabeza!

Última edición por pkj; 03/12/2009 a las 04:47
  #3 (permalink)  
Antiguo 03/12/2009, 09:45
hugui
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Un Reto: Mensaje de texto rotativo

Hola pkj,

Buenas, estube revisando tu ejemplo, la verdad que me gusta.

Sabía que alguien me hiba a poder ayudar con esto... en definitiva, avisame cuanto me cobras por hacer algo bien bien echo, sin controles adicionales, simplemente una función, bien bien echa... yo pienso que casi lo tenes... pero falta un poquito más...


¿Lo podes hacer para este fin de semana? y ¿Cuánto me cobras por este código?

Cualquier pregunta, avisame...

Un saludo,
Hugui
  #4 (permalink)  
Antiguo 03/12/2009, 10:56
Avatar de pkj
pkj
 
Fecha de Ingreso: julio-2006
Ubicación: Órbita sincrónica
Mensajes: 899
Antigüedad: 17 años, 9 meses
Puntos: 29
Respuesta: Un Reto: Mensaje de texto rotativo

El quitar el ListBox es simple y el código es un regalo.
Si necesitas mejorarlo comentalo. Puede que se me ocurra algo o alguien te lo complete.

Código :
Ver original
  1. Function AutoTexto(ByVal TextoBase As String) As String
  2.   Dim PosicionInicio As Long
  3.   Dim PosicionFin As Long
  4.   Dim Lista() As String
  5.   Dim Contador As Long
  6. Repite:
  7.   PosicionInicio = InStr(PosicionInicio + 1, TextoBase, "{")
  8.   If PosicionInicio <> 0 Then
  9.     PosicionFin = InStr(PosicionInicio + 1, TextoBase, "}")
  10.     If PosicionFin > PosicionInicio Then
  11.       Contador = Contador + 1
  12.       ReDim Preserve Lista(Contador)
  13.       Lista(Contador) = Mid$(TextoBase, PosicionInicio + 1, PosicionFin - PosicionInicio - 1)
  14.       TextoBase = Left$(TextoBase, PosicionInicio - 1) & "TextoVariable" & Contador & Mid$(TextoBase, PosicionFin + 1)
  15.       PosicionInicio = 0
  16.       GoTo Repite
  17.     End If
  18.   End If
  19.   Dim Opciones() As String
  20.   Dim Eleccion As String
  21.   Dim F As Long
  22.   Randomize Timer
  23.   For F = 1 To UBound(Lista)
  24.     Opciones = Split(Lista(F), "|")
  25.     Eleccion = Opciones(Rnd * UBound(Opciones))
  26.     TextoBase = Replace(TextoBase, "TextoVariable" & F, Eleccion)
  27.   Next F
  28.   AutoTexto = TextoBase
  29. End Function

Saludos
__________________
No hay preguntas tontas, solo gente estup..., ¡No!, ¿como era? No hay gente que pregunte a tontos... ¡Nooo!... ¡Vaya cabeza!
  #5 (permalink)  
Antiguo 03/12/2009, 11:30
hugui
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Un Reto: Mensaje de texto rotativo

Estimado pkj,

Hola otra vez, muchas gracias por tu ayuda y por el regalo (Aunque mi intensión es pagar algunos dólares por esto, ya que es complicado para mi)

Más tarde lo voy a ver con tiempo, para saber si con esto es suficiente... quizás sí.


Desde ya, muchas... muchas gracias.

Un saludo,
Hugui
  #6 (permalink)  
Antiguo 03/12/2009, 16:53
Avatar de pkj
pkj
 
Fecha de Ingreso: julio-2006
Ubicación: Órbita sincrónica
Mensajes: 899
Antigüedad: 17 años, 9 meses
Puntos: 29
Respuesta: Un Reto: Mensaje de texto rotativo

Te agradezco tu honradez, pero lo he pasado demasiado bien como para cobrar.

EDITO ESTE MENSAJE PARA EVITAR ACUMULACION DE CÓDIGO SIMILAR Y REEMPLAZO LA FUNCION

El caso es que estaba seguro de que la solución no era tan dificil partiendo de lo que ya había hecho, y al final he acabado haciendo justo lo que pedias para que sea más práctica la función.

Resumen:
Función que devuelve un texto aleatorio a partir de un texto base que contenga una o varias partes opcionales.
Para marcar 2 o más partes como opcionales se introducen entre {} y se separan con |
Una opción puede contener otras partes opcionales y estas partes a otras casi sin límite siempre que se encapsulen correctamente.
Ejemplo:
Código :
Ver original
  1. Dim Texto As String
  2. Dim Resultado As String
  3. Texto = "Ven y trae a {quien {quieras|tu {elijas|desees}}|la familia|los amigos}"
  4. Resultado = AutoTexto(Texto)
  5. MsgBox Resultado

Código :
Ver original
  1. Function AutoTexto(ByVal TextoBase As String) As String
  2.   On Local Error Resume Next
  3.   AutoTexto = TextoBase
  4.   Do
  5.     Dim PosicionInicio As Long
  6.     PosicionInicio = InStr(PosicionInicio + 1, AutoTexto, "{")
  7.     If PosicionInicio <> 0 Then
  8.       Dim PosicionFin As Long
  9.       PosicionFin = InStr(PosicionInicio + 1, AutoTexto, "}")
  10.       If PosicionFin > PosicionInicio Then
  11.         Dim BuscaMas As Long
  12.         BuscaMas = PosicionInicio
  13.         Do
  14.           BuscaMas = InStr(BuscaMas + 1, AutoTexto, "{")
  15.           If BuscaMas > 0 And BuscaMas < PosicionFin Then
  16.             PosicionFin = InStr(PosicionFin + 1, AutoTexto, "}")
  17.             If PosicionFin = 0 Then Exit Do
  18.           Else
  19.             Exit Do
  20.           End If
  21.         Loop
  22.         If PosicionFin = 0 Then Exit Do
  23.         Dim Contador As Long
  24.         Contador = Contador + 1
  25.         Dim Lista() As String
  26.         ReDim Preserve Lista(Contador)
  27.         Lista(Contador) = Mid$(AutoTexto, PosicionInicio + 1, PosicionFin - PosicionInicio - 1)
  28.         AutoTexto = Left$(AutoTexto, PosicionInicio - 1) & "TextoVariable" & Format(Contador, "000000") & Mid$(AutoTexto, PosicionFin + 1)
  29.         PosicionInicio = 0
  30.       Else
  31.         Exit Do
  32.       End If
  33.     Else
  34.       Exit Do
  35.     End If
  36.   Loop
  37.   Dim F As Long
  38.   For F = 1 To Contador
  39.     If InStr(1, Lista(F), "{") <> 0 And InStr(1, Lista(F), "}") <> 0 And InStr(1, Lista(F), "}") > InStr(1, Lista(F), "{") Then
  40.       Lista(F) = AutoTexto(Lista(F))
  41.     End If
  42.     Dim Opciones() As String
  43.     Opciones = Split(Lista(F), "|")
  44.     Randomize Timer
  45.     Dim Eleccion As String
  46.     If Trim$(Replace(Lista(F), "|", "")) <> "" Then
  47.       Do
  48.         Eleccion = Opciones(Rnd * UBound(Opciones))
  49.         If Trim$(Eleccion) <> "" Then Exit Do
  50.       Loop
  51.     Else
  52.       Eleccion = Opciones(Rnd * UBound(Opciones))
  53.     End If
  54.     AutoTexto = Replace(AutoTexto, "TextoVariable" & Format(F, "000000"), Eleccion)
  55.   Next F
  56.   On Local Error GoTo 0
  57. End Function

EDITO ESTE MENSAJE PARA EVITAR ACUMULACION DE CÓDIGO SIMILAR Y REEMPLAZO LA FUNCION

Ha sido divertido.
Como curiosidad te cuento que cuando ya había probado esta nueva versión y estaba a punto de publicarla se me ocurrió ampliar la parte final del texto de prueba y por suerte decidí probarlo en el programa antes de guardar el mensaje, y resulta que fallaba estrepitosamente.
He tardado un buen rato y estaba a punto de perder la paciencia cuando al fin he encontrado el tonto fallo.
De todas formas he pasado un rato muy entretenido, he creado una función que cualquier día me puede servir para algo y espero haber echado una mano que tambien alegra la vida.

Si aparece un nuevo fallo comentadlo.

Saludos.
__________________
No hay preguntas tontas, solo gente estup..., ¡No!, ¿como era? No hay gente que pregunte a tontos... ¡Nooo!... ¡Vaya cabeza!

Última edición por pkj; 04/12/2009 a las 04:47
  #7 (permalink)  
Antiguo 03/12/2009, 19:53
Avatar de pkj
pkj
 
Fecha de Ingreso: julio-2006
Ubicación: Órbita sincrónica
Mensajes: 899
Antigüedad: 17 años, 9 meses
Puntos: 29
Respuesta: Un Reto: Mensaje de texto rotativo

Mejorada la función anterior. He editado el mensaje anterior pero aviso aquí para que se note por si alguien tiene interés.

Saludos

PD: Como soy cabezón le he seguido dando vueltas, y cuando se me ha ocurrido quitar una de las llaves del texto para simular un fallo de encapsulado de opciones, el resultado ha sido un bucle infinito.

De modo que una vez solucionado aviso que vuelvo a editar el mensaje anterior para incluir la comprobación necesaria.

PD2: Muchas pruebas y alguna comprobación añadida por si acaso y esto parece haber quedado muy estable.

PD3: Nueva mejora del código. Edito por última vez (espero).
__________________
No hay preguntas tontas, solo gente estup..., ¡No!, ¿como era? No hay gente que pregunte a tontos... ¡Nooo!... ¡Vaya cabeza!

Última edición por pkj; 04/12/2009 a las 04:46
  #8 (permalink)  
Antiguo 04/12/2009, 05:05
hugui
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Un Reto: Mensaje de texto rotativo

Estimado amigo,

¡Infinitas gracias, por todo lo anterior!



¿Te puedo pedir una ayuda más?

Te comento, estaba pensando en colorear los "{" y "}"... pero por la complejidad que tu le agregaste (eso de los subniveles infinitos) creo que es mejor colorear fragmento por fragmento... distinguiendo cuando un fragmento está dentro de otro... con distintos colores... algo que a mi, me puede llevar toda la semana y quizás el resto del mes... pero ahora que te conozco un poquito, me imagino, a vos te puede salir al instante...

Un ejemplo sería este:

Cita:
Ven y trae a {quien {quieras|tu {elijas|desees}}|la familia|los amigos}
Ya con esto quedaría perfectamente identificado que parte es que parte, con colores distintos...


¡¡Desde ya muchas gracias, de verdad!!

Un saludo,
Hugui

Última edición por hugui; 09/12/2009 a las 21:01 Razón: Colorear segun niveles
  #9 (permalink)  
Antiguo 10/12/2009, 06:49
Avatar de pkj
pkj
 
Fecha de Ingreso: julio-2006
Ubicación: Órbita sincrónica
Mensajes: 899
Antigüedad: 17 años, 9 meses
Puntos: 29
Respuesta: Un Reto: Mensaje de texto rotativo

A ver que te parece esto.
Tiene el problema del parpadeo, sobre todo porque la sub que colorea el texto es bastante lenta, pero el resultado de momento es el buscado.
Me he limitado a 5 colores, pero verás que es facil añadir mas.

RT1 es el RichTextBox

Código :
Ver original
  1. Option Explicit
  2. Dim Colores(5) As ColorConstants
  3.  
  4. Private Sub Form_Load()
  5.   Colores(0) = vbBlack
  6.   Colores(1) = vbBlue
  7.   Colores(2) = vbRed
  8.   Colores(3) = vbGreen
  9.   Colores(4) = vbMagenta
  10.   Colores(5) = vbYellow
  11.   Me.Show
  12. End Sub
  13.  
  14. Private Sub RT1_Change()
  15.   Dim Pos As Long
  16.   With RT1
  17.     .Visible = False
  18.     Pos = .SelStart
  19.     CambiaColores RT1
  20.     .SelStart = Pos
  21.     .Visible = True
  22.     .SetFocus
  23.   End With
  24.  End Sub
  25.  
  26. Sub CambiaColores(RTB As RichTextBox)
  27.   Dim F As Long
  28.   Dim Contador As Long
  29.   With RTB
  30.   For F = 1 To Len(.Text)
  31.     If Mid$(.Text, F, 1) = "{" Then
  32.       Contador = Contador + 1
  33.       If Contador > 5 Then Contador = 5
  34.       .SelStart = F - 1
  35.       .SelLength = 1
  36.       .SelColor = Colores(Contador)
  37.     ElseIf Mid$(.Text, F, 1) = "}" Then
  38.       .SelStart = F - 1
  39.       .SelLength = 1
  40.       .SelColor = Colores(Contador)
  41.       Contador = Contador - 1
  42.       If Contador < 0 Then Contador = 0
  43.     Else
  44.       .SelStart = F - 1
  45.       .SelLength = 1
  46.       .SelColor = Colores(Contador)
  47.     End If
  48.   Next F
  49.   End With
  50. End Sub

Saludos
__________________
No hay preguntas tontas, solo gente estup..., ¡No!, ¿como era? No hay gente que pregunte a tontos... ¡Nooo!... ¡Vaya cabeza!
  #10 (permalink)  
Antiguo 10/12/2009, 07:42
hugui
Invitado
 
Mensajes: n/a
Puntos:
Sonrisa Respuesta: Un Reto: Mensaje de texto rotativo

Hola,

borro este mensaje, porque esta de mÁs...

Un saludo,
hugui

Última edición por hugui; 13/12/2009 a las 19:18
  #11 (permalink)  
Antiguo 12/12/2009, 09:20
Avatar de pkj
pkj
 
Fecha de Ingreso: julio-2006
Ubicación: Órbita sincrónica
Mensajes: 899
Antigüedad: 17 años, 9 meses
Puntos: 29
Respuesta: Un Reto: Mensaje de texto rotativo

Ya he creado una versión de la sub CambiaColores bastante más rápida. A ver si no aparecen bugs.

Código vb:
Ver original
  1. Sub CambiaColores(RTB As RichTextBox)
  2.   Dim Pos As Long
  3.   Dim PosAbre As Long
  4.   Dim PosCierra As Long
  5.   Dim Contador As Long
  6.   With RTB
  7.     Do
  8.       PosAbre = InStr(Pos + 1, RTB.Text, "{")
  9.       PosCierra = InStr(Pos + 1, RTB.Text, "}")
  10.       If PosAbre > 0 And (PosAbre < PosCierra Or PosCierra = 0) Then
  11.         .SelStart = Pos
  12.         .SelLength = PosAbre - Pos - 1
  13.         .SelColor = Colores(Contador)
  14.         If Contador < 5 Then Contador = Contador + 1
  15.         .SelStart = PosAbre - 1
  16.         .SelLength = 1
  17.         .SelColor = Colores(Contador)
  18.         Pos = PosAbre
  19.       ElseIf PosCierra > 0 Then
  20.         .SelStart = Pos
  21.         .SelLength = PosCierra - Pos
  22.         .SelColor = Colores(Contador)
  23.         If Contador > 0 Then Contador = Contador - 1
  24.         Pos = PosCierra
  25.       Else
  26.         .SelStart = Pos
  27.         .SelLength = Len(RTB.Text)
  28.         .SelColor = Colores(Contador)
  29.         Exit Do
  30.       End If
  31.     Loop
  32.   End With
  33. End Sub

A ver si alguien publica un "aleatori-libro" de aventuras

Saludos
__________________
No hay preguntas tontas, solo gente estup..., ¡No!, ¿como era? No hay gente que pregunte a tontos... ¡Nooo!... ¡Vaya cabeza!

Última edición por pkj; 12/12/2009 a las 09:35
  #12 (permalink)  
Antiguo 12/12/2009, 15:51
hugui
Invitado
 
Mensajes: n/a
Puntos:
De acuerdo Respuesta: Un Reto: Mensaje de texto rotativo

Estimado amigo pkj,

Te agradezco tu ayuda, de verdad.
Esto funciona muy bien, si ejecuto esto desde un botón.

Pero ¿Cómo podría hacer para que siga funcionando igual de bien, mientras escribo en el RichTextBox?

Lo puse en el evento Change y se corre el cursor, ó no me deja escribir...

Mi intensión es ir escribiendo normalmente y "programando" una carta, con la ventaja de ver el coloreo en tiempo real... todo un problema, ya lo sé... pero no lo puedo solucionar... igual sigo intentando.

Muchas gracias de verdad, estoy aprendiendo mucho.

Un saludo,
Hugui

PD: GRACIAS
  #13 (permalink)  
Antiguo 12/12/2009, 16:07
Avatar de pkj
pkj
 
Fecha de Ingreso: julio-2006
Ubicación: Órbita sincrónica
Mensajes: 899
Antigüedad: 17 años, 9 meses
Puntos: 29
Respuesta: Un Reto: Mensaje de texto rotativo

Solo tienes que usar el evento change que puse como ejemplo, cambiando RT1 por el nombre de tu RichTextBox:

Private Sub RT1_Change()
Dim Pos As Long
With RT1
.Visible = False
Pos = .SelStart
CambiaColores RT1
.SelStart = Pos
.Visible = True
.SetFocus
End With
End Sub
__________________
No hay preguntas tontas, solo gente estup..., ¡No!, ¿como era? No hay gente que pregunte a tontos... ¡Nooo!... ¡Vaya cabeza!
  #14 (permalink)  
Antiguo 12/12/2009, 21:31
hugui
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Un Reto: Mensaje de texto rotativo

Hola pkj,

Gracias, no me había dado cuenta, se ve que estoy con mi cabeza en otro lado...

Te agradezco nuevamente por tu paciencia... gracias, gracias, gracias.



Hugui
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 12:10.