Spanish Texto en etiquetas elegidas por software - Objetos con índice?

ngr888

Member
Hola a todos.
Necesito poner texto en etiquetas sin conocer su nombre previamete.
Me explico, quiero poner un texto determinado por software, en una etiqueta cuyo nombre también sea determinado en el programa.
Algo así como:
teniendo un vector con cadenas: t(0) = "a", t(1) = "b", etc.
poner el texto de t(5) en la etiqueta lblN3; t(m) en lblNx...
Tengo el siguiente código que resuelve el problema, aunque con un mal funcionamiento según lo escriba de una u otra forma; y pensando que no es el mejor modo de hacerlo.
B4X:
Sub Globals
  'These global variables will be redeclared each time
  Private btnFin As Button
  Private btnOtra As Button
  Private lbl1 As Label
  Private lbl2 As Label
  Private lbl3 As Label
  Private lbl4 As Label
  Private lbl5 As Label
  Private lbl6 As Label
  Private Lista As List    'Una lista con las etiquetas anteriores
  
  Dim Salida(6) As Int    ' Números prueba para mostrar en las etiquetas
  Dim i As Int
End Sub

Sub Activity_Create(FirstTime As Boolean)
  Activity.LoadLayout("Layout")
  Lista.Initialize
  Iniciar            ' Crear la lista
End Sub

Private Sub btnOtra_Click
  Dim et As Label    ' Etiqueta temporal  

' generar valores de prueba
  For i = 0 To 5
    Salida(i) = 100 + i
  Next
 
' Leer las etiquetas por orden de lugar,
'   cuyo nombre no responde aningún tipo de índice
  For i = 0 To 5
    et = Lista.Get(i)
    et.Text = Salida(i)  
  Next
End Sub

Private Sub btnFin_Click
  Activity.Finish
End Sub

'  ++++++++++++++++++++++++
Sub Iniciar
  'Lista.AddAll(Array As Label(lbl4, lbl3, lbl5, lbl2, lbl1, lbl6))

  Lista.Add(lbl4)
  Lista.Add(lbl3)
  Lista.Add(lbl5)
  Lista.Add(lbl2)
  Lista.Add(lbl1)
  Lista.Add(lbl6)
End Sub

Evidentemente, cambiando el orden de los elementos de la lista, los valores que se les pasen serán diferentes.

Ello obliga a crear tantas listas como distribuciones necesite presentar, y luego elegir una mediante un SELECT nn. (Engorroso.)

El problema momentáneo es que si en la rutina "Iniciar", activo la primera línea quitando el apóstrofo: List.AddAll
y deshabilito las últimas: List.Add
el programa no funciona; y no entiendo por qué.

Otra cuestión es si no hay forma de simular algo parecido a usar "objetos" con índice.
Algo así como:
B4X:
Dim Etiquetas as List
Etiquetas.Initialize
Etiquetas.AddAll(Array As Label(lbl1, lbl2, etc.))
Dim et(n) As Label 'n coincidirá con el No de elementos de Etiquetas
...
For i = 0 to n-1
  et(i) = Etiquetas.Get(i)
  et(i).text = "xxx"
Next

¿Alguna idea?

Gracias por vuestro tiempo.
 

roerGarcia

Active Member
Licensed User
Longtime User
Y ... ¿con que intencion es eso?
Los objetos se pueden crear y manipular en codigo.
 

astronald

Active Member
Licensed User
Longtime User
Usar Mapas,
Código:
Dim mLista as Map
mLista.initialize
mLista.put(1,lbl1)
mLista.put(2,lbl2)


Dim etiqueta as label = mLista.get(2)

No se si es lo que quiere pero es muy funcional para ciertos casos.
 

klaus

Expert
Licensed User
Longtime User
You can also use an Array of Labels:
B4X:
    Private lbl1, lbl2, lbl3, lbl4, lbl5, lbl6 As Label
    Private et(6) As Label
And:
B4X:
et = Array As Label(lbl1, lbl2, lbl3, lbl4, lbl5, lbl6)
And:
B4X:
    For i = 0 To et.Length - 1
        et(i).Text = "New text " & i
    Next
 

ngr888

Member
Y ... ¿con que intencion es eso?

Usar Mapas,
No se si es lo que quiere pero es muy funcional para ciertos casos.

Hola. Agradezco las sugerencias.

