intersection in vb - vba

why use we this statement if not intersect(...) is nothing then
but do not use intersect(...) is nothing?

Often when we use intersect we wish to know if two ranges intersect.
Intersect returns where these ranges intersect, but we often aren't interested in WHERE, but IF. So we ignore the returned value, and just check that we do get a value.
If Not Intersect() is Nothing Then
There's nothing stopping you from using it without the Not, even the documentation example is using it this way.
The reason why we usually don't do it in say, a selection_change is that the If returns true when the ranges do not intersect. And usually, we want to do things when they do intersect. This would make you end up with an empty If, and forcing you to use else as a trigger.
Consider the following:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Not Intersect(Target, Range("A1")) Is Nothing Then
'Do things
End If
End Sub
Compared to
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Intersect(Target, Range("A1")) Is Nothing Then
'Do nothing
Else
'Do things
End If
End Sub

Related

VBA Goal Seek To without going below zero

I built a goal seek formula which works, however when you increase the target cell (G3) by too much of an increase, excel keeps reiterating into the negative and cant figure out a solution. Is there a way to add a condition to make the changing cell ("b2") have to be greater than negative, or make it so goal seek guesses is high enough that it will find the ideal positive goal seek before going negative. Here is the current code.
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Application.Intersect(Target, Range("g3")) Is Nothing Then
Range("g21").GoalSeek Goal:=1.3, ChangingCell:=Range("b2")
End If
End Sub
Figured it out. I set the changing range to be set to well above any potential answer, and then it will work every time.
> Private Sub Worksheet_Change(ByVal Target As Range)
> If Not Application.Intersect(Target, Range("g3")) Is Nothing Then
> Range("b2") = 1000000000
> Range("g21").GoalSeek Goal:=1.3, ChangingCell:=Range("b2")
> End If End Sub

Change formatting of Cell when it is edited

I want to change the formatting of a cell if the value changes. I just need it to be shaded in.
I'm trying to use the following:
Private Sub Worksheet_Change(ByVal Target As Range)
Target.Interior.ColorIndex = 45
End Sub
However this is far too sensitive. For example if i delete a row, the entire row changes colour as technically it's a change. Even if I go into a cell, make no change and come out of it, it changes the formatting.
Is there anyway to edit the above so it only formats the cell's when the value has changed?
Thanks
I think you could use below code as a base for your further logic.
The idea is: we need to remember value before it is changed, so best to read it when some range is selected (since you are talking about single cell, I didn't consider ranges consisting of more cells). The value would be stored in global variable ValueOnEnter.
When the change is finally made, we compare values "before" and after", and if they differ, change the color.
Public ValueOnEnter As String
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Count > 1 Then Exit Sub
If Target.Value <> ValueOnEnter Then
Target.Interior.ColorIndex = 45
End If
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Count > 1 Then Exit Sub
ValueOnEnter = Target.Value
End Sub

Run macro when cell changes pass value

I have this certain code on a worksheet event cell change. It finds certain data that I have on a Worksheet when I type an id_parameter on cell A1.
After data is found, it writes it on this worksheet.
Now I'd like to run a different macro when I change the values on column C of the data.
I'm not able to find the proper procedure. Do_something() receives the value changed in column C. I hope I explained it clearly enough.
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("A1")) Is Nothing Then
Call Search_data
End If
'Data is written in B2:E10
If Not Intersect(Target, Range("C2:C10")) Is Nothing Then
Call Do_something(Target.Value)
End If
End Sub
The code you have posted works as intended. The issue is most probably due to Search_Data and or Do_Something.
You change the cell A1 which then changes all cells from B2:E10. Including the changed C2:C10 so make sure that the change_event cannot be triggered again by this.
Option Explicit
Public EventsDisabled As Boolean
Private Sub Worksheet_Change(ByVal Target As Range)
If Not EventsDisabled Then
EventsDisabled = True
If Not Intersect(Target, Range("A1")) Is Nothing Then
Call search_data
End If
'Data is written in B2:E10
If Not Intersect(Target, Range("C2:C10")) Is Nothing Then
Call do_something(Target.Value)
End If
End If
End Sub
The Public variable EventsDisabled will make sure that the change event runs when a user input is given but not if a Worksheet_Change event changes the worksheet. Otherwise you will run into all sorts of weird loopings which might be infinite or at least take a long time. Your issue will most probably also be related to this. Make sure that your Do_Something sub has the right input type. You should set a few breakpoints and open the local window under:
view>local window here you can see all variables and objects and their type. You can also type:
debug.print typename(Target.value)
into the direct window and then see what type you need to type into the Do_Something signature.

How to prevent copy/paste in excel only for some columns or cells

Is there a way prevent copy/paste for some columns in Excel?.
Here is a potential workaround although it may not be satisfactory; you can make a range essentially unselectable therefore no copying or pasting would work as you can't actually select the data.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim LockedRange As Range: Set LockedRange = Me.Range(Columns(1), Columns(3))
If Not Application.Intersect(Target, LockedRange) Is Nothing Then
Me.Range("D1").Select
End If
End Sub

Hide Active Column when cell value is changed

I have been trying to work this out myself for the last few days and caught myself in a bit of a one step forward three steps back cycle. I've been reluctant to bother you thinking this would have been answered somewhere else before now.
The idea is that I have a spreadsheet that has criteria in rows with separate entries in rows; in row 6 it is the status of each column entry, which when changed to "Completed" I would like the column to be hidden.
I've been floundering around with Worksheet_Change and been able to hide specific columns, but not the active column.
Any help offered would be much appreciated and I'm sorry if this has been covered elsewhere, but I've not been able to successfully apply any examples out there.
Thanks.
Whenever you have to work with worksheet_change events, you have to consider a cycle for it, due to user may delete multiple data at the same time or do a copy paste, if you only consider "Target" It would give a debugger error.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim ItemMultipleData As Range
For Each ItemMultipleData In Target 'handles multiple cells, paste, del, etc
'your code (instead of using "Target" change to ItemMultipleData. IE:
'If ItemMultipleData.Value = "Completed" Then
Next ItemMultipleData
End Sub
Here is a starting point. It only checks row # 6:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rng As Range
Set rng = Range("6:6")
If Intersect(Target, rng) Is Nothing Then Exit Sub
If Target.Count <> 1 Then Exit Sub
If Target.Value = "Completed" Then
Application.EnableEvents = False
Target.EntireColumn.Hidden = True
Application.EnableEvents = True
End If
End Sub
EDIT#1:
This approach assumes that only one cell at a time is being changed........that makes it easy to "find the active cell"