最近做了很多表,决定看一下VBA,下面的文章不错,贴下来,方便以后查找

原文地址:

http://blog.csdn.net/sunxing007/archive/2010/06/09/5658384.aspx

 vba excel编程三日谈(1)

 

 

准备工作

 

vba是一种寄宿语言,像javascript生存在浏览器中一样,vba生存在office应用程序中。所以请确保你安装了office,本人学习的时候采用的office2007, 版本差异会引起一些问题, 但是office2003和office2007的差异不是很大。

 

新建一个excel文档test.xls, 按alt+F11进入vba编程界面。双击左面的thisWorkbook,在右边输入:

 

Private Sub Workbook_Open()

    MsgBox "Hello, world"

End Sub

 

 

 

保存并退出excel,然后重新打开该excel,则会看到弹出的消息Hello,world。 如果遇到macro安全警告,请enable。这就是第一个vba程序,Workbook_Open是对事件open的响应函数(关于事件在后面会有更多介绍)。

 

当然你可以把代码写在任何一个sheet里面,也可以就地运行,调试。双击sheet1,在右边输入:

 

Sub test()

    MsgBox "Hello, world"

End Sub

 

然后把光标移到函数名test上,点击工具栏上的绿色的箭头即可运行测试该函数。

 

我们还可以在excel的工作表上添加一个控件(比如按钮),通过点击控件来执行函数。把菜单切换到Developer标签,如下图点击Insert即可选择插入的控件(如果是office2003则在菜单试图->工具栏->控件工具箱)

 

 

 

点击按钮,在工作表的任意位置画一个按钮,同时在选择框中点击你刚编写的函数test,保存。 此时点击按钮即可触发该函数。

 

当然你还可以录制宏, 这也是学习vba的好方法。在这里不做介绍。

 

OK, 至此,我们学会在怎么定义一个过程(函数), 然后怎么触发运行它(通过事件,通过vba运行调试,通过按钮),准备工作到此结束。

 

vba excel对象模型

 

类似javascript中的dom模型, windows编程中的组件对象模型, vba也有自己的对象模型. excel的模型中的对象有很多(自己可以google一下), 但是经常用到的无非这四五个:application -> workbooks -> worksheets -> range ->cells. application处于最顶上,表示正在运行的程序(Excel)本身. workbook工作薄, 即一个excel文件单元, 对应着一个xls文件. worksheet是工作表, 新建一个workbook里面默认包含了3个worksheet; range表示工作表中的一块区域, 比如Range("A1:D10")表示A1:D10之间的那块区域, 一个range包含多个Cell,一个cell即worksheet中的一个小格子. 新建一个文件1.xls,并在sheet1的A1单元格中随便输入内容, 下面的程序将更清楚的表明它们之间的关系. 继续在刚才的test.xls的sheet1的代码区中输入如下代码:

 

view plaincopy to clipboardprint?

Sub test()   

    '去读本文件的单元格的内容   

    MsgBox Application.Workbooks("test.xls").Worksheets("Sheet1").Range("A1").Value   

    '如果是当前的application,则application可以省略   

    MsgBox Workbooks("test.xls").Worksheets("Sheet1").Range("A1").Value   

    '如果是当前workbooks,则workbooks可以省略   

    MsgBox Worksheets("Sheet1").Range("A1").Value   

    '如果是当前的sheet,则worksheet可以省略   

    MsgBox Range("A1").Value   

    '还可以这么用   

    MsgBox Sheets("Sheet1").Range("A1").Value   

    'ActiveWorkbook代表当前活动的workbook   

    '这样就更直接了   

     MsgBox Cells(1,1).Value   

    '也可以改写cell的value   

    Cells(1,1).value = "我在学vba"  

    MsgBox ActiveWorkbook.Worksheets(1).Range("A1").Value   

    '还可以这么用   

    MsgBox ThisWorkbook.Worksheets(1).Range("A1").Value   

    '也可读取外部xls文件的内容   

    MsgBox Application.Workbooks("1.xls").Worksheets("Sheet1").Range("A1").Value   

    '也可以通过下标应用对象   

    MsgBox Application.Workbooks(2).Worksheets(1).Range("A1").Value   

End Sub  

