Autore Topic: Come Interrompere l'esecuzione di una Sub  (Letto 1394 volte)

Offline kicco

  • Senatore Gambero
  • ******
  • Post: 1.728
  • So dove andare, seguitemi, ci perderemo insieme!
    • Mostra profilo
Come Interrompere l'esecuzione di una Sub
« il: 11 Agosto 2020, 13:38:01 »
Ho la necessità di interrompere l'esecuzione di una Subroutine esternamente alla Sub stessa.
Nel mio caso: dal Form_close devo interrompere una Sub prima di uscire dal programma.
Prima che vuott mi cazzi!  :P
la domanda specifiche è: esiste un comando diretto che permetta questo?
STOP EVENT si può usare solo all'interno della sub  (ovviamente).
Altri non ne ho trovati!
 :ciao:
Chi ha paura muore ogni giorno, chi non ha paura muore una volta sola. (Paolo Borsellino)

Offline cogier

  • Gambero
  • **
  • Post: 57
    • Mostra profilo
Re:Come Interrompere l'esecuzione di una Sub
« Risposta #1 il: 11 Agosto 2020, 15:09:59 »
Questo aiuterà?

Codice: [Seleziona]
bStop As Boolean

Public Sub Form_Open()

  Me.Show
  Wait 0.25
  Start

End

Public Sub Start()

  Dim iInt As Integer

  Do
    Inc iInt
    Wait 0.5
    Print iInt
    If bStop = True Then Return
  Loop

End

Public Sub Form_Close()

  bStop = True

End

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.723
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Come Interrompere l'esecuzione di una Sub
« Risposta #2 il: 11 Agosto 2020, 15:57:00 »
Nel mio caso: dal Form_close devo interrompere una Sub prima di uscire dal programma.
Puoi qui incollare quella sub-routine da interrompere ?
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline kicco

  • Senatore Gambero
  • ******
  • Post: 1.728
  • So dove andare, seguitemi, ci perderemo insieme!
    • Mostra profilo
Re:Come Interrompere l'esecuzione di una Sub
« Risposta #3 il: 11 Agosto 2020, 18:32:43 »
Questo aiuterà?

Codice: [Seleziona]
bStop As Boolean

Public Sub Form_Open()

  Me.Show
  Wait 0.25
  Start

End

Public Sub Start()

  Dim iInt As Integer

  Do
    Inc iInt
    Wait 0.5
    Print iInt
    If bStop = True Then Return
  Loop

End

Public Sub Form_Close()

  bStop = True

End
Grazie Cogier, anch'io avevo pensato ad una soluzione analoga.
Speravo esistesse un comando specifico.
 :-*
Chi ha paura muore ogni giorno, chi non ha paura muore una volta sola. (Paolo Borsellino)

Offline kicco

  • Senatore Gambero
  • ******
  • Post: 1.728
  • So dove andare, seguitemi, ci perderemo insieme!
    • Mostra profilo
Re:Come Interrompere l'esecuzione di una Sub
« Risposta #4 il: 11 Agosto 2020, 18:36:54 »
Nel mio caso: dal Form_close devo interrompere una Sub prima di uscire dal programma.
Puoi qui incollare quella sub-routine da interrompere ?
Urka!
Devo vedere se riesco a ripulirla perchè è un po' complessa!
Chi ha paura muore ogni giorno, chi non ha paura muore una volta sola. (Paolo Borsellino)

Offline kicco

  • Senatore Gambero
  • ******
  • Post: 1.728
  • So dove andare, seguitemi, ci perderemo insieme!
    • Mostra profilo
Re:Come Interrompere l'esecuzione di una Sub
« Risposta #5 il: 11 Agosto 2020, 23:47:08 »
Rispondo al quesito iniziale: Esiste un comando specifico che permetta di interrompere l'esecuzione di un ciclo al di fuori del ciclo che gestisce l'evento stesso?
Risposta:NO!

La mio domanda nasceva dal fatto che chiudendo un programma che al suo interno prevede un ciclo che può durare anche 40s, si chiudeva tutto, la seriale, tutti i Form, ma il programma rimaneva "appeso" perchè il ciclo di 40s era ancora attivo.

Ho risolto ponendo dopo il Me.close ( Nel Form_open ho attivato Application.MainWindow = Me) l'istruzione Quit che interrompe l'Event Loop e quindi anche la subroutine incriminata permettendo la chiusura pulita.
Chi ha paura muore ogni giorno, chi non ha paura muore una volta sola. (Paolo Borsellino)

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.723
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Come Interrompere l'esecuzione di una Sub
« Risposta #6 il: 12 Agosto 2020, 00:31:43 »
Se non inserisci qui un semplice codice che ripropone in modo essenziale e breve le routine e le righe di comando fondamentali, non si potrà capire perfettamente la questione da te posta, né cercare una soluzione.
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.244
  • Tonno verde
    • Mostra profilo
Re:Come Interrompere l'esecuzione di una Sub
« Risposta #7 il: 12 Agosto 2020, 10:07:17 »
Rispondo al quesito iniziale: Esiste un comando specifico che permetta di interrompere l'esecuzione di un ciclo al di fuori del ciclo che gestisce l'evento stesso?
Risposta:NO!

La mio domanda nasceva dal fatto che chiudendo un programma che al suo interno prevede un ciclo che può durare anche 40s, si chiudeva tutto, la seriale, tutti i Form, ma il programma rimaneva "appeso" perchè il ciclo di 40s era ancora attivo.

Ho risolto ponendo dopo il Me.close ( Nel Form_open ho attivato Application.MainWindow = Me) l'istruzione Quit che interrompe l'Event Loop e quindi anche la subroutine incriminata permettendo la chiusura pulita.

Beh, vista la tua soluzione avresti dovuto rispondere si è Quit.

Quit interrompe sempre un programma, ma quasi mai è una buona soluzione per i programmi grafici, perché lascia in giro parecchie scorie.
Mi sembra strano che la tua console non migugni...

 :ciao:
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.723
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Come Interrompere l'esecuzione di una Sub
« Risposta #8 il: 12 Agosto 2020, 10:27:38 »
Quit interrompe sempre un programma, ma quasi mai è una buona soluzione per i programmi grafici, perché lascia in giro parecchie scorie.
Infatti la guida ufficiale consiglia l'uso dell'istruzione "Quit" per i programmi a riga di comando.
Un esempio semplice può essere quello di interrompere l'Evento "Application_Read()", consentendo al programma di chiudersi:
Codice: [Seleziona]
Private i As Integer
Private bo As Boolean


Public Sub Main()

  Repeat
    Inc i
    Print i
    Wait 0.3
  Until bo == True
 
  Quit    ' Fa sì che il programma sia terminato
 
End


' Cliccando sul tasto "Invio" della tastiera, si scatena questo Evento:
Public Sub Application_Read()
 
  bo = True
 
End

Poiché estremamente radicale, a mio avviso Quit va usato solo come "extrema ratio" per chiudere un programma altrimenti non terminabile.
« Ultima modifica: 12 Agosto 2020, 10:29:22 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.723
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Come Interrompere l'esecuzione di una Sub
« Risposta #9 il: 12 Agosto 2020, 11:00:03 »
Ripeto comunque la necessità che kicco mostri il codice (o una riproduzione essenziale delle routine e dei comandi fondamentali del codice originario), giacché - diversamente - alla sua domanda sulla eventuale esistenza di un "comando unico", se posta con finalità didattica, la soluzione di cogier può essere soddisfacente.
Sappiamo, però, che i cicli posseggono soluzioni proprie, "condizionali", previste appunto per soddisfare la richiesta di uscita; e di norma andrebbero usate quelle.

Infatti in un programma grafico l'uscita dal ciclo, effettuata mediante le previste modalità "condizionali" e causata dalla chiusura arbitraria della finestra principale del programma, non pregiudica in via generale il termine del programma medesimo, rendendo così inutile ed eccessivo l'uso dell'istruzione "Quit":
Codice: [Seleziona]
Private b As Byte


Public Sub Form_Open()
 
  Me.Show
 
  Ciclo()
 
End


Private Procedure Ciclo()
 
  Repeat
    Inc b
    Print b
    Wait 0.3
  Until b == 100
 
End


Public Sub Form_Close()   ' Chiudendo il Form, si scatena questo Evento
 
  b = 100
 
End

In vero, l'uso di "Return", già proposto da cogier, risulta necessario, qualora dopo il ciclo vi siano altre righe di comando che in caso di uscita arbitraria dal ciclo, ottenuta con la chiusura forzata del Form, si intenda non far processare (quindi da saltare).
Ciò conferma che l'uso dell'istruzione "Return" determina, non solo - nel caso di specie - l'uscita dal ciclo, ma anche l'abbandono immediato e definitivo  della sub-routine, ove essa è posta.

A tal riguardo si provino i seguenti codici.
Senza "Return" nel ciclo:
Codice: [Seleziona]
Private b As Byte


Public Sub Form_Open()
 
  Me.Show
 
  Ciclo()
 
End


Private Procedure Ciclo()
 
  Repeat
    Inc b
    Print b
    Wait 0.3
  Until b == 100
 
  Print "Riga di comando successiva al ciclo"
 
End


Public Sub Form_Close()
 
  b = 100
 
End

Con "Return" nel ciclo per l'uscita immediata e definitiva dalla sub-routine:
Codice: [Seleziona]
Private b As Byte


Public Sub Form_Open()
 
  Me.Show
 
  Ciclo()
 
End


Private Procedure Ciclo()
 
  Repeat
    Inc b
    Print b
    If b > 100 Then Return
    Wait 0.3
  Until b == 100
 
  Print "Riga di comando successiva al ciclo"
 
End


Public Sub Form_Close()
 
  b = 200
 
End
« Ultima modifica: 12 Agosto 2020, 18:02:31 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline kicco

  • Senatore Gambero
  • ******
  • Post: 1.728
  • So dove andare, seguitemi, ci perderemo insieme!
    • Mostra profilo
