简体   繁体   中英

How to input a value to a cell based on a range of other cells

To: Stack Overflow

I have read the solution provided to this stackoverflow.com/questions/41416948/ms-excel-copy-contents-of-clicked-active-cell-to-another-cell.

My query is similar but it involves more than 2 separate groups of clicked choices in the same worksheet.

For example, in my worksheet ("FillData"), a value will be input to Cell E7 based on the range E10:E101 , the other value will be input to Cell S7 based on S10:S101 respectively.

I have tried to modify the code by trial and error- the code actually works but i feel that what i have modified is not elegant because there are some repetitions of instruction such as below:-

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Selection.Count = 1 Then
 'Put in your actual range and the cell where you the text to be shown
    If Not Intersect(Target, Range("E10:E101")) Is Nothing Then
        Range("E7").Value = Selection.Value
        End If
End If

If Selection.Count = 1 Then
 'Put in your actual range and the cell where you the text to be shown
    If Not Intersect(Target, Range("S10:S101")) Is Nothing Then
        Range("S7").Value = Selection.Value
End If
End If

I would appreciate it if you could advise how this code could be refined. Thank you.

From LC Tan 10 August 2019

As far as I know, questions regarding refinement are more appropriate for Code Review Stack Exchange. Also, the code in your question appears to be missing an End Sub line. Presume this is just due to a bad paste.

In my opinion, since the code is quite short, there isn't too much to say other than:

  • It doesn't make sense to perform the Selection.Count twice. So maybe just do it once and move the second If Not Intersect... block.
  • If you invert the Selection.Count check, you can exit early and reduce the indentation levels in the rest of the procedure.
  • Maybe use Target instead of Selection .
  • Maybe use Me.Range instead of just Range (although this might be unnecessary).
  • Maybe Range.CountLarge is a better property to use during the check (even if the possibility of overflow error/selecting ~2.1 billion cells is unlikely).
  • Maybe disable events at the start and end of the routine to prevent infinite loop/recursion due to other events firing. (If you do this, maybe have a On Error GoTo ... statement to ensure Application.EnableEvents is restored even if an error occurs.)

Overall, your code might then look like:

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If Target.Cells.CountLarge <> 1 Then Exit Sub

    If Not Intersect(Target, Me.Range("E10:E101")) Is Nothing Then
        Me.Range("E7").Value = Target.Value
    End If

    If Not Intersect(Target, Me.Range("S10:S101")) Is Nothing Then
        Me.Range("S7").Value = Target.Value
    End If
End Sub

If the repeated If Not Intersect... statements bother you, you could either replace them with a function or a loop. Or you could use the below (if you find it to be readable).

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If Target.Cells.CountLarge <> 1 Then Exit Sub
    If Target.Row < 10 Or Target.Row > 101 Then Exit Sub
    If Intersect(Me.Range("E:E,S:S"), Target) Is Nothing Then Exit Sub

    Me.Cells(7, Target.Column).Value = Target.Value
End Sub

There are many ways to express the same logic.

To: Chilin

Thank you very much for your help on the above with 2 solutions that are effective. They are not only elegant, they work after I tried out both solutions. Thank you very much.

From LC Tan 14 August 2019

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM