在 Excel 中编写自定义函数——返回多个值
2008-07-11 16:50
363 查看
前面讲了自定义函数的基本框架和如何传递不定参数,这一篇讲如何返回多个值。返回多个值,基本上就可以理解为返回数组。我们自定义的返回数组的函数,跟 Excel 自带的数组函数一样,需要按 Ctrl+Shift+Enter 输入。
在返回数组这件事上,我们需要决定返回的数组的维度。有下面几种情况:
第一种情况,返回一个大小固定的数组。
这个函数返回一个 3x4 大小的数组,值从 1 到 12。但是这个函数并没有什么应用价值,我们的返回值还是应该根据传入的参数或者输入函数的单元格范围的大小来变化。
第二种情况,根据输入函数的单元格范围大小来变化。也就是说,如果选了 A1:B2 这样 2x2 的范围来输入我们自定义的函数,我们返回的数组就是 2x2 大小;如果选了 C3:E8 这样 6x3 的范围来输入我们自定义的函数,我们返回的数组就是 6x3 大小。要获得输入函数的单元格范围的大小,我们可以用Application.Caller 这个属性。当我们从表单单元格里调用函数时,Application.Caller 属性返回的是一个 Range 对象引用,表示输入该函数的单元格范围。
第三种情况,结合传入的参数和函数的目的来决定返回数组的维度。像我前一篇文章里的 MySum 函数,传入的虽然是个参数数组,但返回唯一的值。我这里举的一个例子,返回的数组大小根据传入的参数范围而变化。这个自定义函数是用来排序的,比如对员工年龄,学生分数等等。期望的参数是至少两列的单元格范围,参数的第一列是标识符,比如姓名,工号等等,参数的最后一列是要排序的数值。返回的数组为两列,行数根据传入的参数变化。返回数组的第一列即传入参数的第一列,返回数组的第二列即传入参数的最后一列,返回的数组里面的数据已经排过序。
最后补充一下,返回的数组应该定义为两维的,单维的数组在填充单元格的时候有问题。
在返回数组这件事上,我们需要决定返回的数组的维度。有下面几种情况:
第一种情况,返回一个大小固定的数组。
Function FixedFill() As Variant Dim N As Long Dim R As Long Dim C As Long N = 0 Dim V(1 To 3, 1 To 4) For R = 1 To 3 For C = 1 To 4 N = N + 1 V(R, C) = N Next C Next R FixedFill = V End Function
这个函数返回一个 3x4 大小的数组,值从 1 到 12。但是这个函数并没有什么应用价值,我们的返回值还是应该根据传入的参数或者输入函数的单元格范围的大小来变化。
第二种情况,根据输入函数的单元格范围大小来变化。也就是说,如果选了 A1:B2 这样 2x2 的范围来输入我们自定义的函数,我们返回的数组就是 2x2 大小;如果选了 C3:E8 这样 6x3 的范围来输入我们自定义的函数,我们返回的数组就是 6x3 大小。要获得输入函数的单元格范围的大小,我们可以用Application.Caller 这个属性。当我们从表单单元格里调用函数时,Application.Caller 属性返回的是一个 Range 对象引用,表示输入该函数的单元格范围。
Function DynamicFill() As Variant Dim CallerRows As Long Dim CallerCols As Long Dim Result() As Long Dim N As Long Dim i As Long Dim j As Long N = 0 With Application.Caller CallerRows = .Rows.Count CallerCols = .Columns.Count End With ReDim Result(1 To CallerRows, 1 To CallerCols) For i = 1 To CallerRows For j = 1 To CallerCols N = N + 1 Result(i, j) = N Next j Next i DynamicFill = Result End Function
第三种情况,结合传入的参数和函数的目的来决定返回数组的维度。像我前一篇文章里的 MySum 函数,传入的虽然是个参数数组,但返回唯一的值。我这里举的一个例子,返回的数组大小根据传入的参数范围而变化。这个自定义函数是用来排序的,比如对员工年龄,学生分数等等。期望的参数是至少两列的单元格范围,参数的第一列是标识符,比如姓名,工号等等,参数的最后一列是要排序的数值。返回的数组为两列,行数根据传入的参数变化。返回数组的第一列即传入参数的第一列,返回数组的第二列即传入参数的最后一列,返回的数组里面的数据已经排过序。
Function MySort(cells As Range) Dim x As Integer Dim y As Integer Dim i As Integer Dim j As Integer Dim workCells() x = cells.Rows.Count y = cells.Columns.Count ReDim workCells(1 To x, 1 To 2) For i = 1 To x workCells(i, 1) = cells(i, 1) workCells(i, 2) = cells(i, y) Next i Dim temp For i = 2 To x temp = workCells(i, 2) j = i - 1 Do While (workCells(j, 2) > temp) workCells(j + 1, 2) = workCells(j, 2) workCells(j + 1, 1) = workCells(j, 1) j = j - 1 If j < 1 Then Exit Do End If Loop workCells(j + 1, 2) = cells(i, y) workCells(j + 1, 1) = cells(i, 1) Next i MySort = workCells End Function
最后补充一下,返回的数组应该定义为两维的,单维的数组在填充单元格的时候有问题。
相关文章推荐
- 在 Excel 中编写自定义函数——模拟 SUM 函数
- 在 Excel 中编写自定义函数——基础篇
- add(2,3)和add(2)(3)编写一个函数,都返回5,该如何实现?
- 编写函数: unsigned int reverse_bit(unsigned int value); 这个函数的返回 值value的二进制位模式从左到右翻转后的值。 如: 在32位机器上25
- 编写一个函数,传入a,b两个int类型的变量,返回两个值的最大公约数。
- 练习 2-5 编写函数 any(s1, s2),将字符串s2中的任一字符在字符串s1中第一次出现的位置作为结果返回。如果s1中不包含s2中的字符,则返回-1。
- 写一个函数,检查字符是否是整数,如果是,返回其整数值。(或者:怎样只用4行代码编写出一个从字符串到长整形的函数?)
- 练习 2-5 编写函数 any(s1, s2),将字符串 s2 中的任一字符在字符串 s1 中第一次 出现的位置作为结果返回。如果 s1 中不包含 s2 中的字符,则返回-1。
- Oracle包体,包含存储过程,自定义函数(function),自定义类型(table),用函数返回自定义类型(相当于返回一张表)
- R语言-编写自定义函数
- 编写函数: unsigned int reverse_bit(unsigned int value); 这个函数的返回 值value的二进制位模式从左到右翻转后的值。 如: 在32位机器上25
- 2.8 编写一个函数rightrot(x, n),该函数返回将x循环右移(即从最右端移出的位将从最左端再移入)n(二进制)位后所得到的值。
- 如何编写和使用自定义的 Shell 函数和函数库
- 10g 自定义功能为WM_CONCAT的函数,返回CLOB
- 练习2-6 编写一个函数setbits(x, p ,n, y),该函数返回对x执行下列操作后的结果值: 将x中从第p位开始的n个(二进制)位设置为y中最右边n位的值,x的其余各位保持不变。
- 使PHP自定义函数返回多个值
- Excel中读取股票信息的自定义函数
- Oracle常用函数:DateDiff() 返回两个日期之间的时间间隔自定义函数
- 编写一个函数,从标准输入读取一列整数, 把这些值存储在一个动态分配的数组中并返回这个数组。 函数通过观察EOF判断输入列表是否结束。 数组的第一个数是数组包含的值的个数, 它的后面就是这些整数值。
- HIVE 编写自定义函数UDF