I have Worksheet_SelectionChange function. In the first line I wanted to condition that if more than 1 cell is selected then exit.
I wrote:
If Target.Cells.Count > 1 Then Exit Sub
However, when I select the whole worksheet, I get an error message:
"Run time error 6 - Overflow"
It seems like Target.Count can't handle such large numbers ?
What can I do to get around this?
Replace Count with CountLarge.
Documentation: http://msdn.microsoft.com/en-us/library/office/ff196838(v=office.15).aspx
The CountLarge property is functionally the same as the Count property, except that the Count property will generate an overflow error if the specified range has more than 2,147,483,647 cells (one less than 2048 columns). The CountLarge property, however, can handle ranges up to the maximum size for a worksheet, which is 17,179,869,184 cells.
Break the check into rows and columns. This way, the count encounters a maximum of "only" 1,048,576 (rows) as opposed to 17,142,120,448 cells.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Rows.Count > 1 Then Exit Sub
If Target.Columns.Count > 1 Then Exit Sub
' do stuff
End Sub
Related
I have created VBA code that displays a message box when a certain condition is met. This if statement loops through a determined range. However, the message box is displayed for every cell that meets my condition. Is there a way to ensure the message box is only displayed once?
Here is my code:
Private Sub Worksheet_Change(ByVal Target As Range)
For Each cell In Range("S194:BZ194")
If cell.Value < 0 Then
MsgBox "Unrestricted cash cannot be less than zero (Row 194). Please lower the loan growth rate."
End If
Next
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
For Each cell In Range("S194:BZ194")
If cell.Value < 0 Then
MsgBox "Unrestricted cash cannot be less than zero (Row 194). Please lower the loan growth rate."
Exit For
End If
Next
End Sub
I am trying to find if a user deletes values in certain cells in column B then cells in same rows in column X are also deleted using worksheet_change function.
When I delete only one cell in column B then IsEmpty(Target) returns true and I am able to clear the same row cell in column X.
However, when select multiple cells in column B and press delete button, the IsEmpty(Target) returns False. Now here Target is range of multiple cells. I just can't find a way to find if a user has deleted range of values in column B at the same time. Any help would be much appreciated.
Below code works when one cell is deleted but not when a range of cells are deleted.
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column <> 2 Then Exit Sub
If Target.Columns.Count > 1 Then Exit Sub
If IsEmpty(Target) Then
Application.EnableEvents = False
ActiveSheet.Range("X" & Target.Row & ":X" & Target.Row + Target.Rows.Count - 1).ClearContents
Application.EnableEvents = True
End If
End Sub
Thanks
Uttam
You misunderstand the purpose of the function IsEmpty.
I guess what you are really looking for are cells which do not contain a value (blank cells). The following line will give you the count of cells which contain a value. If that is equal to zero then they are all blank.
Target.SpecialCells(xlCellTypeConstants).Count
Yet, the above line of code will result in an error if all cells are empty. Hence, you will have to adjust your code as follows:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column <> 2 Then Exit Sub
If Target.Columns.Count > 1 Then Exit Sub
Dim bolIsEmpty As Boolean
On Error GoTo AllAreEmpty
bolIsEmpty = Target.SpecialCells(xlCellTypeConstants).Count = 0
On Error GoTo 0
If bolIsEmpty Then
' ... your code here ...
End If
Exit Sub
AllAreEmpty:
bolIsEmpty = True
Resume Next
End Sub
Copy the column in question into a hidden worksheet (workSheet.Visible = xlVeryHidden), then use WorksheetFunction.CountA to compare the number of non-empty cells in the column of the visible worksheet and in the 'shadow' column of the hidden worksheet. This will quickly inform you if the number of cells with contents has decreased (i.e., contents have been deleted).
If so, get the .UsedRange of the observed column, find the first empty cell in it and check if the corresponding cell in the shadow column is empty as well. If yes, continue to the next empty cell; if not, you know the cell content has been deleted, and you can delete the corresponding cell content in your 'column X'.
After each Worksheet_Change event you need to make another 'shadow' copy.
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.
What would be the best way to write a VBA code to have a message box pop up if the value in one cell is less than or greater than another cell - and then display the difference?
Column N contains total appts (manual input)
Column R contains total results (formula generated)
If the cell in column R after calculated is less than or greater than the cell in column N the message box would pop up and say Total results is less than appts by # or Total results is greater than appts by #.
Add the following routine to your required sheet in the VBA project (e.g. Sheet1)
Private Sub Worksheet_Change(ByVal Target As Range)
If Target = Range("N1") Or Target = Range("R1") Then 'Only attempt to run the below code if target is a range you care about
If Range("R1").Value2 <> Range("N1").Value2 Then
MsgBox "Values differ"
End If
End If
End Sub
On the assumption that you want to compare two cells with one another (as opposed to a whole column of cells):
Private Sub Worksheet_Change(ByVal Target As Range)
If Range("N1") > Range("R1") Then
MsgBox "Oops. Results less than Input by " & Abs(Range("N1") - Range("R1"))
End If
If Range("N1") < Range("R1") Then
MsgBox "Oops. Results greater than Input by " & Abs(Range("N1") - Range("R1"))
End If
End Sub
That should achieve the following:
Compare two cells with one another whenever the sheet changes (regardless whether it be the formula generated value for R1, the manual input for N1, or anything else on the sheet)
Identify which is greater
Pop up an appropriate message
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)