vba looking for a fast way to highlight every other row - excel

so far I have this and it's VERY slow for big data sets. Any help
'For every row in the current selection...
For Counter = 1 To RNG.Rows.Count 'reccnt
'If the row is an odd number (within the selection)...
If Counter Mod 2 = 1 Then
With RNG.Rows(Counter).Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent6
.TintAndShade = 0.799981688894314
.PatternTintAndShade = 0
End With
End If
Next

Give this a try. I imagine it would speed things up a bit. It runs for me almost instantly.
Sub ColorEven()
Set rng = Rows("1:40000")
rng.FormatConditions.Add Type:=xlExpression, Formula1:="=MOD(ROW(),2)=0"
rng.FormatConditions(1).Interior.Pattern = xlSolid
rng.FormatConditions(1).Interior.PatternColorIndex = xlAutomatic
rng.FormatConditions(1).Interior.ThemeColor = xlThemeColorAccent6
rng.FormatConditions(1).Interior.TintAndShade = 0.799981688894314
rng.FormatConditions(1).Interior.PatternTintAndShade = 0
End Sub

an alternative and very Fast (50k rows in no time) method without conditional formatting:
Option Explicit
Sub main()
Dim i As Long, nRows As Long
Dim hlpCol As Range
Dim indexArray1() As Long, indexArray2() As Long
With Range("A1:A50000")
nRows = .Rows.Count '<~~ retrieve n° of rows to be processed
ReDim indexArray1(1 To nRows) '<~~ redim indexArray1 accordingly
ReDim indexArray2(1 To nRows) '<~~ redim indexArray2 accordingly
' fill indexArrays
For i = 1 To nRows
indexArray1(i) = i 'indexArray1, which stores the initial range order
indexArray2(i) = IIf(.Cells(i, 1).Row Mod 2 = 1, i, nRows + i) 'indexArray2, "marks" range "even" rows to be "after" "uneven" ones
Next i
Set hlpCol = .Offset(, .Parent.UsedRange.Columns.Count) '<~~ set a "helper" column ...
hlpCol.Value = Application.Transpose(indexArray1) '<~~ ... fill it with indexArray1...
hlpCol.Offset(, 1).Value = Application.Transpose(indexArray2) '<~~ ... and the adjacent one with indexArray2
.Resize(, hlpCol.Column + 1).Sort key1:=hlpCol.Offset(, 1) '<~~ sort range to group range "uneven" rows before "even" ones
' format only half of the range as wanted
With .Resize(.Rows.Count / 2).Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent6
.TintAndShade = 0.799981688894314
.PatternTintAndShade = 0
End With
.Resize(, hlpCol.Column + 1).Sort key1:=hlpCol '<~~ sort back the range to its initial order
End With
hlpCol.Resize(, 2).Clear '<~~ clear helper columns
End Sub

Use a table!! It's automatically colour banded.

Related

How to put conditional formatting in selected cell?

