Caseta pentru mesaj - Message Box

O altă modalitate de a afișa informația necesară utilizatorului este caseta de tip mesaj. Orice aplicație Windows conține diverse casete de tip mesaj. Acestea sunt simple și limitate, dar joacă un rol important.

Iată la ce se pot folosi casetele de tip mesaj:

  • Informează utilizatorul ce va face macrocomanda (și oferă posibilitatea ieșirii din macrocomandă dacă nu este nevoie să fie executată).
  • Prezintă utilizatorului ce va face macrocomanda și îl întreabă ce decizie ia (de obicei, să continue operațiunea curentă sau să facă altceva).
  • Atenționează utilizatorul despre erorile apărute în timpul execuției macrocomenzii pentru a permite remedierea lor.
  • Informează utilizatorul dacă macrocomanda a fost executată cu succes și s-a încheiat. Acest mesaj este util pentru macrocomenzile care blochează actualizarea ecranului sau ascund altfel ceea ce fac. În aceste cazuri, utilizatorul nu poate ști dacă macrocomanda mai este executată sau s-a terminat. Caseta de tip mesaj poate fi folosită și pentru a informa ce a făcut macrocomanda – de exemplu, că a modificat unele elemente, a făcut modificări sau a descoperit în document probleme care trebuie remediate.

Avantajele și dezavantajele folosirii casetelor de tip mesaj

Avantaje:

  • Utilizatorii nu pot sări peste un mesaj. Procedura se oprește și așteaptă decizia utilizatorului. (Se poate afișa și un mesaj care să spună utilizatorului că nu poate scăpa de mesaj cu Alt+Tab pentru a comuta la altă aplicație.)
  • Utilizatorul poate alege între două sau trei opțiuni.

Dezavantaje:

  • O casetă de tip mesaj poate avea unul, două sau trei butoane, adică utilizatorul are maxim 3 opțiuni.
  • Butoanele din casete sunt predefinite în seturi- nu se pot pune butoane particularizate. (Pentru acestea, se poate folosi o casetă de dialog.)
  • În casetele text nu se pot introduce caracteristici de tip interfață utilizator (user-interface) cum ar fi text box, group box sau list box.

Sintaxa pentru Message-Box

Sintaxa de bază pentru casete de tip mesaj este:

MsgBox(prompt[, buttons] [, title][, helpfile, context])

Iată ce înseamnă elementele din sintaxă:

MsgBox Este funcția folosită de VBA pentru a afișa o casetă de tip mesaj. De obicei, după ea se adaugă mai multe argumente închise între paranteze.

Prompt Argument obligatoriu pentru funcția MsgBox care specifică textul care va fi afișat în caseta de tip mesaj. Prompt este un argument de tip String, care trebuie scris; poate avea maxim 1023 de caractere, deși se recomandă să fie scurt și la obiect. (Orice prompt care are mai mult de 1023 caractere, este trunchiat la 1023 de caractere fără atenționare.)

Buttons Argument opțional care controlează tipul de casetă mesaj pe care VBA îl va afișa specificând butoanele pe care le conține. De exemplu, se poate afișa o casetă de tip mesaj cu un singur buton OK; cu butoanele OK și Cancel; cu butoanele Abort, Retry și Ignore; etc. Se pot adăuga argumente și la argumentul buttons care controlează pictograma din caseta de mesaj și modul de lucru al casetei mesaj.

Title Argument opțional care controlează bara de titlu a casetei de mesaj. Este tot de tip String. Dacă title nu este specificat, VBA folosește titlul aplicației - Microsoft Word pentru Word, Microsoft Excel pentru Excel, Microsoft PowerPoint pentru PowerPoint, etc. Se recomandă specificarea unui titlu, deoarece numele aplicației nu este util (mai ales că utilizatorul îl poate confunda cu o casetă a aplicației în care este executată macrocomanda).

Help file Argument opțional care arată care fișier Help din VBA va fi afișat atunci când utilizatorul apasă tasta F1 fiind în caseta de tip mesaj (sau când face clic pe butonul Help din caseta mesaj care conține un buton Help).

Context Argument opțional care controlează care subiect din fișierul Help al VBA va fi afișat. Dacă se specifică argumentul helpfile, trebuie specificat și argumentul context.