Para una prueba de media distancia se han registrado 8 corredores, por orden de inscripción: 1, 2, 3, 4, 5, 6, 7 y 8.
Se van a sortear las 8 pistas del estadio del siguiente modo:

1° se des-ordenan los números de pistas (no físicamente claro), quedando por azar así: 5, 2, 8, 3, 1, 4, 6 y 7

2° Ahora se genera un número al azar, obteniéndose, digamos, 3

3° Se asignan las pistas como sigue:
el atleta 3 correrá por la pista 5 ' Ambos valores lo son por azar
4 por la 2
5 por la 8
6 por la 3
7 por la 1
8 por la 4 ' Reiniciamos con 1
1 por la 6 y
2 por la 7

Un lío, ¿no?... Pero es el método que se ha preferido. Los griegos habrían metido 8 bolitas en una olla, y los atletas se abrían situado en la fila para sacar bola por orden de llegada al pie del Olimpo (lo más parecido a Android era Talos jejeje).

Tal vez podría usar una lista, dos listas o un mapa (aunque no lo he hecho nunca), pero creo que al final tendré que poner el resultado del sorteo en etiquetas desconocidas de antemano que, además, es la funcionalidad y estética que el programa requiere. Con las etiquetas situadas en el layout en posiciones fijas, no necesariamente en fila o columna; por ejemplo, por países.
Incluso, más adelante, será necesario que los tiempos de cada corredor, facilitados por los jueces de la prueba y referidos únicamente al número de dorsal, se lleven al nombre del atleta correspondiente.

En resumen, lo que echo en falta es un modo de tener n etiquetas que se llamen con el mismo nombre y distinto índice e implementar esto en B4X (aunque asigne un valor TAG, tampoco veo el modo, salvo con un montón de código).

Código que no funcionaría en b4a:
B4X:
' No es B4X,   NO FUNCIONARÍA
'z = 3-4-5-6-7-8-1-2  y pista(i) = 5-2-8-3-1-4-6-7

z = 3
for i = 0 to 7
  lblAtleta(z-1).text = pista(i)   'O tiempo: t=m min, s seg, c cent.
  z = z + 1
  if z > 7 then z = 0
next

Por supuesto para cada atleta hay dos etiquetas emparejadas:
lblNombreAtleta1.text = "Nombre 1" y
lblResultadoAtleta1.text = Resultado xxx (Aquí quiro actuar)

¡LAURELES PARA EL VENCEDOR!

Digo... Saludos a todos (es broma, disculpen). Gracias.
 

ngr888

Member
You can also use an Array of Labels:
B4X:
    Private lbl1, lbl2, lbl3, lbl4, lbl5, lbl6 As Label
    Private et(6) As Label
And:
B4X:
et = Array As Label(lbl1, lbl2, lbl3, lbl4, lbl5, lbl6)
The first code clarifies for me the syntax for the declaration, initialization and filling of the list with the labels.

B4X:
    For i = 0 To et.Length - 1
        et(i).Text = "New text " & i
    Next

But the second doesn't solve what I need (I shouldn't have explained myself well).

The problem is that in:

et(i).Text = "New Text" & i

et(i) will not, however, contain a "New text " & i, but another text with an index not known at the time of programming (i1<>i2). Perhaps:

et(0).Text = "New Text " & 71 (or other value)
et(1).Text = "New Text " & 52
...

Also, the order of the list with the labels will vary in each use.

Other time: et = Array As Label(lbl2, lbl4, lbl1, lbl3, lbl6, lbl5)

And so...

Thanks for your time.
 

roerGarcia

Active Member
Licensed User
Longtime User
La ventaja del mapa es que su contenido es campo-valor, de manera que puedes tener

Datos en Mapa:
    Dim ListOfMaps As List
    ListOfMaps.Initialize
    Dim id As Int
    DateTime.DateFormat = "dd/MM/yyyy hh:mm"
    For i = 1 To 20
        id = i
        Dim m As Map
        m.Initialize
        m.Put("IdFolio", id) ' o Atleta!!!
        m.Put("Fecha", DateTime.Date(DateTime.Now))
        m.Put("Hora", DateTime.Time(DateTime.Now))
        m.Put("Nombre", "Roberto Garcia " & i)
        m.Put("Correo", "[email protected]")
        m.Put("Estatus", "Registrado")
        ListOfMaps.Add(m)
    Next

Este codigo produce una lista de 20 mapas con sus valores guardados en ella.
Si quiero sacar el primer elemento mapa de la lista uso:

dim miMapa as Map = ListOfMaps.get(0) ' Cero es el indice del primer elemento

Luego uso miMapa.get("Nombre") para sacar el nombre del atleta del primer registro.

Prueba a usar listas y mapas.
Saludos
 

josejad

Expert
Licensed User
Longtime User
A ver, si me aclaro un poco con lo que quieres, sería algo como:

B4X:
Dim lstAtletas, lstCalles
'Usas el código que tengas para añadir las lista aleatoria de atletas y la de calles con lstAtletas.Add(valorAleatorio)

 Private lbl1, lbl2, lbl3, lbl4, lbl5, lbl6 As Label
 Private et(6) As Label
et = Array As Label(lbl1, lbl2, lbl3, lbl4, lbl5, lbl6)

    For i = 0 To et.Length - 1 'Mismo número de etiquetas que de objetos en las listas
        et(i).Text = "Atleta: " & lstAtletas(i) & " Pista: " & lstCalles(i)
    Next
 

ngr888

Member
La ventaja del mapa es que su contenido es campo-valor, de manera que puedes tener

Datos en Mapa:
    Dim ListOfMaps As List
    ListOfMaps.Initialize
    Dim id As Int
    DateTime.DateFormat = "dd/MM/yyyy hh:mm"
    For i = 1 To 20
        id = i '...
    Next

Prueba a usar listas y mapas.
La cuestión es que, en mi caso, 'id' no coincide con 'i' del For.
Y puede que ni siquiera sea secuencial, es un valor desconocido.

Probaré el uso de mapas, pero no doy abasto.
También probaré un tipo definido (type) con dos campos: valor, etiqueta. Pero creo que estaré en el mismo caso.
Gracias.
 

ngr888

Member
B4X:
Dim lstAtletas, lstCalles
'Usas el código que tengas para añadir las lista aleatoria de atletas y la de calles con lstAtletas.Add(valorAleatorio)

 Private lbl1, lbl2, lbl3, lbl4, lbl5, lbl6 As Label
 Private et(6) As Label
et = Array As Label(lbl1, lbl2, lbl3, lbl4, lbl5, lbl6)

    For i = 0 To et.Length - 1 'Mismo número de etiquetas que de objetos en las listas
        et(i).Text = "Atleta: " & lstAtletas(i) & " Pista: " & lstCalles(i)
    Next
Hola. Puede que el código que indica funcione, lo probaré.
De momento estoy preparando un programita mucho más elemental que mis necesidades finales, pero que me oriente un poco, pues cada vez me pierdo más. Estoy muy verde con B4X.
Lo exportaré como ZIP y lo colgaré.
De momento todo parece que está correcto (más o menos) porque al compilar, tanto en modo debug como deliver, no se muestra ningún error o aviso.
Pero cuando queda instalado en el terminal, no funciona; y no doy con la causa. De hecho el móvil se bloquea y tengo que reiniciarlo.

Volveré a probar un poco y si no va, lo pondré con error incluido.

Gracias.
 

Attachments

  • ET_Listas_00.zip
    9.7 KB · Views: 84

angel_

Well-Known Member
Licensed User
Longtime User
Prueba así:

B4X:
Sub RellenarEtiquetas
    Dim lista1 As List = Array(lbl3, lbl4, lbl5, lbl1, lbl2)
    
    For i = 0 To 4
        Dim et As Label = lista1.Get(i)
        et.Text = i + 1                ' De momento texto = 'i + 1' para rastrear...
        'et.Text = Rnd(100, 200)   -    O los valores que convengan
    Next
End Sub
 

ngr888

Member
B4X:
Sub RellenarEtiquetas
    Dim lista1 As List = Array(lbl3, lbl4, lbl5, lbl1, lbl2)
    
    For i = 0 To 4
        Dim et As Label = lista1.Get(i)
        et.Text = i + 1                ' De momento texto = 'i + 1' para rastrear...
        'et.Text = Rnd(100, 200)   -    O los valores que convengan
    Next
End Sub

Hola, ya veo la sintaxis para escribirlo adecuadamente, salvo un detalle que me desconcierta
en B4X: declarar "Dim et As Label" dentro del bucle For (tantas declaraciones como iteraciones) y que he visto en más sitios. ¿Puede escribirse una solavez fuera del bucle? ¿O son necesidades de la POO?