Sub test()

    '去读本文件的单元格的内容

    MsgBox Application.Workbooks("test.xls").Worksheets("Sheet1").Range("A1").Value

    '如果是当前的application,则application可以省略

    MsgBox Workbooks("test.xls").Worksheets("Sheet1").Range("A1").Value

    '如果是当前workbooks,则workbooks可以省略

    MsgBox Worksheets("Sheet1").Range("A1").Value

    '如果是当前的sheet,则worksheet可以省略

    MsgBox Range("A1").Value

    '还可以这么用

    MsgBox Sheets("Sheet1").Range("A1").Value

    'ActiveWorkbook代表当前活动的workbook

    '这样就更直接了

     MsgBox Cells(1,1).Value

    '也可以改写cell的value

    Cells(1,1).value = "我在学vba"

    MsgBox ActiveWorkbook.Worksheets(1).Range("A1").Value

    '还可以这么用

    MsgBox ThisWorkbook.Worksheets(1).Range("A1").Value

    '也可读取外部xls文件的内容

    MsgBox Application.Workbooks("1.xls").Worksheets("Sheet1").Range("A1").Value

    '也可以通过下标应用对象

    MsgBox Application.Workbooks(2).Worksheets(1).Range("A1").Value

End Sub 

 

当然每个对象都有很多属性和方法可以使用.如例:

 

view plaincopy to clipboardprint?

Sub test1()   

    MsgBox Application.Name   

    MsgBox Application.Workbooks(2).Name   

    MsgBox Worksheets.Count   

       

    MsgBox "There are " & CStr(Range("A1:D10").Cells.Count) & " Cells"  

       

    Sheets(2).Select  

    ActiveSheet.Cells(1, 1).Value = "This is the first cell in Sheet2"  

    Range("A2").Font.FontStyle = "Bold"  

    Range("A2").Font.Size = 13   

    Range("A3").Borders.LineStyle = xlContinuous   

    Range("A3").Borders.Weight = xlThin   

End Sub  

Sub test1()

    MsgBox Application.Name

    MsgBox Application.Workbooks(2).Name

    MsgBox Worksheets.Count

    

    MsgBox "There are " & CStr(Range("A1:D10").Cells.Count) & " Cells"

    

    Sheets(2).Select

    ActiveSheet.Cells(1, 1).Value = "This is the first cell in Sheet2"

    Range("A2").Font.FontStyle = "Bold"

    Range("A2").Font.Size = 13

    Range("A3").Borders.LineStyle = xlContinuous

    Range("A3").Borders.Weight = xlThin

End Sub

 

 

这么多方法和属性记不住怎么办? 没关系,有自动语法提示: 菜单->tools->options 勾选auto list members.

 

 

 

关于对象模型就说这么多, 记不住或不了解的, 可通过录制宏, 自动代码提示, google等渠道获得.

 

基础语法

 

数据类型和定义变量

 

vba的基础数据类型有byte boolean integer long single double currency decimal date...长度精度上有所差别.

 

如下展示基本数据类型的定义和使用, 其中要注意的是Date类型的赋值比较特殊, 要用##包含起来, 常用类型还有更简单的定义方式:

 

常用类型说明符

% integer

& long

! single

# Double

$ string

@ currency

 

view plaincopy to clipboardprint?

Sub test1()   

    Dim i As Integer, j As Integer  

    Dim s As String  

    i = 2   

    j = 3   

    MsgBox i + j   

    s = "The result is: " & (i + j)   

    MsgBox s   

    Dim d As Date  

    d = #12/12/2002 3:23:00 AM#   

    MsgBox d   

    Dim k%, l&   

    k = 5   

    l = 6   

    MsgBox k + l   

    Dim m As Currency   

    m = 123.456   

    MsgBox m   

End Sub  

Sub test1()

    Dim i As Integer, j As Integer

    Dim s As String

    i = 2

    j = 3

    MsgBox i + j

    s = "The result is: " & (i + j)

    MsgBox s

    Dim d As Date

    d = #12/12/2002 3:23:00 AM#

    MsgBox d

    Dim k%, l&

    k = 5

    l = 6

    MsgBox k + l

    Dim m As Currency

    m = 123.456

    MsgBox m

