Circle Invalid-data Macro - vba

I have a worksheet with many dependant dropdowns that are liable to having invalid data if the initial drop down is altered. I would like a simple auto-macro that would automatically run the "circle invalid data" command every time a cell change within a specified range (D8:T800) is detected.
It sounds fairly straightforward but I am not sure how to do this.
Question - as this macro will run every single time a cell is amended would this macro slow down the worksheet?
EDIT:
Also: as this might be slow,is there a way we can run this command over a selected range?
Your thoughts thanks.

Try this
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Me.Range("D8:T800")) Is Nothing Then
Me.CircleInvalid
End If
End Sub
Note that CircleInvalid applies to the whole sheet, so while this code only triggers when a cell inside D8:T800 changes, all invalid cells on the sheet will be circled

Try placing this code inside your Worksheet:
Private Sub Worksheet_Change(ByVal Target As Range)
' Check target range has changed
If (Not Intersect(Target, Range("D8:T800")) Is Nothing) Then
' Prevent recusrive looping
Application.EnableEvents = False
' Refresh validation circles
Target.Worksheet.CircleInvalid
Application.EnableEvents = True
End If
End Sub
Note that this will NOT work if the values in those cells change due to a calculation from outside the specified range.
Also, the CircleInvalid method applies to the whole worksheet.
You could try editing the code in the conditional to 'do something' if the Target is validated — this would result in you changing the format of invalid cells instead of having the red circles around them.
**PSEUDO-CODE**
For each cell in Target.Range
cell.colour = bright red
Next cell

Related

Run macro when cell changes pass value

I have this certain code on a worksheet event cell change. It finds certain data that I have on a Worksheet when I type an id_parameter on cell A1.
After data is found, it writes it on this worksheet.
Now I'd like to run a different macro when I change the values on column C of the data.
I'm not able to find the proper procedure. Do_something() receives the value changed in column C. I hope I explained it clearly enough.
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("A1")) Is Nothing Then
Call Search_data
End If
'Data is written in B2:E10
If Not Intersect(Target, Range("C2:C10")) Is Nothing Then
Call Do_something(Target.Value)
End If
End Sub
The code you have posted works as intended. The issue is most probably due to Search_Data and or Do_Something.
You change the cell A1 which then changes all cells from B2:E10. Including the changed C2:C10 so make sure that the change_event cannot be triggered again by this.
Option Explicit
Public EventsDisabled As Boolean
Private Sub Worksheet_Change(ByVal Target As Range)
If Not EventsDisabled Then
EventsDisabled = True
If Not Intersect(Target, Range("A1")) Is Nothing Then
Call search_data
End If
'Data is written in B2:E10
If Not Intersect(Target, Range("C2:C10")) Is Nothing Then
Call do_something(Target.Value)
End If
End If
End Sub
The Public variable EventsDisabled will make sure that the change event runs when a user input is given but not if a Worksheet_Change event changes the worksheet. Otherwise you will run into all sorts of weird loopings which might be infinite or at least take a long time. Your issue will most probably also be related to this. Make sure that your Do_Something sub has the right input type. You should set a few breakpoints and open the local window under:
view>local window here you can see all variables and objects and their type. You can also type:
debug.print typename(Target.value)
into the direct window and then see what type you need to type into the Do_Something signature.

ByVal with a range in which formulas are used.

Private Sub Worksheet_Change(ByVal Target As Range)
'Hvis du på noget tidspunkt tilføjer flere rows, så sig til.
Application.EnableEvents = False
If Not Intersect(Range("B27:B33"), Target) Is Nothing Then
Target.Offset(, 1).Formula = "=UDF_Now()"
End If
Application.EnableEvents = True
End Sub
I am using the following VBA code to execute my user defined function whenever a cell value in the Range("B27:B33") changes.
This works fine, as long as I am changing the cell values in the range manually. The issue is now that I want this macro to work for a given range that is made up by formulas. Whenever I change any of the precedents, a cell value of the range changes, but my macro does not execute.
I want this to work with formulas, so that the macro gets executed whenever I change a precedent and thus change the values of the cells within the range.
I hope this is useful explanation.
The Change Event code doesn't get triggered when the cell content is changed due to a formula.
If you want to trigger a event when the value is being changed by a formula, you may consider Worksheet_Calculate also along with change event code if that is also required.

Hide Active Column when cell value is changed

I have been trying to work this out myself for the last few days and caught myself in a bit of a one step forward three steps back cycle. I've been reluctant to bother you thinking this would have been answered somewhere else before now.
The idea is that I have a spreadsheet that has criteria in rows with separate entries in rows; in row 6 it is the status of each column entry, which when changed to "Completed" I would like the column to be hidden.
I've been floundering around with Worksheet_Change and been able to hide specific columns, but not the active column.
Any help offered would be much appreciated and I'm sorry if this has been covered elsewhere, but I've not been able to successfully apply any examples out there.
Thanks.
Whenever you have to work with worksheet_change events, you have to consider a cycle for it, due to user may delete multiple data at the same time or do a copy paste, if you only consider "Target" It would give a debugger error.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim ItemMultipleData As Range
For Each ItemMultipleData In Target 'handles multiple cells, paste, del, etc
'your code (instead of using "Target" change to ItemMultipleData. IE:
'If ItemMultipleData.Value = "Completed" Then
Next ItemMultipleData
End Sub
Here is a starting point. It only checks row # 6:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rng As Range
Set rng = Range("6:6")
If Intersect(Target, rng) Is Nothing Then Exit Sub
If Target.Count <> 1 Then Exit Sub
If Target.Value = "Completed" Then
Application.EnableEvents = False
Target.EntireColumn.Hidden = True
Application.EnableEvents = True
End If
End Sub
EDIT#1:
This approach assumes that only one cell at a time is being changed........that makes it easy to "find the active cell"

