Set the value of a cell when unsaved changes are detected in Excel using VBA - 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

Related

Run macro when linked cell changes value (Excel VBA)

I am currently trying to obtain historical information about how the backlog is developing.
My Excel file is based on queries from an Access Database which can give me a view of the current situation.
I would like to automatically run a macro every time the week number changes. I am currently using the following code:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Target.Worksheet.Range("D3")) Is Nothing Then
Call KPIupdate
End If
End Sub
The macro that should fire is called KPIupdate
My problem is that the Macro only fires if I click the cell. I would like it to just fire when the number changes. The cell "D3" is linked to another cell with the formula =Weeknum(Today();21)
I hope you can help me
According to the MSDN entry for Worksheet_Change:
This event does not occur when cells change during a recalculation. Use the Calculate event to trap a sheet recalculation.
To use Worksheet_Calculate to trap the change in a cell that is set by a formula looking at another cell, you need to set a variable to hold the value of the 'Target' and then check if it has changed after the Calculate event fires.
Here is a simple example:
Option Explicit
Private strCurrentWeek As String
Private Sub Worksheet_Calculate()
If Me.Range("A1").Value <> strCurrentWeek Then
'the linked cell changed
Debug.Print "Sheet1!A1 was changed"
'call another macro
End If
'update the new current week
strCurrentWeek = Me.Range("A1").Value
End Sub
To test this, just set the formula in A1 to be =B1 and then change the value of B1 and check the output in the Immediate window.
You can adapt this code to call KPIupdate where my Debug.Print... statement is.

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!

Excel macro select two ranges and compare

This is a question that was asked to me in an interview. I have a excel list. It is copied to another location and then by mistake a row in the new location gets deleted.
Now I need to write a macro to compare the old and new ranges and then provide the missing data as result.
I can perhaps perform the comparison part. But the problem is I don't know how to get the selected range as input in a macro.
For eg. as soon as I select a range, it should be sent as input to the macro, then the macro should wait for another selection. As soon as I select the new range, the macro should compare and find the missing lines in new range.
Regarding the selection per mouse click you could look at the link I sent in the comments of the other answer. Selection_Change is an event which gets triggered when you change the selection of a worksheet (not only mouseclick but move-by-keys as well). The target coming in is the cell which you have selected. You can pass this as a range on to a function.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
showMsg Target
End Sub
Private Function showMsg(r As Range)
MsgBox r.Address
End Function
You can just as well use another event like BeforeDoubleClick or BeforeRightClick. Check out the events of Excel and choose the one you feel fits best.
If you only want the function to be triggered for a certain range you can filter it.
If target.column <> 1 then exit function
If you don't want the event to trigger your function each time you change a selection you can choose one cell to be the switch which gets triggered by the same event.
If target.address = "$A$1" Then Call toggleSearch()
with toggleSearch being the switching function.
This is a classical diff (and a simple one at that), you shouldn't select by hand or anything. Just sort the two lists in an identical way, then run a Sub which loops over the number of rows in the source sheet comparing each row with the same row in the target sheet. The first mismatch you get is the missing line.
This example assumes both sheets are in the same workbook but you can easily adapt it
Public Sub diffThem()
Dim src as Worksheet, trg as Worksheet
Dim r as Range, i as Integer
Set src = ThisWorkbook.Sheets("Source")
Set trg = ThisWorkbook.Sheets("Destination")
Set r = src.Range("A1")
For i = 1 to ThisWorkbook.Sheets("Source").UsedRange.Rows.Count
If r.EntireRow <> trg.Range("A" & r.Row).EntireRow Then
MsgBox("The missing row is " & r.Row)
Exit Sub
End if
Set r = r.Offset(1,0)
Next i
End Sub
If EntireRow cannot be run due to different layouts or whatever then loop the columns at that point.

Circle Invalid-data Macro

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

VBA function to alert when value is changed within a time frame

I have an excel cell where its value is updated every minute.
What I need is an alert message box; while that cell value moves to a particular time.
Suppose a cell has value 10:
if it reaches 7 in one minute then I need a message box to alert that.
if it is not reaching 7 in one minute then I don't need any alert.
Please help write me a macro for this.
Inside VBA editor for ThisWorkBook, you could write the following code
Dim WithEvents SheetToWatch As Worksheet
Private Sub SheetToWatch_Change(ByVal Target As Range)
If Target.Address = "$A$2" Then
If Target.Value = 7 Then
MsgBox "changed to 7"
End If
End If
End Sub
Private Sub Workbook_Open()
Set SheetToWatch = Sheets("Sheet1")
End Sub
Basically the code sets the reference of Sheet1 to the variable SheetToWatch when the workbook opens. Declaring the variable using WithEvents lets one capture the events.
I am using Change event of the worksheet and checking if the cell that was changed is A2. If so, I am checking or comparing the value with 7 (it can be dynamic and depends on how you want to handle it).
See if this helps.
Cannot be done with a function, any way that I can think of.
If you control the mechanism that is updating the cell, then you could it call a VBA subroutine that you wrote, instead, have to send the alert and then update the cell from that routine.
If you do not control the updating mechanism, then the only thing that I can think of that might work is of the Cell, Range or Worksheet classes have a ChangedDate event that you could catch from VBA and do your alerting from there.