Что вызывает ошибку «Именованный аргумент уже указан» в Excel VBA? - PullRequest
1 голос
/ 13 декабря 2010

Это начало кода, который я написал в 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"

1 Ответ

5 голосов
/ 13 декабря 2010

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

Вам необходимо удалить запятую после вызова метода SaveAs и перед Filename именованный параметр.

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

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

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


РЕДАКТИРОВАТЬ: Точное значение скобок в вызовах методов, и когда они требуются, эточто-то, что смущает даже давних пользователей VBA.Это относительно сложно, поэтому давайте посмотрим, насколько хорошо я могу объяснить это.(Те же правила также применяются к версиям Visual Basic до .NET, таким как 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. сообщение в блоге Эрика Липперта по связанному вопросу, вероятно, объясняет эту проблему лучше, чем я.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...