În exemplele care urmează, vor fi prezentate mai întâi casete de mesaj simple, apoi complexe, cu mai multe argumente.

Afișarea unei casete de tip mesaj simple

Cea mai simplă comandă pentru o casetă de tip mesaj este cea în care se scrie doar textul pentru argumentul prompt, între ghilimele duble:

MsgBox "Aceasta este o caseta de mesaj simpla."

Rulată în Excel, comanda afișează o casetă de tip mesaj simplă, ca în figura de mai jos. Singurul argument este prompt, VBA afișează caseta mesaj cu un singur buton OK și numele aplicației în bara de titlu.

Comanda MsgBox poate fi scrisă pe orice linie goală din macrocomandă. După tastarea cuvântului cheie MsgBox, caracteristica Auto Quick Info din VBA afișează sintaxa funcției.

După introducerea comenzii MsgBox cu argumentul obligatoriu (prompt), caseta poate fi afișată prin parcurgerea codului pas cu pas (cu tasta F8 sau cu clic pe butonul Step Into din bara cu instrumente Debug din VBA Editor) sau prin executarea macrocomenzii (tasta F5 sau click pe butonul Run Sub/UserForm sau din meniu, cu Run > Run Sub/UserForm).

În loc să se scrie șirul de caractere în argumentul prompt, se poate folosi o variabilă de tip String. Următorul exemplu folosește o variabilă de tip String numită strMsg:

Dim strMsg As String
strMsg = "Aceasta este o caseta de mesaj simpla."
MsgBox strMsg

Această modalitate poate fi utilă atunci când se lucrează cu șiruri lungi de caractere (se pot construi șiruri lungi prin concatenarea mai multor șiruri scurte unite cu operatorul &). Folosirea unei variabile este utilă și atunci când trebuie afișat un șir definit anterior în macrocomandă sau un șir creat dinamic de către macrocomandă (de exemplu, după preluarea numelui utilizatorului dintr-o casetă pentru introducere date - input box).

Afișarea unei casete de tip mesaj pe mai multe linii

Implicit, VBA afișează în casetă mesajele scurte pe o singură linie și mesajele lungi pe mai multe linii – atâtea cât sunt necesare, maxim 1024 caractere.

Se poate trece pe o linie nouă prin includerea caracterelor speciale line-feed și carriage-return, astfel:

  • Chr(13) sau vbCr reprezintă carriage return.
  • Chr(10) sau vbLf reprezintă line feed.
  • Chr(10) + Chr(13) sau vbCrLf reprezintă combinația line-feed/carriage-return.

În casetele mesaj, aceste trei caractere au același efect – mutarea caracterelor care urmează pe o linie nouă. Codul este mai ușor de citit dacă se folosește o constantă predefinită - built-in (vbCr, vbLf, sau vbCrLf) în locul construcției corespunzătoare Chr(); este și mai rapid de scris. De obicei, folosirea constantei vbCr este mai clară.

Pentru a adăuga spațiul tab se poate folosi Chr(9) sau vbTab. Și aici, vbTab este mai ușor de citit și de scris.

Următorul cod afișează o casetă de mesaj în Word. De reținut că fiecare parte din text este închisă între ghilimele duble (pentru a indica VBA că sunt parte din string). Caracterele Chr(149) sunt buline, deci textul de după ele începe după câteva spații:

Dim strMsg As String
strMsg = "Word a terminat de formatat raportul cerut."
& vbCr & vbCr & "Puteti executa urmatoarele proceduri:" & vbCr & vbCr & Chr(149) & " Distribuire_Raport, care trimite raportul la " & "Biroul Central." & vbCr & vbCr & Chr(149) & _
" Stocare_Raport, pentru a copia raportul în directorul Arhiva." _
& vbCr & vbCr & Chr(149) & " Backup_Raport, pentru a crea o copie "
& "a raportului pe server." 

VBA Ajută la spațierea/ ortografia automată a codului