B4X:
 Sub RellenarEtiquetas
    Dim lista1 As List = Array(lbl3, lbl4, lbl5, lbl1, lbl2)
    Dim et As Label
    For i = 0 To 4
        et = lista1.Get(i)
        et.Text = i + 1
    Next
End Sub

Gracias por la ayuda.
 

roerGarcia

Active Member
Licensed User
Longtime User
El usar el dim dentro del bucle no es problema.
Simplemente "crea" el objeto cada vez que lo va a usar.
Si eres mas "purista", puedes definirlo una sola vez fuera del bucle o ciclo, tampoco es problema.

Dices:
La cuestión es que, en mi caso, 'id' no coincide con 'i' del For.
Y puede que ni siquiera sea secuencial, es un valor desconocido.


Ese valor desconocido puedes guardarlo en el siguiente elemento de la lista de mapas, luego lo puedes accesar secuencialmente o guardar tus indices aleatoreos en una lista (o vector, arreglo unidimensional) desde donde los puedas referir o usar.

Saludos
 

angel_

Well-Known Member
Licensed User
Longtime User
Hola, ya veo la sintaxis para escribirlo adecuadamente, salvo un detalle que me desconcierta
en B4X: declarar "Dim et As Label" dentro del bucle For (tantas declaraciones como iteraciones) y que he visto en más sitios. ¿Puede escribirse una solavez fuera del bucle? ¿O son necesidades de la POO?
Lo hago para evitar problemas declarando la variable por referencia y no por valor, échale un vistazo al libro (página 12):

 

ngr888

Member
Hola.
Sí, ya había leído eso en el texto original. Me supone un problema que abordaré cuando se me presente.
Vengo de escribir programas que admiten el paso a subrutinas y a funciones eligiendo "ByVal" o "ByRef". En B4X parece que para usar tipos no-primitivos por valor, habrá que enviarlos mediante una copia a una variable tipo primitivo ¿no? De otro modo cambiará el valor original.
Gracias.
 

angel_

Well-Known Member
Licensed User
Longtime User
Así lo entiendo yo, es acostumbrarse y con relación al rendimiento no he notado diferencia.
 

ngr888

Member
[RESUELTO]
Hola a todos.
¡Por fin!... Me ha costado Dios y ayuda.
Más de dos meses de intentos fallidos o códigos mostruosos.

Estoy "traduciendo" un programa de VisualBasic (actualmente 1080 líneas de código perfectamente probado y funcional) a B4A.

Sólo una sentencia (1) me ha tenido atascado:

lblPalabra(ET(i)).Caption = Grupo(G(i)).sNombre

Evidentemente .Caption equivale a .Text.
ET(i) y G(i) son vectores de tipo Int cuyos valores los proporciona la "lógica" del programa.
ET(i) hace referencia a una determinada etiqueta que, por conveniencia, puede ser una de entre un grupo que tienen el mismo nombre compartido y diferenciadas por un índice.
Grupo(i).sNombre es un campo sting de tipo definido por el usuario (Type).

Varias personas habéis hecho aportes de diferente valor. Pero finalmente encontré una salida que me resuelve la situación, de forma razonable, en el manual. Probablemente vosotros encontraréis otras mejores.

Utilicé uno de los escasísimos ejemplos (una pena) del manual: Rapid Android App Developmen Using BASIC, Ed. 15 for B4A 11.20. Pag. 346.

Activity -> RemoveViewAt(Index As Int)

B4X:
Dim vw as View
For i = 0 to Activity.NumberOfViews - 1
  vw = Activity.GetView(i)
    If vw.tag = "btnNew" Then
    Activity.RemoveViewAt(i)
  End If
Next

En tiempo de diseño situé las etiquetas implicadas como las primeras Views y por el orden en que me interesaba. De tal modo que ahora podía referirme a ellas pos su índice de creación.

B4X:
Dim lbl0  As Label   'Usada como título y con texto fijo.
Dim lbl1, lbl2, lbl3  ', ... lbl12 As Label
'
Dim lb As Label
for i = 1 to 12
  lb = Activity.GetView(ET(i))
  lb.Text = Grupo(G(i)).sNombre
  lb.TextColor = Colors.RGB(90, 30, 10)  'U otras cosas
Next
¡Me funcionó! No obstante en VBasic es tremendamente más sencillo y funcional. Empleable para comandos diversos. Muy util.

Agradezco infinitamente las ayudas que me habeís prestado. Por mi parte, doy por resuelto este hilo.

Saludos.
 
Top