Clear remaining cells when value is added - excel

In Excel I have a Table with about 8 products(8 rows).
(the table is a drop down list and can be sorted on alphabet)
The table auto expands when a new product is added at the bottom of the list.
The table is set up like explained below:
Column B = Product Number
Column C = Product Name
Column D = Certain Value
Column E = Certain Value
Column D and E are Usually empty, I want only 1 cell in the whole range(D1:E8) to contain any value. If a new value is added, all the other Cell's in this range need to be cleared.
Is This possible by using a VBA Macro? (If so... Then how?)
For Example,
D3= "x". When a string "x" is entered in cell E6, all other cells (including D3 need to become empty). I'd like to do this by starting a VBA macro, so I could add some additional actions that need to happen after one of the products is selected with an "x"in Column D or E. I know this can be done by a userform as well, but would prefer to do it this way.

In the Worksheet module of the sheet you want this to affect use:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("D1:E8")) Is Nothing Then
If Target.Cells.Count > 1 Then
MsgBox "Please edit one cell at a time!"
Else
Application.EnableEvents = False
newVal = Target.Value
Range("D1:E8").ClearContents
Target.Value = newVal
Application.EnableEvents = True
End If
End If
End Sub

Related

Excel Highlight Second Entry within a Range of Cells

I am trying to highlight the cell of a second entry (and beyond) within a range of cells. I am tyring to implement this feature in my attendence tracking.
For example, in the image below, I have "Peter", "John" and "Tom". If there are only one person who is absent, I do not need to highlight anything, as shown below.
However, if either "Tom" or "John" is the second person to be entered as "Not in" (absent), I want to highlight the cells, as shown below.
Finally, if the last person left is also absent, I would like to highlight it as well, like below image
The values in Column C is not restricted to these phrases ("Absent","Away","Not in").
From another point of view, I want to highlight the second and the later entries within a range of cells. Is there a way to implement such feature without using VBA or macro? Can it be donne using conditional formating?
Please advise. Thank you so much!
You can use the Worksheet_Change event to add a timestamp to a helper column. In my case, I added it to column D:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim myrange As Range
Set myrange = Range("C3:C9")
If Not Application.Intersect(myrange, Range(Target.Address)) Is Nothing And Target.Count = 1 Then
If Target.Value = "" Then
Target.Offset(0, 1).Value = ""
Else
Target.Offset(0, 1).Value = Now()
End If
End If
End Sub
Then use conditional formatting on column C using something like this:
=$D3>=SMALL($D$3:$D$9,2)
This will highlight any rows where the the timestamp is greater than the second smallest timestamp (ignoring blanks).
Here's an example of it in action. For illustration purposes, I put the order I typed things in column C rather than "Absent", "Not Here", etc.

Formula to hide rows based on the value of a cell

I have a worksheet that contains the names of all managers and their employees, ideally the way this sheet needs to work is that there is a drop down in the top left and when a manager selects their name, all rows that don't have their name against, are hidden, so only their team is shown.
I know auto filtering and having them choose their name would be the easiest way and is a good option to fall back on, but I'm hoping there is a way to do this with VBA or a formula to just hide rows when its not their team when they select their name in the drop down. As i'm trying to create something that's quite slick and looks nice
I did try to do something around having a helper cell to display true and false if the names matched, but came a bit stuck at this point. Tried using the code below, but it doesn't seem to actually be doing anything. Column with TRUE/FALSE is in Col A
Sub TEST()
Dim cell As Range
Application.ScreenUpdating = False
Application.EnableEvents = False
For Each cell In Range("A4:A34")
If cell.Value = "FALSE" Then
cell.EntireRow.Hidden = True
Else
cell.EntireRow.Hidden = False
End If
Next
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
Any ideas on how to do this without just using autofilter would be great
Given the following assumptions:
Drop down with Manager name is in cell A1
Column listing manager name for each row is in column A
Data set starts in row 5
Column A is contiguous with no blank spaces
Place the following code into the Worksheet module of the data sheet and change assumptions to fit your data set.
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$A$1" and Target.Cells.Count = 1 Then
Application.ScreenUpdating = False
Range("A5:A1000").EntireRow.Hidden = False
Dim mgrList as Range
Set mgrList = Range(Range("A5"),Range("A5").End(xlDown))
Dim mgrCheck as Range
For each mgrCheck in mgrList
mgrCheck.EntireRow.Hidden = mgrCheck <> Target
Next
End If
End Sub
Use an if then else statement with a call that shows/hides the rows that you'd like to show.
If Range("A1").Value = "John Snow" Then
Call Show_John_Snow
Else
If Range("A1").Value = "Daenerys Targaryen" Then
Call Show_Daenerys
Else....
'subroutine
Show_John_Snow
Rows("17:20").EntireRow.Hidden = True 'hide others
Rows("21:53").EntireRow.Hidden = False 'show John Snow
Rows("54:75").EntireRow.Hidden = True 'hide others
I have this data, in which I have Headers at A3:D3, data starting from row 4 to 99.
I tried applying Autofilter, check if this one works for you.
Sub test()
Range("A3:D3").Select
Selection.AutoFilter
ActiveSheet.Range("A3:D99").AutoFilter Field:=2, Criteria1:="0"
ActiveSheet.Range("A3:D99").AutoFilter Field:=2, Criteria1:="1"
End Sub
Here, I selected option named "0" from drop-down filter from Field-2, that is Range A4, and as you told, other cells automatically gets hidden, and the cells corresponding to that criteria only gets visible.
Also I tried with other option "1".
This seems a very difficult or involved way to do this, I have to show students their results without them seeing other students results.
So, one sheet has all the data and on a "front" sheet I call the relevant data for the particular student using index() and match(). Each student has an ID number which is entered, then for confirmation the name is returned then the relevant grades.

