How can I un-hide hidden rows in a table in Excel? - excel

I made a code to hide some rows using .hidden = True that I don't need to show to make some checks, but I after that I want to show all the data again, so I made this code:
Sub show_hidden_cells()
Dim line As Range
Dim rng As Range
Set rng = Range("Tb_Data[Date]")
For Each line In rng
If line.SpecialCells(xlCellTypeVisible) = False Then
line.EntireRow.Hidden = False
End If
Next line
End Sub
My data has 50.000 rows and my computer it's not really fast, so I don't want to check every cell if is visible, instead of that I want to select only the hidden cells.
EDIT.
Thanks to #Rory and #Flephal who helped me my code now is:
Sub show_hidden_cells()
Dim rng As Range
Set rng = Range("Tb_Data[Date]")
rng.EntireRow.Hidden = False
End Sub

Related

Copy_Paste_Visible_Cells_Only

I have been trying to Copy the Filtered data and pasting the data on filtered cell but my code is not working.
I have data in Range Sheet2.Range("O2:O10000") and i filtered this range to Sheet2.Range("O173:O2400").
I want to copy the data from filtered cells Sheet2.Range("O173:O2400") then paste this data to visible cells on same Sheet2.Range("N173:N2400")
Please note there are multiple hidden rows in this range.
Any help will be appreciated
Sub Copy_Paste__Visible_Cells_Only()
Sheet2.Range("O173:O2400").SpecialCells(xlCellTypeVisible).Copy
Sheet2.Range("N173:N2400").SpecialCells(xlCellTypeVisible).Paste
End Sub
In this case, pasting won't work. As far as I know, you can't change the paste behaviour to only paste to visible cells.
When you select visible cells only, you get a collection of areas (you can think of them as a discontinuous set of ranges). Given you're just trying to move your visible data to the left, you can do it by looping through the areas and assigning their values to the same area in the previous column. Something like this:
Public Sub CopyVisible()
Dim a As Range
For Each a In Sheet1.Range("O4:O17").SpecialCells(xlCellTypeVisible).Areas
a.Offset(0, -1).Value = a.Value
Next
End Sub
The .Offset(0,-1) is signalling that you wish the values to be moved one column to the left
You can see from this example, when I filter on "a" in column O and run the macro, only the "a" values are moved to column N.
I would use a generic sub copyVisibleCellsToOtherColumn to which you pass the source-range and the target-start range.
Advantage you can re-use it for different scenarios.
Sub test_CopyVisibleCells()
Dim rgSource As Range
Set rgSource = sheet2.Range("O173:O2400")
Dim rgTarget As Range
Set rgTarget = sheet2.Range("N173:02400")
copyVisibleCells rgSource, rgTarget
End Sub
'this ist the generic sub
Public Sub copyVisibleCellsToOtherColumn(rgSource As Range, rgTarget As Range)
Dim c As Range, a As Range
For Each a In rgSource.Areas
'this will return the visible cells within rgsource
For Each c In a.Cells
rgTarget.Rows(c.Row).Value = c.Value
Next
Next
End Sub
I found code from somewhere which able to copy visible cells and paste into visible cells. For easy usage, I manually assign a shortcut ctrl+shift+C to call the macro.
Public Sub Copy_Range_Paste_Into_Visible_Cells()
'Sub Copy_Range_Paste_Into_Visible_Cells()
Dim rngSource As Range, rngDestination As Range, cell As Range, cc As Long, i As Long
On Error Resume Next
Application.DisplayAlerts = False
Set rngSource = Application.InputBox("Select the filtered range to copy. ", "Select Filtered Cells", Type:=8)
If rngSource Is Nothing Then Application.DisplayAlerts = True: Exit Sub 'User canceled
Set rngDestination = Application.InputBox("Select the destination cell to paste to. ", "Select Paste Destination", Type:=8)
If rngDestination Is Nothing Then Application.DisplayAlerts = True: Exit Sub 'User canceled
On Error GoTo 0
Application.DisplayAlerts = True
cc = rngSource.Columns.Count
For Each cell In rngSource.Columns(1).SpecialCells(xlCellTypeVisible)
Do Until Not rngDestination(1).Offset(i).EntireRow.Hidden
i = i + 1
Loop
rngDestination(1).Offset(i).Resize(1, cc).Value = cell.Resize(1, cc).Value
i = i + 1
Next
End Sub

using VBA to find the last row of a merged cell

I am trying to use find the last row of a merged cell with text and hide all rows beside that
For example:
A1:A5 is a merged cell with text "A", A6:A10 is a merged cell with text "B", etc
I want to write a code that would find the last row of the merged cell with text "B", and would hide any rows above or below the merged cell.
At the moment I am defining the rows to hide manually, but these change frequently so my method is not very efficient.
Any suggestions on how to find the last row instead?
Sub FindLastRow()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Test")
'Hide all rows above B
ws.Rows("1:5").EntireRow.Hidden = True
'Hide all rows below B
ws.Rows("11:80").EntireRow.Hidden = True
End Sub
I guess you could try the following, making use of Range.Find and Range.MergeArea:
Sub Test()
Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets("Test")
Dim fullRng As Range, fndRng As Range
Set fullRng = ws.Range("A1:A80")
Set fndRng = ws.Range("A1:A80").Find(What:="B", Lookat:=xlWhole)
If Not fndRng Is Nothing Then
fullRng.Rows.Hidden = True
fndRng.MergeArea.Rows.Hidden = False
End If
End Sub

Hide all Rows except matching value

I'm working with some data in excel spanning B9:AJ1108 - so multiple rows and columns. I am looking to hide all rows except where the value in column B matches the number in cell C5.
I've tried multiple and can only just about get everything to hide but the unhiding is the issue. I understand how to hide all and how to unhide all. What I need help with is how to hide all and then unhide if something matches the value in C5.
Code so far:
Private Sub CommandButton2_Click()
Worksheets("Employee information").Range("B9:B1108").Rows.Hidden = False
End Sub
Private Sub CommandButton1_Click()
Worksheets("Employee information").Range("B9:B1108").Rows.Hidden = True
'Need to put in the argument to search for C5 value
End Sub
I would also like this to be button controlled but I don't know if that is a case of creating a module or just code within the sheet?
For unhiding the rows you can use "Rows.EntireRow.Hidden = False"
If you want to use a button for the macro to get executed, create a button and excel will ask you which macro you want to get when you click the button.
value= Worksheets("Employee information").cells(5,3).value
That will give you the value of the cell C5, now you need to go through the rows and look for this value.
Hide Rows Not Containing Criteria in Column
Private Sub CommandButton1_Click()
With Worksheets("Employee information")
' Define Criteria (restrict to numbers).
Dim Criteria As Variant
Criteria = .Range("C5").Value
If Not IsNumeric(Criteria) Then
Exit Sub
End If
' Define Criteria Range.
Dim rng As Range
Set rng = .Range("B9:B1108")
End With
' Declare additional variables.
Dim hRng As Range ' Hide Range
Dim cel As Range ' Current Cell (in Source Range)
Dim CurVal As Variant ' Current Value (of Current Cell in Source Range)
' Create a union (Hide Range) of all the cell ranges
' that do not contain Criteria.
For Each cel In rng.Cells
' Evaluate Current Value.
CurVal = cel.Value
If IsNumeric(CurVal) Then
If CurVal = Criteria Then
GoTo NextCell ' Match found: do nothing.
End If
End If
' Match not found: add Current Cell to Hide Range.
If Not hRng Is Nothing Then
Set hRng = Union(hRng, cel)
Else
Set hRng = cel
End If
NextCell:
Next cel
' Hide rows of Hide Range.
If Not hRng Is Nothing Then
hRng.Rows.Hidden = True
End If
End Sub

Hide rows based on cells contaning all zeroes or no values

I have a dataset where every row is a General Ledger (GL) account and in each column there is the value for the relevant period.
I would like to hide all GL accounts (rows) where no values (or zero values) are included for all periods (columns).
The code below seems to work for the "No values".
How do I hide all the rows with only zeroes (or all rows with zeroes or "no values"?
If one period has an amount, the row shouldn't be hidden.
Sub hide()
Dim c As Range
For Each c In Range("A1:F6")
If c.Value = "" Then
c.EntireRow.Hidden = True
Else
c.EntireRow.Hidden = False
End If
Next c
End Sub
Furthermore once any amounts change in a row this code should also make the unhidden rows reappear. At this moment it hides a row that has no value, but once this changes, the hidden row doesn't reappear anymore.
See code below if you want to test for both all blanks or all zeros and hide row if either present. Starts with an unhide of all rows.
Sub hide()
Dim wb As Workbook
Dim ws As Worksheet
Dim c As Range
Dim targetRange As Range
Set wb = ThisWorkbook
Set ws = wb.Sheets("Sheet5")
Set targetRange = ws.Range("A1:F6")
targetRange.EntireRow.Hidden = False
For Each c In targetRange.Rows
If (WorksheetFunction.CountIf(c,"<>0") - WorksheetFunction.CountIf(c,"") = 0) And (WorksheetFunction.CountA(c) - WorksheetFunction.Count(c) = 0) Then
c.EntireRow.Hidden = True
End If
Next c
End Sub
You have to check every row completely before deciding if to hide it or not. Currently, the last cell of every row decided if a row is hidden.
Give the following code a try. It sets a range to all cells of a row and uses the function CountA to count number of cells that are not empty.
Sub hide()
Dim ws As Worksheet, row As Long
Set ws = ActiveSheet
With ws
For row = 1 To 6
Dim myRange As Range
Set myRange = .Range(.Cells(row, 1), .Cells(row, 6))
.Rows(row).EntireRow.Hidden = (Application.WorksheetFunction.CountA(myRange) = 0)
Next row
End With
End Sub

Hide/show row code speed

Goal: Efficiently show/hide rows based on the data in the row.
Create a helper column that determines whether or not
a row should be hidden.
Have the formula in the helper
column return an error or a number.
Hide the helper column and write
code to execute the hiding/showing.
Question: Which one of the following methods would you expect to be faster? Column B is the helper column and will always be contiguous.
Sub SetRowVisibility1()
Dim rowsToCheck As Range
With ActiveSheet
Set rowsToCheck = .Range(Range("B7"), Range("B7").End(xlDown))
End With
Dim needToShow As Range, needToShow_Showing As Range
Dim needToHide As Range, needToHide_Showing As Range
Set needToShow = rowsToCheck.SpecialCells(xlCellTypeFormulas, xlNumbers)
Set needToHide = rowsToCheck.SpecialCells(xlCellTypeFormulas, xlErrors)
On Error Resume Next
Set needToShow_Showing = needToShow.Offset(0, 1).SpecialCells(xlCellTypeVisible)
Set needToHide_Showing = needToHide.Offset(0, 1).SpecialCells(xlCellTypeVisible)
On Error GoTo 0
If Not needToHide_Showing Is Nothing Then
needToHide_Showing.EntireRow.Hidden = True
End If
If Not needToShow Is Nothing Then
If needToShow.Count <> needToShow_Showing.Count Then
needToShow.EntireRow.Hidden = False
End If
End If
End Sub
Sub SetRowVisibility2()
Dim rowsToCheck As Range
With ActiveSheet
Set rowsToCheck = .Range(Range("B7"), Range("B7").End(xlDown))
End With
Dim needToShow As Range, needToHide As Range
Dim cell As Range
For Each cell In rowsToCheck
If IsError(cell.Value) And (cell.EntireRow.Hidden = False) Then
If needToHide Is Nothing Then
Set needToHide = cell
Else
Set needToHide = Union(needToHide, cell)
End If
End If
If Not IsError(cell.Value) And (cell.EntireRow.Hidden = True) Then
If needToShow Is Nothing Then
Set needToShow = cell
Else
Set needToShow = Union(needToShow, cell)
End If
End If
Next cell
If Not needToHide Is Nothing Then needToHide.EntireRow.Hidden = True
If Not needToShow Is Nothing Then needToShow.EntireRow.Hidden = False
End Sub
there is a different way and that is to use th auto filter feature - after all VBA has an A in it - use the features of the application wherever possible
so this bit of code is pretty short and sweet - assumes that the data is a contiguous block in columns a and b and assumes no other error handling in play. the resume next line allows for the filter to be already turned on.
Sub showHideRange()
Dim testrange
testrange = Range("A1").CurrentRegion.Address
On Error Resume Next
testrange.AutoFilter
ActiveSheet.Range(testrange).AutoFilter Field:=2, Criteria1:="show"
End Sub
If you do not wish to show the user what's happening, would it not be better to perform the calculation in VBA itself, rather than in a hidden column? Granted, that would seem to lock you into option 2, which I suspect is the slower option ... most of my VBA experience is in older versions of Excel, so I've not had the pleasure of working with some of the newer features, and the tasks I've done that involved processing rows of data were done row-by-row.
I guess one possible issue with the first sub is that if there is a problem with the worksheet or the values you're using to determine hiding/showing, the process will fail. If you check row-by-row and there is a row that causes problems, you could skip over that row and process the other ones correctly.

Resources