So I'm at the last hurdle with my VBA coding. I'm creating a schedule for several different countries and need the background for cells A7:H300 to colour automatically depending on a value within the same specific row being the country code.
I know I could use conditional formatting but the colours do not copy and paste into a separate sheet using that method.
The code I have below works but it colours D:K instead of the expected A:H - The value is in Row D so I'm guessing that's the problem but I can't workout a way around it.
Thank you for you help :)
Sub ChangeColour()
Set PC = Range("A:H")
For Each cell In PC
If cell.Value = "BEZEE" Then cell.Columns("A:H").Interior.ColorIndex = 40
If cell.Value = "BEANR" Then cell.Columns("A:H").Interior.ColorIndex = 40
If cell.Value = "DEBRH" Then cell.Columns("A:H").Interior.ColorIndex = 37
If cell.Value = "FRLEH" Then cell.Columns("A:H").Interior.ColorIndex = 38
If cell.Value = "GBBRS" Then cell.Columns("A:H").Interior.ColorIndex = 35
If cell.Value = "GBLPL" Then cell.Columns("A:H").Interior.ColorIndex = 35
If cell.Value = "GBSOU" Then cell.Columns("A:H").Interior.ColorIndex = 35
If cell.Value = "NLRTM" Then cell.Columns("A:H").Interior.ColorIndex = 40
If cell.Value = "FIHNO" Then cell.Columns("A:H").Interior.ColorIndex = 36
If cell.Value = "SEGOT" Then cell.Columns("A:H").Interior.ColorIndex = 36
If cell.Value = "ZADUR" Then cell.Columns("A:H").Interior.ColorIndex = 45
If cell.Value = "ZAELS" Then cell.Columns("A:H").Interior.ColorIndex = 45
If cell.Value = "ZAPLZ" Then cell.Columns("A:H").Interior.ColorIndex = 45
Next
End Sub
You're addressing the wrong range. The way you're attempting to do it effectively acts as an Offset from the referenced Cell. A better of way of writing it as well would be the following:
Public Sub ChangeColour()
Dim PC As Range, LastRow As Range
Dim ColorIndexValue As Long
Dim cell
' Set your desired range - Should reference Relevant worksheet as well
Set PC = Range("A7:H1000")
' Find last used row in that range - This will help limit the number of loops on a fixed range and speed up execution
Set LastRow = PC.Find(what:="*", _
after:=Cells(PC.Row, PC.Column), _
lookat:=xlWhole, _
LookIn:=xlValues, _
searchorder:=xlByRows, _
searchdirection:=xlPrevious)
If Not LastRow Is Nothing Then
' Resize PC to actual used range instead of working on entire sheet
Set PC = PC.Cells(1).Resize(LastRow.Row, PC.Columns.Count)
' Loop through all cells in range in Column D
For Each cell In PC.Columns("D").Cells
' Set ColorIndexValue variable based on cell value
Select Case cell.Value2
Case "GBBRS", "GBLPL", "GBSOU": ColorIndexValue = 35
Case "FIHNO", "SEGOT": ColorIndexValue = 36
Case "BEANR", "DEBRH": ColorIndexValue = 37
Case "FRLEH": ColorIndexValue = 38
Case "BEZEE", "NLRTM": ColorIndexValue = 40
Case "ZADUR", "ZAELS", "ZAPLZ": ColorIndexValue = 45
Case Else: ColorIndexValue = 0
End Select
' Set cell Color. Skip 0 as assume cell is 0 by default
If ColorIndexValue > 0 Then
' Calculates applicable range from cell and PC context
With Range(cell.Offset(0, PC.Cells(1).Column - cell.Column), cell.Offset(0, PC.Cells(1, PC.Columns.Count).Column - cell.Column))
.Interior.ColorIndex = ColorIndexValue
End With
End If
Next cell
End If
End Sub
I think you could try:
Option Explicit
Sub test()
Dim Lastrow As Long, i As Long
With ThisWorkbook.Worksheets("Sheet1")
Lastrow = .Cells(.Rows.Count, "D").End(xlUp).Row
For i = 1 To Lastrow
If .Range("D" & i).Value = "BEZEE" Or .Range("D" & i).Value = "BEANR" Or .Range("D" & i).Value = "NLRTM" Then
.Range("A" & i & ":H" & i).Interior.ColorIndex = 40
ElseIf .Range("D" & i).Value = "DEBRH" Then
.Range("A" & i & ":H" & i).Interior.ColorIndex = 37
ElseIf .Range("D" & i).Value = "FRLEH" Then
.Range("A" & i & ":H" & i).Interior.ColorIndex = 38
ElseIf .Range("D" & i).Value = "GBBRS" Or .Range("D" & i).Value = "GBLPL" Or .Range("D" & i).Value = "GBSOU" Then
.Range("A" & i & ":H" & i).Interior.ColorIndex = 35
ElseIf .Range("D" & i).Value = "FIHNO" Or .Range("D" & i).Value = "SEGOT" Then
.Range("A" & i & ":H" & i).Interior.ColorIndex = 36
ElseIf .Range("D" & i).Value = "ZADUR" Or .Range("D" & i).Value = "ZAELS" Or .Range("D" & i).Value = "ZAPLZ" Then
.Range("A" & i & ":H" & i).Interior.ColorIndex = 45
End If
Next i
End With
Related
I want to have 2 formulas with continuous looping as long as there is value in the cell next to the targeted cell, thus i need to have ifelse function but with continuous looping aswell. for now i don't know how to insert the second formula.
Range("D9").Select
Set ws = Sheets("LAP KEL BIAYA")
lastRow = ws.Range("C" & Rows.Count).End(xlUp).Row
With ws
For i = 9 To lastRow
If Len(Trim(.Range("C" & i).Value)) <> 0 Then
Function Total(Text, Number)
.Range("D" & i).Formula = "=IF(RC[-3]=""B"",IF(AND(R4C3>0,R5C3>0),SUMIFS(FBL3N!C[11],FBL3N!C[21],R4C3,FBL3N!C[22],R5C3,FBL3N!C[16],R7C4,FBL3N!C[47],RC[-1]),IF(AND(R4C3>0,R5C3=""""),SUMIFS(FBL3N!C[11],FBL3N!C[21],R4C3,FBL3N!C[16],R7C4,FBL3N!C[47],'LAP KEL BIAYA'!RC[-1]),IF(AND(R4C3=0,R5C3>0),SUMIFS(FBL3N!C[11],FBL3N!C[22],R5C3,FBL3N!C[16],R7C4,FBL3N!C[47],RC[-1]),IF(AND(R4C3=0,R5C3=0),SUMIFS(F" & _
"BL3N!C[11],FBL3N!C[16],R7C4,FBL3N!C[47],RC[-1]),"""")))))" & _
""
ElseIf Total = "False" Then
If Len(Trim(.Range("C" & i).Value)) <> 0 Then
.Range("D" & i).Formula = "=IF(AND(R4C3>0,R5C3>0,OR(R[-1]C1=""7"",R[-1]C1=""5"",R[-1]C1=""4"")),SUMIFS(FBL3N!C[11],FBL3N!C[21],R4C3,FBL3N!C[22],R5C3,FBL3N!C[16],R7C4,FBL3N!C,R[-1]C[-1]),IF(AND(R4C3>0,R5C3=0),SUMIFS(FBL3N!C[11],FBL3N!C[21],R4C3,FBL3N!C[16],R7C4,FBL3N!C,'LAP KEL BIAYA'!R[-1]C[-1]),IF(AND(R4C3=0,R5C3>0),SUMIFS(FBL3N!C[11],FBL3N!C[22],R5C3,FBL3N!C[16],R7C4,FBL3N!C,R[-1]C[-1]),IF(" & _
"AND(R4C3=0,R5C3=0),SUMIFS(FBL3N!C[11],FBL3N!C[16],R7C4,FBL3N!C,R[-1]C[-1])))))" & _
""
.Range("D" & i).Font.Color = vbRed
End If
Next i
End Function
End With
Attached is XLSM (VBA) for transposing rows to columns.
Transpose Varying rows to columns.
If the data is consistent Use TransposeRows the number of columns to be copied and transposed.
If the number of rows for each set is varying then use the TransposeRows2 procedure.
' Please note the code checks the Font color for the end of the record and transposes them to columns so If you need
' anything other than the color Maybe a specific word like 'end' then it can be used instead of the font color.
Sub TransposeRows()
' Convert Rows to Columns specify the range in this case it is 9 rows offset
Dim rng As Range
Dim i As Long
Dim MyRange As Range
Dim lngLastRow As Long
lngLastRow = Sheet1.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
MsgBox lngLastRow
Set rng = Sheet1.Range("A1")
i = 1
J = 9
Do While rng.Value <> ""
rng.Resize(J).Copy
Sheet2.Range("A" & i).PasteSpecial Transpose:=True
Set rng = rng.Offset(J)
'MsgBox Sheet2.Range("A" & i).Font.ColorIndex
i = i + 1
Loop
Application.CutCopyMode = False
End Sub
Sub TransposeRows2()
' Transpose Varying rows to columns.
' Please note the code checks the Font color for end of the record and transposes them to columns so If you need
' anything other than the color like say a specific word like end then it can be used instead of the font color.
Dim rng As Range
Dim i As Long
Dim MyRange As Range
Dim lngLastRow As Long
lngLastRow = Sheet1.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
'MsgBox lngLastRow
Set rng = Sheet1.Range("A1")
i = 1
J = 0
K = 1
J1 = 0
F = 0
Do While rng.Value <> ""
Do Until Sheet1.Range("A" & K).Font.ColorIndex <> 49 And Sheet1.Range("A" & K).Font.ColorIndex <> 16 And Sheet1.Range("A" & K).Font.ColorIndex <> 50 And Sheet1.Range("A" & K).Font.ColorIndex <> 46 And Sheet1.Range("A" & K).Font.ColorIndex <> 55 'And (Sheet1.Range("A" & K).Font.ColorIndex = 50 Or Sheet1.Range("A" & K).Font.ColorIndex = 16)
K = K + 1
Loop
F = F + J
J = K - F
' K = K + 1
J1 = J
If Sheet1.Range("A" & K).Font.ColorIndex <> 49 Then
'If Sheet1.Range("A" & K + 1).Font.ColorIndex = 16 And Sheet1.Range("A" & K + 1).Font.ColorIndex = 18 And Sheet1.Range("A" & K).Font.ColorIndex <> 49 Then
K = K + 1
End If
rng.Resize(J).Copy
If Sheet1.Range("A" & K).Font.ColorIndex = 18 Then 'Or Sheet1.Range("A" & K).Font.ColorIndex = 16 Or Sheet1.Range("A" & K).Font.ColorIndex = 50 Then
'J = 0
K = K + 1
End If
Sheet3.Range("A" & i).PasteSpecial Transpose:=True
Set rng = rng.Offset(J)
i = i + 1
Loop
Application.CutCopyMode = False
End Sub
But how would we do it for varying rows like one set being 9 rows and another being 16 rows and so on?
Sub TransposeRows2()
Dim rng As Range
Dim i As Long
Dim MyRange As Range
Dim lngLastRow As Long
lngLastRow = Sheet1.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
'MsgBox lngLastRow
Set rng = Sheet1.Range("A1")
i = 1
J = 0
K = 1
J1 = 0
F = 0
Do While rng.Value <> ""
Do Until Sheet1.Range("A" & K).Font.ColorIndex <> 49 And Sheet1.Range("A" & K).Font.ColorIndex <> 16 And Sheet1.Range("A" & K).Font.ColorIndex <> 50 And Sheet1.Range("A" & K).Font.ColorIndex <> 46 And Sheet1.Range("A" & K).Font.ColorIndex <> 55 'And (Sheet1.Range("A" & K).Font.ColorIndex = 50 Or Sheet1.Range("A" & K).Font.ColorIndex = 16)
K = K + 1
Loop
F = F + J
J = K - F
' K = K + 1
J1 = J
If Sheet1.Range("A" & K).Font.ColorIndex <> 49 Then
'If Sheet1.Range("A" & K + 1).Font.ColorIndex = 16 And Sheet1.Range("A" & K + 1).Font.ColorIndex = 18 And Sheet1.Range("A" & K).Font.ColorIndex <> 49 Then
K = K + 1
End If
rng.Resize(J).Copy
If Sheet1.Range("A" & K).Font.ColorIndex = 18 Then 'Or Sheet1.Range("A" & K).Font.ColorIndex = 16 Or Sheet1.Range("A" & K).Font.ColorIndex = 50 Then
'J = 0
K = K + 1
End If
Sheet3.Range("A" & i).PasteSpecial Transpose:=True
Set rng = rng.Offset(J)
i = i + 1
Loop
Application.CutCopyMode = False
End Sub
The AE, AG, AH, whenever the D or AD parallel cells are empty, return e.g. date of 00/01/1900 or time as 00:00. Can you please clarify how to return blank if the same parallel cell in D or AD is blank? Thanks
Sub valuedifference()
Dim Total As Double
Dim TimeX As Date
Dim TimeY As Date
Dim LastRow As Long
Dim i As Long
With ThisWorkbook.Sheets("Test1")
LastRow = .Cells(.Rows.Count, "d").End(xlUp).Row
For i = 2 To LastRow
TimeX = CDate(.Range("d" & i).Value)
TimeY = CDate(.Range("ad" & i).Value)
Total = TimeValue(TimeY) - TimeValue(TimeX)
.Range("ae" & i).Value = Total
.Range("ag" & i).Value = Abs(Total * 24)
.Range("ah" & i).Value = Abs(Total * 1440)
Next i
End With
End Sub
I think this a formatting issue- If TimeY is "" and TimeX is "", then
Total = TimeValue(TimeY) - TimeValue(TimeX) is 0.
0 in time format is 0:0:00 and 0 in date format is 00/01/1900
One solution to this is to include an if statement that checks that there are not blank cells
For i = 2 To LastRow
If .Range("D" & i).Value <> "" And .Range("AD" & i).Value <> "" Then
TimeX = CDate(.Range("d" & i).Value)
TimeY = CDate(.Range("ad" & i).Value)
Total = DateDiff("n", TimeY, TimeX)
.Range("AE" & i).Value = Total
.Range("AG" & i).Value = Format(Abs(Total), "#.##")
.Range("AH" & i).Value = Format(Abs(Total), "#.##")
End If
Next i
I'm very new to VBA and I haven't been able to figure this out yet.
I need a code that copies cell .Range("E" & i) to cell Sheets("CANmonitor").Range("C" & k) if Column B = 1731.
However, it needs to look at .Range("C" & i) as well and set Sheets("CANmonitor").Range("C" & K) = 0 if .Range("C" & i) is between 6 & 16 or between 28 & 39.
To simplify, the value on column C jumps from 6 to 16 and from 28 to 39. I need the code to enter 0s for the missing values (ex: 1731.6 = data from cell ("E" & i) on sheet DIC2; 1731.7 = 0). Here's what I have so far:
Sub DIC2toCAN()
Dim LR As Long, i As Long, k As Long
With Sheets("DIC2")
LR = .Range("B" & Rows.Count).End(xlUp).Row
k = 1
For i = 1 To LR
With .Range("B" & i)
If .Value = "1731" Then
If .Range("C" & i) is between 6 & 16 or is between 28 & 39 Then
Sheets("CANmonitor").Range("C" & k) = 0
Else
Sheets("DIC2").Range("E" & i).Copy _
Destination:=Sheets("CANmonitor").Range("C" & k)
k = k + 1
End If
End If
End With
Next i
End With
End Sub
Here is another version. This code declares all the objects beforehand and then works with it. This way if later you need to change the sheet name, you do it at only one place. This code (Untested) also uses Select Case for simplicity.
Sub DIC2toCAN()
Dim LR As Long, i As Long, k As Long
Dim wsI As Worksheet, wsO As Worksheet
'~~> Set your sheets here
Set wsI = ThisWorkbook.Sheets("DIC2")
Set wsO = ThisWorkbook.Sheets("CANmonitor")
With wsI
LR = .Range("B" & Rows.Count).End(xlUp).Row
k = 1
For i = 1 To LR
'~~> Use Val to get the value
If Val(.Range("B" & i).Value) = 1731 Then
'~~> Use select case for simplicity
Select Case Val(.Range("C" & i).Value)
Case 6 To 16, 28 To 39
wsO.Range("C" & k).Value = 0
Case Else
.Range("E" & i).Copy wsO.Range("C" & k)
k = k + 1
End Select
End If
Next i
End With
End Sub
I cleaned up your code just a bit to correct a few things (formatting, missing dot, removed problematic With statement), and most importantly, I added the syntax for the "between" tests that you needed.
Sub DIC2toCAN()
Dim LR As Long, i As Long, k As Long
With Sheets("DIC2")
LR = .Range("B" & .Rows.Count).End(xlUp).Row
k = 1
For i = 1 To LR
If .Range("B" & i).Value = "1731" Then
Dim test As Variant
test = .Range("C" & i).Value
If (test >= 6 And test <= 16) Or (test >= 28 And test <= 39) Then
Sheets("CANmonitor").Range("C" & k) = 0
Else
Sheets("DIC2").Range("E" & i).Copy Destination:=Sheets("CANmonitor").Range("C" & k)
k = k + 1
End If
End If
Next i
End With
End Sub
You are very, very close.
Change this:
If .Range("C" & i) is between 6 & 16 or is between 28 & 39 Then
to
If (.Range("C" & i) >= 6 and .Range("C" & i) <= 16) OR _
(.Range("C" & i) >= 28 and .Range("C" & i) <=39) Then
Also, simplify this:
Sheets("DIC2").Range("E" & i).Copy Destination:=Sheets("CANmonitor").Range("C" & k)
to this:
Sheets("CANmonitor").Range("C" & k) = Sheets("DIC2").Range("E" & i)
It gives the same result, but requires less typing and is easier to read.
I have 4 columns, A through D. I need to find rows where column C is the same in each row, and column D is the same in each row. It would be best to have a True or False value placed in column E. VBA or a formula works, although I'd think something like this is do-able with a formula.
For example, I have the following:
Row 1 XX 123 XYZ
Row 2 XX 234 XYZ
Row 3 XX 234 YZX
Row 4 XX 234 YZX
In this example, Column E would be False for Rows 1 and 2 and True for Rows 3 and 4.
Is this what you are trying?
Sub Sample()
Dim ws As Worksheet
Dim lRow As Long, i As Long
Set ws = Sheets("Sheet1")
With ws
lRow = .Range("C" & .Rows.Count).End(xlUp).Row
For i = 1 To lRow
If i = 1 Then
If .Range("C" & i).Value = .Range("C" & i + 1).Value And _
.Range("D" & i).Value = .Range("D" & i + 1).Value Then _
.Range("E" & i).Value = "True" Else .Range("E" & i).Value = "False"
Else
If (.Range("C" & i).Value = .Range("C" & i + 1).Value And _
.Range("D" & i).Value = .Range("D" & i + 1).Value) Or _
(.Range("C" & i).Value = .Range("C" & i - 1).Value And _
.Range("D" & i).Value = .Range("D" & i - 1).Value) Then _
.Range("E" & i).Value = "True" Else .Range("E" & i).Value = "False"
End If
Next i
End With
End Sub
SNAPSHOT