End Sub

 

 

如果定义的变量是对象类型, 比如WorkSheet, 则要用set来赋值.

 

view plaincopy to clipboardprint?

Sub test1()   

    Dim sh As Worksheet   

    Set sh = ActiveWorkbook.Sheets(1)   

    MsgBox sh.Cells(1, 1).Value   

End Sub  

Sub test1()

    Dim sh As Worksheet

    Set sh = ActiveWorkbook.Sheets(1)

    MsgBox sh.Cells(1, 1).Value

End Sub 

 

定义和使用数组: 

 

view plaincopy to clipboardprint?

Sub test6()   

    Dim myarr(3) As Integer  

    myarr(1) = 3   

    myarr(2) = 4   

    myarr(3) = 5   

    MsgBox myarr(1) + myarr(2)   

End Sub  

Sub test6()

    Dim myarr(3) As Integer

    myarr(1) = 3

    myarr(2) = 4

    myarr(3) = 5

    MsgBox myarr(1) + myarr(2)

End Sub 

 

过程&函数

 

通过sub subname(param1, param2 ...) ...... end sub 可定义过程, 也可定义function,function和sub的区别是function有返回值.其他都一样, 在这里就不讨论function了. 

 

一个过程可以调用其他过程.

 

view plaincopy to clipboardprint?

Sub test1()   

    MsgBox Application.Name   

    MsgBox Worksheets.Count   

    ActiveSheet.Cells(1, 1).Value = "This is the first cell in Sheet2"  

End Sub  

  

Sub test2()   

    test1   

    'inputBox 是一个系统过程   

     Dim name As String  

    name = InputBox("Please input your name: ")   

    MsgBox "Your name is :" & name   

End Sub  

Sub test1()

    MsgBox Application.Name

    MsgBox Worksheets.Count

    ActiveSheet.Cells(1, 1).Value = "This is the first cell in Sheet2"

End Sub

 

Sub test2()

    test1

    'inputBox 是一个系统过程

     Dim name As String

    name = InputBox("Please input your name: ")

    MsgBox "Your name is :" & name

End Sub 

 

过程可以带参数, 传参数的方式有两种, 传值和传引用. 凡是有编程基础的人都应该明白这两种方式的区别.

 

view plaincopy to clipboardprint?

'传引用调用   

Sub test2()   

    Dim i As Integer  

    i = 123   

    test3 i   

    MsgBox i   

End Sub  

  

Sub test3(ByRef i As Integer)   

    i = 321   

    MsgBox i   

End Sub  

  

'传值调用   

Sub test4()   

    Dim i As Integer  

    i = 123   

    test5 i   

    MsgBox i   

End Sub  

Sub test5(ByVal i As Integer)   

    i = 321   

    MsgBox i   

End Sub  

'传引用调用

Sub test2()

    Dim i As Integer

    i = 123

    test3 i

    MsgBox i

End Sub

 

Sub test3(ByRef i As Integer)

    i = 321

    MsgBox i

End Sub

 

'传值调用

Sub test4()

    Dim i As Integer

    i = 123

    test5 i

    MsgBox i

End Sub

Sub test5(ByVal i As Integer)

    i = 321

    MsgBox i

End Sub

 

 

流程控制

 

if语句:

 

view plaincopy to clipboardprint?

Sub testif()   

    Dim i&   

    i = InputBox("Please input your score:", "Score", 60)   

    If i > 90 Then  

            MsgBox "Your credit is A"  

        ElseIf i > 80 Then  

            MsgBox "Your credit is B"  

        ElseIf i > 70 Then  

            MsgBox "Your credit is C"  

        ElseIf i > 60 Then  

            MsgBox "Your credit is D"  

        Else  

            MsgBox "Your credit is E"  

    End If  

End Sub  

Sub testif()

    Dim i&

    i = InputBox("Please input your score:", "Score", 60)

    If i > 90 Then

            MsgBox "Your credit is A"

        ElseIf i > 80 Then

            MsgBox "Your credit is B"

        ElseIf i > 70 Then

            MsgBox "Your credit is C"

        ElseIf i > 60 Then

            MsgBox "Your credit is D"

        Else

            MsgBox "Your credit is E"

    End If

End Sub 

 

