Sviluppare funzionalita su Microsoft Office con VBA Variabile pubblica che si azzera "da sola"

Login Registrati
Stai vedendo 15 articoli - dal 1 a 15 (di 15 totali)
  • Autore
    Articoli
  • #33139 Score: 0 | Risposta

    ABRAMO48
    Partecipante
      1 pt

      Buongiorno,

      capisco l'assurdità del titolo, ma, apparentemente sembra quello che mi succede. Allora:

      In un progetto, definisco una variabile intera pubblica:

      Public ZAZ As Integer

      Successivamente all'apertura di una cartella la imposto su un valore (il nr delle righe articoli presenti, ma non ha importanza):

      Set AA = Workbooks("LOGISTA_ARTICOLI.xls").Worksheets("ARTICOLI")
          ZAZ = AA.Range("A8")

      Dove in A8 è presente il nr delle righe articoli.

      bene, la variabile è correttamente impostata, diciamo al valore di 500, ma ad un certo punto, nell'esecuzione di una sub scopro che la variabile è "azzerata"!

      Allora, domanda: a parte la più che ovvia obiezione che da qualche parte c'è un'istruzione che la azzera (ma non c'è!), che l'istruzione di cui sopra: ZAZ = AA.Range("A8") viene riseguita e AA.Range("A8") è uguale a "zero" (ma non è così!), a parte queste ovviassimo obiezioni, ci può essere un altro motivo (che so ... variabile dichiarata in un modulo, sub in un altro modulo, ma è pubblica!) nel VBA che azzera la variabile?

      Capisco la stupidità della domanda, ma apparentemente è quello che sembra succedere, ed è un fenomeno che avevo già osservato in un altro caso, di una variabile pubblica impostata all'inizio da, 0 a 1, per dire programma aperto, e poi di ritrovarmela a zero nel corso delle elaborazioni ...

      ???

      Grazie, anticipatamente, per la vostra attenzione,

      Abramo

      #33140 Score: 0 | Risposta

      Marius44
      Moderatore
        58 pts

        Ciao

        Così come l'hai postata dici bene che sembra un'assurdità.

        Prima di esprimere un azzardato giudizio sarebbe il caso di vedere il resto del codice. In qualche punto ci DEVE essere qualcosa che azzera la variabile.

        Se è possibile prova ad eseguire il codice passo-passo (per intenderci con F8) e vedi se ti vien fuori l'errore.

        Ciao,

        Mario 

        #33141 Score: 0 | Risposta

        Oscar
        Partecipante
          45 pts

          Potresti provare anche a bloccare la cella  A8 dopo che hai impostato la variabile , a questo punto se c'è qualcosa che la cancella lo vedi subito 

          #33143 Score: 0 | Risposta

          ABRAMO48
          Partecipante
            1 pt

            Il fenomeno è questo:

            Cliccando un tasto (una forma associata ad una macro) viene eseguita la macro seguente:

            Sub M_SALVA_CAR()
            '
                Set MM = Workbooks("LOGISTA_MACRO.xls").Worksheets("MACRO")
                Set AA = Workbooks("LOGISTA_ARTICOLI.xls").Worksheets("ARTICOLI")
                MsgBox "1 " & ZAZ
                Call X_MSG_ini("", "SALVA CARICO MATRIX", 29)
            
            
            ....

            Viene visualizzato il messaggio 1 0 (valore di ZAZ)

            La Call X_MSG_ini è la seguente:

            Sub X_MSG_ini(ByVal MSGP As String, ByVal MSGQ As String, Optional ByVal RIGT As Integer)
            '
                Set MM = Workbooks("LOGISTA_MACRO.xls").Worksheets("MACRO")
                
                MM.Activate
                Application.ScreenUpdating = True
                MM.Range("A14").Select
            
            If RIGT <> 0 Then
            If RIGT = MM.Range("G15") Then
            If MM.Range("G14") <> 0 _
            Or MM.Range("E14") <> 0 Then
                RIGS = -1
                Call X_XTIME
            End If
            End If
            End If
                    MsgBox "2 " & ZAZ
                Call X_MSG_okk("CONFERMA Esecuzione", MSGQ, 1)
            ....

            viene visualizzato il messaggio 2 0 (Valoredi ZAZ)

            La Call X_MSG_okk è la seguente:

            Sub X_MSG_okk(ByVal MSGC As String, ByVal MSGD As String, ByVal RIGX As Integer)
            '
               Set MM = Workbooks("LOGISTA_MACRO.xls").Worksheets("MACRO")
                
            'If MM.Range("K14") <> MM.Range("L14") Then
            '    MsgBox ("Date Progressivo INCOERENTI !!!")
            '    End
            'End If
                MsgBox "3 " & ZAZ
            If ZAZ <> MM.Range("G38") + 10 Then
                MM.Range("G19") = ZAZ
                MsgBox "(ZAZ) CONTROLLO RIGHE ARTICOLI ERRATO (" & ZAZ & ")"
                Call E_APRI_ARTICOLI_Z
                MsgBox "6 " & ZAZ
                End
            End If
            
            .....

            Viene visualizzato il messaggio 3 0 (Valore di ZAZ)

            Poiché MM.Range("G38") è uguale a 500

            Viene visualizzato il messaggio di errore (ZAZ) CONTROLLO RIGHE ARTICOLI ERRATO (0)

            La Call E_APRI_ARTICOLI_Z è la seguente:

            Sub E_APRI_ARTICOLI_Z()
                Application.Calculation = xlCalculationManual
                MsgBox "4 " & ZAZ
                ZAZ = AA.Range("A8")
                ZBZ = AA.Range("A9")
                ZCZ = AA.Range("A4")
                MM.Range("G19") = ZAZ - 10
                Application.Calculate
                MsgBox "5 " & ZAZ
            End Sub

            Viene visualizzato il messaggio 4 0 (valore di ZAZ)

            poi il messaggio 5 510 (valore di ZAZ)

            poi il messaggio 6 510 (valore di ZAZ)

            E la procedura termina con End

            Dunque, a questo punto ZAZ è uguale a 510

            Bene, riparto con l'esecuzione di M_SALVA_CAR e si ricomincia da capo:

            Viene visualizzato il messaggio 1 0 (valore di ZAZ)

            ecc. ecc.

            Cosa diavolo AZZERA ZAZ ...

            Continuo l'indagine, ma per ora:   ?????

             

             

            #33144 Score: 0 | Risposta

            ABRAMO48
            Partecipante
              1 pt

              Ma no! Ho stupidamente capito! quando termina una procedura VBA ogni variabile torna a ZERO se non viene reimpostata:

              dopo la end la procedura termina e, quando si riparte, ZAZ riparte da ZERO: deve essere reimpostata da AA.Range("A8")

              ...

              mah!

              grazie, rispondere a Voi mi ha fatto arrivare alla soluzione ...

               

               

              #33145 Score: 0 | Risposta

              Raffaele53
              Partecipante
                24 pts

                Non vedo la macro Call X_XTIME
                Non vedo Public ZAZ As Integer 'in un Modulo, meglio se long

                Non è vero (con End Sub), la variabile rimane attiva. Qui sotto avvia con F8 Sub M_SALVA_CAR sino alla fine. Dopo premi Sub A()

                Public ZAZ As Integer
                Sub a()
                MsgBox ZAZ
                End Sub
                Sub M_SALVA_CAR()
                    MsgBox "1 " & ZAZ
                    Call X_MSG_ini("", "SALVA CARICO MATRIX", 29)
                    MsgBox "macro in fase di termine"
                End Sub
                Sub X_MSG_ini(ByVal MSGP As String, ByVal MSGQ As String, Optional ByVal RIGT As Integer)
                        MsgBox "2 " & ZAZ
                        Call X_MSG_okk("CONFERMA Esecuzione", MSGQ, 1)
                End Sub
                Sub X_MSG_okk(ByVal MSGC As String, ByVal MSGD As String, ByVal RIGX As Integer)
                    MsgBox "3 " & ZAZ
                    Call E_APRI_ARTICOLI_Z
                    MsgBox "6 " & ZAZ
                End Sub
                Sub E_APRI_ARTICOLI_Z()
                    MsgBox "4 " & ZAZ
                    ZAZ = 500 'Range("A8")
                    MsgBox "5 " & ZAZ
                End Sub
                
                
                #33146 Score: 0 | Risposta

                rollis13
                Partecipante
                  8 pts

                  Ho cercato di simulare il tuo problema ma non ci sono riuscito; qui funziona tutto a dovere.

                  Dato che hai fatto solo un estratto, non hai indicato se stai utilizzando la funzione Option Explicit in testa al modulo delle macro, non hai esattamente indicato in quale posizione hai inserito la dichiarazione della variabile ZAZ (se è nello steso modulo dove hai le macro o altrove, e dove), mi sorge spontaneo un dubbio: per quello che ho potuto verificare la variabile ZAZ in questa situazione, se impostata correttamente, si può azzerare solo al riavvio del file.

                  #33147 Score: 1 | Risposta

                  patel
                  Moderatore
                    51 pts

                    Raffaele53 ha scritto:

                    Non è vero (con End Sub), la variabile rimane attiva

                    Ma lui ha usato End, non End Sub, forse potrebbe risolvere con Exit Sub

                    #33148 Score: 0 | Risposta

                    ABRAMO48
                    Partecipante
                      1 pt

                      Allora, è tutto chiaro, la causa è proprio l'uscita dal VBA e il rientro in EXCEL, o meglio, come Patel ha ben specificato (e io non lo sapevo) se si esce con End le variabili sono tutte azzerate, altrimenti NO (confermo, ho fatto una prova). E questo mi spiega perché il fenomeno era altalenante, a volte la variabile me la ritrovavo impostata e a volte la variabile me la trovavo a ZERO: dipendeva da come uscivo dalla cascata delle sub che eseguivo.

                      Normalmente si esce dalla sub iniziale alla fine con end sub, e allora le variabili rimangono impostate, ma in alcune condizioni, quando si vuole interrompere l'intera esecuzione delle sub in cascata, occorre per forza uscire con end (o no?) e allora ecco che mi trovavo con le variabili AZZERATE.

                      E' evidente, almeno per me, che la necessità di uscire con END è sempre possibile e dunque occorre sempre di principio reimpostare tutte le variabili ad ogni lancio di un'esecuzione. Vediamo il mio caso personale:

                      Ho un'anagrafica di articoli di magazzino per la quale ho previsto 500 righe di articoli, ma prima erano 300, poi 400, ...

                      Dunque mi capitava di dover allungare le righe e questo mi costringeva a modificare tutte le istruzioni, tipo 

                      AA.Range("AU11:AU510") = AA.Range("AQ11:AQ510").Value

                      o anche i sort:

                      AA.Rows("11:510").Sort Key1:=AA.Range("CF11"), Order1:=xlDescending, _
                                             Key2:=AA.Range("FA11"), Order2:=xlDescending

                      Allora ho risolto di impostare una variabile ZAZ all'apertura della cartella Articoli con il massimo numero di riga disponibile, 510 in questo momento, partendo dalla riga 11 (510 - 10 = 500), e modificare tutte le istruzioni con il valore 510 impostato, per esempio:

                      AA.Range("AU11:AU" & ZAZ) = AA.Range("AQ11:AQ" & ZAZ).Value

                      e così via ...

                      Quando aprivo la cartella Articoli impostavo la variabile ZAZ, ma ... pensavo rimanesse impostata "per sempre", invece no, quando uscivo con END mi si azzerava, altrimenti NO, e, non sapendolo, non capivo la logica e vi ho interpellato, e ragionando con voi ho capito.

                      Ho risolto che, poiché tutte le procedure lanciate passano da una sub di conferma del lancio, una volta confermata l'esecuzione, viene eseguita, ogni volta, l'impostazione della variabile (prendendolo dal RIF.RIGA(510) impostato in A8 in Articoli). 

                      E' tutto, grazie per avermi chiarito le idee.

                      P.S. Sicuramente avrete delle critiche sul mio modo di procedere, critiche che sicuramente attenderò con impazienza per migliorare le mie conoscenze del VBA.

                      Grazie, grazie.

                      Abramo

                      #33149 Score: 0 | Risposta

                      rollis13
                      Partecipante
                        8 pts

                        ABRAMO48 ha scritto:

                        quando si vuole interrompere l'intera esecuzione delle sub in cascata, occorre per forza uscire con end (o no?)

                        Se usi Exit Sub, sapendo dove rientra la macro potresti sempre attivare una flag boolean prima dell'Exit Sub da sfruttare nella macro mittente ed uscire in modo 'pulito' da li.

                        #33150 Score: 0 | Risposta

                        ABRAMO48
                        Partecipante
                          1 pt

                          Capisco, è vero, ma dovrebbe essere gestito in ogni sub, che lancia una sub, che lancia una sub, ... e poi, forse è possibile se impostato fin dall'inizio della progettazione, ma ora in un progetto con non meno di 200 sub ... 

                          Una domanda però: come è possibile, in VBA, assegnare ad una variabile il valore presente in una cella:

                          ZAZ = RANGE("A8").Value

                           è possibile compiere l'operazione contraria?

                          Cioè in EXCEL assegnare ad una cella il valore di una variabile VBA, tipo:

                          in EXCEL, nella cella A8 inserire = Funzione???(ZAZ)

                          Credo di no, però ...

                           

                          #33151 Score: 0 | Risposta

                          rollis13
                          Partecipante
                            8 pts

                            Ma nel progetto quanti "End" ci sono che che possono interferire quando ZAZ è valorizzata ?

                             

                            ABRAMO48 ha scritto:

                             è possibile compiere l'operazione contraria?

                             Scusa ma forse non ho capito:

                            RANGE("A8") = ZAZ

                            #33152 Score: 0 | Risposta

                            ABRAMO48
                            Partecipante
                              1 pt

                              Ogni End interferisce e sono tantissime, tutti i test di controllo di correttezza di avvio delle procedure terminano con End.

                              Poi:

                              RANGE("A8") = ZAZ

                              è un istruzione in VBA e se ZAZ contiene 500 in A8 finisce 500.

                              Bene, ma se esco con End, ZAZ va a ZERO e in A8 rimane 500.

                              Se invece ci fosse, in A8, un'ipotetica funzione del tipo =FUNZ.IPOTETICA(ZAZ) allora dopo la End ci sarebbe ZERO in A8.

                              Ma sicuramente non c'è.

                              Grazie!

                              #33153 Score: 0 | Risposta

                              Raffaele53
                              Partecipante
                                24 pts

                                @patel OK per End

                                Questo codice mi risulta "strambo". Tra tutti i test di contollo non si potrebbe usare un semplice ZAZ=ultima riga?

                                Se potesse servire...
                                Risposta = MsgBox(prompt:="Desideri uscire?", Buttons:=vbYesNo)
                                If Risposta = vbYes Then
                                ZAZ = ???
                                A8 = ???
                                Exit Sub
                                Else
                                ZAZ = ???
                                A8 = ???
                                End
                                End If

                                #33154 Score: 0 | Risposta

                                ABRAMO48
                                Partecipante
                                  1 pt

                                  ZAZ=ultima riga

                                  No, in coda alle righe articoli ci sono altre righe di controllo, "ultima riga" mi darebbe l'ultima di queste e quindi poi dovrei, da questa all'ultima risalire all'ultima riga destinata agli articoli (= Ultima riga - Nr righe di controllo).

                                  Ma in seguito potrei anche modificare in più o in meno queste righe di controllo e quindi poi intervenire sul Nr righe di controllo.

                                  Invece in A8 ho inserito =RIF.RIGA(510) ultima riga articoli attuale. Se inserisco p.e., dopo la riga 490 10 righe articoli, la riga 510 diventa la riga 560 e il valore di A8 "segue" automaticamente l'inserimento diventando =RIF.RIGA(560) e in ZAZ  entra automaticamente il nuovo valore della Cella A8: 560 appunto, senza alcuna correzione da parte mia.

                                   

                                Login Registrati
                                Stai vedendo 15 articoli - dal 1 a 15 (di 15 totali)
                                Rispondi a: Variabile pubblica che si azzera "da sola"
                                Gli allegati sono permessi solo ad utenti REGISTRATI
                                Le tue informazioni: