Range & If Statement using multiple sheets - vba

I have several Sheets involved but I'll have Sheet 2 Active. When I'm on "Sheet 2" I need to know when cell ("C14") becomes active with an IF statement I'm guessing. Once it becomes active, I then need to know if the string in cell ("B2") on Sheet 1 = "Fighter" then I want to insert "some wording regarding the fighter here" in cell ("C14") on Sheet 2. IF it's not "Fighter"then is it "Mage"? If so then insert "some wording regarding the mage here".
This is short hand for example.
if cell C14 on Sheet 2 is active then
check cell B2 on Sheet1. If the text = "Fighter"? Then
insert "You are brave and use a sword" into cell C14 Sheet2
if it's not equal to Fighter then is it = "Mage"? Then
insert "You cast spells" in cell C14 sheet2
etc..
I need to know how to code this in VBA. I've spent hours searching and trying various code but can't seem to get it right. Thanks ahead of time for your help.

Try something like this:
'The way you check which cell is active is by using an
'Event like this one. This goes into the Sheet2 code module
'which you can get to by right clicking on the sheet's tab and
'selecting View Code.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim rng_Source As Excel.Range
Dim rng_Target As Excel.Range
On Error GoTo ErrorHandler
'Setting the cells that you're interested in as
'ranges will help minimise typo errors.
Set rng_Target = ThisWorkbook.Sheets("Sheet2").Range("C14")
Set rng_Source = ThisWorkbook.Sheets("Sheet1").Range("B2")
'Target is a range that specifies the new
'selection. Check its address against rng_Target
'which we defined above.
If Target.Address <> rng_Target.Address Then
Exit Sub
End If
'If you don't want case sensitivity, convert to upper case.
If UCase(rng_Source.Value) = "FIGHTER" Then
rng_Target.Value = "some wording regarding the fighter here"
ElseIf UCase(rng_Source.Value) = "MAGE" Then
rng_Target.Value = "You cast spells"
'You get the idea.
End If
ExitPoint:
On Error Resume Next
'Clean up
Set rng_Source = Nothing
Set rng_Target = Nothing
On Error GoTo 0
Exit Sub
ErrorHandler:
MsgBox "Error " & Err.Number & vbCrLf _
& Err.Description
Resume ExitPoint
End Sub
I do agree with the comments that you should always post the code that you've already tried (which you subsequently did), but this is a relatively trivial one and this just clears it out of the way and may be of use to somebody else as well in the future.

Try this ;)
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
On Error GoTo errH
Dim rng1 As Range
Set rng1 = ThisWorkbook.Worksheets(1).Range("B2")
If Not Intersect(Target, Me.Range("C14")) Is Nothing Then
Application.EnableEvents = False
If rng1.Value2 = "Mage" Then
Target.Value = "OMG This is MAGE!!! Run run run away!!!"
ElseIf rng1.Value2 = "Fighter" Then
Target.Value = "Fighter? :/ Was hoping for something better"
MsgBox "Fighter? :/ Was hoping for something better"
rng1.Value2 = "Mage"
Target.Value = "Mage. Now This is better ;)"
Else
Target.Value = "No, we haven't discussed it."
End If
Application.EnableEvents = True
End If
Exit Sub
errH:
MsgBox ("Error number: " & Err.Number & "Description: " & Err.Description)
Application.EnableEvents = True
End Sub

Related

VBA: Check dropdown list for updates and copy rows, if needed

I would like to create a macro, which is checking column "I:I" for any changes in a dropdown list. This dropdown list contains several entries. Once the entry "Declined" is entered, it should copy the whole row to another worksheet("Declined") and delete the row in the main worksheet("Data"). This would also mean, that this row will always be copied below a previous entry in the worksheet("Declined").
I never worked with Worksheet_Change nor with the Intersect function, so every help is appreciated.
Thanks in advance for your support.
I just found a solution, thanks for the ideas:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim shtDeal As String
Dim shtDecl As String
Dim lastrow As Integer
shtDeal = "Name 1"
shtDecl = "Name 2"
If Not Intersect(Target, Range("F1:F10000")) Is Nothing Then
On Error GoTo ErrHelp
If Target = "Declined by x" Or _
Target = "Declined by y" Or _
Target = "Declined by z" Then
lastrow = Worksheets(shtDecl).Range("A" & Rows.Count).End(xlUp).Row + 1
Target.EntireRow.Copy Destination:=Worksheets(shtDecl).Range("A" & lastrow)
MsgBox "Auf Grund Ihrer Auswahl wurde diese Datenreihe auf das Arbeitsblatt 'Declined' verschoben."
Target.EntireRow.Delete
End If
End If
Done:
Exit Sub
ErrHelp:
End Sub
Maybe this could help others with the same problem.

Find value in column and change cell to left with an if statment

This VBA script should take the value in the cell A37 and check if its in the C column of another worksheet. When the number is found the column to the left should be changed to 0. If it is already 0 then a message box will inform the user and if the number does not exist another message box will inform them of this.
This is the VBA I am using to accomplish this. However, every time I try to run it there is a "compile error: Next without For"
Update This issue now is that I need to activate the cell that the fcell is in before doing an Active.cell offset
Sub Cancelled()
Dim x As Long
Dim regRange As Range
Dim fcell As Range
x = ThisWorkbook.Sheets("Welcome").Range("A37").Value
Set regRange = ThisWorkbook.Sheets("Registration").Range("C:C")
For Each fcell In regRange.Cells
If fcell.Value = x Then
ActiveCell.Offset(0, -1).Select
If ActiveCell.Value = 1 Then
ActiveCell.Value = 0
MsgBox "Changed to zero"
Exit Sub
Else
MsgBox "That registration number is already cancelled"
Exit Sub
End If
End If
Next fcell
MsgBox "That number does not exist"
End Sub
Edit for new question: No need to use Select and ActiveCell
If fcell.Value = x Then
If fcell.Offset(0,-1).Value = 1 Then
fcell.Offset(0,-1).Value = 0
...
Edit 2: A further suggestion: You could also use the Range.Find method. This will throw an error if nothing is found so you have to catch that:
On Error Resume Next 'If an error occurs, continue with the next line
Set fcell = regRange.Find(x)
On Error GoTo 0 'disable the error handler
If fcell Is Nothing Then 'If Find failed
MsgBox "That number does not exist"
Else
'do your stuff with fcell here
End If
Hope this is not too late to answer your question:
Sub Cancelled()
Dim x As Long
Dim regRange As Range
Dim fcell As Range
x = ThisWorkbook.Sheets("Welcome").Range("A7").Value
Set regRange = ThisWorkbook.Sheets("Registration").Range("C:C")
For Each fcell In regRange.Cells
If fcell.Value = x Then
If fcell.Offset(0, -1).Value = 1 Then
fcell.Offset(0, -1).Value = 0
MsgBox "Changed to zero"
Else
MsgBox "That registration number is already cancelled"
End If
Exit Sub
End If
Next fcell
MsgBox "That number does not exist"
End Sub
Instead of
Set regRange = ThisWorkbook.Sheets("Registration").Range("C:C")
its better to get the last row in Column C and then set your range as:
Dim lastRow As Long
lastRow = ThisWorkbook.Sheets("Registration").Cells(Rows.Count, "C").End(xlUp).Row
Set regRange = ThisWorkbook.Sheets("Registration").Range("C1:C" & lastRow)

Determine if ActiveCell is in a specific table

I am trying to determine by VBA in Excel 2013 if the ActiveCell is not just in any table, but in a specific table.
Below is the code as is, but only detects ActiveCell being in any table. The commented out line is what I'm looking for, but obviously it doesn't work.
...
Set rng = Intersect(.EntireRow, ActiveCell.ListObject.DataBodyRange)
'Set rng = Intersect(.EntireRow, ActiveCell.ListObjects("myTable").DataBodyRange)
On Error GoTo 0
If rng Is Nothing Then
MsgBox "Please select the cell of a row within the consensus input table.", vbCritical, "Delete Evaluator"
Else
...
Any suggestions on the right syntax for this?
Thanks!
To test if ActiveCell is in the body of Table1:
Sub qwerty()
If Intersect(ActiveCell, ActiveSheet.ListObjects("Table1").DataBodyRange) Is Nothing Then
MsgBox "activecell not in Table1"
Else
MsgBox "activecell in Table1"
End If
End Sub
Generally, we're interested in work being performed within the DataBodyRange of a table and Excel provides us a shortcut for that area of a Table. For a table named "myTable", you directly access the DataBodyRange in code using [myTable].
Thus, for inclusive table location testing of the ActiveCell one could test as follows:
If Not Intersect(ActiveCell, [myTable]) Is Nothing Then
A more general solution, adaptable to other tables
Sub Demo()
Dim r As Range
Dim lo As ListObject
Set r = ActiveCell
Set lo = r.ListObject
If Not lo Is Nothing Then
Select Case lo.Name
Case "Table1"
If r.Row = lo.Range.Row Then
MsgBox "In Table1 Header"
Else
MsgBox "In Table1 Body"
End If
Case "SomeOtherTable"
'...
End Select
Else
MsgBox "Not in any table"
End If
End Sub
A Range object has a ListObject property that will return the table of the Range. All you have to do is to test if the cell is in any table:
If ActiveCell.ListObject Is Nothing Then
...
and see if it is in your specific table:
If ActiveCell.ListObject.Name = "MyTable" Then
...
and you're done!
Much cleaner than using Application.Intersect(...). chris neilsen's answer alludes to this as well.
I use the following line of code:
ActiveCell.ListObject.Name
or sub:
Sub IsActiveCellInTable()
'If active cell in table then get name'
Dim strTblName As String
'Disable error checking'
On Error Resume Next
strTblName = ActiveCell.ListObject.Name
'Reset error checking'
On Error GoTo 0
If strTblName <> "" Then
MsgBox "Cell (" & ActiveCell.Address & ") is included in: " & strTblName
Else
MsgBox "Cell (" & ActiveCell.Address & ") is not included in table."
End If
End Sub

Excel VBA, How to Loop a Msgbox when text in cell changes to "News" to answer of Msgbox in next column

I'm trying to create a MsgBox that automatically pops up with a prompt of "Yes or No" when a cell in a column changes from blank to "News", and to put the answer into the next column.
I will be continuing to add to rows over time so it has to automatically pop up when the cell changes from blank to "news" and input the answer into the newly added cell to the right.
I'm pretty sure I need the For each loop, but honestly I'm a little lost and get a mismatch error during debug at the If Intersect line.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim myRange As Range
Set myRange = Range("G2:G1000")
If Intersect(myRange, Target) Then
If Range("G2").Value = "News" Then Answer = MsgBox("Good?", vbYesNo)
Answer = ActiveCell.Offset(0, 1) = 1 'not sure if this is right, or is it Range.Offset?
Dim cel As Range
For Each cel In Range("G2:G1000")
If cel.Value = "News" Then Answer = MsgBox("Good?", vbYesNo)
Answer = ActiveCell.Offset(0, 1) = 1 'not sure if this is right, or is it Range.Offset?
Exit For
Next
End If
End Sub
Here you go:
Private Sub Worksheet_Change(ByVal Target As Range)
On Error Resume Next
If Target.Column = 7 Then
If Target.Count = 1 Then
If LCase$(Target) = "news" Then
Application.EnableEvents = False
Target(, 2) = Array("Yes", "No")(MsgBox("Good?", vbYesNo) - 6)
End If
End If
End If
Application.EnableEvents = True
End Sub

VBA Record date of row change in specific column

I'm trying to automatically update the "Updated" column of an excel spreadsheet when any cell of that specific row changes to today's date. I was able to do this by hard-coding where the "Updated" column header would be, however, it is now necessary to search for that column header as it may move.
The code I am trying to implement works but immediately gives me the error Automation error - The object invoked has disconnected from it's clients.
Any help would be appreciated. Here is the code I have currently:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("A:DX")) Is Nothing Then
Dim f As Range
Set f = ActiveSheet.Range("A1:DD1").Find("Updated", lookat:=xlWhole)
' f.Row = Range(Target).Row
If Not f Is Nothing Then
Range(Split(f.Address, "$")(1) & Target.Row).Value = Now
Else
MsgBox "'Updated' header not found!"
End If
End If
End Sub
You got into an endless loop.
Try this:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("A:DX")) Is Nothing Then
Dim f As Range
Set f = ActiveSheet.Range("A1:DD1").Find("Updated", lookat:=xlWhole)
' f.Row = Range(Target).Row
If f Is Nothing Then
MsgBox "'Updated' header not found!"
ElseIf Intersect(Target, f.EntireColumn) Is Nothing Then
Intersect(Target.EntireRow, f.EntireColumn).Value = Now
' Else
' MsgBox "We entered this function again because the row above updated the Updated column", vbInformation, "False alarm"
End If
End If
End Sub
To understand what happens,
Uncomment the else and MsgBox
Put a breakpoint on the MsgBox
When you hit it, press [ctrl]-L
In a case such as this, I run into far fewer problems when I simply loop through the available cells to find the column header. Using the .Find method also works, but is less "tunable" to my needs in a custom application.
Public Function FindColumn(header As String) As Long
Dim lastCol As Long
Dim headerCol As Long
Dim i As Long
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("VTO2 Labor")
lastCol = sh.Cells(1, sh.Columns.Count).End(xlToLeft).Column
headerCol = 0
For i = 1 To lastCol
If sh.Cells(1, i).Value = header Then
headerCol = i
End If
Next i
FindColumn = headerCol
End Function
It isn't clear on whether the Updated column header could be in row 1 or if it will always be in row 1, just not in the same location.
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("A:DX")) Is Nothing Then
On Error GoTo bm_SafeExit
'TURN OFF EVENTS IF YOU ARE GOING TO WRITE A VALUE INTO THE WORKSHEET!
Application.EnableEvents = False
Dim uCol As Long, f As Range
If Application.CountIf(Rows(1), "updated") Then
uCol = Application.Match("updated", Rows(1), 0)
For Each f In Intersect(Target, Range("A:DX"))
If f.Row > 1 Then _
Cells(f.Row, uCol) = Now
Next f
Else
MsgBox "'Updated' header not found!"
End If
End If
bm_SafeExit:
Application.EnableEvents = True
End Sub
That should survive multiple updates (e.g. when pasting values). The problem I see is that is the Updated column is being shifted around, presumably through inserting columns or the like, then the change routine is going to run.