excel循环的自定义函数
我是一个VB的新手,所以我希望有人可以帮助我这个:我想要计算的第一个单元格的行中没有值为零的列号(例如:如果它是0 0 0 1应该给我4),但很难使其显示在工作表上,这是我的代码 –
Function Module1(y As Integer) Dim x As Integer x = 1 Dim a As Integer a = 0 Do While x < 100 Or a <> 0 If Cells(x, y).Value = 1 Then a = x x = x + 1 Loop Cells(y, 101).Value = a End Function
y是我想得到这个函数的列号,有100列。
你声明了一个函数'Module1'。 由于“Module1”曾经是代码容器“Module1”的名称,因此不是一个好的函数名称。
所以:
按Alt + F11,右键点击你的项目,添加一个模块(自动编号给你的新模块名称Module1,Module2等),input下面的代码:
Public Function GetNonZeroRank(r As Range) x = 1 Do While x <= r.Rows.Count And a = 0 If r.Cells(x, 1).Value <> 0 Then a = x End If x = x + 1 Loop GetNonZeroRank = a End Function
您可以从单元格A101使用此function:在公式中键入:
=GetNonZeroRank(A1:A100)
那就是如何使用(Public)函数
重要提示:您无法从工作表调用的函数内更改单元格值:
单元格(y,101).Value = a
你可以在Sub方法中做到这一点
除了其他答复所提出的观点之外,还有几点意见:
-
通过你的代码,看起来你循环了100多行 ,结果显示在第
x
行(这是第y
列的第一个非零行)和第101
列。 这是你真正想要的吗? -
为什么是函数而不是子例程 ? 除非你想从电子表格中使用它(在这种情况下,你可以只改变你所说的单元格的内容,一般来说),这里的函数没有用。 如果你将一个函数的返回值赋给另一个variables,这将是有用的。
-
你的代码会崩溃,如果你走的行数多于
32,767
,这是Integer
可以容纳的最大的数字。 我可以看到你需要你的代码运行到100行,但我会build议使用Long
,这是更强大,更快的评估。 - 当单元格值等于1时,您的代码在
a<>0
的条件下退出循环。 在你的描述中,你声明你想得到第一个非零单元格的行号,一般来说,它不一定是第一个非零的单元格,它等于1.你实际上是哪两个想? -
其实,有一个技巧可以完全避免循环(见下文)。
Sub test1() test 1 End Sub ' Optional passes a default value to the argument. ' If no value is given here, then y = 1 Sub test(Optional y As Long = 1) Dim x As Long With Sheet1 x = .Evaluate("MATCH(1,--(" & .Range(.Cells(1, y), .Cells(100, y)).Address & "<>0),0)") .Cells(101, y) = x End With End Sub
上面用EVALUATE
来parsing一个excel公式。
这个想法是
- 数组部分是(列
A
示例)A1:A100<>0
,它是一个类似于{FALSE, FALSE, ..., TRUE, ...}
的二进制数组 -
--{FALSE, FALSE, ..., TRUE, ...}
评估为{0, 0, ..., 1, ...}
-
MATCH(1,{0,0, ...,1, ...},0)
返回find的第一个1
的位置 - 我也将这个expression式包装在一个
IFERROR
语句来控制如果所有的值都是0
会发生什么。
我们实际上可以在单元格中testing这个公式的excel版本。 它必须是数组input(通过Control + Shift + Enter
),从VBA
进入时会自动发生。
我希望这有帮助!