Re:Come Interrompere l'esecuzione di una Sub
« Risposta #10 il: 12 Agosto 2020, 17:40:49 »
Se non inserisci qui un semplice codice che ripropone in modo essenziale e breve le routine e le righe di comando fondamentali, non si potrà capire perfettamente la questione da te posta, né cercare una soluzione.
Eccolo:
Codice: [Seleziona]
Private fFlag As Boolean

Public Sub BtFalse_Click()

  fFlag = False

End

Public Sub BtTrue_Click()

  fFlag = True

End

Public Sub BtStart_Click()

  Dim i As Integer
  Dim ia As Integer

  For i = 0 To 200
    Print "Ciclo Principale " & i

    For ia = 1 To 30
      If fFlag = True Then
        Break
        fFlag = False
      Endif
      Wait 1
    Next

    If fFlag = False Then
      Print "Scaduti i 30s"
    Endif
    fFlag = False

  Next

  fFlag = False

End
Premetto che non ho ancora provato i codici che hai proposto...
Chi ha paura muore ogni giorno, chi non ha paura muore una volta sola. (Paolo Borsellino)

Offline kicco

  • Senatore Gambero
  • ******
  • Post: 1.728
  • So dove andare, seguitemi, ci perderemo insieme!
    • Mostra profilo
Re:Come Interrompere l'esecuzione di una Sub
« Risposta #11 il: 12 Agosto 2020, 17:46:46 »
Rispondo al quesito iniziale: Esiste un comando specifico che permetta di interrompere l'esecuzione di un ciclo al di fuori del ciclo che gestisce l'evento stesso?
Risposta:NO!

La mio domanda nasceva dal fatto che chiudendo un programma che al suo interno prevede un ciclo che può durare anche 40s, si chiudeva tutto, la seriale, tutti i Form, ma il programma rimaneva "appeso" perchè il ciclo di 40s era ancora attivo.

Ho risolto ponendo dopo il Me.close ( Nel Form_open ho attivato Application.MainWindow = Me) l'istruzione Quit che interrompe l'Event Loop e quindi anche la subroutine incriminata permettendo la chiusura pulita.

Beh, vista la tua soluzione avresti dovuto rispondere si è Quit.

Quit interrompe sempre un programma, ma quasi mai è una buona soluzione per i programmi grafici, perché lascia in giro parecchie scorie.
Mi sembra strano che la tua console non migugni...

 :ciao:
Lo so che Quit non va usato per uscire dai programmi grafici.
Ho usato infatti Me.close dopo aver messo Application.MainWindow = Me nel Form_open.
Solo dopo ho usato Quit
Magari potrei mettere un wait tra i due per attendere che tutti i Form siano chiusi correttamente.
Codice: [Seleziona]
Public Sub Form_Close()
     ....
     .... 
      Me.close
      Quit

End
Chi ha paura muore ogni giorno, chi non ha paura muore una volta sola. (Paolo Borsellino)

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.723
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Come Interrompere l'esecuzione di una Sub
« Risposta #12 il: 12 Agosto 2020, 17:51:12 »
Premetto che non ho ancora provato i codici che hai proposto...

Hanno l'intenzione di essere meramente didattici.
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline kicco

  • Senatore Gambero
  • ******
  • Post: 1.728
  • So dove andare, seguitemi, ci perderemo insieme!
    • Mostra profilo
Re:Come Interrompere l'esecuzione di una Sub
« Risposta #13 il: 12 Agosto 2020, 20:20:19 »
Allego un progetto che mima la situazione che vi descrivevo.
Col tasto START si avvia il programma.
Con TRUE e FALSE si può intervenire sui cicli.
Con Esci ovviamente si esce,ma vedrete che nell'IDE il programma non si chiude.
Spero che questo chiarisca!
 :ciao:
Chi ha paura muore ogni giorno, chi non ha paura muore una volta sola. (Paolo Borsellino)

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.723
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Come Interrompere l'esecuzione di una Sub
« Risposta #14 il: 12 Agosto 2020, 20:28:27 »
Dunque, l'intento di kicco è quello di far terminare il programma, quando viene chiusa arbitrariamente la finestra principale.
Per fare ciò, deve assicurarsi che il controllo del processo esca dai due cicli, previsti dalla routine "BtStart_Click()".
 
Riprendo il codice esemplificativo di kicco, tentando di risolvere il problema con l'uso delle modalità "condizionali", previste dagli specifici cicli, evitando quindi l'uso della ghigliottina "Quit".

Codice: [Seleziona]
Private fFlag As Boolean
Private i As Integer


Public Sub BtTrue_Click()

  fFlag = True

End

Public Sub BtStart_Click()
 
  Dim ia As Integer
 
  Repeat
    Print "Ciclo Principale " & i
 
    ia = 1

    While (ia < 30) And (fFlag == False)
      Wait 1
      Inc ia
    Wend

    If fFlag = False Then Print "Scaduti i 30s\n"
    fFlag = False
    Inc i
  Until i > 200
 
  Print "Uscito dal ciclo principale"

End

Public Sub BtExit_Click()

  Me.Close

End

Public Sub Form_Close()

  fFlag = True
  i = 255

End
« Ultima modifica: 12 Agosto 2020, 20:35:01 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »