问题
How can I make a formula such that when update a value in Completed
for a particular value of ID
, it automatically gets filled in all cells of Completed
for that particular ID
? And, when I remove the value from one cell in Completed
, it automatically gets removed from all cells in Completed
that correspond to that value in ID
.
For eg. in the data below, I'd like the three blank cells automatically filled with 4
, 6
and 5
respectively.
Role ID Completed
A 1 3
A 2 4
A 5 3
A 8 6
B 2
B 8
B 10 5
C 10
C 15 2
回答1:
A Worksheet Change Solution
What does it do?
- When a value in
Target Column
is changed to a new value, the value in the same row ofSource Column
is being looked up in the sameSource Column
. With each found value, the value in this (found) row inTarget Column
is changed to the mentioned new value.
Usage
- To run the following successfully, both codes have to be copied to one workbook appropriately: the first to a sheet module and the second to a standard module.
- There is nothing to run here, everything runs automatically.
- The only thing that could be changed are the last three values in the short code.
The Two Codes
1. Sheet Module
The following code is to be copied into a sheet module e.g. Sheet1
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Call updateColumn(Me, Target, "B", "C", 2)
End Sub
- Instead of
"B"
and"C"
you can use the numbers2
and3
. - You can change the values as you see fit.
- You can copy it into multiple sheet modules and change the parameters
for
SourceColumn
,TargetColumn
andFirstRow
. Me
andTarget
stay the same.
2. Standard Module
The following code is to be copied into a standard module e.g. Module1
Option Explicit
Sub updateColumn(Sheet As Worksheet, _
TargetCell As Range, _
ByVal SourceColumn As Variant, _
ByVal TargetColumn As Variant, _
Optional ByVal FirstRow As Long = 4)
If TargetCell.Cells.CountLarge > 1 Then GoTo MoreThanOneCell
Dim rng As Range: Set rng = Sheet.Columns(TargetColumn)
If Intersect(TargetCell, rng) Is Nothing Then GoTo NotInTargetColumn
Set rng = rng.Find("*", , xlValues, , , xlPrevious)
If rng Is Nothing Then GoTo EmptyTargetColumn
If rng.Row < FirstRow Then GoTo FirstRowBelowLastRow
Dim LastRow As Long: LastRow = rng.Row
Set rng = Sheet.Columns(SourceColumn).Find("*", , xlValues, , , xlPrevious)
If Not rng Is Nothing Then
If rng.Row > LastRow Then LastRow = rng.Row
Else ' Empty Source Column. Don't care.
End If
If FirstRow = LastRow Then GoTo OnlyOneCell
Set rng = Sheet.Range(Sheet.Cells(FirstRow, TargetColumn), _
Sheet.Cells(LastRow, TargetColumn))
If Intersect(TargetCell, rng) Is Nothing Then GoTo NotInTargetRange
Dim ColOff As Long: ColOff = Sheet.Columns(SourceColumn).Column - rng.Column
Dim Target As Variant: Target = rng.Value
Dim Source As Variant: Source = rng.Offset(, ColOff).Value
Dim i As Long, tVal As Variant, sVal As Variant
tVal = TargetCell.Value
sVal = TargetCell.Offset(, ColOff).Value
Debug.Print TargetCell.Address, tVal, _
TargetCell.Offset(, ColOff).Address, sVal
On Error GoTo CleanExit
For i = 1 To UBound(Source)
If Source(i, 1) = sVal Then
Target(i, 1) = tVal
End If
Next i
'Application.EnableEvents = False
rng.Value = Target
CleanExit:
' Application.EnableEvents = True
LastExit:
Exit Sub
MoreThanOneCell:
'Debug.Print "More than one cell."
GoTo LastExit
NotInTargetColumn:
'Debug.Print "Not in Target Column."
GoTo LastExit
EmptyTargetColumn:
'Debug.Print "Empty Target Column."
GoTo LastExit
FirstRowBelowLastRow:
'Debug.Print "First row below last row."
GoTo LastExit
OnlyOneCell:
'Debug.Print "Only one cell."
GoTo LastExit
NotInTargetRange:
'Debug.Print "Not in Target Range."
GoTo LastExit
End Sub
You can uncomment the Debug.Print
lines to monitor the behavior of the Change event
in the Immediate window
(CTRL + G) in VBE
(Alt+F11).
回答2:
Here is one approach.
Your setup is in column A, B & C
Prepare a LOOKUP table in column E & F as shown below.
ID Completed 1 3 2 4 5 3 8 6 10 5 15 2
Then in column C (cell C2), you can use a simple formula like below and copy down as much needed.
=IFERROR(VLOOKUP(B2,$E:$F,2,0),"")
So, as soon as you update status in column E & F, it will get updated in the formula column.
来源:https://stackoverflow.com/questions/62547297/excel-formula-to-fill-a-column-based-on-value-in-another-column