Excel clear contents of drop down based on another cell being cleared - excel

I have a cell on Sheet1 that contains a drop-down list, let's say N3. The items in the drop down change, depending on the value in J3. At start, both cells are blank. Enter data in J3, and the drop down populates in N3. If I clear the contents of J3, the drop down in N3 is now empty, but the last selected value (if one was selected), still appears as a 'ghost' entry. It's a ghost entry to ME because it is old data, but I do understand the software is doing as designed. If J3 is cleared of contents, how do I get N3 to be cleared of that last selection? I am not VBA trained, but dangerous enough to handle it if that's what's needed to accomplish this. thanks!

You may consider to use the worksheet_change event.Put the below code in sheet1 code module.
Private Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo err_rout
Application.EnableEvents = False
If Not Intersect(Range("J3"), Target) Is Nothing And Target.Value = vbNullString Then
Range("N3").Value = vbNullString
End If
err_rout:
Application.EnableEvents = True
End Sub

Related

Excel VBA: changing visible cells based on names cell value. Works once then not again

I am trying to get a spreadsheet to show a set of names rows called authorisations when there is no project number in the project ref cell but if a project number is added to the cell the authorisations are not required and should disappear.
If the cell is blank and the row visible then when project reference is added the rows disappear but if I then delete that reference and change cell they do not reappear.
Private Sub Worksheet_Change(ByVal Target As Range)
If Project_Ref = "" Then
Range("authorisations").EntireRow.Hidden = False
Else
Range("authorisations").EntireRow.Hidden = True
End If
End Sub
I have tried a search online and found comments that adding Application.EnableEvents = True before the End sub should help but it didn't seem to make a difference. I am now wondering if Worksheet_change in fact operates as I thought it did where it would look for any changes in the sheet and then execute the code if required.

Referencing an excel cell that has a variable formula on VBA

I have built an appraisal sheet that allows you select your name from a drop down and all other details about you pop up in other cells. One of such detail will either pop up as Yes or No, depending on whether you manage a team. Now, my VBA code references this cell (F8) that has Yes or No, and it hides or unhides some rows depending on the value of F8. The problem here is that F8 has a formula that was used to derive its value (A Vlookup) and the formula reads
=IFERROR(VLOOKUP($C$6,Data!$E:$I,5,0),"")
My VBA code no longer hides or unhides any cells since I started using a formula in F8. My VBA code is below
ActiveSheet.Activate
If Not Application.Intersect(Range("F8"), Range(Target.Address)) Is Nothing Then
Select Case Target.Value
Case Is = "Yes": Rows("25:26").EntireRow.Hidden = False
Case Is = "No": Rows("25:26").EntireRow.Hidden = True
End Select
End If
End Sub
Range(Target.Address) is actually the same as Target, don't over complicate things.
And ActiveSheet is called ActiveSheet because that sheet is active. So to .Activate an aleady active sheet ActiveSheet.Activate is pretty useless :)
The following should do it.
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Application.Intersect(Me.Range("C6"), Target) Is Nothing Then
Select Case Me.Range("F8").Value
Case Is = "Yes": Me.Rows("25:26").EntireRow.Hidden = False
Case Is = "No": Me.Rows("25:26").EntireRow.Hidden = True
End Select
End If
End Sub
But note that if the values in Data!$E:$I that you lookup change then the formula result of F8 =IFERROR(VLOOKUP($C$6,Data!$E:$I,5,0),"") will change without triggering the Worksheet_Change event! So be aware that after changing something in the Data sheet you need to rewrite/re-select the value in C6, to trigger the macro again.

Block cells without block the list

Is there any way to block cell without block list?
Ex: I have in cell A1 the list:
Brazil
USA
Ireland
If I block the cell using "protect sheet"
I can't select the list
If I block on VBA using the code application.cutcopymode = false
It works, but if the person paste from a notepad, for example, it doesn't work
Is there any way to block it?
Private Sub Worksheet_SelectionChange(ByVal Target as Range)
If intersect(Target, range("A1")) is nothing then Exit Sub
Application.CutCopyPaste = False
End sub
I don't think you can do so (curious if I'm wrong).
What you could do however:
1) Developers > Insert > Combobox
2) Align Combobox with cell A1
3) Assign the appropriate list and a linked cell
4) On the Protection tab, select the Locked check box
5) On linked cell make sure you deselect the Locked check box
6) Protect your worksheet
Pasting values in cell A1 no longer possible, users deleting/moving/shaping your combobox is disabled AND you can still use the validation list :)

VBA code to not allow user to select a cell with certain text

