What I am trying to accomplish is:
If cells in column F contain a number, then convert it to a percentage
If cells in column F are empty and the corresponding cell in column G contain 0 then write in cell in column F "-"
If cells in column F dont contain a number and the corresponding cell in column G contain a number higher than 0 then write in cell in column F "Action Required"
Column G is formatted as number.
However, with the given code, everything becomes "-". Where is the trick?
Sub Replace()
Dim ws As Worksheet, dataLastRow As Long, cell As Range, MyRng As Range
Set ws = ThisWorkbook.Worksheets("MyTab")
Application.ScreenUpdating = False
dataLastRow = ws.Range("F" & Rows.Count).End(xlUp).Row
Set MyRng = ws.Range("F2:F" & dataLastRow)
' Loop through column F
For Each cell In MyRng
If cell = "" And cell.Offset(0, 1) = 0 Then
cell = "-"
ElseIf cell = "" And cell.Offset(0, 1) > 0 Then
cell = "Action Required"
ElseIf cell >= 0 Then
With MyRng
.NumberFormat = "0.00%"
.Value = .Value
End With
Else
End If
Next cell
Application.ScreenUpdating = True
End Sub
Your question looks weird: you get a list of data, you need to summarise those data and instead of putting the summary in another column, you decide to overwrite your data with your summary.
In case you change your mind, I've written this formula which creates the summary (not entirely correct, some small adaptations need to be done):
=IF(AND(ISBLANK(F1),G1=0),"-",IF(ISNUMBER(F1),F1,"Action required"))
(Oh, in case you use the formula, don't forget modifying the cell format into percentage.)
Related
i have a list of names(Column A), the numbers in columns B to F are result of a formula. I'm trying to create a FOR LOOP code that will check columns B to F, if all cells in B to F are zero then the code should ignore the current row and skip to the next row; if any of the cells in columns B to F is greater than 0, then the code should get the corresponding name in Column A.
Example: If any of the cells in B2, C2, D2, and E2 is greater than 1, then i should get the name/value of A2. if all cells in B2, C2. D2, and E2 are all zeros, then proceed to check next row and do the same thing.
here's the code i used to try to get the names that has any of the 4 column cell values greater than 1
For i = 2 To LastCalcAnalystRowIndex '//wsCalculations.Cells(Rows.Count, "CP").End(xlUp).Row
'//Get Component from cell in column "BP"
Analyst = wsCalculations.Cells(i, "CP").Value
Component = wsCalculations.Cells(i, "CN").Value
weeknumber = wsCalculations.Range("BR2").Value + 3
If wsCalculations.Cells(i, "B").Value = 0 And wsCalculations.Cells(, "C").Value = 0 _
And wsCalculations.Cells(i, "D").Value = 0 And wsCalculations.Cells(i, "E").Value = 0 _
And wsCalculations.Cells(i, "F").Value = 0 Then
Exit For
Else
wsCalculations.Cells(i, "A").Value = wsCalculations.Cells(i, "CP").Value
End If
Next
using the code above, i tried to get the names which all 4 column values are not equal to zero, but the result i get is just a copy of the original list. i highlighted the rows i want my code to skip. i also included the result i get and the result i want to get.
Below is a sample data. My original data has 54 rows. .
can anyone please tell me what im getting wrong?
There's no real need for VBA.
Note that I have used a Table with structured references. You can change it to a range with normal references if you prefer.
If you have O365, you can use a helper column and a formula.
Add a helper column which SUM's the cells in each row (and you can hide that column if necessary).
eg: G2: =SUM(Table3[#[Column2]:[Column6]])
Then, assuming the data is in a Table named Table3 use the formula:
=INDEX(FILTER(Table3,Table3[sumRow]>0),0,1)
If you have an earlier version of Excel, you can use:
I2: =IFERROR(INDEX(Table3[Column1],AGGREGATE(15,6,1/(Table3[sumRow]>0)*ROW(Table3)-ROW(Table3[#Headers]),ROWS($1:1))),"")
and fill down the length of the table.
Not the solution but could shorten your initial code
Why not create a hidden column* that does an =SUM of the entire row
Then get the value from that
instead of using code to get the value of each 5 cells then adding it up.
edit: changed the 'hidden cell' to 'hidden column' :P
Try
Sub test()
Dim rngDB As Range
Dim rng As Range, rngSum As Range
Dim wsCalculations As Worksheet
Dim vR() As Variant
Dim n As Long
Set wsCalculations = ActiveSheet
With wsCalculations
Set rngDB = .Range("a2", .Range("a" & Rows.Count).End(xlUp))
End With
For Each rng In rngDB
Set rngSum = rng.Offset(, 1).Resize(1, 5)
If WorksheetFunction.Sum(rngSum) > 0 Then
n = n + 1
ReDim Preserve vR(1 To n)
vR(n) = rng
End If
Next rng
With wsCalculations
If n Then
.Range("h2").Resize(n) = WorksheetFunction.Transpose(vR)
End If
End With
End Sub
can anyone please tell me what im getting wrong?
actually your shown code isn't consistent with your wording, so it's impossibile to tell all that's wrong
but for sure that Exit For is a logical error, since it actually gets you out of the loop when it first meets five zeros
so as far as this logical error is concerned, you should change that piece fo code to the following:
With wsCalculations
For i = 2 To .Cells(.Rows.Count, "A").End(xlUp).Row
If WorksheetFunction.CountIf(.Cells(i, 2).Resize(, 5), 0) < 5 Then ' when a row is eligible for math
' do your math
End If
Next
End With
where I used WorksheetFunction.CountIf() function that enables you to deal with different conditions since your wording wasn't clear about this item, too ("greater than 0", "all cells...are zero", "greater than 1")
This formula colors an entire row based on a cell in that row containing a specific value.
For Each Cell In .Range("Y5:" & .Range("Y1500").End(xlDown).Address)
If .Cells(Cell.Row, 25).value = "Super Project" Then
Cell.EntireRow.Interior.Color = vR(WorksheetFunction.RandBetween(1, n))
End If
Next
End With
How can I make the cell in column “B” also turn bold?
To bold a cell: Range.Font.Bold = True
Your target cell is in Col Y (Col 25) so to get to Col B (Col 2) you need to go backwards (offset by a value of) 23 columns resulting in:
Cell.Offset(0,-23).Font.Bold = True
The OCD side of me insists on advising you to
Indent Properly
Modify the loop range (see code)
Column Y = Column 25. No need for .Cells(Cell.Row, 25). Just analyze the variable, Cell
Last, distinguishing between Cells the Object and Cell the Variable you declared can be confusing and lead to errors. Change Cell to something like MyCell so the difference is clear.
Dim MyCell as Range
With Sheets(1) 'Some Sheet
For Each MyCell In .Range("Y5:Y" & .Range("Y" & .Rows.Count).End(xlUp).Row)
If MyCell = "Super Project" Then
MyCell.EntireRow.Interior.Color = vR(WorksheetFunction.RandBetween(1, n))
MyCell.Offset(,-23).Font.Bold = True
End If
Next
End With
Set cell = Range("A2")
Do While cell.Value <> ""
Set cell2 = cell.Offset(1)
Do While cell2.Value = cell.Value
Set cell2 = cell2.Offset(1)
Loop
Application.DisplayAlerts = False
cell.Offset(0, 15).Resize(cell2.Row - cell.Row).Merge
cell.Offset(0, 15).Formula = "=+RC[4]"
cell.Offset(0, 16).Resize(cell2.Row - cell.Row).Merge
cell.Offset(0, 17).Resize(cell2.Row - cell.Row).Merge
cell.Offset(0, 18).Resize(cell2.Row - cell.Row).Merge
Application.DisplayAlerts = True
Set cell = cell2
Loop
This code merges cells for me based on a ref # in col a. I would like to add to it so in col Q I get the sum from the corresponding rows in col u
Thanks
I wouldn't use offset - I would first recommend setting up your worksheet as a variable. If you have multiple sheets open at a time Excel can get confused if you aren't specifically referring to that sheet - so running the macro can end up running it on an unintended sheet with irreversible results.
So if I were you I would set it up so I had the usual wb = ThisWorkbook, then set your range up I guess the same, I again would rather just loop through a range and do a check if blank, exit statement. But if you like doing it that way ok.
Just put in a loop statement in there to sum the columns before the one in question. Return that column by using cell.Column, and then you can loop from the previous column by creating a new range based on that column and however many rows you need (that wasn't really clear from your question).
Set r = range(cells(1,column-1), cells(xxx, column-1))
temp = 0
For Each item In r
temp = temp + item
Next
Then set your new item equal to that temp.
Hopefully that's what you meant?
I would just set my range first, and workbook.
wb = ThisWorkBook
sh = "Sheet1" <-- whatever your sheet name is
I don't understand what exactly you're trying to accomplish, but in your main loop just add a loop instead of the insert formula statement (which I assume is your current try at a sum) and use a temp variable (temp = 0), which will then just add the current value of each row in the range you need. So as you said to someone else U2-U9, etc. Just make another range for the specific set of cells being merged.
I got it
cell.Offset(0, 16).Formula = "=sum(U" & cell.Row & ":U" & cell2.Row - 1 & ")"
I'm rather new to all of this and have looked everywhere.
I have a named range "Ruptures" (N14:P60) in sheet 7 in which I would like to find in column P values greater than 0 and paste corresponding cells N:P in sheet 9 F:H. I can't seem to search only column P.
This is what I've tried so far:
Dim cell As Variant
Dim count As Long
count = 0
With Sheet7
Set Rng = Sheet7.Range("Ruptures")
For Each cell In Rng
'But I only want to check cells from the P column (this is where I am stumped)
If cell.Value > 0 Then
Range(cell.Offset(0, -2), cell.Offset(0, 0)).Copy
Sheet9.Activate
Range("F14", "H14").Offset(count, 0).PasteSpecial (xlPasteValues)
count = count + 1
Sheet7.Activate
Next
End With
End If
End Sub
Thank so much in advance and have a great day ! :)
Ursula
This is iterating over the entire (multi-column) range:
Set Rng = Sheet7.Range("Ruptures")
For Each cell In Rng
You can limit this to the third column using this:
For Each cell in Rng.Columns(3)
I would also simplify the copy/paste to avoid unnecessary worksheet Activate and to use direct Value assignment from one range to the other (see here for more detail as well). And as noted in the comments, your Next statement can't be inside the If block:
For Each cell in Rng.Columns(3)
If cell.Value > 0 Then
Sheet9.Range("F14", "H14").Offset(count, 0).Value = Range(cell.Offset(0, -2), cell.Offset(0, 0)).Value
count = count + 1
End If
Next
This could be further refined using Resize methods:
For Each cell in Rng.Columns(3)
If cell.Value > 0 Then
Sheet9.Range("F14").Offset(count).Resize(1,3).Value = cell.Offset(0,-2).Resize(1,3).Value
count = count + 1
End If
Next
I want to run an excel vba which will go down column E and upon finding the value = "capa" will go two cell below, calculate the hex2dec value of that cell, present it by the cell with the value "capa" in column F and continue to search down column E.
So far I've came with the below but it doesn't work:
For Each cell In Range("E:E")
If cell.Value = "Capa" Then
ActiveCell.Offset.FormulaR1C1 = "=HEX2DEC(R[2]C[-1])"
End If
Next cell
Thanks!
How about something like this?
This will search volumn E for "Capa" and, if found, will place formula in column F using the value directly below "Capa" in column E
Sub CapaSearch()
Dim cl As Range
For Each cl In Range("E:E")
If cl.Value = "Capa" Then
cl.Offset(0, 1).Formula = "=HEX2DEC(" & cl.Offset(1, 0) & ")"
End If
Next cl
End Sub
You really want to limit the loop so you don't loop over the whole sheet (1,000,000+ rows in Excel 2007+)
Also, copying the source data to a variant array will speed things up too.
Try this
Sub Demo()
Dim dat As Variant
Dim i As Long
With ActiveSheet.UsedRange
dat = .Value
For i = 1 To UBound(dat, 1)
If dat(i, 6 - .Column) = "Capa" Then
.Cells(i, 7 - .Column).FormulaR1C1 = "=HEX2DEC(R[2]C[-1])"
End If
Next
End With
End Sub