Get notification for all cell changes in VBA

I want to get a notification for all cell updates in excel.
My current code is something like this:
Private Sub Worksheet_Change(ByVal Target As Range)
...
End Sub
My problem is, that it only runs when a direct cell change happens. If I modify a cell, some other cells might change if their values relies on the modified cell.
Is there a way to detect these changes too? I would like to avoid the mirror copy method.
The following code will allow you to access all cells containing formulae which depend upon Target.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim cell As Range
...
On Error Resume Next
For Each cell In Target.Dependents
' Do something
Next cell
On Error GoTo 0
...
End Sub
The On Error Resume Next statement is necessary because the loop will throw an error if there are no dependent cells.
You may also want to call Application.Calculate before that For Each loop in order to force re-calculation of those cells.

How do i insert a new blank cell before current cell that has just been populated

I have a two (very long) TO-DO lists- one going across and the other going down.
What i want to achieve is for a blank cell to appear at the start of the list instead of having to scroll to the end of the lists to enter a new item.
So then when i have entered an item in a cell and hit enter, i want the cell just populated to move down the list (or across if i hit tab) and a new empty cell to appear at the start of the list.
It would be useful for the new blank cell to be pre-populated with the current date but that is not essential.
Thanks for your help.
NOT FOR POINTS.
Piggy-backing on Gary's answer, the mistake is that you set A to Range("C4:C6"). What happens is, when you enter data into any of C4, C5, and C6, they are all moved to the right because of A.Insert, which refers to all the cells assigned to A.
The trick here is to fully qualify your requirements for Target. Let's say you have a table from B1:E3, like below:
Now, let's say you want to move row 1 if you enter something into A1, row 2 if A2, etc. The following macro should do it (notice the difference with Gary's macro):
Private Sub Worksheet_Change(ByVal Target As Range)
Dim QualifyingRange As Range
'Dim OrigRng As String
Set QualifyingRange = Range("A1:A3")
If Intersect(Target, QualifyingRange) Is Nothing Then Exit Sub
Application.EnableEvents = False
'OrigRng = Target.Address
Target.Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
'Range(OrigRng).Value = Date
Application.EnableEvents = True
End Sub
What is the difference in the above? Very simple but very important. When a Worksheet_Change is in a sheet's code, every time you do a valid change to the sheet, the macro fires. The range you just edited will be known to the macro as Target. Now, usually, if you don't declare what the qualifications for Target are, the Worksheet_Change macro just fires indiscriminately. How do we qualify Target properly then?
We use Intersect. First, we declare a range of cells that we want to track. These cells, when changed, should fire the macro. Otherwise, macro is kaput. This line: If Intersect(Target, QualifyingRange) Is Nothing Then Exit Sub basically reads: If Target is not inside my desired range, then nothing happens.
This is the reason why I declared A1:A3 as my QualifyingRange. This way, if my change is to any of the cells above, the macro will fire. HOWEVER, .Insert should not be applied to the whole range but to Target alone. This is because if we do QualifyingRange.Insert, every time a change is detected in any cells in A1:A3, all three rows will move. This is what happened when you set A to three cells and kept A.Insert.
Hopefully, this clears up the confusion. Let us know if this helps.
Here is a partial solution. The following event macro monitors entry to cell A1 . Once you have entered a value in A1, the macro "pushed" the values in column A down by one. This means that value you just entered has been pushed down to A2 and A1 is empty:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim A As Range
Set A = Range("A1")
If Intersect(A, Target) Is Nothing Then Exit Sub
Application.EnableEvents = False
A.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
Application.EnableEvents = True
End Sub
Because it is worksheet code, it is very easy to install and automatic to use:
right-click the tab name near the bottom of the Excel window
select View Code - this brings up a VBE window
paste the stuff in and close the VBE window
If you have any concerns, first try it on a trial worksheet.
If you save the workbook, the macro will be saved with it.
If you are using a version of Excel later then 2003, you must save
the file as .xlsm rather than .xlsx
To remove the macro:
bring up the VBE windows as above
clear the code out
close the VBE window
To learn more about macros in general, see:
http://www.mvps.org/dmcritchie/excel/getstarted.htm
and
http://msdn.microsoft.com/en-us/library/ee814735(v=office.14).aspx
To learn more about Event Macros (worksheet code), see:
http://www.mvps.org/dmcritchie/excel/event.htm
Macros must be enabled for this to work!
EDIT#1
To push across rather than down:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim A As Range
Set A = Range("A1")
If Intersect(A, Target) Is Nothing Then Exit Sub
Application.EnableEvents = False
A.Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
Application.EnableEvents = True
End Sub
To handle multiple cells, you must specify which cells get pushed across and which cells get pushed down.