I am having trouble assigning a value to constant variant declaration. So the declaration is this
Option Explicit
public const Abc as variant = ?
Abc is a Microfocus rumba object which gets initiated when the workbook is open, something like this
sub workbook_open()
Set Abc= session.GetRDEObject()
End sub
But I cannot use this to assign it to the const variable, it says "Circular dependencies". The reason I am wanting to assign value is to ensure the object Abc is alive even after user executes End statement. Is there a way I can do this?.
I have tried creating a separate function and adding its return value to the Abc, but it does not work.
A constant is exactly that, so try something like this:
Option Explicit
Private Abc As Object
Private Sub Workbook_Open()
Set Abc = Session.GetRDEObject()
End sub
Public Function GetAbc() As Object
Set GetAbc = Abc
End Function
Related
Edit: Please note that I am aware this code will fail at run-time. I kept it as short as possible for the demonstration of the issue.
Consider this VBA class module "TestClass":
Option Explicit
Public TestCol As New Collection
In a standard module, this won't compile:
Sub Test()
Dim Smth As New TestClass
Smth.TestCol(1) = "Something"
End Sub
Error message given: "Wrong number of arguments or invalid property assignment"
This will compile just fine:
Sub Test()
Dim Smth As New TestClass
Smth.TestCol.Item(1) = "Something"
End Sub
This will also compile fine:
Sub Test()
Dim Smth As New TestClass
Dim X as String
X = Smth.TestCol(1)
End Sub
It's the same with e. g. dictionaries.
Why will the compiler not allow access to the default member .Item without explicitly stating it?
The Items in a Collection are primarily objects, even though the value of the Item is a Variant and may contain any type.
The following code will not cause a compile error because it uses the Set keyword to assign an object.
Sub Test()
Dim Smth As New TestClass
Set Smth.TestCol(1) = New TestClass
End Sub
However, this code will fail at runtime because you cannot assign to an Item in a Collection directly. (Use Remove+Add instead.)
I'm pretty new to VBA but I have been trying to figure out what is going wrong here. When I try to set a variable declared in my class module from a Sub in my module, the value isn't assigned for some reason and I can't figure out why. How do I get the variable table to go all the way through to the function call response = add_edit_data("fund_management.db", table)? It all compiles and runs, until it reaches the add_edit_data function which of course does not work without this variable. My Debug.Print checkpopup.table in the Sub returns nothing although I know the variable table from calling the Sub is set correctly as Debug.Print table returns the correct value when called from inside the Sub.
My module looks like this:
Private checkpopup As class_checkpopup
Public Sub checkbox_popup_fund(table)
Set checkpopup = New class_checkpopup
checkpopup.Show
checkpopup.table = table
Debug.Print checkpopup.table
End Sub
The class module is:
Public table As String
Private WithEvents check_box_popup As check_box
Private Sub Class_Initialize()
Set check_box_popup = New check_box
End Sub
Public Sub Show()
check_box_popup.Show
End Sub
Private Sub check_box_popup_Closed()
End Sub
Private Sub check_box_popup_Yes()
response = add_edit_data("fund_management.db", table)
End Sub
and I activate the eventhandler with:
Public Event Yes()
Private Sub check_box_yes_Click()
RaiseEvent Yes
End Sub
Thank you to Nicholas Hunter and Variatus for helping me out. I wasn't aware that it mattered to set the variable before showing the Form, but it does. I changed my module to:
Private checkpopup As class_checkpopup
Public Sub checkbox_popup_fund(table)
Set checkpopup = New class_checkpopup
Let checkpopup.table = table
checkpopup.Show
Debug.Print checkpopup.table
End Sub
and now my value carries through all the way to my function. Thank you very much for the help
In an Excel 2007 workbook I have three Excel modules, each containing one subroutine. The Driver sub (UpdateDataFromOracle) calls the subs UpdateResponse and UpdateSched. The code is working fine, but I'd like to check the "return code" of each of the called subs. I only want the Driver sub visible to the user, so I made the subs in Modules 1 and 2 Private.
Module 1 Private Sub UpdateResponse
Module 2 Private Sub UpdateSched
Module 3 Public Sub UpdateDataFromOracle
Here's code from the Driver sub
Sub UpdateDataFromOracle()
'DECLARE VARIABLES
Dim varSchedReturn as variant
'...
Call UpdateResponse
Call UpdateSched
'I Would like to insert the "return code" check here
End Sub
Here's code from the Called sub
Option Explicit
Private Sub UpdateResponse()
'DECLARE VARIABLES
'...
If Sheets(strTempSheet).UsedRange.Rows.Count > 10 Then
UpdateResponse = 0
Else UpdateResponse = 90
End If
End Sub
To call the Private subs I had to abandon the "Call" and use"
Application.Run "Module1.UpdateResponse"
But I can't figure out how to get a return code that way.
I also made UpdateResponse and UpdateSched Private Functions, but I still couldn't figure out how to get a return code back.
When I made UpdateResponse and UpdateSched Public Functions, I can use a statement at the end of the called subs like:
Else UpdateResponse = 90
The problem is that the called subroutines are visible to the user if I leave the functions Public.
My goal is to have only the Driver sub visible to the user, and be able to evaluate some sort of "Return Code" from the called subs in the Driver sub.
Thanks for looking at this.
I didn't fully read the question, but change them to Function
Private Function UpdateResponse() As Integer
'DECLARE VARIABLES
'...
If Sheets(strTempSheet).UsedRange.Rows.Count > 10 Then
UpdateResponse = 0
Else
UpdateResponse = 90
End If
End Function
Then:
Dim response ' As Variant or Integer
response = Application.Run("Module1.UpdateResponse")
Also, there are 2 better ways with Option Private Module or a public variable in Module1
3 Ways to Call a Private Sub from Another Module
The answer #DougGlancy gave worked well. It's listed as a comment to my original question, so I'm adding this Answer to indicate that his answer was correct.
One option for Windows Excel that I have used is to set values on the user's machine that can be retrieved in a later process.
https://msdn.microsoft.com/en-us/library/z46c489x(v=vs.110).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-1
Alternatives could be to set some properties of your Excel workbook or in Excel you can create names and values associated with them. (part of named ranges).
Lastly, you can add and change values in the windows registry.
I am writing a module with several subs, and I need some variables to have the same value in all the modules. I know about declaring variables as
Public varname as vartype
but how can I assign a global value to such a variable?
Thanks
For a worksheet object (any object for that matter) you need to do the following:
In a standard code module:
Public varName As Excel.Worksheet
In the Workbook_Open() event:
Private Sub Workbook_Open()
Set varName = Sheets("mySheet")
End Sub
Then you can refer to varName in any other module for that workbook and it will point to your worksheet object.
From your question/comments, it seems that you actually want some sort of object constant, which can't be done in VBA - see Declare a Workbook as a Global variable for more infromation.
If you're referring to a value data type such as String, Integer or Long then you can use a constant instead of a variable, however a constant's value cannot be changed once it has been declared (kind of the definition of 'constant') i.e.
Public Const someName As String = "Macro Man"
Public Const someNumber As Long = "1234567890"
Public Const someInt As Integer = "1453"
Is it possible to have a static variable declared in one procedure, and use this variable in several different procedures using Excel VBA?
i.e.
Public myvar as integer
Sub SetVar()
static myvar as integer
myvar=999
end sub
sub Usevar()
dim newvar as integer
newvar=myvar*0.5
end sub
I need myvar to be seen by other procedures, and not change or get "lost". The code above works if myvar is not declared as a static variable, but more code then the variable is "lost". If the static declaration is used, myvar is not seen by the usevar procedure. And "Public Static myvar as integer" is not accepted by VBA.
Thanks for your help
Zeus
Try this by calling MAIN() :
Public myvar As Integer
Sub MAIN()
Call SetVar
Call UseVar
End Sub
Sub SetVar()
myvar = 999
End Sub
Sub UseVar()
Dim newvar As Variant
newvar = myvar * 0.5
MsgBox newvar
End Sub
If you declare an item Static , its value will be preserved within the procedure or sub.If you declare the item Public , its value will be preserved and it will be visible to other procedures as well.
Although this question was answered over four years ago by #Gary's Student, there's a subtle nuance worth mentioning, since the solution can depend on the data type of myvar.
First of all, as you've noted in the question, Public Static myvar as Integer doesn't work, because Static is only allowed inside a sub or function.
As noted in the comments to the OP by #Patrick Lepelletier, you can easily get around this by declaring a Constant instead (assuming you don't need to change it dynamically): Public Const myvar as Integer = 999. (Or possibly Private Const myvar...)
Another option is to declare myvar as a function instead of a variable or constant, effectively turning it into a pseudo-constant:
Private Function myvar() as Integer
Static intMyvar as Integer
intMyvar = 999
myvar = intMyvar
End function
In this simple example where myvar is an integer, the pseudo-constant approach is obviously unnecessary and adds the overhead of a function call. Simply declaring a Constant does the job. However, using a constant only works if the value is static and not an object. It will not work if myvar is an object, for example a Range. In that case, using pseudo-constants might be useful:
Private Function myvar() as Range
Set myvar = Range("A1")
End Function
Another advantage is that you can use code inside the function to check for certain conditions and assign different values to myvar accordingly.
The pseudo-constant approach can also be combined with naming worksheet ranges: If cell A1 is a named range, say MyRange, then you could write:
Dim strMyString as String
strMyString = "MyRange"
Private Function myvar() as Range
Set myvar = Range(strMyString)
End Function
Now it is possible to move around the content of cell A1 without breaking the code, since the named range follows along if you cut and paste the cell. I find this approach useful in the design stage, when things tend to move around a lot in a worksheet.
Pseudo-constants also help avoiding some problems usually associated with global (or module-level) variables that might be an issue in larger projects.
The key is to use 2 variables. In the code below, myvar is public but not static. stvar is static but not public. Its scope is only within Main(). By assigning myvar=stvar and stvar=myvar, it effectively creates a variable that is both public and static. The value is preserved.
Public myvar As String
Sub Main() 'in module 1
Static stvar As String
myvar = stvar
toInput
stvar = myvar
End Sub
Sub toInput() 'in module2
myvar = InputBox("enter something", "Input", myvar)
End Sub