Como hacer que un procedimiento público realice cambios en un informe

- Tengo un informe que, a modo de ejemplo, vamos a llamar "suma".
- Al abrir ese informe se tienen que realizar cambios en dos etiquetas (lbl_1 y lbl_2)
- Para dar un valor a esas etiquetas tengo un procedimiento público dentro de un módulo:

Public Sub usr()
        u1 = Int((9) * Rnd)
        u2 = Int((9 - u1) * Rnd)
        lbl_u1.Caption = u1
        lbl_u2.Caption = u2
End Sub

Mi problema es que, al ejecutarse, se para en la primera etiqueta (lbl_u1) y me dice que se requiere un objeto y no sé qué tengo que hacer.

Hay un problema añadido: a ese procedimiento se le puede llamar (call usr) desde distintos informes.

3 Respuestas

Respuesta
1

Desde Colombia, prueba incluyendo dos textos invisibles como invisibles asigna a esos textos el valor de las variables U1 y U2, luego asignarle a los valores de los Labels el valor de los textos.

Te agradezco la respuesta, pero no te entiendo.

Creo que la respuestas de los otros dos compañeros puede ser una respuesta más adecuada al problema que tengo. De todas formas, te agradezco el querer echarme una mano. Gracias.

De nada, que pena por cuestión de tiempo no haberle podido colaborar más.

Respuesta
2

A tu procedimiento público le falta indicarle dónde están las etiquetas, en tu caso, si es un informe llamado "suma", tendría que ser así:

Public Sub usr()
        u1 = Int((9) * Rnd)
        u2 = Int((9 - u1) * Rnd)
        Reports("suma").lbl_u1.Caption = u1
        Reports!suma.lbl_u2.Caption = u2
End Sub

Verás que he usado dos notaciones distintas para incluir el nombre del informe, para que conozcas varias formas de hacerlo.

Si fuera un formulario, sería: Forms("suma").lbl_u1.Caption=u1

Un saludo.


Acabo de ver tu última línea y amplío mi respuesta:

Tendrás que pasarle como argumento al procedimiento el nombre del informe, para poder reutilizarlo en distintos informes, con lo que tu código quedaría así (de una de las varias formas que se podría resolver):

Public Sub usr(elInforme As String)
        u1 = Int((9) * Rnd)
        u2 = Int((9 - u1) * Rnd)
        Reports(elInforme).lbl_u1.Caption = u1
        Reports(elInforme).lbl_u2.Caption = u2
End Sub

Y cuando lo llames, tendrás que hacer:

call usr("suma")

call usr("otroInforme")

...

He hecho lo que me has dicho pero me sale el siguiente error: "el nombre del informe "Modelo_s2d" está mal escrito o hace referencia a un informe que no está abierto o no existe.

Por si sirve de ayuda, hay un informe principal que llamaré "informe1" y luego 9 subinformes con el nombre "Modelo_s2d". El subinforme "Modelo_s2d" genera sumas automáticas siendo cada suma diferente a las otras.

En el subinforme "Modelo_s2d" está el código:

Call dsr("Modelo_s2d")

...que llama a los procedimientos que me has señalado y que se encuentran en un módulo llamado variables,  quedando de esta forma:

Public Sub dsr(elInforme As String)

     d1 = Int((10 - 1) * Rnd + 1)
     d2 = Int((10 - d1) * Rnd + 1)

     If d1 + d2 > 9 Then
     If d1 > d2 Then
     d1 = d1 - 1
     Else
     d2 = d2 - 1
     End If
     End If

     Reports(elInforme).lbl_d1.Caption = d1
     Reports(elInforme).lbl_d2.Caption = d2
End Sub

El error aparece en la linea

Call dsr("Modelo_s2d")

Gracias de nuevo

Los pasos que yo te indiqué eran para hacerlo en un informe, no en un subinforme (algo que desconocía), así que es lógico que no te funcione.

A un subinforme se le hace referencia como a cualquier otro control de un informe, es decir, primero has de indicar el informe, luego el subinforme y por último el control, es decir, algo así:

Reports. NombreInforme. NombreSubInforme. Report.nombreEtiqueta...

En tu caso se podría hacer, adaptando lo que tienes, así:

Public Sub usr(elInforme As Report)
Randomize
u1 = Int((9) * Rnd)
u2 = Int((9 - u1) * Rnd)
elInforme.lbl_u1.Caption = u1
elInforme.lbl_u2.Caption = u2
End Sub

y luego, en el evento "al cargar" del formulario principal, llamas al procedimiento público pasándole los subinformes, por ejemplo:

Private Sub Report_Load()
usr Me.Modelo_s2d.Report
usr Me.Modelo_s2d2.Report
End Sub

Como una imagen vale más que mil palabras, te dejo un mini-ejemplo con el código funcionando: http://www.filebig.net/files/ajn6bkPKXc 

Sigue sin funcionar. He hecho lo siguiente:

1. Pruebo el subinforme "Modelo_s2D" ejecutándolo en vista previa. En teoría debería funcionar. Este subinforme tiene el código siguiente:

Call dsr("Modelo_S2D") 'decenas sin rebasar
Call usr("Modelo_S2D") 'unidades sin rebasar

2. Al ejecutarlo me sale el error "Calificador no válido" en la siguiente linea del procedimiento que está en un módulo: 

Public Sub dsr(elInforme As String)
        Randomize
        d1 = Int((10 - 1) * Rnd + 1)
        d2 = Int((10 - d1) * Rnd + 1)
        If d1 + d2 > 9 Then
            If d1 > d2 Then
                d1 = d1 - 1
            Else
                d2 = d2 - 1
            End If
        End If
        elInforme.lbl_d1.Caption = d1 'AQUÍ APARECE EL ERROR "CALIFICATIVO NO VÁLIDO"
        elInforme.lbl_d2.Caption = d2
End Sub

El informe principal realmente lo único que hace es contender 9 repeticiones del subinforme "Modelo_S2D". Es para que aparezcan 9 sumas diferentes en la página.

En el informe he puesto el código siguiente que no sé muy bien para qué vale, pero me fío de ti. Pero no funciona:

Private Sub Report_Load()
usr Me.Modelo_s2d.Report
dsr Me.Modelo_s2d.Report
End Sub

Si en el código del procedimiento público que hay en el módulo escribo lo siguiente:

Reports(elInforme).lbl_d1.Caption = d1

Me funciona bien al ejecutar únicamente el informe "modelo_s2d". Pero cuando ese informe lo meto repetido 9 veces dentro de un informe principal ya no funciona

Fíjate bien en los códigos de mi segunda respuesta, pues la declaración del procedimiento cambia. Fíjate también en que tal como te lo describo en dicha respuesta es como está en el ejemplo, y funciona... Y no es lo que estás haciendo ahora con tu código...

Lo primero, muchas gracias por el tiempo que me estás dedicando. He revisado el código y es verdad lo que dices. No obstante, lo que he visto en el ejemplo que me has mandado es que para hacer nueve sumas en una hoja tendría que hacer 9 subinformes con diferente nombre. Lo digo porque he probado en tu base de datos a poner dentro del informe, el subinforme "modelo_s2d" dos veces, y sólo calcula los números en el primero de ellos, pero no en el segundo.

Te mando, muy simplificado, la base de datos por si no me explico bien del todo.

https://1drv.ms/u/s!Aq9-cAUzTMqcjuEVM67tIIGfV2FpqQ 

Ahí te lo dejo, para que lo termines de completar tú: http://www.filebig.net/files/bmL6Qx7DRD 

Fíjate bien en que los subinformes tienen un nombre para el objeto (suma, secundario270...) y otro para el informe que hace de subinforme (Modelo_S2D), y es a los primeros a los que tienes que hacer referencia...

Respuesta
1

Yo no condicionaría la función a un nombre específico de una etiqueta o reporte, sabiendo que son 2 etiquetas, más bien llamaría una función en donde pasaría 1 parámetro (1 ó 2) y la llamaría en el evento Al abrir del reporte. Esta es la función:

Public Function lnLabel(Optional intLabel As Integer) As Integer
 Dim u1 As Integer
 u1 = Int((9) * Rnd)
 If CLng(intLabel) = 0 Then
   intLabel = 1
 End If
 If intLabel = 1 Then
       lnLabel = u1
 Else
        lnLabel = Int((9 - u1) * Rnd)
 End If
End Function

Ahora en el evento Al abrir de cualquier reporte o en la sección donde vayan las etiquetas:

Private Sub Report_Open(Cancel As Integer)

  Me.lbl_u1.Caption = lnLabel(1)
  Me.lbl_u2.Caption = lnLabel(2)

End Sub

Igualmente sirve para cualquier formulario y es más rápido que hacer referencia a un objeto, en este caso Reports.

Estoy probando también con tu sugerencia, además de la de Sveinbjom. En tu caso me encuentro con el problema de que no me hace los cálculos aleatorios. Tengo en el subinforme el siguiente código:

lbl_d1.Caption = dsr(1)
lbl_d2.Caption = dsr(2)

y el código de la función en el módulo variables (en ese mismo módulo he definido d1 y d2 como variables públicas:

Public Function dsr(Optional intLabel As Integer) As Integer
     If intLabel = 1 Then
     d1 = Int((10 - 1) * Rnd + 1)
     Else
     d2 = Int((10 - d1) * Rnd + 1)
     End If

End Function

Pero al llamar a la función de la forma que he dicho al principio, devuelve siempre el valor "0".

¿No entiendo para que define d1 y d2 como públicas? Probé el código con un informe y no desde un subinforme pero debe trabajar igual. El error está en que ud en la función no retorna el valor porque debe cambiar d1 y d2 por dsr.

esta noche lo pruebo y le comento

Ya funciona. Muchas gracias.

Excelente

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas