I have been trying to create a notification system for Excel VBA, however I've hit a brick wall that I can't seem to be able to solve. I keep getting Error 404 - Object Required for the code I created. Hope you all can help.
Public price_col As Range
Public vol_col As Range
Public Sub setVars()
Set price_col = Range("E2:E90")
Set vol_col = Range("J2:J90")
End Sub
Private Sub Worksheet_Calculate()
checkPrice price_col
checkVol vol_col
End Sub
Private Sub Worksheet_Change(ByVal target As Range)
setVars
If Not Intersect(target, price_col) Is Nothing Then
checkPrice target
End If
If Not Intersect(target, vol_col) Is Nothing Then
checkVol target
End If
End Sub
Public Sub checkPrice(target As Range)
**For Each cell In target**
Dim row As Long
row = Range(cell.Address).row
If cell.Value > 0.025 Then
If ThisWorkbook.getPriceState(row) <> 1 Then
MsgBox "Price " & Application.WorksheetFunction.RoundDown(cell.Value * 100 / 1, 0) * 1 & "% rise: " & Range(cell.Address).Offset(0, -2).Value
ThisWorkbook.setPriceState row, 1
End If
ElseIf cell.Value < -0.025 Then
If ThisWorkbook.getPriceState(row) <> -1 Then
MsgBox "Price " & Application.WorksheetFunction.RoundDown(cell.Value * 100 / 1, 0) * 1 & "% fall: " & Range(cell.Address).Offset(0, -7).Value
ThisWorkbook.setPriceState row, -1
End If
ElseIf cell.Value <> "" Then
If ThisWorkbook.getPriceState(row) <> 0 Then
ThisWorkbook.setPriceState row, 0
End If
End If
Next cell
End Sub
Public Sub checkVol(vol_col As Range)
For Each cell In vol_col
Dim row As Long
row = Range(cell.Address).row
If cell.Value >= 2.5 Then
If ThisWorkbook.getVolState(row) <> 3 Then
MsgBox "Volume Change above 250%" & Range(cell.Address).Offset(0, -7).Value
ThisWorkbook.setVolState row, 3
End If
ElseIf cell.Value >= 2 Then
If ThisWorkbook.getVolState(row) <> 2 Then
MsgBox "Volume Change above 200%" & Range(cell.Address).Offset(0, -7).Value
ThisWorkbook.setVolState row, 2
End If
ElseIf cell.Value >= 1.5 Then
If ThisWorkbook.getVolState(row) <> 1 Then
MsgBox "Volume Change above 150%" & Range(cell.Address).Offset(0, -7).Value
ThisWorkbook.setVolState row, 1
End If
ElseIf cell.Value <> "" Then
If ThisWorkbook.getVolState(row) <> 0 Then
ThisWorkbook.setVolState row, 0
End If
End If
Next cell
End Sub
I got the error on the code "for each cell in target"; which was bolded. Thanks for helping!
If your calculate event fires, and the variables aren't set, then you'll get the error. At the very least, you should add a call to setVars at the start of Worksheet_Calculate
Related
I need to find the match for each cell(C:C)value of sheet1 in sheet2 (C:C) and if the value matches copy the corresponding next cell i.e, D:D and replace in sheet 2. If it does not match then copy and paste the Range A to D in the next empty cell in sheet 2
Sub Method1()
Dim strSearch As String
Dim strOut As String
Dim bFailed As Boolean
Dim i As Integer
strSearch = Sheet1.Range("C2")
i = 1
Do Until ActiveCell.Value = Empty
ActiveCell.Offset(1, 0).Select 'move down 1 row
i = i + 1 'keep a count of the ID for later use
Loop
'ActiveCell.Value = i
On Error Resume Next
strOut = Application.WorksheetFunction.VLookup(strSearch, Sheet2.Range("C:C"), 2, False)
If Err.Number <> 0 Then bFailed = True
On Error GoTo 0
If Not bFailed Then
MsgBox "corresponding value is " & vbNewLine & strOut
Else
MsgBox strSearch & " not found"
End If
End Sub
Sheet1:`enter code here
Sheet2:
However, I made change to my code and it does the job, but I want to repeat the function for each cell in C:C, have a look
Sub Method1()
Dim strSearch As String
Dim strOut As String
Dim bFailed As Boolean
Dim i As Integer
strSearch = Sheet1.Range("C2")
i = 1
'Do Until ActiveCell.Value = Empty
ActiveCell.Offset(1, 0).Select 'move down 1 row
i = i + 1 'keep a count of the ID for later use
' Loop
'ActiveCell.Value = i
On Error Resume Next
strOut = Application.WorksheetFunction.VLookup(strSearch, Sheet2.Range("C:C"), 1, False)
If Err.Number <> 0 Then bFailed = True
On Error GoTo 0
If Not bFailed Then
Worksheets("Sheet1").Range("e2").Copy
Worksheets("Sheet2").Range("e2").PasteSpecial Paste:=xlPasteFormulas
Application.CutCopyMode = False
ActiveCell.Interior.ColorIndex = 6
MsgBox "corresponding value been copied " & vbNewLine & strOut
Else
MsgBox strSearch & " not found"
End If
End Sub
Try this:
Sub Method1()
Dim cSearch As Range, m
Set cSearch = Sheet1.Range("C2")
Do While Len(cSearch.Value) > 0
'omit the "WorksheetFunction" or this will throw a run-time error
' if there's no match. Instead we check the return value for an error
m = Application.Match(cSearch.Value, Sheet2.Range("C:C"), 0)
If Not IsError(m) Then
'got a match - update ColD on sheet2
Sheet2.Cells(m, "D").Value = cSearch.Offset(0, 1).Value
Else
'no match - add row to sheet2 (edit)
cSearch.Offset(0, -2).Resize(1, 4).Copy _
Sheet2.Cells(Rows.Count, "A").End(xlUp).Offset(1, 0)
End If
Set cSearch = cSearch.Offset(1, 0) 'next value to look up
Loop
End Sub
I'm trying to get a piece of code that, when a cell in column 8 changes it deletes the value of cell next to it(column 9).
Well... That is the simple version
Column 8 and 9 are both dropdown lists, the dropdown list in column 9 is dependent on column 8. In column 9, multiple answers are necesary so i found a code on the internet that made that possible, but now the value in column 9 doesn't delete automatically when i change the value in column 8.
This piece of code below works, but only when i change 1 cell(in column 8) at the time. It doesn't work when i paste multiple Cells in Column 8 or when i select a cell in column 8 and then drag it down(from the lower right corner).
I don't have a lot of experience with coding and just can't seem to find the right solution for this.
Thanks to QHarr i got a bit further.
This is my second attempt:
Dim ClearC9 As String
Dim i As Long
For i = 2 To 1000
If Target.Cells.Count > 1 Then GoTo ClearC9
If Not Intersect(Target, Range("H" & i)) Is Nothing Then
Range("I" & i).ClearContents
End If
Next i
exitHandler:
Application.EnableEvents = True
Columns("I:I").EntireColumn.AutoFit
ClearC9:
Selection.Offset(, 1).ClearContents
First Attempt:
Dim i As Long
For i = 2 To 1000
If Target.Cells.Count > 1 Then Exit Sub
If Not Intersect(Target, Range("H" & i)) Is Nothing Then
Range("I" & i).ClearContents
End If
This is the entire code:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rngDV As Range
Dim oldVal As String
Dim newVal As String
Dim lUsed As Long
If Target.Count > 1 Then GoTo exitHandler
On Error Resume Next
Set rngDV = Cells.SpecialCells(xlCellTypeAllValidation)
On Error GoTo exitHandler
If rngDV Is Nothing Then GoTo exitHandler
If Intersect(Target, rngDV) Is Nothing Then
'do nothing
Else
Application.EnableEvents = False
newVal = Target.Value
Application.Undo
oldVal = Target.Value
Target.Value = newVal
If Target.Column = 9 Then
If oldVal = "" Then
'do nothing
Else
If newVal = "" Then
'do nothing
Else
lUsed = InStr(1, oldVal, newVal)
If lUsed > 0 Then
If Right(oldVal, Len(newVal)) = newVal Then
Target.Value = Left(oldVal, Len(oldVal) - Len(newVal) - 2)
Else
Target.Value = Replace(oldVal, newVal & ", ", "")
End If
Else
Target.Value = oldVal _
& ", " & newVal
End If
End If
End If
End If
End If
Dim i As Long
For i = 2 To 1000
If Target.Cells.Count > 1 Then Exit Sub
If Not Intersect(Target, Range("H" & i)) Is Nothing Then
Range("I" & i).ClearContents
End If
Next i
exitHandler:
Application.EnableEvents = True
Columns("I:I").EntireColumn.AutoFit
End Sub
The general pattern to to create an intersection range:
if it is Nothing then do nothing
otherwise loop over its cells
for example:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rngDV As Range, TheIntersection As Range, r As Range
' stuff
TheIntersection = Intersect(Target, rngDV)
If TheIntersection Is Nothing Then
' do nothing
Else
For Each r In TheIntersection
' do something
Next r
End If
End Sub
I have an excel sheet, with column both A、B、C、D.
Both C & D number changes all the time (they have different criteria), since it calculates by stock data that fetches in real-time.
I need message box to pop up both when C & D matches my target value, and showing the the ticker in column A, the name in column B, and the number in C/D.
With the help I know the code when there is only column C:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.column = 3 And Target.value >= -4 And Target.value <= 4 Then
Call MsgBoxMacro(Target.value, Target.column, Target.row)
End If
End Sub
Sub MsgBoxMacro(value, column, row)
MsgBox "Ticker: " & Cells(row, column - 2) & vbNewLine & "Stock Name: " & Cells(row, column - 1) & vbNewLine & "Variable Value: " & value
End Sub
I don't know what to do, when I want to add column D data into the code. (so i can have message box pop up when D number reaches the criteria) please help.
Thank you!
By passing another parameter to the function MsgBoxMacro will solve your problem:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.column = 32 And Target.value >= -4 And Target.value <= 4 Then
Call MsgBoxMacro(Target.value, Target.column, Target.row, 0)
End If
If Target.column = 33 And Target.value >= -4 And Target.value <= 4 Then
Call MsgBoxMacro(Target.value, Target.column, Target.row, 1)
End If
End Sub
Sub MsgBoxMacro(value, column, row, counter)
MsgBox "Ticker: " & Cells(row, column - 31 - counter) & vbNewLine & "Stock Name: " & Cells(row, column - 30 - counter) & vbNewLine & "Variable Value: " & value
End Sub
Hope this helps.
Something like this, not far from what you had. This will go in the worksheet where the changes are to be made.
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column = 4 Then
If ((Target.Offset(0, -1).Value > -4 And Target.Offset(0, -1).Value < 4) And _
(Target.Value > -4 And Target.Value < 4)) Then
' Msgbox here
Else
End If
End If
End Sub
I have started creating a VBA Macro that helps me add formatting to rows as I add them with a custom NumberFormat. But since My partner and I sometimes Enter item like "ss.00" and this messed up the cell. So I started writing out another Sub where it checks if its missing the semicolon. How can I add "0:" to the front of this value automatically where the cell would show "0:50.20", Everytime I do it, it ends up being a long number.
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
If Target.Cells.Count = 1 Then
If Target.Column = 1 Then
If Target.Row < 24 And Target.Row > 1 Then
Set FirstRow = Target.Offset(0, 1)
Set LastRow = Target.Offset(0, 11)
If Target.Value <> "" Then
For Each Cel In Range(FirstRow, LastRow)
Cel.NumberFormat = "m:ss.00;#"
Next
Else
If MsgBox("This will erase the row! Are you sure?", vbYesNo) = vbNo Then
Exit Sub
Else
For Each Cel In Range(FirstRow, LastRow)
Cel.ClearContents
Next
End If
End If
End If
End If
Const sCheckAddress As String = "B2:L24"
Dim rngIntersect As Range
On Error Resume Next
Set rngIntersect = Intersect(Me.Range(sCheckAddress), Target)
On Error GoTo 0
If Not (rngIntersect Is Nothing) Then
If Target.Value2 <> "" Then
If InStr(Target.Value2, ":") < 1 Then
End If
End If
End If
End If
End Sub
Maybe this would help you :
If InStr(Target.Value2, ":") < 1 Then
' ":" not found
Target.Value = CStr("0:" & Target.Value)
Else
' ":" found
'Nothing to add
End If
I need help for VBA as I'm new to this programming language. Is it possible to have 2 different sets of codes in one sheet in the workbook?
I want to make the Excel sheet more interactive like clicking on certain cell then highlighting the entire row that the cell is selected. But the sheet that im trying to make it interactive has a set of codes already.
Here is the codes that I want to make the excel sheet interactive
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
initializeWorksheets
Dim ws As Worksheet
For Each ws In Worksheets
ws.Activate
' Clear the color of all the cells
Cells.Interior.ColorIndex = 0
If IsEmpty(Target) Or Target.Cells.Count > 1 Then Exit Sub
Application.ScreenUpdating = False
With ActiveCell
' Highlight the row and column that contain the active cell, within the current region
Range(Cells(.Row, .CurrentRegion.Column), Cells(.Row, .CurrentRegion.Columns.Count + .CurrentRegion.Column - 1)).Interior.ColorIndex = 6
End With
Next ws
Application.ScreenUpdating = True
End Sub
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
'filtering
Dim ws As Worksheet
ws.Activate
Dim ccolumn As Integer
Dim vvalue As String
ccolumn = ActiveCell.Column
vvalue = ActiveCell.Value
For Each ws In Worksheets
If IsEmpty(Target) Or Target.Cells.Count > 1 Then Exit Sub
Application.ScreenUpdating = False
With ActiveCell
Range(Cells(.Row, .CurrentRegion.Column), Cells(.Row, .CurrentRegion.Columns.Count + .CurrentRegion.Column - 1)).AutoFilter Field:=ccolumn, Criteria1:=vvalue
Cancel = True
End With
Next ws
End Sub
Here is the codes that it is used for the same sheet:
Private Sub Workbook_SheetFollowHyperlink(ByVal Sh As Object, ByVal Target As Hyperlink)
initializeWorksheets
Application.ScreenUpdating = False
If (ActiveSheet.Name = "Student Viewer") Then
searchKey = Trim(Target.Range.Value)
If (Right(searchKey, 1) = ")") Then
searchKey = Right(searchKey, Len(searchKey) - InStrRev(searchKey, "(", -1))
searchKey = Left(searchKey, Len(searchKey) - 1)
End If
temp = 2
Do While (mainSheet.Range(findColumn(mainSheet, "IC Number") & temp) <> searchKey & "")
temp = temp + 1
If (temp > 65535) Then
MsgBox ("Error in Finding xxxx Details")
End
End If
Loop
viewerSheet.Unprotect
' Set details
For i = 2 To 10
viewerSheet.Range("C" & i) = mainSheet.Range(findColumn(mainSheet, Left(viewerSheet.Range("B" & i), Len(viewerSheet.Range("B" & i)) - 1)) & temp)
viewerSheet.Range("F" & i) = mainSheet.Range(findColumn(mainSheet, Left(viewerSheet.Range("E" & i), Len(viewerSheet.Range("E" & i)) - 1)) & temp)
Next i
For i = 2 To 3
viewerSheet.Range("I" & i) = mainSheet.Range(findColumn(mainSheet, Left(viewerSheet.Range("H" & i), Len(viewerSheet.Range("H" & i)) - 1)) & temp)
Next i
loadSummary
viewerSheet.Protect
ElseIf (ActiveSheet.Name = "xxxx Viewer") Then
searchKey = Trim(Target.Range.Value)
viewerSheet2.Unprotect
' Set details
temp = 2
Do While (DetailsSheet.Range(findColumn(DetailsSheet, "Policy Num") & temp) <> searchKey & "")
temp = temp + 1
If (temp > 65535) Then
MsgBox ("Error in Finding Details")
End
End If
Loop
For i = 2 To 11
viewerSheet2.Range("C" & i) = DetailsSheet.Range(findColumn(DetailsSheet, Left(viewerSheet2.Range("B" & i), Len(viewerSheet2.Range("B" & i)) - 1)) & temp)
Next i
For i = 2 To 6
viewerSheet2.Range("I" & i) = ValuesSheet.Range(findColumn(ValuesSheet, Left(viewerSheet2.Range("H" & i), Len(viewerSheet2.Range("H" & i)) - 1)) & temp)
Next i
For i = 7 To 12
viewerSheet2.Range("I" & i) = DetailsSheet.Range(findColumn(DetailsSheet, Left(viewerSheet2.Range("H" & i), Len(viewerSheet2.Range("H" & i)) - 1)) & temp)
Next i
viewerSheet2.Hyperlinks.Add Anchor:=Range("C2"), Address:="", SubAddress:="'Client Viewer'!A1"
loadDetail
viewerSheet2.Protect
End If
Application.ScreenUpdating = True
End Sub
As commented, you can try this approach:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
On Error GoTo halt
Application.EnableEvents = False
With Me ' Me refers to the worksheet where you put this code
.Cells.Interior.ColorIndex = -4142 ' xlNone
If Not CBool(-Target.Hyperlinks.Count) Then ' Check if there is hyperlink
Target.EntireRow.Interior.ColorIndex = 6 ' or you can use RGB(255, 255, 0)
Else
Target.Hyperlinks(1).Follow ' follow hyperlink if there is
CodeFromYourFollowHyperlinkEvent ' call a routine
End If
End With
moveon:
Application.EnableEvents = True
Exit Sub
halt:
MsgBox Err.Description
Resume moveon
End Sub
As you can see above, CodeFromYourFollowHyperlinkEvent should be a sub that contains what you want done in your FollowHyperlink event as shown below.
Private Sub CodeFromYourFollowHyperlinkEvent()
' Put your code in FollowHyperlink here
initializeWorksheets
Application.ScreenUpdating = False
If (ActiveSheet.Name = "Student Viewer") Then
.
.
.
End Sub
Now take note that you need to exercise explicitly working on your objects.
To know more about that, check this cool post out.