Highlight Current Row Without Deleting Existing Cell Colours - excel

I found the code below, and while it highlights the entire row it also removes the color from any previously colored cell.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Cells.Count > 1 Then Exit Sub
Application.ScreenUpdating = False
' Clear the color of all the cells
Target.Parent.Cells.Interior.ColorIndex = 0
With Target
' Highlight the entire row and column that contain the active cell
.EntireRow.Interior.ColorIndex = 8
End With
Application.ScreenUpdating = True
End Sub
I would like to highlight the entire row on selection of a cell (that may already be colored), but when I move to a cell in a different row, the previously highlighted row should return to its previous color.
Is there a way to modify the previously selected cells/rows?

Conditional formatting overrides "regular" formatting (without replacing it), so if you don't already have some CF applied it's a convenient way to highlight a row without zapping any existing cell colors.
Here's a very basic example:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Cells.Count > 1 Then Exit Sub
Application.ScreenUpdating = False
Me.Cells.FormatConditions.Delete
With Target.EntireRow.FormatConditions.Add(Type:=xlExpression, _
Formula1:="=TRUE")
.SetFirstPriority
.Interior.Color = 65535
End With
Application.ScreenUpdating = True
End Sub

You will need to store the format and row number somewhere then paste it back upon selecting a new row.
This will store the exiting format and row number before the highlight to the 1,040,000 row on the same sheet.
Then when another row is selected it will check if there is formatting there and replace the row from where it was copied back.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Cells.Count > 1 Then Exit Sub
Application.ScreenUpdating = False
'test if formatting exist and copy it back to the row just left.
If Cells(1040000, 1) <> "" Then
Rows(1040000).Copy
Rows(Cells(1040000, 1).Value).PasteSpecial Paste:=xlPasteFormats
End If
'Copy formating to store
Rows(Target.Row).Copy
Rows(1040000).PasteSpecial Paste:=xlPasteFormats
Cells(1040000, 1) = Target.Row
With Target
' Highlight the entire row and column that contain the active cell
.EntireRow.Interior.ColorIndex = 8
End With
Application.CutCopyMode = False
Application.ScreenUpdating = True
End Sub

I have created an add-in for this. Download, enable content, and click the install button. The add-in creates three buttons on the View ribbon tab that toggle the highlighting.
Uses Conditional Formatting, so no overriding cell color settings.
All code is in the add-in, so no additional VBA required.

This is what I can come up with:
Public rngPreviousColor As Range
Public lngColor As Long
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Cells.Count > 1 Then Exit Sub
If Not rngPreviousColor Is Nothing Then
rngPreviousColor.Interior.ColorIndex = lngColor
End If
Set rngPreviousColor = Target.EntireRow
lngColor = rngPreviousColor.Interior.ColorIndex
With Target
.EntireRow.Interior.ColorIndex = 8
End With
End Sub
The idea is that the other row is the whole in one color and we save the row as a range rngPreviousColor and the color as lngColor.

Related

Excel - When enter a value: error instead of locked cell

When you enter a value the cell should be locked. Just the yellow cells should be able to lock. But always when I enter something in the cell i get this error code:
The error in the code:
Full code:
Private Sub Worksheet_Change(ByVal Target As Range)
Sheet1.Unprotect "1234"
If VBA.IsEmpty(Target.Value) Then
Target.Locked = False
Else
Target.Locked = True
End If
Sheet1.Protect "1234"
End Sub
table:
I suspect the reason you are getting the error is you do not have a sheet called Sheet1. You may have renamed or deleted the first sheet at some point.
To call a Worksheet dynamically from a range you can use Range.Worksheet. This will give you the worksheet of the range you are using.
Here is a way to use it in your scenario:
First it requires a bit of Prep
Select All cells in worksheet
Right Click --> Format Cells
Protection Tab
Uncheck Locked. (This means no cell on the sheet is locked)
When a cell is edited if it was yellow and has a value in it, it will locked. Then all the cells on that worksheet will be locked if they were set to be locked.
Private Sub Worksheet_Change(ByVal Target As Range)
' Only deal with one Cell.
If Target.Columns.Count = 1 And Target.Rows.Count = 1 Then
'Target background is Yellow (You may have to modify the code to the RGB value of your yellow) and value is Empty
If Target.Interior.Color = RGB(255, 255, 102) And Target.Value <> "" Then
Target.Worksheet.Unprotect "1234"
Target.Locked = True
Target.Worksheet.Protect Password:="1234", Contents:=True
End If
End If
End Sub

