功能太长了但我需要它 - 可以在VBA中完成吗?

时间:2015-03-12 20:32:46

标签: excel vba function excel-udf

由于严重缺乏知识,我做了一个非常漫长的功能,以便我可以进行计算。问题是它对于Excel来说太长了,我试着在网上看看如何在VBA中创建一个引用我的函数的新函数。我在这一方面迷失了,任何帮助都会很棒。这个函数太乱了,不能在这里发帖(长度为30k字符)。

好的,所以这里 - 这是函数的一部分: = + IF(ISERROR(IF(LEFT(C12,FIND(“”,C12,1))= $ C $ 2,SUMPRODUCT(P12:S12,Selection!$ B $ 4:Selection!$ E $ 4),IF(LEFT( C12,FIND(“”,C12,1))= $ C $ 3,SUMPRODUCT(P12:S12,选择!$ B $ 5:选择!$ E $ 5),IF(左(C12,FIND(“”,C12,1) ))= $ C $ 4,SUMPRODUCT(P12:S12,选择!$ B $ 6:选择!$ E $ 6),IF(LEFT(C12,FIND(“”,C12,1))= $ C $ 5,SUMPRODUCT(P12 :S12,选择$ B $ 7:!选择$ E $ 7),IF(RIGHT(C12,LEN($ C $ 6))= $ C $ 6 SUMPRODUCT(P12:S12,选择$ B $ 8:!选择$ E $ 8),IF(RIGHT(C12,LEN($ C $ 7))= $ C $ 7,SUMPRODUCT(P12:S12,选择$ B $ 9:!选择$ E $ 9),IF(RIGHT(C12,LEN($ C $ 8))= $ C $ 8 SUMPRODUCT(P12:S12,选择$ B $ 10:!选择$ E $ 10),SUMPRODUCT(P12:S12,选择$ B $ 11:!选择$ E $ 11)))))) ))),1,IF(LEFT(C12,FIND(“”,C12,1))= $ C $ 2,SUMPRODUCT(P12:S12,Selection!$ B $ 4:Selection!$ E $ 4),IF(LEFT( C12,FIND(“”,C12,1))= $ C $ 3,SUMPRODUCT(P12:S12,选择!$ B $ 5:选择!$ E $ 5),IF(左(C12,FIND(“”,C12,1) ))= $ C $ 4,SUMPRODUCT(P12:S12,选择!$ B $ 6:选择!$ E $ 6),IF(LEFT(C12,FIND(“”,C12,1))= $ C $ 5,SUMPRODUCT(P12 :S12,选择$ B $ 7:!选择$ E $ 7),IF(RIGHT(C12,L EN($ C $ 6))= $ C $ 6 SUMPRODUCT(P12:S12,选择$ B $ 8:!选择$ E $ 8),IF(RIGHT(C12,LEN($ C $ 7))= $ C $ 7,SUMPRODUCT (P12:S12,选择$ B $ 9:!选择$ E $ 9),IF(RIGHT(C12,LEN($ C $ 8))= $ C $ 8 SUMPRODUCT(P12:S12,选择$ B $ 10:选择! $ E $ 10),SUMPRODUCT(P12:S12,选择$ B $ 11:!选择$ E $ 11)))))))))

3 个答案:

答案 0 :(得分:1)

回答你的问题"可以在VBA中完成吗?",答案是肯定的。如果您可以使用Excel功能,可以使用VBA执行此操作。虽然可能存在功能上的缺点,但编写函数的语法将完全不同(尽管通常使用谷歌搜索很容易翻译)。

在你去VBA之前要考虑的一件事是将功能分解成多个单元吗?这可能适合您的需要并绕过角色限制,但如果它长达30k个字符,则可能不实用甚至不可能。

我建议首先使用谷歌搜索" VBA相当于excel功能XXXX"对于您使用的每个Excel功能。然后从中间括号开始,以与excel函数相同的顺序对输入执行操作。 VBA函数和Excel函数之间的主要区别在于,您可以逐行对同一变量执行操作,而不是使用复杂的操作顺序。

