1. Visual Basic IDE(集成开发环境)设置 :必须打开设置选项的“要求变量声明”,“对齐控件到网格”,“自动缩进”开关。 Tab的宽度统一为4个空格,网格单位一律设为:width 60 height 60。
2. 命名约定
(注意:在任何时候,不能使用中文及全角字符,只允许使用英文字母、下划线和数字)
2.1 工程的命名
ActiveX控件和DLL工程命名格式为(….Lib),EXE工程直接命名,如果是通用组件工程,直接命名,如果是项目或产品工程,则使用项目或产品缩写作为前缀。如:XWY….Lib。 工程命名不必缩写,为了表达意思和用途,可以尽可能地长,而且命名格式采用 (名词) 、 (形容词 + 名词) 或 (名词 + 动作的名词形式)。如: StockOperationLib或StockLib。
2.2 变量的命名
程序中的变量遵循匈牙利表示法,即“前缀+变量含义”,变量的含义为一个或多个英文单词,每个单词的第一个字母大写。变量前缀为三个小写字母示意其类型,所需添加的前缀遵循微软在MSDN中的建议。列表如下: 对于一般的计数器变量定义,应该尽可能地简单,如:Dim i As IntegerFor i = 0 to 100Next i范围标识:
全局变量加前缀:’g_’ 例如:g_strFdbm
模块级变量加前缀:’m_’ 例如:m_strFdbm
过程级变量不加前缀 全局变量和模块级变量应该尽量使用全名称,不推荐使用缩写,如:gEntityManager
常见的变量类型和控件类型前缀如下表所示:
变量类型前缀列表
数据类型
|
前缀
|
示例
|
boolean
|
bln
|
blnloggedin
|
currency
|
cur
|
cursalary
|
control
|
ctl
|
ctllastcontrol
|
double
|
dbl
|
dblmiles
|
errobject
|
err
|
errlasterror
|
single
|
sng
|
sngyears
|
handle
|
hwd
|
hwdpicture
|
long
|
lng
|
lngonhand
|
object
|
obj
|
objusertable
|
integer
|
int
|
intage
|
string
|
str
|
strname
|
user-defined type
|
udt
|
udtemployee
|
variant (including dates)
|
vnt
|
vntdatehired
|
array
|
arr
|
arremployees
|
数据库对象 |
前缀 |
示例 |
database |
dbs
|
dbsaccounts
|
recordset |
rec
|
recforecast
|
command |
cmd
|
cmdquery
|
connection |
con
|
consql
|
2.3 控件的命名
控件命名一律使用控件类型缩写+控件用途的命名方式,缩写规则同变量命名,以下是常用控件的类型缩写,应该严格遵守。如果使用了新的控件(包括升级版本),必须向公司提出申请,经评审通过后,协同一致其类型名称缩写,再进行使用。
控件类型前缀列表
控件
|
前缀
|
举例
|
ado data
|
ado
|
adobiblio
|
animated button
|
ani
|
animailbox
|
checkbox
|
chk
|
chkprint
|
combo box
|
cbo
|
cbotitle
|
command button
|
cmd
|
cmdcancel
|
communications
|
com
|
comfax
|
data
|
dat
|
datbiblio
|
data-bound combo box
|
dbcbo
|
dbcbolanguage
|
data-bound grid
|
dbgrd
|
dbgrdqueryresult
|
common dialog control
|
dlg
|
dlgcommon
|
control
|
ctr
|
ctrcurrent
|
directory list box
|
dir
|
dirsource
|
drive list box
|
drv
|
drvtarget
|
dtpicker dropdatecontrol
|
dt
|
|
enumeditbox
|
enm
|
|
file list box
|
fil
|
filsource
|
frame
|
fra
|
fralanguage
|
form
|
frm
|
frmmain
|
vfgrid
|
grd
|
|
graph
|
gra
|
|
group push button
|
gpb
|
gpbchannel
|
hierarchical flexgrid
|
flex
|
flexorders
|
horizontal scroll bar
|
hsb
|
hsbvolume
|
image
|
img
|
imgicon
|
image imagelist
|
img
|
|
label
|
lbl
|
lblhelpmessage
|
line
|
lin
|
linvertical
|
list box
|
lst
|
lstresultcodes
|
listview
|
lv
|
|
mci
|
mci
|
mcivideo
|
mdi child form
|
mdi
|
mdicontact
|
menu control
|
mnu
|
mnufileopen
|
numeditbox
|
nm
|
|
ole container
|
ole
|
olephoto
|
option button
|
opt
|
optspanish
|
panel
|
pnl
|
pnlsettings
|
picture box
|
pic
|
picdiskspace
|
picture clip
|
clp
|
clptoolbar
|
progressbar
|
prg
|
prgloadfile
|
report
|
rpt
|
|
scroll bar
|
sbr
|
|
shape
|
shp
|
shpcircle
|
slider
|
sld
|
sldscale
|
spin
|
spn
|
|
statusbar
|
st
|
|
toolbar
|
tb
|
|
text box
|
txt
|
txtaddress
|
timer
|
tmr
|
tmralarm
|
treeview
|
tv
|
tvflbm
|
vertical scroll bar
|
vsb
|
vsbrate
|
|
|
|
2.4 函数和过程的命名
此处函数包括sub和function,以下这两种过程统称为函数。
函数表示的是一个动作,所以它的结构应该是 动词+名词,动词必须小写,后面的名称首字母大写,如:
getmaterialcode
updategrid
readorder
函数命名尽量不要使用缩写,而且它的名称应该使人一目了然,能够从名称就知道这个函数的功能,不要使用无意义的函数名称,如:getcode,update,readdata。
当函数名称不足以表达其功能时,使用在函数头部加上让调用者足够明白的注释。
参数的命名:参数命名的原则是全部小写,如果参数包括两个或以上的单词时,首单词字母小写,其它单词首字母大写,如showcol、isupdate。
2.5 常量的命名
常量的命名应该全部大写,使用‘_’作为单词间的分隔符,单词尽量使用全名称,如:
public const msg_empty_row as string = “有空行存在!”
解释:
(1) 对一些常用词应该使用简写,如msg
(2) 使用public来声明常量
(3) 对常量的声明必须带上类型,如上面的as string
2.6 属性的命名
属性的命名采用首字母大写的原则,如itemcount item
2.7 类、窗体和模块的命名
类的命名:cls前缀+功能名词,并且单词首字母大写。如:clssystemconfig
窗体命名:使用frm前缀+功能名词,并且单词首字母大写。如:frmlist。
模块命名:mod前缀+功能名词,并且单词首字母大写。如modlist。
以上三种命名在一个项目内必须保持唯一。
2.8 自定义控件的命名
自定义控件的命名:名词 + ctrl
如:editgridctrl
3. 书写格式约定
3.1 定义
定义的代码块应该放在一起,不要在中间定义变量,变量的定义应该顶行进齐,不能缩进。
如下:
dim i as integer
dim j as integer
dim em as entitymanager
对象的定义应该尽可能地带上所属的库名称,防止以后引起名称冲突,如引用了两个lib,每个中都包含一个stock类,如果不使用as ….lib.stock的定义方式,则无法编译通过,为了防止以后程序扩充和修改时引入新的库带来命名冲突,推荐在定义类对象时全部加上库标识,如:
dim em as objectpersistencelib.entitymanager
3.2 空行
空行是区分代码块与块的间隔,在函数之间必须加上空行(两行左右),而函数内部,变量声明块和实现块(实现块指除变量声明外的其它代码)要使用空行来间隔(一行),实现块的内部,通过空行来标识一个功能段,如:
private sub check(order as nysalebacklib.order)
减少库存
dim objstockitem as nystocklib.stockitem
dim objstock as nystocklib.stock
dim i as integer
set objstock = createstock()
for i = 0 to order.itemcount - 1
set objstockitem = order.item(i)
减少库存
call objstock.reduceitem(objstockitem, true)
next i
set objstock = nothing
end sub
(注意:不要使用过多的空行,空行太多影响代码阅读!)
3.3 缩进
缩进必须严格执行,变量声明块不缩进,实现块必须保证全部缩进(即不可能有实现块是行首对齐的)。
每个单位的代码缩进为一个tab,非相关代码留一行空白的间隔。
注:goto标签不缩进
对于基本的控制结构,必须要有缩进,如:if、do、with、for、open、select块,缩进示例如下:
private function getmax(byref lngarray() as long) as long
dim lngmax as long
dim lngcount as long
getmax=0
for lngcount =0 to ubound(lngarray)
if lngarray (lngcount)>lngmax then
lngmax=lngarray(lngcount)
end if
next
end function
对于过长的语句,必须使用续行,续行位置要有明显意义,示例:
sql = “select [code],[name] from [person] “ _
& “ where [code] like ‘001%’ “
& “ and [code] like ‘002%’ “
函数的参数如果过长,也应该续行,示例:
增加库存
productcode 产品编号
spec 长度规格
color 颜色
patch 是否拼圈
volumn 盘号
ordinal 子库存顺序号
length 长度
ischeck 是否审核入库增加(否则为弃审出库增加)
public sub adddetail(productcode as string, _
spec as double, _
color as string, _
patch as boolean, _
volumn as string, _
ordinal as integer, _
length as double, _
ischeck as boolean)
4. 注释约定
4.1 注释量
程序的注译越详尽,越仔细越好。
程序中声明的每一个变量,能加上注译最好,至少用来运算或者保存关键数据的变量必须加上注译。
对于每一段逻辑上实现某个基本功能的几句代码,最好在其上一行加上简单注译。
对于每一个自定义的函数,不管大小都必须加上注译。
4.2 格式
注译的格式如下:
******************************************************
函数所实现的功能
函数的参数1的含义:xxxxx
函数的参数2的含义:xxxxx
……
函数返回值所代表的错误信息:xxxxx
函数的返回值为0表示执行成功,为其它值表示执行失败
******************************************************
public(private) function forexample(……………………) as long
…………………………………………
end function
在每个代码模块(窗体、类、模块、控件)的最上面,必须写上代码编写人、代码创建时间、代码修改时间和修改说明。
示例:
库存修改窗体
作者 xxxxxx
建立日期 2005-6-22
修改日期 2005-6-23 修改人 xxxxxx
增加对库存修改时同时影响最后入库日期的功能
5. 程序设计约定
1. 程序一律从main()函数开始执行。
2. 同一个程序在一台机器同时只能运行一次,既不能同时运行同一个程序的多个副本。
即if app.previnstance = true then end
3. 同一个登录用户同时只能登录同一个系统一次。
4. 建议使用long型的变量来代替integer类型。
这样做可以减少一些数据溢出的错误,而且,在win32位平台上,cpu处理32位的数据比16位的数据速度更快。
5. 在连接字符串时使用 & 运算符,避免使用 + 运算符。
下面例子用 + 运算符来连接可能会导致问题。例如:
vntvar1 = "10.01"
vntvar2 = 11
vntresult = vntvar1 + vntvar2 vntresult = 21.01
vntresult = vntvar1 & vntvar2 vntresult = 10.0111
6. 当产生长字符串时,使用下划线连接字符产生多行代码,这样便于阅读或调试字符串。
当显示一个消息框 (msgbox) 或输入框 (inputbox),或产生一个 sql 字符串时,这一技术特别有用。例如:
dim msg as string
msg = "this is a paragraph that will be " _
& "in a message box. the text is" _
& " broken into several lines of code" _
& " in the source code, making it easier" _
& " for the programmer to read and debug."
msgbox msg
dim qry as string
qry = "select *" _
& " from titles" _
& " where [year published] > 1988"
titlesqry.sql = qry
7. 不要将类型转换的工作交给vb自动去做,而使用以下类型转换函数。
cbool(expression)
cbyte(expression)
ccur(expression)
cdate(expression)
cdbl(expression)
cdec(expression)
cint(expression)
clng(expression)
csng(expression)
cstr(expression)
cvar(expression)
val(expression)
8. 错误处理(编一个函数处理所有已知错误)
在main()函数或主窗体load过程中添加如下代码:
******************************************************
打开错误日志文件,在form_unload()中关闭
******************************************************
dim strexepath as string
if right(app.path, 1) = "/" then
strexepath = app.path
else
strexepath = app.path & "/"
end if
interrlogfilehandle = freefile()
open strexepath + "err.log" for append shared as interrlogfilehandle
在主窗体退出函数中添加如下代码:
******************************************************
关闭错误日志文件
******************************************************
close #interrlogfilehandle
在某个module中添加:
******************************************************
写入错误日志
******************************************************
public sub writeerrlogfile(byval strsub as string, byval strerr as string)
print #interrlogfilehandle, date, time, strsub, strerr
end sub
在每个过程或自定义的函数中,使用如下的系统错误捕获机制:
public function forexample(…………) as long
on error goto funcerror
forexample=true
………………………
………………………
exit function
funcerror:
forexample=false
writeerrlogfile " forexample ", "错误号:" & err.number & ",错误源:" & err.source & ",错误描述:" & err.description
msgbox "……… ", vbcritical
在此作内存资源回收工作
end function
9. 窗体布局
窗体内各个控件的布局,建议如下:
1、所有与窗体上、下、左、右四条边界相邻的控件与窗体的边缘相距120缇
2、各个控件之间的间距为:相关控件60缇,非相关控件120缇
3、按钮控件大小为高300缇,长〉=1200缇,这也是操作系统默认按钮的大小
4、各个控件的字体建议为宋体五号字
一、类型级单位的命名
1、类。
以Class声明的类,都必须以名词或名词短语命名,体现类的作用。如:
Class Indicator
当类是一个特性(Attribute)时,以Attribute结尾,当类是一个异常(Exception)时,以Exception结尾:
Class ColorSetException
Class CauseExceptionAttribute
当类只需有一个对象实例(全局对象,比如Application等),必须以Class结尾,如
Class ScreenClass
Class SystemClass
当类只用于作为其他类的基类,根据情况,以Base结尾:
MustInherit Class IndicatorBase
如果定义的类是一个窗体,那么名字的后面必须加后缀Form,如果是Web窗体,必须加后缀Page:
Class PrintForm : Inherits Form '* Windows窗体
Class StartPage : Inherits Page '* Web窗体
2、枚举和结构
同样必须以名词或名词短语命名。最好体现枚举或结构的特点,如:
Enum ColorButtons '以复数结尾,表明这是一个枚举
Structure CustomerInfoRecord '以Record结尾,表明这是一个结构体
3、委派类型
普通的委派类型以描述动作的名词命名,以体现委派类型实例的功能:
Delegate Sub DataSeeker (ByVal SeekString As String)
用于事件处理的委派类型,必须以EventHandler结尾,如:
Delegate Sub DataChangedEventHandler (ByVal Sender As Object, ByVal e As DataChangedEventArgs)
4、接口
与其他类型不同,接口必须要由I作为前缀,并用形容词命名,突出表现实现接口的类将具有什么能力:
Interface ISortable
5、模块
模块不是类型,他的名称除了必须以名词命名外,必须加以后缀Module:
Module SharedFunctionsModule
上述所有规则的共同特点是,每个组成名称的词语都必须是大写开头,禁止完全大写或小写的名称。
二、方法和属性的命名
1、方法
无论是函数还是子程序,方法都必须以动词或动词短语命名。无需区分函数和子程序,也无需指明返回类型。
Sub Open(ByVal CommandString As String)
Function SetCopyNumber(ByVal CopyNumber As Integer)
参数需要指明ByVal还是ByRef,这一点写起来会让程序边长,但非常必要。如果没有特别情况,都使用ByVal。参数的命名方法,参考后面“变量的命名方法”。需要重载的方法,一般不写Overloads,根据需要编写重载的方法。
2、属性
原则上,字段(Field)是不能公开的,要访问字段的值,一般使用属性。属性以简洁清晰的名词命名:
Property Concentration As Single
Property Customer As CustomerTypes
3、事件
事件是特殊的属性,只能在事件处理上下文中使用。命名的原则一般是动词或动词的分词,通过时态表明事件发生的时间:
Event Click As ClickEventHandler
Event ColorChanged As ColorChangedEventHangler
三、变量和常数
常数以表明常数意义的名词命名,一般不区分常数的类型:
Const DefaultConcentration As Single = 0.01
在严格要求的代码中,常数以c_开头,如c_DefaultConcentration,但最好不要用它,它会带来输入困难。
普通类型的变量,只要用有意义的名字命名即可,不可使用简称和无意义的名称诸如A,x1等,下面给出了良好的例子:
Dim Index As Integer
Dim NextMonthExpenditure As Decimal
Dim CustomerName As String
不能起太长的名字,应该尽量简洁,如下面的例子:
Dim VariableUsedToStoreSystemInformation As String '* 错误,太复杂了
Dim SystemInformation As String '* 正确,简单明了
Dim sysInfo As String '* 错误,过于简单
特殊情况可以考虑一个字母的变量:
Dim g As Graphic
对于控件,应该指明控件的类型,方法是直接在变量后面加以类名:
Friend WithEvents NextPageButton As Button '* 按钮
Friend WithEvents ColorChoicerPanel As Panel '* 面版
Friend WithEvents CardFileOpenDialog As FileOpenDialog '* 文件打开对话框
等等,无需规定某种类型的变量的前缀,只需把类型写在后面就行了,试对比下列代码:
btnCancel.Text = "&Cancel"
CancelButton.Text = "&Cancel"
显然后者更能使阅读者明白变量的类型是一个按钮。
四、标签
标签就是用于Goto跳转的代码标识,由于Goto并不推荐使用,所以标签的使用也比较苛刻。标签必须全部大写,中间的空格用下划线_代替,而且应该以_开头,比如:
_A_LABEL_EXAMPLE:
如此定义标签是为了与其他代码元素充分区别。
五、名字空间
通常,一个工程使用一个名字空间,通常不需要用Namespace语句,而是在工程选项的“Root Namespace”中指定,使用根名字空间可以使代码更加整齐,容易修改,这一点是VB十足的优点。名字空间的语法是:
公司名.产品名[.组件名的复数]
如:
Namespace Ninputer.VirtualScreen
Namespace Ninputer.CardEditor.CustomeControls
随便起一个名字空间的名字绝对不是一个好主意,一定要遵守上述规定。
六、注释
注释的规则繁多,这里仅提到其中一点:正常的注释以'*开头,单独的'只用来注释暂时不用的代码
'* 这是普通的注释
'* 这段代码在调试正确后加入
'If UseHighSpeed(g) = True Then ....
这样能够方便的采用代码注释工具控制代码的使用。
以上已经简单的介绍了个人使用的VB.net代码规范,这个代码规范也适用于C#。仅供大家参考。