Why can't I change the active Excel worksheet using VBA - excel

I have a Function that is attempting to change the current active sheet ("Sheet1") to (Sheet2) and then assign a value to a cell in Sheet2.
However the ActiveSheet.name doesn't change and the assignment fails. see the code snippet. The function is called from sheet1.
Dim oldwksheet as String
oldwksheet = ActiveSheet.Name 'value is Sheet1
Sheets("Sheet2").Activate
Sheets("Sheet2").Select
oldwksheet = ActiveSheet.Name 'value still is Sheet1"
Sheets("Sheet2").Range("F2") = Now() 'this fails.
end function
Why? What am I doing wrong.

You need a sub and not a function.
A function can only return a value to the cell in which it resides. It can't select or activate worksheets or deposit values in arbitrary cells.

I couldn't say why, but you could use a Function
assuming your function's named after "MyFunction" then place in relevant worksheet code pane the following code:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Count = 1 Then If Left(Target.Formula, 12) = "=MyFunction(" Then Sheets("Sheet2").Range("F2") = Now()
End Sub
this way, whenever you type =MyFunction() in any cell of the relevant worksheet, the current date and time is being placed in cell F2 of Sheet2

Related

Worksheet_Change Target.Address on specific sheet

I am trying to automatically hide/unhide rows on sheet2 when cell c9 changes on sheet1.
I have my Hide/Unhide Rows toggle all set up.
My worksheet change works when the target cell is on sheet2 but does not when I attempt to set the target cell to sheet1 (As is shown in my code below).
Module1 Code:
Sub Hide_Rows_Toggle()
Dim r As Range
For Each r In Columns(2).Cells
If r.Value = "X" Then
r.EntireRow.Hidden = True
End If
Next r
End Sub
Sheet2 Code:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = Worksheets("Sheet1").Range("$C$9") Then
Call Hide_Rows_Toggle
End If
End Sub
In ThisWorkbook:
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
If Sh.Name = "Sheet1" And Target.Address = "$C$9" Then
Call Hide_Rows_Toggle
End If
End Sub
Now I'm home, and have tested the following;
You haven't qualified a Workbook or Worksheet object in your Hide_Rows_Toggle() sub. As such it is implicitly referencing the ActiveWorksheet
Per Worksheet.Columns documentation:
Using the Columns property without an object qualifier is equivalent to using ActiveSheet.Columns. If the active document isn't a worksheet, the Columns property fails.
The Worksheet_Change event is Worksheet specific, meaning, the event is triggered on each worksheet independantly - If you make a change on Sheet1 the event won't trigger on Sheet2 etc.
You should do the following:
Move your Worksheet_Change event to the module for Sheet1, where the change is happening.
Qualify your target worksheet (at least) in your Hide_Rows_Toggle Subroutine like so:
Qualify your range in your sub like so:
Sub Hide_Rows_Toggle()
Dim r As Range
For Each r In ThisWorkbook.Sheets("Sheet2").Columns(2).Cells
If r.Value = "X" Then
r.EntireRow.Hidden = True
End If
Next r
End Sub
This ensures the rows will only be hidden on Sheet2, otherwise it will always target the ActiveSheet which has to be the sheet you made the change in.
Lastly, It's a little unclear exactly what you are attempting to evaluate in your Worksheet_Change event.
Currently you are looking to see if the Target.Address is equal to the Value in Cell $C$9 on Sheet1. This is because the default member for the Range object is Value. So it will only return true if you are setting a cell reference in $C$9 to dictate which cell triggers the sub.
If you are intending to run Hide_Rows_Toggle when the value in $C$9 is changed, you will need to add the .Address property to your range - If Target.Address = Worksheets("Sheet1").Range("$C$9").Address - or - simply change it to a string to match the address like If Target.Address = "$C$9" Then.

Excel VBA Worksheet_Change refer to cells in another sheet with named range

I would like to use a user's input from a dropdown (yes/no) in sheet1 to hide/unhide rows in sheet2. A formula in sheet2 refers to the input in sheet1.
I also think that a named range (scope: workbook) on its own can only refer to the same sheet? Code below does not work but illustrates. Could not make other references work to named ranges with ThisWorkbook or similar.
Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("screener")) Is Nothing Then
With Sheets("Sheet2")
.Range("calc1.1").Rows.EntireRow.Hidden = (.Range("calc1.1").Cells(1, 1).Value = "No")
.Range("calc1.2").Rows.EntireRow.Hidden = (.Range("calc1.2").Cells(1, 1).Value = "No")
End With
End If
End Sub

Hide sheet if cell on anther sheet meets conditions

I am attempting to write a macro that will hide a sheet once the reference cell on a "Home" sheet is highlighted Green.
Attempted If Statement:
Dim Archive As String
Archive = ActiveSheet.Name
If Sheets("Home").Range("$A:$1).Value = Archive And Sheets("Home") _
.Range("$A:$1).Interior.Color = vbGreen Then
ActiveSheet.Hide
End If
The sheet and cell I am attempting to reference have the same name. The cell is Hyperlinked to the sheet. Both the Sheet and the cell with hyperlink are created by another macro.
I cannot identify a specific cell in the If statement because the cell will be different depending on the sheet I want to hide.
Hope this helps you out,
You can create a module and paste the following method over there.
Sub checkRef(ByVal shtName As String)
Dim archive As String
archive = shtName
If Sheets("Home").Range("A1").Value = archive And Sheets("Home").Range("A1").Interior.Color = vbGreen Then
ActiveSheet.Visible = False
Else
MsgBox "Activesheet not referenced to hide"
End If
End Sub
You can edit the above as per your need.
Then on the Worksheet_Activate event of the worksheet you want to hide call the above method as given below.
Private Sub Worksheet_Activate()
checkRef (ActiveSheet.Name)
End Sub
Then you can check the result by changing the value of Range("A1") of Home sheet to Name of the sheet you want to hide and also change the interior color to vbGreen.
You must be able to hide your sheet.

Pop up form depending on cell value

I would like a pop up form named 'Question' to show up when a value in cell A9 in worksheet called 'Calculator' matches one of the values in Column O in Worksheet 'Data'.Values. In cell A9 are results of formula.
This code works but when I have other Excel workbooks open, it gives me 'Subscript out of range error'. I would like it to apply to this one particular workbook and not affect the other workbooks I have open.
Private Sub Worksheet_Calculate()
If IsError(Application.Match(Range("A9").Value, Sheets("Data").Columns("O"), 0)) Then Exit Sub
If Application.Match(Range("A9").Value, Sheets("Data").Columns("O"), 0) Then
Question.Show
End If
End Sub
You could make the code reference only the workbook that the code is stored in:
Private Sub Worksheet_Calculate()
With ThisWorkbook
If IsError(Application.Match(.ActiveSheet.Range("A9").Value, .Sheets("Data").Columns("O"), 0)) Then Exit Sub
If Application.Match(.ActiveSheet.Range("A9").Value, .Sheets("Data").Columns("O"), 0) Then
Question.Show
End If
End With
End Sub
...It would be good to replace ActiveSheet with a specific sheet reference.

Mirroring column in one excel sheet to other multiple excel sheets with automatic updating

I have an excel workbook that contains multiple sheets within it. For the sake of this question, the sheets are named Sheet1, Sheet2, Sheet3, and so on. I would like to have Column A from sheet1 be replicated throughout the rest of the sheets and as new cells are added to column A in sheet1, they would automatically be entered into the other sheets within the workbook. I would prefer not to have a set "ending range; ie: A100000" for this. For example, if I enter First in cell A1 of Sheet1, the word "First" should now also appear in cell A1 of Sheet2. I have used the following code, and it does not seem to work. Any help would be greatly appreciated.
Private Sub Worksheet_Change(ByVal Target As Range)
Call UpdateFromSheet1
End Sub
Sub UpdateFromSheet1(ByVal Sh As Object, ByVal Target As Range)
If Sh.CodeName = "Sheet1" Then
If Not Intersect(Target(1, 1), Range("A1:A1000")) Is Nothing Then
Sh.Range("A1:A1000").Copy Sheet2.Range("A1")
End If
End If
End Sub
UPDATE
For a clean looking Non-VBA solution, you can use the formula references that others have mentioned, but enter it like this.
In Sheet2 cell A1 = If(Sheet1!A1="","",Sheet1!A1) That way you can fill down on the whole of column A and not have "0" pop-up if Sheet1 has a rows without data.
I think you have the general idea, but I suspect you may not have your code in the right place.
For the VBA solution:
First, you don't need to call the sub from Worksheet_Change event (unless of course you want to use this sub for other reasons and pass variables to it. Second, if you place this code in the worksheet object in the VBE of the "Sheet1" it will do as you wish:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Columns("A")) Is Nothing Then
Dim wks As Worksheet
For Each wks In Sheets(Array("Sheet2", "Sheet3"))
Target.EntireColumn.Copy wks.Columns(1)
Next
End If
End Sub
This is a very basic use for excel. You can set cells equal to each other. You in no way would need a VBA macro for this.
If you put this in cell "A1" on Sheet2 and Sheet3:
=Sheet1!A1
Then when you type something into A1, it will be "mirrored" on sheets 2 and 3. You can autofill this down to all the cells in column A on sheets 2 and 3.
Are you familiar with the term autofill?
If you don't understand anything I just said and you want to just run a macro then run this and start typing away:
Sub MacroBasicQuestion()
Dim wbk As Workbook
Set wbk = ThisWorkbook
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim ws3 As Worksheet
Set ws1 = wbk.Sheets(1)
Set ws2 = wbk.Sheets(2)
Set ws3 = wbk.Sheets(3)
Dim cell As Range
Set cell = ws2.Range("A1:A1")
ws2.Select
cell.FormulaR1C1 = "=Sheet1!RC"
cell.Select
Selection.AutoFill Destination:=Range("A:A"), Type:=xlFillDefault
Set cell = ws3.Range("A1:A1")
ws3.Select
cell.FormulaR1C1 = "=Sheet1!RC"
cell.Select
Selection.AutoFill Destination:=Range("A:A"), Type:=xlFillDefault
End Sub
Good Luck.

Resources