用VB.NET(Visual Basic 2010)封装EXCEL VBA为DLL_COM组件(二)

——将EXCEL VBA代码移植到VB.NET

.NET是微软公司在2002年推出的全新编程框架,支持多种语言应用程序开发。使用Visual Basic在Microsoft .NET Framework上编程,这就是Visual Basic.NET,简称VB.NET。

VB.NET是Microsoft Visual Studio .NET组件中的重要组成部分,是VB6.0的后续版本,VB.NET仍使用VB的基本语法,二者几乎在90%以上保持相似或相同,虽然Excel VBA代码不能完全像移植到VB6.0那样直接移植到Visual Basic 2010,但大多数情况下,移植还是相当简单的。

一、Excel程序的对象模型。

在 Excel 中,Excel 程序对象(Application)是顶级的对象,往下依次是工作簿对象(Workbook)、工作表对象(Worksheet)和单元格对象(Range)。只有当打开了 Excel 程序(Appliation 对象),才能创建或打开工作簿(Workbook 对象),才能选中某个工作表(Worksheet 对象),以及对某个单元格区域(Range 对象)进行操作。

众多个工作簿,若干张工作表,数不清的单元格,要在“Book1”工作簿中的“Sheet1”工作表中的“A1”单元格内录入内容“A1”,必须像叙述家庭住址一样把各个需引用的对象关系从大到小的顺序叙述清楚。如下代码:

1 Sub Rng2()
2  Application.Workbooks("Book1.xls").Worksheets("Sheet1").Range("A1").Value = "A1"
3 End Sub

Application对象代表Excel程序,属于最顶层对象,通常可以省略,上述代码亦可修改为:

1 Sub Rng3()
2  Workbooks("Book1.xls").Worksheets("Sheet1").Range("A1").Value = "A1"
3 End Sub

在 Excel VBA 中,引用或操作对象时允许省略其上级对象,但并非表示该对象的上一级的对象不存在。

二、Visual Basic.NET编写处理Excel表格代码(即代码移植)

1、声明对象变量时需要前置“Excel”,例如:

Dim VbApp As Excel.Application '定义Excel对象

Dim VbBook As Excel.Workbook '定义工作簿对象

Dim VbSht As Excel.Worksheet '定义工作表对象

Dim VbRng As Excel.Range '定义单元格对象

2、不能直接使用“Application”(即Excel.exe进程),而需要一个变量调用。

首先在模块中声明一个变量VbApp:

Public VbApp As Excel.Application '定义Excel对象

然后对变量VbApp赋值:

(1)、引用Excel.exe进程

通在Excel中引用DLL动态链接库Excel程序都是已经打开了的,即通过任务管理器查看进程可以看到Excel.exe进程,我们需要处理已打开Excel文档,必须引用当前Excel.exe进程。代码如下:

VbApp = GetObject(, "Excel.Application") '引用当前Excel.exe进程,确保已打开Excel程序否则报错

(2)、创建Excel.exe进程

通过下列语句就可以创建新的Excel.exe进程了,Visual Basic .Net可以通过对此进程的处理来操作Excel表格:

VbApp = New Excel.Application '创建新的Excel.exe进程

在后续的应用中可调用变量VbApp来代替“Application”,如:

当执行完创建一个新的Excel.exe进程语句后,通过任务管理器查看进程就发现多出Excel.exe进程,当此时Excel程序的运行界面并没有显示,在此语句后加入以下代码,Excel的运行界面就显示出来了:

VbApp.Visible = True '显示Excel程序的运行界面

Excel运行界面虽然显示,但其中并没有表格,下列代码是在Excel程序中创建一个新表格:

VbApp.Workbooks.Add

3、所有对象必须显示声明,表示它是Excel的对象。

在 Excel VBA 中,引用或操作对象时允许省略其上级对象,但把代码移植到VB.NET中,我们必须使用完整的表达式精确表示某个对象。例如:

Visual Basic .Net处理Excel表格是通过引用(或创建)的Excel.exe进程来实现的。引用(或创建)的Excel.exe进程对应上述代码中的VbApp,即变量VbApp代表Excel 程序对象(Application)。下面代码给工作簿Book1.xls的第1张工作表的“A1”单元格赋值“A1”:

VbApp. BookExcel.Worksheets("Book1.xls").Range("A1").Value = "A1"

当编辑完Excel表格后,可以通过下列语句就关闭Excel表格,并销毁Excel.exe进程:

VbApp. BookExcel.Close ( )'关闭Excel表格

