I created an entry form that transposes data into a table.
I would like to check that all required cells are filled out before allowing the user to save the data.
I tried using a Range("A2:E2") but it didn't seem to work, so I entered every cell that I want to check.
I am having an issue where my IsEmpty = True Or _ statement seems to never be satisfied. Even if I enter data into every cell I am checking, the MsgBox is displayed, and the Else command is skipped.
After the Else is my Macro for saving the data in the table.
Any help appreciated. Thanks.
If IsEmpty(Range("A2").Value) = True Or _
IsEmpty(Range("B3").Value) = True Or _
IsEmpty(Range("C3").Value) = True Or _
IsEmpty(Range("D3").Value) = True Or _
IsEmpty(Range("E3").Value) = True Or _
IsEmpty(Range("C5").Value) = True Or IsEmpty(Range("C6").Value) = True Or IsEmpty(Range("C7").Value) = True Or IsEmpty(Range("C8").Value) = True Or IsEmpty(Range("C9").Value) = True Or IsEmpty(Range("C10").Value) = True Or IsEmpty(Range("C11").Value) = True Or _
IsEmpty(Range("E5").Value) = True Or IsEmpty(Range("E6").Value) = True Or IsEmpty(Range("E7").Value) = True Or IsEmpty(Range("E8").Value) = True Or IsEmpty(Range("E9").Value) = True Or IsEmpty(Range("E10").Value) = True Or IsEmpty(Range("E11").Value) = True Or _
IsEmpty(Range("G5").Value) = True Or IsEmpty(Range("G6").Value) = True Or IsEmpty(Range("G7").Value) = True Or IsEmpty(Range("G8").Value) = True Or IsEmpty(Range("G9").Value) = True Or IsEmpty(Range("G10").Value) = True Or IsEmpty(Range("G11").Value) = True Or _
IsEmpty(Range("H5").Value) = True Or IsEmpty(Range("H6").Value) = True Or IsEmpty(Range("H7").Value) = True Or IsEmpty(Range("H8").Value) = True Or IsEmpty(Range("H9").Value) = True Or IsEmpty(Range("H10").Value) = True Or IsEmpty(Range("H11").Value) = True Or _
IsEmpty(Range("I5").Value) = True Or IsEmpty(Range("I6").Value) = True Or IsEmpty(Range("I7").Value) = True Or IsEmpty(Range("I8").Value) = True Or IsEmpty(Range("I9").Value) = True Or IsEmpty(Range("I10").Value) = True Or IsEmpty(Range("I11").Value) = True Or _
IsEmpty(Range("J5").Value) = True Or IsEmpty(Range("J6").Value) = True Or IsEmpty(Range("J7").Value) = True Or IsEmpty(Range("J8").Value) = True Or IsEmpty(Range("J9").Value) = True Or IsEmpty(Range("J10").Value) = True Or IsEmpty(Range("J11").Value) = True Or _
IsEmpty(Range("K5").Value) = True Or IsEmpty(Range("K6").Value) = True Or IsEmpty(Range("K7").Value) = True Or IsEmpty(Range("K8").Value) = True Or IsEmpty(Range("K9").Value) = True Or IsEmpty(Range("K10").Value) = True Or IsEmpty(Range("K11").Value) = True Or _
IsEmpty(Range("L5").Value) = True Or IsEmpty(Range("L6").Value) = True Or IsEmpty(Range("L7").Value) = True Or IsEmpty(Range("L8").Value) = True Or IsEmpty(Range("L9").Value) = True Or IsEmpty(Range("L10").Value) = True Or _
IsEmpty(Range("L11").Value) = True _
Then
MsgBox "Please fill out all required cells before saving!"
Else
'''
Count Blank Cells
Returns a message box if one of the cells in the range is empty, in the first example, or blank, in the second example. Note that the only difference between the solutions is in a different parameter for the LookIn argument of the Find method: xlFormulas (empty) vs xlValues (blank).
I abandoned the Application.CountBlank idea because it doesn't work with non-contiguous ranges.
Empty Cells
Sub FindEmpty()
Dim rgAddress As String: rgAddress = "A2,B3:E3,C5:C11,E5:E11,G5:L11"
Dim ws As Worksheet: Set ws = ActiveSheet ' improve!
Dim fCell As Range: Set fCell = ws.Range(rgAddress).Find("", , xlFormulas)
If Not fCell Is Nothing Then
MsgBox "Please fill out all required cells before saving!"
Else
' Continue to save...
End If
End Sub
Blank Cells
Sub FindBlank()
' Blank cells are:
' 1. empty cells,
' 2. cells containing the formula '=""'
' 3. cells containing a single quote (')...
Dim rgAddress As String: rgAddress = "A2,B3:E3,C5:C11,E5:E11,G5:L11"
Dim ws As Worksheet: Set ws = ActiveSheet ' improve!
Dim fCell As Range: Set fCell = ws.Range(rgAddress).Find("", , xlValues)
If Not fCell Is Nothing Then
MsgBox "Please fill out all required cells before saving!"
Else
' Continue to save...
End If
End Sub
Bonus (if someone wants to play)
Sub PopulateRange()
Const rgAddress As String = "A2,B3:E3,C5:C11,E5:E11,G5:L11"
Dim ws As Worksheet: Set ws = ActiveSheet ' improve!
Dim cell As Range
Dim n As Long
For Each cell In ws.Range(rgAddress).Cells
n = n + 1
cell.Value = n
Next cell
End Sub
Related
On this page you check what sections will be part of the change order and then click the command button. (The checkboxes don't line up, I'll fix it later.)
Once you click the button I want to use VBA to change a template sheet to only show the tables associated with the boxes checked. Then the template sheet is copied and named based on entries.
The problem is that the unwanted tables are not hidden.
When I check just the first box that works, also checking all boxes works.
The tables look like this:
EDIT- After using debug it seems my tables are not being identified. For example the one I have as rng1 "laborhourly" is hiding rows 3-21 instead of 17-22
Also if I change it from
rng1.CurrentRegion.EntireRow.Hidden = False
to
rng1.EntireRow.Hidden = False
it does not hide extra rows, but the table header is still there.
Private Sub CommandButton1_Click()
Dim rng As Range
Dim ars As Areas
Set wb = Sheets("New Change Order Request")
Set ws = Sheets("RFCO")
ws.Range("1:60").EntireRow.Hidden = False
Set rng1 = ws.Range("laborhourly").CurrentRegion
Set rng2 = ws.Range("laborot").CurrentRegion
Set rng3 = ws.Range("laborprem").CurrentRegion
Set rng4 = ws.Range("equip").CurrentRegion
Set rng5 = ws.Range("rental").CurrentRegion
Set rng6 = ws.Range("subs").CurrentRegion
Set rng7 = ws.Range("materials").CurrentRegion
Set rng8 = ws.Range("other").CurrentRegion
If wb.Range("c10") = True Then
ws.Range("1:15").EntireRow.Hidden = False
rng1.CurrentRegion.EntireRow.Hidden = False
ws.CommandButton1.Visible = True
Else
rng1.EntireRow.Hidden = False
rng1.EntireRow.Hidden = True
ws.CommandButton1.Visible = False
End If
If wb.Range("c11") = True Then
ws.Range("1:15").EntireRow.Hidden = False
rng2.EntireRow.Hidden = False
ws.CommandButton2.Visible = True
Else
ws.Range("1:15").EntireRow.Hidden = False
rng2.EntireRow.Hidden = True
ws.CommandButton2.Visible = False
End If
If wb.Range("c12") = True Then
rng3.EntireRow.Hidden = False
ws.CommandButton3.Visible = True
Else
rng3.EntireRow.Hidden = False
ws.CommandButton3.Visible = True
End If
If wb.Range("c13") = True Then
rng4.EntireRow.Hidden = False
ws.CommandButton4.Visible = True
Else
rng4.EntireRow.Hidden = True
ws.CommandButton4.Visible = False
End If
If wb.Range("c14") = True Then
rng5.EntireRow.Hidden = False
Worksheets("RFCO").CommandButton5.Visible = True
Else
rng5.EntireRow.Hidden = True
ws.CommandButton5.Visible = False
End If
If wb.Range("c15") = True Then
ws.Range("1:15").EntireRow.Hidden = False
ws.Range("subs").CurrentRegion.EntireRow.Hidden = False
Worksheets("RFCO").CommandButton6.Visible = True
Else
ws.Range("subs").CurrentRegion.EntireRow.Hidden = True
ws.CommandButton6.Visible = False
End If
If wb.Range("c16") = True Then
rng7.EntireRow.Hidden = False
Worksheets("RFCO").CommandButton7.Visible = True
Else
rng7.EntireRow.Hidden = True
ws.CommandButton7.Visible = False
End If
If wb.Range("c17") = True Then
rng8.EntireRow.Hidden = False
Worksheets("RFCO").CommandButton8.Visible = True
Else
rng8.EntireRow.Hidden = True
ws.CommandButton8.Visible = False
End If
MsgBox ("DONE")
End Sub
Any time I enable the macro below, the worksheet corrupts.
I have copied and pasted my data into a brand new book.
Upon saving and re-opening, I receive the "Do you want to attempt to recover as much as we can?" dialog, and the formatting on the macro-enabled sheet is reset, and the macro disabled.
I see this in the VBA editor, which appears like "Sheet 2" is being treated as some unknown object, and gives "First Article" another sheet variable.
Can anyone help?
Private Sub Worksheet_Activate()
Dim vars As Variant
vars = Array("<CLICK FOR VARIANT LIST>", "sensitive content hidden")
Dim sVars As String
sVars = Join(vars, ",")
With Range("E6").Validation
.Delete
.Add Type:=xlValidateList, Formula1:=sVars
End With
vars = Array("NOT SET", "SET")
sVars = Join(vars, ",")
With Range("I6").Validation
.Delete
.Add Type:=xlValidateList, Formula1:=sVars
End With
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
Dim vars As Variant
vars = Array("<CLICK FOR VARIANT LIST>", "sensitive content hidden")
If Target.Address = Range("E6").Address Then
Dim i As Integer
i = Application.Match(Range("E6").Value, vars, False)
If i = 1 Then
Range("A11:A109").EntireRow.Hidden = True
Range("D111:D112").EntireRow.Hidden = False
Else
Range("A11:A109").EntireRow.Hidden = False
Range("D111:D112").EntireRow.Hidden = True
Range("A1").Value = i + 6
End If
'SXM/HD
If i = 0 _
Or Range("E6").Value = "sensitive content hidden" Then
Range("hd_sw_row").EntireRow.Hidden = False
Range("hd_pn_row").EntireRow.Hidden = False
Range("sxm_pn_row").EntireRow.Hidden = False
Range("sxm_function_row").EntireRow.Hidden = False
Else
Range("hd_sw_row").EntireRow.Hidden = True
Range("hd_pn_row").EntireRow.Hidden = True
Range("sxm_pn_row").EntireRow.Hidden = True
Range("sxm_function_row").EntireRow.Hidden = True
End If
'DAB
If i = 0 _
Or Range("E6").Value = "sensitive content hidden"
Then
Range("dab_sw_row").EntireRow.Hidden = False
Range("dab_pn_row").EntireRow.Hidden = False
Range("dab_function_row").EntireRow.Hidden = False
Else
Range("dab_sw_row").EntireRow.Hidden = True
Range("dab_pn_row").EntireRow.Hidden = True
Range("dab_function_row").EntireRow.Hidden = True
End If
'GPS
If i = 0 _
Or Range("E6").Value = "sensitive content hidden"
Then
Range("gps_sw_row").EntireRow.Hidden = False
Range("gps_pn_row").EntireRow.Hidden = False
Range("gps_function_row").EntireRow.Hidden = False
Else
Range("gps_sw_row").EntireRow.Hidden = True
Range("gps_pn_row").EntireRow.Hidden = True
Range("gps_function_row").EntireRow.Hidden = True
End If
End If
End Sub
I'm new to arrays and how to use them correctly. I keep getting MyArray(i,1) = subscript out of range and it highlights the rows, where I put in those asterisks.
I want to minimize line count and make it more efficient, so I can pull the same array into different pivot to filter.
Sub Macro1()
Dim MyArray() As Variant
Dim i As Integer
'Populate the array.
MyArray = Array("I1", "I2", "I3")
'Filter based off array values
For i = 1 To UBound(MyArray)
* ActiveSheet.PivotTables("PivotTable1").PivotFields("letters "). _
* CurrentPage = MyArray(i, 1)
Next i
End Sub
My old code that I'm trying to make more efficient is:
Sub Macro1()
Sheets("NonDomestic").PivotTables("PivotTable1").PivotFields("letters "). _
CurrentPage = "(All)"
With Sheets("NonDomestic").PivotTables("PivotTable1").PivotFields( _
"dir sales ship cust cot ")
.ClearAllFilters
.PivotItems("A1").Visible = False
.PivotItems("B1").Visible = False
.PivotItems("C1").Visible = False
.PivotItems("C2").Visible = False
.PivotItems("D1").Visible = False
.PivotItems("D2").Visible = False
.PivotItems("D3").Visible = False
.PivotItems("D4").Visible = False
.PivotItems("D5").Visible = False
.PivotItems("D6").Visible = False
.PivotItems("D7").Visible = False
.PivotItems("E1").Visible = False
.PivotItems("F1").Visible = False
.PivotItems("F2").Visible = False
.PivotItems("F3").Visible = False
.PivotItems("F4").Visible = False
.PivotItems("F5").Visible = False
.PivotItems("F6").Visible = False
.PivotItems("F7").Visible = False
.PivotItems("G1").Visible = False
.PivotItems("G2").Visible = False
.PivotItems("G3").Visible = False
.PivotItems("G4").Visible = False
.PivotItems("G5").Visible = False
.PivotItems("H1").Visible = False
.PivotItems("H3").Visible = False
.PivotItems("H4").Visible = False
'.PivotItems("I1").Visible = False
'.PivotItems("I2").Visible = False
'.PivotItems("I3").Visible = False
End With
On Error GoTo 0
CurrentPage is intended to show only 1 PivotItem of your filter.
If you have a list of visible/unvisible PivotItems, then set them individually visible, addressing them by their name or by their index.
Private Sub PivotFilterTest()
Dim pf As PivotField
Dim myArray() As Variant
Dim i As Long
myArray = Array("I1", "I2", "I3")
Set pf = ActiveSheet.PivotTables("PivotTable1").PivotFields("letters ")
With pf
.ClearManualFilter
.EnableMultiplePageItems = True
For i = LBound(myArray) To UBound(myArray)
.PivotItems(myArray(i)).Visible = False
Next i
End With
End Sub
What I'm trying to do is use a multiple checkbox form to set filter values based on a table in my "Projects" worksheet. I've been able to successfully get this working on individuals however what I need this to do is take any combination of currently 33 checkboxes to filter rows that meet all criteria selected. Below is what I currently have and it keep kicking back on the range. My range runs columns K:AQ which equal values of 11 to 43 as you'll see below.
Private Sub FilterButton_Click()
Dim wb As Workbook: Set wb = ThisWorkbook
Dim ws As Worksheet
Set ws = wb.Sheets("Projects")
Dim fld As Long
For fld = 11 To 43
Next
If frmSearch.CheckBox1 = True = True Or _
frmSearch.CheckBox2 = True Or frmSearch.CheckBox3 = True Or _
frmSearch.CheckBox4 = True Or frmSearch.CheckBox5 = True Or _
frmSearch.CheckBox6 = True Or frmSearch.CheckBox7 = True Or _
frmSearch.CheckBox8 = True Or frmSearch.CheckBox9 = True Or _
frmSearch.CheckBox10 = True Or frmSearch.CheckBox11 = True Or _
frmSearch.CheckBox12 = True Or frmSearch.CheckBox13 = True Or _
frmSearch.CheckBox14 = True Or frmSearch.CheckBox15 = True Or _
frmSearch.CheckBox16 = True Or frmSearch.CheckBox17 = True Or _
frmSearch.CheckBox18 = True Or frmSearch.CheckBox19 = True Or _
frmSearch.CheckBox20 = True Or frmSearch.CheckBox21 = True Or _
frmSearch.CheckBox22 = True Or frmSearch.CheckBox23 = True Or _
frmSearch.CheckBox24 = True Or frmSearch.CheckBox25 = True Or _
frmSearch.CheckBox26 = True Or frmSearch.CheckBox27 = True Or _
frmSearch.CheckBox28 = True Or frmSearch.CheckBox29 = True Or _
frmSearch.CheckBox30 = True Or frmSearch.CheckBox31 = True Or _
frmSearch.CheckBox32 = True Or frmSearch.CheckBox33 = True Then
ws.Range("K2:AQ1500").AutoFilter Field:="fld", Criteria1:="<>"
End If
End Sub
So I don't know what your UserForm looks like, but if you can, I would suggest moving these CheckBoxes to a Frame so you can loop through them much easier... like this:
Private Sub FilterButton_Click()
Dim wb As Workbook: Set wb = ThisWorkbook
Dim ws As Worksheet
Set ws = wb.Sheets("Projects")
Dim i As Integer
' For each child control in the frame
For i = 0 To Frame1.Controls.Count - 1
' If the child control is a check box
If TypeOf Frame1.Controls.Item(i) Is CheckBox Then
' If the CheckBox is checked
If Frame1.Controls.Item(i).Value Then
'Your code here...
Debug.Print (i & " " & Frame1.Controls.Item(i).Name)
End If
End If
Next i
End Sub
As for applying the filter, it sounds like each checkbox should be linked to a column in your range... (meaning Checkbox1 ==> 'K'?) I would do that like this: (replacing the 'your code here' from above)
' Add a filter to the column at the index of 'i' (+1 so we aren't using base 0)
ws.Range("K2:AQ1500").AutoFilter Field:=i + 1, Criteria1:="<>"
Please, if you don't understand the code, ask! I'm more than happy to explain anything. Remember that copy/paste doesn't teach! :D
Does your code not have too many "True" at the If frmSearch.CheckBox1 = True = True
part?
Try below.
Private Sub FilterButton_Click()
Dim wb As Workbook: Set wb = ThisWorkbook
Dim ws As Worksheet
Set ws = wb.Sheets("Projects")
Dim fld As Long
For fld = 11 To 43
Next
If frmSearch.CheckBox1 = True Or _
frmSearch.CheckBox2 = True Or frmSearch.CheckBox3 = True Or _
frmSearch.CheckBox4 = True Or frmSearch.CheckBox5 = True Or _
frmSearch.CheckBox6 = True Or frmSearch.CheckBox7 = True Or _
frmSearch.CheckBox8 = True Or frmSearch.CheckBox9 = True Or _
frmSearch.CheckBox10 = True Or frmSearch.CheckBox11 = True Or _
frmSearch.CheckBox12 = True Or frmSearch.CheckBox13 = True Or _
frmSearch.CheckBox14 = True Or frmSearch.CheckBox15 = True Or _
frmSearch.CheckBox16 = True Or frmSearch.CheckBox17 = True Or _
frmSearch.CheckBox18 = True Or frmSearch.CheckBox19 = True Or _
frmSearch.CheckBox20 = True Or frmSearch.CheckBox21 = True Or _
frmSearch.CheckBox22 = True Or frmSearch.CheckBox23 = True Or _
frmSearch.CheckBox24 = True Or frmSearch.CheckBox25 = True Or _
frmSearch.CheckBox26 = True Or frmSearch.CheckBox27 = True Or _
frmSearch.CheckBox28 = True Or frmSearch.CheckBox29 = True Or _
frmSearch.CheckBox30 = True Or frmSearch.CheckBox31 = True Or _
frmSearch.CheckBox32 = True Or frmSearch.CheckBox33 = True Then
ws.Range("K2:AQ1500").AutoFilter Field:="fld", Criteria1:="<>"
End If
End Sub
Dim ConsolidateSheetObj As Workbook
Dim str As String
Dim keycount,row As Interger
Set ConsolidateSheetObj = Workbooks.open("filePath")
Set str = ConsolidateSheetObj.Sheets(3).Cells(row, 17 + keycount).Value
If str.IsEmpty() Then
. . .
...
End If
Coercing to a string and checking its length is a poor way to do this. Additionally, your using Set str is syntatically invalid: Set is only used for object types.
A better way is:
Dim v as Variant
v = ConsolidateSheetObj.Sheets(3).Cells(row, 17 + keycount).Value
If VarType(v) = vbEmpty Then
'this is an empty range
End If
Sub checkEmpty()
'Used variables
Dim filePath As String
Dim sheet, row, keycount As Integer
Dim cellEmpty As Boolean
'Disable Screen updates
Application.ScreenUpdating = False
filePath = "C:\Your_file.xlsx"
sheet = 3
row = 3
keycount = 2
cellEmpty = False
'Open other workbook
Workbooks.Open Filename:= _
filePath
'Check if cell is empty
If isEmpty(Sheets(sheet).Cells(row, 17 + keycount)) Then
cellEmpty = True
End If
'Close other workbook
Application.DisplayAlerts = False
ActiveWorkbook.Close SaveChanges:=No
If cellEmpty Then
MsgBox ("Cell is Empty!")
'...Your Code here!
End If
'Enable Screen updates
Application.ScreenUpdating = True
End Sub