How to edit info in cells displayed via macro code in Excel? - excel

I have a macro so that when you highlight a row on sheet1, the macro takes all the info from this row and displays this by itself on sheet2. If you highlight a different row on sheet1, the info on sheet2 is changes to show the info from that row.
My problem is that if I change the info displayed on sheet2, it doesn't change the info on sheet1. Is there a way I could add this functionality?
I have the following code at the moment:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim myList
If Target.Address <> Target.EntireRow.Address Then Exit Sub
If Target.Rows.Count > 1 Then Exit Sub
myList = [{"B1","B2","B3","B4","B5","B6","B7","B8","B9","B10","B11","B12","B13","B14","B15"}] '<- adjust to your need
With Target.EntireRow
For i = 1 To UBound(myList)
Sheets("sheet2").Range(myList(i)).Value = .Cells(i).Value
Next
End With
End Sub
Any Help would be awesome! :)

After copying your sheet1 row to sheet2 you could also record the original row # that the values came from. Then you can add an additional macro that would compare the sheet2 values with the values in sheet1 - any changes could then be migrated over.
A possible basic flow:
copy sheet1 row to sheet2 (current macro)
copy sheet1 row # to sheet2 (ie one row down)
make changes on sheet2
copy sheet2 row to sheet1 row (use row # saved on sheet2) -> this assumes that no changes will be made to sheet1.

You are currently using a Worksheet_SelectionChange event macro to recognize when a full single row has been selected. You need a Worksheet_Change event macro for Sheet2 to recognize when values in the B1:B15 range have been changed and pass the changes back to Sheet1.
Because the Worksheet_Change is triggered on a change in values, you will need to disable the Application.EnableEvents property so that it is not triggered when you write the values from Sheet1's Worksheet_SelectionChange sub.
You are going to require a couple of public variables. One to remember the position that changes should be returned to and another to locate the target cells on Sheet2. These can only be made public in a module code sheet.
Book1 - Module1 (Code)
Option Explicit
Public Const sRNG As String = "B1:B15"
Public rRNG As Range
I've made a couple of small modifications to your original Worksheet_SelectionChange and added the disabling of event handling.
Book1 - Sheet1 (Code)
Option Explicit
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Cells.Count = Columns.Count And Target.Rows.Count = 1 And _
CBool(Application.CountA(Target)) Then '<~~ one complete non-blank row
On Error GoTo bm_Safe_Exit
Application.EnableEvents = False
With Sheet2.Range(sRNG)
Set rRNG = Target.Cells(1, 1).Resize(.Columns.Count, .Rows.Count)
.Cells = Application.Transpose(rRNG.Value)
End With
End If
bm_Safe_Exit:
Application.EnableEvents = True
End Sub
The Worksheet .CodeName property was used to identify Sheet2 since this does not change if the worksheet is conventionally renamed.
It is a little unclear on how you were planning to identify the row to return the values to once they were changed. I've used a public range-type variable declared in Module1 to record the last location that values were transferred from Sheet1 to Sheet2. Changes on Sheet2 will return them to the last recorded location.
Book1 - Sheet2 (Code)
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range(sRNG)) Is Nothing Then
Debug.Print rRNG.Address(0, 0, external:=True)
On Error GoTo bm_Safe_Exit
Application.EnableEvents = False
rRNG = Application.Transpose(Range(sRNG).Value)
End If
bm_Safe_Exit:
Application.EnableEvents = True
End Sub
Note that the 'remembered' location is in memory only. Closing and reopening the workbook effectively 'zeroes' it. Do not make changes on Sheet2 unless you have freshly loaded values from Sheet1.

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.

Multiple Worksheet Change Events: Multiple Dropdowns