În acest exemplu se poate observa că apare câte un spațiu de o parte și de alta a fiecărui caracter ampersand (&) și a semnului egal. Aceste spații pot fi scrise de către programator sau sunt introduse automat de VBA atunci când se mută punctul de inserție pe o altă linie, apăsând Enter sau făcând clic pe mouse. (Mutarea punctului de inserție pe o altă linie determină VBA să verifice linia la care tocmai s-a lucrat și face diverse modificări automate, dacă este necesar. De exemplu, unele caractere pot fi transformate în majuscule sau dacă s-a tastat EndIf, VBA le va despărți în două cuvinte.)

Alegerea butoanelor pentru o casetă mesaj

Argumentul buttons controlează ce butoane va conține caseta de mesaj. VBA oferă tipurile de casete mesaj din tabelul de mai jos, controlate de argumentul buttons.

Aceste tipuri de casete mesaj pot fi specificate în cod folosind fie valoarea numerică, fie constanta. De exemplu, se poate specifica fie valoarea 1, fie vbOKCancel pentru a afișa o casetă mesaj cu butoanele OK și Cancel. Valoarea este mai ușor de tastat; constanta este mai ușor de citit. Ambele comenzi de mai jos au ca rezultat în PowerPoint aceeași casetă mesaj :

Dim lngR As Long
lngR = MsgBox("Aplicati formatarea standard la diapozitiv?", vbYesNo) 
lngR = MsgBox("Aplicati formatarea standard la diapozitiv?", 4)

Din punctul de vedere al VBA, nu contează dacă în macrocomenzi se folosesc valori sau constante pentru casetele mesaj. Pentru programatori, se recomandă constantele text, deoarece codul este mai ușor de citit.

Alegerea unei pictograme pentru o casetă mesaj

La caseta mesaj se poate adăuga și o pictogramă prin includerea ca argument a unei valori sau a unei constante.

Și aici, referirea la pictograme se poate face fie prin valoare, fie prin constantă: valoarea 48 sau constanta vbExclamation va afișa o pictogramă cu semnul exclamării. Constanta este mai ușor de citit.

Pentru a adăuga valoarea sau constanta pentru pictogramă la caseta mesaj, se folosește semnul plus (+). De exemplu, pentru a afișa o casetă text care conține butoanele Yes și No împreună cu semnul întrebării (ca în figura de mai jos), se poate introduce vbYesNo + vbQuestion (sau 4 + 32, vbYesNo + 32, sau 4 + vbQuestion):

lngR = MsgBox("Aplicati formatarea standard la diapozitiv?", _ vbYesNo + vbQuestion)

Setarea unui buton implicit pentru caseta mesaj

Ca și în interfața Windows, utilizatorul este direcționat la un buton implicit din caseta mesaj. Este butonul care are un contur albastru și în interior are o linie punctată în jurul zonei de text. (A se vedea butonul Yes din figura de mai sus.) Utilizatorul poate muta selecția la un alt buton folosind tasta Tab sau Shift+Tab sau tastele săgeți →, ←, ↑, ↓.

În cod se poate specifica butonul implicit.

Folosirea Practică a Butoanelor Implicite

Butonul implicit pentru o casetă mesaj poate fi ales în comanda MsgBox. Alegerea unui anumit buton este recomandată mai ales atunci când macrocomanda va executa o acțiune importantă. (Utilizatorul ar putea apăsa din greșeală pe tasta Enter sau ar putea da clic pe butonul marcat ca implicit.)

Atunci când o macrocomandă poate distruge munca cuiva dacă este executată necorespunzător, se recomandă ca butonul implicit din caseta mesaj să fie setat la No sau la Cancel, pentru ca utilizatorul să aleagă continuarea macrocomenzii. Caseta mesaj oprește executarea, permite utilizatorului să fie de acord sau nu cu acțiunea propusă, apoi continuă macrocomanda în funcție de alegerea utilizatorului.

De ce VBA a inclus un buton implicit? Pentru ca utilizatorul să aleagă mai ușor butonul implicit (Yes sau OK) apăsând tasta Enter. Programatorul trebuie să decidă care este butonul implicit. Butonul implicit în VBA este primul buton din caseta mesaj. Dar sunt cazuri în care trebuie ales un alt buton implicit. Folosind această tehnică, utilizatorul este forțat să ia o decizie. Tabelul de mai jos conține valorile și constantele cu care se alege butonul implicit. Exemplul de după tabel arată cum se alege butonul implicit.

