VBA using drop down lists on other worksheets to hide rows automatically - vba

Afternoon all!
I am using the results of various drop down lists to hide the relevant rows on a spreadsheet as the value on the drop down list is changed (so automatically).
With some googling, I have come across the below set up which works nicely, although I have now hit a snag when trying to specify drop down list cell from another worksheet.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim disabled As Boolean
If Range("D2") = "Yes" Then
disabled = True
End If
If disabled Then
Rows("3:8").EntireRow.Hidden = False
Else
Rows("3:8").EntireRow.Hidden = True
End If
End sub
Using the following has not worked, and googling for a solution has lead me up many a dead end:
If Sheets("Topsheet").Range("D27") = "Yes" Then
Am I unable to use values from a neighbouring sheet when declaring a variable due to it being a private sub?
Any help would be much appreciated as I have been stumped on this for a couple of hours!

Your code can be massively simplified. Try using this (You'll have to update the sheet name if it's not the same as yours)
Private Sub Worksheet_Change(ByVal Target As Range)
Sheets("SheetWithRowsToBeHidden").Rows("3:8").EntireRow.Hidden = IIf(Me.Range("D27").Value2 = "Yes", True, False)
End Sub
Also, where have you put this code? Have you put it inside a Module or is it in the Sheet Object? It needs to be in the Sheet Object that has the dropdowns on.

Related

Excel VBA to call a single macro by mutliple independent worksheet changes

I have used the following Worksheet Change VBA code which is applied to a single cell reference, and is used to call a macro dependent on selection from a data validation list. The event triggered by the macro applies to the row of the active cell.
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address(True, True) = "$H$2" Then
Select Case Target
Case "Yes"
Call StandardEntry
Case Else
'Do nothing
End Select
End If
End Sub
I would now like to be able to apply this worksheet change event to be triggered by individual cells within the same column, generating the same event within the active cells row and not affecting any other rows. Identical data validation has been applied to the other cells in the column.
I would appreciate assistance in writing the appropriate code or adjusting the code above to suit.
Thanks #YowE3K!Changing
If Target.Address(True, True) = "$H$2" Then
to
If Target.Column = 8 Then
did the trick and is a really simple solution! Yeehar!

Default values for fields in a new row of a data table

When you have a data table in Excel, part of the standard functionality is that pressing tab in the last cell adds a new row at the bottom of the table. I want to auto-populate that new row with useful default values. In particular I want to put current date-time in one cell, and copy values into some other cells from the previous row of the table.
It is not workable to do that using formulae -- e.g. using =now() for the date-time stamp is inadequate because it will be auto-updated every time the spreadsheet recalculates, whereas I want it to retain the date-time at the moment when the row was added.
So I am trying to write VBA to be triggered by the event of the row being added, and in that code to write values into the cells of the new row. From MS documentation I thought DataTable.TableNewRow would be the appropriate event. But when I try to write any code for that event it is not being executed. When I look up DataTable in the VBA object browser the TableNewRow event is not listed.
Versions:
VBA for Applications 7.1
Excel 2013
So my questions:
Is the direction of my thinking right, or can you suggest a better approach?
Can you offer any working code that does something like this?
Is DataTable.TableNewRow the event I should be working with?
What do I need to do to get that event accessible in my VBA code?
You can try this:
Write this code in Thisworkbook.
Private Sub Workbook_Open()
Set ref_tbl = Sheet1.ListObjects(1).DataBodyRange
End Sub
Then below code in a Worsksheet Object.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
On Error GoTo halt
Application.EnableEvents = False
Dim tbl_rng As Range
Set tbl_rng = Me.ListObjects(1).DataBodyRange
If Not Intersect(Target, tbl_rng) Is Nothing Then
If tbl_rng.Rows.Count > ref_tbl.Rows.Count Then
MsgBox "Table increase in size"
'~~> Do your stuff here
Set ref_tbl = tbl_rng
End If
End If
forward:
Application.EnableEvents = True
Exit Sub
halt:
MsgBox Err.Number & ": " & Err.Description
Resume forward
End Sub
You will also need a Module to declare the public variable
Public ref_tbl As Range
So basically, this will tell you when your table increase in size.
If we're able to capture that, then you can do your stuff when that condition is met.
This works in the situation you describe in your question.
It will not work though when you insert row between entries in the table. Anyways, HTH.

Turning off a worksheet change-based event macro in Excel

