"Option Explicit" deve sempre essere usato per forzare la dichiarazione delle
variabili ed è un buon ausilio al loro commento.
Il tempo perso cercando di trovare i bugs causati da digitazioni (aUserNameTmp
vs. sUserNameTmp vs. sUserNameTemp) supera notevolmente il tempo necessario
per una Dim.
La tavola seguente definidce il nostro standard dei prefissi per i controlli.
Tavola 1. Standard Prefissi per i nomi dei controlli
|
Prefix |
Control Type Description |
|
ani |
Animation button |
|
bed |
Pen Bedit |
|
cbo |
Combobox and dropdown Listbox |
|
chk |
Checkbox |
|
clp |
Picture Clip |
|
cmd |
Command Button |
|
com |
Communications |
|
ctr |
Control (Used within procs when the specific type is unknown) |
|
db |
ODBC Database |
|
dir |
Dir List Box |
|
dlg |
Visual Basic Pro Common Dialog |
|
drv |
Drive List Box |
|
ds |
ODBC Dynaset |
|
fil |
File List Box |
|
frm |
Form |
|
fra |
Frame |
|
gau |
Gauge |
|
gpb |
Group Push Button |
|
grd |
Grid |
|
hed |
Pen Hedit |
|
hsb |
Horizontal Scroll Bar |
|
img |
Image |
|
ink |
Pen Ink |
|
key |
Keyboard key status |
|
lbl |
Label |
|
lin |
Line |
|
lst |
Listbox |
|
mpm |
MAPI Message |
|
mps |
MAPI Session |
|
mci |
MCI |
|
mnu |
Menu |
|
opt |
Option Button |
|
ole |
Ole Client |
|
pic |
Picture |
|
pnl |
3d Panel |
|
shp |
Shape |
|
spn |
Spin Control |
|
txt |
Text/Edit Box |
|
tmr |
Timer |
|
vsb |
Vertical Scroll Bar |
* Nota del traduttore *
Ulteriori estensioni verranno aggiunte man mano.
Dato che i menu possono essere numerosi, la denominazione dei menu richiede
un po' più di attenzione. I prefissi dei menu continuano oltre l'iniziale
"mnu" aggiungendo un ulteriore lettera maiuscola per ogni livello
di nidificamento, con il nome del menu derivato dalla stessa caption alla fine.
Quando c'è ambiguità causata da duplicazione di caratteri, come
un menu con un Main con la stessa iniziale, ad es: Format e File, verrà
usata una lettera minuscola addizionale per differenziarli.
Esempi:
|
Struttura del menu |
Nome del menu |
|
Help.Contents |
mnuHContents |
|
File.Open |
mnuFiOpen |
|
Format.Character |
mnuFoCharacter |
|
File.Send.Fax |
mnuFSFax |
|
File.Send.Email |
mnuFSEmail |
In questo modo tutti i membri di un gruppo di menu saranno elencati vicini
gli uni agli altri.
Questo è un sistema molto efficiente di trovare un particolare menu,
specie se ve ne sono molti.
* Nota del traduttore *
Per ridurre il numero di menu elencati un eccessivo sparpagliamento
del codice è possibile definire un array di menu per tutte le voci dello
stesso livello.
In questo caso la denominazione segue le stesse regole di cui sopra omettendo
però la parte finale del nome.
Gli indici verranno identificati da costanti con prefisso "MNU_"
e il relativo codice sarà gestito nell'evento click tramite una Select.
Esempi:
|
Struttura del menu |
Nome del menu |
|
Help.Contents |
mnuH(MNU_CONTENTS) |
|
File.Open |
mnuFi(MNU_OPEN) |
|
Format.Character |
mnuFo(MNU_OPEN) |
|
File.Send.Fax |
mnuFS(MNU_FAX) |
|
File.Send.Email |
mnuFS(MNU_EMAIL) |
Per i controlli non elencati sopra viene lasciato al buon senso del programmatore
trovare un prefisso univoco che identifichi la classe.
[snap da parte dell'organizzatore]
La convenzione per la denominazione delle funzioni era descritta in modo analogo
a quella usata per le variabili.
Le funzioni useranno ora una convenzione differente.
<prefisso><corpo><qualificatore><suffiso>
Il prefisso descrive l'uso e lo scopo di una variabile come in iRecordNext
e sNameFirst.
ll qualificatore denota uno standard di derivazione di una variabile o funzione
come in iRecordNext e sNameFirst.
Il suffisso è l'opzionale carattere che identifica il tipo ($, %, #,
e così via).
* Nota del traduttore *
Il prefisso per le funzioni pubbliche dovrebbe identificare, a differenza di quanto avviene per le variabili, il modulo di provenienza seguendo le stesse regole per il suffisso dei controlli.
Es: Modulo Graphics.bas -> Function DrawLine --> Function
grpDrawLine
E' consigliato l'uso del descrittore As Tipo nella dichiarazione,
anzichè il carattere di tipo.
Le variabili devono sempre essere tipizzate anche se dichiarate Variant.
L'uso del tipo Variant sarà discusso più avanti.
Prefissi
La tavola seguente definisce i prefissi delle variabili che sono basati sul
C ungherese.
Questi dovrebbero essere usati universalmente, persino con le variabili tipizzate.
Tavola 2. Prefissi per i nomi di variabili
* Nota del traduttore *
Corretta per la ver. 32bit di VB
|
Prefisso |
Descrizione del tipo di variabile |
|
b |
Boolean |
|
c |
Currency - 64 bits (vb type = @) |
|
d |
Double - 64 bit signed quantity (vb type = #) |
|
db |
Database |
|
ds |
Dynaset |
|
dt |
Date+Time |
|
f |
Float/Single - 32 bit signed floating point (vb type = !) |
|
h |
Handle (vb type = &) |
|
i |
Index (vb type = %, &) *NDO* riconducibile a "l" |
|
l |
Long - 32 bit signed quantity (vb type = &) |
|
n |
Integer (sizeless, counter) (vb type = %) *NDO* riconducibile a "l" |
|
s |
String (vb type = $) |
|
u |
Unsigned - 16 bit unsigned quantity (must use &) |
|
ul |
Unsigned Long - 32 bit unsigned quantity (must use #) *NDO* riconducibile a "l" se la quantità lo permette |
|
v |
Variant (big and ugly to discourage use and make sure it gets the reader's attention) |
|
w |
Word - 16 bit signed quantity (vb type = %) |
|
a |
Array |
| t |
User defined type |
| y | Byte |
Il metodo ungarico è utile in Visual Basic in quanto il nome da solo
non dà informazioni sufficienti sullo scopo di una variabile e del suo
contenuto.
Per esempio, iSend (che probabilmente è un contatore per i messaggi spediti),
bSend (che probabilmente è un flag che indica il successo dell'ultima
operazione di invio), e hSend (che probabilmente è un handle per un oggetto)
suggeriscono molto concisamente qualcosa di differente. Questa informazione
è persa quando il nome è semplicemente Send.
Corpo
Il corpo di un nome di variabile o routine dovrebbe usare lettere maiuscole e minuscole in modo da descrivere il loro scopo. Nomi di funzioni dovrebbero inoltre iniziare con un verbo come in InitNameArray or CloseDialog.
Per termini lunghi o usati frequentemente, abbreviazioni (come Init, Num, Tbl,
Cnt e Grp per Number, Table, Count, e Group) sono suggerite per mantenere il
nome della funzione il ragionevolmente corto.
Quando queste abbreviazioni sono usate DEVONO essere usate coerentemente in
tutto il progetto: passare casualmente da "Cnt" a "Count"
all'interno dello stesso progetto produce frustrazione negli sviluppatori.
Qualificatori
Spesso vengono usate variabili e relative routines per gestire e manipolare
oggetti comuni.
In questi casi può essere veramente d'aiuto standardizzare i qualificatori.
Benchè mettere il qualificatore dopo il corpo può suonare male
(come in sGetNameFirst, sGetNameLast anzichè sGetFirstName e sGetLastName),
questa pratica aiuterà ad ordinare e a tenere raggruppati nell'editor
di VB le funzioni rendendo anche più semplice la comprensione della struttura
dell'applicazione
La tavola seguente definisce i qualificatori più comunemente usati e il loro significato.
Tavola 3. Qualificatori comuni
|
Qualificatore |
Descrizione (a seconda del corpo) |
|
First |
primo elemento di un set. |
|
Last |
ultimo elemento di un set. |
|
Next |
prossimo elemento in un set. |
|
Prev |
elemento precedente in un set. |
|
Cur |
elemento corrente di un set. |
|
Min |
valore minimo in un set. |
|
Max |
valore massimo in un set. |
|
Save |
Usato per salvare un valore che sarà ripristinato in seguito. |
|
Tmp |
Una variabile temporanea con scope fortemente localizzato. |
|
Src |
Sorgente (Source). |
|
Dst |
Destinazione (Destination). Spesso usata insieme a Source. |
|
WM_CLICK |
Window Message, con valore per "Click" |
|
NEW_LINE |
New Line character string |
Con la sola eccezione elencata sotto i tipi Variant NON dovrebbero essere usati.
Quando è necessaria una conversione di tipo le variabili Variant probabilmente
offrono una performance leggermente migliore rispetto alle funzioni di conversione
esplicita (val(), str$(), and the like), ma questo non è sufficiente
per giustificare l'ambiguità e la trascuranza generale del codice
Esempi:
vnt1 = "10.01" : vnt2 = 11 : vnt3 = "11" : vnt4 = "x4"
vntResult = vnt1 + vnt2 ' Does vntResult = 21.01 or 10.0111?
vntResult = vnt2 + vnt1 ' Does vntResult = 21.01 or 1110.01?
vntResult = vnt1 + vnt3 ' Does vntResult = 21.01 or 10.0111?
vntResult = vnt3 + vnt1 ' Does vntResult = 21.01 or 1110.01?
vntResult = vnt2 + vnt4 ' Does vntResult = 11x4 or ERROR?
vntResult = vnt3 + vnt4 ' Does vntResult = 11x4 or ERROR?
Additionally, the type conversion routines assist in documenting implementation details, which make reading, debugging, and maintaining code more straightforward.
Example:
(iVar1 = 5 + val(sVar2) 'use this
vntVar1 = 5 + vntVar2 'not this!
Eccezione
Raramente è necessaria (specie lavorando con databases, messages, DDE, o OLE), una funzione generica che può ricevere dati di qualsiasi tipo.
Esempio:
Sub ConvertNulls(rvntOrg As Variant, rvntSub As Variant)
'If rvntOrg = Null, replace the Null with rvntSub
If IsNull(rvntOrg) Then rvntOrg = rvntSub
End Sub
I blocchi di indentazione (tab) devono essere di quattro spazi.
Il commento alla funzione dovrebbe essere indentato di una tabulazione.
Il primo statement della funzione dovrebbe partire indentato di un tab, e un
tab per ogni linea di codice all'interno del blocco.
Function iFindUser (rasUserList() as String, rsTargetUser as String) as Integer
' Search UserList and if found, return index of first occurrence of TargetUser,
' else return -1
Dim i as Integer 'loop counter
Dim bFound as Integer 'target found flag
iFindUser = -1
i = 0
While i <= Ubound(rasUserList) and Not bFound
If rasUserList(i) = rsTargetUser Then
bFound = True
iFindUser = i
End If
Wend
End Function
vntVar1 = "10.01"
vntVar2 = 11
vntResult = vntVar1 + vntVar2 'vntResult = 21.01
vntResult = vntVar1 & vntVar2 'vntResult = 10.0111