2010-12-13 1 views
1

Это начало кода, который я написал в Excel VBA, но я не понимаю, почему я продолжаю получать ошибку компиляции (VBA указывает на последнюю строку кода как источник ошибки с «Именованный аргумент, уже указанный «). Здесь очень много умных программистов, поэтому кто-нибудь может сообщить мне, что именно не так (и изменить код)? Я нахожусь на ранних этапах обучения VBA, поэтому больше объяснений и рекомендаций относительно того, что я неправильно закодировал, было бы очень полезно для меня.Что вызывает ошибку «Именованные аргументы уже заданы» в Excel 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" 

ответ

4

Вы собираетесь думать, что это глупо, но это будет исправить вашу проблему ...

Вы должны удалить запятую после вызова метода SaveAs и перед именем параметра Filename ,

Так что самая последняя строка кода должна выглядеть следующим образом:

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

Вы должны использовать только запятую, если вы предоставляете более одного именованный аргумент. Поскольку вы предоставляете только один (Filename), нет необходимости в запятой, и это заставляет вас получить (несколько загадочный) «Именованный аргумент уже заданный» ошибка времени компиляции. Excel думает, что вы пропустили, предоставляя именованный аргумент в начале, перед запятой. Возьмите это, и он поймет, что вы только хотели включить его.


EDIT: Точный смысл скобкой в ​​методе вызовов, и когда они необходимы, является то, что это сбивает с толку даже пользователей VBA долгое время. Это относительно сложно, поэтому позвольте мне посмотреть, как хорошо я могу это объяснить. (Те же правила применимы и к версиям Visual Basic Visual Basic, например, VB 6.)

Простым правилом является то, что когда вы назначаете результат функции переменной или другому объекту, вы всегда заключите список аргументов в круглые скобки. Таким образом, если бы я имел функцию с именем GetAge, которая возвращала числовое значение, когда я указал на имя и фамилию, я хотел бы написать следующее:

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

В противном случае, он никогда не нужно заключать аргументы в скобки , Это охватывает два возможных случая. Во-первых, когда вы вызываете подпрограмму («sub»), которая никогда не возвращает значение, а во-вторых, если вы вызываете функцию (которая всегда возвращает значение), но не присваивает значение, возвращается к любой переменной или объекту , По существу, когда вы находитесь , игнорируя значение, которое оно возвращает. Например:

''#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" 

В качестве альтернативы, вы можете позвонить как подпрограммы и функции которых возвращаемое значение вы игнорируете используя 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") 

Обратите внимание на то место, которое он добавляется между именем метода и аргументов заключенной в скобках? Это пространство указывает, что аргументы передаются ByVal. Eric Lippert's blog post по соответствующему вопросу, вероятно, объясняет эту проблему лучше, чем я могу.

+0

Большое вам спасибо. У меня есть еще один глупый вопрос, который более общий по своей природе. Я видел, что иногда аргументы в VBA могут быть представлены в скобках, в то время как другие просто обозначаются после пробела (как в .saveas), при каких обстоятельствах вы бы использовали их? Это настолько запутанно, что я только начинаю изучать VBA – Carole

+0

@Carole http://bytes.com/topic/access/insights/732414-how-use-named-arguments –

+0

@Carole: Я добавил ответ на ваш вопрос мой ответ. К сожалению, это не простой ответ. :-) –

Смежные вопросы