• Hi All

    Please note that at the Chandoo.org Forums there is Zero Tolerance to Spam

    Post Spam and you Will Be Deleted as a User

    Hui...

  • When starting a new post, to receive a quicker and more targeted answer, Please include a sample file in the initial post.

Hide Check boxes if cells are blank

Hi Friends,

I am trying to do the following two things:
- Hide checkbox if either one of the cell in column A or C is blank
- If applied filter in column B and selected only cells with "XYZ" value (i.e. hide rows with "-") then the check boxes in respective rows should also get hidden

I have attached a sample file in which i am trying to add the above features. Please note that the check boxes are VBA coded to strike through the cell content if checked.

Many thanks in advance,
Manish
 

Attachments

Right click the sheet's tab, View Code, and paste for the first code block. There is code after that that goes into a Module. I tend to code with Dim and use routines more modular than some because I am lazy and help many with similar needs.

For your 2nd item about filter, if you filter by XYZ then all rows in that column are hidden <> XYZ. Were you wanting a macro to do the autofilter? Normally, one would just do that manually but some like more control.

As I explained in your other thread, I coded this so that if you cut and paste back your A and C columns, it will hide/show the checkbox form controls as you wanted. From then on, a one cell change columns A or C below row 1 will trigger it again.

Code:
Private Sub Worksheet_Change(ByVal Target As Range)
  Dim r As Range, c As Range, calc As Integer
  Dim lr As Long, s As Shape, a, sa, pos As Long
  Dim i As Long
  On Error GoTo TheEnd
  Set r = StripFirstRow(ActiveSheet.UsedRange)
  Set r = Intersect(Union(Columns("A"), Columns("C")), Target)
  If r Is Nothing Then Exit Sub
  With Application
    .ScreenUpdating = False
    .EnableEvents = False
    calc = .Calculation
    .Calculation = xlCalculationManual
  End With
  'Make 2 arrays to hold shape names and topleftcell address
  ReDim a(1 To Shapes.Count)
  sa = a
  For Each s In Shapes
    i = i + 1
    sa(i) = s.Name
    a(i) = s.TopLeftCell.Address
  Next s
  'Iterate each cell change in the target range.
    'Set shape in target row's column D to visible or not.
  For Each c In r
    lr = c.Row
    pos = PosInArray(Cells(lr, "E").Address, a)
    If c.Value = "" Then
      If pos > 0 Then Shapes(sa(pos)).Visible = msoFalse
      Else
      If Cells(lr, "A").Value <> "" And Cells(lr, "C").Value <> "" And _
        pos > 0 Then Shapes(sa(pos)).Visible = msoTrue
    End If
  Next c
TheEnd:
  With Application
    .ScreenUpdating = True
    .EnableEvents = True
    .Calculation = calc
    .CutCopyMode = False
  End With
End Sub

Module code:
Code:
Function StripFirstRow(aRange As Range) As Range
  Dim i As Long, j As Long, r As Range, z As Long, idx As Long
  For i = 1 To aRange.Areas.Count
    For j = 1 To aRange.Areas(i).Rows.Count
      z = z + 1
      If z = 1 Then GoTo NextJ
      If r Is Nothing Then
        Set r = aRange.Areas(i).Rows(j)
        Else
        Set r = Union(r, aRange.Areas(i).Rows(j))
      End If
NextJ:
    Next j
  Next i
  Set StripFirstRow = r
End Function

'If array is 0 based, 1 is returned if aValue matches anArray(0).
Function PosInArray(aValue, anArray)
  Dim pos As Long
  On Error Resume Next
  pos = -1
  pos = WorksheetFunction.Match(CStr(aValue), anArray, 0)
  PosInArray = pos
End Function
 
Last edited:
Right click the sheet's tab, View Code, and paste for the first code block. There is code after that that goes into a Module. I tend to code with Dim and use routines more modular than some because I am lazy and help many with similar needs.

For your 2nd item about filter, if you filter by XYZ then all rows in that column are hidden <> XYZ. Were you wanting a macro to do the autofilter? Normally, one would just do that manually but some like more control.

As I explained in your other thread, I coded this so that if you cut and paste back your A and C columns, it will hide/show the checkbox form controls as you wanted. From then on, a one cell change columns A or C below row 1 will trigger it again.

Code:
Private Sub Worksheet_Change(ByVal Target As Range)
  Dim r As Range, c As Range, calc As Integer
  Dim lr As Long, s As Shape, a, sa, pos As Long
  Dim i As Long
  On Error GoTo TheEnd
  Set r = StripFirstRow(ActiveSheet.UsedRange)
  Set r = Intersect(Union(Columns("A"), Columns("C")), Target)
  If r Is Nothing Then Exit Sub
  With Application
    .ScreenUpdating = False
    .EnableEvents = False
    calc = .Calculation
    .Calculation = xlCalculationManual
  End With
  'Make 2 arrays to hold shape names and topleftcell address
  ReDim a(1 To Shapes.Count)
  sa = a
  For Each s In Shapes
    i = i + 1
    sa(i) = s.Name
    a(i) = s.TopLeftCell.Address
  Next s
  'Iterate each cell change in the target range.
    'Set shape in target row's column D to visible or not.
  For Each c In r
    lr = c.Row
    pos = PosInArray(Cells(lr, "E").Address, a)
    If c.Value = "" Then
      If pos > 0 Then Shapes(sa(pos)).Visible = msoFalse
      Else
      If Cells(lr, "A").Value <> "" And Cells(lr, "C").Value <> "" And _
        pos > 0 Then Shapes(sa(pos)).Visible = msoTrue
    End If
  Next c
TheEnd:
  With Application
    .ScreenUpdating = True
    .EnableEvents = True
    .Calculation = calc
    .CutCopyMode = False
  End With
End Sub

Module code:
Code:
Function StripFirstRow(aRange As Range) As Range
  Dim i As Long, j As Long, r As Range, z As Long, idx As Long
  For i = 1 To aRange.Areas.Count
    For j = 1 To aRange.Areas(i).Rows.Count
      z = z + 1
      If z = 1 Then GoTo NextJ
      If r Is Nothing Then
        Set r = aRange.Areas(i).Rows(j)
        Else
        Set r = Union(r, aRange.Areas(i).Rows(j))
      End If
NextJ:
    Next j
  Next i
  Set StripFirstRow = r
End Function

'If array is 0 based, 1 is returned if aValue matches anArray(0).
Function PosInArray(aValue, anArray)
  Dim pos As Long
  On Error Resume Next
  pos = -1
  pos = WorksheetFunction.Match(CStr(aValue), anArray, 0)
  PosInArray = pos
End Function

It is working beautifully. Thanks a lot Kenneth for your time and help.

Regards,
 
Back
Top