VbApp.Quit ( )'销毁Excel.exe进程

VbApp = Nothing '释放对象变量

可见,我们在Excel编写VBA代码时严格使用完整的表达式精确表示对象,移植代码时使用变量VbApp来调用“Application”,即可。

三、VBA与VB.NET语法变通

随着VB.NET的引入,VB迎来了自发布以来最大的变革,整个运行库模型变成了一个新的公共语言运行库(CLR)环境,语言也从基于对象变成面向对象,对熟悉Excel VBA的程序员移植封装代码带来了困难。不仅需要掌握VB.NET语法,还需要理解并运用VB.NET提出的新功能、概念和观点。当然也需要掌握.Net框架,理解CLR(Common Language Runtime,通用语言进行时)。在移植代码时要特别以下语法变化。

1、数据类型

用于存储任意类型数据的数据类型Variant被Object替代;用于存储大浮点数的数据类型Currency被Decimal替代,并支持更高数度;在VBA中可以在声明字符 串时指定其长度,而VB.NET不支持固定长度字符串。

2、变量赋值

在VBA中不能同时声明和初始化变量,而VB.NET则支持声明的同时初始化变量。例如:

Dim StrName As String

StrName = "VBA封装"

在VB.NET中可以二合一:

Dim StrName As String = "VBA封装"

在VBA中对对象变量赋值必须使用Set语句,而在VB.NET中已取消Set语句,也就是说对象变量的赋值与普通变量一样。如:

ExcelVBA初始化对象变量: Set Rng=Nothing 

而在VB.NET中不需要Set语句: Rng=Nothing 

3、数组

VBA数组下界可以自定义,如以下语句声明了下界为1、上界为10共10个元素的数组Arr:

Dim Arr(1 To 10) As String

而在VB.NET中,数组下界总是从0开始,若使用Dim Arr(1 To 10) As String声明数组将会报错。

在VBA中,可以指定数组的长度,如:

Dim Arr(2) As Integer

这里的Arr数组长度是固定的,不能用ReDim语句改变长度。VB.NET不支持固定长度数组,所以ReDim总是有效。

在VBA中,ReDim用于初始化动态数组,而在VB.NET中,ReDim关键字的使用略有变化,第一个变化是:必须先定义该数组实例,不能用ReDim语句声明数组;第二个变化是:ReDim只能用于改变数组长度,不能改变数组的维数。在VB.NET中动态数组声明时特别注意,如:

Dim Arr() As Integer '声明一维动态数组

上面的声明只能创建一个一维动态数组,若要声明一个二维动态数组,上述声明应包含一个逗号,如:

Dim Arr(,) As Integer '声明二维动态数组

4、变量作用域

在VBA中,变量作用域有:过程级、模块级和全局。在VB.NET中新增了块作用域,也称为结构作用域。

结构是由两条语句而不是一条语句组成的编码结构,如If…Then决策结构、For…Next循环结构。在VB.NET中,如果变量是在结构中声明的,则其作用域限定在结构内,该变量在遇到相应的Dim语句后才被创建,在结构结束处被销毁。如:

1 If Flag = True Then
2 
3     Dim IntNum As Integer
4 
5 End If

5、循环语句

VB.NET增加了Continue关键字,使用Continue For语句,在For…Next循环结构中能够在到达Next语句之前进入下一次For…Next循环;当然也可以使用Continue Do语句,在Do…Loop循环结构中能够在到达Loop语句之前进入下一次Do…Loop循环。

以上语法变化是必必须掌握的,当然我们还需要逐渐掌握一些新旧语法替代,如:虽VB.NET还支持数据类型转换函数,但在VB.NET应力争避免使用,处理数据类型转换的更通用方法是使用System.Convert类;Excel VBA是通过On Error语句来处理错误,这种处理方法在VB.NET中仍得到支持,但已被摒弃,强烈建议使用Try…Catch…Finally结构来处理异常(错误);VB.NET仍支持老式MsgBox()函数,但不建议使用,而是改用MessageBox.Show()函数。

以上介绍并不能使读者了解VB.NET语法的方方面面,如果想进一步了解必须阅读一些专业书籍。如:

《Visual Basic 2010入门经典(中文版)》——[美] James Foxall 著、梅兴文 译、人民邮电出版社。

《Visual Basic 2010 & .NET 4 高级编程(第6版)》——(美) Billy Hollis 等著、彭珲 余科洋 译、清华大学出版社。

posted @ 2017-04-02 15:38  自游假期  阅读(6066)  评论(0编辑  收藏  举报