Excel formula to fill a column based on value in another column

房东的猫 提交于 2021-01-28 18:20:35

问题


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 of Source Column is being looked up in the same Source Column. With each found value, the value in this (found) row in Target 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 numbers 2 and 3.
  • You can change the values as you see fit.
  • You can copy it into multiple sheet modules and change the parameters for SourceColumn, TargetColumn and FirstRow.
  • Me and Target 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!