For instance a simple equation is
F = m * a
And I have in my excel sheet
So in here I have not entered m
Would it be possible to rearrange the equation to calculate for m
m = F / a
Does excel have a built in facility to do this?
Can VBA do this?
Any other way to achieve this incase the above 2 are not possible?
So basically If I leave any one of the variable cells blank and fill in the other two, I would like the result for the 3rd variable.
Put this in the worksheet's private code sheet (right-click worksheet name tab, View Code).
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("B2:B4")) Is Nothing Then
On Error GoTo safe_exit
Application.EnableEvents = False
If Application.Count(Range("B2:B4")) = 2 Then
If IsEmpty(Range("B2")) Then
Range("B2") = Range("B3").Value2 * Range("B4").Value2
ElseIf IsEmpty(Range("B3")) Then
Range("B3") = Range("B2").Value2 / Range("B4").Value2
Else
Range("B4") = Range("B2").Value2 / Range("B3").Value2
End If
Range("B2").NumberFormat = "0 \N"
Range("B3").NumberFormat = "0.0 \k\g"
Range("B4").NumberFormat = "0 \m\/\s\²"
End If
End If
safe_exit:
Application.EnableEvents = True
End Sub
You can do this with a if() statement:
=if(b3="",b2/B4,if(b2="",B3*b4,if(b4="",b2/b3,"Check")))
Not put any error checking such as checking for numbers in any two cells etc...
Related
I was looking for a code to automatically insert the ':' (colon) into the columns R and S, W and X, and found code that I thought I could customise to my needs, but I am facing two issues:
The code works in R and S, but also need the code to run in columns W and X as well
I get an error:
Variable not Defined - stopping at TLen and I guess it will also stop at TimeV
The programmer doesn't use the Option Explicit, (it works OK without Option Explicit). But all my code is always with Option Explicit, but I'm not sure how to write the Dim for the two variables.
This code is in a specific worksheet, in the Worksheet_Change sub, where I have other code for other things, like the timestamp when people make a selection from column B, it will automatically populate when a selection is made in column B.
I have tried the colon code in another workbook, without the Option Explicit and it works without giving errors.
The source of the code came from
Excel VBA tips n tricks #12 no more colons when typing time of day, type 123 instead of 01colon23 AM
I've adapted the code to reference columns R and S in the code below.
Private Sub Worksheet_Change(ByVal Target As Range)
' This code will ADD the COLON for TIME automatically
' The code is from: https://www.youtube.com/watch?v=ATxaNbTV2d0 (Excel is Fun -
' Excel VBA Tips n Tricks #12 NO MORE COLONS When Typing Time of Day, Type 123 instead of 01colon23 AM
' To avoid an error if you select more than 1 cell, this next line of code will exit the sub
If Selection.Count > 1 Then
Exit Sub
End If
If Not Intersect(Range("R4:S1200"), Target) Is Nothing Then
TLen = Len(Target)
[![Layout of Worksheet and sample of the columns that need automatic insertion of colons ][1]][1]
If TLen = 1 Then
TimeV = TimeValue(Target & ":00")
ElseIf TLen = 2 Then
TimeV = TimeValue(Target & ":00")
ElseIf TLen = 3 Then
TimeV = TimeValue(Left(Target, 1) & ":" & Right(Target, 2))
ElseIf TLen = 4 Then
TimeV = TimeValue(Left(Target, 2) & ":" & Right(Target, 2))
ElseIf TLen > 4 Then
'Do nothing
End If
'Target.NumberFormat = "HH:MM"
Application.EnableEvents = False
Target = TimeV
Application.EnableEvents = True
End If
End Sub
Expand the range of the Intersect Intersect(Range("R:S,W:X"),Target).
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Cells.Count > 1 Then Exit Sub
If IsNumeric(Target) = False Then
MsgBox Target & " is not a number", vbExclamation
Exit Sub
ElseIf Intersect(Range("R:S,W:X"), Target) Is Nothing Then
Exit Sub
End If
Dim n As Long
n = Len(Target)
If n >= 1 And n <= 4 Then
Application.EnableEvents = False
Target.NumberFormat = "hh:mm"
If n <= 2 Then
Target.Value2 = TimeSerial(Target, 0, 0)
Else
Target.Value2 = TimeSerial(Int(Target / 100), Target Mod 100, 0)
End If
Application.EnableEvents = True
End If
End Sub
I understand that you are 'stretching & teaching' me to work things out for myself, and it is appreciative (and I definitely have learned how to see the type (1.)). But in this instance, the 'Type' is coming as Variant/Date, even though it is meant to be time (maybe I am misunderstanding the syntax). – TheShyButterfly
You did well! Yes, that is one way to find the type. The other way is to use the VarType function:
Option Explicit
Sub Sample()
Dim TimeA
TimeA = TimeValue("01:00 PM")
MsgBox VarType(TimeA)
End Sub
This will give you 7 which is vbDate.
You can also store time as Variant and Double as shown below.
Option Explicit
Sub Sample()
Dim TimeA As Date
Dim TimeB As Double
Dim TimeC As Variant
TimeA = TimeValue("01:00 PM")
TimeB = TimeValue("01:00 PM")
TimeC = TimeValue("01:00 PM")
MsgBox "Time stored as Date : " & TimeA
MsgBox "Time stored as Double : " & TimeB
MsgBox "Time stored as Variant : " & TimeC
MsgBox "TimeA formated as Date : " & Format(TimeA, "hh:mm:ss AM/PM")
MsgBox "TimeB formated as Date : " & Format(TimeB, "hh:mm:ss AM/PM")
MsgBox "TimeC formated as Date : " & Format(TimeC, "hh:mm:ss AM/PM")
End Sub
but without an example how am I to learn, I have obviously exhausted my search on resolving this, but found nothing .. the reason why I posted the question. Thank you for encouraging me to continue solving things on my own :) TheShyButterfly
You can write the range as CDP1802 shown in his post or you can use the Application.Union method (Excel).
For example,
Option Explicit
Sub Sample()
Dim rngA As Range
Dim rngB As Range
Dim rngCombined As Range
Set rngA = Range("R4:S1200")
Set rngB = Range("W4:X1200")
Set rngCombined = Union(rngA, rngB)
MsgBox rngCombined.Address
End Sub
So in your code it becomes Intersect(rngCombined, Target) Is Nothing.
Also since you are working with Worksheet_Change and Events, I recommend seeing Working with Worksheet_Change.
I’m trying, with Excel 2013, to hide and unhide rows when a cell is a certain value.
It's a form which should expand based on answers given.
When C16 = YES hide rows 18:22
When C16 = NO hide rows 24:38
When C16 =blank hide rows 18:38
When L43 = YES unhide rows 43:68 (if it’s not yes a zero is displayed)
I have tried 2 methods.
First: Into the worksheet - selected change in the top right dropdown
Private Sub Worksheet_Change(ByVal Target As Range)
Range("A18:A22").EntireRow.Hidden = (Range("$C$16").Value = "Yes")
Range("A24:A38").EntireRow.Hidden = (Range("$C$16").Value = "NO")
Range("A18:A38").EntireRow.Hidden = (Range("$C$16").Value = "")
Range("A43:A68").EntireRow.Hidden = (Range("$L$43").Value = "0")
End Sub
Second: code from here:
Unhide rows based on cell value
Using both of these methods only one of the changes seems to go ahead. So cell C16 is changed but that means range L43 is ignored
Also when the cell was blank it didn’t change anything. It remained as is and didn’t hide the columns as required.
Your ranges overlap so even if C16 = "Yes" the line C16 = "" will override it and unhide it. L42 is probably also a number where as you're comparing it to a text value try using the following instead. Your code would run on every single change in your sheet as well so have also updated it to only run when either C16 or L43 is changed
Private Sub Worksheet_Change(ByVal Target As Range)
With Me
If Not Intersect(Target, Union(.Range("C16"), .Range("L43"))) Is Nothing Then
.Range("A18:A38").EntireRow.Hidden = False
Select Case LCase(.Range("C16").Value2)
Case "yes"
.Range("A18:A22").EntireRow.Hidden = True
Case "no"
.Range("A24:A38").EntireRow.Hidden = True
Case Else
.Range("A18:A38").EntireRow.Hidden = True
End Select
.Range("A43:A68").EntireRow.Hidden = False
Select Case LCase(.Range("L43").Value2)
Case "yes"
.Range("A43:A68").EntireRow.Hidden = False
Case Else
.Range("A43:A68").EntireRow.Hidden = True
End Select
End If
End With
End Sub
After comments
I'd break this into two from your comments. The first would watch the dropdown and execute on the change of that cell. The second would update using the calculate event. Put these Subs in the sheets where applicable
Private Sub Worksheet_Change(ByVal Target As Range)
With Me
If Not Intersect(Target, Union(.Range("C16"), .Range("L43"))) Is Nothing Then
.Range("A18:A38").EntireRow.Hidden = False
Select Case LCase(.Range("C16").Value2)
Case "yes"
.Range("A18:A22").EntireRow.Hidden = True
Case "no"
.Range("A24:A38").EntireRow.Hidden = True
Case Else
.Range("A18:A38").EntireRow.Hidden = True
End Select
End If
End With
End Sub
Private Sub Worksheet_Calculate()
Application.EnableEvents = False
With Me
.Range("A43:A68").EntireRow.Hidden = False
Select Case LCase(.Range("L43").Value2)
Case "yes"
.Range("A43:A68").EntireRow.Hidden = False
Case Else
.Range("A43:A68").EntireRow.Hidden = True
End Select
End With
Application.EnableEvents = True
End Sub
Try:
With Worksheets("Sheet1")
.Rows("18:68").EntireRow.Hidden = False
opt = UCase(.Range("C16").Value)
Select Case opt
Case "YES"
Rows("18:22").EntireRow.Hidden = True
Case "NO"
Rows("24:38").EntireRow.Hidden = True
Case ""
Rows("18:38").EntireRow.Hidden = True
Case Else
MsgBox "Invalid option in cell C16."
End Select
If UCase(.Range("L43").Value) = "Yes" Then
Rows("43:68").EntireRow.Hidden = True
Else
MsgBox "Invalid option in cell L43."
End Select
End With
...though I didn't understand what you wanted to be '0'.
My apologies if my question is too basic. I am trying to achieve the following results
If Cell E11 value is less than 25,000, then hide Rows 14 & 15.
If Cell E11 value is between 25k-50k, then hide only row 15 only.
If Cell E11 value is between 50k-75k, then unhide both rows.
And it is possible to make the calculation automated?
So far I found the following code, which of course isn't helping with my situation.
Sub PG1()
If Range("E11").Value = "Pass" Then
Rows("14:14").EntireRow.Hidden = True
ElseIf Range("E11").Value = "Fail" Then
Rows("14:14").EntireRow.Hidden = False
End If
End Sub
A minor amount of trial and error based on nothing else but the code you posted gave me this code, which should get you started. It completes two of the three requirements (using different cells and rows), but it works. If it's still not something you can use to complete your task, you should probably hire someone to do this for you.
Sub ShowOrHide()
If ActiveSheet.Range("A1").Value < 25000 Then
ActiveSheet.Rows("2:3").EntireRow.Hidden = True
ElseIf ActiveSheet.Range("A1").Value >= 50000 Then
ActiveSheet.Rows("2:3").EntireRow.Hidden = False
End If
End Sub
Here you go.
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$E$11" Then
If Target.Value < 25000 Then Rows("13:15").EntireRow.Hidden = True
If Target.Value > 25000 Then Rows("13:14").EntireRow.Hidden = False
If Target.Value > 50000 Then Rows("13:15").EntireRow.Hidden = False
If Target.Value > 75000 Then Rows("13:15").EntireRow.Hidden = True
End If
End Sub
I've got several data validation dropdown boxes across the top row of a spreadsheet. I'm using the following code to expand the box size (to help the users see their options) upon selecting the cell. I'm having problems getting the VBA script to ignore columns A:C upon returning the columns to normal width. These columns should be fixed at 20 and the others returned to 8.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Cells.Count > 1 Then Exit Sub
If Intersect(Target, Range("D1:AP1")) Is Nothing And Target.Columns <> "A1:C1" Then
ActiveWindow.Zoom = 100
Target.Columns.ColumnWidth = 8
Else
ActiveWindow.Zoom = 120
Target.Columns.ColumnWidth = 30
End If
End Sub
If I have understand well, the code shall be like:
Application.ScreenUpdating = False
If Target.Cells.Count > 1 Then
Exit Sub
Application.ScreenUpdating = True
End If
Set xx = Application.Intersect(Target, Range("D1:AP1"))
If xx Is Nothing Then
ActiveWindow.Zoom = 100
For i = 4 To 42
If Columns(i).Hidden = False Then Columns(i).ColumnWidth = 8
Next
Else
ActiveWindow.Zoom = 120
Target.Columns.ColumnWidth = 30
End If
Application.ScreenUpdating = True
The control of the Target cor Columns A:C shall be made after.
Also I prefer to chaneg all the width for columns D:AP when you return ...
I have a little bit chaged the code... Adding the check if are Hidden, and with the line Application.ScreenUpdating, the code show only at the end.
I have also removed code non necessary (some if ...).
Im having a little trouble with a code in excel vba.
What I want to do is that If any CELL within a RANGE on Sheet 1 is <= 2000 THEN hide a given row on Sheet 2. So it only takes 1 cell within a that range to be <= 2000 for the rows on the other sheet to be hidden. Kind of like a rotten apple spoils the bunch kind of thing.
Any help would be greatly appriciated. Thanks in Advance.
Edit: code i have that isnt working:
Edit2: code updated based on comments given, still no luck with it working.
Private Sub HideRows()
Sheets("Summary").Cells.EntireRow.Hidden = False
For Each cell In Sheets("Worksheet").Range("G9:P9")
If Abs(cell.Value) < 2000 Then
Sheets("Summary").Rows(11).EntireRow.Hidden = True
Sheets("Summary").Rows(23).EntireRow.Hidden = True
Sheets("Summary").Rows(43).EntireRow.Hidden = True
Sheets("Summary").Rows(54).EntireRow.Hidden = True
Sheets("Summary").Rows(78).EntireRow.Hidden = True
Sheets("Summary").Rows(90).EntireRow.Hidden = True
End If
Next
End Sub
The code does have the correct enders too such as End Select, Next, End Sub
-Matt
I'd do it this way:
Private Sub HideRows()
Worksheets("Summary").Cells.EntireRow.Hidden = False
For Each cell In Sheets("Worksheet").Range("G9:P9")
If Abs(cell) < 2000 Then
Worksheets("Summary").Range("A11,A22,A43,A54,A78,A90").EntireRow.Hidden = True
End If
Next
End Sub
It's best to use the Range object and reference non-contiguous cells as it makes it a single line.
You might Want to try and avoid Loops Something Like:
Sub NoLoopSample()
Dim lngLessThenSum As Long, lngGreaterThenSum As Long
Dim rngTestRange As Range
Set rngTestRange = Sheets("Worksheet").Range("G9:P9")
lngBetween2k4k = WorksheetFunction.SumIfs(rngTestRange, rngTestRange, ">=" & 2000, rngTestRange, "<" & 4000)
lngLessThenSum = WorksheetFunction.SumIf(rngTestRange, "<" & 2000)
If lngBetween2k4k > 0 Then
MsgBox "Atleast 1 Number Is Between 2000 And 4000"
End If
If lngLessThenSum > 0 Then
MsgBox "Atleast 1 Number Is Less then 2000"
Sheets("Summary").Range("11:11, 23:23, 43:43, 54:54, 78:78, 90:90").EntireRow.Hidden = True
End If
End Sub
Should do what you want and won't have to test EVERY Single cell in your range. There may be other functions or ways to do it but this was at the top of my head. Although on such a small range you shouldn't even notice the difference.
I also like to make as few changes to a worksheet from VBA as possible so in my example I hide all the rows you mention in one call rather then a call for each row.
Maybe it's about EntireRow property ..
Reference .. http://msdn.microsoft.com/en-us/library/office/ff836836.aspx
Since your code .. Rows("11").EntireRow.Hidden = True .. you have to make it sure that Row("11") is Range var ..
And to hide rows you may do Rows(11).Hidden = True
Sub try()
i = 1
While Sheet1.Cells(i, 1).Value <> ""
If Sheet1.Cells(i, 1).Value > 2000 Then
Sheet2.Rows(i).EntireRow.Hidden = True
End If
i = i + 1
Wend
End Sub
Straight to the point:
Range("a11,a22,a43,a54,a78,a90").EntireRow.Hidden = [sum((g9:p9>0)*(g9:p9<2001))]
You are concerned more with the minimum value only. I would rather use Excel's Min function for the work:
Sub HideRows()
Set InRng = Worksheets("Worksheet").Range("G9:P9") 'Input Range
Set OutRng = Worksheets("Summary").Range("A11,A22,A43,A54,A78,A90") 'Rows to be hidden
MinVal = Application.WorksheetFunction.Min(InRng) 'Invoking inbuilt function to get minimum value
If MinVal < 2000 Then
OutRng.EntireRow.Hidden = True
End If
End Sub