Jump to content
  • Debido a la crisis sanitaria, hasta el día 31 de marzo, el registro al foro de Ayuda Excel será totalmente gratuito para facilitar el teletrabajo. Todos los registros que se produzcan entre estas fechas tendrán acceso gratuito ilimitado a la comunidad hasta el 30 de abril.

    Regístrate

    Si te surge alguna duda mientras estás trabajando en casa con Excel, ya tienes a quien preguntar.

    Espero que esta medida te sirva de ayuda. Frenar la expansión del coronavirus depende de todos. Sé responsable.

paikerr

PROBLEMA CON UNA VARIABLE

Recommended Posts

Hola a todxs,

 

Tengo el siguiente código de programación:

' Zona de Declaraciones '
Public Hola As Boolean


' Zona de Procedimientos '

Sub PRUEBAS1()
  If Hola = False Then
    MsgBox "Bienvenido/a al foro 'ayudaexcel.com'"
    PRUEBAS2
  Else
    Application.Quit
  End If
End Sub

Sub PRUEBAS2()
  MsgBox "¿Podemos ayudarte?"
  ACTIVAR_VARIABLE
End Sub

Sub ACTIVAR_VARIABLE()
  Hola = True
End Sub

 

Lo que quiero conseguir con el código anterior es lo siguiente:

  1) Si el procedimiento "PRUEBAS1" se ejecuta por primera vez, entonces que realice todo el código contenido en el mismo.

  2) Una vez haya terminado de ejecutar el procedimiento "PRUEBAS1", entonces que pase a realizar el procedimiento "PRUEBAS2" sin necesidad de llamarle manualmente.

  3) Cuando termine de ejecutar "PRUEBAS2", que se active la variable "Hola" con el valor booleano "True" a través del procedimiento "ACTIVAR_VARIABLE".

  4) De modo que si volviera a ejecutar de nuevo el procedimiento "PRUEBAS1", entonces la bifurcación condicional pase directamente a "Else" y aplique el código "Application.Quit".

 

Es decir, la variable "Hola" sólo se activa en modo verdadero cuando se ejecuta el procedimiento "PRUEBAS2" por primera vez.

Y si la variable "Hola" toma el valor "True" y se volviera a ejecutar el procedimiento "PRUEBAS1", entonces que nos expulse/salgamos directamente de la aplicación.

 

¿No sé si me he explicado bien? Igual existe alguna otra opción de hacer lo mismo sin dar tantas vueltas... No sé, pero necesito de vuestra ayuda.

 

Muchas gracias de antemano por vuestro tiempo.

Edited by paikerr

Share this post


Link to post
Share on other sites

Solo te falta una linea:

 

Public Hola As Boolean

Sub PRUEBAS1()
  If Hola = False Then
    MsgBox "Bienvenido/a al foro 'ayudaexcel.com'"
    PRUEBAS2
  Else
    Application.Quit
  End If
End Sub

Sub PRUEBAS2()
  MsgBox "¿Podemos ayudarte?"
  ACTIVAR_VARIABLE
End Sub

Sub ACTIVAR_VARIABLE()
  Hola = True
  Call PRUEBAS1
End Sub

 

Saludos.

Edited by Leopoldo Blancas

Share this post


Link to post
Share on other sites

o

Public Hola As Boolean

Sub PRUEBAS1()
  If Hola = False Then
    MsgBox "Bienvenido/a al foro 'ayudaexcel.com'"
    PRUEBAS2
  Else
    Application.Quit
  End If
End Sub

Sub PRUEBAS2()
  MsgBox "¿Podemos ayudarte?"
  ACTIVAR_VARIABLE

Call PRUEBAS1
End Sub

Sub ACTIVAR_VARIABLE()
  Hola = True
End Sub

Share this post


Link to post
Share on other sites

Muchas gracias, @Leopoldo Blancas.

El problema es que no quiero construir un bucle, sino lo que quiero construir es lo siguiente:

> La primera vez que ejecute el procedimiento "PRUEBAS1", también se ejecute "PRUEBAS2" y se active el valor verdadero en la variable "Hola".

> De modo que se quede almacenado el valor "True" en la variable "Hola", para volverlo a usar de nuevo en otros procedimientos.

> Así si volviera a ejecutar el procedimiento "PRUEBAS1" de manera manual, entonces que se cierre la aplicación "If .../ Else > Application.Quit / End If".

¿No sé si me explico?

 

La idea es básicamente que si "PRUEBAS2" ya se ha ejecutado una primera vez, entonces si volvemos a ejecutar "PRUEBAS1" que se cierre directamente la aplicación.

Share this post


Link to post
Share on other sites
Hace 16 minutos , paikerr dijo:

La idea es básicamente que si "PRUEBAS2" ya se ha ejecutado una primera vez, entonces si volvemos a ejecutar "PRUEBAS1" que se cierre directamente la aplicación.

Igual existe alguna otra forma de realizarlo... Pero se me ha ocurrido hacerlo con una variable lógica.

Share this post


Link to post
Share on other sites

Tu código original eso es lo que hace.

Solo hay 2 condiciones:

1.- Que la Variable Pública se declare en un Módulo

2.- Que no te salga de la aplicación, VBA ya sea por medio de un formulario o Macro. Osea que no te regreses a la hoja de trabajo.

Y si quieres regresar a la hoja de trabajo y hacer cualquier cosa y quieres que se siga conservando el valor de la variable, entonces guarda el valor de la variable en una Celda. Y lo recuperas al iniciar PRUEBAS1.

Saludos.

 

Share this post


Link to post
Share on other sites

Gracias a todxs de nuevo.

 

Efectivamente mi código de prueba funciona a la perfección, pero no consigo dar con el problema.

Sin embargo, dentro de mi código de archivo creo que se debe a que tengo activado un 'Scripting.dictionary', y no me reconoce la declaración de nuevas variables... No sé, pero esto ya va siendo un quebradero de cabeza.

 

¿Os pasó el código de mi archivo?

Share this post


Link to post
Share on other sites
Cita

.... Sin embargo, dentro de mi código de archivo creo que se debe a que tengo activado un 'Scripting.dictionary', y no me reconoce la declaración de nuevas variables...

Pues yo me he tomado un café y se ha puesto a llover...

Anda, sube el archivo.

Share this post


Link to post
Share on other sites
Hace 2 horas, Antoni dijo:

Anda, sube el archivo.

' *** ZONA DE DECLARACIONES **** '
    Public Hola As Boolean


' *** ZONA DE PROCEDIMIENTOS *** '

Sub PRUEBAS1()

    If Hola = False Then
      MsgBox "Bienvenido al foro 'ayudaexcel'"

    ' Aquí tengo introducido mucho más código VBA, pero mostrarlo ahora no es lo que me interesa.
    ' Lo que me preocupa es comprobar por qué no se almacena el valor 'True' en la variable 'Hola'.

      Call PRUEBAS2
    Else
      Application.Quit
    End If

End Sub

Sub PRUEBAS2()

    ' *** DECLARACION DE VARIABLES *** '

    Dim Mat, Vec(1 To 4), Q&, i&, j%, vec_CH, vec_CF, iKey$

    Dim Dic1
    Set Dic1 = CreateObject("Scripting.Dictionary")
    Dim Dic2
    Set Dic2 = CreateObject("Scripting.Dictionary")

Application.ScreenUpdating = False


    ' *** ACTUALIZACION DE DATOS *** '

    With Sheets("Hoja1")
      If .Cells(2, 1) = "" Then GoTo Fin
      Mat = .Range("i2", .Cells(1, 1).End(xlDown)): Q = UBound(Mat)

      For i = 1 To Q
        For j = 6 To 9: Vec(j - 5) = Mat(i, j): Next
        iKey = Mat(i, 1) & Mat(i, 2) & Mat(i, 3) & Mat(i, 4)
        Dic1(iKey) = Vec
        Dic2(iKey) = i
      Next
    End With

    With Sheets("Hoja2")
      On Error Resume Next
        .Outline.ShowLevels RowLevels:=0, ColumnLevels:=3
        .Outline.ShowLevels RowLevels:=0, ColumnLevels:=2
      On Error GoTo 0
      
      With .Range("e5", .[b5].End(xlDown))
        Mat = .Cells: Q = UBound(Mat)
        vec_CH = .Offset(, 6).Resize(, 2)
        vec_CF = .Offset(, 9).Resize(, 2)
      End With
    
      For i = 1 To Q
        iKey = Mat(i, 1) & Mat(i, 2) & Mat(i, 3) & Mat(i, 4)
        If Dic1.Exists(iKey) Then
          vec_CH(i, 1) = Dic1(iKey)(1)
          vec_CH(i, 2) = Dic1(iKey)(2)
          vec_CF(i, 1) = Dic1(iKey)(3)
          vec_CF(i, 2) = Dic1(iKey)(4)
          Dic2(iKey) = 0
        End If
      Next
        
      .[h5:i5].Resize(Q) = vec_CH
      .[k5:L5].Resize(Q) = vec_CF

      With .[j5].Resize(Q)
        .FillDown
        .Offset(1) = .Offset(1).Value
      End With

      With .[m5].Resize(Q)
        .FillDown
        .Offset(1) = .Offset(1).Value
      End With
    End With

    With Sheets("Hoja1")
      .[j2].Resize(Dic2.Count) = Application.Transpose(Dic2.items)
      .[a1].CurrentRegion.Sort .[j1], xlAscending, Header:=xlYes
      Set Mat = .[a1].CurrentRegion.Columns("j"). _
        Find(what:=0, LookIn:=xlValues, LookAt:=xlWhole, SearchDirection:=xlPrevious)
      If Not Mat Is Nothing Then .Range("a2", Mat).Delete xlShiftUp
      .[a1].CurrentRegion.Columns("j").ClearContents
    End With

