Excel VBA中导致“已命名的参数已指定”错误的原因是什么?

这是我在Excel VBA编写的代码的开始,但我不明白为什么我不断收到一个编译错误(VBA指向最后一行代码作为错误的来源与“已命名参数已指定”) 。 这里有很多聪明的程序员,所以任何人都可以告诉我什么是错的(并修改代码)? 我正处于学习VBA的初级阶段,所以对于我错误编码的更多解释和指导对我来说真的很有帮助。

非常感谢你。

'''''''''''''''''''''''''''''''''''''''''''' Dim outputbook, sourcebook As Workbook '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 'Firstly creating new worksheet Set sourcebook = ActiveWorkbook Set outputbook = Workbooks.Add outputbook.SaveAs , Filename:="Output" & " " & Format(Now(), "dd_mm_yyyy_hh_mm_AMPM") & ".xlsx" '''''''''''''''''''''''''''''''''''''''''''''''''''''' Dim analysisbook As Workbook ''''''''''''''''''''''''''''''''''''''''' 'Create another new workbook where analysis will be performed Set analysisbook = Workbooks.Add analysisbook.SaveAs , Filename:="analysis" & " " & Format(Now(), "dd_mm_yyyy_hh_mm_AMPM") & ".xlsx" 

你会觉得这很愚蠢,但它会解决你的问题…

您需要在调用SaveAs方法之后和Filename命名参数之前删除逗号。

所以你的代码的最后一行应该是这样的:

 analysisbook.SaveAs Filename:="analysis" & " " & Format(Now(), "dd_mm_yyyy_hh_mm_AMPM") & ".xlsx" 

如果您提供多个命名参数,则只需使用逗号。 由于你只提供一个( Filename ),所以不需要逗号,这就导致你得到(有点神秘的)“命名参数已经指定”的编译时错误。 Excel认为你错过了在逗号前面提供一个命名的参数。 拿出来,它会意识到,你只是想包括一个。


编辑:在方法调用括号中的确切含义,以及什么时候需要,是甚至长期的VBA用户混淆的东西。 这是相对复杂的,所以让我看看我能做些什么来解释它。 (相同的规则也适用于Visual Basic的pre.NET版本,如VB 6)

简单的规则是,当你将一个函数的结果分配给一个variables或另一个对象时,你总是将参数列表括在括号内。 所以,如果我有一个名为GetAge的函数,当我指定名字和姓氏时返回一个数值,我会写下面的代码:

 Dim age As Integer age = GetAge("John", "Smith") 

否则,不必将括号括起来。 这涵盖了两种可能的情况。 首先,当你调用一个子程序(“sub”)时,它永远不会返回一个值,其次,如果你调用一个函数(它总是返回一个值),但是不赋值则返回任何variables或对象。 基本上,当你忽略它返回的价值。 例如:

 ''#Calling a subroutine MsgBox "Hello World" ''#Calling the same function as above, but ignoring its return value ''# (this particular example is not very useful, but sometimes you'll do this) GetAge "John", "Smith" 

或者,可以select使用Call语句来调用其忽略的返回值的子例程和函数 ,这总是需要将参数包装在括号中。 我个人更喜欢这种语法,因为它与我工作的其他语言更相似,消除了何时需要括号以及何时不需要的含糊之处,并且在代码中更明确地调用外部方法。 对于上面给出的两个例子,代码将变为:

 ''#Calling a subroutine, but using the Call statement Call MsgBox("Hello World") ''#Calling a function, but ignoring its return value Call GetAge("John", "Smith") 

最后,如果你以为你已经掌握了所有这一切,那么还有一种可能你应该明白。 如果将参数包装到一个子程序或函数的返回值中,并且不用括号括起来,并且不使用Call语句,那么VBA会将参数解释为通过ByVal )传递,否则它们通常会被引用传递( ByRef )。 当你以这种方式编写一个方法调用时,编译器会自动为你重新格式化,表明它在解释方式上的差异:

 ''#The following line MsgBox("Hello World") ''#will be re-formatted by the compiler to MsgBox ("Hello World") 

注意它在方括号和圆括号中的参数之间添加的空格? 该空间表示parameter passing给ByVal 。 Eric Lippert关于相关问题的博客文章可能比我能更好地解释这个特殊的问题。