Excel VBA If statements - excel

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

Related

hiding rows with If statement for a calander

So I am a student and my chef gave me the task of making the occupancy plan in excel more dynamic. Now I want to hide the columns if they dont belong to the specific month but it doesnt work like I want it. The days are now only shown up to the 28. of every month.
What is wrong here?
Sub montatslen()
Dim spaltenr As Integer
For spaltenr = 32 To 34
If Cells(3, 7).Value = Month(Cells(14, spaltenr).Value) Then
Columns(spaltenr).EntireColumn.Hidden = False
Else
Columns(spaltenr).EntireColumn.Hidden = True
End If
Next spaltenr
End Sub
I tried writing it this way and it seemed to work. It hides columns AF, AG and AH
Sub montatslen()
Dim spaltenr As Integer
For spaltenr = 32 To 34
columnLetter = Split(Cells(1, spaltenr).Address, "$")(1)
If Range("G3").Value = Month(Range(columnLetter & "14").Value) Then
Columns(spaltenr).EntireColumn.Hidden = False
Else
Columns(spaltenr).EntireColumn.Hidden = True
End If
Next spaltenr
End Sub

use checkbox to hide/unhide rows based on cell value

Using VBA in excel, trying to understand how I can use a checkbox to hide/unhide any row that has a specific value in a specific column. My VBA skills are getting better more I practice but I am still not good with loops just yet. Appreciate any help you can provide. Here is what I have so far.
Private Sub CkBx_ShowAllRecords_Click()
If Me.CkBx_ShowAllRecords = True Then
For Each Row In Range("Table1").ListObject.ListColumns
If Row.Cells(1, "column5").Value = "Submission Complete" Then
Application.EntireRow.Visible=True
Next
End if
End Sub
Additionally when I uncheck the box I would want all rows where column 5 cell value equals "submission complete" would be hidden (just the opposite of what I put above when I check the box control).
Hope this may help you:
Private Sub CkBx_ShowAllRecords_Click()
Dim i As Long
If Me.CkBx_ShowAllRecords = True Then
For i = 1 To ActiveSheet.ListObjects("Table1").Range.Rows.Count
If ActiveSheet.ListObjects("Table1").DataBodyRange(i, 5).Value = "Submission Complete" Then
Rows((i + 1) & ":" & (i + 1)).Select
Selection.EntireRow.Hidden = True
End If
Next i
Else
ActiveSheet.Rows.EntireRow.Hidden = False
End If
Me.Hide
End Sub

Insert New Row with Sequential Number after criteria is met

I will admit to being a terrible at code, and have always struggled with Macros... forgive my ignorance.
What I am working on building is a part number index that will create a new sequential number within a numerical series after a macro-button is pressed.
I'd like each button to scan between a range [i.e. 11-0000 (MIN) and 11-9999 (MAX)] and select the max value cell that exists. At that selection point insert an entire new row below with the next + 1 sequential number in the "B" column.
I have my button creating the table row as I would like, however I need help in defining the ".select(=Max(B:B))" and as I understand Max will also limit the # of line items it queries?
I have also been playing with .Range("B" & Rows.CountLarge) with little to no success.
Ideally the 11-**** button [as seen in the screen cap] should insert a sequential number below the highlighted row.
Maybe I'm way over my head, but any guidance even in approach or fundamental structure of the code would help be greatly appreciated!
Private Sub CommandButton1_Click()
Sheets("ENGINEERING-PART NUMBERS").Range("B" & Rows.CountLarge).End(xlUp).Select
ActiveCell.Offset(1, 0).Select
ActiveCell.EntireRow.Insert Shift:=xlDown
ActiveCell.Value = "=ActiveCell + 1"
End Sub
Screen Cap of Spread Sheet
Perhaps there is a simpler solution that I've overlooked, but the below will work.
Insert a module into your workbook and add this code:
Public Sub AddNextPartNumber(ByVal FirstCellInColumn As Range, Optional ByVal PartMask As Variant = "")
Dim Temp As Variant, x As Long, MaxValueFound(1 To 2) As Variant
'Some error checking
If PartMask = "" Then
MsgBox "No part mask supplied", vbCritical
Exit Sub
ElseIf Not PartMask Like "*[#]" Then
MsgBox "Invalid part mask supplied; must end in ""#"".", vbCritical
Exit Sub
ElseIf PartMask Like "*[#]*[!#]*[#]" Then
MsgBox "Invalid part mask supplied; ""#"" must be continuous only.", vbCritical
Exit Sub
End If
'Get the column of data into an array
With FirstCellInColumn.Parent
Temp = .Range(FirstCellInColumn, .Cells(.Rows.Count, FirstCellInColumn.Column).End(xlUp))
End With
'Search through the array and find the largest matching value
For x = 1 To UBound(Temp, 1)
If Temp(x, 1) Like PartMask Then
If MaxValueFound(1) < Temp(x, 1) Then
MaxValueFound(1) = Temp(x, 1)
MaxValueFound(2) = x
End If
End If
Next x
'Output new part number
If MaxValueFound(2) = 0 Then
'This part mask doesn't exist, enter one with 0's at the end of the list
With FirstCellInColumn.Offset(x - 1, 0)
.Value = Replace(PartMask, "#", 0)
.Select
End With
Else
'Get the length of the number to output
Dim NumberMask As String, NumFormatLength As Long
NumFormatLength = Len(PartMask) - Len(Replace(PartMask, "#", ""))
NumberMask = String(NumFormatLength, "#")
'Determine the new part number
MaxValueFound(1) = Replace(MaxValueFound(1), Replace(PartMask, NumberMask, ""), "")
MaxValueFound(1) = Replace(PartMask, NumberMask, "") & Format((MaxValueFound(1) * 1) + 1, String(NumFormatLength, "0"))
'Insert row, add new part number and select new cell
FirstCellInColumn.Offset(MaxValueFound(2), 0).EntireRow.Insert
With FirstCellInColumn.Offset(MaxValueFound(2), 0)
.Value = MaxValueFound(1)
.Select
End With
End If
End Sub
Then, for each button, you write the code like this:
Private Sub CommandButton1_Click()
'this is the code for the [ADD 11-****] button
AddNextPartNumber Me.Range("B16"), "11-####"
End Sub
Private Sub CommandButton2_Click()
'this is the code for the [ADD 22-****] button
AddNextPartNumber Me.Range("B16"), "22-####"
End Sub
This has been written assuming that inserting a new row onto your sheet won't affect other data and that adding new data to the bottom of the table without inserting a row also won't affect other data.
Assuming you're working with a table, by default it should auto-resize to include new data added to the last row.
Good luck learning the ropes. Hopefully my comments help you understand how what I wrote works.

