Input box Compile Error - vba

I have been trying to get the name of a file name when someone uses this Macro. But for some reason every time I run the Macro I get the error:
Compile error:
Wrong number of arguments or invalid property assignment
I have looked at tons of videos and other responses but none of them have helped me deal with this error.
Sub inputbox()
Dim x As Variant
x = inputbox("Please enter your file name:", "File name")
MsgBox ("Your file name is" & x)
End Sub

Here is your procedure, corrected: (Copy & paste into a new module.)
Option Explicit
Sub MyInputBoxTest()
Dim x As Variant
x = inputbox("Please enter your file name:", "File name")
MsgBox ("Your file name is " & x)
End Sub
Explanation:
Variant was misspelled. Note that since Variant is the default data type, you actually don't need to specify it. Dim x is the same as Dim x as Variant.
You can't use names like InputBox OR MsgBox as the name of your procedure. They are reserved words -- already used by another procedure built-in to VBA, so it confuses the compiler since it doesn't know which one you're referring to.
Added a space after the word is. (purely cosmetic)
Functions like MsgBox and InputBox can be called different ways depending on whether you use brackets and whether you need to return a value.
InputBox "Hi"
InputBox ("Hi")
...either of these will run fine (but won't return the what the user enters.)
Dim x
x = InputBox ("Hi")
...will return the value to variable x, however:
x = InputBox "Hi"
...will throw an error.
It's highly recommended that, especially while learning, you add the line Option Explicit to the very top of every module. This will help "force" you to properly declare and refer to variables, objects, etc, by generating compile errors when you try to compile (F9) or run (F5) the code.

Related

Runtime error 2482 while executing string as code

So I'm attempting to change the value of a textbox on a form with VBA code.
I'm actually doing this by running a string as code so I can loop through a number of textboxes that are named similarly (RacewayOrder1, RacewayOrder2, etc...) and populate them all one at a time. So my code looks like this:
Private Sub FillRow(ByVal OrderNumber As Integer)
Dim tempstr As String
tempstr = "RacewayOrder" & OrderNumber & " = " & OrderNumber
Eval (tempstr)
End Sub
However, I am getting runtime error 2482 "Database cannot find the name 'RacewayOrder1' you entered in the expression"
I have verified that this isn't a typo, as I copied the text box's name directly into vba, but that doesn't seem to help. I even created the tempstr variable so I could inspect the code it is attempting to run, but that hasn't helped at all either.
To make matters more annoying, I debug.printed tempstr and pasted it in as a command, and it works fine.
Any advice?
You can't use Eval() to assign a value to your text box. If you overcome the RacewayOrder1 not found problem, Eval() will treat your string expression as a test for equality, not as a value assignment.
Forget about Eval() for this and simply reference the text box by name in the form's Controls collection:
Me.Controls("RacewayOrder" & OrderNumber).Value = OrderNumber

MsgBox not accepting optional parameters

I'm struggling with this basic piece of code :
If Dir(LocationAddress & "\" & chart & " Complete.pdf") = "" Then
MsgBox("The file wasn't created.", vbCritical + vbRetryCancel)
Else
MsgBox ("The file was created.")
End If
When I click "save" in the VBA editor, the line corresponding to the error message turns red, and when I try to execute, it tells me there's a syntax error. I found this similar code online, with a different syntax, which also doesn't work, even when copied and pasted into the editor.
MsgBox("Important message", MsgBoxStyle.Critical, "MsgBox Example")
I also ran my initial code with only one style instruction as an optional argument, to make sure the issue wasn't simply that I was combining them with improper syntax.
I hardly know anything about vba, I've only written a few subs by copying and editing code found online.
As igittr commented above, on the line MsgBox("The file wasn't created.", vbCritical + vbRetryCancel), the parenthesis aren't needed.
When there's only one statement on the line, then VBA knows that the arguments are for the MsgBox procedure. If you put brackets around the arguments, it will try to evaluate everything within the brackets first, resulting in the error (that's why MsgBox ("The file was created.") still works, even though the brackets again aren't needed).
So either write the line as MsgBox "The file wasn't created.", vbCritical + vbRetryCancel
Or, if you want to still use brackets, use Call MsgBox("The file wasn't created.", vbCritical + vbRetryCancel). This works because you have two statements, Call and MsgBox, and the brackets are needed to indicate what procedure the arguments belong to.
Since, you show the message with some buttons option, the working solution should look as:
Dim ans As VbMsgBoxResult
ans = MsgBox("The file wasn't created.", vbCritical + vbRetryCancel, "A choice...")
If ans <> vbRetry Then Exit Sub ' the code will stop even if the right corner 'x' will be clicked.
'your code if want it continuing...
'or viceversa according to what do you intend doing in case of Cancel option.
MsgBox("The file wasn't created.", vbCritical + vbRetryCancel)
This won't work as you are calling a function as a sub. When calling functions as subs it needs to be treated as a sub which means no brackets. This is core Basic - brackets for functions and no brackets for subs.
MsgBox ("The file was created.")
This will work because you aren't using brackets for the sub. Brackets around a parameter mean pass that parameter by value. Where ever possible computer languages pass by reference as it more efficient.
However it means that the string is copied, and the copy given to msgbox. So it uses more memory.
Call
call is obsolete. In QuickBasic it allowed a different calling convention when calling inline assembler functions. Assembler didn't return a value. So the convention was to pass a variable by reference as an input parameter and on return would hold the return value.
Dir
Dir is obsolete. It became obsolete in the 90s when it was replaced by the file system object. See https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/filesystemobject-object
Brackets in Basic
From https://ericlippert.com/2003/09/15/what-do-you-mean-cannot-use-parentheses/
The author was the maintainer programmer at Microsoft for VBScript.
Here’s the deal: parentheses mean several different things in VB and
hence in VBScript. They mean:
Define boundaries of a subexpression: Average = (First + Last) / 2
Dereference the index of an array: Item = MyArray(Index)
Call a function or subroutine: Limit = UBound(MyArray)
Pass an argument which would normally be byref as byval: in Result
= MyFunction(Arg1, (Arg2)) , Arg1 is passed by reference, Arg2is passed by value.
That’s confusing enough already. Unfortunately, VB and hence VBScript
has some weird rules about when #3 applies. The rules are
3.1) An argument list for a function call with an assignment to the returned value must be surrounded by parens: Result = MyFunc(MyArg)
3.2) An argument list for a subroutine call (or a function call with no assignment) that uses the Call keyword must be surrounded by
parens: Call MySub(MyArg)
3.3) If 3.1 and 3.2 do not apply then the list must not be surrounded by parens.
And finally there is the byref rule: arguments are passed by reference
when possible but if there are “extra” parens around a variable then
the variable is passed by value, not by reference.
Trivia
The msgbox function is a wrapper around the Windows MessageBox() functions. Basic passes on verbatim any parameters you pass. Of course only on Windows can you use the system parameters not listed in the Basic docs. See https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-messagebox

Input box getting a compile error in VBA

I am learning how to create input boxes and I keep getting the same error. I have tried two different computers and have received the same error. The error I get is a "Compile Error: Wrong number of arguments or invalid property assignment"
Here is my code:
Option Explicit
Sub InputBox()
Dim ss As Worksheet
Dim Link As String
Set ss = Worksheets("ss")
Link = InputBox("give me some input")
ss.Range("A1").Value = Link
With ss
If Link <> "" Then
MsgBox Link
End If
End With
End Sub
When I run the code, it highlights the word "inputbox"
And help would be greatly appreciated.
Thanks,
G
Three things
1) Call your sub something other than the reserved word InputBox as this may confuse things. *Edit... and this alone will resolve your error. See quote from #Mat's Mug.
2) A̶p̶p̶l̶i̶c̶a̶t̶i̶o̶n̶.̶I̶n̶p̶u̶t̶B̶o̶x̶(̶"̶g̶i̶v̶e̶ ̶m̶e̶ ̶s̶o̶m̶e̶ ̶i̶n̶p̶u̶t̶"̶)̶ Use VBA.Interaction.InputBox("give me some input"). You can do this in addition to the first point. Documentation here.
3) Compare with vbNullString rather than "" . See here. Essentially, you will generally want to do this as vbNullString is, as described in that link, faster to assign and process and it takes less memory.
Sub GetInput()
Dim ss As Worksheet
Dim Link As String
Set ss = Worksheets("ss")
Link = VBA.Interaction.InputBox("give me some input")
ss.Range("A1").Value = Link
' With ss ''commented out as not sure how this was being used. It currently serves no purpose.
If Link <> vbNullString Then
MsgBox Link
End If
' End With
End Sub
EDIT: To quote #Mat's Mug:
[In the OP's code, what is actually being called is] VBA.Interaction.InputBox, but the call is shadowed by the procedure's identifier "InputBox", which is causing the error. Changing it to Application.InputBox "fixes" the problem, but doesn't invoke the same function at all. The solution is to either fully-qualify the call (i.e. VBA.Interaction.InputBox), or to rename the procedure (e.g. Sub DoSomething(), or both.
Sub InputBox()
That procedure is implicitly Public. Presumably being written in a standard module, that makes it globally scoped.
Link = InputBox("give me some input")
This means to invoke the VBA.Interaction.InputBox function, and would normally succeed. Except by naming your procedure InputBox, you've changed how VBA resolves this identifier: it no longer resolves to the global-scope VBA.Interaction.InputBox function; it resolves to your InputBox procedure, because VBAProject1.Module1.InputBox (assuming your VBA project and module name are respectively VBAProject1 and Module1) are always going to have priority over any other function defined in any other referenced type library - including the VBA standard library.
When VBA resolves member calls, it only looks at the identifier. If the parameters mismatch, it's not going to say "hmm ok then, not that one" and continue searching the global scope for more matches with a different signature - instead it blows up and says "I've found the procedure you're looking for, but I don't know what to do with these parameters".
If you change your signature to accept a String parameter, you get a recursive call:
Sub InputBox(ByVal msg As String)
That would compile and run... and soon blow up the call stack, because there's a hard limit on how deep the runtime call stack can go.
So one solution could be to properly qualify the InputBox call, so that the compiler knows exactly where to look for that member:
Link = VBA.Interaction.InputBox("give me some input")
Another solution could be to properly name your procedure so that its name starts with a verb, roughly describes what's going on, and doesn't collide with anything else in global scope:
Sub TestInputBox()
Another solution/work-around could be to use a similar function that happens to be available in the Excel object model, as QHarr suggested:
Link = Application.InputBox("give me some input")
This isn't the function you were calling before though, and that will only work in a VBA host that has an InputBox member on its Application class, whereas the VBA.Interaction.InputBox global function is defined in the VBA standard library and works in any VBA host.
A note about this:
If Link <> "" Then
This condition will be False, regardless of whether the user clicked OK or cancelled the dialog by "X-ing out". The InputBox function returns a null string pointer when it's cancelled, and an actual empty string when it's okayed with, well, an empty string input.
So if an empty string needs to be considered a valid input and you need to be able to tell it apart from a cancelled inputbox, you need to compare the string pointers:
If StrPtr(Link) <> 0 Then
This condition will only be False when the user explicitly cancelled, and will still evaluate to True if the user provided a legit empty string.

Word VBA: Status of a checkbox in Word table cells

I have a set of identical Word files containing a set of yes/no questions organized in a table with simple checkboxes (from the Developer tab / Content Controls) included in columns 3 and 5, corresponding to the Yes or No answer.
The Yes and No checkboxes are either checked or unchecked.
I want to count the number of Yes and No checks for each of the questions. The Word files are already available and their format cannot be changed.
As a first step in this task I am trying to recognize when a table cell contains a checkbox, and then read the status of the checkbox: checked or unchecked.
I came to the following code to identify the checkboxes. VBA complains with a compilation error: "Object Required", at line "set nitem.....".
Dim tbl As Table
Dim cl As Cell
Dim nitem As Integer
''All tables
For Each tbl In ActiveDocument.Tables
For Each cl In tbl.Rows(1).Cells
If Not cl.Range.ContentControls Is Nothing Then
Set nitem = c1.Range.ContentControls.Count
MsgBox ("Nr of Items" & nitem)
If c1.Range.ContentControls.Item(1).Type = wdContentControlCheckBox Then
''Select ...
cl.Column.Select
.........
End If
End If
Next
Next
The keyword "Set" is for objects. An Integer is not an object so your line needs to be just:
nitem = cl.Range.ContentControls.Count
without "Set"
EDIT: This would cause the error that you are referring to, but I also noticed another issue that needs to be fixed after your comment.
Note that the declared variable is "cl" where the second character is a lowercase "L". You have tried to use it as "c1" where the second character is the numeral "One" Make sure to use "CL" in all cases where this variable appears (in the line in question and also two lines below this)
If you use "Option Explicit" at the beginning of the "This_Workbook" module (or whatever module the code is in) before any Subroutines, this will help prevent misspelling errors like this as the compiler will raise an exception alerting you that the variable is not defined.

Compile Error Expected Function Or Variable

I'm new and trying to learn VBA. When I'm typing in the code I get Compile Error Expected Function Or Variable.
Is something regarding the activecell, but can't figure it out.
Sub Testare()
Dim FilmName As String
Dim FilmLenght As Integer
Dim FilmDescription As String
Range("b10").Select
FilmName = ActiveCell.Value
FilmLenght = ActiveCell.Offset(0, 2).Value
If FilmLenght < 100 Then
FilmDescription = "Interesant"
Else
FilmDescription = "Suficient"
End If
MsgBox FilmName & " is " & FilmDescription
End Sub
This error happens also when a Sub is called the same as variable (i.e. in one Sub you have for loop with iterator "a", whilst another Sub is called "a").
This gives an error that fits to your description.
Regards
It is possible to make your code fail in two different ways:
Place a very large value in D10
Place a text value in D10
This will result in either an overflow error or type mismatch error.
I know this was asked a while ago, but I ended up with the same error when I created a Sub within a worksheet with the Sub Name the same as the Worksheet name.
Unfortunately when this happens, no error is highlighted by a compile; the error only appears at run time. Also, the offending line is not highlighted, which makes it a bit difficult to find.
Changing the Sub name solves it though.
Here is what caused this error in my case:
Inside a new Public Function that I was starting to write, I began to type a statement, but needed to copy a long varname from another location, so I just inserted the letter a to prevent Excel from popping-up the uber-annoying Compile Error: Expected Expression dialog. So I had this:
myVarName = a
I then attempted to step-through my code to get to that point, and when Excel entered that function I received the message "Compile Error: Expected Function Or Variable". To resolve, I just changed the placeholder to a number:
myVarName = 1
And all continued just fine.