Where to put my code - VBA - excel

I have a code running on my sheet. This code contains two subroutines. But I want to run this code in all my sheets and I was wondering what would be the best approach.
The total code that is running is the following:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim Rng As Range
Set Rng = Range(Cells(3, 6), Cells(500, 7))
Dim Intersection
Set Intersection = Application.Intersect(Target, Rng)
If Target.Cells.Count = 1 Then
If Not Intersect(Target, [B2]) Is Nothing Then _
Range("E:E").Find(vbNullString, [E3], , , , xlNext).Select
End If
If Not Intersection Is Nothing Then
If IsNumeric(Selection.Value) And Selection.Value <> "" Then
If (GetAsyncKeyState(vbKeyRButton)) Then 'right mouse button
Selection.Value = (Selection.Value + 1)
Cells(Selection.Row, 1).Select
End If
End If
End If
End Sub
Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)
Dim Rng As Range
Set Rng = Range(Cells(3, 6), Cells(500, 7))
Dim Intersection
Set Intersection = Application.Intersect(Target, Rng)
If Not Intersection Is Nothing Then
Cancel = True
End If
End Sub
If anyone could give me tips, it would be much appreciated!

Put your code in module. You can follow below link.
http://www.contextures.com/xlvba01.html

It is more complicated that just putting your code in another location. If you put your code in a module (which is the right move) you will need to tell it to run on other sheets too. You're code can be written to apply to any sheet in any open or closed workbook from a Worksheet objects code module, too. It is all about how it is written.
Are you using works like Me or ActiveSheet in your code? This is red flag that no matter where you place it the result will probably not be what you are looking for.

If you want a change event to be effective for all the sheets in a workbook, put the code in the ThisWorkbook module and use the Workbook_SheetChange event. This event will fire when any cell is changed in any sheet.
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
End Sub

Related

Is there a way to make a multi-step worksheet change macro work?

I'm building out a simple proof of concept inventory management system. To simplify the steps, I'm using excel vba's event change functionality with private subscripts on the sheets. The process flow should look like this: work order number is scanned into cell I2, triggering cell L4 to be selected. After something is entered into range L4:L13, it will then move to the next column over. Once cell O4 is changed, it will kick off another macro to update the database of entries. The problem lies in the fact that when cell I2 is changed, nothing happens.
I've tried creating multiple change event private subscripts, but that didn't work.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim WorkOrder As Range
Dim MoveTo As Range
Dim ChangeStatus As Range
Dim ChangeComplete As Range
Set WorkOrder = Range("I2")
Set MoveTo = Range("L4:L13")
Set ChangeStatus = Range("M4:M13")
Set ChangeComplete = Range("O4")
If Not Application.Intersect(WorkOrder, Range(Target.Address)) _
Is Nothing Then
Range("L4").Select
ElseIf Not Application.Intersect(MoveTo, Range(Target.Address)) Is Nothing Then
Range("M4").Select
ElseIf Not Application.Intersect(ChangeComplete, Range(Target.Address)) Is Nothing Then
Call Module1.EditWorkOrderStatus
End If
Range("i2").Select
End Sub
I expect the macro in module1 to run and clear out all of the changed cells, but nothing is occurring. I'm receiving no errors on my code at this time.
UPDATED CODE:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim WorkOrder As Range
Dim MoveTo As Range
Dim ChangeStatus As Range
Dim ChangeComplete As Range
Set WorkOrder = Range("I2")
Set MoveTo = Range("L4:L13")
Set ChangeStatus = Range("M4:M13")
Set ChangeComplete = Range("O4")
If Not Application.Intersect(WorkOrder, Target) _
Is Nothing Then
If WorkOrder = "" Then
WorkOrder.Select
Else
Range("L4").Select
End If
ElseIf Not Application.Intersect(MoveTo, Target) Is Nothing Then
Range("M4").Select
ElseIf Not Application.Intersect(ChangeComplete, Target) Is Nothing Then
If ChangeComplete = "" Then
Else
Call Module1.EditWorkOrderStatus
Range("o4").ClearContents
Range("i2").Select
End If
End If
End Sub
you can try:
If Not Application.Intersect(Target, Me.Range("I2")) Is Nothing Then

Vba beginner question: same macro applied differently shows different behaviour

I have the following question:
The code you see below has been pasted in an excel object
Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Application.ScreenUpdating = False
Dim DAY, other As Range
Set DAY = Range("b4:af4")
If Not Intersect(DAY, Range(Target.Address)) Is Nothing Then
ActiveCell.Copy
Sheets("SP Analysis").Activate
Range("b2").PasteSpecial Paste:=xlPasteValues
'ElseIf Not Intersect(other, Range(Target.Address)) Is Nothing Then
End If
End Sub
The macro runs but it doesn't copy the activecell in the sheet SP Analysis.
If I change the code with the following:
Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) Application.ScreenUpdating = False Dim DAY, other As Range Set DAY = Range("b4:af4")
If Not Intersect(DAY, Range(Target.Address)) Is Nothing Then Call TEST
'ElseIf Not Intersect(other, Range(Target.Address)) Is Nothing Then End If End Sub
with macro TEST doing
sub test
ActiveCell.Copy
Sheets("SP Analysis").Activate
Range("b2").PasteSpecial Paste:=xlPasteValues
end sub
The command does what is supposed to do.
Question is why? what's the difference between one method and the other?
And, how can I have the command working in an excel object rather than having to call a macro?
Thank you
Try this. Use Target rather than ActiveCell although in this case I don't know why the latter wouldn't work. And we can transfer the value directly without having to activate anything.
Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Application.ScreenUpdating = False
Dim DAY As Range, other As Range 'need to specify type for each variable, otherwise Variant
Set DAY = Range("b4:af4")
If Not Intersect(DAY, Target) Is Nothing Then
Cancel=True
Sheets("SP Analysis").Range("b2").Value = Target.Value 'use target
End If
Application.ScreenUpdating = True 'turn it back on
End Sub

Which arguments should be used when calling a sub with parameters (ByVal Target As Range)

I'm making a macro on VBA that is attached to a data validation list in excel. When a certain option is selected from the list I want it to run a macro assigned to that selection. However I am repeatedly getting the error 'Compile error. Argument is not optional.' I understand I need to add parameters after calling the macro but anything I enter results in 'Object required' or 'expected )'
This code is in my worksheet. The line 'Case "Fifteen": Macro1' is the one with the error.
Private Sub Worksheet_change(ByVal Target As Range)
If Not Intersect(Target, Range("P4")) Is Nothing Then
Select Case Range("P4")
Case "Fifteen": Macro1
End Select
End If
End Sub
The following code is located in a module - It is used to copy values from the cells in one worksheet to another.
Sub Macro1(ByVal Target As Range)
Dim r1 As Range, r2 As Range
Set r1 = Sheets("Calculator").Range("C18:D19")
Set r2 = Sheets("Answers").Range("I14:J15")
If Intersect(Target, r1) Is Nothing Then Exit Sub
Application.EnableEvents = False
r2.Value = r1.Value
Application.EnableEvents = True
End Sub
Any idea's what the Argument parameters should be? I thought it would be along the lines of Case "Fifteen":Macro1("C18:D19") or Case "Fifteen":Macro1(r1), but no luck was had.
The code in the module works when it is on its own so I don't think there would be any issues with it.
Any help is greatly appreciated. I looked around and couldn't find an answer.
Thanks for the help. By removing the intersect lines it now works as intended. The final code is below.
Private Sub Worksheet_change(ByVal Target As Range)
Select Case Range("P4")
Case "Fifteen": Macro1
End Select
End If
End Sub
Sub Macro1()
Dim r1 As Range, r2 As Range
Set r1 = Sheets("Calculator").Range("C18:D19")
Set r2 = Sheets("Answers").Range("I14:J15")
Application.EnableEvents = False
r2.Value = r1.Value
Application.EnableEvents = True
End Sub

Excel VBA: Worksheet Change cell value to different sheet

