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
Related
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
I have an excel sheet with data about 30.000 rows and 5 columns. The first row of data is the 12th row, where column names are.
Cells in Range("A1:A10") are used for set of string parameters.
I am using method:
Sub FindString(aString As String)
Dim RangeResult As Range
Set RangeResult = Range("A1:A10").Find(What:=aString)
RangeResult.Select
End Sub
that works fine when calling
FindString aString:="Type"
But when I have an active filter on my data that remains only (let's say) 100 rows visible, I am receiving an error Object variable or With block variable not set. It is caused by that fact that RangeResult = Nothing when debugging.
I have to say that the target parameter is always present in Cell A2. So the only difference is when calling with/without filtered data.
It would be nice if you could help me to solve this issue.
Thanks in advance!
EDIT (when solved): The issue is related with the fact that cell A2 becomes hidden
AutoFilter Embarrassing the Find Method
In the end I could produce your problem in two cases:
The wrong worksheet was active.
After applying a filter using AutoFilter and Row 2 was hidden ("Type" was in A2).
The first case is considered in all three solutions.
The second case still affects the Find method solution.
'Luckily', there are other solutions, e.g. Application.Match and the 'good old' For Each Next loop (it's only 10 cells).
To conclude, the Find method doesn't 'like' AutoFilter, but then AutoFilter 'likes' to be in the first row.
An interesting issue to see how AutoFilter 'likes' the first row, is when a filter is applied and you try to unhide any hidden rows above it. You cannot do it before you haven't removed the filter e.g. used ShowAllData. The same applies to rows below the filtered range, so one might conclude that AutoFilter 'reserves the rights' on rows: 'No row gets unhidden while my data is filtered'.
The Code
Option Explicit
' Still 'buggy'.
Sub findString(aWorksheet As Worksheet, ByVal aString As String)
If Not aWorksheet Is Nothing Then
With aWorksheet.Range("A1:A10")
Dim cel As Range
' ".Cells(10)" ensures the first occurrence from "A1".
' "xlFormulas" covers hidden rows.
Set cel = .Find(What:=aString, After:=.Cells(10), _
LookIn:=xlFormulas)
If Not cel Is Nothing Then
.Worksheet.Activate
cel.Select
'Debug.Print Selection.Address
End If
End With
End If
End Sub
Sub TESTfindString()
findString Sheet1, "Type"
End Sub
Sub matchString(aWorksheet As Worksheet, ByVal aString As String)
If Not aWorksheet Is Nothing Then
Dim rng As Range
Set rng = aWorksheet.Range("A1:A10")
Dim idx As Variant
' Case-insensitive: A=a
' If you need A<>a, you can set "Option Compare 1" (or "TextCompare")
idx = Application.Match(aString, rng, 0)
If Not IsError(idx) Then
aWorksheet.Activate
rng(idx).Select
'Debug.Print Selection.Address
End If
End If
End Sub
Sub TESTmatchString()
matchString Sheet1, "Type"
End Sub
Sub loopString(aWorksheet As Worksheet, ByVal aString As String)
If Not aWorksheet Is Nothing Then
Dim rng As Range
Set rng = aWorksheet.Range("A1:A10")
Dim i As Long
For i = 1 To 10
' Case-sensitive: "A<>a".
If rng(i).Value = aString Then
' If you need "A=a" then use this instead:
'If StrComp(rng(i).Value, aString, vbTextCompare) = 0 Then
aWorksheet.Activate
rng(i).Select
'Debug.Print Selection.Address
Exit For
End If
Next i
End If
End Sub
Sub TESTloopString()
loopString Sheet1, "Type"
End Sub
I have checkboxes that are LINKED to their own respective cells. When I check checkbox1, I want all the checkboxes in a specific range to be checked/unchecked.
Here is what I Used but it's not working. It's giving me error Object variable or With block variable not set.
Sub SelectAll_Click()
Dim xCheckBox As CheckBox
Dim rng As Range, cell As Range
Set rng = Range("B19:B28")
For Each cell In rng
If xCheckBox.Name <> Application.ActiveSheet.CheckBoxes("Check Box 1").Name Then
xCheckBox.Value = Application.ActiveSheet.CheckBoxes("Check Box 1").Value
End If
Next cell
End Sub
Thank you
To toggle a checkbox that is linked to a cell you can simply set the cell value (or return value from a formula) to either True or False.
Using your example it would look something like:
Sub SelectAll_Click()
Dim xCheckBox As CheckBox
Dim rng As Range, cell As Range
Set rng = Range("B19:B28")
For Each cell In rng
cell.value = True
Next cell
End Sub
If you need logic based on the checkbox itself then you would instead loop the checkboxes rather than the a range.
Private Sub demoLoopingCheckboxes()
Dim control As OLEObject
For Each control In ActiveSheet.OLEObjects
With control
' The type of activex control
' Use this is a if statement to limit to only "CheckBox"
Debug.Print TypeName(.Object)
' The cell Address to the linked cell
Debug.Print .LinkedCell
' Can read/write the value to the checkbox itself
Debug.Print .Object.Value
End With
Next control
End Sub
I would like to have a button in my Excel sheet that:
1) Asks me to select the range I want to use
2) Changes the blank cells found in this range to a fixed value ("NA")
I could find how to get a box asking me to select a range, but not a solution on changing the values in combination with this box.
You can use SpecialCells() to do this in only two lines:
Sub t()
Dim rng As Range
Set rng = Application.InputBox("Select a range", Type:=8).SpecialCells(xlCellTypeBlanks)
rng.Value = "NA"
End Sub
Just pass the range from your other existing get range value from a sub to a sub like this:
Private Sub BlankToNA(Target as Range)
Target.SpecialCells(xlCellTypeBlanks).Value = "NA"
End Sub
I'm trying to hide a sheet in an Excel workbook based on the contents of any of the cells in a given range.
Let's say I have two sheets - "Sheet1" and "Sheet2".
On Sheet1, I want to set up a range - cell C10 to F10.
Each of these cells can either be blank, or contain "Yes" or "No" - chosen from a dropdown box.
If ANY of the cells in the range are set to "Yes", I want Sheet2 to be visible, otherwise (if all the cells are either blank or contain "No") I want Sheet2 hidden.
I've tried various pieces of code, including the below.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rCell As Range
Application.ScreenUpdating = False
For Each rCell In Range("C10:F10")
If rCell.Value = "Yes" Then
Worksheets("Sheet2").Visible = True
Else
Worksheets("Sheet2").Visible = False
End If
Next rCell
Application.ScreenUpdating = True
End Sub
I've got about as far as Sheet 2 being visible if all the cells equal "Yes" or if F10 equals "Yes", but not if only one of the cells contains "Yes".
No loop needed, and create an If to test whether the Cell that change is in the range to test, just to save some comp time:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Range("C10:F10"),Target) Is Nothing Then
Worksheets("Sheet2").Visible = Application.Countif(Range("C10:F10"),"Yes")>0
End If
End Sub
Modify and try:
Option Explicit
Sub test()
Dim ws As Worksheet
Dim rng As Range, cell As Range
Dim Hide As Boolean
For Each ws In ThisWorkbook.Worksheets
Set rng = ws.Range("C10:F10")
For Each cell In rng
Hide = False
If cell.Value = "Yes" Then
Hide = False
Exit For
Else
Hide = True
End If
Next
If Hide = True Then
ws.Visible = False
End If
Next
End Sub