Hiding columns in excel using VBA - excel

I am trying to hide multiple columns using VBA based on cell value (this can either be blank or 0). The cells have an array lookup formula also which I think is stopping the functioning of the normal column hiding via VBA. For instance, there are 40 columns, with a maximum of 6 containing a value which has been obtained from another worksheet via a VLookup array. The 6 columns which contain a value can be any of the 40 columns from the VLookup.

To get you started here is a basic macro that will check each cell in a range, and if either of the conditions are met the current column will be hidden. The sheet name and range needs to be changed as needed.
Dim cel As Range
For Each cel In ThisWorkbook.Sheets("Sheet1").Range("A1:J20")
If cel.Value = "0" Or cel.Value = "" Then
cel.EntireColumn.Hidden = True
End If
Next cel

Related

find blank cells in columns and replace them with 0, repeat for next row if next row has data

I am using excel userform to input the data. I want for Columns C2:F2, if the user has not inputted any number in it, excel should convert these blanks into 0. And I want it to repeat for the next row when the data for next row is inputted. I tried some simple coding but it didn't work.
Public Sub BlankCells()
Dim rng As Range
rng = Range("C2:C1000", "D2:D1000", "E2:E1000", "F2:F1000")
For Each cell In rng
If cell = "" Then cell.Value = "0"
Next cell
Find
End Sub
It works if use coding for single row only i.e. "C2:F2", but i want it repeat for the next rows as well when the next row gets the data.
When you create a variable for sheet or range, you need to use the Set keyword like this:
Set rng = Range("C2:F1000")
If you'd like to refer to multiple ranges, you can add all the ranges as one comma separated string

VBA for filtering cells in a row based on another cell value in the same row

I have an excel sheet with numbers in each cell. I want to eliminate the cells containing values which are larger than a specific value, different for each row, for example in the picture
I want to eliminate all the cells in a certain row that has values more than the BL cell.
Not sure the exact context in which this is being used, So possibly some conditional formatting would be more stable?
Also not sure what you meant by "Eliminate" so the following code just turns the cell red.
anyway, hopefully this code will help you get started :)
Sub Cell_Vaue_Check()
Dim row As Excel.Range
Dim cel As Excel.Range
For Each row In Sheets("Sheet1").Range("A1:C5").Rows '<<- Replace "Sheets("Sheet1").Range("A1:C5")" with the Sheet and Range you want to check
For Each cel In row.Cells
If cel.Value > Range("E" & cel.row).Value Then '<<- Replace "E" with the Column in which the check value is located
cel.Interior.Color = RGB(288, 0, 0) '<<- This line turns the cell Red. Replace it with whatever code you want depending on what "eliminate" means to you
End If
Next
Next
Set row = Nothing
Set cel = Nothing
End Sub
If Anybody has any improvements please feel free to Add!

Excel: Working around sorting tables by date, with empty rows in the range

I am working on a model that requires me to sort data in a range by date, before copying the data into a different template on another sheet. Every row has a formula that pulls data from Bloomberg, so even if the cell looks empty, excel recognizes that there is content in the cell. Sorting the date column as it is does not work, as excel wont recognize the data that Bloomberg pulls as a date, so it would be sorted from A to Z, which scrambles the dates instead.
To work around this, I inserted and adjacent column with the formula (using cell A1 as an example) "=(A1+0)" that then allows the column to be sorted from new to old. The problem here is that if cell A1 does not display a date (in other words, it appears empty yet the cell contains a formula that leaves the cell looking empty if no date is pulled) it returns a #VALUE! error and sorting new to old would put the errors at the top (Thank you Excel for this fantastic feature, btw).
To work around this new issue, I replaced the above formula in the cell with "=IFERROR(A1+0,1)" which gives me the date 1/1/1900. Fine, now the data is sorted in the manner I want it, but I have a bunch of ancient dates that just make my end product look ugly.
I have two questions, first; how can I use VBA to delete the data in the cells where the date equals 1 (which shows the date 1/1/1900), and only those cells? Or, alternatively, only copying the rows above the cell that contains 1/1/1900. This is a relatively small amount of cells that would be affected by this, 40 at most.
Second; is there a different way of sorting the data using VBA that I am missing, that might be more efficient?
Try this macro, I tried to test it with as many anomalies as possible.
Sub SortByDateColumnH()
Dim r As Range: Set r = Sheet1.Range("B3:P40")
Dim cel As Range
For Each cel In r.Columns(7).Cells
If IsError(cel.Value) Then
cel.Value = 0
ElseIf Not IsDate(cel.Value) Then
cel.Value = 0
Else
cel.Value = CLng(cel.Value)
End If
Next
r.Columns(7).NumberFormat = "0"
r.Sort Key1:=r.Cells(1, 7), Order1:=xlDescending, Header:=xlNo
For Each cel In r.Columns(7).Cells
If cel.Value < 100 Then cel.ClearContents
Next
r.Columns(7).NumberFormat = "m/d/yyyy" '<-- set the format to your preference
'r.Copy Destination:=someDestination ' you can copy the range by code if needed
End Sub