select case 语句:

 

view plaincopy to clipboardprint?

Sub testselectcase()   

    Sheets("Sheet3").Select  

    Select Case ActiveSheet.Cells(1, 1).Value   

        Case Is < 60   

            MsgBox "bad"  

        Case Is < 70   

            MsgBox "So so"  

        Case Is < 80   

            MsgBox "good"  

        Case Is < 90   

            MsgBox "very good"  

        Case Else  

            MsgBox "excellent"  

    End Select  

End Sub  

Sub testselectcase()

    Sheets("Sheet3").Select

    Select Case ActiveSheet.Cells(1, 1).Value

        Case Is < 60

            MsgBox "bad"

        Case Is < 70

            MsgBox "So so"

        Case Is < 80

            MsgBox "good"

        Case Is < 90

            MsgBox "very good"

        Case Else

            MsgBox "excellent"

    End Select

End Sub

 

 

循环控制:

 

view plaincopy to clipboardprint?

Sub testfor1()   

    Dim i&, total&   

    total = 0   

    For i = 1 To 1000 Step 1   

        total = total + i   

    Next  

    MsgBox "total: " & CStr(total)   

    total = 0   

    For i = 1000 To 1 Step -2   

        total = total + i   

    Next  

    MsgBox "total: " & CStr(total)   

End Sub  

  

Sub testfor2()   

 Dim sh As Worksheet   

 For Each sh In ActiveWorkbook.Worksheets   

    MsgBox sh.Name   

 Next  

End Sub  

  

Sub testdowhile()   

    Dim i&, total&   

    i = 1000   

    total = 0   

    Do While i > 0   

        total = total + i   

        i = i - 1   

    Loop  

    MsgBox total   

End Sub  

  

  

Sub testdountil()   

    Dim i&, total&   

    i = 1000   

    total = 0   

    Do  

        total = total + i   

        i = i - 1   

    Loop Until i < 0   

    MsgBox total   

End Sub  

Sub testfor1()

    Dim i&, total&

    total = 0

    For i = 1 To 1000 Step 1

        total = total + i

    Next

    MsgBox "total: " & CStr(total)

    total = 0

    For i = 1000 To 1 Step -2

        total = total + i

    Next

    MsgBox "total: " & CStr(total)

End Sub

 

Sub testfor2()

 Dim sh As Worksheet

 For Each sh In ActiveWorkbook.Worksheets

    MsgBox sh.Name

 Next

End Sub

 

Sub testdowhile()

    Dim i&, total&

    i = 1000

    total = 0

    Do While i > 0

        total = total + i

        i = i - 1

    Loop

    MsgBox total

End Sub

 

 

Sub testdountil()

    Dim i&, total&

    i = 1000

    total = 0

    Do

        total = total + i

        i = i - 1

    Loop Until i < 0

    MsgBox total

End Sub

 

 

最后说一下vba的with语法和语句换行. with语法是为了减轻程序输入负担, 在with范围类, 默认的当前对象就是with指定的对象, 如下程序 with指定了font, 则下面的.Name .FontStyle等都是指Range("A1").font的成员:

 

view plaincopy to clipboardprint?

Public Sub testwith()   

    With Range("A1").Font   

        .Name = "华文彩云"  

        .FontStyle = "Bold"  

        .Size = 18   

        .ColorIndex = 3   

        .Underline = 2   

    End With   

End Sub  

Public Sub testwith()

    With Range("A1").Font

        .Name = "华文彩云"

        .FontStyle = "Bold"

        .Size = 18

        .ColorIndex = 3

        .Underline = 2

    End With

End Sub

 

 

vba程序的基本单元是行, 如果要换行, 需用符号"_"来处理:

 

view plaincopy to clipboardprint?

Sub test7()   

    Dim s As String  

    s = "12345" & _   

    "67890"  

    MsgBox s   

    MsgBox ActiveWorkbook.Worksheets(1) _   

    .Range("A1").Value   

End Sub  

Sub test7()

    Dim s As String

    s = "12345" & _

    "67890"

    MsgBox s

    MsgBox ActiveWorkbook.Worksheets(1) _

    .Range("A1").Value

End Sub 

 

ok, 太累了,这篇就写到这儿.