Toate casetele mesaj descrise mai sus pot avea 1-3 butoane, dar se mai poate adăuga un buton Help la orice casetă mesaj (descrierea mai jos), deci casetele pot avea maxim 4 butoane.

În VBA, dacă nu se specifică altfel, primul buton este automat butonul implicit – de exemplu, butonul OK din caseta mesaj vbOKCancel, butonul Abort din caseta mesaj vbAbortRetryIgnore, butonul Yes din caseta mesaj vbYesNoCancel, butonul Yes din caseta mesaj vbYesNo și butonul Retry din caseta mesaj vbRetryCancel. VBA numără butoanele în ordinea în care apar în caseta mesaj. Deci într-o casetă mesaj vbYesNoCancel, primul buton este Yes, al doilea - No și al treilea - Cancel.

Pentru a face ca alt buton să fie cel implicit, se specifică valoarea sau constanta ca parte a argumentului buttons. În PowerPoint, comanda următoare afișează o casetă mesaj ca în figura de mai jos:

Dim lngQuery As Long
lngQuery = MsgBox("Doriti sa stergeti aceasta prezentare?", _ 
  vbYesNo + vbCritical + vbDefaultButton2)

Controlul modului de afișare a casetei mesaj

VBA poate afișa deopotrivă casete mesaj de tip application-modal sau system-modal – cel puțin teoretic. Casetele mesaj de tip application-modal opresc execuția macrocomenzii în aplicația curentă până la când utilizatorul face o alegere, pe când casetele mesaj system-modal opresc orice acțiune pe întregul computer până când utilizatorul face o alegere.

Majoritatea casetelor mesaj sunt de tip application modal, care permit utilizatorului să comute la o altă aplicația apăsând tastele Alt+Tab (sau folosind butoanele din Taskbar). Utilizatorul poate lucra în altă aplicație, chiar dacă nu a făcut o alegere în caseta mesaj. Acest lucru oferă libertate și flexibilitate. Însă unele casete mesaj (mai ales cele folosite la un proces de instalare) sunt de tip system modal, care insistă ca utilizatorul să își concentreze atenția doar asupra lor. Erorile critice de sistem din Windows și mesajele "you must restart your computer now" sunt de tip system modal pentru a preveni evitarea lor.

La proiectarea macrocomenzilor, folosirea casetelor mesaj de tip system-modal se recomandă doar în cazuri absolut necesare – de exemplu, când o acțiune ar putea avea ca rezultat pierderea de date sau instabilitatea sistemului.

De obicei se folosesc casetele mesaj de tip application-modal.

Teoretic, se poate controla modul casetelor mesaj folosind argumentele buttons din tabelul următor:

În practică, chiar dacă se folosește argumentul vbSystemModal, utilizatorul poate comuta la o altă aplicație și să își continue lucrul. Însă caseta mesaj rămâne afișată pe ecran deasupra altor ferestre ("on top"), fără a împiedica lucrul în altă aplicație.

Implicit, casetele mesaj sunt de tip application modal, deci doar în cazuri rare se poate alege o casetă mesaj de tip system-modal, prin adăugarea constantei vbSystemModal sau a valorii 4096 la argumentul buttons:

Response = MsgBox("Doriti sa stergeti acest document?", _ 
    vbYesNo + vbCritical + vbDefaultButton2 + vbSystemModal)

Casetele mesaj de tip system-modal sunt afișate la fel ca și cele de tip application-modal.

Specificarea unui titlu pentru o casetă mesaj

Următoarea componentă a casetei mesaj este bara de titlu, controlată de argumentul opțional title. Dacă argumentul title este omis, VBA afișează numele aplicației ca și titlu, dar menționarea unui titlu poate fi de folos utilizatorilor.

Expresia title de tip string poate avea, teoretic, maxim 1024 caractere, (ce depășește 1024 caractere este trunchiat, fără mesaj de atenționare sau eroare), dar practic orice titlul mai lung de 75 de caractere este trunchiat cu (...). Pentru ca titlul să poată fi ușor de citit, sunt suficiente 25 de caractere.

Barele de titlu pot oferi informații utile

