为了巩固本章所学,安排了3个与函数有关的示例,给出了Excel VBA和Python两个版本的代码。
函数示例1-计算圆环的面积
图10-2所示工作表中第3列和第4列为各圆环的外半径和内半径数据,现利用数据计算各圆环的面积。计算圆环面积的公式为:S=pi*(R*R-r*r),其中,pi为圆周率,R和r为圆环的外半径和内半径,计算公式返回圆环面积S。
图10-2 计算圆环的面积
计算各圆环的面积之前,先将计算面积的公式写成函数,这样对每个圆环进行计算时,可以重复调用该函数计算面积。
【Excel VBA】
示例文件的存放路径为Samples\ch10\Excel VBA\计算圆环的面积.xlsm。
Function CircleArea(dblR1 As Double, dblR2 As Double) As Double
'计算圆环的面积
'dblR1为外半径,dblR2为内半径
CircleArea = 3.1416 * (dblR1 * dblR1 - dblR2 * dblR2)
End Function
Sub Test()
Dim intI As Integer
Dim intR As Integer '数据最大行号
Dim intL As Integer, intU As Integer
Dim dblR1(), dblR2(), dblArea() '外半径,内半径,面积
Dim sht As Object
Set sht = ActiveSheet
intR = sht.Range("C2").End(xlDown).Row
'获取数据,转换为一维数组
dblR1 = sht.Range("C3:C" & CStr(intR)).Value
dblR1 = Application.WorksheetFunction.Transpose(dblR1)
dblR2 = sht.Range("D3:D" & CStr(intR)).Value
dblR2 = Application.WorksheetFunction.Transpose(dblR2)
intL = LBound(dblR1)
intU = UBound(dblR1)
ReDim dblArea(intL To intU)
'调用函数计算各圆环面积
For intI = intL To intU
dblArea(intI) = CircleArea(CDbl(dblR1(intI)), CDbl(dblR2(intI)))
Next
'输出
sht.Range("E3").Resize(intU - intL + 1, 1).Value = _
Application.WorksheetFunction.Transpose(dblArea)
End Sub
运行程序,在工作表中E列输出各圆环的面积。
【Python】
本示例的数据文件存放路径为Samples\ch10\Python\计算圆环的面积.xlsx,py文件保存在相同目录下,文件名为sam10-01.py。
def circle_area(r1,r2):
#计算圆环的面积
#r1为外半径,r2为内半径
return 3.1416*(r1*r1-r2*r2)
import xlwings as xw #导入xlwings包
#从constants类中导入Direction
from xlwings.constants import Direction
import os #导入os包
#获取本py文件的当前路径
root = os.getcwd()
#创建Excel应用,可见,没有工作簿
app=xw.App(visible=True, add_book=False)
#打开数据文件,可写
bk=app.books.open(fullname=root+\
r'\计算圆环的面积.xlsx',read_only=False)
sht=bk.sheets(1) #获取第1个工作表
#工作表中第3列数据最大行号
row_num=sht.api.Range('C2').End(Direction.xlDown).Row
areas=[]
#调用函数计算各圆环的面积,结果添加到列表中
for i in range(row_num-2):
areas.append(circle_area(sht.cells(i+3,3).value,sht.cells(i+3,4).value))
#输出结果
sht.range('E3').options(transpose=True).value=areas
运行脚本,在工作表中E列输出各圆环的面积。
函数示例2-递归计算阶乘
图10-3所示工作表中第3列给出了整数1到10,现在希望计算它们各自对应的阶乘,输出在第4列。
图10-3 计算给定整数的阶乘
计算之前,需要构造一个计算指定整数阶乘的函数。整数n的阶乘n!可以看作n与n-1的阶乘的乘积,即n*(n-1)!,而n-1的阶乘又可以看作n-1与n-2的阶乘的乘积,即(n-1)*(n-2)!,如此可以用递归算法进行计算。
【Excel VBA】
首先构造递归函数Factorial,然后遍历C列每个整数,调用该函数计算阶乘。示例文件的存放路径为Samples\ch10\Excel VBA\递归计算阶乘.xlsm。
Function Factorial(lngN As Long) As Long
'用递归求lngN的阶乘
If lngN > 1 And lngN <= 20 Then
Factorial = lngN * Factorial(lngN - 1)
Else
Factorial = 1
End If
End Function
Sub Test()
Dim intI As Integer
Dim intR As Integer '数据最大行号
Dim intL As Integer, intU As Integer
Dim lngN(), lngV() '给定的数字及其阶乘
Dim sht As Object
Set sht = ActiveSheet
intR = sht.Range("C2").End(xlDown).Row
'获取数据,转换为一维数组
lngN = sht.Range("C2:C" & CStr(intR)).Value
lngN = Application.WorksheetFunction.Transpose(lngN)
intL = LBound(lngN)
intU = UBound(lngN)
ReDim lngV(intL To intU)
'调用函数求阶乘
For intI = intL To intU
lngV(intI) = Factorial(CLng(lngN(intI)))
Next
'输出
sht.Range("D2").Resize(intU - intL + 1, 1).Value = _
Application.WorksheetFunction.Transpose(lngV)
End Sub
运行程序,在工作表D列输出各整数的阶乘。
【Python】
首先构造递归函数factorial,然后遍历C列每个整数,调用该函数计算阶乘。本示例的数据文件存放路径为Samples\ch10\Python\递归计算阶乘.xlsx,py文件保存在相同目录下,文件名为sam10-02.py。
def factorial(n):
#计算整数n的阶乘
if n==1:return 1
return n*factorial(n-1)
import xlwings as xw #导入xlwings包
#从constants类中导入Direction
from xlwings.constants import Direction
import os #导入os包
#获取本py文件的当前路径
root = os.getcwd()
#创建Excel应用,可见,没有工作簿
app=xw.App(visible=True, add_book=False)
#打开数据文件,可写
bk=app.books.open(fullname=root+\
r'\递归计算阶乘.xlsx',read_only=False)
sht=bk.sheets(1) #获取第1个工作表
#工作表中第3列数据最大行号
row_num=sht.api.Range('C2').End(Direction.xlDown).Row
lst=[]
#调用函数计算各整数的阶乘,结果添加到列表中
for i in range(row_num-1):
lst.append(factorial(sht.cells(i+2,3).value))
#输出结果
sht.range('D2').options(transpose=True).value=lst
运行脚本,在工作表D列输出各整数的阶乘。
函数示例3-删除字符串中的数字
图10-4所示工作表中第3列给出了一些由字母和数字组成的字符串,现在希望删除这些字符串中的数字。
图10-4 删除字符串中的数字
处理这些字符串之前,先构造一个删除字符串中数字的函数。数字的ASCII码为48-57,遍历字符串中的每个字符,获取当前字符的ASCII码,如果它落在48-57的范围内,就去掉它,否则保留。
【Excel VBA】
首先构造去除字符串中数字的函数DelNumers,然后遍历C列每个字符串,重复调用DelNumers函数进行处理。Excel VBA中用Asc函数获取字符的ASCII码。示例文件的存放路径为Samples\ch10\Excel VBA\删除字符串中的数字.xlsm。
Function DelNumers(strOri As String)
Dim strChar As String
Dim strTemp As String
Dim intI As Integer
strTemp = ""
'变量字符串中的每个字符
For intI = 1 To Len(strOri)
strChar = Mid(strOri, intI, 1)
'数字的ASCII码48-57
'如果不在这个范围内,添加字符;否则忽略
If Asc(strChar) < 48 Or Asc(strChar) > 57 Then
strTemp = strTemp & strChar
End If
Next
DelNumers = strTemp
End Function
Sub Test()
Dim intI As Integer
Dim intR As Integer
Dim intL As Integer, intU As Integer
Dim strV(), strR()
Dim sht As Object
Set sht = ActiveSheet
intR = sht.Range("C2").End(xlDown).Row
'获取数据,转换为一维数组
strV = sht.Range("C3:C" & CStr(intR)).Value
strV = Application.WorksheetFunction.Transpose(strV)
intL = LBound(strV)
intU = UBound(strV)
ReDim strR(intL To intU)
'调用函数去除数字
For intI = intL To intU
strR(intI) = DelNumers(CStr(strV(intI)))
Next
'输出
sht.Range("D3").Resize(intU - intL + 1, 1).Value = _
Application.WorksheetFunction.Transpose(strR)
End Sub
运行程序,在工作表D列输出去除数字后的字符串。
【Python】
首先构造去除字符串中数字的函数del_numbers,然后遍历C列每个字符串,重复调用del_numbers函数进行处理。Python中用ord函数获取字符的ASCII码。本示例的数据文件存放路径为Samples\ch10\Python\删除字符串中的数字.xlsx,py文件保存在相同目录下,文件名为sam10-03.py。
def del_numbers(st):
#从给定字符串中去除数字
st0=''
#遍历字符串中的每个字符
for i in range(len(st)):
#数字的ASCII码48-57
#如果不在这个范围内,添加字符;否则忽略
if ord(st[i])<48 or ord(st[i])>57:
st0=st0+st[i]
return st0
import xlwings as xw #导入xlwings包
#从constants类中导入Direction
from xlwings.constants import Direction
import os #导入os包
#获取本py文件的当前路径
root = os.getcwd()
#创建Excel应用,可见,没有工作簿
app=xw.App(visible=True, add_book=False)
#打开数据文件,可写
bk=app.books.open(fullname=root+\
r'\删除字符串中的数字.xlsx',read_only=False)
sht=bk.sheets(1) #获取第1个工作表
#工作表中第3列数据最大行号
row_num=sht.api.Range('C3').End(Direction.xlDown).Row
lst=[]
#调用函数计算各整数的阶乘,结果添加到列表中
for i in range(row_num-2):
lst.append(del_numbers(sht.cells(i+3,3).value))
#输出结果
sht.range('D3').options(transpose=True).value=lst
运行脚本,在工作表D列输出去除数字后的字符串。