Im having trouble takign my assigned variable and offseting it. What am I doing wrong?
Public Sub SampleBox_Change()
Dim str As Integer
If (SampleBox.ListIndex > -1) Then
str = SampleBox.List(SampleBox.ListIndex)
End If
End Sub
Public Sub Samplesdel(str As Integer)
Range(Range("BA1").EntireColumn, Range("BA1").Offset(0, -str).EntireColumn).Select
End Sub
Public Sub CommandButton1_Click()
Application.Run "Samplesdel"
End Sub
So the variable (str) is a whole number. I would like to use this number to select a certain number of columns (from BA1 to "left however many columns valued as str"). so if the user selects 8 i would like to select BA1 and left 8 columns.
The combobox is in a userform where the code for the assigned variable is set.
I would like to use the assigned variable in a macro (where i used the select function).
so the variable str gets assigned from a userform combobox. I would then like to pass this variable to a macro where i use it in the offset function.
I just used your snippets of code here, I'll assume you know what you're trying to accomplish with this. As mentioned in another answer, I think it's an issue of scope; it doesn't seem like there's a good reason you can't combine your statements as follows:
Public Sub SampleBox_Change()
Dim str As Integer
If (SampleBox.ListIndex > -1) Then
Range(Range("BA1").EntireColumn, Range("BA1").Offset(0, SampleBox.ListIndex).EntireColumn).Select
End If
End Sub
To add some unsolicited feedback, naming a variable that is an integer "str" will be very confusing to anyone else that has to read your code, the name "str" implies "string", a different data type.
James, you are setting the value of str here correct?
Public Sub SampleBox_Change()
Dim str As Integer
If (SampleBox.ListIndex > -1) Then
str = SampleBox.List(SampleBox.ListIndex)
End If
End Sub
The scope for str will only be this function and it will not be able to be accessed by any other function.
What value are you passing to Samplesdel as the parameter?
Application.Run "Samplesdel"
Related
I am having trouble with losing static variables within an Excel user form.
I have been working on a routine for excel. I am a (very) novice coder.
I am attempting to populate a cell range to an array. I have been able to do this without issue.
However, when I attempt to store the array as a *static * variable, the variable is not retained for as long as I want it to be.
I think the problem occurs when another page is selected in the multipage, the static variable is cleared.
Code is something like this:
Sub UserForm_Initialize ()
static myArray () as variant
dim myRange as range
set myRange = [namedrange]
myArray=myRange
msgbox myArray(0,0) 'this works fine
call OtherSub
end sub
sub OtherSub ()
msgbox myArray(0,0) 'this returns a blank
end sub
The first sub of code shows the array element just fine. The array element is blank in the second sub.
I have tried:
Declaring the array as a public variable, but this returns an error (I think that variables within user forms are private by default and cannot be changed).
using a very small variable (a simple string)
writing code in a module before opening the user form (variable is not retained).
I am aware that I can just write data to a cell range, but this would defeat the purpose. I was hoping to avoid multiple instances of reading large arrays from the worksheet.
This might explain it a bit clearer. Moving MyArray outside of the Procedure will set it's scope to a Module Level, making it usable through other subs within that module. You will generally want to keep the scope of your variables to the lowest level required. The other option would be to pass your variable as a parameter to your other procedure.
Option Explicit
Dim MyArray() As Variant ' Private Module Level Scope
Public ExampleVariable As String ' Public Module Level Scope (Not required, just showing an example.)
Sub UserForm_Initialize()
Dim myRange As Range ' Procedure Level Scope
Set myRange = [namedrange]
MyArray = myRange
MsgBox MyArray(0, 0) 'this works fine
Call OtherSub
End Sub
Sub OtherSub()
MsgBox MyArray(0, 0) 'this returns a blank
End Sub
I encounter a weird problem that I believe is related to Excel behavior, rather than to my code.
I have a global variable named "numEtape", which is an integer. My code consists in several steps where the user has to type data on a sheet, then press a button which saves the data in an array and increments the "numEtape", before going to the next step.
The code (simplified) looks like this :
Dim numEtape As Integer
Sub AjoutEssai()
numEtape = 2
UFPreAjoutInfos.Show 'Unrelated Userform that asks user for more informations, but doesn't modify "numEtape" or call any other macro
Call InterfaceFiller
End Sub
Sub InterfaceFiller()
Dim rangedubtn As Range
Dim btnPrecedent As Button
Select Case numEtape
Case 2
'Change value of some cells
Case 3
'Change value of some cells
Case 4
'Change value of some cells
Case Is >= 5
'Change value of some cells
Case Else
Debug.Print "Error"
End Select
Set rangedubtn = Sheets("Interface").Range("M3")
Set btnPrecedent = Sheets("Interface").Buttons.Add(rangedubtn.Left, rangedubtn.Top,rangedubtn.Width, rangedubtn.Height)
With btnPrecedent
.OnAction = "mSuivant"
.Caption = "Suivant"
.Name = "btnSuivant"
End With
End Sub
Sub mSuivant()
numEtape = numEtape + 1
Call InterfaceFiller
End Sub
I don't think the code itself is important, what I can expect from it, since I first call AjoutEssai(), is for numEtape to always be greater than 2.
However, when during the steps the user opens and close other excel/office files (that don't have any vba code/macros in it), excel seems to empty numEtape, which makes the Select Case go to the Case Else.
When does excel remove global variables from memory, and is there a way to prevent this behavior from happening?
Public numEtape As Long
A viable option is to use the word public like public numEtape As Long.
Then the variable will be saving its value for as long as the Excel workbook is opened. In older versions of VBA the word was Global (What is the difference between Dim, Global, Public, and Private as Modular Field Access Modifiers?)
Dim numEtape As Long
For using Dim outside of Sub or Function, the variable will be emptied, after the code is over. Take this snippet only:
Dim numEtape As Long
Sub MainTest()
numEtape = 23
End Sub
Once you run it and you hit End Sub the variable would be emptied as well. Check after running the MainTest():
Sub PrintingVariable()
Debug.Print numEtape
End Sub
If you want to save the value, there are 2 basic ways that work:
Write the value in an excel cell
Write the value in a database
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
I have a load of variable names in a spreadsheet column. These variables are defined and have values in the modules I have in my project.
I want to have a code that references the variable name in a spreadsheet, and returns the value that it have in the module and pastes the value in another spreadsheet i.e
Sub code()
dim variable1 as integer
variable1 = 2
End sub
sheet 1: cell A1: variable1
Sub code2()
sheet(2).range("a1").value = sheet(1).range("a1").value
end sub
sheet 2: cell A1: 2
There is no way to ask for a variable by name in VBA during runtime. During compilation all variable names are stripped away, and at runtime the variables are referenced just with memory locations. Also, if the variable is declared within a sub, it only exists while that sub is being executed. If you try to access it later, something else will be using its memory location.
The only way to do this is to declare all the variables at module level, and then have a function which explicitly maps variable names to these variables:
Private variable1 As Integer
Sub code()
variable1 = 2
End Sub
Sub code2()
Sheets(2).Range("a1").Value = VariableByName(Sheets(1).Range("a1").Value)
End Sub
Function VariableByName(VarName As String) As Variant
Select Case VarName
Case "variable1": VariableByName = variable1
End Select
End Function
Actually, your best option is to forget about using variables and use names instead:
Sub code()
Names.Add "variable1", 2, Visible:=False
End Sub
Sub code2()
Sheets(2).Range("a1").Value = Evaluate(Sheets(1).Range("a1").Value)
End Sub
But when you go that route, if you need to access the variable in VBA you can't just say variable1, you need to use code like this:
Sub code3()
Dim variable1 As Integer
variable1 = Evaluate("variable1") 'bring it into a normal variable
variable1 = variable1 * 2 'now you can use it like a normal variable
Names("variable1").RefersTo = variable1 'need to save it when you're done
End Sub
This worked in Excel 2010
variable1 = [variable1].Value
VBA treats [variable1] (with brackets) as a variant that references the named cell.
-mmh
I have a Subroutine "Days" which has a variable Days. I want to pass values form that Days variable to a different subroutine "GetDays"
For eg:
Sub Day()
Dim Days() as variant
Days = Array(1,3,5,7,10,11)
End Sub
Sub GetDay()
'How do I get the values of Days here?
End Sub
Not completely sure I understand what you're after, but my best guess is that you want to set up a "DayClass" object that both holds the days values and returns them to other functions when they're needed:
(1) in the VBA editor, insert a CLASS module
(2) in the properties window for this module, change the name to (say) DayClass (overriding the default name "Class1".)
(3) put this code into the DayClass module:
Private mDays As Variant ' member variable to hold the days array
' initialization method to populate the array
Private Sub Class_Initialize()
mDays = Array(1, 3, 5, 7, 10, 11)
End Sub
' little function to return a particular value from the array
Public Property Get Day(i As Long)
Day = mDays(i)
End Property
(4) To see the code above in action, insert a regular MODULE and put this little function in it, which may be invoked from the formula bar (if you want):
Public Function GetDays(i As Long)
Dim DC As New DayClass ' DC is dim'd of type DayClass
' so via DC you can get at whatever is in there
GetDays = DC.Day(i) ' this function returns the i'th value of the
' array in DayClass, via DayClass's "Get Day" property
End Function
(5) Since "GetDays" is a public function in a regular code module, you can test this out by entering the following formula into any spreadsheet cell:
=GetDays(3)
cell result = 7