How to autopopulate excel column based on dropdown list selection from another column

I have a spreadsheet that has two buttons - To retrieve rows from a sql table using a macro and another one to update data changes back to the table from excel. I have also attached an image here for reference. The table columns are EmpID, EName, Grouping, CCNum,CCName, ResTypeNum, ResName and Status.
Now to update changes, I have drop down lists for CCName and ResName. I would like the ResTypeNum to change automatically whenever the value in ResName column from dropdown list changes. Using Vlookup doesn't seem to work as the formula gets wiped out every time I click on the Retrieve button to refresh data. Also, I have to drag down the formula which I don't want but instead the value in ResTypeNum should automatically update whenever the ResName column is changed. I would appreciate any new ideas to make this work.
Thank you,
Hema
Assumptions:
First value is in A4
ResName column is G
Sheet with data validation list and corresponding code in sheet "ResNameSheet"
In the tables sheet event module you place the following code:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column = 7 And Target.Row > 3 Then
If Target.Value2 = "" Then
Target.Offset(0, -1).Value2 = ""
Exit Sub
End If
Dim rngDataValidation As Range
Dim rngRow As Range
Set rngDataValidation = ThisWorkbook.Sheets("ResNameSheet").UsedRange
For Each rngRow In rngDataValidation.Rows
If rngRow.Cells(1, 1).Value2 = Target.Value2 Then
Target.Offset(0, -1).Value2 = rngRow.Cells(1, 2).Value2
End If
Next
End If
End Sub
Explaining how the code works:
Fires on changes to the sheet
checks if changes are in column G (7) and that it occurs below the header row (3)
Checks that the change was not deleting from column G, if it is it clears all values on the corresponding column F
Loops through the Rows collection in the range with ResName list
Checks if values match
If it does it writes the corresponding code to the column to left of Target
Hope this helps.

Excel cell value update macro

I have a spread sheet for tracking different savings, so column A has a name, B has a currency value. I want to be able to enter a value in column C and have it update the B cell next to it, then return to 0. For example:
B1 = £50.00
I type -£12.00 in C1
B1 = £38.00
C1 = £0.00
I thought there would be a built in function, but I can't find one. I think I will need to write a macro to do this. Can anyone show me how this would be done?
You'll want to add the following code to the sheet your working on. Right Click the sheet name Tab and choose View code and paste this in.
Private Sub Worksheet_Change (ByVal Target as Range)
Dim FirstNum as Currency 'Long is for number currency should help keep format
Dim SecNum as Currency
If Target.Column = 3 Then 'Only Runs if Cell being changed is in column C, Might need to be Columns
Application.EnableEvents = False ' Stop macro changes calling function repeatedly
FirstNum = Target.offset(-1,0).Value ' Value in Column B
SecNum = Target.Value ' Value being typed in C
Target.Offset(-1,0).Value = FirstNum - SecNum ' Makes Cell B equal to difference of previous value and value typed in C
MsgBox("Difference Found") ' Just to display code worked Remove when confirm code works
Target.Clear ' Clears Value you typed
Application.EnableEvents = True ' Re-enable the macro call
End if
End Sub
Seems like you are wanting to do something here that is a little different to the way that excel would normally work. Suggest you use more rows then you wouldn't need a macro. e.g. B1 = $50 C1=-$12
then B2==IF(C1<>"",B1+C1,""). Then you copy cell B1 down to propegate the formulae in cells below. You enter you next value in C2. Does this do what you need?

