VBA Color row cells if they are unequal to blank - vba

I'm using the code shown below to essentially make the first row of the spreadsheet color grey based on if the cell is empty or not. For example Cell A1 is not blank so color it grey, cell B1 is not blank so color it Grey but cell C1 is blank so don't color it at all. So far my script colors the whole row grey based on A1. Is there an alternative for this?
Sub test()
Dim c As Integer
c = Application.WorksheetFunction.CountA(ActiveSheet.Range("A1"))
If c > 0 Then
ActiveSheet.Range("A1").EntireRow.Interior.ColorIndex = 48
End If
End Sub

When working with Excel-VBA, it's enourmously helpful to grasp the idea of Objects and Collections and how to loop them.
The Watch-window is your best friend here, as is the With keyword when writing code.
In your case:
a Cell is an object inside the Worksheet.Cells-collection (in your case, also an object inside the ActiveSheet.Rows(1).Cells-collection.
This does what you want, based on the information you gave us (you didnt specify that you do NOT want to loop the whole row ;) )
Option Explicit
Sub ColorCells()
Dim objCell As Object
With ActiveSheet
With .Rows(1)
For Each objCell In .Cells
With objCell
If .Value > 0 Then .Interior.ColorIndex = 48
End With
Next objCell
End With
End With
End Sub
This should give you an idea how Excel-Objects work.
Obviously, we can write this shorter:
Sub ColorCells()
Dim objCell As Object
For Each objCell In ActiveSheet.Rows(1).Cells
If objCell.Value > 0 Then objCell.Interior.ColorIndex = 48
Next objCell
End Sub
Note:
This code will loop all 16k Cells in your Row. Obviously, we could stop at your last used Cell. However, since this runs in under a second, i left that out on purpose to keep the code clean
While you could do this with conditional formatting, i support the idea of doing this with code ONCE, with no traces (that is, your conditional formats), left.
I understand what you tried to do with .CountA and .EntireRow, this doesnt work here.

Related

in VBA Why does the Selection Object act differently when indexed?

hopefully you can help me with this!
I am writing a code in VBA and I am having issues with the Selection object acting differently than I expect.
When I write a for loop as in
For Each Cell in Selection
MsgBox Cell.Value
Next Cell
It works as expected, but then I try to index it and it acts differently. Especially it is a non-contiguous cell selection.
Like this;
For i = 0 to 5
MsgBox Selection(i).Value
Next i
It gives pretty random values. any insight would be great!
Edit:
Thanks for the input everyone, it seems I need to find another way of doing the following. I have a piece of code that takes a user's selected cells and uses those values for calculations. Right now, I have been trying to make it so they can select non-contiguous cells. Basically, I need to make an array of these values, and my thoughts were to make a for loop as follows
For I = 0 To 5
Array(i) = Selection(i).Value
Next I
I'm not sure if there is another way of doing this. If anyone has some suggestions, I am interested!
As others have stated, you should not use Selection this way. But to answer your question...I did some quick testing based on your example use-case.
It appears that when you loop cell in Selection it goes left to right, then top to bottom by range area. So for example if you have two non-contiguous ranges selected then if will look something like this:
When you index it, it does not seem to make the jump between range areas. instead it will continue iterating left to right top to bottom within the column bounds of the first range area:
So if you slected 2 columns, iterating on the index would just continue down the first column, even if it is outside of the selection.
My test code:
Private Sub testing()
Dim i As Integer
For i = 1 To Selection.Cells.Count
Selection(i).Value = i
Next i
End Sub
Private Sub testing2()
Dim c As Range
For Each c In Selection.Cells
c.Value = c.Column
Next c
End Sub

Change Text Colour in Cell Based on Text in Same Cell - Word VBA

I am new to VBA so I am struggling with what seems to be quite a simple task.
I have a few lines of text in each cell in a word document. Each cell contains a category such "Science" or "Health" or one of several others. At the minute I'm actually just using a special character such as "*" or "#" for testing purposes.
I need the text colour of all text in the cell to change depending on which category is in the cell. So the txt would be e.g. green for "Science" and red for "Health".
It seems that running a macro is quickest way of making these changes (there will be over 200 such cells in my final document and colouring manually is such a waste of time). Basically, I'm struggling with first changing the colour of all the text in the cell, and secondly how to make the macro search again if the first criteria is not met. I would like 1 macro that could complete colouring for the entire document, rather than having multiple macros for each colour I need.
If you could give me some examples of VBA I could work with that would be most helpful. I'm really struggling and any help you could give will save me and my team so much time.
This should perform reasonably well unless your document is huge or your keyword list is huge or both.
Sub ColorCells()
Dim tbl As Table
Dim rw As Row
Dim cll As Cell
Dim i As Long
Dim Keywords As Variant, Colors As Variant
'if you have more than one table, you have to look through them
Set tbl = ThisDocument.Tables(1)
'Make two arrays - one with keywords and the second with colors
'where the colors are in the same position in their array as the
'keywords are in theirs
Keywords = Array("Science", "Health")
Colors = Array(wdBlue, wdDarkRed)
'Loop through every row in the table
For Each rw In tbl.Rows
'Loop through every cell in the row
For Each cll In rw.Cells
'Loop through every keyword in your array
For i = LBound(Keywords) To UBound(Keywords)
'if the keyword exist, change the color and stop checking
'further keywords
If InStr(1, cll.Range.Text, Keywords(i)) > 0 Then
cll.Range.Font.ColorIndex = Colors(i)
Exit For
End If
Next i
Next cll
Next rw
End Sub
If you want to use custom colors instead of built in ones, change the Colors array assignment line to
Colors = Array(RGB(192, 192, 192), RGB(188, 25, 67))
and the line where you set the color to
cll.Range.Font.TextColor.RGB = Colors(i)

How do I use xlCellTypeLastCell in VBA?

I selected all cells in a sheet and Clear All to bring me a blank spreadsheet. Then I entered in E6 and A1 some texts. Then I ran the following code, however, I got E7 cell selected. How weird! I wonder if I missed something.
Sub Macro1()
Cells.SpecialCells(xlCellTypeLastCell).Select
End Sub
Call the Worksheet.UsedRange property all by itself to reset the xlCellTypeLastCell property of the Range.SpecialCells method.
Sub Macro1()
Range("E7") = "abc"
Cells.Clear
Range("E5") = "xyz"
Cells.SpecialCells(xlCellTypeLastCell).Select
ActiveSheet.UsedRange
Cells.SpecialCells(xlCellTypeLastCell).Select
End Sub
If you step through that with [F8], first E7 will be selected, then after the call to .UsedRange, E5 will be selected.
Based on my experience the best solution to finding last cell / row etc. containing data is by .find method, because it is reliable even after deleting some data. The only drawback is that it doesn't detect hidden rows.
Code below returns the last row containing data in 5th column (Column E). Replace "Columns(5)" with "Cells" if you want to get number of last row containing data in your whole sheet.
Selecting is a bad practice in VBA (slow - can't use for big data sets and non transparent for coding). You can refer to the cell from my code as Range("E" & TheLastRow).
Option Explicit
Sub Macro1()
Dim TheLastRow as long
TheLastRow = Columns(5).Find(What:="*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
End Sub

Macro for removing conditional formatting fill color Red

I have a large excel report and I am trying to make life easier for my technicians.
I have cells where if a number is not within 10% of another cell then that cell will highlight in RED. My problem is I do NOT want my customers to see the red highlight in my report. I have to convert my excel reports to PDF.
Is there a Macro code that would only take out the conditional formatting for highlight RED?
I have other conditional formatting in my report and that's why I cannot use the Macro code that deletes all conditional formatting.
Also, is there a Macro code that will make it go back to RED?
Any help on this is appreciated. Thanks
The answer is yes. First you need to identify the range you're working on.
Then check if your range has formatting, delete if yes, apply otherwise (like a toggling).
Below code does just that. Change the lines I've commented and adapt. HTH.
Sub ColorUnColor()
Dim myformat As String
Dim cfr As Range
myformat = "=A1<(0.1*B1)" '~~> change to suit
With Sheet2 '~~> change to suit
Set cfr = .Range("D1:D10") '~~> change to suit
If cfr.FormatConditions.Count = 0 Then
.Range("A1").FormatConditions.Add xlExpression, , myformat
With .Range("A1").FormatConditions(1)
.Interior.Color = RGB(255, 0, 0)
.ModifyAppliesToRange cfr
End With
Else
cfr.FormatConditions.Delete
End If
End With
End Sub
Result:
Important: You can assign conditional formatting in any Range, but it will be applied to what you set in ModifyAppliedToRange which I discussed in here.
You could use this to clear any cell on the sheet that is colored red (255). Not sure if that's exactly what you need.
Sub testes()
Dim SrchRng As Range
Set SrchRng = ActiveSheet.UsedRange
For Each Source In SrchRng
If Source.Interior.Color = 255 Then
Source.Interior.Color = xlNone
End If
Next Source
End Sub
As for going back to red couldn't you just run the macro you already have?
Try this:
Selection.FormatConditions.Delete

Automatically filling in 0 and 0% in Excel blank cells

I am trying to automatically enter 0 and 0% values in blank cells in Excel. I have a report in Excel that gets automatically filled up from SAS. After I save this report, I want the blank cells get automatically filled as 0 in numeric columns and 0% in percent columns.
What would the macro or VBA code be for that?
If you just want to add 0 to a blank cell, there are several ways to do that - here's one using range A1:D10 as an example. Note that if a cell is formatted as percentage, the "%" is automatically appended to the 0. :
Sub test()
Dim cell As Range
For Each cell In Range("A1:D10")
If Len(cell.Value) = 0 Then
cell.Value = 0
End If
Next
End Sub
Please note that if you are doing this on a large range of cells (actually it's good practice to do this all the time), you want to make sure you add Application.ScreenUpdating = False at the start of the code and Application.ScreenUpdating = True at the end. That will make it run much faster.
If the cells are truly blank (ie empty) then there are two ways to fill the cells immediately using SpecialCells, either manually, or with quick code avoiding loops.
David Mcritchie has written this up in detail here.
manual route
Make a selection
PressF5 ... Special .. Goto blanks
in the formula bar add 0
then press Ctrl + Enter
code route
Sub Quickfull()
'reset usedrange
ActiveSheet.UsedRange
On Error Resume Next
ActiveSheet.Cells.SpecialCells(xlBlanks).Value = 0
End Sub