I'm creating the game War in Excel using VBA. Everything is working, the only thing I need to do is be able to reset everything to it's original values when the game is over or if they press a reset button. After the game is over is easy because I just save the values in a variable at the beginning of the module. However, I don't know how to get the original values for the reset button. How do I make the values from the first button public so I can access them in the reset button? Or do I need to set up a Workbook_Open event and record the values when the project is open and then reference them in the other modules? I have no idea how to do this however so any help will be appreciated.
When you declare a variable outside a Sub or Function, it will be publicly available within your project. These public variables also must be declared in either a Module or Class Module, and not inside ThisWorkbook code or one of the Worksheets code.
You could then have a Sub SetInitialValues that sets the original values and call it in Workbook_Open and when the reset button is pressed.
Example:
Option Explicit
Public player1Name As String
Public player2Name As String
Sub SetInitialValues()
player1Name = "John"
player2Name = "Peter"
End Sub
Related
I want to call/ activate a button at the end of a Sub. I know the cell address of the command button, but I don't know the name/ID of the button.
How do I select/activate the button without looping through each button on active sheet?
https://stackoverflow.com/a/30600479/13049793
I have created my buttons on multiple rows with each assigned to the same macro, from my understanding, I cannot call the macro the button is assigned to because the macro uses the button's relative position, below is a simple example to illustrate the use of the buttons relative position:
Sub ExampleButtonClick()
Dim Cellvalue As String
Cellvalue = ActiveSheet.Buttons(Application.Caller).TopLeftCell.Offset(0, -1).Value
Msgbox (Cellvalue)
End Sub
i assume you want to run one macro that at the end initiates a different macro, i also assume the reason the button is rather not as a sub that is just called is because it has its independent function that can be used without the other sub
assuming that you used a command button as an activeX control, why not just use a private sub that the button performs and place that in an individual module and at the end of your current sub;
call module1 'assuming the private sub exists in module 1
or rather include the code even if duplicated in the first sub, searching for a button seems the circular route unless there is another intention you wish to pursue.
maybe elaborate on the task at hand or post the current code you are working on?
I have a userform that is used to generate reports.
In case i have to share the userform with someone i share the entire excel sheet.
Is it possible to make the existing user form as an Add-in.so that,once installed it can be accessible through any excel sheet that is opened and not just that particular excel sheet.
Thanks in advance.
Yes, you can, but, you need to do a bit of preparation.
Ensure your addin has a Project name that differs from the name of your workbook. For example, if your user's workbook's Project is called VBAProject, then your add-in's project name must be (and should be named something more appropriate anyway) as something like MyAddin.
So, you have:
Book1.xlsm (Project name = VBAProject), and
MyAddin.xlam (Project name MyAddin)
Steps:
Within Book1/VBAProject, add a reference (Tools..References) to MyAddin.
Within MyAddin, create your UserForm (MyUserForm)
For early-binding, we need to make the form instancing PublicNotCreatable, but the VBE UI doesn't offer that property for forms, so we need to export the form to a file folder, then edit the MyUserForm.frm file, changing the Attribute VB_Exposed attribute to True (by default it's False). That is, in a text editor, edit the exported file named MyUserForm.frm and adjust the existing line as follows:
Attribute VB_Exposed = True
Save the file changes, (delete the original form in MyAddin) and then Import the MyUserForm.frm into the project. The new user form will have PublicNotCreatable instancing.
Add a public factory function to MyAddin, that will create a new instance of the form, and return it to any VBA that calls it:
Public Function GetUserForm() As MyUserForm
Set GetUserForm = New MyUserForm
End Function
In Book1.xlsm, you can now write code like the following, along with full early-binding support.
Public Sub test()
Dim frm As MyAddin.MyUserForm
Set frm = MyAddin.GetUserForm()
frm.Show
End Sub
Yes, you can share the userform.
Right click on the userform and Export it.
And you can add the form by Importing it.
Thanks
In VBA for Excel, how do I assign an existing function or sub, say myFun(), in a module to a newly added ActiveX click button directly?
I understand I can do the following on the worksheet code page where the ActiveX command (click) button is located.
Private Sub myFun_Click()
myFun()
End Sub
By "directly" I mean naming the button "myFun" and point the button directly to the function myFun() with having to placing myFun() in another sub as shown above.
There are 2 types of controls you can place on a worksheet:
ActiveX controls
You handle their Click event in the code-behind, by double-clicking the control and generating a handler for it.
Form controls
You assign a macro to these controls, exactly like you would assign a macro to any other shape. The macro can be an existing one (any parameterless Public Sub procedure in a non-private standard module).
If you want to assign a button to MyFun, assuming the signature looks like this:
Public Sub MyFun()
Then you can try using a form control instead of an ActiveX control.
Note: MyFun() has to be a Sub to be exposed as a Macro. A 'Sub' is a procedure, not a function. A 'Function' has a return value, a 'Sub' doesn't. A 'Function in a standard code module (.bas) can be exposed to be used in worksheet formulas as a UDF, a 'Sub' in a standard code module (.bas) can be exposed to be used as a macro.
VBA events bound to control are "local" to the worksheet by defintion, therefore if you put button "A" on a worksheet "w1" the resulting click event handler function will be named:
Private Sub A_Click()
But if you put button "A" on worksheet "w2" the click event handler signature will be the same but actually trigger the click event of the button placed on "w2".
If you want to implement the same behavior when the user clicks on button "A" from different worksheets, then you need to do this by adding a Sub/Function on a VBA Module, which is shared among all the worksheets of the workbook object.
Private Sub A_Click() {
CommonFunction()
}
I have already looked at these two posts:
Closing a Userform with Unload Me doesn't work
Error when closing an opened workbook in VBA Userform
They both suggest that when you want to close a file from Form code, you need to Unload the Form first (using Unload Me). However, if I Unload, I have a global array that's getting dereferenced.
Take a look at my code below though (which crashes on assigning global_int(0,0) to test). I can't Unload the Form unless I remove the array. Is this really the only solution to this problem?
Create a fresh excel file. In it, create a Userform. On that, create a Command Button with the following Click event code and global declaration:
Private global_int(2, 10) As Integer
Private Sub CommandButton1_Click()
global_int(0, 0) = 23
Dim filename As String
Dim opened_workbook As Workbook
filename = Application.GetOpenFilename() ' User selects valid Excel file
Set opened_workbook = Application.Workbooks.Open(filename)
' File operations would occur here
Unload Me
opened_workbook.Close ' Exception thrown here
Dim test As Integer
test = global_int(0, 0)
MsgBox "If you got here, it worked!"
End Sub
I'm just adapting someone else's code to work on a Mac, so I'd like to avoid completely refactoring if possible.
Thanks.
based on what I can understand is you have a userForm and the code is inside there. You can't unload the user form from inside the userForm code and expect the rest of the code to work. One option would be to write the code in a separate module. Call the user form to run from there
My question is basically answered in this post
But instead of the class code below:
Sub CmdEvents_Click()
MsgBox "Hello World"
End Sub
I need to run this code (it's just a sample, I want to use the name of the button clicked later in the program)
Sub CmdEvents_Click()
Dim mvCtrl As Control
Set mvCtrl = Me.ActiveControl
MsgBox mvCtrl.Name
End Sub
But this code above will NOT, by any means return correctly the Name of the button I just created in run time in the message box.
It returns "Button 6".... I did a search in my workbook and I don't even have this name.
I actually I modified the original code from the link above to get the names of the buttons all from a list. This way I can modify the list, thus modifying the name of the buttons, or caption if I want to. And this Button 6 doesn't even exists in my list.
I made some traps in my code, showing message boxes for the variable I use to get the button name from, and it's correct, it's carrying the string I want to name my button before it creates it.
Assuming you followed the post you linked to, your class instance already contains a variable CmdEvents which references the clicked button, so you can use
Msgbox CmdEvents.Name
If your code is different, it would be useful to post the relevant parts so we can see what's going on.