Reputation: 161
I've written some VBA code to the following:
[Cost1] [Cost2] [Cost3] [TotalCost] [Margin%] [Margin$] [Price]
I was not able to add protected formulas to the Price column because the user may want to change that value, thus the formula would be erased. So I decided to code VBA which works perfectly calculation wise. However, I've lost some of the most valued features of excel: e.g. If a want to copy the value of one price to several other rows, it just triggers the recalculation for the firs row where it is copied but not for the others. I'v also lost the ability of UNDO after exiting the cell.
To detect that a cell was modified I'm using the following:
Private Sub Worksheet_Change(ByVal Target As Range)
If (Target.Column = Range("Price").Column)
Call calcMargins(Target.Row)
End If
If (Target.Column = Range("Cost1").Column) or _
If (Target.Column = Range("Cost2").Column) or _
If (Target.Column = Range("Cost3").Column) or
Call calcMargins(Target.Row)
Call calcPrice(Target.Row)
End If
Upvotes: 1
Views: 20548
Reputation: 149287
Try this
I have deliberately broken down the code into several If statements and duplicate codes for understanding perspective. For example
Cells(Target.Row, 4) = "Some Calculation" '<~~ TotalCost Changes
Cells(Target.Row, 6) = "Some Calculation" '<~~ Margin$ Changes
Cells(Target.Row, 7) = "Some Calculation" '<~~ Price Changes
Please put them in a common procedure.
Also note the use of Error Handling
and Application.EnableEvents
. These two are a MUST when working with Worksheet_Change
. Application.EnableEvents = False
ensures that the code doesn't get into a possible infinite loop in case there are recursive actions. Error Handling
not only handles the error but also stops the code from breaking up by showing you an error message and then resetting the Application.EnableEvents
to True
and finally exiting the code gracefully.
Code
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo Whoa
Application.EnableEvents = False
If Not Intersect(Target, Columns(1)) Is Nothing Then '<~~ When Cost 1 Changes
Cells(Target.Row, 4) = "Some Calculation" '<~~ TotalCost Changes
Cells(Target.Row, 6) = "Some Calculation" '<~~ Margin$ Changes
Cells(Target.Row, 7) = "Some Calculation" '<~~ Price Changes
ElseIf Not Intersect(Target, Columns(2)) Is Nothing Then '<~~ When Cost 2 Changes
Cells(Target.Row, 4) = "Some Calculation" '<~~ TotalCost Changes
Cells(Target.Row, 6) = "Some Calculation" '<~~ Margin$ Changes
Cells(Target.Row, 7) = "Some Calculation" '<~~ Price Changes
ElseIf Not Intersect(Target, Columns(3)) Is Nothing Then '<~~ When Cost 3 Changes
Cells(Target.Row, 4) = "Some Calculation" '<~~ TotalCost Changes
Cells(Target.Row, 6) = "Some Calculation" '<~~ Margin$ Changes
Cells(Target.Row, 7) = "Some Calculation" '<~~ Price Changes
ElseIf Not Intersect(Target, Columns(7)) Is Nothing Then '<~~ When Cost Price Changes
Cells(Target.Row, 5) = "Some Calculation" '<~~ Margin% Changes
Cells(Target.Row, 6) = "Some Calculation" '<~~ Margin$ Changes
End If
LetsContinue:
Application.EnableEvents = True
Exit Sub
Whoa:
MsgBox Err.Description
Resume LetsContinue
End Sub
I am assuming that Row 1 is protected and the user is not gonna change that. If the Header row is unprotected then you will have check for the row number withing the If
Statements to exclude Row 1
FOLLOWUP
I select one of the costs (first of Cost1), do a Ctrl+C, select all cells under Cost 3 and do Crl+V, it copies the values but it only re-calculates the TotalCost for the firs cell of the selection. Than you for your help!!! – Ronald Valdivia 24 mins ago
Ah I see what you are trying :)
Use this code
Private Sub Worksheet_Change(ByVal Target As Range)
Dim cl As Range
On Error GoTo Whoa
Application.EnableEvents = False
If Not Intersect(Target, Columns(1)) Is Nothing Then
For Each cl In Target
Cells(cl.Row, 4) = Cells(cl.Row, 1) + Cells(cl.Row, 2) + Cells(cl.Row, 3)
Next
ElseIf Not Intersect(Target, Columns(2)) Is Nothing Then
For Each cl In Target
Cells(cl.Row, 4) = Cells(cl.Row, 1) + Cells(cl.Row, 2) + Cells(cl.Row, 3)
Next
ElseIf Not Intersect(Target, Columns(3)) Is Nothing Then
For Each cl In Target
Cells(cl.Row, 4) = Cells(cl.Row, 1) + Cells(cl.Row, 2) + Cells(cl.Row, 3)
Next
End If
LetsContinue:
Application.EnableEvents = True
Exit Sub
Whoa:
MsgBox Err.Description
Resume LetsContinue
End Sub
Upvotes: 1