Excel formula in VBA code

So, in Sheet1 I have base of some names and it looks like this:
In Sheet2 I'm working with these names from Sheet1. I'm doing that in a way that I'm entering Code value in column A and in column B I get the Name, in column C I get the Last Name. That looks like this:
I've done this with formulas, entering it in the formula bar. For column A(or Name) I've used this formula: =IFERROR(VLOOKUP(A2;Sheet1!A:C;2;FALSE);"") and for column B(or Last Name) I've used this one: =IFERROR(VLOOKUP(A2;Sheet1!A:C;3;FALSE);""). I've dragged these formulas to row 20 and it works great.
Now, what I'd like to do is to put these formulas into Excel VBA code and them to work for noted range. I've just started to use VBA and I don't know how to do it in it, tried something but doesn't work, ..., I've done this so far. I'm new to this Excel/Macro/VBA thing so any help would be appreciated.
The below code will work if you type in your Code values in sheet2 and highlight them, and run this macro:
Selection.Offset(0, 1).FormulaR1C1 = "=IFERROR(VLOOKUP(RC[-1],Sheet1!C[-1]:C,2,FALSE),"""")"
Selection.Offset(0, 2).FormulaR1C1 = "=IFERROR(VLOOKUP(RC[-2],Sheet1!C[-2]:C,3,FALSE),"""")"
Selection.Offset(0, 1).Value = Selection.Offset(0, 1).Value
Selection.Offset(0, 2).Value = Selection.Offset(0, 2).Value
Edit: If you are wanting to update values as you type use (thank you #PeterAlbert for added optimisation!):
Private Sub Worksheet_Change(ByVal Target As Range)
'end if the user made a change to more than one cell at once?
If Target.Count > 1 Then End
'stop system activating worksheet_change event while changing the sheet
Application.EnableEvents = False
'continue if column 1(A) was updated
'and
'dont continue if header or row 1 was changed
If Target.Column = 1 And Target.Row <> 1 Then
With Target.Offset(0, 1) 'alter the next cell, current column +1 (column B)
'RC1 = current row and column 1(A) e.g. if A2 was edited, RC1 = $B2
'C1:C2 = $A:$B
.FormulaR1C1 = "=IFERROR(VLOOKUP(RC1,Sheet1!C1:C2,2,FALSE),"""")"
.Value = .Value 'store value
End With
With Target.Offset(0, 2) 'alter the next cell, current column +2 (column C)
'C1:C3 = $A:$C
.FormulaR1C1 = "=IFERROR(VLOOKUP(RC1,Sheet1!C1:C3,3,FALSE),"""")"
.Value = .Value 'store value
End With
End If
Application.EnableEvents = True 'reset system events
End Sub
Explinatioin of RC:
The FormulaR1C1 formula types are good to use when referencing a cell with respect to the current cell. There a few rules to remember:
The R stands for Row and C is for Column and the integer after it, if any, defines the row or column;
As a basis the RC formula references itself;
Any number following the R or C wraped in [] is an offset to itself, e.g. if you are in cell A1 and use R[1]C[1] you would be referencing cell B2;
Also any number following the R and C is an exact, e.g. if you reference R2C2 no matter the cell you are in would also point to B2; and
To complicate things if you were in cell C5, e.g. using Range("C5").FormulaR1C1 = and coded the follwing:
"=RC[-1]" references cell B5
"=RC1" references cell A5, more rightly $A5
"=R[1]C[-2]" references cell A6
"=Sum(C[-1]:C5)" is =Sum(B:E), more rightly =Sum(B:$E)
If I understand your question and comments correctly, you want to ensure that columns B&C always show you the right values based on your formula, but also want to protect (and maybe even hide the formula) from the users.
I'd suggest you use sheet protection instead: all you need to do is to unlock the cells you want the users to edit, i.e. select column A and in the _ Format cells_ dialog uncheck "Locked" in the Protection tab. Similarly for columns B&C, check "Hidden". Now right click the sheet name and select Protect Sheet. Once this is done, the user can edit column A - but will not see the formula in B&C and cannot edit those cells.
If for some reasons you need to ensure this in VBA, use the following code:
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False 'to prevent endless loop
With Target.Offset(, 2 - Target.Column).Resize(, 2)
.FormulaR1C1 = "=IFERROR(VLOOKUP(RC1,Sheet1!C1:C3,COLUMN(RC),0),"""")"
.Value = .Value
End With
Application.EnableEvents = True
End Sub
You need to place this in the module of the worksheet.

Resources