I have a range 'Bills' (A10:B50) containing dates of my bills, some are paid on the same date so there are duplicates and blanks at the end. I have a range 'Consolidated' (D10:E30) which consolidates the dates and bill amounts into single entries. When I click on the date in 'Consolidated' it highlights the individual entries in the Bills range using conditional formatting.
I use the following to get the date I am clicking on:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
ActiveSheet.Range("C40").Formula = "=" & Target.Address
End Sub
However, I use C40 elsewhere, it is formatted as a date, the vba causes havoc when the active cell is not a date. How do I get my vba to work ONLY if the active cell is within the Consolidate range?
Thanks
Not the cleanest solution, but try something like this:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Row < Range("$D$10").Row Then Exit Sub
If Target.Column < Range("$D$10").Column Then Exit Sub
If Target.Row > Range("$D$30").Row Then Exit Sub
If Target.Column > Range("$D$30").Column Then Exit Sub
ActiveSheet.Range("C40").Formula = "=" & Target.Address
End Sub
To explain, this checks the target row and columns and makes sure they are not below or above the range of your choice. If you click anywhere outside of range D10 through D30, then nothing will happen with cell C40.
I have tested this and it works. When clicking within D10 through D30, it changes the contents of C40. Hopefully it works for you.
Related
I have a workbook with a two sheets, Rep and Aux.
I want to dynamically set Aux!A2 to the value of the ActiveCell, which is on sheet Rep, but only if the ActiveCell is on column D of that sheet (in the range Rep!D2:D5000).
To top it all of I need this mechanism to run as long as the workbook is active, not just a one-shot.
For example: While being on sheet Rep I place the cursor, i.e. ActiveCell on cell D2. I expect Aux!A2 to be set to the value of Rep!D2. I move the cursor to, say, Rep!F5 and expect nothing to happen to Aux!A2, lastly, I activate cell Rep!D7 and again, expect Aux!A2 to get the ActiveCell's value. Continue till I close the workbook.
My VBA skills are non-existent and Googling, the only thing remotely close to what I described was:
Sub Macro1()
If Not Intersect(ActiveCell, Sheets("Rep").Range("D2:D5000")) Is Nothing Then Sheets("Aux").Range("A2").Value = ActiveCell.Value
End Sub
Which fails completely.
Put this in the code of the "Rep" worksheet. Triggers anytime a cell is selected on that sheet, if the cell is in column 4 (D) then it sets the value of the cell on Aux to match.
Private Sub Worksheet_SelectionChange(ByVal Target As Excel.Range)
If Target.Column = 4 Then
ThisWorkbook.Worksheets("Aux").Cells(2, 1).value = Target.Value
End If
End Sub
EDIT: In response to comments.
Private Sub Worksheet_SelectionChange(ByVal Target As Excel.Range)
End Sub
This subroutine is an event that exists on every worksheet. Any time a selection changes it will run any code you put in it. The "ByVal Target as Excel.Range" part is saying it's giving you a copy of the target range being selected, because you could select more then one cell.
If Target.Column = 4 Then
end if
This is an If Block. If the condition is true, any code between the "Then" and the "End If" will execute. The condition is if the target's column is 4 in this case.
ThisWorkbook.Worksheets("Aux").Cells(2, 1).value = Target.Value
This sets the cell at row 2 column 1 value to match the value of the target that was selected.
Now that I think about it I wonder what this code will do if you select a range of cells.....
I have the excel formula below to pull data from another sheet.
=IF(ISNUMBER(SEARCH("Yes",Sheet7!C4)),Sheet7!A4,"")
These cells used, C4 and A4, will always remain the same. Different item numbers are being scanned in one after another so the values in the cells will change.
When the word Yes is shown in C4 i would like it to record the item # in A4 into the new sheet. This formula works great for that.
However, after the item # is recorded in the new sheet, i would like it to go down to the next row and copy the formula so it can record the next item # scanned.
Is this VBA possible? thank you!
I think you are trying to get something like
If Worksheets("Sheet7").Range("C4").Value Like "*Yes*" Then
ActiveCell.Value = Worksheets("Sheet7").Range("A4").Value
Else
ActiveCell.Value = ""
End If
but don't use ActiveCell - use a proper reference to the cell in which you want to put the value. (Your question doesn't contain enough information to determine what the location is, which is why I was forced to just refer to it as ActiveCell.)
Based on comments, it sounds like you want the following Worksheet_Change event in Worksheets("Sheet7"):
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Cells.Count <> 1 Then
Exit Sub
End If
If Intersect(Range("A4"), Target) Is Nothing Then
Exit Sub
End If
If Range("C4").Value Like "*Yes*" Then
With Worksheets("Sheet1")
.Cells(.Rows.Count, "A").End(xlUp).Offset(1, 0).Value = Target.Value
End With
End If
End Sub
Using:
Microsoft Office Excel Macro-Enabled Worksheet 2007
Microsoft Visual Basic
I've been searching on ways to resolve my issue and couldn't really find the key to resolve this.
Case
In a worksheet I need to automatically insert a value (static timestamp) into column right after specified range of columns based on condition that they are all not null (have been filled).
Example goal
Given the order of inserting values into rows one after another, when values in range of columns A:C are filled, I'd want the column D (the next one after specified range) to update.
ColumnA ColumnB ColumnC AutoInsert
filled filled filled 2016-01-11 20:57
filled filled
filled
filled filled filled 2016-01-11 20:58
What have I got?
Right now when I insert value into column A current timestamp appears in column B.
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Cells.Count > 1 Then Exit Sub
If Not Intersect(Target, Range("A:A")) Is Nothing Then
With Target(1, 2)
.Value = Now
End With
End If
End Sub
Current results:
ColumnA AutoInsert
value 2016-01-11 21:06
value 2016-01-11 21:06
value 2016-01-11 21:07
What do I need?
I need some way to check for specified range of columns within row, not only the first column like shown above (in what have I got? section).
I'm not sure whether I need some other method than Intersect, or some kind of a loop. I've tried experimenting with Target(x, y) and Range("A:C"), but the behavior is different than expected and seems to be applied to each active cell.
Try this:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Cells.Count > 1 Then Exit Sub
If Not Intersect(Target, Range("A:C")) Is Nothing And WorksheetFunction.CountBlank(Range("A" & Target.Row & ":C" & Target.Row)) = 0 Then
With Me.Cells(Target.Row, 4)
Application.EnableEvents = False
.value = Now
End With
End If
Application.EnableEvents = True
End Sub
The Me refers to the sheet. It works because this is a worksheet event. If this was in a module it would need to be ActiveSheet. The .Cells is a Range. It used in this format Cells(Row,Column). The whole thing could have been rewritten as Me.Range("D" & Target.row).
Target is a range and doing Target(row,column) is shorthand for Target.Cells(row,column) You could have put Target(1,4). Target(1,1) would have referred to itself, or the upper left cell in a range of cells. It is not constrained by the range but uses the upper left cell as a starting point.
I have put values in columns from C to F, with G being the calculation from these cells (C to F).
Is there a way to automatically move to cell C in next row when I put the number in cell F at the end?
I have tried using macro plus VBA but it seems there is a problem.
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$H$6" Then
Call Macro1
End If
End Sub
MACRO
Sub Macro1()
'
' Macro1 Macro
'
ActiveCell.Offset(1, -3).Range("A1").Select
End Sub
In H6, I used the SUM of the F cell to trigger it but it didn't work.
You are checking only for the cell H6. It will only move if you type something in H6 other cells will have no effect.
So, test for the F column (number 6):
if Target.Column = 6 then
....
endif
Since the acive cell is probably below the one edited (if user pressed enter) or anywhere else (if user just clicked another place), using ActiveCell will be a bad thing, use the changed row instead:
if Target.Column = 6 then
call Macro1(Target.row)
end if
Sub Macro1(row as integer)
Worksheets("TheNameOfTheSheet").Cells(row,3).Select
end sub
This code will only fire if the user changes the value in cell H6. It doesn't fire if that value is changed due to a calculation (ie because the user changes the value in another cell). This is mentioned in the MSDN documentation for the Worksheet Change event at https://msdn.microsoft.com/en-us/library/office/ff839775.aspx.
Also, I would suggest not using ActiveCell.Offset as you don't know which cell will be active when macro1 is run. If the user types a number in F6 and presses enter then F7 becomes the Activecell, but if the user types a number and presses the right arrow key, it will be cell G6.
Instead of using ActiveCell, you can use Target from the Change event, as we know that is the cell that was updated:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$F$6" Then
Macro1 LastCell:=Target
End If
End Sub
Sub Macro1(LastCell As Range)
LastCell.Offset(1, -3).Select
End Sub
If you have more than one row of data and want to repeat the macro for a number of cells in F, you may want to test for a specific Colum (F), and a range of Row numbers, instead of one cell address. There's also no real need to call a separate sub unless you're doing something more complex. You might want to try something like the following:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column = 6 Then
If Target.Row > 1 And Target.Row < 10 Then
Target.Offset(1, -3).Select
End If
End If
End Sub
(You'd need to adjust the Row numbers according to your needs).
I have this function which is trying to detect when a particular cell value changes. The problem is, if the user selects the whole spreadsheet and presses delete, I get an overflow in my check that the range is only a single cell:
Public Sub Worksheet_Change(ByVal Target As Range)
'Overflow can occur here if range = whole spreadsheet
If Not IsError(Int(Target.Cells.Count)) Then
If Target.Cells.Count = 1 Then
If Target.Cells.Row = 4 And Target.Cells.Column = 1 Then
Sheets("X").Cells(5, 1).Calculate
End If
End If
End If
End Sub
Is there a more elegant way that I can get this code to only run, when a single particular cell value is changed? (with no overflows, problems when I clear the whole worksheet etc)?
I'm assuming you are on Excel 2007+ since the number of rows and columns increased dramatically in those versions. You might have better luck checking to make sure both the row and column count = 1, since those maxes will be much lower than the product of the two (ie, the cell count):
If Target.Rows.Count = 1 And Target.Columns.Count = 1 Then
Use CountLarge instead of Count
Private Sub Worksheet_SelectionChange(ByVal target As Range)
If target.Cells.CountLarge > 1 Then Exit Sub
'Code...
End Sub
See: MSDN Range.CountLarge Property (Excel)