I am working on a spreadsheet to copy a users data from the previous day, then delete any numerical values but keep cells with "NA". What I want is for users to not be able to change/delete the cells that still have "NA" in them. I found some code that used OFFSET to move down one cell if a certain cell was selected (based on the row and column) but I haven't been able to figure out how to use the OFFSET to move down one cell if the current cell contains "NA". (https://www.extendoffice.com/documents/excel/3820-excel-lock-cell-without-protecting-sheet.html) This worksheet is already locked with a Quality-set password, so I can't do anything to unlock the spreadsheet, then select the "NA" cells to be locked, then relock the spreadsheet, thus looking for a creative way to keep the cells from being selected or changed. Also, the code would need to run all the time, not just when a macro was selected to run. Any ideas?
If it's possible for the user to open the book without macros enabled, then I'm not sure what you're asking is possible.
If you can assume macros are enabled though, you could use events to either prevent the user selecting the cell (similar to the OFFSET you mention) or you could track changes manually onto a hidden tab in order to note changes and deal with them as you see fit. There are many ways you can achieve the latter, just search "VBA tracking changes to a sheet" etc.
This is how you'd use the OFFSET method:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Cells(1, 1).Text = "NA" Then
Beep
Cells(Target.Row, Target.Column).Offset(0, 1).Select
End If
End Sub
Keep in mind though, this is a very simplistic method. It won't prevent users selecting multiple cells (a range) and deleting the contents. Nor will it prevent values being pasted to range that includes the 'NA'.
UPDATE:
The following is an improved version that will at least prevent users from selecting multiple cells (for pasting into or deleting) if one of the cells contains "NA".
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim testarea As Range
Set testarea = Intersect(UsedRange, Target.Cells)
If Not (testarea Is Nothing) Then
Application.EnableEvents = False
For Each cell_to_check In Intersect(UsedRange, Target.Cells)
If cell_to_check.Text = "NA" Then
Beep
Cells(cell_to_check.Row, cell_to_check.Column).Offset(0, 1).Select
Do Until Selection.Text <> "NA"
Selection.Offset(0, 1).Select
Loop
Exit For
End If
Next
Application.EnableEvents = True
End If
End Sub
This is still slightly flawed however, as it is still possible to drag-fill cells from other areas over a cell containing "NA".

Hide and unhide rows based on a value

I am trying to create a survey in Excel and want to hide and unhide rows based on their answers. For example, if D3 = "no" hide rows D4:D10, and I want to repeat this multiple times throughout, but the number of rows to hide changes. So if D3 = "yes" leave unhidden. Then move to answer D5, if D5 = "no" hide rows D6:D7. And this continues on and on throughout.
Using the worksheet_change() event. In your VBE double click the worksheet where this change (this cell) will happen. Then enter:
Private Sub Worksheet_Change(ByVal Target As Range)
'Detect if the worksheet change was on cell D3
If Not (Intersect(Target, Range("D3")) Is Nothing) Then
'Hide rows if the value of D3 is "No"
Range("D4:D10").EntireRow.Hidden = (Range("D3").Value = "No")
End If
End Sub
Every time a change happens on this worksheet this subroutine will fire off, test if the change occured in cell "D2" then toggle the row's hidden property based on the value.
The Hidden property of the EntireRow range object takes a True or False value, so we are able to just set it equal to the result of the conditional statement (Range("D3").value = "No") which will return a True or False greatly simplifying the amount of code you need to write.
You'll just need to add more If Not (Intersect(Target, Range("whatever")) Is Nothing) Then lines to test for your other cells like D5 and hide the appropriate rows base on whatever value you are testing for in that cell.
If that gets to be too much code (testing all those intersects) you can just test the intersects once like:
If Not (Intersect(Target, Union(Range("D3"), Range("D5"), Range("D8"))) Is Nothing) Then
'And then in here your individual lines that toggle the hidden property:
Range("D4:D10").EntireRow.Hidden = (Range("D3").Value = "No")
Range("D6:D7").EntireRow.Hidden = (Range("D5").Value = "No")
...
End If
Lastly, because this beast will fire any time any change is made on this worksheet, you may want to shut off event firing while the subroutine is running. So turn enableEvents off at the top of the subroutine and turn it back on at the end:
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
If Not (Intersect(Target, Union(Range("D3"), Range("D5"), Range("D8"))) Is Nothing) Then
Range("D4:D10").EntireRow.Hidden = (Range("D3").Value = "No")
Range("D6:D7").EntireRow.Hidden = (Range("D5").Value = "No")
Range("D9:D12").EntireRow.Hidden = (Range("D8").Value = "No")
End If
Application.EnableEvents = True
End Sub
This will prevent this same subroutine getting called by itself while it's busy changing the sheet causing an infinite loop and locking up excel (which sucks if you didn't save the workbook before firing it off).

Resources