In column A1:A145 need code to highlight color.
Apply format color in A1, how many rows? Base on the image1.
enter image description here
In column A , 14 rows will have yellow, next 14 rows will have blue and so on. (number will always change)
In column B need to repeat the number that appear in column D.
Looking for this result image 2
enter image description here
The below code only copy the color and number from column C at the end of row A:145, what we need is trying to highlight rows base on another cell value, working with sheet 1 until sheet 8 or more sheets.
Sub Color_My_Cells()
Application.ScreenUpdating = False
Dim i As Long
Dim Lastrow As Long
Lastrow = Cells(Rows.Count, "A").End(xlUp).Row
Dim Lastrowa As Long
Lastrowa = Cells(Rows.Count, "B").End(xlUp).Row
For i = 1 To Lastrowa
Cells(Lastrow, 1).Resize(Cells(i, 2).Value) = Cells(i, 2).Value
Cells(Lastrow, 1).Resize(Cells(i, 2)).Interior.Color = Cells(i, 2).Interior.Color
Lastrow = Cells(Rows.Count, "A").End(xlUp).Row + 1
Next
Application.ScreenUpdating = True
End Sub
#GoalExcel the code below loops through all sheets in your Excel file and repeat the same steps for each one.
Sub ColorMyCells()
Dim i, j, intRowCounterAB, intRowC As Integer
For Each ws In ThisWorkbook.Sheets
ws.Activate
intRowC = Evaluate("=COUNTA(C:C)")
intRowCounterAB = 1
For i = 1 To intRowC
For j = 0 To Range("C" & i).Value - 1
Range("A" & intRowCounterAB).Interior.Color = Range("C" & i).Interior.Color
Range("B" & intRowCounterAB).Value = Range("D" & i).Value
intRowCounterAB = intRowCounterAB + 1
Next j
Next i
Next ws
End Sub
Related
I am trying to change the cells under B column to blue if the sum for the corresponding row is less than 55000. Below is my code I have figured out to achieve that for one row. How could I modify it so that it works for the other rows if I have a lot of rows?
Dim rng As Range
Dim result As Long
Set rng = Sheets(2).Range("C2:N2")
result = Application.WorksheetFunction.Sum(rng)
If result < 550000 Then
Sheet2.Range("B2").Font.Color = vbBlue
Sheet2.Range("B2").Font.Bold = True
End If
With a loop:
With Sheet2
Dim lastRow As Long
lastRow = .Cells(.Rows.Count, "B").End(xlUp).Row
Dim i As Long
For i = 2 To lastRow
If Application.Sum(.Range("C" & i & ":N" & i)) < 550000 Then
.Cells(i, "B").Font.Color = vbBlue
.Cells(i, "B").Font.Bold = True
End If
Next
End With
EDIT:
If you want to do the same thing, but for columns instead of rows:
With Sheet2
Dim lastColumn As Long
lastColumn = .Cells(1, .Columns.Count).End(xlToRight).Column
For i = 3 To lastColumn
If Application.Sum(.Columns(i)) < 550000 Then
.Cells(1, i).Font.Color = vbBlue
.Cells(1, i).Font.Bold = True
End If
Next
End With
I really don't understand much VBA, so be patient with me.
I have a list of people assigned to a specific flight (LEGID) and I want to copy those people (Worksheet pax) to a specific cell in another worksheet (temp - cell b15), but it doesn't work.
This data table is a query report from salesforce.
Sub pax()
Dim LastRow As Long
Dim i As Long, j As Long
Dim legid As String
Application.ScreenUpdating = False
legid = ThisWorkbook.Worksheets("setup").Range("SelReq").Value
Debug.Print legid
'Find the last used row in a Column: column A in this example
With Worksheets("pax")
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
End With
' MsgBox (LastRow)
'first row number where you need to paste values in temp'
With Worksheets("temp")
j = .Cells(.Rows.Count, "a").End(xlUp).Row + 1
End With
For i = 1 To LastRow
With Worksheets("pax")
If .Cells(i, 1).Value = legid Then
.Rows(i).Copy Destination:=Worksheets("temp").Range("a" & j)
j = j + 1
End If
End With
Next i
Application.ScreenUpdating = True
End Sub
If you are looking to just get the names copied over. You can use this; however you will need to update your sheet names and ranges if they are named ranges. This code looks at a specific cell for a value on Sheet3 then if that value matches a value from a range on Sheet1 it will place the values from Column B on Sheet1 into Sheet2
Sub Test()
Dim cell As Range
Dim LastRow As Long, i As Long, j As Long
Dim legid As String
With Sheet1
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
End With
With Sheet2
j = .Cells(.Rows.Count, "A").End(xlUp).Row + 1
End With
legid = Sheet3.Range("A1")
For i = 2 To LastRow
For Each cell In Sheet1.Range("A" & i)
If cell.Value = legid Then
Sheet2.Range("A" & j) = cell.Offset(0, 1).Value
j = j + 1
End If
Next cell
Next i
End Sub
I have searched far and wide without finding a good answer for this issue.
I have two lists with two columns in each. The lists contains dealer numbers (column A) and part numbers for the dealers (column B). The same value may be duplicate in each of the columns (each dealer has several part numbers and each part number may occur for several dealers).
I want the script to start with A1 and B1 in sheet1, check if both cells have a match in sheet2 - column A and column B and if so mark the equivalent cell in A1 as red, and then move to A2 + B2 to do the same comparison again. In other words, it should check row1 in sheet 1, compare it with each row in Sheet2 for a match, mark the A-cell in Sheet1 red if there is a match, and then move to the next row in Sheet1.
Here is where i have problems getting it right; I cannot seem to make the script flexible. My script does not seem to check both Cell A and B in Sheet1 and it does not check the full range in Sheet 2 for each loop.
In the next step I would also want the script to check if a third column in Sheet2 is higher than the respective cell in Sheet1, but I should be able to handle that once I get the basics going.
Here's how my code looks now:
Sub Comparestwocolumns()
Dim i As Long
Dim lastrow As Long
Dim ws As Worksheet
Set ws = Sheet1
Set ws2 = Sheet2
For i = 1 To 500000
If IsEmpty(ws.Range("A" & i)) = True Then
Exit For
End If
For j = 1 To 500000
If IsEmpty(ws2.Range("A" & j)) = True Then
Exit For
End If
If ws.Range("A" & i).Value = ws2.Range("A" & j).Value Then
If ws.Range("A" & i).Offset(0, 1).Value = ws2.Range("A" & j).Offset(0, 1).Value Then
ws.Range("A" & i).Interior.Color = vbRed
Else
ws.Range("A" & i).Interior.Color = vbWhite
End If
Exit For
End If
Next j
Next i
MsgBox ("Finished ")
End Sub
Thank you!
Close, so close.
Most of the changes I made to your code were "cosmetic" (e.g. using "B" instead of offsetting one column from "A").
The main change is the If statement. After the "cosmetic" changes, your If statement ended up looking like:
If ws.Range("A" & i).Value = ws2.Range("A" & j).Value Then
If ws.Range("B" & i).Value = ws2.Range("B" & j).Value Then
ws.Range("A" & i).Interior.Color = vbRed
End If
Exit For
End If
The problem is that that exits the For j loop as soon as the values in column A match, even if the values in column B didn't match. The Exit For needs to only be executed once both column A and column B match, e.g.
If ws.Range("A" & i).Value = ws2.Range("A" & j).Value Then
If ws.Range("B" & i).Value = ws2.Range("B" & j).Value Then
ws.Range("A" & i).Interior.Color = vbRed
Exit For
End If
End If
The final code, after all my changes, ends up as:
Sub Comparestwocolumns()
Dim i As Long
Dim j As Long
Dim lastrow As Long
Dim ws As Worksheet
Set ws = Sheet1
Set ws2 = Sheet2
For i = 1 To 500000
If IsEmpty(ws.Range("A" & i)) Then
Exit For
End If
For j = 1 To 500000
If IsEmpty(ws2.Range("A" & j)) Then
Exit For
End If
If ws.Range("A" & i).Value = ws2.Range("A" & j).Value Then
If ws.Range("B" & i).Value = ws2.Range("B" & j).Value Then
ws.Range("A" & i).Interior.Color = vbRed
Exit For
End If
End If
Next j
Next i
MsgBox ("Finished ")
End Sub
to loop until you have data on your sheets:
Option Explicit
Sub matcher()
Dim i As Integer, j As Integer
i = 1
While Sheets(1).Cells(i, 1).Value <> ""
j = 1
While Sheets(2).Cells(j, 1).Value <> ""
If Sheets(1).Cells(i, 1).Value = Sheets(2).Cells(j, 1).Value And Sheets(1).Cells(i, 2).Value = Sheets(2).Cells(j, 2).Value Then
Sheets(1).Cells(i, 1).Interior.ColorIndex = 3
End If
j = j + 1
Wend
i = i + 1
Wend
End Sub
you can use AutoFilter():
Option Explicit
Sub Comparestwocolumns()
Dim firstShtRng As Range, filteredRng As Range, colorRng As Range, cell As Range
With Worksheets("Sheet2") '<--| reference your 2nd sheet
Set firstShtRng = .Range("A1", .cells(.Rows.Count, 1).End(xlUp)) '<--| gather its column A values from row 1 down to last not empty row to be checked in 2nd sheet
End With
With Sheets("Sheet1") '<--| reference your 1st sheet
With .Range("A1", .cells(.Rows.Count, 1).End(xlUp)) '<--| reference its column A range from row 1 down to last not empty row
.AutoFilter Field:=1, Criteria1:=Application.Transpose(firstShtRng.Value), Operator:=xlFilterValues '<--| filter referenced cells with 'firstShtRng' values
Set filteredRng = .SpecialCells(xlCellTypeVisible) '<--| set filtered cells to 'filteredRng' range
Set colorRng = .Offset(, 1).Resize(1, 1) '<--| initialize 'colorRng' to a "dummy" cell that's out of range of interest: it'll be used to avoid subsequent checking against "nothing" before calling 'Union()' method and eventually discharged
End With
.AutoFilterMode = False
End With
For Each cell In filteredRng '<--| loop through filtered cells in "Sheet1"
If firstShtRng.Find(What:=cell.Value, LookIn:=xlValues, LookAt:=xlWhole).Offset(, 1) = cell.Offset(, 1) Then Set colorRng = Union(colorRng, cell) '<--| if current cell adjacent value matches corresponding value in "Sheet2" then update 'colorRng'
Next
Set colorRng = Intersect(filteredRng, colorRng) '<--| get rid of "dummy" cell
If Not colorRng Is Nothing Then colorRng.Interior.Color = vbRed '<--| if any survived cell in "Sheet1" then delete corresponding rows
End Sub
I am working with 4 rows (test bed for my code) and each product is allocated 2 rows: Data range is A1:E5
Fizzy Drink Australia Perth no sugar High
Fizzy Drink 3 5 7 5
Still water Australia Perth flavoured High
Still water 4 7 5 4
The above is on sheet 1 and there's a sheet for each produce i.e. total 3 sheets. I'm using a For loop in column 'A' to find the product and then copy the text in each of the 4 columns to the right onto the respective product sheets in columns H1:K1. This text acts as headers for each product sheet, so the headers are not the same for each product. Each product's text must be copied to the correct product sheet.
I'm having problems copying the text attached in the first row against each product in column 'A', as the 2nd row has values. The format is same for all the products - 2 rows - first row for text and second for formulas.
The challenge (which I have failed miserably) is to make the code copy text in columns B:E for each particular product.
The text can change on often basis so if the code can identify the product in column 'A' and copy/paste the text that would be fantastic.
Option Explicit
Sub copy_Text_Formulas_to_sheets
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim ws3 As Worksheet
Dim Lastrow As Long
Dim Lastrow1 As Long
Dim Lastrow2 As Long
Dim i As Integer
Dim j As Integer
Set ws1 = ThisWorkbook.Worksheets("Key") 'this is the sheet I'm pulling data from
Set ws2 = ThisWorkbook.Worksheets("Fizzy Drink") 'this is the worksheet I'm pulling data into for Prd1
Set ws3 = ThisWorkbook.Worksheets("still water") 'this is the worksheet I'm pulling data into for Prd2
Lastrow = ws1.Cells(ws1.Rows.Count, "A").End(xlUp).Row
Lastrow1 = ws2.Cells(ws2.Rows.Count, "A").End(xlUp).Row
Lastrow2 = ws3.Cells(ws3.Rows.Count, "A").End(xlUp).Row
For i = 1 To Lastrow
For j = 1 To Lastrow
If ws1.Cells(i, "A").Value = "Fizzy Drink" And ws1.Cells(i, "B").Value = "Australia" And _
ws1.Cells(i, "C").Value = "Perth" And ws1.Cells(i, "D").Value = "no sugar" And ws1.Cells(i, "E").Value = "High" Then
ws1.Range("B" & i, "E" & i).Copy 'copy row with text from B to E including all formatting
ws2.Select
ws2.Range("H1:K1").PasteSpecial xlPasteValues
'If the above conditions are not met msg user
End If
If ws1.Cells(j, "A").Value = "Fizzy Drink" And ws1.Range(i,"B:E").HasFormlua Then
ws2.Range("B2:E2") = ws1.Range(j, "H:K") 'copy the formulas in row B:E with relative references
'If the above conditions are not met msg user
End If
If ws1.Cells(i, "A").Value = "still water" And ws1.Cells(i, "B").Value = "Australia" And _
ws1.Cells(i, "C").Value = "Perth" And ws1.Cells(i, "D").Value = "flavoured" And ws1.Cells(i, "E").Value = "High" Then
ws1.Range("B" & i, "E" & i).Copy 'copy row with text from B to E including all formatting
ws3.Select
ws3.Range("H1:K1").PasteSpecial xlPasteValues 'copy including all formatting
'If the above conditions are not met msg user
End If
If ws1.Cells(j, "A").Value = "still water" And ws1.Range(i, "B:E").HasFormlua Then
ws2.Range("B2:E2") = ws1.Range(j, "H:K") 'copy the formulas in row B:E with relative references
'If the above conditions are not met msg user
End If
Next j
Next i
On Error Resume Next
ws2.Range("B2:E2").AutoFill Destination:=Range("B2:E" & Lastrow1) 'copy formula in row to down to lastrow
ws3.Range("B2:E2").AutoFill Destination:=Range("B2:E" & Lastrow2) 'copy formula in row to down to lastrow
This should help. I didn't do anything with the header row because I don't know why you would have to change it one, let alone once for each record.
Sub copy_Text_Formulas_to_sheets1()
Dim ws1 As Worksheet, ws2 As Worksheet, ws3 As Worksheet
Dim Lastrow As Long, i As Long
Dim msg as String
Set ws1 = ThisWorkbook.Worksheets("Key") 'this is the sheet I'm pulling data from
Set ws2 = ThisWorkbook.Worksheets("Fizzy Drink") 'this is the worksheet I'm pulling data into for Prd1
Set ws3 = ThisWorkbook.Worksheets("still water") 'this is the worksheet I'm pulling data into for Prd2
With ws1
Lastrow = .Cells(ws1.rowS.Count, "A").End(xlUp).Row
MsgBox "Last Row:" & Lastrow
For i = 1 To Lastrow
msg = msg & .Cells(i, "A") & vbcrlf
If IsNumeric(.Cells(i, 2)) Then
If .Cells(i, "A").value = "Fizzy Drink" Then
.Range(.Cells(i, "B"), .Cells(i, "E")).Copy getNextRow(ws2, "H")
ElseIf .Cells(i, "A").value = "Still water" Then
.Range(.Cells(i, "B"), .Cells(i, "E")).Copy getNextRow(ws3, "H")
End If
End If
Next
MsgBox "Range B2 is Numeric:" & .Cells(2, 2) & vbCrLF & "Range B3 is Numeric:" & .Cells(3, 2)
MsgBox "Range B2 has formula:" & .Cells(2, 2).HasFormula & vbCrLF & "Range B3 has formula:" & .Cells(3, 2).HasFormula
MsgBox msg
End With
End Sub
Function getNextRow(xlWorksheet As Worksheet, colmnLetter As String) As Range
Set getNextRow = xlWorksheet.Cells(rowS.Count, colmnLetter).End(xlUp).Offset(1, 0)
End Function
I added a couple of message to see what's up. Let me know what you get back. Can you provide a download link with sample data?
I'm running a dataimport macro, and I want to merge all rows in a dataset that have equal values in column x, and then I want to get a row that represents the average of group x[y] x being the column, and y being the value of the column x for that particular grouping.
Is there a simple function to do this, or must I create an extensive loop with a lot of spare cycles?
Explicitation:
So my dataset looks like
A | B | C
1 2 4
1 2 5
2 7 3
2 5 1
3 2 1
1 5 6
Now I want to merge rows by column A value, so all A's with equal value get the rest of their rows averaged so I would get somethin that looked like:
A | B | C
1 3 5
2 6 2
3 2 1
So far I've been trying to loop over the possible values of column A (1 to 10) manually by this function, but it keeps crashing excel, and I can't figure out why, I must have an endless loop somewhere in this function:
Function MergeRows(sheet, column, value)
Dim LastRow
Dim LastCol
Dim numRowsMerged
Dim totalValue
numRowsMerged = 1
LastRow = sheet.UsedRange.Rows.Count
LastCol = sheet.UsedRange.Columns.Count
With Application.WorksheetFunction
For iRow = LastRow - 1 To 1 Step -1
'enter loop if the cell value matches what we're trying to merge
Do While Cells(iRow, column) = value
For iCol = 1 To LastCol
'skip the column that we're going to use as merging value, and skip the column if it contains 3 (ikke relevant)
If Not (iCol = column) And Not (Cells(iRow, iCol) = 3) Then
Cells(iRow, iCol) = (Cells(iRow, iCol) * numRowsMerged + Cells(iRow + 1, iCol)) / (numRowsMerged + 1)
End If
Next iCol
'delete the row merged
Rows(iRow + 1).Delete
Loop
'add one to the total number of rows merged
numRowsMerged = numRowsMerged + 1
Next iRow
End With
End Function
solution
I ended up creating a range that I would gradually extend using Union, like this:
Function GetRowRange(sheet, column, value) As range
Dim LastRow
Dim LastCol
Dim numRowsMerged
Dim totalValue
Dim rowRng As range
Dim tempRng As range
Dim sheetRange As range
numRowsMerged = 1
Set sheetRange = sheet.UsedRange
LastRow = sheet.UsedRange.Rows.Count
LastCol = sheet.UsedRange.Columns.Count
With Application.WorksheetFunction
For iRow = 1 To LastRow Step 1
'enter loop if the cell value matches what we're trying to merge
If (sheetRange.Cells(iRow, column) = value) Then
Set tempRng = range(sheetRange.Cells(iRow, 1), sheetRange.Cells(iRow, LastCol))
If (rowRng Is Nothing) Then
Set rowRng = tempRng
Else
Set rowRng = Union(rowRng, tempRng)
End If
End If
'add one to the total number of rows merged
numRowsMerged = numRowsMerged + 1
Next iRow
End With
Set GetRowRange = rowRng
End Function
Is this what you are trying? Since you wanted VBA code, I have not used Pivots but used a simpler option; formulas to calculate your average.
Option Explicit
Sub Sample()
Dim col As New Collection
Dim wsI As Worksheet, wsO As Worksheet
Dim wsIlRow As Long, wsOlRow As Long, r As Long, i As Long
Dim itm
'~~> Chnage this to the relevant sheets
Set wsI = ThisWorkbook.Sheets("Sheet1")
Set wsO = ThisWorkbook.Sheets("Sheet2")
'~~> Work with the input sheet
With wsI
wsIlRow = .Range("A" & .Rows.Count).End(xlUp).Row
'~~> get unique values from Col A
For i = 1 To wsIlRow
On Error Resume Next
col.Add .Range("A" & i).Value, """" & .Range("A" & i).Value & """"
On Error GoTo 0
Next i
End With
r = 1
'~~> Write unique values to Col A
With wsO
For Each itm In col
.Cells(r, 1).Value = itm
r = r + 1
Next
wsOlRow = .Range("A" & .Rows.Count).End(xlUp).Row
'~~> Use a simple formula to find the average
For i = 1 To wsOlRow
.Range("B" & i).Value = Application.Evaluate("=AVERAGE(IF(" & wsI.Name & _
"!A1:A" & wsIlRow & "=" & .Range("A" & i).Value & _
"," & wsI.Name & "!B1:B" & wsIlRow & "))")
.Range("C" & i).Value = Application.Evaluate("=AVERAGE(IF(" & wsI.Name & _
"!A1:A" & wsIlRow & "=" & .Range("A" & i).Value & _
"," & wsI.Name & "!C1:C" & wsIlRow & "))")
Next i
End With
End Sub
SCREENSHOT
This is easy to do with a pivot table.
Here's a picture of the end result.