Add a identifier if you change a cell value in a row

Is there a way in excel (VBA) to mark any change in a row (A2-A10) for example with an identifier if any cell in that row is changed. So for if A2 changes, add an X in A1
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Count > 1 Then Exit Sub
Application.EnableEvents = False
If Not Intersect(Target, Range("A2:A10")) Is Nothing And Target <> "" Then '<- If there is any change in area A2:A10 and the value of the affect cell IS NOT empty then
ThisWorkbook.Worksheets("Sheet1").Range("A1").Value = "X"
ElseIf Not Intersect(Target, Range("A2:A10")) Is Nothing And Target = "" Then '<- If there is any change in area A2:A10 and the value of the affect cell IS empty then
ThisWorkbook.Worksheets("Sheet1").Range("A1").Value = ""
End If
Application.EnableEvents = True
End Sub
You can have a macro function to change the value or add new value when anything changes in the source cell.
This macro will be on the rows where the change needs to be recorded.

If A1 changes, put something into B1 | If A2 changes, put something into B2

I have rows from 1-100.
I know how to target specific cells and get data from them, but how would I do this when any row from 1 to 100 can be changed?
Say you put anything into Row A3. How would you write "Updated" into row B3 via VBA?
I want this to apply to rows A1-A100.
Thanks
Place the following event macro in the worksheet code area:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim A As Range, Intersection As Range, Cell As Range
Set A = Range("A1:A100")
Set Intersection = Intersect(Target, A)
If Intersection Is Nothing Then Exit Sub
Application.EnableEvents = False
For Each Cell In Intersection
Cell.Offset(0, 1).Value = "Updated"
Next Cell
Application.EnableEvents = True
End Sub
Open VBA Editor
Double click on the sheet you event take action (sheets appears in the left top box)
Select Worksheet on the left box above code box
Select change on the right box above code box
Paste the code
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
With ThisWorkbook.Worksheets("Sheet1")
If Not Intersect(Target, .Range("A1:A100")) Is Nothing Then
Application.EnableEvents = False
.Range("B" & Target.Row).Value = "Updated"
Application.EnableEvents = True
End If
End With
End Sub

How to prevent pasting over validation drop down cell in Excel VBA

I need to stop the user from pasting over my validation drop down cell. I have read and tried various solutions, none of which work just right. This code I have checks if the pasted value follows validation rules, but it doesn't work if the entire cell is pasted over my validation cell (it seems that this event fires after the paste, so the validation gets erased together with the previous cell):
Private Sub Worksheet_Change(ByVal Target As Range)
Dim Cell As Range
For Each Cell In Range("D2:F13")
If Not Cell.Validation.Value Then
MsgBox "Value violates validation rule"
Application.Undo
Exit Sub
End If
Next
Ideally the code would check if the value of the cell that's being pasted matches validation dropdown options and only allows to paste the value (not the formatting) into the cell.
Thanks!
You can disable the Cut\Copy in the specific cell:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
' TARGET IS YOUR VALIDATION CELL
If Target.Column = 1 And Target.Row = 1 Then
Application.CutCopyMode = False
End If
End Sub
Or more complex you can try to check the clipboard of the user on SelectionChange
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
' TARGET IS YOUR VALIDATION CELL
If Target.Column = 1 And Target.Row = 1 Then
Set MyData = New DataObject
MyData.GetFromClipboard
'In MyData.GetText you have the clipboard data in text format
If MyData.GetText <> "what you want" then
'...
End if
End If
End Sub
In this case you must add a reference to Microsoft Forms 2.0 Object Library. You can find it in this path: C:\Windows\System32\FM20.DLL

Autofit Target cell but only when content is larger

I am using the following piece of vba inside my Worksheet_Change Sub to autosize a particular column with text entries:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim nextTarget As Range
Set nextTarget = Range(Selection.Address) 'store the next range the user selects
If Target.Column = 1 Then
Target.Columns.Select 'autofit requires columns to be selected
Target.Columns.AutoFit
nextTarget.Select
End If
End Sub
The above has the problem that every time you enter in a cell of that column text which is shorter than the other cells, it will shrink the column to fit the target cell, leaving the other cells with text outside. Is there any addition that I could make to solve this?
Use the .EntireColumn method. With this there is no need to Select any cells.
Private Sub Worksheet_Change(ByVal Target As Range)
'added extra error trapping in case something happens where more than 1 column is changed.
If Target.Columns.Count = 1 And Target.Column = 1 Then
Target.EntireColumn.AutoFit
End If
End Sub

Resources