I am trying to create a workbook where if I change a dropdown on 1 sheet, it automatically updates that same dropdown on a second sheet. These dropdowns will represent different scenarios and my purpose in creating this is to allow the end-user the ability to change the scenario dropdown from any sheet, rather than just one.
I used this reference to create a VBA for changing 1 dropdown -Original VBA code referenced - and it worked correctly (See example workbook to download). However, now I want to add the other 2 dropdowns so that if any changes are made to them it updates accordingly.
I'm also open to other solutions if you know of something better.
Sorry if this question was elementary -- I am new to VBA.
Using the example from the Original VBA code referenced, if you were looking to apply this rule to 2 sets of drop downs (4 total), instead of 1 set - you would duplicate the snippet from "If Not Intersect(..." to "..End if" and then update the reference to the 2nd set of cells.
EXAMPLE:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Dim targetSheet As Worksheet
If Not Intersect(Target, Range("A1")) Is Nothing Then ' watch only cell A1
Set targetSheet = ActiveWorkbook.Worksheets("Sheet2") ' define the sheet to copy to
On Error Resume Next
Application.EnableEvents = False
targetSheet.Range("B1") = Target.Value ' copy to cell B1 on the target sheet
Application.EnableEvents = True
End If
If Not Intersect(Target, Range("A2")) Is Nothing Then ' watch only cell A1
Set targetSheet = ActiveWorkbook.Worksheets("Sheet2") ' define the sheet to copy to
On Error Resume Next
Application.EnableEvents = False
targetSheet.Range("B2") = Target.Value ' copy to cell B1 on the target sheet
Application.EnableEvents = True
End If
End Sub
You would then repeat for the other worksheet.

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

Remove Validation Rules Row by Row from Sheet Based on Column G Value

Hy Experts, I am using an excel sheet that has multiple columns. Every column has validation rules. I want to remove these validation rules upon selecting any row in the entire sheet. When I select the row then I will put the value in G from drop down menu. on the basis of column G value the entire row validation rules should be cleared. The sheet looks like this.
enter image description here
The code that I am using is as under.
Sub RemoveDV()
Dim ws As Worksheet
For Each ws In Worksheets
ws.Cells.Validation.Delete
Next ws
MsgBox ("All Validation Rules has been removed successfully")
End Sub
it working fine but it delete the entire worksheet. But I want to delete the validation only row that I am working on.
Thanks
Try this:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Debug.Print Target.Address
If Not Intersect(Target, Range("G:G")) Is Nothing And Target.Count = 1 Then
If Target.Value = "The value that will trigger the validation clearing" Then
Target.EntireRow.Validation.Delete
End If
End If
End Sub
This will trigger anytime you change a value in column "G" of the specified sheet and if the new value = the text you want.
EDIT:
Let say you store your values (values that will trigger the script) in a range on the same page you can adapt following code to your needs:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Dim Arr: Arr = Application.Transpose(Range("$P$1:$P$12").Value) 'Values stored in "P1:P12"
If Not Intersect(Target, Range("G:G")) Is Nothing And Target.Count = 1 Then
If UBound(Filter(Arr, Target.Value)) > -1 Then
Target.EntireRow.Validation.Delete
End If
End If
End Sub

Select first empty cell in specific column when switching between worksheets

I have a single workbook with multiple sheets. Sheet 1 uses cell A1 as a search box to find a specific sheet in the book. The sheets after Sheet 1 are named like this, SO123456 with different numbers following the SO. I have the following code on sheet 1 to open the corresponding sheet from the value typed into A1 of Sheet 1:
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Range("A1"), Target) Is Nothing Then Exit Sub
Sheets(Target.Value).Activate
End Sub
When the corresponding sheet is opened, I want to open it to the next empty cell in column A. I have some code on the SOxxxxxx sheets that populates time in Column C when my data is entered in Column A. Here is that code:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Application.Intersect(Target, Columns("A:A")) Is Nothing Then
Target.Offset(0, 2).Value = Now
End If
End Sub
I'm not sure how to make sure the first empty cell in Column A is selected or where the code goes; sheet being opened or where the call is to open the sheet. I tried entering the following code below the Worksheet_Change block with no luck:
Range("A" & Rows.Count).End(xlup).Offset(1).Row
Cells(Rows.Count,1).End(xlup).Offset(1).Row
UsedRange.Rows.Count
I know next to nothing about VBA if you haven't already noticed.
Try this
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address <> "A$1” Then Exit Sub
With WorkSheets(Target.Value)
.Activate
.Cells(.Rows.Count,1).End(xlup).Offset(1).Select
End With
End Sub
This should get you to the first empty cell in Column A
rowEmpty = Range("A" & 10000).End(xlup).Row +1
You can replace the number 10000 with a sufficiently large number that ensures there will be no data there. There are alternatives to that, but I think this one is easier to begin with.
With this code, typing a sheet name in cell A1 from sheet1 will activate the sheet you type, and the active cell will be the first one in blank in column A.
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Range("A1"), Target) Is Nothing Then Exit Sub
Sheets(Target.Value).Activate
ActiveSheet.Cells(Sheets(Target.Value).Range("A1").End(xlDown).Row + 1, 1).Select
End Sub

Resources