Selection.Count overflow when selecting all cells - vba

In Excel 2007 I want to prompt a message when a cell (L2) is clicked on. I have a piece of code that works but the problem is that when I select all the cells in the sheet with Ctrl+A I get error number 06: overflow on the line If Selection.Count = 1 Then
Mandatory VBA code:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Selection.Count = 1 Then
If Not Intersect(Target, Range("L2")) Is Nothing Then
MsgBox "ACTION!"
End If
End If
End Sub

Easily fixed:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Selection.CountLarge = 1 Then
If Not Intersect(Target, Range("L2")) Is Nothing Then
MsgBox "ACTION!"
End If
End If
End Sub

Try this:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If InStr(1, CStr(Target.Address), ":") < 1 Then
If Selection.Count = 1 Then
If Not Intersect(Target, Range("L2")) Is Nothing Then
MsgBox "ACTION!"
End If
End If
End If
End Sub

You must change your code as follows. No Error-Traps needed:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Selection.Area.Count = 1 Then
If Not Intersect(Target, Range("L2")) Is Nothing Then
MsgBox "ACTION!"
End If
End If
End Sub

If you had 64-bit Excel I would tell you to use CountLarge instead of Count. Excel 2007 only comes in the 32-bit variety so that's not an option for you.
Your problem is that Range.Count returns a Long variable and throws an error if the number of cells is greater than a Long can store.
To get around this, you can do the following:
Use a Decimal data type stored inside a Variant. The combination can count more than the 1,048,576 rows x 16,384 columns of cells in an Excel worksheet.
Count the cells one column at a time to avoid the error with Range.Count.
I wrote a function that does that. Save this function in a regular code module (not a Worksheet or Workbook module) and use it like this:
If CountLarge32(Selection) = 1 Then
Here's the actual function:
Public Function CountLarge32(ByVal rangeOrSelection As Variant) As Variant
Dim target As Excel.Range
On Error Resume Next
Set target = rangeOrSelection
On Error GoTo 0
Dim cnt As Variant
Dim iColumn As Excel.Range
If Not target Is Nothing Then ' parameter -IS- a valid Range
' Use Range.Count on one column at a time to avoid the overflow error
' if counting higher than the limit of the Long data type.
For Each iColumn In target.Columns
cnt = CDec(cnt + iColumn.Cells.Count)
Next iColumn
CountLarge32 = cnt
End If
End Function
This function also avoids the error that occurs if Select is an object (e.g. button, shape, chart, etc.) instead of a cell.

Related

VBA Run time error on Worksheet_SelectionChange sub

I'm trying to figure out a way I can do a simple if statement to choose between two different statements in a Worksheet_SelectionChange Sub. If Intersect of one column is selected Then execute some code or if intersect of another column is selected then do some other code, if any other row is selected do nothing. Now unfortunately this isn't working as expected and drops a "Object variable or with block variable not set" error.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim CommentRow As Range
Dim TestRow As Range
Set TestRow = Intersect(Target, Range("J2:J10000"))
Set CommentRow = Intersect(Target, Range("G2:G10000"))
If ActiveCell = "" Then
GoTo Cancel
ElseIf ActiveCell = TestRow Then
GoTo TestRowComment
ElseIf ActiveCell = CommentRow Then
GoTo CommentRowComment
End If
This should be quite simple but I'm really not sure why it drops an error before reaching the Then statement. It worked fine with just one intersect when I only had CommentRow as my single Range adding the second range I'm not able to workout how to make it work.
You can check for the column without intersect:
Option Explicit
Private Const columnComment = 7 'G
Private Const columnTest = 10 'J
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim c As Range: Set c = Target.Cells(1, 1)
If c.Row >= 2 Then
Select Case c.Column
Case columnTest 'column J
'call sub for test
Case columnComment
'call sub for comment
End Select
End If
End Sub
```

Display cell content in a text box in excel using VBA

I have a range of cells with data. I want a text box to show the cell content when I click on any cell in the text box. Is this possible? Thanks
You could just use something like this:
Option Explicit
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim i As Long
Dim lRow As Long
lRow = Cells(Rows.Count, 1).End(xlUp).Rows
For i = 1 To lRow
If Cells(i, 1).Count = 1 Then
If Cells(i, 1) = "" Then
Else
If Not Intersect(Target, Cells(i, 1)) Is Nothing Then
MsgBox (i)
End If
End If
End If
Next i
End Sub
This will show the value in a message box, not a text box. Not sure why you need a text box.
i refers to the row and change the 1 in lRow = Cells(Rows.Count, 1).End(xlUp).Rows to the correct column number you are working in
Add this to the worksheet (see the black arrow):
Option Explicit
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
MsgBox Target.Value
End Sub
In general, if you want to check for a specific range, you can define the range in the event:
Option Explicit
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim rngPreselected As Range
Set rngPreselected = Range("A1:B10")
If Not Intersect(Target, rngPreselected) Is Nothing Then
MsgBox Target.Value
End If
End Sub
In this case, A1:B10 is the defined range.
That's called Event. See more about events here: http://www.cpearson.com/excel/events.aspx

Macro with show messsage box if cell contains value

I would like to do a macro. My testing cells are on another sheet. Sheet - (data) Macro check a range ("D2:D10") if the cells contain value 12 if yes show me a message box "Go to add to system" and this cell where macro found a value will be set to 0.
I have this code but it doesn't work for me I don't known why. Can you help me?
Private Sub check(ByVal Target As Range)
For Each c In Worksheet("data").Range("D2:D10")
If Range("D2:D10") = 12 Then
MsgBox "Go to add to system"
Range ("D2:D10").value = 0
End If
Next c
End Sub
The code below will correct your code (it will run without errors):
Option Explicit
Private Sub check(ByVal Target As Range)
Dim c As Range
For Each c In Worksheets("data").Range("D2:D10")
If c.Value = 12 Then
MsgBox "Go to add to system"
c.Value = 0
End If
Next c
End Sub
However, you could go with a slightly different approach - by accomplishing what you are trying to achieve in the Worksheet_Change event (of "data" sheet).
Code
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Dim c As Range
' Optional : use if criteria below to check the range only
' if one of the cells inside range("D2:D10") has changed
If Not Intersect(Range("D2:D10"), Target) Is Nothing Then
' if you decide to use the "If"above, then you don't need the "For" loop below
For Each c In Range("D2:D10")
If c.Value = 12 Then
MsgBox "Go to add to system"
c.Value = 0
End If
Next c
End If
End Sub

VBA - Open a UserForm by clicking anywhere in a specific column

I would like to build a makro in VBA which opens a UserForm when I click in a cell in a specific column, for more details look here.
With this code (from Mr.Burns):
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Selection.Count = 1 Then
If Not Intersect(Target, Range("A1")) Is Nothing Then
'name of userform .Show
End If
End If
End Sub
I was able to open the UserForm by clicking in the cell A1, but not by clicking in any cell inside the column A.
I tried to solve this problem with this code:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Selection.Count = 1 Then
Dim check As Boolean
check = True
If check Then
Dim i As Long
For i = 1 To 100000
If Not Intersect(Target, Range("A" & i)) Is Nothing Then
UserForm1.Show
check = False
End If
Next
End If
End If
End Sub
It actually works fine, but it is very slow, is there any better possibility to solve this?
To display the form when a cell is selected in column A:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
' if target is one cell and in column A
If Target.Columns.count = 1 And Target.Rows.count = 1 And Target.Column = 1 Then
UserForm1.Show
End If
End Sub
You can use .count and .column property together with AND and it will become so much simple and fast. Following code triggers pop-up if u click in column A on active-sheet
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
On Error GoTo errorhandler
If Target.Count = 1 And Target.Column = 1 Then '.count to check if only one cell is selected and .column to check if it is a first column
'UserForm1.Show
'Do whatever you want to do here like opening User form
MsgBox "You clicked in column A"
End If
errorhandler:
End Sub

Run-Time error '1004' with my VBA for hiding and unhiding rows

I have code for hiding and unhiding rows in my sheet based on changing the value in my dropdown. Every time I change the dropdown I get Run-Time error of '1004'. I had a private Sub before and changed it to a Sub but that doesn't seem to be the solution.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rng As Range
Set rng = Target.Parent.Range("L6")
If Target.Count > 1 Then Exit Sub
If Intersect(Target, rng) Is Nothing Then Exit Sub
Application.Run "dynamic_hide"
End Sub
Sub dynamic_hide()
If Target.Range = "$S$9:$S$51" Then
If Target.Range = 0 Then Rows("F9:T51").EntireRow.Hidden = True
If Target.Value <> 0 Then Rows("F9:T51").EntireRow.Hidden = False
End If
End Sub
You have a few problems going on here:
First, the default property of a Range object is Value, so Target.Range = "$S$9:$S$51" will always be false. Use Target.Address instead.
Second, don't use Application.Run to call Subs from the same VBProject. Use Call instead.
Third, you've not let the sub dynamic_hide know what Target is since Target is only a parameter of the Worksheet_Change event subroutine. You can solve this by declaring your sub like Sub dynamic_hide(ByVal Target As Range) And then you can use it: Call dynamic_hide(Target)
Lastly, since Target is a range you don't need to use Target.Range since Target is a range so you can simply omit every .Range from Target.Range Target.Parent.Range is fine.