How can I simplify this into one sentence in vba?
If [BT12] = "a" Then
Range("AB12").ClearContents
End If
If [BT13] = "a" Then
Range("AB13").ClearContents
End If
If [BT14] = "a" Then
Range("AB14").ClearContents
End If
How can I simplify this into one sentence in vba?
If [BT12] = "a" Then
Range("AB12").ClearContents
End If
If [BT13] = "a" Then
Range("AB13").ClearContents
End If
If [BT14] = "a" Then
Range("AB14").ClearContents
End If
Here it is in one line:
[AB12:AB14] = [IF(BT12:BT14 = "a","",AB12:AB14)]
Here is another using UNION:
Union(IIf([BT12] = "a", [AB12], [AFD1040000]), IIf([BT13] = "a", [AB13], [AFD1040000]), IIf([BT14] = "a", [AB14], [AFD1040000])).ClearContents
The first creates an array of the values, either ""
or the value in the cell. It is very concise and can easily be expanded to include a larger range. The drawback is that if the data in AB is filled by formula the formula will be replaced by the value and the formula will be removed.
The second only clears those that need to be cleared leaving the others unchanged but is not as easily editable with larger ranges.
here's your one-sentence code:
If Not [BT12:BT14].Find("a", , xlValues, xlWhole) Is Nothing Then Range(IIf([BT12] = "a", IIf([BT13] = "a", IIf([BT14] = "a", "AB12:AB14", "AB12:AB13"), IIf([BT14] = "a", "AB12,AB14", "AB12")), IIf([BT13] = "a", IIf([BT14] = "a", "AB13:AB14", "AB13"), IIf([BT14] = "a", "AB14", "")))).ClearContents
that you can (possibly) read more comfortably as:
If Not [BT12:BT14].Find("a", , xlValues, xlWhole) Is Nothing Then Range( _
IIf([BT12] = "a", _
IIf([BT13] = "a", _
IIf([BT14] = "a", "AB12:AB14", "AB12:AB13"), _
IIf([BT14] = "a", "AB12,AB14", "AB12") _
), _
IIf([BT13] = "a", _
IIf([BT14] = "a", "AB13:AB14", "AB13"), _
IIf([BT14] = "a", "AB14", "") _
) _
) _
).ClearContents
This is bad practice and not recommended but is a one-liner. It is expected that this would be wrapped in a With statement holding the parent sheet reference.
Dim i As Long: For i = 12 To 14: If .Cells(i, 72).Value = Chr$(97) Then .Cells(i, 28).ClearContents: Next
Yes, it can be done :-)
Just for fun: assuming you provide an ► empty cell in [AB11]
, you can use this one liner via the Application.Index
function:
[AB11:AB14] = Application.Transpose(Application.Index([AB11:AB14], Array(1, IIf([BT12] = "a", 1, 2), IIf([BT13] = "a", 1, 3), IIf([BT14] = "a", 1, 4)), 1))
(Edit thx DisplayName:)
Amplifying remarks to the Index
function
You can find amplifying remarks to the use of the Index
function at Insert first column in array without Loops or API calls
For what you are asking for; the IIF
function works, whether you are evaluating using a True
or False
clause. Try this one liner.
For Each cel In Range("BT12:BT14"): IIf cel = "a", cel.Offset(, -44).ClearContents, True: Next
How can I simplify this into one sentence in vba?
Should you? Your example code is concise, and easy to read. As Rawrplus points out, shorter for the sake of being shorter is usually not a good idea.
One could simplify each line to this:
If [BT12] = "a" Then Range("AB12").ClearContents
If [BT13] = "a" Then Range("AB13").ClearContents
If [BT14] = "a" Then Range("AB14").ClearContents
Is that better? Arguably no in my opinion. If the actions of the condition ever need more complexity, you'll be forced to refactor anyway.
The quick answer is: it cant' be done. But one could figure out a solution if one want's to although it be rather far fetched.
First create a sub to put in a library module.
Sub ClearCellContent(ParamArray Args())
Dim i As Integer, J As Integer
i = UBound(Args)
For J = 0 To i Step 3
If Args(J).value = Args(J + 1) Then Args(J + 2).ClearContents
Next
End Sub
From a somewhere in your code you can now call this sub like so:
ClearCellContent [BT12], "a", [AB12], [BT13], "a", [AB13], [BT14], "a", [AB14]
Like I said, far fetched but a oneliner of sorts.