例如,不是把= if(a2> 3,b3 + 5,b3-5)* if(A1> 3,B2 + 3,B2-3),而是放置:

Function Your_Function_Name1(Cell_one As Range, Cell_two As Range, _
                            Cell_three As Range, Cell_four As Range) As Double
    If Cell_four > 3 Then
        If Cell_three > 3 Then
            Your_Function_Name1 = (Cell_one.Value + 5) * (Cell_two.Value + 3)
        Else
            Your_Function_Name1 = (Cell_one.Value - 5) * (Cell_two.Value + 3)
        End If
    Else
        If Cell_three > 3 Then
            Your_Function_Name1 = (Cell_one.Value + 5) * (Cell_two.Value - 3)
        Else
            Your_Function_Name1 = (Cell_one.Value - 5) * (Cell_two.Value - 3)
        End If
    End If
End Function

并致电=Your_Function_Name1(B3,B2,A2,A1)。但它也是完全合法的,通常更容易做到这一点:

Function Your_Function_Name(Cell_one As Range, Cell_two As Range, _
                            Cell_three As Range, Cell_four As Range) As Double
    If Cell_three > 3 Then
        Your_Function_Name = Cell_one.Value + 5
    Else
        Your_Function_Name = Cell_one.Value - 5
    End If

    If Cell_four > 3 Then
        Your_Function_Name = Your_Function_Name * (Cell_two.Value + 3)
    Else
        Your_Function_Name = Your_Function_Name * (Cell_two.Value - 3)
    End If

End Function

这两个函数将以相同的方式调用并产生相同的结果。

我认为这应该足以让你入门,虽然一旦你进入并开始调试你可能最终会发布另一个或两个问题,但至少你会有特定的代码询问。 VBA起初很难,但值得花时间。

祝你好运!

答案 1 :(得分:0)

以下指南是重构现有代码以及将来编写新代码的好方法:

对于具有或足够大的描述性注释的每个代码块,创建一个子例程并使用描述性注释命名它(在 PascalCase 中) 。识别所有局部变量并在新子例程中重新声明它们。将所有全局值作为命名参数传递。

冲洗并重复,直到所有子程序都小于40行左右。

答案 2 :(得分:0)

您可以使用IFERROR而不是IF(ISERROR将功能缩减一半 此外,您的Selection!$B$4:Selection!$E$4可以缩减为Selection!$B$4:$E$4

=IFERROR(IF(LEFT(C12,FIND(" ",C12,1))=$C$2,SUMPRODUCT(P12:S12,Selection!$B$4:$E$4),IF(LEFT(C12,FIND(" ",C12,1))=$C$3,SUMPRODUCT(P12:S12,Selection!$B$5:$E$5),IF(LEFT(C12,FIND(" ",C12,1))=$C$4,SUMPRODUCT(P12:S12,Selection!$B$6:$E$6),IF(LEFT(C12,FIND(" ",C12,1))=$C$5,SUMPRODUCT(P12:S12,Selection!$B$7:$E$7),IF(RIGHT(C12,LEN($C$6))=$C$6,SUMPRODUCT(P12:S12,Selection!$B$8:$E$8),IF(RIGHT(C12,LEN($C$7))=$C$7,SUMPRODUCT(P12:S12,Selection!$B$9:$E$9),IF(RIGHT(C12,LEN($C$8))=$C$8,SUMPRODUCT(P12:S12,Selection!$B$10:$E$10),SUMPRODUCT(P12:S12,Selection!$B$11:$E$11)))))))),1)

现在这对我有用,但你对LEFT(C12,FIND(" ",C12,1))=$C$2的测试似乎很可疑。如果C12在House中包含Cat,则左侧将评估为 " Cat" 最后有一个空格。在你测试的单元格中最好包含一个空格,但我猜他们不会。您可能想要制作文字 LEFT(C12,FIND(" ",C12,1)-1)=$C$2