Bara de titlu este de obicei prima parte a casetei mesaj pe care o vede utilizatorul, deci este de dorit ca informația din titlu să fie clară și precisă. Eticheta convențională este de a pune numele macrocomenzii în bara de titlu și folosirea argumentului prompt pentru a explica acțiunile care vor fi executate pentru fiecare buton în parte.

În plus, în cazul macrocomenzilor revizuite, în bara de titlu se poate pune și numărul versiunii, astfel încât utilizatorii să poată afla versiunea macrocomenzii folosite (și să o acualizeze la o versiune corespunzătoare). De exemplu, macrocomanda Stergere Document este identificată ca fiind la versiunea 2.5 în caseta mesaj din figura următoare.

De obicei, în caseta mesaj se specifică argumentul title. Tot în bara de titlu se poate include și versiunea.

Argumentul title se specifică după argumentul buttons, astfel:

Dim lngQuery As Long
lngQuery = MsgBox("Doriti sa stergeti acest document?", vbYesNo + vbCritical + vbDefaultButton2, "Stergere document v.2.5")

Pentru argumentul title se poate folosi o variabilă de tip string. De exemplu, se poate declara o singură variabilă de tip string care se folosește pentru a furniza titlul fiecărei casete mesaj apelate de macrocomandă. Sau titlul casetei poate conține un string creat sau stocat în macrocomandă.

Se evită folosirea caracterelor speciale în titluri

Se evită folosirea caracterelor line-feed, carriage-return sau Tab în argumentul title. VBA le ignoră.

Adăugarea butonului Help în caseta mesaj

Pentru a adăuga un buton Help într-o casetă mesaj, se folosește constanta vbMsgBoxHelpButton. Acest argument se adaugă la oricare butoane sunt specificate pentru caseta mesaj:

lngQuery = MsgBox("Doriti sa stergeti documentul?", vbYesNo _
    + vbCritical + vbDefaultButton2 + vbMsgBoxHelpButton, _
    "Stergere document")

Adăugarea argumentului vbMsgBoxHelpButton afișează butonul Help button în caseta mesaj – dacă utilizatorul face clic pe butonul Help, nu se afișează fișierul Help. Trebuie să se specifice care fișier Help și subiectul care va fi afișat (descrierea în secțiunea următoare). Figura 13.9 afișează caseta mesaj afișată cu butonul Help.

Specificarea fișierului Help pentru Message Box

Argumentele finale care pot fi folosite pentru o casetă mesaj sunt helpfile și context:

  • Argumentul helpfile este un argument de tip string care specifică numele și locația fișierului Help pe care îl va afișa VBA atunci când utilizatorul cere ajutor din caseta mesaj.
  • Argumentul context este numărul de context din fișierul Help. Acest număr indică care subiect din fișierul Help va fi afișat.

Argumentele helpfile și context sunt utile dacă programatorul scrie propriile fișiere de Help, altfel este dificil să se acceseze numerele de context Help, care se află în fișierele Help oficiale.

Pentru a accesa propriile fișiere Help, sintaxa cu care se specifică argumentele helpfile și context este simplă:

Dim lngQuery As Long
lngQuery = MsgBox("Doriti sa stergeti documentul?", vbYesNo _
+ vbCritical + vbDefaultButton2 + vbMsgBoxHelpButton, _
"Stergere document", "c:\Windows\Help\My_Help.chm", 1012)

În acest caz, fișierul Help este specificat ca fiind My_Help.chm, care se află pe partiția C, în folderul \Windows\Help\. VBA afișează subiectul 1012 din Help.

Atunci când utilizatorul face clic pe butonul Help din caseta mesaj, VBA afișează subiectul specificat din fișierul Help. Caseta mesaj rămâne pe ecran, astfel încât, după ce utilizatorul a consultat fișierul Help, să revină la caseta mesaj pentru a face o alegere.

Numărul de context Help pentru deschiderea primei pagini a unui fișier Help este 0. Atunci când nu se cunoaște numărul de context, se folosește 0 pentru a deschide fișierul Help. Apoi utilizatorul trebuie să localizeze informația de care are nevoie.

Trei constante pentru efecte speciale

VBA furnizează trei constante speciale pentru folosirea cu casetele mesaj. Ele pot fi specificate ca prim argument în argumentele buttons:

vbMsgBoxSetForeground Indică VBA să afișeze caseta mesaj în fața celorlalte ferestre. Această constantă nu se folosește des, deoarece casetele mesaj sunt afișate implicit în fața celorlalte ferestre (pentru a le vedea).

vbMsgBoxRight Indică VBA să alinieze textul la dreapta în caseta mesaj.

vbMsgBoxRtlReading Indică VBA să aranjeze textul de la dreapta la stânga pe sistemele Hebrew și Arabic. Nu are efect pe sistemele non-BiDi (non-bidirecționale).

Folosirea doar a unor argumente

De reținut că argumentele opționale sunt chiar opționale. La afișarea unei casete mesaj, se pot specifica sau omite argumentele opționale. Pentru a specifica un argument care urmează după alte argumente care nu au fost specificate, se folosește virgula, care indică fiecare argument opțional nefolosit. (Această tehnică poate fi folosită cu orice listă de argumente.) De exemplu, pentru a afișa caseta mesaj din exemplul anterior fără a specifica argumentele buttons și title, se poate folosi comanda:

Raspuns = MsgBox("Doriti sa formatati raportul?",,, _
"c:\Windows\Help\Macro Help.chm", 1012

Aici, cele trei virgule indică faptul că argumentele buttons și title sunt omise (aici VBA le va afișa pe cele implicite – caseta mesaj vbOKOnly cu bara de titlu care conține numele aplicației), astfel se evită ca VBA să confunde argumentul helpfile cu argumentul buttons. Alternativ, se pot folosi numele argumentelor, care duce la un cod mai puțin concis, dar mai ușor de citit:

Raspuns = MsgBox("Doriti sa formatati raportul?", _
HelpFile:="c:\Windows\Help\Macro Help.chm", Context:=1012)

Obținerea unei valori dintr-o casetă mesaj

La afișarea unei casete mesaj vbOKOnly, se poate afla pe care buton a făcut clic utilizatorul, deoarece caseta are un singur buton OK. Dar când se folosește o casetă mesaj cu mai multe butoane, pentru a afla care buton a fost ales, trebuie să se obțină o valoare de la caseta mesaj care să indice butonul apăsat de utilizator. (Apoi se poate alege o anumită comandă, în funcție de butonul apăsat.)

Pentru a recupera o valoare de la caseta mesaj, se declară o variabilă. Apoi se pune egal între variabila aleasă și caseta mesaj, astfel:

Dim lngRaspuns As Long
lngRaspuns = MsgBox("Doriti sa creati raportul zilnic?", _ 
    vbYesNo + vbQuestion, "Creare Raport Zilnic")

Mai întâi se declară variabila care trebuie să fie de tip Long, pentru a conține alegerea utilizatorului.

La executarea codului, VBA stochează în variabilă, ca valoare, butonul ales de utilizator. Apoi se verifică valoarea și se poate declanșa o anumită acțiune.

Tabelul de mai jos afișează lista cu butoane pe care le poate alege utilizatorul. Butoanele pot fi referite fie ca nume de constantă, fie ca valoare. Ca de obicei, constanta este mai simplu de citit.

De exemplu, pentru a verifica butonul ales din caseta mesaj vbYesNo, se poate folosi o comandă If...Then...Else:

Dim lngAlegereButon As Long
lngAlegereButon = MsgBox("Doriti sa creati raportul zilnic?", _ 
   vbYesNo + vbQuestion, "Creare Raport Zilnic")
If lngAlegereButon = vbYes Then Goto CreareRaportZilnic
Else
  Goto Bye
EndIf

Aici, dacă utilizatorul alege butonul Yes, VBA merge la linia de cod identificată de eticheta CreareRaportZilnic și continuă execuția macrocomezii; dacă nu, încheie macrocomanda mergând la eticheta Bye de la sfârșitul procedurii. Condiția If verifică răspunsul generat de alegerea utilizatorului în caseta mesaj pentru a vedea dacă a ales vbYes (generat de clic pe butonul Yes sau tasta Enter, atunci când butonul Yes este selectat). Instrucțiunea Else este executată dacă răspunsul nu a fost vbYes, adică dacă utilizatorul a ales clic pe butonul No sau a apăsat tasta Esc.