So I have 2 sheets in my excel book, there are columns with dates as shown here http://prntscr.com/j4931e (this is in sheet 2) for each type of attendance (eg present or absent) I type into a cell I want it to update that same cell that is part of a column B in sheet 1 http://prntscr.com/j494s2. I hope you understand what I mean. Thanks.
Private Sub Worksheet_Change(ByVal Target As Range)
Worksheets(2).Range(Target.Address) = Target
End Sub
Try this. There are two options as not 100% sure what you're after. The code should go in the sheet 2 module. You might want to restrict the range triggering it, e.g. columns B-F only?
Private Sub Worksheet_Change(ByVal Target As Range)
If target.column>1 then
Worksheets(1).Range("B" & target.row).Value = Target.Value
End if
End Sub
Related
I have simple code that clears out the "State" cell whenever the "Payroll Country" cell changes. For example if the user selects "USA" in A6 and then selects "Arizona" in X6, then maybe later for some reason they change their mind and want to pick "CAN" for the country, the state cell will clear out.
But if someone in the future decides to insert a column before the X column, it will obviously move my State column over. Is there a way to make the VBA smarter (or make me smarter) so that the function will be tied to the "State" column rather than the specific "X" column?
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.CountLarge > 1 Then Exit Sub 'CountLarge handles larger ranges...
'check Target column and row...
If Target.Column = 1 And Target.Row >= 6 Then
With Target.EntireRow
'State column
.Columns("X").Value = ""
End With
End If
End Sub
You can use a named range, or you can use .Find to determine where your State column currently is. Here is an example using .Find
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.CountLarge > 1 Then Exit Sub 'CountLarge handles larger ranges...
'check Target column and row...
If Target.Column = 1 And Target.Row >= 6 Then
Dim StateCol As Long
StateCol = Me.Range("1:5").Find("State", LookIn:=xlValues, LookAt:=xlPart).Column
With Target.EntireRow
'State column
.Columns(StateCol).Value = ""
End With
End If
End Sub
If you were to use a named range instead, you can define StateCol using StateCol = Me.Range("NamedRange").Column, it would be a little bit faster, since it doesn't need to search the row each time the user changes a value.
Side Note: The search range for .Find is Rows 1 to 5, but you may want to restrict or expand that range based on how you expect the data to move.
I (always) define an enum for the columns, like this
Public enum col_TableXXX 'adjust to your needs
col_ID = 1
col_PayrollCountry
col_State
end enum
enums are numbered automatically - so col_PayrollCountry equals to 2, col_State equals to 3 etc.
In case there are new columns or the order changes you only have to move the enums around or add a new enum.
(You can avoid code typing by transpose-pasting the column titels on an excel sheet and then create the code via formulas)
You can then use the enums like this:
If target.column = col_PayrollCountry then
target.entireRow.columns(col_State) = vbnullstring
End If
This is also much more "readable" than columns("X")
Culprit of this solution: you have to know that the columns changed. It is not an automatism that is based on the columns name.
There is another solution to your question (I was influenced by the short discussion with ACCtionMan regarding the enum-stuff):
If you can insert a table (insert > table) then you can use the listobject. Among a lot of other advantages you can reference the column by its name.
I assume that the table is named "tblData"
Private Sub Worksheet_Change(ByVal Target As Range)
Dim lo As ListObject
Set lo = Me.ListObjects("tblData")
If Not Intersect(Target, lo.ListColumns("Payroll Country").DataBodyRange) Is Nothing Then
'changed cell is in Payroll country column then
'take the intersection of the targets row and the State column to change the value
Intersect(Target.EntireRow, lo.ListColumns("State").DataBodyRange) = vbNullString
End If
End Sub
But I would prefer the following solution - because I like to have business logic in the event handlers.
If a collegue of you (or even you in 6 months) looks into the change-event code he/she will immediately understand what is happening here - without reading how it is done.
Option Explicit
Private m_loData As ListObject
Private Sub Worksheet_Change(ByVal target As Range)
'if target cells is not within loData we don't need to check the entry
If Intersect(target, loData.DataBodyRange) Is Nothing Then Exit Sub
If ColumnHeaderOfRange(target) = "Payroll Country" Then
resetStateColumnToEmptyValue target
End If
End Sub
Private Sub resetStateColumnToEmptyValue(c As Range)
Intersect(c.EntireRow, loData.ListColumns("State").DataBodyRange) = vbNullString
End Sub
'this could go in a general module - then add listobject as parameter
Private Function ColumnHeaderOfRange(c As Range) As String
On Error Resume Next ' in case c is outside of listobject
ColumnHeaderOfRange = Intersect(c.Cells(1, 1).EntireColumn, loData.HeaderRowRange)
On Error GoTo 0
End Function
'this could be public then you can access the table from outside the worksheet module
Private Function loData() As ListObject
If m_loData Is Nothing Then
Set m_loData = Me.ListObjects("tblData")
End If
Set loData = m_loData
End Function
I Have a long list of hyperlink formulas in column B. Below is an example of the formula inside a cell. What i want to achieve is when i click a hyperlink in any rows of the whole column B, It will run also a separate single VBA Macro.
=HYPERLINK("#SHEET1!D"&ROW(D2066),D2066)
Thank you.
There is a Private Sub Worksheet_FollowHyperlink(ByVal Target As Hyperlink)
event but I don't think it will work with a hyperlink formula. Possibly a selection_change event would work in this case.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Count > 1 Then Exit Sub
If Target.Column = 2 Then
If Left(Target.Formula, 10) = "=HYPERLINK" Then
MsgBox "My Code here"
End If
End If
End Sub
This would go in the worksheet module.
I am looking for a script that will pull data from last edited cell into Cell B1 of active sheet and also look up data from cell in column A and then display it in cell A1.
So far I've got this to pull last edited cell into B1 and it works fine but I cannot figure out how to then go back from that point to row A and display the other info.
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Target.Worksheet.Range("F13:W9910")) Is Nothing Then
ActiveSheet.Range("B1").Value = Target.Value
End If
End Sub
In the attached picture if I add any numbers in section called trays completed (in red) to display in B1 and then look up number in Sap column and display the number in cell A1
Something like this:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Me.Range("F13:W9910")) Is Nothing Then
Me.Range("B1").Value = Target.Value
Me.Range("A1").Value = Target.Entirerow.Cells(1).Value
End If
End Sub
Note when in a sheet code module you can refer to the worksheet using Me
Also be aware that Target might be >1 cell and your code might need to handle that.
This will take the corresponding value in A and place it in A1. I only added one line of code to yours.
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Target.Worksheet.Range("F13:W9910")) Is Nothing
Then
ActiveSheet.Range("B1").Value = Target.Value
ActiveSheet.Range("A1").Value = ActiveSheet.Range("A" & Target.Row)
End If
End Sub
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
Any idea how to force with VBA the column "B" of sheet called "extra" to have format of percentage with 2 decimal places? Thanks a lot.
In the code sheet for "extra" , place this code.
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Columns("B"), Target) Is Nothing Then
Intersect(Columns("B"), Target).NumberFormat = "0.00%"
End If
End Sub