I want to check if a range in Excel is empty.
How do I write in VBA code:
If Range("A38":"P38") is empty
Found a solution from the comments I got.
Sub TestIsEmpty()
If WorksheetFunction.CountA(Range("A38:P38")) = 0 Then
MsgBox "Empty"
Else
MsgBox "Not Empty"
End If
End Sub
If you find yourself in a situation where you can’t use CountA then it's much faster to first store your range as an array and loop on the array's data than it is to individually loop on range/cell data.
Function IsRangeEmpty(ByVal rng As Range) As Boolean
''Returns true if a value is found in parameter range.
''Converts parameter range to an array to check it quickly.
'if range has cells in it then
If Not rng Is Nothing Then
Dim area As Range
For Each area In rng.Areas 'checks through all sub-ranges within the original range e.g., rng=Range("A1:B5,C6:D9")
'if sub-range has more than one cell then
If area.Cells.Count > 1 Then
'save range as array
Dim arr As Variant
arr = area.value
'loop through array
Dim arrCell As Variant
For Each arrCell In arr
'if cell is not empty then
If Len(Trim(arrCell)) > 0 Then
IsRangeEmpty = False
Exit Function
End If
Next arrCell
Else 'unnecessary to loop on a single cell
'if cell is not empty then
If Len(Trim(area.Value2)) > 0 Then
IsRangeEmpty = False
Exit Function
End If
End If
Next area
End If
IsRangeEmpty = True
End Function
Example of how to use it:
Sub debug_IsRangeEmpty()
Debug.Print IsRangeEmpty(Range("A38:P38"))
End Sub
If Range("A38:P38") is empty, it would print True in the Immediate Window.
IsEmpty returns True if the variable is uninitialized, or is explicitly set to Empty; otherwise, it returns False. False is always returned if expression contains more than one variable. IsEmpty only returns meaningful information for variants. (https://msdn.microsoft.com/en-us/library/office/gg264227.aspx) . So you must check every cell in range separately:
Dim thisColumn as Byte, thisRow as Byte
For thisColumn = 1 To 5
For ThisRow = 1 To 6
If IsEmpty(Cells(thisRow, thisColumn)) = False Then
GoTo RangeIsNotEmpty
End If
Next thisRow
Next thisColumn
...........
RangeIsNotEmpty:
Of course here are more code than in solution with CountA function which count not empty cells, but GoTo can interupt loops if at least one not empty cell is found and do your code faster especially if range is large and you need to detect this case. Also this code for me is easier to understand what it is doing, than with Excel CountA function which is not VBA function.
Dim M As Range
Set M = Selection
If application.CountIf(M, "<>0") < 2 Then
MsgBox "Nothing selected, please select first BOM or Next BOM"
Else
'Your code here
End If
From experience I just learned you could do:
If Selection.Rows.Count < 2
Then End If`
Clarification to be provided a bit later (right now I'm working)
Dim cel As Range, hasNoData As Boolean
hasNoData = True
For Each cel In Selection
hasNoData = hasNoData And IsEmpty(cel)
Next
This will return True if no cells in Selection contains any data. For a specific range, just substitute RANGE(...) for Selection.
Another possible solution. Count empty cells and subtract that value from the total number of cells
Sub Emptys()
Dim r As range
Dim totalCells As Integer
'My range To check'
Set r = ActiveSheet.range("A1:B5")
'Check for filled cells'
totalCells = r.Count- WorksheetFunction.CountBlank(r)
If totalCells = 0 Then
MsgBox "Range is empty"
Else
MsgBox "Range is not empty"
End If
End Sub
This just a slight addition to #TomM's answer/ A simple function to check
if your Selection's cells are empty
Public Function CheckIfSelectionIsEmpty() As Boolean
Dim emptySelection As Boolean:emptySelection=True
Dim cell As Range
For Each cell In Selection
emptySelection = emptySelection And isEmpty(cell)
If emptySelection = False Then
Exit For
End If
Next
CheckIfSelectionIsEmpty = emptySelection
End Function
This single line works better imho:
Application.Evaluate("SUMPRODUCT(--(E10:E14<>""""))=0")
in this case, it evaluates if range E10:E14 is empty.
Related
I am completely new to visual basic. I have a few spreadsheets containing numbers. I want to delete any rows containing numbers outside of specific ranges. Is there a straightforward way of doing this in visual basic?
For example, in this first spreadsheet (image linked) I want to delete rows that contain cells with numbers outside of these two ranges: 60101-60501 and 74132-74532.
Can anyone give me some pointers? Thanks!
Code
You need to call it for your own needs as shown on the routine "Exec_DeleteRows". I assumed that you needed if it is equals or less to the one that you state on your routine. In this example, I will delete the rows where values are between 501-570 and then the ones between 100-200
Sub Exec_DeleteRows()
Call Exec_DeleteRowsInRangeBasedOnNumberValue(Range("C8:H11"), 501, 570)
Call Exec_DeleteRowsInRangeBasedOnNumberValue(Range("C8:H11"), 100, 200)
End Sub
Sub Exec_DeleteRowsInRangeBasedOnNumberValue(RangeToWorkIn As Range, NumPivotToDeleteRowBottom As Double, NumPivotToDeleteRowTop As Double)
Dim RangeRowsToDelete As Range
Dim ItemRange As Range
For Each ItemRange In RangeToWorkIn
If IsNumeric(ItemRange.Value) = False Then GoTo SkipStep1
If ItemRange.Value >= NumPivotToDeleteRowBottom And ItemRange.Value <= NumPivotToDeleteRowTop Then ' 1. If ItemRange.Value >= NumPivotToDeleteRowBottom And ItemRange.Value <= NumPivotToDeleteRowTop
If RangeRowsToDelete Is Nothing Then ' 2. If RangeRowsToDelete Is Nothing
Set RangeRowsToDelete = RangeToWorkIn.Parent.Rows(ItemRange.Row)
Else ' 2. If RangeRowsToDelete Is Nothing
Set RangeRowsToDelete = Union(RangeToWorkIn.Parent.Rows(ItemRange.Row), RangeRowsToDelete)
End If ' 2. If RangeRowsToDelete Is Nothing
End If ' 1. If ItemRange.Value >= NumPivotToDeleteRowBottom And ItemRange.Value <= NumPivotToDeleteRowTop
SkipStep1:
Next ItemRange
If Not (RangeRowsToDelete Is Nothing) Then RangeRowsToDelete.EntireRow.Delete
End Sub
Demo
Delete Rows Containing Wrong Numbers
It is assumed that the data starts in A1 of worksheet Sheet1 in the workbook containing this code (ThisWorkbook) and has a row of headers (2).
This is just a basic example to get familiar with variables, data types, objects, loops, and If statements. It can be improved on multiple accounts.
Option Explicit
Sub DeleteWrongRows()
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim ws As Worksheet: Set ws = wb.Worksheets("Sheet1") ' worksheet
Dim rg As Range: Set rg = ws.Range("A1").CurrentRegion ' range
Application.ScreenUpdating = False
Dim rrg As Range ' Row Range
Dim rCell As Range ' Cell in Row Range
Dim rValue As Variant ' Value in Cell
Dim r As Long ' Row
Dim DoDelete As Boolean
' Loop backwards through the rows of the range.
For r = rg.Rows.Count To 2 Step -1
Set rrg = rg.Rows(r)
' Loop through cells in row.
For Each rCell In rrg.Cells
rValue = rCell.Value
If IsNumeric(rValue) Then ' is a number
If rValue >= 60101 And rValue <= 60501 Then ' keep
ElseIf rValue >= 74132 And rValue <= 74532 Then ' keep
Else ' delete (outside the number ranges)
DoDelete = True
End If
Else ' is not a number
DoDelete = True
End If
If DoDelete Then ' found a cell containing a wrong value
rCell.EntireRow.Delete
DoDelete = False
Exit For ' no need to check any more cells
'Else ' found no cell containing a wrong value (do nothing)
End If
Next rCell
Next r
Application.ScreenUpdating = True
MsgBox "Rows with wrong numbers deleted.", vbInformation
End Sub
Using Range.Delete is the built-in way of completely erasing a row in Excel VBA. To check an entire row for numbers meeting a certain criteria, you would need a Loop and an If Statement.
To evaluate a lot of values at a faster pace, it is smart to first grab the relevant data off the Excel sheet into an Array. Once in the array, it is easy to set up the loop to run from the first element (LBound) to the final element (UBound) for each row and column of the array.
Also, when deleting a lot of Ranges from a worksheet, it is faster and less messy to first collect (Union) the ranges while you're still looping, and then do the delete as a single step at the end. This way the Range addresses aren't changing during the loop and you don't need to re-adjust in order to track their new locations. That and we can save a lot of time since the application wants to pause and recalculate the sheet after every Deletion.
All of those ideas put together:
Sub Example()
DeleteRowsOutside ThisWorkbook.Worksheets("Sheet1"), Array(60101, 60501), Array(74132, 74532)
End Sub
Sub DeleteRowsOutside(OnSheet As Worksheet, ParamArray Min_and_Max() As Variant)
If OnSheet Is Nothing Then Set OnSheet = ActiveSheet
'Find the Bottom Corner of the sheet
Dim BottomCorner As Range
Set BottomCorner = OnSheet.Cells.Find("*", After:=OnSheet.Range("A1"), SearchDirection:=xlPrevious)
If BottomCorner Is Nothing Then Exit Sub
'Grab all values into an array
Dim ValArr() As Variant
ValArr = OnSheet.Range(OnSheet.Cells(1, 1), BottomCorner).Value
'Check each row value against min & max
Dim i As Long, j As Long, DeleteRows As Range
For i = LBound(ValArr, 1) To UBound(ValArr, 1) 'For each Row
For j = LBound(ValArr, 2) To UBound(ValArr, 2) 'For each column
Dim v As Variant: v = ValArr(i, j)
If IsNumeric(v) Then
Dim BoundaryPair As Variant, Is_Within_A_Boundary As Boolean
Is_Within_A_Boundary = False 'default value
For Each BoundaryPair In Min_and_Max
If v >= BoundaryPair(0) And v <= BoundaryPair(1) Then
Is_Within_A_Boundary = True
Exit For
End If
Next BoundaryPair
If Not Is_Within_A_Boundary Then
'v is not within any acceptable ranges! Mark row for deletion
If DeleteRows Is Nothing Then
Set DeleteRows = OnSheet.Rows(i)
Else
Set DeleteRows = Union(DeleteRows, OnSheet.Rows(i))
End If
GoTo NextRow 'skip to next row
End If
End If
Next j
NextRow:
Next i
If Not DeleteRows Is Nothing Then DeleteRows.EntireRow.Delete
End Sub Exit For 'skip to next row
End If
End If
Next j
Next i
If Not DeleteRows Is Nothing Then DeleteRows.EntireRow.Delete
End Sub
I use a ParamArray to accept a variable number of Min and Max ranges. To keep things tidy, the Min and Max pairs are each in an array of their own. As long as all the numbers in the row are within any of the provided ranges, the row will not be deleted.
Here's some code with Regex and with scripting dictionary that I've been working on. I made this for my purposes, but it may be useful here and to others.
I found a way for selecting noncontinguous cells based on an array and then deleting those cells.
In this case, I selected by row number because VBA prevented deletion of rows due to overlapping ranges.
Sub findvalues()
Dim Reg_Exp, regexMatches, dict As Object
Dim anArr As Variant
Dim r As Range, rC As Range
Set r = Sheets(3).UsedRange
Set r = r.Offset(1).Resize(r.Rows.Count - 1, r.Columns.Count)
Set Reg_Exp = CreateObject("vbscript.regexp")
With Reg_Exp
.Pattern = "^[6-6]?[0-0]?[1-5]?[0-0]?[1-1]?$|^60501$" 'This pattern is for the 60101 to 60501 range.
End With
Set dict = CreateObject("Scripting.Dictionary")
For Each rC In r
If rC.Value = "" Then GoTo NextRC ''skip blanks
Set regexMatches = Reg_Exp.Execute(rC.Value)
If regexMatches.Count = 0 Then
On Error Resume Next
dict.Add rC.Row & ":" & rC.Row, 1
End If
NextRC:
Next rC
On Error GoTo 0
anArr = Join(dict.Keys, ", ")
Sheets(3).Range(anArr).Delete Shift:=xlShiftUp
End Sub
I'm new to Excel VBA and have double and triple checked my code and still can't seem to find the issue.
I'm trying to iterate through a column (A) and create a unique identifier of the concatenation of value in column C and a random number between 1 and 6MIL. I am also iterating through column C.
Appreciate any help in advance!
Here is my code:
Sub unique_id()
Dim c As Range
For Each i In Range("A:A")
For Each x In Range("C:C")
If IsNull(i.Value) = True Then
i.Value = Concat(x.Value, RandBetween(1, 6000000))
End If
End If
Next x
Next i
End Sub
There are a few things that need addressing in your code:
You are doing a nested loop over all cells in 2 columns (that's over 1,000,000,000,000,000,000 calculations per loop), as you can figure, not the best idea, rather set the range at the beginning
Dim all of your variables correctly, as pointed out in the comments
I'm assuming by using the IsNull() function you are implying that there's no value in the cell? In that case it's better to use if val = "" then
You need to take into account error checking, part of this being that if you are creating unique IDs you need to check whether they really are unique (already exist or not)
Try the following code out, adjust as necessary
Sub unique_ID()
Dim c As Range
Dim rng As Range
Dim uniqueID As String
Dim dupeFlag As Boolean 'flag to check for duplicate IDs
Set rng = Intersect(ActiveSheet.UsedRange, ActiveSheet.Columns("C")) 'goes through only the cells which have been used
For Each c In rng.Cells
If CStr(c.Offset(, -2).value) = "" Then 'checks if col A has any value inside
dupeFlag = True 'turns flag on for the while loop
Do While dupeFlag
uniqueID = c.value & Application.WorksheetFunction.RandBetween(1, 6000000) 'create the unique ID
If findDuplicate(uniqueID, rng.Offset(, -2)) = False Then 'checks if the ID already exists
c.Offset(, -2) = uniqueID 'if ID doesn't exist then then write it to col A
dupeFlag = False 'flag turns off to go to next cell
End If
Loop
End If
Next
End Sub
Function findDuplicate(val As String, srchRng As Range) As Boolean
'function to check if a duplicate is found in a range (the above macro calls it)
Dim cell As Range
For Each cell In srchRng.Cells
If cell.value = val Then
findDuplicate = True
Exit Function
End If
Next
findDuplicate = False
End Function
I want to check if a range in Excel is empty.
How do I write in VBA code:
If Range("A38":"P38") is empty
Found a solution from the comments I got.
Sub TestIsEmpty()
If WorksheetFunction.CountA(Range("A38:P38")) = 0 Then
MsgBox "Empty"
Else
MsgBox "Not Empty"
End If
End Sub
If you find yourself in a situation where you can’t use CountA then it's much faster to first store your range as an array and loop on the array's data than it is to individually loop on range/cell data.
Function IsRangeEmpty(ByVal rng As Range) As Boolean
''Returns true if a value is found in parameter range.
''Converts parameter range to an array to check it quickly.
'if range has cells in it then
If Not rng Is Nothing Then
Dim area As Range
For Each area In rng.Areas 'checks through all sub-ranges within the original range e.g., rng=Range("A1:B5,C6:D9")
'if sub-range has more than one cell then
If area.Cells.Count > 1 Then
'save range as array
Dim arr As Variant
arr = area.value
'loop through array
Dim arrCell As Variant
For Each arrCell In arr
'if cell is not empty then
If Len(Trim(arrCell)) > 0 Then
IsRangeEmpty = False
Exit Function
End If
Next arrCell
Else 'unnecessary to loop on a single cell
'if cell is not empty then
If Len(Trim(area.Value2)) > 0 Then
IsRangeEmpty = False
Exit Function
End If
End If
Next area
End If
IsRangeEmpty = True
End Function
Example of how to use it:
Sub debug_IsRangeEmpty()
Debug.Print IsRangeEmpty(Range("A38:P38"))
End Sub
If Range("A38:P38") is empty, it would print True in the Immediate Window.
IsEmpty returns True if the variable is uninitialized, or is explicitly set to Empty; otherwise, it returns False. False is always returned if expression contains more than one variable. IsEmpty only returns meaningful information for variants. (https://msdn.microsoft.com/en-us/library/office/gg264227.aspx) . So you must check every cell in range separately:
Dim thisColumn as Byte, thisRow as Byte
For thisColumn = 1 To 5
For ThisRow = 1 To 6
If IsEmpty(Cells(thisRow, thisColumn)) = False Then
GoTo RangeIsNotEmpty
End If
Next thisRow
Next thisColumn
...........
RangeIsNotEmpty:
Of course here are more code than in solution with CountA function which count not empty cells, but GoTo can interupt loops if at least one not empty cell is found and do your code faster especially if range is large and you need to detect this case. Also this code for me is easier to understand what it is doing, than with Excel CountA function which is not VBA function.
Dim M As Range
Set M = Selection
If application.CountIf(M, "<>0") < 2 Then
MsgBox "Nothing selected, please select first BOM or Next BOM"
Else
'Your code here
End If
From experience I just learned you could do:
If Selection.Rows.Count < 2
Then End If`
Clarification to be provided a bit later (right now I'm working)
Dim cel As Range, hasNoData As Boolean
hasNoData = True
For Each cel In Selection
hasNoData = hasNoData And IsEmpty(cel)
Next
This will return True if no cells in Selection contains any data. For a specific range, just substitute RANGE(...) for Selection.
Another possible solution. Count empty cells and subtract that value from the total number of cells
Sub Emptys()
Dim r As range
Dim totalCells As Integer
'My range To check'
Set r = ActiveSheet.range("A1:B5")
'Check for filled cells'
totalCells = r.Count- WorksheetFunction.CountBlank(r)
If totalCells = 0 Then
MsgBox "Range is empty"
Else
MsgBox "Range is not empty"
End If
End Sub
This just a slight addition to #TomM's answer/ A simple function to check
if your Selection's cells are empty
Public Function CheckIfSelectionIsEmpty() As Boolean
Dim emptySelection As Boolean:emptySelection=True
Dim cell As Range
For Each cell In Selection
emptySelection = emptySelection And isEmpty(cell)
If emptySelection = False Then
Exit For
End If
Next
CheckIfSelectionIsEmpty = emptySelection
End Function
This single line works better imho:
Application.Evaluate("SUMPRODUCT(--(E10:E14<>""""))=0")
in this case, it evaluates if range E10:E14 is empty.
In line with a previous question I asked I am trying to hide rows that contain zeros, but skip over rows that contain any text in any one or more cells. I received excellent help previously skipping blank rows, and was hoping for more help now. I've searched through the internet on every forum I can find and have found nothing that does what I need it to. There are two codes on that hides and an exact copy of that one but with hide set to false. Here is the one that Hides.
Sub HideRows()
Dim R As Long
Dim Rng As Range
If Selection.Rows.Count > 1 Then
Set Rng = Selection
Else
Set Rng = ActiveSheet.UsedRange
End If
For R = 1 To Rng.Rows.Count
Set myRange = Range(Rng(R, 2), Rng(R, Rng.Columns.Count))
If Application.CountBlank(myRange) <> myRange.Cells.Count And IsNumeric(myRange(Row)) = False Then
If Application.Sum(myRange) = 0 Then
Rng.Rows(R).Hidden = True
End If
End If
Next R
End Sub
By the way I know that the IsNumeric(myRange(Row)) = False really should probably be = True, but for some reason on one of my worksheets this setup works and if I change to True it pretty much does nothing.
Thanks in Advance for any help.
When I tried your code, I got the following syntax errors:
myRange is not defined.
Row (as in myRange(Row)) is undefined.
Other issues with your code:
myRange is a range so IsNumeric(myRange) will always be false.
If Application.CountBlank(myRange) <> myRange.Cells.Count means blank rows are not hidden.
IsNumeric and IsNumber both operate on a single value. I can find nothing in the documentation to suggest they can be made to operate on arrays, collections or ranges. My experiments have produced results consistant with this. I do not believe there is any way of handling the difficult cases except by checking individual cells within a row.
I think I have tested the following code for all the boundary conditions but I cannot guarantee this. It hides blank rows and rows that contain nothing but zeros. If a range is selected, columns outside that range are treated as blank.
Sub HideRows()
Dim ColCrnt As Integer
Dim Hide As Boolean
Dim myRange As Range
Dim R As Long
Dim Rng As Range
If Selection.Rows.Count > 1 Then
Set Rng = Selection
Else
Set Rng = ActiveSheet.UsedRange
End If
For R = 1 To Rng.Rows.Count
Set myRange = Range(Rng(R, 1), Rng(R, Rng.Columns.Count))
If Application.CountBlank(myRange) = myRange.Cells.Count Then
' Blank row
Hide = True
ElseIf Application.Sum(myRange) <> 0 Then
' At least on numeric cell with a non-zero value
Hide = False
Else
' Row contains one or more cells containing text, booleans or zeroes
' Hide if all these cells are zeros.
ColCrnt = Rng.Columns.Count
Set myRange = Rng(R, ColCrnt)
If IsCellZero(myRange) Or IsEmpty(myRange) Then
' Last cell of row is zero or blank so will have to check row
Do While True
' Skip to first non-blank cell to left or column 1
' if no non-blank cells
Set myRange = myRange.End(xlToLeft)
If myRange.Column < Rng(R, 1).Column Then
' Have move outside selection
Hide = True
Exit Do
End If
If myRange.Column = Rng(R, 1).Column Then
' Have reached column 1
If IsCellZero(myRange) Or IsEmpty(myRange) Then
' Column 1 is zero or blank so nothing interesting on row
Hide = True
Exit Do
Else
' Column 1 is not zero or blank
Hide = False
Exit Do
End If
End If
If Not IsCellZero(myRange) Then
Hide = False
Exit Do
End If
If myRange.Column = Rng(R, 1).Column Then
' No non-zero cells found
Hide = True
Exit Do
End If
Loop
Else
' Last cell of row is neither zero nor empty
Hide = False
End If
End If
If Hide Then
Rng.Rows(R).Hidden = True
Else
Rng.Rows(R).Hidden = False
End If
Next R
End Sub
Function IsCellZero(Rng As Range) As Boolean
' Rng must be a single cell. Returns true only if Rng.Value is numeric zero
' Function uses IsNumber because IsNumeric returns True
' for empty cells and booleans
If Application.WorksheetFunction.IsNumber(Rng.Value) Then
If Val(Rng.Value) = 0 Then
IsCellZero = True
Else
IsCellZero = False
End If
Else
' Value is blank, text or boolean
IsCellZero = False
End If
End Function
The cause of your problems is And IsNumeric(myRange(Row)) = False
Row is undefined and never set. So it will have the default value of 0. Therefore (since myRange is defined starting at column 2) myRange(Row) refers to the single cell in column A on the row myRange refers to.
If you drop the (Row) bit, IsNumeric will always return FALSE
Also, Set myRange = Range(Rng(R, 2), refers to Row R of the used range, offset one column to the right
Conclusion:
Assuming you want to test all cells, change to `Set myRange = Range(Rng(R, 1), Rng(R, Rng.Columns.Count))
To correctly test for no non-numeric cells use
If Application.Count(myRange) > 0 And _
Application.CountBlank(myRange) + _
Application.Count(myRange) = myRange.Cells.Count Then
By the way, its good practice DIM all you variables. This would have identified the issue with (Row). If you add Option Explicit to the top of your module this will become manditory.
Here's what I need to do:
1) Loop through every cell in a worksheet
2) Make formatting changes (bold, etc) to fields relative to each field based on the value
What I mean is that if a field has a value of "foo", I want to make the field that is (-1, -3) from it bold, etc. I tried to do this with the following script with no luck.
Thanks
Johnny
Pseudo Code to Explain:
For Each Cell in WorkSheet
If Value of Cell is 'Subtotal'
Make the cell 2 cells to the left and 1 cell up from here bold and underlined
End If
End ForEach
The Failed Macro (I don't really know VB at all):
Sub Macro2()
'
'
'
Dim rnArea As Range
Dim rnCell As Range
Set rnArea = Range("J1:J2000")
For Each rnCell In rnArea
With rnCell
If Not IsError(rnCell.Value) Then
Select Case .Value
Case "000 Total"
ActiveCell.Offset(-1, -3).Select
ActiveCell.Font.Underline = XlUnderlineStyle.xlUnderlineStyleSingleAccounting
End Select
End If
End With
Next
End Sub
Option Explicit
Private Sub macro2()
Dim rnArea As Range
Dim rnCell As Range
' you might need to change the range to the cells/column you want to format e. g. "G1:G2000" '
Set rnArea = Range("J1:J2000")
For Each rnCell In rnArea
With rnCell
If isBold(.Offset(1, 3).Value) Then
.Font.Bold = True
End If
If isUnderlined(.Offset(1, 3).Value) Then
'maybe you want this: .Font.Underline = xlUnderlineStyleSingle '
.Font.Underline = xlUnderlineStyleSingleAccounting
End If
End With
Next
End Sub
Private Function isBold(cellValue As Variant) As Boolean
Dim myList() As Variant
Dim listCount As Integer
Dim i As Integer
myList = Array("Totals", "FooTotal", "SpamTotal")
listCount = 3
isBold = False
For i = 0 To listCount - 1
If cellValue = myList(i) Then
isBold = True
Exit Function
End If
Next i
End Function
Private Function isUnderlined(cellValue As Variant) As Boolean
Dim myList() As Variant
Dim listCount As Integer
Dim i As Integer
myList = Array("FooTotal", "SpamTotal")
listCount = 2
isUnderlined = False
For i = 0 To listCount - 1
If cellValue = myList(i) Then
isUnderlined = True
Exit Function
End If
Next i
End Function
I added two functions but it should have also worked with an extensive if / else if / else.
Based on the comments on the solution above, i think this might be helpful
Sub FormatSpecialCells()
Dim SearchRange As Range
Dim CriteriaRange As Range
Set SearchRange = Range("A2:A24")
Set CriteriaRange = Range("C2:C5")
Dim Cell As Range
For Each Cell In SearchRange
TryMatchValue Cell, CriteriaRange
Next
End Sub
Private Sub TryMatchValue(CellToTest As Range, CellsToSearch As Range)
Dim Cell As Range
For Each Cell In CellsToSearch
If Cell.Value = CellToTest.Value Then
Cell.Copy
CellToTest.PasteSpecial xlPasteFormats, xlPasteSpecialOperationNone, False, False
End If
Next
End Sub
This does not fully accomplish your goal. What it does is it searches a specified list of cells, and it matches them against a seperate list of cells. If it matches the values, it takes the FORMAT of the second list of cells and applies it to the cell it matched in the first list of cells. You can modify this by changing the TryMatchValue function so that instead of matching the CellToTest, it pastes the format onto another cell which is 2 across and one up.
This has the advantage that, if you want to add more values and different formats, you only need to go to your excel sheet and add more values. Also you only need to change the format on that value.
An example would be...
Have the cells you are searching in A1:D1000
Have these values in cells E2:E6...
Subtotal (which is bold and underlined)
Total (which is bold, underlined and italic)
Net (which is bold underlined and Red)
etc...
then when it hits Subtotal, it will change the cell to be bold and underlined.
When it hits Total it will change the cell to be bold underlined and italic
etc etc...
hope this helps
Would the conditional formatting functionality in excel give you what you need without having to write a macro?