Hide a column if corresponding cell "is blank"/"formula is null" upon sheet's activation - vba

I am new to VBAing but have a small amount of javascript knowledge and hoping for a bit of guidance/help as I can't seem to get the code working. There's probably some glaring mistakes so thanks for the patience.
I'm trying to get a spreadsheet to update a sheet upon that sheet's activation, where it will hide columns whose 2nd row cell is "blank" (or the formula x(y) in the cell is null).
Below is what have tried so far.
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
If Sh.Name = "FSM" Then
Function hideBlankColumns()
i = 2
For i = 2 To 30
If IsNull(Cells(2, i).Value) = True Then
Columns(i).EntireRow.Hidden = True
Else: Columns(i).EntireRow.Hidden = False
End If
Next i
End Function
End If
End Sub
Thanks in advance!

You have three errors in your code:
you cannot define a function inside another sub.
you are talking about hiding/unhiding columns, but in the code you hide rows: Columns(lCol).EntireRow.Hidden = True
function IsNull always returns False if you pass Excel cell or its value as a parameter. In this case you should use function IsEmpty instead.
This code should work properly:
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
Dim i As Integer
If Sh.Name = "FSM" Then
For i = 2 To 30
Columns(i).EntireColumn.Hidden = IsEmpty(Cells(2, i).value)
Next i
End If
End Sub

Try something like this.
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
If Sh.Name = "FSM" Then
lCol = 2
Do While lCol <= ws.UsedRange.Columns.count
If IsNull(Cells(2, lCol).Value) = True Then
Columns(lCol).EntireColumn.Hidden = True
Else
Columns(lCol).EntireColumn.Hidden = False
End If
lCol = lCol + 1
Loop
End if
End sub

Related

Macro fires 50% of the time when changing slicer item

I have a particular problem and couldn't find any solution anywhere on the internet.
So I have a pivot table which is connected to 6 slicers and also a chart which data range is dependent on pivot table values.
I've made a macro which updates chart scales everytime a value in any of the worksheet cells is changed. Here is the macro:
Public Sub worksheet_Change(ByVal Target2 As Range)
If ActiveSheet.Name = "Dashboard" Then
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.DataEntryMode = xlOff
'Chart_axis Macro
Sheets("Dashboard").ChartObjects("Chart 9").Activate
If ActiveSheet.Range("B19") = "excluding CE" Then
ActiveChart.Axes(xlValue).MinimumScale = Range("E3").Value
ActiveChart.Axes(xlValue).MaximumScale = Range("E4").Value
Else
ActiveChart.Axes(xlValue).MinimumScale = Range("A3").Value
ActiveChart.Axes(xlValue).MaximumScale = Range("A4").Value
End If
ActiveChart.Refresh
ActiveSheet.Range("B18").Select
Application.EnableEvents = True
Application.ScreenUpdating = True
End If
End Sub
In order to work as intended i also had to made a function which reads the active elements of a slicer:
Public Function GetSelectedSlicerItems(SlicerName As String) As String
Application.Volatile
Set coll = New Collection
Dim cache As Excel.SlicerCache
Dim i As Integer
Set cache = ActiveWorkbook.SlicerCaches(SlicerName)
Dim sItem As Excel.SlicerItem
Dim result As String
For Each sItem In cache.SlicerItems
If sItem.Selected And sItem.HasData Then
'Debug.Print sItem.Name
'Debug.Print sItem.HasData
'GetSelectedSlicerItems = (sItem.Name)
coll.Add sItem.Name
End If
Next sItem
For i = 1 To coll.Count
'Debug.Print coll(i)
result = result & coll(i) & ", "
Next i
result = Left(result, Len(result) - 2)
GetSelectedSlicerItems = result
End Function
My problem is that while the value of the function always updates when the slicer item is changed, the macro only does it randomly about 50% of the time.
Screenshot of my report:
The formulas containing the selected slicer items function are on the top right.
So do you have any idea how to make it work 100% of the time?
Thanks in advance,
Alan
Edit: i forgot to add that it's only the issue if only one slicer is highlited. When i select multiple slicers (with ctrl+click) it always works.

If condition associated with applying a column filter

I'm trying to use an if-condition regarding filters. I wish I could write a code to check if a specific filter is applied and then do something... (of course)
My first attempt was:
If ActiveSheet.Range("$D$4:$Q$20").AutoFilter Field:=2 then
Rows("22:22").Select
Selection.EntireRow.Hidden = True
End If
In the very first line, VBA doesn't accept the condition that is written...
Any guess?
tks
This will tell you if a range is in a filter and the filter is active:
Public Function IsFilterOn(rng As Range) As Boolean
Dim ws As Worksheet
Dim iFilterNum As Integer
Set ws = rng.Parent
If Not ws.AutoFilter Is Nothing Then
If Not Application.Intersect(rng, ws.AutoFilter.Range) Is Nothing Then
With ws.AutoFilter.Filters
iFilterNum = rng.Column - .Item(1).Parent.Range.Column + 1
If iFilterNum <= .Count Then
IsFilterOn = .Item(iFilterNum).On
Exit Function
End If
End With
End If
End If
End Function
Note that you don't need to select a row before hiding it.
Sub HideWhenFiltered()
With ActiveSheet
If .AutoFilterMode Then
If .AutoFilter.Filters(2).On Then
.Rows(22).Hidden = True
End If
End If
End With
End Sub

If Range EntireRow.Hidden

I would really appreciate your help with following issue I am facing.
I want 3 rows to be hidden unless something is written in a specific cell.
If something is written in the specific cell I want the next row to become unhidden. And so it suppose to continue with the next two cells.
I have written the following code in th module, please guide me on how to solve this (what am I doing wrong?)
Sub InsertRow()
If Range("U6") <> "" Then
Rows("7").EntireRow.Hidden = False
Rows("8:9").EntireRow.Hidden = True
End If
End Sub
Not sure if this is what you want, but this goes through all used cells in col U and checks rows beneath
Public Sub InsertRow()
Dim targetCol As Range, itm As Range
Set targetCol = Worksheets("Sheet1").UsedRange.Columns(21) 'UsedRange starts at A1
Application.ScreenUpdating = False 'Update sheet name and column number
For Each itm In targetCol.Cells
itm.Offset(1).EntireRow.Hidden = (Len(itm.Value2) = 0)
Next
Application.ScreenUpdating = True
End Sub
Try this solution:
Sub InsertRow()
Rows("7").EntireRow.Hidden = Range("U6") = ""
Rows("8:9").EntireRow.Hidden = True
End Sub

speed up Excel off-sheet dependents search

I've incorporated the off-sheet dependents search using the "ShowDependents" and "NavigateArrow" VBA methods. Everything works well but it is just painfully slow (for a large number of dependents).
Are there alternatives, way to speed it up? I've tried disabling the ScreenUpdating but that doesn't speed it up by much.
This is what my code is based on: http://www.technicana.com/vba-for-checking-dependencies-on-another-sheet
Consider the following function which is supposed to return true if the cell you pass it has a direct dependent on a different sheet:
Function LeadsOut(c As Range) As Boolean
Application.ScreenUpdating = False
Dim i As Long, target As Range
Dim ws As Worksheet
Set ws = ActiveSheet
c.ShowDependents
On Error GoTo return_false
i = 1
Do While True
Set target = c.NavigateArrow(False, i)
If c.Parent.Name <> target.Parent.Name Then
ws.Select
ActiveSheet.ClearArrows
Application.ScreenUpdating = True
LeadsOut = True
Exit Function
End If
i = i + 1
Loop
return_false:
LeadsOut = False
ActiveSheet.ClearArrows
Application.ScreenUpdating = True
End Function
Sub test()
MsgBox LeadsOut(Selection)
End Sub
To test it, I linked the test sub to a command button on Sheet1.
In A2 I entered the formula = A1 + 1, with no other formulas on Sheet1.
On Sheet2 I entered the formula =Sheet1!A2.
Back on Sheet1, if I select A2 and invoke the sub it almost instantly pops up "True". But if I select A1 and invoke the sub it returns "False" -- but only after a delay of several seconds.
To debug it, I put a Debug.Print i right before i = i + 1 in the loop. The Immediate Window, after running it again, looks like:
32764
32765
32766
32767
Weird!!!!!
I was utterly stumped until I replaced Debug.Print i by
Debug.Print target.Address(External:=True)
Which led to output that looks ends like:
[dependents.xlsm]Sheet1!$A$1
[dependents.xlsm]Sheet1!$A$1
[dependents.xlsm]Sheet1!$A$1
[dependents.xlsm]Sheet1!$A$1
NavigateArrow(False,i) goes back to the originating cell and stays there once i exceeds the number of dependents! This is seemingly undocumented and massively annoying. The code you linked to was written by someone who hasn't discovered this. As a kludge, you should check that when you are navigating arrows you haven't returned to the starting point. The following seems to work almost instantly in all cases, although I haven't tested it very much:
Function LeadsOut(c As Range) As Boolean
Application.ScreenUpdating = False
Dim i As Long, target As Range
Dim ws As Worksheet
Set ws = ActiveSheet
c.ShowDependents
On Error GoTo return_false
i = 1
Do While True
Set target = c.NavigateArrow(False, i)
If target.Address(External:=True) = c.Address(External:=True) Then
GoTo return_false
End If
If c.Parent.Name <> target.Parent.Name Then
ws.Select
ActiveSheet.ClearArrows
Application.ScreenUpdating = True
LeadsOut = True
Exit Function
End If
i = i + 1
Loop
return_false:
LeadsOut = False
ActiveSheet.ClearArrows
Application.ScreenUpdating = True
End Function
The key lines are the three lines which begin
If target.Address(External:=True) = c.Address(External:=True)
Adding some such check in the sub you linked to should make a massive difference.

Vba macro excel: How to hide rows if cell equal FALSE

I have a project which requires Excel to hide rows on a separate sheet(within the same workbook) after user selects specific options on the activesheet. The macro is linked to a button, when clicked rows will be hidden on the separate sheet, and the whole process occurs in the background. If the user want to check the table with hidden rows they'd need to navigate to that separate sheet to see the result.
Image explanation:
http://postimg.org/image/ek6981vg1/
Worksheets("Input- Select Pens") --> active sheet where has the button
Worksheets("Input- Pen") --> separate sheet where has the hidden rows
I have tried several methods, but none of them worked:
Method 1:
Sub selectPens()
Dim c As Range
Application.EnableEvents = False
On Error Resume Next
For Each c In Range("E6:E35")
If c.Value = "FALSE" Then
Worksheets("Input- Pen").c.EntireRow.Hidden = True
ElseIf c.Value = "TRUE" Then
Worksheets("Input- Pen").c.EntireRow.Hidden = False
End If
Next c
On Error GoTo 0
Application.EnableEvents = True
End Sub
Method 2:
Sub selectPens()
Dim i As Long
Set wselect = Sheet11
With wselect
For i = 6 To 35
If ActiveSheet.Cells(i, 5).Value = "FALSE" Then
.Range("i:i").EntireRow.Hidden = True
' .Rows(i).EntireRow.Hidden = True
ElseIf ActiveSheet.Cells(i, 5).Value = "TRUE" Then
' .Rows(i).EntireRow.Hidden = False
.Range("i:i").EntireRow.Hidden = False
End If
Next i
End With
End Sub
I would be greatly appreciated for any help.
Many thanks!
Sub selectPens()
Dim i As Long, wsselect
Set wselect = Sheet11
For i = 6 To 35
'EDIT
wselect.Rows(i).Hidden = (ActiveSheet.Cells(i, 5).Value = False)
Next i
End Sub