I've been working on this for some time now and have hit a real stumbling block.
I have a set of values that are available via a validated dropdown menu in Sheet 3, Column D. Once selected this value currently displays in a different sheet (Sheet 7) using excel function ='Sheet 3'!D4 and so on, and I have some code that reads this and performs an IF statement to produce a value in another cell.
My problem is the code is dependant on reading the value and not the formula.
I currently have a worksheet change command for a separate function I want to run, is there a way for this to run a second function and call any changes from sheet 3 column D into sheet 8 column D and then run my other change function?
Sheet 7 Code:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim c As Range
If Intersect(Target, Range("D2:D102")) Is Nothing Then Exit Sub
Application.EnableEvents = False
On Error GoTo Finalize
For Each c In Target.Cells
Select Case c.Column
Case 4
Call Print_Quality(c)
End Select
Next c
Finalize:
Application.EnableEvents = True
End Sub
Sheet 7 Module:
Sub Print_Quality(c As Range)
Dim PrintQuality As String
Dim PrintSpeed As String
PrintQuality = c.Value
If PrintQuality = "A Quality 1" Then PrintSpeed = "100"
c.Offset(0, 5).Value = PrintSpeed
End Sub
I've been trying this route but to no avail:
Worksheet 3 code:
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Range("D4:D104")) Is Nothing Then Exit Sub
Application.EnableEvents = False
On Error GoTo Finalize
UpdateVal
Finalize:
Application.EnableEvent = True
End Sub
Module:
Sub UpdateVal()
Worksheets("Sheet 7").Range("D2").Value = Worksheets("Sheet 3").Range("D4").Value
End Sub
Many thanks
Sods law, I've managed to fix this an hour after my desperation post.
I completed another worksheet change from the sheet it was calling from (Sheet 3)
Private Sub Worksheet_Change(ByVal Target As Range)
Dim KeyCells As Range
Set KeyCells = Range("D4:D104")
If Not Application.Intersect(KeyCells, Range(Target.Address)) Is Nothing Then
Call UpdateVal
End If
End Sub
then added this function into the module
Sub UpdateVal()
Sheet8.Cells(2, 4).Value = Sheet3.Cells(4, 4)
End Sub
this now references the value of the dropdowns in sheet 8 and allows other functionality to continue using the cell value
Have you tried stepping through your code to see where it is having an issue? It not, I would suggest putting a break at the beginning of each module, and then use F8 to step through. This will confirm it is running as it should.
You should also be fully-qualifying your references to worksheets. While presumably the sheet references should carry through given that they are in worksheet modules, there is the chance of failure. You can simply assign a variable to hold the worksheet like so:
Dim wb as Workbook
Dim ws as Worksheet
Set wb = ThisWorkbook
Set ws = wb.Sheets("YourSheetName")
Additionally, your worksheet 3 code:
EnableEvent = True
Should be:
EnableEvents = True

Excel Worksheet_Change Event not working

I am trying to write a macro where changing any column
should automatically save worksheet.
My Excel sheet expands till G25.
I tried this but its not working:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Target.Worksheet.Range("G25")) Is Nothing Then
ActiveWorkbook.Save
End Sub
I have save it under ThisWorkBook.
Any help is appreciated.
Under ThisWorkbook that handler is called Workbook_SheetChange and it accepts two arguments, Sh (of type Object) and Target (a Range). So, your code won't work there.
If you put your code in the sheet you want (Sheet1, for instance) instead of in the ThisWorkbook, put the End If and change the range to "A1:G25" (representing a square from row 1 column A to row 25 column 25), it should work.
This did:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Target.Worksheet.Range("A1:G25")) Is Nothing Then
MsgBox "changed"
End If
End Sub
For completeness, under ThisWorkbook, this will work:
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
If Not Intersect(Target, Target.Worksheet.Range("A1:G25")) Is Nothing Then
MsgBox "changed"
End If
End Sub
The other common reason why an Event doesn't work is that EnableEvents has been set to False
I would code your problem like this as
typically you need to work with the range of interest that is being tested. So creating a variable rng1 below serves both as an early exit point, and a range object to work with. On a sheet event Target.Worksheet.Range("A1:G25") will work but it is lengthy for it's actual use
If you do have a range to manipulate then making any further changes to the sheet will trigger a recalling of the Change event and so on, which can cause Excel to crash. So it is best to disable further Events, run your code, then re-enable Events on exit
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rng1 As Range
Set rng1 = Intersect(Target, Range("A1:G25"))
If rng1 Is Nothing Then Exit Sub
Application.EnableEvents = False
'work with rng1
Application.EnableEvents = True
End Sub

Resources