Excel cell value change depending on other cell value - vba

What I want to achieve is this:
Cell F1 can contain values "MT", "LT" or "MT+LT". If I change the value to "MT", cells C10:C15 should change to value 0. If I change value to LT, cells C3:C8 should change to 0. This looks like a simple task, but I can't find an example, how to do it.
I'm new to VBA so please be gentle :)

You can try this code (you have to paste it in desired sheet in VBE). It will be fired on every change in the sheet:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
'if value changed in some other cell than F1, then finish Sub
If Target.Address <> "$F$1" Then Exit Sub
If Target.Value = "MT" Then
Range("C10:C15").Value = 0
ElseIf Target.Value = "LT" Then
Range("C3:C8").Value = 0
ElseIf Target.Value = "MT+LT" Then
'some action, you seem to forgot
End If
End Sub

Related

Issue with VBA in excel for enabling/disabling of Cells

Requirement Explanation :-
Whenever specific input given in some field/column of excel then the user should be restricted to input for specific range of fields/columns in the same row and same sheet of excel.
Input is selected from dropdown values in each cell of fields/columns.
Other than those specific input, those specific range can be allowed for user input.
This applies for all the rows of the input column until the last cell.
Example Scenario :-
If user selects "AWB" from dropdown in the cell C6, then user should not able to provide input from DP6 to ED6 (DP6 - ED6 should be read only/not editable).
Else DP6 - ED6 cell should be enabled. (Here, we have enabling and disabling in the same row) .
Note : And no other sheet should be impacted because of this.
My code :-
WorkBook.Sheets("SheetName").Unprotect
WorkBook.Sheets("SheetName ").Range("A15:A20").Locked = False
mainworkBook.Sheets("SheetName ").Protect
Here is an example taken from the PCreview website that makes column F read-only. This can be adapted to make any cells read-only.
Dim OldValue As Variant
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column = 6 Then
On Error GoTo Whoops
Application.EnableEvents = False
MsgBox "Values in this column cannot be changed!"
Target.Value = OldValue
End If
Whoops:
Application.EnableEvents = True
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Column = 6 Then OldValue = Target.Value
End Sub

If Cells A1:C1= "No", All cells in the risk of the row will be blocked from input

Anyone know how to block cells from input (also gray it out) if for example cells A1:C1 = "No" then the rest of the row up to a say F1 is grayed out and blocked from input? I was hoping to do this in VBA but if there are other easier ways, please let me know! Thank you!
Didi
Just to show a different approach:
Put this in the sheet-code-tab:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Not (Intersect(Target, Me.Range("D1:F1")) Is Nothing) And Me.Evaluate("AND(LOWER(A1:C1)=""no"")") Then Me.Range("A1").Select
End Sub
And to grey them out, best will be conditional formatting:
Range: =$D$1:$F$1
Formula: =AND(LOWER($A$1:$C$1)="no")
Using the conditional formatting allows to change the cells as you like without the need to alter the VBA code (this also will be faster)
The VBA part itself, just sets the selected cell to A1 if A1:C1 is "No" and a range is selected which also includes any of the cells of D1:F1
The LOWER can be skipped if you want it to be case sensitive
The only con is: if A1:C1 is "no" you still can paste a range to a cell (not any of D1:F1 directly) which also include the locked cells.
The biggest pro is: this also works for shared workbooks (as there is no need to lock/unlock sheets)
EDIT
If the cells need to be protected then something like this will do:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim a As Boolean
a = Me.Evaluate("AND(LOWER(A1:C1)=""no"")")
If a <> Me.Range("D1").Locked Then
Me.Unprotect
Me.Range("D1:F1").Locked = a
Me.Protect
End If
End Sub
as was mentioned in the comments, look to use a workbook change event with the following sub
Sub test()
If Worksheets("Sheet1").Range("A1").Value = "no" And Worksheets("Sheet1").Range("B1").Value = "no" And Worksheets("Sheet1").Range("C1").Value = "no" Then
Worksheets("Sheet1").Range("D1:F1").Interior.Color = RGB(220, 220, 220)
Worksheets("Sheet1").Range("D1:F1").Locked = True
Worksheets("Sheet1").Protect
End If
End Sub

Array formula into range of cells

I'm trying to put an array formula into a range of cells ("B2:B10") The formula should return multiple results dependent on the value in cell A2. When I do it the normal way (ctrl, shift, enter) it works ok, but when I try to do it with code it returns the same result in each cell which is the first instance found. Can anyone help me out to get the result I'm looking for?
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = Range("$A$2").Address Then
With Range("B2:B10")
.FormulaArray = "=INDEX(Absence!$C$2:$C$151, SMALL(IF($A$2=Absence!$A$2:$A$151, ROW(Absence!$A$2:$A$151)-ROW(Absence!$A$2)+1), ROW(Absence!1:1)))"
.Value = .Value
End With
End If
End Sub
Is this any better:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = Range("$A$2").Address Then
Range("B2").FormulaArray = "=INDEX(Absence!$C$2:$C$151, SMALL(IF($A$2=Absence!$A$2:$A$151, ROW(Absence!$A$2:$A$151)-ROW(Absence!$A$2)+1), ROW(Absence!1:1)))"
Range("B2").Copy Range("B3:B10")
Range("B2:B10").Value = Range("B2:B10").Value
End If
End Sub
The problem is that you are array-entering the formula into all of the cells at once instead of array-entering into the first cell and filling down. Without filling down, the ROW(1:1) does not progess. You need to put all of the possible k values for the SMALL function in at once with ROW(1:150).
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = Range("$A$2").Address Then
With Range("B2:B10")
.FormulaArray = "=INDEX(Absence!$C$2:$C$151, SMALL(IF($A$2=Absence!$A$2:$A$151, ROW(2:151)-ROW(2:2)+1), ROW(1:9)))"
.Value = .Value
End With
End If
End Sub
Btw, when we use ROW(Absence!$A$2:$A$151) to achieve a number between 2 and 151, the worksheet and column letter are not necessary. ROW(2:151) will do fine and cleans up the formula a little.

Excel VBA Case not recognizing value of cell

Im trying to use VBA to hide/show a group of rows on a separate sheet within the same workbook named Invoice
To do this, on the InputForm sheet, there is a cell (N14) which uses =ISBLANK(D53) to check if D53 contains anything and obviously returns TRUE/FALSE
From this im trying to run an If Statement in VBA to hide/show rows based on whether the cell N14 contains TRUE/FALSE
The code i've tried works ok if i manually type TRUE/FALSE but not if it is automatically entered by the formula.
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address(False, False) = "N14" Then
Select Case Target.Value
Case "TRUE": Sheets("Invoice").Rows("57:123").Hidden = True:
Case "FALSE": Sheets("Invoice").Rows("57:123").Hidden = False:
End Select
End If
End Sub
The format of Cell N14 is "Text"
As I mentioned in comments, Worksheet_Change doesn't fires when result of your formula changes. It fires only if you change value of cell itself. You should look into Worksheet_Calculate event instead:
Private Sub Worksheet_Calculate()
Application.EnableEvents = False
Sheets("Invoice").Rows("57:123").Hidden = Range("N14").Value
Application.EnableEvents = True
End Sub

Merge a cell in excel, depending on it's value

I want to merge a cell automatically with the one underneath if the cell has a certain value ("vv").
a solution i found is to check every cell in an array every time a change is made, but thought there would be a possibility to check the value of a cell after it changed?
So if I enter in a blank cell "vv" (without quotes) and I select a different cell I'd like that cell (with vv in it) to merge with the one right under it.
in my solution with the array it takes a second every time you change a cell, which is not neat if you make a lot of changes.
Any help?
Try this code in your worksheet:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Value = "vv" Then Target.Resize(2).Merge
End Sub
In case you want to prevent any content in the cell below, this code will ask you if the cells shall be merged in case any content is found:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Value = "vv" Then
If Target.Offset(1).Value "" Then
If MsgBox("Do you want to overwrite the cell below (containing '" & _
Target.Offset(1) & "?", vbYesNo) = vbYes Then
Target.Resize(2).Merge
End If
Else
Target.Resize(2).Merge
End If
End If
End Sub
Note: The code needs to go in the target sheet, not a new module, as it is an Event procedure: