› Excel e gli applicativi Microsoft Office › Sfida numero 4: MsgBox senza If
-
AutoreArticoli
-
Oggi vi propongo una sfida tecnica, apparentemente banale, il cui spunto deriva da una recente discussione corsa qui in Forum qualche giorno fa.
Si tratta di indirizzare la scelta dell'utente in risposta a una message box, che prevede una domanda a cui si deve rispondere Ok o Annulla, e che comporta l'uscita dalla procedura se l'utente sceglie Annulla.
Sia data la routine seguente, scritta in un modo canonico:Sub self_destruction() Dim answer As Long answer = MsgBox("Vuoi formattare il disco C: ?", vbOKCancel, "Attenzione") If answer = vbCancel Then Exit Sub MsgBox "Boom!" End Sub
La sfida consiste nel riscrivere la stessa procedura, che dia l'identico risultato, senza fare uso di costrutti decisionali (If, IIf, Select Case).
Le proposte verranno accettate solo fra cinque giorni da adesso: quindi potrete pubblicare i vostri post da sabato 30 marzo a partire dalle ore 12. Questa discussione viene chiusa da ora e riaperta al momento giusto.
Eventuali richieste di chiarimento potranno essere fatte in chat o direttamente alla mail della Redazione.
Il vincitore verrà stabilito mediante sondaggio aperto a tutta la comunità: il sondaggio durerà qualche giorno (verrà stabilito al momento della chiusura della sfida). Solo le risposte che arriveranno in questa discussione verranno prese in considerazione.
In caso di parità si terrà conto del criterio cronologico. Ognuno può pubblicare tutte le soluzioni che vuole, ma solo l'ultima postata verrà tenuta in considerazione in caso di parità di voti ottenuti.Il vincitore avrà la soddisfazione di aver partecipato e di aver illustrato qualche tecnica magari nuova o interessante. Riceverà anche una piccola coccarda accanto al proprio nick e avrà l'onore di proporre la sfida successiva!
Quindi pronti? ...via! cominciate a pensarci, ci rivediamo qui a partire da sabato prossimo!
Salve a tutti.
Io non ho trovato di meglio che sfruttare un gestore degli errori, ma sono curiosissimo di vedere cos'altro partorirete 🙂
Ecco alcune varianti`Sub self_destruction_1() On Error GoTo Exit_Sub Debug.Print 1 / CLng(MsgBox("Vuoi formattare il disco C: ?", vbOKCancel + vbQuestion, "Attenzione") <> vbCancel) MsgBox "Boom!" Exit_Sub: On Error GoTo 0 End Sub Sub self_destruction_2() Dim Dumb_Var As Long On Error GoTo Exit_Sub Dumb_Var = Log(Abs(CLng(MsgBox("Vuoi formattare il disco C: ?", vbOKCancel + vbQuestion, "Attenzione") <> vbCancel))) MsgBox "Boom!" Exit_Sub: On Error GoTo 0 End Sub Sub self_destruction_3() On Error GoTo Exit_Sub Sheets(Abs(CLng(MsgBox("Vuoi formattare il disco C: ?", vbOKCancel + vbQuestion, "Attenzione") <> vbCancel))).Select MsgBox "Boom!" Exit_Sub: On Error GoTo 0 End Sub Sub self_destruction_4() On Error GoTo Exit_Sub Debug.Print Cells(Abs(CLng(MsgBox("Vuoi formattare il disco C: ?", vbOKCancel + vbQuestion, "Attenzione") <> vbCancel)), 1).Value MsgBox "Boom!" Exit_Sub: On Error GoTo 0 End Sub`
Discussione riaperta: via alle pubblicazioni!
Scadenza: martedì 2 aprile ore 20, poi via al televoto!
Bravo VF, simpatica sfida.
Visto che il desiderata era di evitare l'uso dei costrutti condizionali (If, Iif e Select) e non di evitare l'uso di MsgBox(), propongo una soluzione molto scarna ma che clona aspetto e comportamento dell'esercizio proposto:
Sub self_destruction() Dim answer As Long answer = MsgBox("Vuoi formattare il disco C: ?", vbOKCancel, "Attenzione") On Error GoTo exit_err answer = 1 / (answer - 2) MsgBox "Boom!" exit_err: End Sub
Una soluzione più smart, con gestione personalizzata anche dell'opzione 'annulla':
Sub self_destructionSmart() Dim answer As Long, sMess As String ', vRis As Variant sMess = "paura eh ...?!" answer = MsgBox("Vuoi formattare il disco C: ?", vbOKCancel, "Attenzione") On Error GoTo exit_err answer = 1 / (answer - 2) 'vRis = ... sMess = "Boom!" exit_err: Err.Description = sMess MsgBox Err.Description End Sub
Per conto di Albatros54 che è impossibilitato a postare in questi giorni, e mi ha gentilmente pregato di farlo, pubblico le sue due proposte:
Albatros #1
Sub self_destruction1() Dim answer As Long answer = MsgBox("Vuoi formattare il disco C: ?", vbOKCancel, "Attenzione") Do Until answer <> 1 MsgBox "Boom!" Exit Do Loop End Sub
Albatros #2
Sub self_destruction4() Dim answer As Long answer = MsgBox("Vuoi formattare il disco C: ?", vbOKCancel, "Attenzione") On answer GoTo 1, 2 1: MsgBox "Boom!" Exit Sub 2: Exit Sub End Sub
Bravo VF, simpatica sfida.
Mi prendo i complimenti di scossa e ne sono onorato
Grazie! l'idea è di divertirsi un po' insieme.
Comunque Zerokelvin ha scritto prima che io postassi il "discorso" di apertura... un vero fulmine di guerra però non conta tanto la velocità quanto l'originalità delle idee, che poi voteremo da martedì.
In ogni caso io pensavo alla soluzione che ha postato Albatros (che ci saluta perchè in questi giorni non può collegarsi), ma già da voi ho visto degli spunti interessanti! Quindi bravi a tutti voi!
le mie 2 soluzioni
'--------- prima ----------- Sub SenzaIF() Dim answer As Integer, risposte risposte = Array("Si", "No") answer = MsgBox("Vuoi formattare il disco C: ?", vbOKCancel, "Attenzione") Application.Run (risposte(answer - 1)) End Sub Sub si() MsgBox "Boom!" End Sub Sub no() End Sub '--------- seconda ----------- Sub Senza_IF() Dim answer As Integer answer = MsgBox("Vuoi formattare il disco C: ?", vbOKCancel, "Attenzione") On answer GoTo si, no si: MsgBox "Boom!" Exit Sub no: End Sub
Tutte le soluzioni con lo stesso messaggio con codici differenti.
Rem Il codice riproduce solo visivamente quanto richiesto nel quiz senza dividere il ciclo Rem On Error Resume Next Sub self_destruction_1() Dim answer As Long answer = MsgBox("Vuoi formattare il disco C: ?", vbOKCancel, "Attenzione") On Error Resume Next MsgBox "Boom!", vbOKOnly, "Microsoft Excel", "c:\Help.chm", answer * 1024 ^ 3 End Sub Rem While Sub self_destruction_2() Dim answer As Long answer = MsgBox("Vuoi formattare il disco C: ?", vbOKCancel, "Attenzione") While answer = 2: Exit Sub: Wend MsgBox "Boom!" End Sub Rem Note: Obfuscation code for Excel VBA Rem While Sub self_destruction_3() prelim MsgBox("Vuoi formattare il disco C: ?", vbOKCancel, "Attenzione") End Sub Sub prelim(silent As Long) While silent = 2: Exit Sub: Wend MsgBox "Boom!" End Sub Rem Do While Sub self_destruction_4() Dim answer As Long answer = MsgBox("Vuoi formattare il disco C: ?", vbOKCancel, "Attenzione") Do While answer = 2: Exit Sub: Loop MsgBox "Boom!" End Sub Rem Do While + Timer Sub self_destruction_5() Dim answer As Long Dim oSHL As Object Set oSHL = CreateObject("WScript.Shell") 'Visualizzo la finestra in primo piano con il timer a 5 secondi, allo scadere del tempo Formatto il disco :) answer = oSHL.PopUp("Vuoi formattare il disco C: ?", 5, "Attenzione", vbOKCancel + 4096) Do While answer = 2: Exit Sub: Loop MsgBox "Boom!" End Sub Rem Loop While Sub self_destruction_6() Dim answer As Long On Error GoTo Annulla Do: answer = MsgBox("Vuoi formattare il disco C: ?", vbOKCancel, "Attenzione", "c:\Help.chm", answer * 1024 ^ 3) Loop While answer = 2 MsgBox "Boom!" Exit Sub Annulla: Exit Sub End Sub Rem Do Until Sub self_destruction_7() Dim answer As Long answer = MsgBox("Vuoi formattare il disco C: ?", vbOKCancel, "Attenzione") Do Until answer = 1: Exit Sub: Loop MsgBox "Boom!" End Sub Rem Do Until + Timer Sub self_destruction_8() Dim answer As Long Dim oSHL As Object Set oSHL = CreateObject("WScript.Shell") 'Visualizzo la finestra con il timer a 5 secondi e chiudo il messaggio senza Formattare il disco :) answer = oSHL.PopUp("Vuoi formattare il disco C: ?", 5, "Attenzione", vbOKCancel) Do Until answer = 1: Exit Sub: Loop MsgBox "Boom!" End Sub Rem Loop Until Sub self_destruction_9() Dim answer As Long On Error GoTo Annulla Do: answer = MsgBox("Vuoi formattare il disco C: ?", vbOKCancel, "Attenzione", "c:\Help.chm", answer * 1024 ^ 3) Loop Until answer = 1 MsgBox "Boom!" Exit Sub Annulla: Exit Sub End Sub Rem For Sub self_destruction_10() Dim answer As Long answer = MsgBox("Vuoi formattare il disco C: ?", vbOKCancel, "Attenzione") For answer = 1 To answer - 1 Exit Sub: Next MsgBox "Boom!" End Sub Rem For Step -1 Sub self_destruction_11() Dim answer As Long For answer = 1 To MsgBox("Vuoi formattare il disco C: ?", vbOKCancel, "Attenzione") Step -1 MsgBox "Boom!" Next End Sub Rem On Error GoTo Sub self_destruction_12() Dim answer As Long answer = MsgBox("Vuoi formattare il disco C: ?", vbOKCancel, "Attenzione") On Error GoTo Annulla answer = answer * 1024 ^ 3 MsgBox "Boom!" Exit Sub Annulla: Exit Sub End Sub Rem La procedura più articolata per gestire correttamente On Error GoTo Rem On Error GoTo Sub self_destruction_13() Dim answer As Long answer = MsgBox("Vuoi formattare il disco C: ?", vbOKCancel, "Attenzione") On Error GoTo Err_SomeName Debug.Print 1 / (answer - 1) CleanUp: Exit Sub Err_SomeName: MsgBox "Boom!" Resume CleanUp End Sub Rem Finalmente la prima procedura attesa Rem On answer GoTo Sub self_destruction_14() Dim answer As Long answer = MsgBox("Vuoi formattare il disco C: ?", vbOKCancel, "Attenzione") On answer GoTo Sub1, Sub2 ' Execution resumes here after Exit Sub Sub1: MsgBox "Boom!" Exit Sub Sub2: Exit Sub End Sub Rem Finalmente la seconda procedura attesa Rem On answer GoSub Sub self_destruction_15() Dim answer As Long answer = MsgBox("Vuoi formattare il disco C: ?", vbOKCancel, "Attenzione") On answer GoSub Sub1, Sub2 ' Execution resumes here after Exit Sub Sub1: MsgBox "Boom!": Return Sub2: Return End Sub
Mirko un fiume inarrestabile
Salve a tutti
Non vorrei essere ... fuori tema ma posto lo stesso due sub che attendono alle stesse function. Eccole
Sub Scelta() Dim risp As Integer risp = MsgBox("Vuoi formattare il disco C: ?", vbOKCancel, "Attenzione") Run Choose(risp, "Esplode", "Esce") End Sub 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Sub Scegli() Dim risp As Integer risp = MsgBox("Vuoi formattare il disco C: ?", vbOKCancel, "Attenzione") Run Switch(risp = 1, "Esplode", risp = 2, "Esce") End Sub 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Function Esplode() MsgBox "Boom" End Function Function Esce() End Function
Si potrebbe fare a meno dell'ultima function.
Ciao e buon W.E. a tutti,
Mario
Ma se fai a meno di "Esce" non si arrabbia? cioè metti una stringa vuota? Comunque buona pensata
(perchè dovresti essere fuori tema?)
Sarà dura scegliere questa volta
Già: pensavo quindi di impostare il sondaggio a scelta multipla, così possiamo votare più candidati secondo i criteri che ci piacciono di più 🙂
Beh, ogni tanto qualche idea di un "vecchio" ... viene presa in considerazione.
Meno male.
Ciao,
Mario
ogni tanto
Ciao a tutti
Spero abbiate passato un buon WE.
Qui di seguito le mie proposte. A ben vedere sono parenti (molto strette di altre già postate in precedenza)
Per Riassumere io ho usato:
- Gestione degli errori
- Cicli (Do ... Loop, While ... Wend e For ... NExt)
- Gestione di Routine Secondarie
Tutte le soluzioni sono modificabili a seconda del tipo di Msgbox (OKCancel, Oppure SiNO,....)
Ho cercato di tenere dentro i loop le istruzioni per uscire dalla macro in modo tale che le operazioni richieste in caso affermativo fossero fuori da un ciclo
HO scoperto anche switch e choose che non conoscevo. Pertanto Grazie all'esercizio
Option Explicit ' Promemoria '|Costante| Valore | Descrizione | '| vbOK | 1 | OK | '|vbCancel| 2 | Annulla | '|vbAbort | 3 | Interrompi | '|vbRetry | 4 | Riprova | '|vbIgnore| 5 | Ignora | '| vbYes | 6 | Sì | '| vbNo | 7 | No | Sub MsGBoxErrore1() 'Macro con Gestione Errori Dim Scelta On Error GoTo ErrorHandler Scelta = 1 / (MsgBox("Procedo?", vbQuestion + vbOKCancel, "SCEGLI") - 2) On Error GoTo 0 Exit Sub ErrorHandler: MsgBox "Esco" End Sub Sub MsgBoxDoNot1() 'Con ciclo Do...Loop Do While Not CBool(MsgBox("Procedo?", vbQuestion + vbOKCancel, "SCEGLI") = vbOK) MsgBox "Esco" Exit Sub Loop MsgBox "Sto Procedendo" End Sub Sub MsgBoxFor() ' Usando un ciclo For...NExt Dim index as integer For index = MsgBox("Procedo?", vbQuestion + vbOKCancel, "SCEGLI") To 2 Step -1 MsgBox "Esco" Exit Sub Next MsgBox "Sto Procedendo" End Sub Sub MsgBoxWhile() 'Con Ciclo While...Wend While MsgBox("Procedo?", vbQuestion + vbOKCancel, "SCEGLI") = vbCancel MsgBox "Esco" Exit Sub Wend MsgBox "Sto Procedendo" End Sub Sub MsgBoxSubSwitch() ' Con Due Macro e Switch Dim Macro Dim Risultato Risultato = MsgBox("Procedo?", vbQuestion + vbOKCancel, "SCEGLI") Macro = Switch(Risultato = vbOK, "ProcedendoMacro", Risultato = vbCancel, "StopMacro") Application.Run Macro End Sub Sub MsgBoxSubChoose() ' Con Due Macro e Choose Application.Run Choose(MsgBox("Procedo?", vbQuestion + vbOKCancel, "SCEGLI"), "ProcedendoMacro", "StopMacro") End Sub Sub ProcedendoMacro() 'Macro da eseguire per procedere MsgBox "Sto procedendo" End Sub Sub StopMacro() Macro da eseguire per uscire MsgBox "Esco" 'End Sconsigliato ma termina tutte le esecuzioni End Sub
Eccole tutte insieme
HO scoperto anche switch e choose che non conoscevo
Strano che non li conoscessi! In qualche occasione ne faccio uso e avevo memoria di averne postato degli esempi. Comunque bene. Sono contento di quello che dici perché rafforza lo scopo ludico didattico dell'iniziativa
Ciao!
Non avete ancora pubblicato un solo esempio con Userform
Rem Do While + Userform1 Sub self_destruction_Userform() prelimin MsgBox("Vuoi formattare il disco C: ?", vbOKCancel, "Attenzione") End Sub Function prelimin(silent As Long) Do While silent = 1 UserForm1.Show Exit Do Loop End Function
Allegati:
You must be logged in to view attached files.Però è divertente no? 😀
Ciao allora piuttosto sostituirei il msgbox di scelta direttamente con una userform che fa la domanda e assocerei a due pulsanti le macro desiderate.
Non è più veramente aderente alla sfida ma sarebbe più comodo.
Vedi File Allegato.
Ahhhhhrg ho allegato de file qualcuno mi può eliminare il secondo (_1)?
Allegati:
You must be logged in to view attached files.Si possono sempre utilizzare le finestre di "Dialogo "
In un modulo...
Sub self_destruction_Dialogo() With ActiveWorkbook.DialogSheets(1) .Buttons(1).OnAction = "myCustomButtonOk" .Buttons(2).OnAction = "myCustomButtonExit" While .Show = False: Exit Sub: Wend End With '[More Code] End Sub Private Sub myCustomButtonOk() MsgBox "Boom!" End Sub Private Sub myCustomButtonExit() 'MsgBox "exit" End Sub
Allegati:
You must be logged in to view attached files. -
AutoreArticoli