I don't know where i have gone wrong. The Script works but it doesn't automatically run unless i go into the VBA application and click the play button for the script to run. Can someone help?
Private Sub HideChart1()
If ActiveWorkbook.Sheets("User Interface").Range("F8") = "Yes" Then
ActiveWorkbook.Sheets("Sheet1").ChartObjects("Chart 6").Visible = True
Else
ActiveWorkbook.Sheets("Sheet1").ChartObjects("Chart 6").Visible = False
End If
End Sub
Handle SheetChange, and call your procedure in there.
Private Sub Worksheet_Change(ByVal Target As Range)
HideChart1
End Sub
Done. Don't implement logic in event handlers, it's the first Gate of Hell and spaghettification. Having a separate, dedicated procedure for it is perfect - all you need is something that calls it automatically.
If HideChart1 is implemented in its own standard module, you'll need to make it Public to be able to call it from a worksheet's code-behind; add Option Private Module at the top of that module to avoid exposing members as macros and/or worksheet functions.
You want to use a Worksheet Change event.
Untested, but should work. Put this in your "User Interface" worksheet module.:
Private Sub Worksheet_Change(ByVal target As Range)
If target = Range("F8") And target.Value = "Yes" Then
ActiveWorkbook.Sheets("Sheet1").ChartObjects("Chart 6").Visible = True
Else
ActiveWorkbook.Sheets("Sheet1").ChartObjects("Chart 6").Visible = False
End If
End Sub
With Worksheet Change, I don't think (keyword "think") you need to specify the worksheet the Range("F8") is expected to be on, since it's by definition, the activesheet. If you want though, add the sheet name before that to be sure.
If my comment is correct, then you'll need something like this:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Target.Worksheet.Range("F8")) Is Nothing Then
If Target.Worksheet.Range("F8").Value = "Yes" Then
ActiveWorkbook.Sheets("Sheet1").ChartObjects("Chart 6").Visible = True
Else
ActiveWorkbook.Sheets("Sheet1").ChartObjects("Chart 6").Visible = False
End If
End If
End Sub
You can find more information about the worksheet change event here
automatically execute an Excel macro on a cell change
The key takeaway from that question, is to put the code in the worksheet module, not a regular module, or the workbook module.
Related
Is it possible to make a VBA script or something else that automatically pushes a button with a macro in it?
For example, if the cell (1:I) has WAAR in it, that the button (planning maken) is pushed automatically (see image)?
It doesn't have to be this way, if you know something else it's fine too.
No, it is not possible to "push a button" automatically.
However, I imagine that the code behind the "push button" is something like:
Sub CommandButton_Click(Target as Range)
...
End Sub
What you can do, is create a macro that launches this procedure, but then you have the problem, when would anybody launch that macro? There, you have provided the answer (more or less) yourself: when cell "I1" gets a certain value. This, however, is not possible: you cannot declare a macro to be launched when a cell gets a certain value.
But: you can launch a macro when any cell is changed, it works as follows:
What does this all mean?
In the VBA project editor (left pane), you need to select your sheet, and in the source code editor, you need to go for "Worksheet" and "Change", like this you have the event which is called whenever some value changes in your worksheet.
The code itself looks as follows:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Row = 1 And Target.Column = 9 And Target.Value = True Then
CommandButton_Click (...)
End If
End Sub
This means that the macro will always be launched, but you only want something to happen when:
Target.Row = 1 (which correspond with cell "I1")
Target.Column = 9 (which corresponds with cell "I1")
Target.Value = True (which corresponds with value `WAAR`, I assume here that `WAAR` is just
the Dutch translation for the boolean `True` and not some string value)
You can use Worksheet_Change event to trigger a macro. So, you have to make sub and call it from Worksheet_Change event. Sub will be same as Planning Button doing. Check below code
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("I1")) Is Nothing Then
If Target = "WAAR" Then
Call MyMacro
End If
End If
End Sub
Sub MyMacro()
MsgBox "Value is entered to I1 cell"
End Sub
Depending on which type of button it is you need to either call the Sub the button is connected to, or trigger the button_click event procedure.
Say you have a Forms button which is calling the Sub Test:
Public Sub Test()
MsgBox "Forms Button clicked"
End Sub
In your Worksheet_Change() procedure your code would look like this:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Row = 1 And Target.Column = 9 And Target.Value = True Then
Test
End If
End Sub
If you have an ActiveX button your code would look like this:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Row = 1 And Target.Column = 9 And Target.Value = True Then
Sheet1.CommandButton1.Value = True ' This triggers the click event
End If
End Sub
I am trying to create a drop down list that will run a macro with each option selection. The drop down list will contain "Google" and New Businesses". When Google is selected, I need a certain macro to run. I have the macros codes ready to go, just wondering if this is even possible since I am working on a Macbook.
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("F4")) Is Nothing Then
Select Case Range("F4")
Case "Google": Google
Case "New Businesses": New_Businesses
End Select
End If
End Sub
The code above is located in the first sheet with Worksheet and Change as the drop down options. The following codes are located in Module1:
Sub Google()
'First Macro
Call GoogleManagementFee
'Second Macro
Call HideTermsAndConditions
End Sub
Sub GoogleManagementFee()
Sheets("THIRD-PARTY").Range("C26").Value = 0
End Sub
Sub HideTermsAndConditions()
Worksheet("SOW").Range("54:110").Rows.Hidden = True
End Sub
Sub New_Businesses()
Call UnhideTermsAndConditions
Call ManagementFee10
End Sub
Sub UnhideTermsAndConditions()
Range("54:110").Rows.Hidden = False
End Sub
Sub ManagementFee10()
Sheets("THIRD-PARTY").Range("C26").Value = 0.10
End Sub
I believe these codes should enable macros to run when I select either Google or New Businesses from the drop down menu I created. I'm wondering if I need to download ActiveX or if I simply did something wrong with the codes.
This is just an example of what I want to do. I have an elaborate macro that I want to do different things depending on whether it was called by another macro or not.
sub Example()
Call MyCode
end sub
sub MyCode()
If Called by Example GoTo SkipNextLine
Do these things
exit sub
SkipNextLine:
Do other things
end sub
You can create hidden name (which, actually, isn't tied to range). Think of it as global variable. The difference between global variable and this name is that name is persisted in workbook when you close it. When you open workbook again - you can start using it without any initialization. As a bonus, this name won't be displayed in Name Manager. The defining of name is required only once.
Sub SetHiddenName()
Names.Add Name:="Caller", RefersTo:="StartValue", Visible:=False
End Sub
Sub FF()
Names("Caller").Value = "FF"
Call SS
End Sub
Sub SS()
Select Case [Caller]
Case "FF": MsgBox "Called by FF" '...
Case "ZZ": MsgBox "Called by ZZ"
End Select
End Sub
A simple approach would be to use arguments and parameters.
Sub Example()
Call MyCode("Example")
End Sub
Sub Example2()
Call MyCode("Example2")
End Sub
Sub MyCode(Origin as String)
Select Case Origin
Case "Example"
'Do stuff here
Case "Example2"
'Do other stuff here
End Select
End Sub
I made my way to this post wanting a macro that changed things on the sheet, but not wanting to kick off event driven macros. In case it's also useful for someone else, it's possible to turn these off in excel using Application.EnableEvents in the parent macro using:
Sub parentMacro()
Application.EnableEvents = False
'Do stuf here
Application.EnableEvents = True
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
'this now only is called on worksheet changes outside of parent macro,
'as it's disabled while parent runs
'Note: This disables all event macros running, so might not be perfect for all cases
End Sub
I'm trying to capture the worksheet change event when a table heading is cleared by the user.
Private Sub Worksheet_Change(ByVal Target As Range)
application.EnableEvents = False
If Not Intersect(Target, Me.ListObjects("Table1").HeaderRowRange) Is Nothing Then
msgbox "Hello"
end if
application.EnableEvents = True
End Sub
If the user presses "delete" to clear a non-default heading name on the table, Excel automatically replaces the blank heading with the default heading name (eg. "Column1"). This seems to cause the worksheet change event to run multiple times. I'd like to figure out a way to have this event run only once when the user clears the a heading.
Any help is greatly appreciated.
The easiest workaround for this is to add an assertion at the beginning of your event, that checks that the target cell does not already contain a default column name.
I would do this with a simple if and like statement, which catches when a heading begins with "Column" and exits the event using Exit Sub. You could do all of this in one simple line of code. Something like...
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.value Like "Column*" Then Exit Sub
application.EnableEvents = False
If Not Intersect(Target, Me.ListObjects("Table1").HeaderRowRange) Is Nothing Then
msgbox "Hello"
end if
application.EnableEvents = True
End Sub
This code is admittedly untested but it should provide you with a good base to start from.
I don't seem to understand the strange behaviour of Excel 2007, and after a dozen solutions, I came to you asking for help.
I have office 2007.
Here is my class module code :
Public WithEvents App As Application
Private Sub App_SheetChange(ByVal Sh As Object, ByVal Target As Range)
MsgBox "event din app"
End Sub
Here is my InitializeAppObject module :
Dim X As New EventClassModule
Sub InitializeApp()
Set X.App = Application
MsgBox "am facut setarea"
End Sub
Here is my Sheet one code :
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Not Application.Intersect(Target, Me.Range("a1:c10")) Is Nothing _
Then
Application.EnableEvents = False
MsgBox "suntem in range"
Application.EnableEvents = True
Else
MsgBox "nu suntem in range"
End If
End Sub
Before changing any values on the grid, I execute the InitializeApp() procedure.
From my understanding, the sheet event should be triggered first, then the workbook one, and then the application one. However this is not the case. It first fires up the workbook one, the the application one, and finally the sheet one.
Is Excel malfunctioning or I got it wrong ?
How can I execute just the sheet event? cause obviously the Application.EnableEvents = false is not doing any good from stopping the event from being triggered upstream.
Thank you so much in advance for all your help!
kind regards,
radu
I think the problem may be that you're using the SelectionChange event in the sheet module. You're correct about the order of events. Here's how it goes - you're events have a *
Worksheet_Change
Workbook_SheetChange*
Application_SheetChange*
then assuming the selection moves after you enter something
Worksheet_SelectionChange*
Workbook_SheetSelectionChange
Application_SheetSelectionChange
Nothing in your code is triggering events, so putting message boxes in between EnableEvents doesn't achieve the desired result. All of the events are already queued up by the time the first event code runs. If instead, you had
Private Sub App_SheetChange(ByVal Sh As Object, ByVal Target As Range)
Application.EnableEvents = False
Sh.Range("a1").Value = 1
Application.EnableEvents = True
End Sub
Then the code that changed the value of A1 would not trigger any events. If you only want to run the Worksheet_Change event, you should delete the other event code. OK, it's probably there for a good reason. But whatever the logic is for when you run which event code needs to be in the procedure. For instance, if you only want to run the Worksheet_Change event on a particular worksheet name "Master", you would set it up like this
Private Sub App_SheetChange(ByVal Sh As Object, ByVal Target As Range)
If Sh.Name <> "Master" Then
MsgBox "event din app"
End If
End Sub
And the Worksheet_Change event code would be in master sheet's class module, so it would only respond to events on that page.