I've been stuck on this for awhile. I have a macro that runs every time a change is made and creates a data table that updates after each change with information like : Old Value, New Value, Data Changes, etc.
I am trying to kind of pause the worksheet change macro when I don't want it to be run anymore. Ex: If I am plugging in blank information, I don't need to document the fact that it used to be blank, and now it has data, etc.
I made some specifications for if I deleted an entire row as shown here:
If Target.Address = Target.EntireRow.Address Then Exit Sub
but that only dealt with one case. I just now thought of a very simple solution that I will post as the answer, so I hope this will help other people as much as it helped me
It's actually a very simple solution.
To begin pick a cell that has no information in but can be clearly located. For the purpose of this lets say A1.
Now pick key words that you will use to turn the macro on and off. Ex: I just chose True and False (capitals need to be consistent so pick what you want)
At this point, go to the beginning of your worksheet change macro and type in this right after the sub starts:
Private Sub Worksheet_Change(ByVal Target As Range)
If Range("A1").Value = "False" Then
Exit Sub
End If
Now, before your macro starts, it will always verify that the cell doesn't contain False, so if you want it on, put anything else but False, and if you want it off, keep the cell as False. Hope this helps someone.
You want to disable events while ensuring that you enable them later. To do this, use an error handler to catch all errors and set the state back at the end.
Public Sub example()
On Error GoTo errHandler
Application.EnableEvents = False ' => disable events
'The code ...
errHandler:
Application.EnableEvents = True ' => enable events
End Sub

Set the value of a cell when unsaved changes are detected in Excel using VBA

I'm trying to detect changes within an entire workbook (doesn't matter what changes) so that any change that occurs prior to save will result a specific cell getting set to a specific value. The goal is to show a visual indicator of whether the workbook is saved using conditional formatting (non issue, already have that set up).
The code I use to set the value of the cell is Sheets("Sheet1").Range("H1").Value = 1.
I've tried to detect changes by using Sub Worksheet_Change(ByVal Target As Range), but I'm unsure of how to set the range.
Any help would be greatly appreciated.
If I'm reading your question correctly, you want to setup your worksheet so that every time a change is made by a user, update the value in the cell.
You are already most of the way there, you just need to put the following subroutine in your workbook.
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
Sheets("Sheet1").Range("H1").Value = 1
End Sub
Once this is saved with your workbook, that specific workbook will perform the functionality you require. Here's a link to the documentation - http://msdn.microsoft.com/en-us/library/office/ff839775(v=office.15).aspx.
Private Sub Worksheet_Change(ByVal Target As Excel.Range) 'Target is the variable name of the Range where the Change occured
If thisworkbook.saved=false then
Sheets("Sheet1").Range("H1").Value = 1
else
Sheets("Sheet1").Range("H1").Value = 0 'or other value
End if
End Sub

Making excel graphs appear/disappear

I want a graph only to appear when a condition is fulfilled. To be more precise: I have a drop down menu that changes the content of a graph. If the menu point "Total revenue" is clicked, I want a second graph to appear. I am new to VBA and this is what I came up with so far:
Sub Iffuntion()
Dim SelectedChart As Range
Dim notVisible As Boolean
If Range("D100").Value = Range("E100").Value Then
ActiveSheet.ChartObjects("Testchart").Visible = True
Else
ActiveSheet.ChartObjects("Testchart").Visible = notVisible
End If
End Sub
It works, but I have to execute the VBA to make the graph appear/disappear and I would like that to happen automatically. Also the condition should eventually be in another worksheet to keep the sheet with the graphs nice and tidy. I read that to achieve this I have toI have to activate the other worksheet. Would you recommend this way or is there a better solution?
Thanks for the help and best regards!
Pete
EDIT: Here is the link to a sample file with the proposed solution of Cor_Blimey, that I couldn't get to work properly. The interconnections in the excel are more complicated than they would have to be, but I wanted to be as accurate ad possible in displaying what is actually happening in my excel. Thanks for taking a look!
https://dl.dropboxusercontent.com/u/18406645/sample.xlsm
Assuming you mean that they change, from a data validation drop down list, the contents of a cell then you can put your code into the Worksheet's Worksheet_Change event. This event is fired when the user changes the content of a cell (or by an external link).
Then test for the cell being the right cell then run your code.
Like:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rng As Range
Set rng = Intersect(Target, Me.Range("D100"))
If Not rng Is Nothing Then
If rng.Value = Me.Range("E100").Value Then
Me.ChartObjects("Testchart").Visible = True
Else
Me.ChartObjects("Testchart").Visible = False
End If
End If
End Sub