I'm trying to create an AutoExec Macro that'll run a function upon loadup.
I have the function declared and written in a macro called: checkUser
I created an AutoExec Macro, it's code is set to the "RunCode" command, and when I type the "checkUser()" function name, it auto-populates, so obviously it can see it.
However, once I run the AutoExec macro I get this error:
The expression you entered has a function name that Microsoft Access can't find
I've also tried to convert the Autoexec to VBA, and then manually enter the code, when I do I either nothing happens, or I get an error stating that it can't be repeated more than 19 times.
Am I just putting the function in the wrong spot?
As you hint at in your comments, it looks like you have a name resolution issue. If your module name is the same as the function name, you need to further qualify the function name like checkUser.CheckUser()
Related
I have been working with Visio VBA for a couple of years. I pass arguments from the ShapeSheet of a shape to several procedures in VBA using either RUNMACRO() or CALLTHIS() Functions.
I either pass pass plain strings or the value of different formulas in the ShapeSheet. The most common argument that I pass to my procedures is the ID() of the shape.
After a patch update of Windows: https://support.microsoft.com/en-us/topic/march-15-2021-kb5001566-os-build-18363-1441-out-of-band-23c4c824-8638-43e9-a381-ff58213ae6fe, I am no longer able to pass arguments from the ShapeSheet of a Shape to my procedures in VBA. Whenever I use RUNMACRO or CALLTHIS, all the arguments that I pass, even if they are plain strings, in my procedure side everything that I get is "", blank information.
Is there a way to know if this is a bug or if this is on purpose, maybe as a security measure?
Here is a simple example procedure:
Public Function HelloWorld(Number As Integer)
If Number = 1 Then
MsgBox ("Hello World 1")
End If
If Number = 2 Then
MsgBox ("Hello World 2")
End If
End Function
And this procedure is called in the EventDblClick of a Shape:
RUNMACRO("HelloWorld(1)","Test")
When the EventDblClick is triggered the value of Number stays as null, ignoring the argument sent in the RUNMACRO function, which is a 1. Since the argument of Number in the HelloWorld() function is not optional, it triggers a Compile error message
"Argument not optional"
My programs were also recently affected by this update. Previously, I was able to structure the ‘macroname’ string in RUNMACRO (macroname [,projname_opt]) to include arguments to my functions and subroutines (as in Alexis’ HelloWorld example). However, that suddenly seems to be no longer possible. It is almost as if RUNMACRO is now modifying the ‘macroname’ string to exclude any arguments prior to making the call to the Function or Subroutine.
One workaround that I have found is to use CALLTHIS and restructure the VBA Function or Subroutine slightly as shown below. That said, it is going to be a huge hassle for me to execute this change in every cell, in every shape, in every file using the RUNMACRO formula. I’m going to have to write a separate macro just to execute this change.
Workaround:
CALLTHIS(HelloWorld,,1)
[NOTE: The two commas are intentional.]
Public Function HelloWorld(callingShape as Visio.Shape, number as Integer)
‘Insert Code Here
End Function
I'm still learning VBA so I might be doing a lot of very basic mistakes. At the moment I'm trying to make a macro which could count the rows of a table. This sub works perfectly (with a table named "Tab").
Sub AddRowTable()
ActiveSheet.ListObjects("Tab").ListRows.Add (2)
End Sub
However, when I try to convert this sub to a function so I can call it with the name of the table as variable, I get a name error when writing "=AddRowTableFunction(Tab)" in a cell.
Function AddRowTableFunction(TableName)
ActiveSheet.ListObjects(TableName).ListRows.Add (3)
End Function
I understand that it is just a problem of type, but I just cant find how to do it properly.
Thanks.
At the moment I'm trying to make a macro which could count the rows of a table.
First off, that is not what your code is doing. Your code is adding a row to the table. The number of rows would be accessed using ListRows.Count.
when I try to convert this sub to a function so I can call it with the name of the table as variable...
You don't need a Function in order to include a variable. The differance between a Sub and a Function is that a Function returns a variable, while a Sub does not (i.e. a Function gives back a variable to the code that used it). Both Subs and Functions can take variables.
A Function that returns the number of rows in a given table would be something like this:
Function AddRowTableFunction(TableName As String)
AddRowTableFunction = ActiveSheet.ListObjects(TableName).ListRows.Count
End Function
For adding a row, you would probably use a Sub, because the action of adding a row doesn't return any information:
Sub AddRowTable(TableName As String)
ActiveSheet.ListObjects(TableName).ListRows.Add
End Sub
Finally, when using the Function in a formula, as Apafey pointed out, you need to write "Tab" (in quotes), not just Tab. "Tab" tells Excel to pass the text of the word Tab, while Tab tells Excel to look for a range named Tab, which probably doesn't exist.
You should try:
=AddRowTableFunction("Tab")
You wrote:
=AddRowTableFunction(Tab)
that is not fine.
As FaneDuru said, an UDF function can't change other cells, which explains the error). Thnaks !
I've created several custom functions which I would like to Register. Currently, I have a different procedure for which I specify the registration for each function (there's no issue with that piece). However, the only way I know of to registering all these functions is by calling each Macro by name in another procedure like this:
Sub spRegisterFunctions()
Call spRegisterCUSTOMAfunction
Call spRegisterCUSTOMBfunction
Call spRegisterCUSTOMCfunction
Call spRegisterCUSTOMDfunction
End Sub
I'm actually looking for something more dynamic so that every time I create a new function, and it's corresponding "spRegister..." procedure, I don't have to remember to add the "Call" code to the "Sub spRegisterFunction()" procedure for that specific function.
Here's an example of what attempting to do:
Sub spRegisterFunctions()
Dim mc as Macro
For Each mc in VBProject("NameOfProject").Module("NameOfModule")
If Left(mc.Name,10)="spRegister" then
Call mc
End If
Next mc
End Sub
As you can see, I'm attempting to run any macro in a specific module who's name begins with "spRegister". Obviously the code above will not work, partly because some of those objects don't even exist.
Is there any way to do this?
I have an Access web database
In this database, I have a web form with a button on it
In its on-click event macro, it calls RunMacro Macro1 (client-macro) which fires successfully
in Macro1, if I call RunCode Function Name: DoTest() it returns the error: "The function you entered can't be used in this expression... Error Number 2426 (or 2950 if I have an "=" symbol in front of my function)
This issue is easily reproduced by doing these steps:
Create a blank web database in MS Access
Add and save a table
Create a default form from that table and put a button on it
Create a new VBA module "Module1" and put the following function in it:
Public Function DoTest()
MsgBox "Test function runs smoothly"
End Function
Create a client-macro "Macro1" with RunCode: Function Name: DoTest() (Note that IntelliSense recognizes the macro, and it runs fine from here)
Create the form's button's on-click macro event RunMacro: Macro Name: Macro1
Click the form's button from form-view to receive the error:
The function you entered can't be used in this expression.
You may have used a DoEvents, LBound, UBound, Spc, or Tab function in an
expression.
You may have used an aggregate function, such as Count, in a design grid or in a calculated control or field.
Clicking "Ok" shows error number 2426 or 2950 depending on if you have an equals sign before your function name or not in the client-side macro's RunCode command.
I've tried all of the tips from this very similar question without any luck. Access seems to find the function fine, as replacing the function name with gibberish gives a very different error.
What the heck am I doing wrong?
In my actual web database which uses Access Services published to SharePoint 2010, I use an If IsClient() Then macro statement on the form's button's on-click event to ensure that the VBA is only running in the client mode, but that is not relevant to the error I'm receiving.
After some extra digging, I came across this post in another forum.
Here, the author simply explains that what I'm trying to do doesn't work (when you would think that it should).
Because it's on another forum, I'll spell out the workaround that also worked for me (credit: jakedrew, UtterAccess post, Jun 9 2011). Basically, you need to use a client-form in addition to a client-macro as intermediate steps to get from your web form to VBA. I made this effective for my current application by doing the following:
I re-saved my function as a sub instead:
Public Sub DoTest(ByVal intArg As Integer)
MsgBox "Test sub runs smoothly with argument = " & intArg
End Sub
Create a client-form (mine is named "frmVBA_Bridge") and create the following OnOpen event:
Private Sub Form_Open(Cancel As Integer)
' run your code using this command. Note that if you don't have an argument, you won't include the part of this line following the comma
Application.Run TempVars("SubName").Value, TempVars("Arg1").Value
' reset the "parameters"
TempVars("SubName").Value = ""
TempVars("Arg1").Value = 0
DoCmd.Close acForm, Me.Name, acSaveYes
End Sub
The client-side macro "Macro1" now instead does:
OpenForm
Form Name frmVBA_Bridge
View Form
Where Condition
Data Mode
Window Mode Hidden
The web form's button's on-click embedded macro gets changed to:
If IsClient() = True Then
SetTempVar
Name SubName
Expression ="DoTest"
SetTempVar
Name Arg1
Expression = 100
RunMacro
Macro Name Macro1
End If
Quite a bit of a workaround for such a simple thing, but it seems to do the job!
As a first step in creating a VBA script to resize a currently selected image to 100% x 100%, I'm trying to reproduce the example in http://msdn.microsoft.com/en-us/library/ee814736(v=office.14).aspx. The macro is very simple:
Sub Test()
MsgBox ("Hello world")
End Sub
The VBA script was simply created in "Project1" which opens by default when one presses Alt+F11. However, I keep getting the error "Sub or Function not defined" when trying to run the VBA script (Figures 1 and 2).
How can I make the VBA script 'accessible' to Outlook?
Figure 1 Running the "Test" macro in Microsoft Outlook
Figure 2 "Sub or Function not defined" error, with module tree in the background
I solved the problem by following the instructions on msdn.microsoft.com more closely. There, it is stated that one must create the new macro by selecting Developer -> Macros, typing a new macro name, and clicking "Create". Creating the macro in this way, I was able to run it (see message box below).
I had a similar situation with this issue. In this case it would have looked like this
Sub Test()
MsqBox ("Hello world")
End Sub
The problem was, that I had a lot more code there and couldn't recognize, that there was a misspelling in "MsqBox" (q instead of g) and therefore I had an error, it was really misleading, but since you can get on this error like that, maybe someone else will notice that it was cause by a misspelling like this...
This error “Sub or Function not defined”, will come every time when there is some compile error in script, so please check syntax again of your script.
I guess that is why when you used msqbox instead of msgbox it throws the error.
This probably does not answer your question, but I had the same question and it answered mine.
I changed Private Function to Public Function and it worked.
I need to add that, if the Module name and the sub name is the same you have such issue.
Consider change the Module name to mod_Test instead of "Test" which is the same as the sub.
I think you need to update your libraries so that your VBA code works, your using ms outlook