VBA: How to filter through a sheet based on a checkbox?

I'm new to VBA and I'm trying to set up a customizable sheet that allows the user to filter certain columns based on the checkboxes that I have set up. So far, I understand how checkboxes work and how I can integrate them into the code, but I think I have an issue with the autofilter function. Specifically, I think that I'm putting the wrong value for Criteria1.
I've been looking around for similar coding problems, but none of them seem to work with what I'm trying to do.
TL;DR I think my issue lies with how I format the array to put in Criteria1 of the AutoFilter()
Sub Auto_filter()
'variables are for checkboxes'
Dim VC1500 As Shape
Dim VC7500 As Shape
Dim VC144024 As Shape
'initiates to check for the checkboxes'
Set VC1500 = Sheets("Sheet7").Shapes("Check Box 4")
Set VC7500 = Sheets("Sheet7").Shapes("Check Box 5")
Set VC144024 = Sheets("Sheet7").Shapes("Check Box 6")
'if statement that will add a string to strCriteria if checkbox is true'
If VC1500.OLEFormat.Object.Value = 1 Then
strCriteria = strCriteria & ", VC1500"
End If
If VC7500.OLEFormat.Object.Value = 1 Then
strCriteria = strCriteria & ", VC7500"
End If
If VC144024.OLEFormat.Object.Value = 1 Then
strCriteria = strCriteria & ", 144024"
End If
'with statement that finds for column vendor then filter it based on
strCriteria, I think this is where my issue is'
With Worksheets("Open Purchase Orders")
With .Range("A1", .Cells(1, Columns.Count).End(xlToLeft))
Set vendorfind = .Rows(1).Find("Vendor")
If Not vendorfind Is Nothing Then
.AutoFilter Field:=vendorfind.Column,
Criteria1:=Split(strCriteria, ", "), Operator:=xlFilterValues
End If
End With
.AutoFilterMode = False
End With
End Sub
I expect to have the sheet filtered based on the checkboxes.
I get a runtime error 9 error:subscript out of range
Have you tried using Slices?
Its easy and should do simple filters without Macros.
Select your data > Insert Table.
Once the table is done, from the Design tab you can select "Insert Slicer".
Try if this solves your problem.
Some parts of that code look to me like scratching your left ear with your right hand going over your head. But I'm not entirely clear on how it actually looks (a sample would be helpful) - does each vendor have some separate indication column? If so, what are you filtering there? A vendor tag, by the looks of it?
This for example is a solution for a single vendor column (D) which may contain the 3 names. It basically applies an autofilter of a list of values. (I'm using activex checkboxes below as their properties can be accessed directly.)
Private Sub VC1500_Click()
Update_Filter
End Sub
Private Sub VC7500_Click()
Update_Filter
End Sub
Private Sub VC144024_Click()
Update_Filter
End Sub
Private Sub Update_Filter()
Dim varr_filter(3) As String
Dim indshow As Boolean
indshow = True
If VC1500 Then
varr_filter(0) = VC1500.Caption
indshow = False
End If
If VC7500 Then
varr_filter(1) = VC7500.Caption
indshow = False
End If
If VC144024 Then
varr_filter(2) = VC144024.Caption
indshow = False
End If
If indshow Then
Range("$A:$D").AutoFilter
Else
Range("$A:$D").AutoFilter field:=4, Criteria1:=varr_filter, Operator:=xlFilterValues
End If
End Sub
Note: Pick the correct column for filtering as the "field" value, and if you wish to separate the checkboxes from the form for some reason, then add """sheets("sheetname").{each checkbox}""".
Alternatively, if each of the vcs possesses a separate column, and seeking rows which literally say "vendor", I'd merge them in the sheet like so:
E2=if(cond1)*checkbox1 + if(cond2)*checkbox2 + if(cond3)*checkbox3 ; E > 0.
Cond1 could be b2="Vendor", for example.
To make the sheet display all cols when no ticks are selected,
I've added another value: 1 - max(checkboxes).
E6=1-MAX($H$4:$H$6) + IF(AND(B2="Vendor"),1,0)*$H$4 +
IF(AND(C2="Vendor"),1,0)*$H$5 + IF(AND(D2="Vendor"),1,0)*$H$6
That's one example where a hidden sheet value helps, since you can actually define such a column without vb. And then, the code itself is simplified a bit.
Private Sub VC1500_Click()
If VC1500.Value Then
Range("$H$4").Value = 1
Else
Range("$H$4").Value = 0
End If
Update_Filter
End Sub
Private Sub VC7500_Click()
If VC7500.Value Then
Range("$H$5").Value = 1
Else
Range("$H$5").Value = 0
End If
Update_Filter
End Sub
Private Sub VC144024_Click()
If VC144024.Value Then
Range("$H$6").Value = 1
Else
Range("$H$6").Value = 0
End If
Update_Filter
End Sub
Private Sub Update_Filter()
Range("$A:$E").AutoFilter field:=5, Criteria1:=">0", Operator:=xlFilterValues
End Sub
It's also easier to transition to a form control, by checking the range value during click instead of the checkbox, and hiding column H. Not entirely bulletproof yet sufficient for the average user. Either that or read the shape as you wrote.
Edit: Added tested code above for both cases (single col, multicol), including displaying all rows when no tickboxes are checked rather than none. Here are the demo shots.
Single col code
Single col sample sheet
Single col filtered
Multicol code
Multicol sample
Multicol filtered

Excel VBA offset Copy Paste

Hope you're doing well. I'm going to preface this by saying I'm not a programmer and I'm sure the code I have started is riddled with more errors then what I think. Hopefully you can help :D.
I have an Excel sheet that gets generated from another program that comes out like this:
excel sheet
However, the size of this sheet can change with every new generation of this sheet from the other program. (ex, A can have 7 next time, and D could have 9) And the sheet as it is cannot be used easily to do the math required as I only need specific groups of information at a given time, in this example groups B and D only.
What I'm hoping to create is something that will take the sheet as its generated, and turn it into something that looks like this:
result sheet
This is the code I've written so far, but since I don't really know what I'm doing I keep running into numerous problems. Any help would be appreciated.
Option Explicit
Sub Numbers()
Dim matchesFound As Integer
Dim row As Integer
Dim c As Integer
Dim copyRow As Integer
Dim copyLocationColumn As Integer
Dim arr(2) As String
arr(0) = "1"
arr(1) = "2"
arr(2) = "3"
Function arrayContainsValue(array, varValue)
found = false
for each = 0 to array
if array(i) = varValue then
found = true
exit for
arrayContainsValue = found
End Function
row = 1
c = 1
copyLocationColumn = 1
copyRow = 1
matchesFound = 0
Do While matchesFound < 3
if arrayContainsValue(arr, ThisWorkbook.Sheets("Data").Cell(column,row))
matchesFound = matchesFound + 1
Do While ThisWorkbook.Sheets("Data").Cell(column, row)
ThisWorkbook.Sheets("postHere").Cell(copyLocationColumn, copyRow) = _
ThisWorkbook.Sheets("postHere").Cell(c + 1, row)
copyRow = copyRow+1
row = row + 1
Loop
End If
row = row + 1
Loop
End Sub
There are many logic errors to numerate in a comment, Excel highlights them automatically I'll do a summary explaining them:
1. Function can't be "in the middle" of the sub, finish the Sub (take the Function from the sub and paste until it says end sub.
2.array is a forbidden name, try with another variable name
3.For each =0 ? to array? what do you try to mean like that? For Each has to be element in something For each element in Array for example For and To are for something defined in numbers (for counter=1 to 15)
Function arrayContainsValue(***array***, varValue) '2nd problem
found = false
for each = 0 to array '3rd problem
if array(i) = varValue then
found = true
exit for
arrayContainsValue = found
End Function
....
4. you're missing a then at the end
if arrayContainsValue(arr, ThisWorkbook.Sheets("Data").Cell(column,row))
I don't get the coding logic on how relates to the problem stated (?)

Resources