How to code button to hide a range of cells? - vba

I am trying to create buttons that imitate the nature of nested rows, where when clicked, will hide the indented columns below it. I previously targeted a specific range of rows for each button, but as my company will attempt to add rows in the future, I want the code to continue to run properly regardless of where in the sheet the new row is added. Below is the code that I used:
Sub aButton()
With Rows("1:22")
If .Hidden Then
.Hidden = False
Else
.Hidden = True
End If
End With
End Sub
My attempted work around is to make a hidden column with A, B, C values per row to identify which range of rows go together. I want to be able to target all rows with "A" in column G, and use those values as my range in my existing code.
Can you help?

Related

Macro to auto fill text in a column down to the last cell in one table (while there are additional tables below)

example of tables in the spreadsheet
Hi I am new to VBA and wanted to create a macro that can auto fill column "Y/N" (as shown in the attached pic) with the text "Yes" by clicking a button.
Right now I have 3 rows in the first table, which is fine and I used the following code:
Sub autofill1()
Range("E12").Value = "Yes"
Range("E12").Select
Selection.AutoFill Destination:=Range("E12:E14")
End Sub
However, the rows in the first table will keep changing, say it becomes 20, 50, 100 depending on different cases. I wonder if there's a way for me to define the auto fill range to be cell E12 to the last cell in this table, not to extend to the rest of the tables below.
I checked the codes provided for other similar questions - looks like it will auto fill all the way down to the last cell in my worksheet, which is the last cell in this column of the 5th table. And I don't want that. Is there a way to only auto fill down to the last cell of the 1st table? Thanks so much in advance!
In my opinion, adding "yes" until found a bottom border.
Sub autofill1()
'Range("E12").Value = "Yes"
'Range("E12").Select
'Selection.AutoFill Destination:=Range("E12:E14")
Dim i As Long
i = 11
Do While Range("E" & i).Borders(xlEdgeBottom).LineStyle _
= xlNone
i = i + 1
Cells(i, 5) = "Yes"
Loop
End Sub

Using an Autofilter function for multiple criteria with cases

I have a sheet, where I would like to filter the blank rows in column T and U.
I have certain cases to be considered.
I have few missing rows and have denoted them as missing in column S. If they are missing, I don't want them to be considered for filter condition. In Default they are blank.
The other case is, any one of the rows in column T and U are found blank, has to be filtered. IF both columns are blank, they also have to be filtered.
I have attached two images for reference. Could anyone suggest me how I could do it ? I am a beginner in VBA, Any lead would be helpful.
Sub FC()
Dim ws As Worksheet
Set ws = Sheets("FC")
With ws
.Range("A5:T1000").autofilter Field:=20, Criteria1:="=", Operator:=xlFilterValues
End With
End Sub
I tried the above code, It works with column T.
How can I include multiple criteria? Because with my cases, with column S as missing, I don't need to consider the complete row. And with my T and U, both blank or any one is blank, then I need them to be filtered.
This is how my sheet looks like in the beginning.
I would like to have a code, in such a way that, I want to filter the column T and S with blank rows, any of the rows in column T and U are found blank,
then I would like to filter them.
Ok so here's how you can achieve your custom filtering using a helper column. Let's take column Z for this mission.
Sub FC()
With Sheets("FC").Range("Z5:Z100")
.EntireColumn.Hidden = True ' <-- optional, to hide the temp column
.Formula = "=AND(S5<>""Missing"",OR(ISBLANK(T5),ISBLANK(U5)))"
.AutoFilter 1, True
End With
End Sub

Select only one column even if a merged range lies below

Test case:
Take an empty sheet, and merge the range "D2:F2". You can do this manually.
Then, activate the macro recorder and select the column E by just clicking on the E letter on the top of the spreadsheet. You will get the following:
Columns("E:E").Select
Now, try to run this line of code from the same macro directly: you will see that it selects the three columns D, E and F.
Question:
Is this a bug of the macro recorder? Or, rather, a bug of VBA itself (that detects the merged range in my column and decides to extend the selection even if explicitly asked to select one single column)? How should I do to select only one of the columns on which a merged range lies via VBA code, exactly as I can do manually?
Need:
I have a spreadsheet with year on a line, months on the below line and days on the below line.
Hence, the days are just cells but months and especially years are shared/merged cells among the several days.
My need is just to detect the current day and select the column, in order for the user to see on which day they should look the data at. But, because of the "years" cell widely merged just above, the entire year is selected.
No, this is not a bug.
Why: Try to manually select the range E1 to E5. That is what is going on when you use Columns("E:E").select. Think of it as .Select not selecting the column, but instead selecting each cell from top to bottom.
The .select method isn't something you should depend on. What exactly are you trying to use select for? There is another (quite arguably better way) to do this.
Edit: Also, as my father always says, merged cells shouldn't be used. He uses "center across selection" instead, which looks exactly like a merged cell without any of the seemingly buggy behavior.
Need: I would use the macro to highlight the data... probably with something like this...
Range("E7").Interior.ColorIndex = RGB(0, 0, 0)
I feel that the question is genuine unlike some of the comments here. I will try to explain.
Using the test case from the question, say I want to do some action only on column D (say change its column width), without changing the same for columns E to F. I can do that in excel by selecting column D specifically by pressing on column header (press on that "D" in the column names bar). If we select column using range selection (mouse or keyboard shortcut CTRL+SPACE), it extends the selection to include E and F columns. But if we press that column D on the header, it only selects one column. I expect VBA to do the same.
Sadly, I couldn't find anything to "select" a single column or range which includes cells merging through multiple columns or range. However, I could do the action on that single column.
I tried following that didn't work. And I feel that it should work.
Range("D:D").Select
Didn't work. Extends the selection to include merged cells. I guess, this is okay.
Columns("D").Select
Didn't work. Extends the selection to include merged cells. I feel this is not okay.
Columns("D").EntireColumn.Select
Even this didn't work. This definitely should've.
So finally I directly applied the action without selecting the cells.
Column("D").ColumnWidth = 10
And this did it. Only the column D width was changed, leaving column E and F untouched. Similarly, I could do font change and other actions.
Only drawback is that I have to do all actions individually. So, I use a loop to perform action on the selection.
Something like this:
For Each x in Range("D:D")
x.font.size = 10
x.font.name = "Calibri"
'...and so on...
Next x
You probably know the row in which the days start. Therefore, instead of selecting the entire column, you could define a range starting from the first day row to the last day row and select that range.
REQUIREMENTS:
Your table should have this values and formats
Then you can loop through each column on row 4 -just assumed- and check each value if they match today. Next you can scroll to that cell using Application.Goto.
CODE:
Sub FindToday()
Dim wsTable As Worksheet '<~ worksheet with your table
Set wsTable = Sheet2
Dim Cols As Integer '<~ a variable to loop through columns
With wsTable
For Cols = 1 To .Cells(4, .Cells.Columns.Count).End(xlToLeft).Column + 1
If .Cells(4, Cols).Value = Date Then '<~ check if the date is today
Application.Goto wsTable.Cells(1, Cols), True '<~ scroll to that cell if true
Exit For
End If
Next
End With
End Sub
If you want just to hide the particular column if there is merged cell try not to select the column just use like this for example -- Columns("N").EntireColumn.Hidden = True... This will solve your doubt.

Macro to Hide/Unhide Columns in Excel

I created a simple macro to hide/unhide columns in Excel (attached below).
It works fine, however, when adding a column within the range of columns in the macro, the last column supposed to be hidden remains unhidden.
To make myself clear: The range of columns in macro is AM:BF. When I need to add a column within this range, the column BF stays unhidden. Could you help me how to improve the code so that the initial range of columns would stay hidden as well as the added one?
With Columns("AM:BF")
If .EntireColumn.Hidden = True Then
.EntireColumn.Hidden = False
Else
.EntireColumn.Hidden = True
End If
End With
You need to have a placer for the column. You could used a named range along the top row of columns AM:BF (Which will then change if you add a column in the middle of it). Your code could then look like
With ThisWorkbook.Sheets("MySheet").Range("NamedRange").EntireColumn
.Hidden = Not .Hidden
End With

Removing a row in a table if it doesn't contain keyword

Right now I have a really long table in a Word doc which I populated from an Excel worksheet. It has 6 columns and I'm trying to code something in Word VBA that will go through all the rows in the table and delete the entire row if the cell in the first column DOES NOT start with an equal sign ("=").
For example, I'm only trying to keep the rows that has texts like,
"=1+S -03F7", "=1+M -06M1", etc. etc.
How would I code this? I can't give the code anything specific to look for since the parts after the equal sign will be different for every row.
So this wouldn't work, right?:
If Not ActiveDocument.Tables(83).Columns(1).Range.Text = "=" Then
EntireRow.Select
Selection.Delete
I guess I should reference to cells in column 1, not the column itself... Also, it doesn't work because it's only looking for things with just the equal sign... And I don't know how I can get it to select the row if it find the cell without the equal sign. I don't know how to match by case in the cell of the first column.
You can loop through the rows in the table using the Rows property. You can then find the first cell in that Row using the Cells property. You can then check just the first character of the Range:
Sub DeleteUnwantedRows()
Dim t As Table
Dim r As Row
Set t = ActiveDocument.Tables(1)
For Each r In t.Rows
If r.Cells(1).Range.Characters(1) <> "=" Then r.Delete
Next r
End Sub