Edit: I should clarify what I was trying to do. I have a list of values in column D through H and sometimes I may not have any values in the top most rows (they then equal 0, usually 40 rows or so). I want to make it so I don't have to scroll down to the rows that do have values not equaling zero. So I thought it would be easiest to hide the rows that have values equaling zero. But I have values in column A that I don't want to hide. I didn't realize I couldn't hide rows in a specific column without hiding the whole row. I need to rethink how I want to do this.
Original post: I am new to VBA, please bear with me. I have been copy and pasting different snippets of code, trying to get something to work.
I want to loop through all cells in column D through H and have the cells that equal zero to hide themselves. I plan on reusing this sheet so I want the cells to unhide themselves when the value is above zero again.
Here is my code:
Private Sub Hide_Cells_If_zero()`enter code here`
Dim targetRange As Range, po As Long, i As Long
Set targetRange = Columns("D:H")
po = targetRange.Count
With targetRange
For i = 1 To po
If .Cells(i, 1).Value = 0 Then
.Rows(i).Hidden = True
End If
Next
End With
End Sub
Hide Rows With Criteria
This will hide each row where the value of any cell in columns D:H evaluates to 0.
The Code
Option Explicit
Private Sub Hide_Cells_If_zero()
Dim sRng As Range
Set sRng = Columns("D:H")
Dim tRng As Range
Dim rRng As Range
Dim cel As Range
For Each rRng In sRng.Rows
For Each cel In rRng.Cells
If cel.Value = 0 Then
If Not tRng Is Nothing Then
Set tRng = Union(tRng, cel)
Else
Set tRng = cel
End If
Exit For
End If
Next cel
Next rRng
If Not tRng Is Nothing Then
tRng.EntireRow.Hidden = True
End If
End Sub
Related
I need to select a range of data in column Q that meet criteria found in column A (specifically, I wish to select only those cells which correspond to non-"" values in column A). The resulting range of selected cells will be non-contiguous.
I then want to copy these cells and paste their values in column K. The pasted values should retain the same row references as the copied range; basically, I'm just taking the values in the copied range and pasting the values x many columns to the left.
The problem I'm encountering is that it seems to only copy the final value in column Q and then paste this value in column K. So, I seem to be getting it to paste in the right place, but it's not copying the way I want it to.
The code I've written can be found below.
Option Explicit
Sub NonConRngPaste()
Dim rCell As Range
Dim rRng As Range
Dim r As Range
Dim pasteRng As Range
For Each rCell In Range("A1:A1000")
If rCell.Value <> "" Then
If rRng Is Nothing Then
Set rRng = rCell
Else
Set rRng = Application.Union(rRng, rCell)
End If
End If
Next
Set pasteRng = rRng.Offset(0, 10)
For Each r In rRng.Offset(0, 16).Cells
pasteRng.Value = r.Value
Next
End Sub
May as well be simpler?
Sub NonConRngPaste()
Dim c As Range
Application.Screenupdating = False
For Each c In Range("A1:A1000").cells
If len(c.value) > 0 Then
with c.EntireRow
.Columns("K").Value = .Columns("Q").Value
end with
End If
Next
End Sub
I'm trying to build a VBA application that checks for a certain value, then adds a row on top for each time this value is found.
Sub copy()
Dim rng As Range
Dim row As Range
Dim cell As Range
Set rng = Range("B2:B10")
For Each row In rng.Rows
For Each cell In row.Cells
If cell.value = "test" Then
MsgBox "found" + cell.Address
cell.EntireRow.Insert
End If
Next cell
Next row
End Sub
Every time I try to run this function, however, it keeps adding rows on top of each other continuously and not for each occurrence.
If you loop the cells from top to bottom, adding the row will push your original range down, causing the next loop to evaluate the previous cell.
To avoid this, loop backwards (i.e. bottom to top):
Sub copy_test()
Dim rng As Range
Set rng = Range("B2:B10")
Dim i As Long
For i = rng.Cells.Count To 1 Step -1
If rng.Cells(i).Value = "test" Then
Debug.Print "Found"
rng.Cells(i).EntireRow.Insert
End If
Next i
End Sub
Note: Set rng = Range("B2:B10") is telling VBA that you are referring to Cells B2:B10 of the ActiveSheet which might not be what you want.
Please fully qualify your range to avoid this. (e.g. ThisWorkBook.Worksheets("Sheet1").Range("B2:B10") or use the code name of the worksheet Sheet1.Range("B2:B10").)
I have a spreadsheet that has hidden rows 17-111. Data is added to three cells in each row (Columns P,Q & R).
The data comes from Userforms where the user has three option buttons to choose from. Depending on the option, the result of either "Pass", "Fail" or "NA" is populated into each of the cells in the range P17-R111.
I need to unhide all rows where "Fail" is in any of the P, Q or R column cells for that row.
e.g. If cell R57 is a "Fail" and cell P66 is "Fail", then the rows 57 and 66 need to be unhidden.
I have tried variations of code found searching the net, but I get a result where rows are unhidden only where column P has a "Fail", not where the P cell has no fail but other cells in the same row do.
e.g. If cell P57 has a "Pass", but cell R57 has a fail, the row remains hidden.
This is my latest (and more simple) attempt:
Private Sub CommandButton1_Click()
Dim cel As Range
Dim RangeToUnhide As Range
For Each cel In Worksheets("Sheet1").Range("P17:R111")
If cel = "Fail" Then
If RangeToUnhide Is Nothing Then
Set RangeToUnhide = cel
Else
Set RangeToUnhide = Union(RangeToUnhide, cel)
End If
End If
Next
RangeToUnhide.EntireRow.Hidden = False
End Sub
I tried changing the range to ("P17:P111") and then run two further copies of the code for ranges in Q and R. All I get is rows that unhide where the P cell is a 'Fail", the Q and R cells are ignored.
Use this Code
Sub Hide()
Dim cel As Range
Dim RangeToUnhide As Range
For Each cel In Worksheets("Sheet1").Range("A7:B11")
'Change Name of Sheet & Range as per your use
If cel = "A" Then
'Change Value as per your use
If RangeToUnhide Is Nothing Then
Set RangeToUnhide = cel
Else
Set RangeToUnhide = Union(RangeToUnhide, cel)
End If
End If
Next
RangeToUnhide.EntireRow.Hidden = True
End Sub
The above code is for hide use this for unhide
Sub Unhide()
Dim cel As Range
Dim RangeToUnhide As Range
For Each cel In Worksheets("Sheet1").Range("A7:B11")
'Change Name of Sheet & Range as per your use
If cel = "A" Then
'Change Value as per your use
If RangeToUnhide Is Nothing Then
Set RangeToUnhide = cel
Else
Set RangeToUnhide = Union(RangeToUnhide, cel)
End If
End If
Next
RangeToUnhide.EntireRow.Hidden = False
End Sub
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
I have values on Sheet 1 and I gave the background color using conditional formatting.
I want to copy only the color and paste it to the corresponding cell of sheet 2 without pasting the value.
Example if sheet 1 cell A1 has red color for specific value, transfer the color to sheet 2 A1.
I use two colors, red and white. Red is for higher value and white is for lower value.
Sub copycolor()
Dim intRow As Integer
Dim rngCopy As Range
Dim rngPaste As Range
For intRow = 1 To 20
Set rngCopy = Sheet1.Range("A" & intRow + 0)
Set rngPaste = Sheet2.Range("b" & intRow)
'Test to see if rows 500+ have a value
If rngCopy.Value <> "" Then
'Since it has a value, copy the value and color
rngPaste.Value = rngCopy.Value
rngPaste.Interior.Color = rngCopy.Interior.Color
End If
Next intRow
End Sub
rngPaste.Interior.Color = rngCopy.DisplayFormat.Interior.Color
Seems to work for me. Keep in mind that DisplayFormat is read-only and is not allowed to return value outside of the function it's used in. Also it is only available in Excel 2010 +
I was editing my answer to include the other stuff you mentioned and realized it was getting confusing to explain it all in separate chunks. Here's a recommended approach to achieve what you're saying.
Public Sub CopyColor()
Dim SourceSht As Worksheet
Dim TargetSht As Worksheet
Dim rngCopy As Range
Dim rngPaste As Range
Dim LastCopyRow As Long
Dim LastCopyColumn As Long
'Define what our source sheet and target sheet are
Set SourceSht = ThisWorkbook.Worksheets("Sheet1")
Set TargetSht = ThisWorkbook.Worksheets("Sheet2")
'Find our used space on the source sheet
LastCopyRow = SourceSht.Cells(Rows.Count, "A").End(xlUp).Row
LastCopyColumn = SourceSht.Cells(1, Columns.Count).End(xlToLeft).Column
'Setup our ranges so we can be sure we don't loop through unused space
Set rngCopy = SourceSht.Range("A1:" & SourceSht.Cells(LastCopyRow, LastCopyColumn).Address)
Set rngPaste = TargetSht.Range("A1:" & TargetSht.Cells(LastCopyRow, LastCopyColumn).Address)
'Loop through each row of each column.
' This will go through each cell in column 1, then move on to column 2
For Col = 1 To LastCopyColumn
For cel = 1 To LastCopyRow
' If the string value of our current cell is not empty.
If rngCopy.Cells(cel, Col).Value <> "" Then
'Copy the source cell displayed color and paste it in the target cell
rngPaste.Cells(cel, Col).Interior.Color = rngCopy.Cells(cel, Col).DisplayFormat.Interior.Color
End If
Next cel
Next Col
End Sub
Simplest would be to apply the same conditional formatting to Sheet2, but use the values from Sheet1 as your criteria. So if Sheet1 Cell A1 has the value that makes it red, add formatting to Sheet2 that turns Sheet2 Cell A1 red as well.
There's a good explanation of how to achieve this here.
.Interior.Color gets the actual colour of the cell rather than the conditionally formatted colour (the one you see). So you can't copy/paste this red colour in your example in this way.
I believe that the only way to get the conditionally formatted colour you see would be to recompute whatever formula you've used in your conditionally formatting criteria.
Excel 2007 conditional formatting - how to get cell color?
Edit
While #JeffK627 was giving an elegant solution, I was knocking up some rough vba code to recompute what I gather your conditional formatting does. I've done this over range A1:A20 on sheet 2. At the moment it colours the cell that contains the value itself, but only requires a little tweak to colour the equivalent cell on another sheet.
Sub ColouringIn()
Dim intColIndex As Integer
Dim dblMax As Double
Dim dblMin As Double
Dim rngCell As Range
'RGB(255, 255, 255) = white
'RGB(255, 0, 0) = red
'so need to extrapolate between
dblMax = Application.WorksheetFunction.Max(Sheet2.Range("A1:A20"))
dblMin = Application.WorksheetFunction.Min(Sheet2.Range("A1:A20"))
For Each rngCell In Sheet2.Range("A1:A20")
If IsNumeric(rngCell.Value) And rngCell.Value <> "" Then
intColIndex = (rngCell.Value - dblMin) / (dblMax - dblMin) * 255
rngCell.Interior.Color = RGB(255, intColIndex, intColIndex)
End If
Next rngCell
End Sub
Adding following example as alternative solution, as I needed something dynamic/active where color IS a required condition of data & not reliant on any other trigger.
Option1:
Dim rngPrev2Update As Range
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim cellbox As Range
Dim rngDest As Range
If Not rngPrev2Update Is Nothing Then
For Each cellbox In rngPrev2Update.Cells
Worksheets("Sheet2").Range(cellbox.Address).Interior.ColorIndex = cellbox.Interior.ColorIndex
Next cellbox
End If
Set rngPrev2Update = Target
End Sub
This will update destination cells when cursor is next moved to another cell.
Option2:
Private Sub Worksheet_Activate()
Dim cellbox As Range
Dim rngCells As Range
Set rngCells = Range("B1:B10")
For Each cellbox In rngCells.Cells
Range(cellbox.Address).Interior.ColorIndex = Worksheets("Sheet2").Range(cellbox.Address).Interior.ColorIndex
Next cellbox
End Sub
Will update relevant cells on sheet load.
Note: If you have very large data set you may want to put this into a macro button &/or filter this further for only the cells you need, otherwise this may slow your spreadsheet down.
Appreciating this was some time ago. I would like to do a similar thing however would like to append the Interior Color Reference ie. 255 to the cells value.
so if cell A1 has Hello in the cell and is Colored Red I'd want in the other worksheet cell A1: Hello | 255
Just used | as a delimiter but anything sensible...