Conditional Formatting Condition:If selected cell("cel7") is not blank then put Black fill on it.
How can i modify my current code in such away that conditional formatting condition is used in cel7.
I tried to use xlnoblankscondition but i could not find any VBA examples of it on web.
P.S:As i have written all cel7 cell as C1,every condition will be true ie NOT BLANK.
x = ws.Range("A4").Value
y = ws.Range("A5").Value
ocol = 4
Set cel = Range("E6")
Set cel7 = cel.Offset(2, 0)
For m = 1 To x
For o = 1 To y
cel7.Value = "C1"
cel7.Select
With Selection
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlCenter
End With
Set cel7 = cel7.Offset(4, 0)
Next
Set cel = cel.Offset(0, ocol)
Set cel7 = cel7.Offset(0, ocol)
Next
I'm sorry as I'm still not clear on what you mean.
Anyway, I'm guessing that you want to coding the Conditional Formatting, just like when you do it manually.
I find the code below after I macro recording my manual step in Conditional Formatting.
I think the code in your condition maybe like this :
Sub test()
Cells.FormatConditions.Delete
cel7.Select
cf = cel7.Address(0, 0)
Selection.FormatConditions.Add Type:=xlExpression, Formula1:= _
"=NOT(ISBLANK(" & cf & "))"
Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
With Selection.FormatConditions(1).Font
.ThemeColor = xlThemeColorDark1
.TintAndShade = 0
End With
With Selection.FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorLight1
.TintAndShade = 0
End With
Selection.FormatConditions(1).StopIfTrue = False
Application.WindowState = xlMaximized
End Sub
I try the code above by having cel7 variable refer to cell D10.
After I run the code, if I type something in cell D10, D10 fill black with white font.
If I clear the content of D10, D10 back to normal (no fill).
Also I try by having cel7 variable to a range D2 to D10.
If I type on any cell within D2:D10, the cell fill black with white font.
If I clear it, the cell back to normal.
But once again, maybe that's not what you want to achieve.
If I'm not mistaken read your code, it seems that your cel7 formatting is a non-contagious row. So please try your o loop like this one :
Cells.FormatConditions.Delete 'put this line before m loop
For m = 1 To x
For o = 1 To y
Cel7.Select
cf = Cel7.Address(0, 0)
Selection.FormatConditions.Add Type:=xlExpression, Formula1:= _
"=NOT(ISBLANK(" & cf & "))"
Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
With Selection.FormatConditions(1).Font
.ThemeColor = xlThemeColorDark1
.TintAndShade = 0
End With
With Selection.FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorLight1
.TintAndShade = 0
End With
Selection.FormatConditions(1).StopIfTrue = False
Application.WindowState = xlMaximized
Set Cel7 = Cel7.Offset(4, 0)
Next o
In the code below I took out your Selection of Cel7. You can address the range directly. I also added variable declarations. Omitting them causes more work than it saves. For the rest of it, the cell color is applied if the cell is found not to be Empty.
Sub Macro1()
Dim Ws As Worksheet
Dim Cel As Range, Cel7 As Range
Dim Tmp As Variant
Dim oCol As Long
Dim x As Long, y As Long
Dim m As Long, o As Long
Set Ws = ActiveSheet
x = Ws.Range("A4").Value
y = Ws.Range("A5").Value
oCol = 4
Set Cel = Ws.Range("E6")
Set Cel7 = Cel.Offset(2, 0)
For m = 1 To x
For o = 1 To y
With Cel7
Tmp = "C1" ' avoid read/write to sheet multiple times
.Value = Tmp
If IsEmpty(Tmp) Then
.Interior.Pattern = xlNone
Else
.Interior.Color = vbBlack
End If
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlCenter
End With
Set Cel7 = Cel7.Offset(4, 0)
Next o
Set Cel = Cel.Offset(0, oCol)
Set Cel7 = Cel7.Offset(0, oCol)
Next m
End Sub

How to create a macro which will copy data from row to column, using conditions?

I am using currently v lookup to find and place values against the specific item. however, I am looking for help for a VB macro which will out the data in defined outcome.
please see 1st screen shot of raw data
second screen shot, should be the outcome.
Please note the "site" is not constant it can be any value, so I have put all site in column A .
currently V look is doing the job well. but makes the file crash sometime.
You can solve this with a Pivot Table using your original data source with NO changes in the table layout.
Drag the columns as shown below (you'll want to rename them from the default names): For Columns, drag the Date field there first. The Σ Values field will appear after you've dragged two Fields to the Values area, and should be below Date.
And with some formatting changes from the default, the result can look like:
Can you change your source data?
If you change your data to look like the table "Changed Source Data" below you can solve your issue with a pivot table.
Solution with a Pivot Table
Changed Source Data
There question can easily solved with pivot table. For practice i have create the below.
Let us assume that:
Data appears in Sheet "Data"
Results will be populated in sheet "Results"
Option Explicit
Sub Allocation()
Dim LastRow As Long, Row As Long, Column As Long, Invetory As Long, Sold As Long, Remaining As Long, LastRowRes As Long, LastColRes As Long, CurrentCol As Long, CurrentRow As Long, i As Long, y As Long
Dim iDate As Date
Dim Site As String
Dim wsData As Worksheet, wsResults As Worksheet
Dim ExcistSite As Boolean, ExcistDate As Boolean
Set wsData = ThisWorkbook.Worksheets("Data")
Set wsResults = ThisWorkbook.Worksheets("Results")
LastRow = wsData.Cells(wsData.Rows.Count, "A").End(xlUp).Row
wsResults.UsedRange.Clear
For Row = 2 To LastRow
iDate = wsData.Cells(Row, 1).Value
Site = wsData.Cells(Row, 2).Value
Invetory = wsData.Cells(Row, 3).Value
Sold = wsData.Cells(Row, 4).Value
Remaining = wsData.Cells(Row, 5).Value
If Row = 2 Then
With wsResults.Range("B1:D1")
.Merge
.Value = iDate
End With
wsResults.Range("A2").Value = "Site"
wsResults.Range("A2").Offset(1, 0).Value = Site
wsResults.Range("B2").Value = "Invetory"
wsResults.Range("B2").Offset(1, 0).Value = Invetory
wsResults.Range("C2").Value = "Sold"
wsResults.Range("C2").Offset(1, 0).Value = Sold
wsResults.Range("D2").Value = "Remaining"
wsResults.Range("D2").Offset(1, 0).Value = Remaining
Else
'Check if Site appears
LastRowRes = wsResults.Cells(wsResults.Rows.Count, "A").End(xlUp).Row
For i = 3 To LastRowRes
ExcistSite = False
If wsResults.Cells(i, 1).Value = Site Then
CurrentRow = i
ExcistSite = True
Exit For
Else
CurrentRow = i + 1
End If
Next i
If ExcistSite = False Then
wsResults.Cells(CurrentRow, 1).Value = Site
End If
'Check if date appears
LastColRes = wsResults.Cells(1, wsResults.Columns.Count).End(xlToLeft).Column
For y = 2 To LastColRes
ExcistDate = False
If wsResults.Cells(1, y).Value = iDate Then
CurrentCol = y
ExcistDate = True
Exit For
Else
CurrentCol = y + 1
End If
Next y
If ExcistDate = False Then
wsResults.Cells(2, CurrentCol + 2).Value = "Invetory"
wsResults.Cells(i, CurrentCol + 2).Value = Invetory
wsResults.Cells(2, CurrentCol + 3).Value = "Sold"
wsResults.Cells(i, CurrentCol + 3).Value = Sold
wsResults.Cells(2, CurrentCol + 4).Value = "Remaining"
wsResults.Cells(i, CurrentCol + 4).Value = Remaining
With wsResults.Range(Cells(1, LastColRes + 3), Cells(1, LastColRes + 5))
.Merge
.Value = iDate
End With
Else
wsResults.Cells(CurrentRow, CurrentCol).Value = Invetory
wsResults.Cells(CurrentRow, CurrentCol + 1).Value = Sold
wsResults.Cells(CurrentRow, CurrentCol + 2).Value = Remaining
End If
End If
Next Row
LastColRes = wsResults.Cells(1, wsResults.Columns.Count).End(xlToLeft).Column
LastRowRes = wsResults.Cells(wsResults.Rows.Count, "A").End(xlUp).Row
With wsResults.Range(Cells(1, 2), Cells(1, LastColRes))
With .Font
.Bold = True
.ThemeColor = xlThemeColorDark1
End With
With .Interior
.ThemeColor = xlThemeColorAccent1
End With
End With
With wsResults.Cells(2, 1)
With .Font
.Bold = True
.ThemeColor = xlThemeColorDark1
End With
With .Interior
.ThemeColor = xlThemeColorLight1
End With
End With
For i = 2 To LastColRes Step 3
With wsResults.Range(Cells(2, i), Cells(LastRowRes, i))
With .Interior
.ThemeColor = xlThemeColorAccent1
.TintAndShade = 0.399975585192419
End With
End With
Next i
For i = 3 To LastColRes + 3 Step 3
With wsResults.Range(Cells(2, i), Cells(LastRowRes, i + 1))
With .Font
.ThemeColor = xlThemeColorDark2
.TintAndShade = -0.249977111117893
End With
End With
Next i
With wsResults.UsedRange
.Borders.LineStyle = xlContinuous
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlCenter
.EntireColumn.AutoFit
End With
End Sub

Adding new row and give color if cells are emty

working on work project and i am stuck.
I allready have a function thats add a new row over active cell.
Now i want to add grey color to new row, and when new row cells has letters or numbers in it, it will appear as no color (hvite). SEE IMAGE OF PROJECT HERE
Also i dont want the color to go longer than column S as ilustrated in image.
Im not the author of this code. And theres is much i dont even understand. Code goes as follows. AND THERE MAY BE SOME TYPE ERRORS IN THIS CODE, HAD TO WRITE IT FROM A COMPUTER TO ANOTHER. THE CODE BELOW WORKS. just need to add the color to the row
`Sub insert_row()
Dim LineNumber As Integer
Dim insertionpoint
Dim Rownumber, Positionrow As Integer
Dim MarkedArea As String
Application.ScreenUpdating = False 'Stops screenupdating
Insertionpoint = ActiveCell.Address
LineNumber = ActiveCell.Row
For Rownumber = 5 To 1000
If Range("B" & Rownumber).Value = "PLACE" Then
Positionrow = Rownumber + 1
End If
Next Rownumber
If LineNumber < Positionrow - 5 And LineNumber > 6 Then
Range(Insertionpoint).Select
Selection.EntireRow.Insert 'Inserts new row over active cell
LineNumber = ActiveCell.Row
Range("A" & LineNumber).Select
ActiveCell.FormulaR1C1 = "=IF(RC[1]="""","""",TEXT(RC[1],""DDMM"")&""0""&RC[2])"
'More cell properties .....
'More .....
'More .....
MarkedArea = "B" & LineNumber & ":X" & LineNumber
Range("B" & LineNumber).Select
'SetStandardFormat
Range("AB6:AS6).Select ' not shown in picture
Selection.Copy
Range(Insertionpoint).Select
Selection.PasteSpecial Paste:=x1PasteFormats, Operation:=x1None, _
SkipBlanks:=False, Transpose:=False
Else
MsgBox ("Row can not be added here")
End If
Application.ScreenUpdating = False
End Sub`
Also there is a button with this in it
Private Sub CommandButton2_Click()
'add row
Insert_row
End Sub
Hope for some help! Thanks.
You just want a grey-color to the added row?
Insertionpoint = ActiveCell.Address
Range(Insertionpoint).Select
Selection.EntireRow.Insert
With Range(Insertionpoint).EntireRow.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorDark1
.TintAndShade = -0.249977111117893
.PatternTintAndShade = 0
End With
Giving what I used to test... didn't fix any .select, and pulled out what I needed to test, from your code.
Edit
Adding some code for the loop to add color... will assume that the date is in Column B:
Dim i As Long, LR As Long
LR = Cells(Rows.Count, "A").End(xlUp).Row 'assumes column A is contiguous
For i = 2 To LR 'Assumes row 1 is headers
If Cells(i, "B").Value = "" Then
With Rows(i).EntireRow.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorDark1
.TintAndShade = -0.249977111117893
.PatternTintAndShade = 0
End With
Else
Rows(i).EntireRow.Interior.Color = xlNone
End If
Next i

How to highlight cells with decimals or characters less than 3 and more than 6 using vba?

I'm new to VBA coding and please help me create a VBA script with the following conditions.
Should highlight cells containing decimals.
Should highlight cells with number of characters less than 3 or more than 6.
Should execute from Column G (G1) till the last row last used cell.
My data is alphanumeric or numeric.
I have tried using characters.count and Value.count but it didn't work out. Hope it will work with len, but I'm not sure how to start with.
Attached is the sample excel file with highlighted cells
I have tried the below code. Since my data is alphanumeric, characters count doesn't help.
Sub HighlightCells()
Range(" G1").Select
Do
If ActiveCell.Characters.Count < 3 Then
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
End If
ActiveCell.Offset(0, 1).Select 'need to run in every row till the last row last used cell
Loop Until ActiveCell = ""
Range(" G1").Select
Do
If ActiveCell.Characters.Count > 6 Then
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
End If
ActiveCell.Offset(0, 1).Select 'need to run in every row till the last row last used cell
Loop Until ActiveCell = ""
End Sub
Before:
This code is almost a direct translation of your description in English into VBA:
Sub Dural()
Dim N As Long, i As Long, s As String, L As Long
N = Cells(Rows.Count, "G").End(xlUp).Row
For i = 1 To N
s = Cells(i, "G").Text
L = Len(s)
If InStr(1, s, ".") > 0 Or (L < 3 Or L > 6) Then
With Cells(i, "G").Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
End If
Next i
End Sub
and after:
Sub Test()
Application.ScreenUpdating = False
LastRow = Rows(ActiveSheet.UsedRange.Row + _
ActiveSheet.UsedRange.Rows.Count - 1).Row
LastCol = Columns(ActiveSheet.UsedRange.Column + _
ActiveSheet.UsedRange.Columns.Count - 1).Column
For Each cll In Range(Cells(1, 7), Cells(LastRow, LastCol))
s = cll.Value
l = Len(s)
If ((l > 0) And (l < 3)) Or (l > 6) Or (s Like "*#.#*") _
Then cll.Interior.Color = vbRed
Next cll
Application.ScreenUpdating = True
End Sub

Excel Range selection problem

I'm trying to make a macro that select colors a group of 5 cells
So basically it goes:
clear, yellow, blue, clear, yellow, blue, ...
Sub ColorBanding()
Dim num As Integer
For i = 2 To 50
Dim range As String
range("A" + Str(i) + ":E" + Str(i)).Select
If i Mod 3 = 0 Then
Cells(1, 1).Select
' Yellow
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
ElseIf i Mod 3 = 2 Then
' Blue
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent1
.TintAndShade = 0.399975585192419
.PatternTintAndShade = 0
End With
End If
Next i
End Sub
I'm having trouble with this line:
"range("A" + Str(i) + ":E" + Str(i)).Select"
Example on evaluation for i = 2:
outputs: "A 2:E 2"
should be: "A2:E2"
The technical error I get is:
"Expected an array"
Is there a better way of doing this?
And is there a way to get this way to work right?
This is correct syntax. Also don't select/activate anything as it only slows things down. What use is 'num'?
Sub test()
Dim num As Integer, MyRange As Range, i As Integer
For i = 2 To 50
Set MyRange = Range("A" & i & ":E" & i)
MsgBox MyRange.Address 'Delete this test line
With MyRange.Cells(1, 1).Interior
If (i Mod 3) = 0 Then
'Yellow
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
ElseIf i Mod 3 = 2 Then
'Blue
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent1
.TintAndShade = 0.399975585192419
.PatternTintAndShade = 0
End If
End With
Next i
End Sub
The problem is here
Dim num As Integer
For i = 2 To 50
Dim range As String
range("A" + Str(i) + ":E" + Str(i)).Select
If i Mod 3 = 0 Then
Cells(1, 1).Select
Please put all dims at the top
dim range as string? what where you thinking, a range is a range. As in a lumb of cells on a worksheet.
range is a reserved word, don't use it as a variable name, use something like MyRange instead.
Objects (like range, worksheet etc..) can only be assigned in a Set object = reference_to_other_object_of_the_same_type statement, see below.
Cells(1,1) relative to what? The default object is ActiveWorksheet and ActiveWorksheet.Cells(1,1) is permanently fixed to cell "A1". MyRange.Cells(1,1) on the other hand can move around.
In VBA '&' concatenates strings, the '+' operator only works on numbers
Change it to:
Dim num As Integer
Dim MyRange as Range
Dim i as Integer
For i = 2 To 50
Set MyRange = range("A" & Str(i) & ":E" & Str(i))
MyRange.Select
If (i Mod 3) = 0 Then
MyRange.Cells(1, 1).Select
...
Haven't tested the code yet, but I'm pretty sure it is close.

Resources