Argument not optional vba что делать
Перейти к содержимому

Argument not optional vba что делать

  • автор:

VBA Function — Argument Not Optional

I understand the error message, its telling me I did not fill out a parameter. But I only have one parameter, and I’ve declared it optional. It looks like the code thinks I’m trying to call the function from the function?

3 Answers 3

Anytime you assign an object you need to use the set keyword.

set RETURN_Equipment = myCollection

Brad's user avatar

I was getting this error because I was using the wrong function name when trying to return a result from a function. I was doing this:

This happened because I copied a function from somewhere else and changed the name, but not the return statement. This is not the OP’s problem, but I was getting the same error message.

Because you’ve specified the Optional Parameter as a string it will default to an empty string if you’ve not specified a value.

This means it can’t be missing

If you’d specified it as

It would be a variant and that could be missing, although you’d also be able to mess things up by passing non string variants as the category parameter

Argument not optional vba что делать

Gray Pipe

This forum has migrated to Microsoft Q&A. Visit Microsoft Q&A to post new questions.

Answered by:

Question

I have written a program, using VBA in Excel 2007, and it runs perfect. I have been reading that it is good practice to ‘compile’ your program, not something I have previously done. When I click compile, I get the following error: "Complie Error: Argument not optional". What does this mean?

The error occurs on this line of code: Call InsertVaRSummaryFigure

Which calls this function (which works fine):

Function InsertVaRSummaryFigure(SummarySheet As String)

Worksheets(SummarySheet).Select
strFindAddressClearSection = Range("C1:C1000").Find("Total Core Rates GB", Range("C1"), xlValues, xlWhole, xlByColumns, xlNext).Address
Range(strFindAddressClearSection).Offset(0, 2).Formula = "=-VaRData!D11"

Синтаксис VBA Передача параметров процедурам и функциям в VBA

Параметры — значения, которые передаются от одной процедуры другой. В принципе, можно обойтись и без параметров, воспользовавшись только переменными уровня модуля, но при использовании параметров читаемость программы улучшается. Чтобы процедура имела возможность принимать параметры, ее вначале нужно объявить с параметрами. Например, вот пример простой функции, которая складывает два числа и выводит результат:

Function fSum (nItem1 As Integer, nItem2 As Integer)

fSum = nItem1 + nItem2

Вызов ее может выглядеть так:

В данном случае мы объявили оба параметра как обязательные, и поэтому попытка вызвать функцию без передачи ей какого-либо параметра (например, так: MsgBox (fSum(3))) приведет к ошибке «Argument not optional» — «Параметр не является необязательным». Чтобы можно было пропускать какие-то параметры, эти параметры можно сделать необязательными. Для этой цели используется ключевое слово Optional:

Function fSum (nItem1 As Integer, Optional nItem2 As Integer)

В справке по встроенным функциям VBA необязательные параметры заключаются в квадратные скобки.

Для проверки того, был ли передан необязательный параметр, используется либо функция IsMissing (если для этого параметра был использован тип Variant), либо его значение сравнивается со значениями переменных по умолчанию (ноль для числовых данных, пустая строка для строковых и т.п.)

Вызов функции с передачей параметров может выглядеть так:

nResult = fSum (3, 2)

Однако здесь есть несколько моментов, которые необходимо рассмотреть.

В нашем примере мы передаем параметры по позиции, то есть значение 3 присваивается первому параметру (nItem1), а значение 2 — второму (nItem2). Однако параметры можно передавать и по имени:

nResult = fSum (nItem 1 := 3, nItem 2 := 2)

Обратите внимание, что несмотря на то, что здесь выполняется вполне привычная операция — присвоение значений, оператор присвоения используется не совсем обычный — двоеточие со знаком равенства, как в C++. При использовании знака равенства возникнет ошибка.

Конечно, вместо явной передачи значений (как у нас — 3 и 2) можно использовать переменные. Однако что произойдет с переменными после того, как они «побывают» в функции, если функция изменяет их значение? Останется ли это значение за пределами функции прежним или изменится?

Все зависит от того, как именно передаются параметры — по ссылке (по умолчанию, можно также использовать ключевое слово ByRef или по значению — нужно использовать ключевое слово ByVal).

Если параметры передаются по ссылке, то фактически в вызываемую процедуру передается ссылка на эту переменную в оперативной памяти. Если эту переменную в вызываемой процедуре изменить, то значение изменится и в вызывающей функции. Это — принятое в VBA поведение по умолчанию.

Если параметры передаются по значению, то фактически в оперативной памяти создается копия этой переменной и вызываемой процедуре передается эта копия. Конечно же, чтобы вы не сделали с этой копией, на исходную переменную это никак не повлияет и в вызывающей процедуре не отразится.

Продемонстрировать разницу можно на простом примере:

Private Sub TestProc ()

‘Объявляем переменную nPar1 и присваиваем ей значение

Dim nPar1 As Integer

‘Передаем ее как параметр nItem1 функции fSum

MsgBox (fSum(nItem1:=nPar1, nItem2:=2))

‘А теперь проверяем, что стало в нашей переменной nPar1, ‘после того, как она побывала в функции fSum:

Function fSum(nItem1 As Integer, nItem2 As Integer)

‘Используем значение переменной

fSum = nItem 1 + nItem 2

‘А затем ее меняем!

Проверьте, что будет, если поменять строку объявления функции

Function fSum(nItem1 As Integer, nItem2 As Integer)

на следующую строку :

Function fSum(byVal nItem1 As Integer, nItem2 As Integer)

Можно продемонстрировать компилятору VBA, что то, что возвращает функция, наш совершенно не интересует. Для этого достаточно не заключать ее параметры в круглые скобки. Например, в случае со встроенной функцией MsgBox это может выглядеть так:

а для нашей функции —

Такой код будет работать совершенно нормально. Однако, если нам потребуется все-таки узнать, что возвращает MsgBox, то придется передаваемые ему параметры заключать в круглые скобки:

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

Excel vba Compile error – Argument not optional,

I keep getting an error: "Compile error – Argument not optional". I am supplying the arguments and they are set as Optional!

Trying to pass a string and an array to a function and count occurrences of the array strings within the string passed.

Code stops running at the line:

with a "Compile error: Argument not optional" message highlighting the Val in the line:

Best Solution

Val is a VBA function which requires a single, mandatory, argument — therefore the compiler generates the message saying "Argument not optional" if you don't provide that argument. (MSDN documentation of Val )

It is a bad idea to use VBA function names as variable names, so I would recommend you don't use Val as a variable name — use myVal or anything else that VBA hasn't already used.

If you really want to use Val (and you are sure that you won't be needing to access the Val function at all), you can use it as a variable name if you simply declare it as such, e.g.

You will also have problems with your line saying

as countTextInText has been declared to be an Integer , and Set should only be used when setting a variable to be a reference to an object. So that line should be

Related Solutions
Excel – way to crack the password on an Excel VBA Project

You can try this direct VBA approach which doesn't require HEX editing. It will work for any files (*.xls, *.xlsm, *.xlam . ).

Tested and works on:

Excel 2007
Excel 2010
Excel 2013 — 32 bit version
Excel 2016 — 32 bit version

Looking for 64 bit version? See this answer

How it works

I will try my best to explain how it works — please excuse my English.

  1. The VBE will call a system function to create the password dialog box.
  2. If user enters the right password and click OK, this function returns 1. If user enters the wrong password or click Cancel, this function returns 0.
  3. After the dialog box is closed, the VBE checks the returned value of the system function
  4. if this value is 1, the VBE will "think" that the password is right, hence the locked VBA project will be opened.
  5. The code below swaps the memory of the original function used to display the password dialog with a user defined function that will always return 1 when being called.

Using the code

Please backup your files first!

    Open the file(s) that contain your locked VBA Projects

Create a new xlsm file and store this code in Module1

code credited to Siwtom (nick name), a Vietnamese developer

Paste this code under the above code in Module1 and run it

Come back to your VBA Projects and enjoy.

Excel – How to avoid using Select in Excel VBA

Some examples of how to avoid select

Use Dim 'd variables

Set the variable to the required range. There are many ways to refer to a single-cell range:

Or a multi-cell range:

You can use the shortcut to the Evaluate method, but this is less efficient and should generally be avoided in production code.

All the above examples refer to cells on the active sheet. Unless you specifically want to work only with the active sheet, it is better to Dim a Worksheet variable too:

If you do want to work with the ActiveSheet , for clarity it's best to be explicit. But take care, as some Worksheet methods change the active sheet.

Again, this refers to the active workbook. Unless you specifically want to work only with the ActiveWorkbook or ThisWorkbook , it is better to Dim a Workbook variable too.

If you do want to work with the ActiveWorkbook , for clarity it's best to be explicit. But take care, as many WorkBook methods change the active book.

You can also use the ThisWorkbook object to refer to the book containing the running code.

A common (bad) piece of code is to open a book, get some data then close again

And it would be better like:

Pass ranges to your Sub s and Function s as Range variables:

You should also apply Methods (such as Find and Copy ) to variables:

If you are looping over a range of cells it is often better (faster) to copy the range values to a variant array first and loop over that:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *