用于循环的excel自定义函数

时间:2014-10-12 19:48:00

标签: excel loops excel-vba vba

我是擅长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列。

2 个答案:

答案 0 :(得分:1)

您声明一个函数'Module1'。这不是函数的好名称,因为'Module1'曾经是代码容器'Module1'的名称。

所以:

按Alt + F11,右键单击您的项目,添加一个模块(自动编号为您的新模块命名为Module1,Module2等),输入以下代码:

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中使用此功能:输入公式:

=GetNonZeroRank(A1:A100)

如何使用(公共)功能

重要提示:您无法更改从工作表调用的函数内部的单元格值:

  

单元格(y,101).Value = a

您可以在Sub方法

中执行此操作

答案 1 :(得分:0)

除了其他回复所做的那些之外,还有几点:

  • 根据您的代码,您似乎正在循环超过100个和 结果显示在行x中(这是第一个非零行 列y)和列101。这是你真正想要的吗?

  • 为什么是函数而不是子例程? 除非你想在电子表格中使用它(在这种情况下你只能改变你调用它的单元格的内容,一般来说),这里的函数没用。如果将函数的返回值赋给另一个变量,将会很有用。

  • 如果你去的行32,767 ,那么你的代码就会崩溃,这是Integer可以容纳的最大数字。我可以看到你需要你的代码运行到第100行,但我建议使用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来解析excel公式。

想法是

  • 数组部分是(列A的示例)A1:A100<>0,它是二进制文件 看起来像{FALSE, FALSE, ..., TRUE, ...}
  • 的数组
  • --{FALSE, FALSE, ..., TRUE, ...}评估为{0, 0, ..., 1, ...}
  • MATCH(1,{0,0, ...,1, ...},0)返回找到的第一个1的位置
  • 我还会将此表达式包装在IFERROR语句中,以控制如果所有值都为0会发生什么。

我们实际上可以在单元格中测试此公式的excel版本。必须输入数组(通过Control + Shift + Enter确认),从VBA输入时会自动生成。

我希望这有帮助!