I'm trying to finish up a project of mine and I right now have a Form Control that when pressed adds to the value of a number and another button will subtract that value.
Another value has the two different buttons for the same thing, but the value is also dependent on the first value and other things than just the buttons modify that value. I tried implementing this code for validation
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Target.Worksheet.Range("F19")) Is Nothing Then
If Range("E19") = 2 And Range("F19") < 12 Then
Range("E20") = 1
End If
End If
End Sub
but Excel apparently doesn't recognize that cell F19 has changed when the change is caused by the button, only when it is caused by user input. So, what this is saying is, if F19 updates and 19 is 2 and F19 is less than 12 (the prerequisite for E12 being 2 is F19 being 12 or greater) then set E20 to 1 (E20 is a modifier for E19 which also has other modifiers going into it). This method works on other values that aren't button controlled, but how can I get excel to realize when the Form Control button changes the value (or at least monitor when the form control is pressed.)
Edit: The macro actually doesn't work if the cell changes by formula either. I don't think I can use Worksheet_Calculate to monitor the change in a specific cell.
Why are you doing this with code anyway? You could have Cell E20 have a formula like: =IF(AND(E19=2,F19<12),1,"") which would make the cell blank unless the condition is met.
If you really want to do it with code, you should take this into account: The Worksheet_Change event "Occurs when cells on the worksheet are changed by the user or by an external link."
I would recommend instead of having
If Range("E19") = 2 And Range("F19") < 12 Then
Range("E20") = 1
End If
In your Worksheet_Change event that you add it as a separate sub, that you call from Worksheet_Change. You would also call the sub from the code for your button, after you've performed whatever action your button does. That way, you're guaranteed the check gets run and do not try to rely on events.
Daniel is partialy right, Worksheet_Change "Occurs when cells on the worksheet are changed by the user or by an external link." But this includes changes caused by VBA, and Excludes changes by a formula.
Your problem may be caused (or at least exacerbated) by the only partial qualification of your ranges:
Range("E19") will refer to 'E19' on the active sheet, which may or may not be be the sheets Target is on. You got it right with Target.Worksheet.Range("F19")
Try (note the .'s)
With Target.Worksheet
If Not Intersect(Target, .Range("F19")) Is Nothing Then
If .Range("E19") = 2 And .Range("F19") < 12 Then
.Range("E20") = 1
End If
End If
End With
BTW. I'm with Daniel in that your whole solution seems a little off, but we may not be getting the whole picture...
Related
I have created a spreadsheet which uses the Worksheet_Change feature and the code associated with that works very well. I can stop it firing unnecessarily when inside the module by using Application.EnableEvents = False.
However, while I've created a form to enter data directly into the next available row (again, that works fine in terms of entry) it doesn't cause the formulae in the sheet to calculate (even though auto calculation is on and re-enabled within the module). If I manually place my cursor in the row, hit F2 and simply press enter, everything then fires up.
I have tried to enter data directly into the cells, but of course the Worksheet_Change feature then kicks in again and the cursor isn't simply moving to the next adjacent cell ....
I've tried to check firs for any direct entry with the code below and if it looks like the user isn't entering directly into the cell, the Worksheet_Change is disabled:
Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo eventhandler
Sheets(1).Range("a1").Select
LastCell2 = Sheets(1).Cells(Rows.Count, "A").End(xlUp).Row
Dim intersection As Range
Set intersection = Intersect(Target, Range("A3:F" & LastCell2))
If intersection.Row = LastCell + 1 Then
Exit Sub
End If
Application.EnableEvents = False
The code above is simply checking to see if data is being entered into the next empty cell and if that's the case I want it to just exit there but it isn't working.
So I actually have 2 problems :
the first is why this formula isn't triggering after entry via a vba form - I've used INDIRECT since there are other macros that delete rows by moving the remaining cells up and that was causing the count in the $A$3:$A$500 to reduce to $A$499 and then 498 etc - the addition is done depending on the system date and the transaction date so I get a current value and a future value using a standard sum statement:
=AD1-(SUMIF(INDIRECT("$A$3:$A$500"),"<="&TODAY(),INDIRECT("$E$3:$E$500")))+(SUMIF(INDIRECT("$A$3:$A$500"),"<="&TODAY(),INDIRECT("$F$3:$F$500")))
The second is why I can't enter data directly into the spreadsheet and trap the fact that I don't want it to do anything and simply allow the user to hit enter and move to the next adjacent cell to the one they just entered data into.
Is this a lost cause and am I trying to do too much here? I'm relatively new to coding and teaching myself so apologies if the standard and style isn't to everyone's taste.
Thanks in advance for any replies.
I have a workbook written by someone else and a particular cell is being changed by some code. I cannot figure out the code that is changing the cell value.
I cannot even figure out a strategy to narrow down the code possibilities apart from setting a breakpoint in hundreds of procedures. So I would be happy with strategy ideas.
I am very experienced using VBA in Microsoft Access and a little bit experienced using VBA in Excel.
EDIT
Gotta larf. I cannot even F8 throught the code by starting at the start. What I mean is..
The cell in question changes after I change a value (a year actually) in the worksheet. So I set up a subroutine and breakpoint as below.
Private Sub Worksheet_Change(ByVal Target As Range)
End Sub '<== set breakpoint here
Then I press F8 and no other code is entered by the debugger and yet the cell changes.
The problem may be because there is an awful lot of dynamic formula creation going on in the code. Not sure. Don't know enough about Excel quirks.
EDIT 2
There is a missing formula in the cell in question. Sorry to have wasted everyone's time.
So how can a missing formula change a cell's value. It can't!
The question should have been "How to determine why a cell is NOT changing."
So why didn't I ask that?
I did not notice that other cells in the same column as this cell contain a formula. Because the other cells were changing values correctly and this cell was not, I presumed it was some VBA code not working so I tried to track down the rogue code. I guess not being an experienced Excel person I did not rule out the bleeding obvious and went straight to VBA. Phew!
Add a change event handler on the sheet containing the cell you want to track.
In that Event Handler, add code to break when a change in the tracked cell takes place
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Me.Cells(1, 1)) Is Nothing Then
Stop
End If
End Sub
Chnage Me.Cells(1, 1) to cell of your choosing.
When the code breaks, open the Call Stack, to see where the change came from
Here's a proof of concept. I ran ZX. Call stack shows the Change event at the top. The next function is what changed to cell.
I have a bit of time series data, and potentially want to do a calculation on it. I allow a user to decide if the calculation should be done.
To achieve this, I have a cell that applies data validation to restrict its options to 'Yes' and 'No'. Then I use a conditional that just duplicates the source data, in an adjacent column, if the drop down is toggled to 'No'. If toggled to 'Yes' a lengthy function is applied. For example, =if($AO$9='No', B3, B3 * some long function), where AO9 contains the toggle and this would be entered in C3 and then extended the length of column B.
When toggled from 'No' to 'Yes' the sheet doesn't automatically recalculate. The odd thing is, if I modify any other cell subsequent to toggling between 'No' and 'Yes' it updates instantly and uses the appropriate condition. Additionally, after toggling the cell, if I click in and out of the formula bar it also updates appropriately. Neither of these are ideal solutions when there are other people working on this book. I've checked all of the usual suspects (i.e., calculation options set to automatic, proof below, and that the toggle cell is set to type general and not text).
I've used this sort of scheme for a long time to allow user interaction, and have never had a problem. I did however just upgrade to 365 (Version 1802 Build 9029.2253). Has anyone else encountered this? If so, any suggestions?
Thanks!
You've kept a lot of details super-secret but I would propose a Worksheet_Change event sub procedure that forces B3 to recalculate.
In B3's parent worksheet's private code sheet,
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("AO9")) Is Nothing Then
On Error GoTo meh
Application.EnableEvents = False
Range("B3").Calculate
End If
meh:
Application.EnableEvents = True
End Sub
Failing that, just use INDIRECT or OFFSET inside the super-secret 'long formula' and it will recalculate whenever anything in any open workbook changes.
I am trying to create a table that tracks downtime for a production machine. the operator will be using a table with the columns down time start and down time stop. each time something happens that they have to leave the station I want them just to have to click the empty cell under downtime stat title and the time will appear/ log itself in the cell then the same for downtime stop.
I under stand how =now() works but then it shows the time when the file is opened, i want it to display only when the cell is selected.
Any help is much appreciated! I have never had to do anything like this in excel before.
You'll need some VBA for this. In your VBE (alt+f11) go to your worksheet and use something like the following:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
'Check to see if the click/selected cell is in columns A or B
If Not Intersect(Target, Range("A:B")) Is Nothing Then
'Make sure just one cell is selected:
If Target.Cells.Count = 1 Then
'Update the value
Target.Value = Now()
End If
End If
End Sub
Here we are using the Worksheet_SelectionChange() event. This event will fire any time a selection change is detected on the worksheet in which this code is placed. When the change is detected it will test to see if the selection was in columns A or B. It will also test to insure that only one cell was clicked (otherwise highlighting those columns would cause every row in the column to update with the time, which would be bad). If that all passes, then it just sets the selected cell's (target) value to the current time.
So, it's a new week, and I've got new ideas for improving things. Part of what I do is send out reports to individual offices and departments all over the place; these offices in turn are supposed to go through the information and note inconsistencies. As with everything in life, this turns out to be more trouble than anything else. In an effort to make it a little bit more painless (I hope) I want to try somethinga little different for them. What I would like to do is set up something within the worksheet that the individuals receive that does two things:
First, I would like to set up the worksheet so that when the user
clicks on a cell the cell is highlighted;
Second, after the cell highlights then the activebox would
automatically transfer to a "comments" box at the end of the row
where the user would enter their comments as to why the cell in
question was highlighted; and
Third, assuming that someone will make a mistake and highlight
something by mistake I would like to add the additional function
that if a user selects a cell that is highlighted then it would
clear the highlight from the cell.
Possible? Suggestions? Thanks!
JMax is correct in identifying the flaw in that you cannot edit a cell if it changes color and selects a comments cell every time you click on it. The best way around this problem is to change the color only on double-click. I would also define the selected row/column and see if they fall within a table's range (instead of using Application.Intersect) but that's just personal preference
Something like...
Private Sub Worksheet_Beforedoubleclick(ByVal target As Range, cancel As Boolean)
Application.EnableEvents = False
Dim TargRow as Variant
Dim TargCol as Variant
TargRow = target.Row
TargCol = target.Column
'Define Header, FirstCol, CommentCol, LastCol as required to define your table/range where you wish these changes to be made. CommentCol is the cell in which comments should be made
If TargRow > Header And TargCol > FirstCol and TargCol < LastCol Then
If Cells(TargRow,TargCol).Interior.ColorIndex <> -4142 Then 'change color as required to match background
Cells(TargRow,TargCol).Interior.ColorIndex = 3 'change color as required; this makes them red
Cells(TargRow,CommentCol).Select
Else
Cells(TargRow,TargCol).Interior.ColorIndex = -4142 'match color from start of IF statement
End If
End If
Application.EnableEvents = True
End Sub
Note that we disable events so no other code can be triggered by us selecting a different cell. This is an absolute necessity when implementing the Worksheet_SelectionChange event, less so with the BeforeDoubleClick event
It's very important to consider how you trigger macros and how they give the user flexibility. This Excel help video provides a reasonable introduction
What you can (and probably have to) use is the Worksheet_SelectionChange event procedure:
See MSDN for how it works.
You also should have a look at Chip Pearson's page about events.
When the user changes the selection, you should check wheter you are in the right cells (using Intersect) and if so, change the Target background color and change the ActiveCell to the one where you should put comments.
Btw, you can check if the cell is aldreay highlighted before moving to another cell.
The main drawback of this method is that it will move the Excel Selection every time the user clicks on a corresponding cell. A solution would be to tell the user to use the Scroll Lock key and to navigate with arrows. See this link on how it works.