Fin: Mat = Empty: Dic1 = Empty: Dic2 = Empty: vec_CH = Empty: vec_CF = Empty


    ' *** SALIR DE LA MACRO *** '

    Hola = True
    Beep

End Sub

Este código me lo pasó por aquí @Cacho R.

Ya os digo... He probado con introducir al final del procedimiento las instrucciones "Dic1.RemoveAll" y "Dic2.RemoveAll", y en algunas pruebas si he conseguido que se almacenara el valor "True" dentro de la variable "Hola". Pero aún así, me sigue dando problemas constantemente.

 

El objetivo de esta movida es que "si se ha ejecutado por primera vez el procedimiento PRUEBAS2, entonces que salgamos de la aplicación si volvemos a ejecutar manualmente el procedimiento PRUEBAS1".

 

Perdonadme todos por mi ignorancia... :(

Edited by paikerr

Share this post


Link to post
Share on other sites

Hola @paikerr,

Es que creo que ya se resolvio tu problema, nada mas que tu no lo vez o como dice Haplox, esto es un verdadero jaleo de tu parte y de tu código.

Y como dice @Antoni

Hace 3 horas, Antoni dijo:

Última oportunidad:

Anda, sube el archivo.

Anda, sube el archivo.

Anda, sube el archivo.

Anda, sube el archivo.

Anda, sube el archivo.

 

 

 

Saludos.

Share this post


Link to post
Share on other sites

A tener en cuenta que las variables públicas pierden su valor cuando:

  1. Añades una macro
  2. Defines una nueva variable
  3. Se produce un error en una macro
  4. Cancelas la ejecución de una macro
  5. .......
Edited by Antoni

Share this post


Link to post
Share on other sites

Definitivamente, no tengo ni p... idea de qué es lo que está ocurriendo.

El código del archivo Excel sobre el que estoy aplicando las pruebas, me funciona perfectamente.

Descargar: ACTUALIZAR.xlsm (archivo de pruebas)

 

Sin embargo, cuando exporto ese mismo código desde archivo de pruebas al archivo original sobre el que directamente trabajo, me ocurre algo muy gracioso:

"Si el procedimiento 'PRUEBAS2' se ejecuta a través del condicional 'If / Else', entonces NO se almacena el valor 'True' dentro de la variable 'Hola'.

Pero si el procedimiento 'PRUEBAS2' lo ejecuto de manera manual a través de la ventana de macros, entonces SI se almacena el valor 'True' dentro de la variable 'Hola'."

 

Esto debe ser cosa de brujas, ahora que se aproxima Halloween... :D

Share this post


Link to post
Share on other sites

Hola @paikerr

Tu macro si hace lo que quieres:

Ejecuto PRUEBAS1 y dice : bienvenido al foro ayuda excel

EL VALOR ACTUAL DE LA VARIABLE HOLA ES FALSO

ESTAN CORRECTOS LOS DATOS: -> SI

VUELVES A EJECUTAR PRUEBAS 1 Y TE DICE:

EL VALOR ACTUAL DE LA VARIABLE HOLA ES VERDADERO

Y SE SALE DE LA APLICACIÓN.

ESO ES LO QUE QUIERES NO???

Share this post


Link to post
Share on other sites
Hace 23 horas, Antoni dijo:

A tener en cuenta que las variables públicas pierden su valor cuando:

  1. Añades una macro
  2. Defines una nueva variable
  3. Se produce un error en una macro
  4. Cancelas la ejecución de una macro
  5. ....... 

Gracias @Antoni.

 

Hace 16 horas, Leopoldo Blancas dijo:

ESO ES LO QUE QUIERES NO???

Efectivamente, así es.

 

A ver... Corrijo... Estamos haciendo pruebas con ventanas de alerta... Pero donde he puesto un MsgBox, dentro de mi código de origen van muchas otras instrucciones: Bucles For / Next, Copy / Destination, cambios de formato, etc.

Pero no creo que ninguna de esas instrucciones, afecten a la variable 'Hola'.

 

Llegados a este punto, mi pregunta es: Dado que con la declaración de una variable no consigo el resultado esperado, ¿existe alguna macro para conocer si un procedimiento se ha ejecutado al menos una vez?

De manera que mi código podría ser algo como lo siguiente:

Sub PRUEBAS1()
  If <Código para comprobar si se ha ejecutado el procedimiento PRUEBAS2> = False Then
    MsgBox "Bienvenido/a al foro online ayudaexcel.com"
    PRUEBAS2
  Else
    Application.Quit
  End If
End Sub

Sub PRUEBAS2()
  MsgBox "¿Podemos ayudarte?"
End Sub

 

Muchas gracias de antemano a los dos.

Edited by paikerr

Share this post


Link to post
Share on other sites

Gracias @Leopoldo Blancas por toda tu ayuda.

Y a @Antoni también.

 

Efectivamente no puedo compartir ese archivo en el foro, porque dispone de datos personales de terceros que no puedo mostrar públicamente.

De modo que tengo que ingeniármelas en construir otros archivos parecidos y que tengan esos mismos problemas que presento por aquí en el foro.

 

Al final he conseguido hacer lo mismo, pero por otro camino diferente...

Gracias de todos modos.

 

Saludos.

 

*** TEMA CERRADO ***

Share this post


Link to post
Share on other sites
Hace 7 horas, paikerr dijo:

Al final he conseguido hacer lo mismo, pero por otro camino diferente...

Gracias de todos modos.

Como si fuese atletismo... tu quieres llegar a la meta sin pasar por todo el proceso de preparación (leer a fondo VBA, como lo haria un profesional de su disciplina)

Te aconsejo desde ya, te vas a perder mas, si continuas entre el no saber a fondo como usar VBA

Comienza desde lo mas basico, como cuando comenzamos en la escuela, este ambiente de programación es rico en todo sentido de automatización de tareas, pero si eres iniciador, debes ser consciente de tus pocos conocimientos para emprender proyectos grandes, solo a base de ayudas...

Como tu hemos visto muchos en ese andar

 

Saludos!

Share this post


Link to post
Share on other sites

Gracias por el consejo @Gerson Pineda, aunque tu comentario me deja un poco en fuera de juego... :huh:

 

Mi objetivo en este foro no es abordar "proyectos grandes" (como tú dices), sino más bien dudas concretas que me van surgiendo a medida que voy aprendiendo a programar.

Si tienen fácil solución, copio el código y lo implanto dentro de mis proyectos. O bien, lo dejo guardado como favoritos para volver a reutilizarlo en un futuro.

 

Pero vamos, que ni de lejos he llegado a pensar en desarrollar un proyecto completo a través de este foro... Simplemente, las dudas que me surjan las voy planteando por aquí. Si tienen rápida y fácil solución, bien. Y si no, pues ya pensaré yo en cómo hacerlo de otro modo (a eso me refería con lo de "elegir otro camino", no a otra cosa).

Share this post


Link to post
Share on other sites
Hace 5 horas, paikerr dijo:

Mi objetivo en este foro no es abordar "proyectos grandes" (como tú dices)

Con mi comentario, quise decir que vas  a necesitarlo... a menos que no aspires a dominar este lenguaje como se debe [por igual te lo recomiendo, aprender a fondo]

Tu tema es interesante, pero te sugiero leer sobre lo mismo, con tranquilidad; la clave en principio esta precisamente en las variables que usamos y hasta a veces no son necesarias [según el caso]

 

Saludos 

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.



×
×
  • Create New...

Important Information

Privacy Policy


CTA Templates.png