vba excel looping thru an array

I'm a rookie at vba.
I created a solution that works on a micro basis, but can't get the same code to run when I add additional parameters to that code.
I created a multiple choice quiz with answer cells which test against the answers on a separate (hidden) sheet. An adjacent cell shows Yes or No response. That functionality which I researched on the web works well. I'm trying to clear.contents for all the cells so that the user can complete the quiz, clear all responses to give it another go.
I have 395 questions which I created code to clear "Range("B2").ClearContents"
My subroutine has 395 such commands and takes 45-60 seconds. I'm looking for a more efficient solution. I don't want to clear the entire column only the 395 non-adjacent cells which have user input.
Sub Test_Clear()
Range("B2,B5,B7,B9,B11").ClearContents
End Sub
My list of cells is on Sheet2 D1:D395 Each cell in D1:D395 lists a cell on Sheet1 which I want to clear (i.e. B6, B11, B17, B22, B35 etc.) How can I reference those cells on Sheet2 and perform the ClearContents?
While you could just hard code your list in VBA instead of your Sheet2 range, here is how you could reference that list of cells in sheet2 and clear the contents all at once:
Sub clearall()
Dim rngCell, listCells As String
For Each rngCell In Sheet2.Range("D1:D395").Cells
If listCell <> "" Then listCell = listCell & "," & rngCell.Value Else listCell = rngCell.Value
Next
Sheet2.Range(listCell).ClearContents
End Sub
If you just want to clear the cells in column A which have something in them you could use this
Sheet1.Range("A:A").SpecialCells(xlCellTypeConstants).ClearContents
'or
Sheet1.Range("A1:A395").SpecialCells(xlCellTypeConstants).ClearContents
The VBA Join function can be used to join values into string, and the Excel Transpose function is needed to "flip" the column values 2D array to a 1D row values array:
stringAdress = Join([Transpose(Sheet2!D1:D395)], ",")
ThisWorkbook.Worksheets("Sheet1").Range(stringAdress).ClearContents
If any of the cells in the Sheet2!D1:D395 range are blank, the above will result in error.
In Excel 2016, the TextJoin function can be used to ignore empty cells (not tested):
stringAdress = [TextJoin(",", True, Sheet2!D1:D395)]
ThisWorkbook.Worksheets("Sheet1").Range(stringAdress).ClearContents

Unmerge cells and distribute contents in Excel (for mac) 2011

I have a spreadsheet with a large amount of data in. About half the cells are merged horizontally with other cells and contain names e.g. John Doe.
Does anyone know how to write a macro to unmerge the cells while distributing the value of the cell to all the cells that were previously merged?
Cheers
Jack
EDIT: The reason I am doing this is to check to see if two adjacent cells are equal i.e. is A1 = A2. But I run into problems when either cell is merged. If anyone knows a way around this problem without separating the cells and copying the data that would be even better!
The idea I provide below is tested for Excel 2010 VBA Win7. However, being not sure I hope it should work as for Mac, too (as this is rather set of standard properties and methods of Range object). If this doesn't work please let me know to delete my answer.
This simple code will work for selected area however it's quite easy to change it to any other range. Some other comment inside the code below.
Sub Unmerging_Selection()
Dim tmpAddress As String
Dim Cell As Range
'change Selection below for any other range to process
For Each Cell In Selection
'check if cell is merged
If Cell.MergeCells Then
'if so- check the range merged
tmpAddress = Cell.MergeArea.Address
'umnerge
Cell.UnMerge
'put the value of the cell to
Range(tmpAddress) = Cell
End If
Next
End sub
And the picture presenting before and after result:
I was able to get the solution from KazJaw to work on a mac with one edit, changing Cell.UnMerge to
ActiveSheet.UsedRange.MergeCells = False, as provided by Ron Debruin here: http://www.rondebruin.nl/mac/mac027.htm.
Sub Unmerging_Selection()
Dim tmpAddress As String
Dim Cell As Range
'change Selection below for any other range to process
For Each Cell In Selection
'check if cell is merged
If Cell.MergeCells Then
'if so- check the range merged
tmpAddress = Cell.MergeArea.Address
'umnerge
ActiveSheet.UsedRange.MergeCells = False
'put the value of the cell to
Range(tmpAddress) = Cell
End If
Next
End sub

Resources