I want to update some blank cell with preceding values in a range of P4 to P22, Q4 to Q22 & R4 t R22. In my case I have values in P4, Q4 & R4 if the cells below are blank and if corresponding column values of X4 matches with the corresponding blank cell values in X5 then the blank cells will automatically get updated. If it doesn't natch then the cells will stay blank. Can some one share a VBA based solution in excel?
Let me show you, using some screenshots, how I handle this (you can record it into a VBA macro):
Start with a sheet with some data:
Select the range I want to work with:
Press Ctrl+G (Goto), and choose "Special". In there, choose "Blanks":
Start typing a formula in the formula bar (you might need to press F2 for focusing on the formula bar), and type =B3 (the upper left value):
Press Ctrl+ENTER (don't forget the Ctrl button):
Voila:
Have fun!
Next time please share code that you have tried so far so it will easier for you and for the one who answering. Here is quick code example I tried to write according to your instructions. It can be improved and adjusted, but it still should do the task required.
Sub UpdateCells()
Dim sh As Worksheet
Dim y As Long
Set sh = Sheets("Your Sheet Name")
For y = 5 To 22 'starting from 5 to 22 since you have asked for this. It can be changed to your liking
If sh.Cells(y, "X") = sh.Cells(y - 1, "X") Then 'compares values in column X
sh.Cells(y, "P").Value = sh.Cells(y - 1, "P").Value 'copies values from above if values in column X matches
sh.Cells(y, "Q").Value = sh.Cells(y - 1, "Q").Value
sh.Cells(y, "R").Value = sh.Cells(y - 1, "R").Value
End If
Next y
End Sub
Related
I'm trying to search on the specific column(E), and if matched with the first 4 digit, I would like to copy the number to a different column.
Column E is where i would like to paste all the random number(dynamic)
Column A/B/C is static where i would add 4 digits from time to time.
Column I/J/K is where is would like to paste the result.
PS:
I'm doing it manually and would really appreciate if someone can help me out with the automation hence no code is provided. :(
Having ExcelO365 means you may use FILTER(). Therefor try the below:
Formula in I2:
=FILTER($E:$E,ISNUMBER(MATCH(--LEFT($E:$E,4),A:A,0)))
Drag right to K2. Now, this is dynamic and will change accordingly upon data entry in column E:E, or changing values in A:C.
this is the code to execute on sheet 1, it goes through the entire column E and validates through the formula of counting if in each of the first three columns and assigns the value found in the corresponding columns.
Sub macro()
Dim Static_Data As String
Dim Sht As Worksheet
Set Sht = ThisWorkbook.Sheets("Hoja1")
Active_row = 2
Do While Sht.Range("E" & Active_row).Value <> ""
Static_Data = Sht.Range("E" & Active_row).Value
For i = 1 To 3
If Application.WorksheetFunction.CountIf(Sht.Columns(i), Mid(Static_Data, 1, 4)) > 0 Then
Sht.Cells(Sht.Cells(Rows.Count, i + 8).End(xlUp).Row + 1, i + 8).Value = Static_Data
End If
Next i
Active_row = Active_row + 1
Loop
End Sub
For Excel versions that don't support FILTER or as an alternative you can use standard formulas for this.
If you use columns F-H as helper columns (and these columns can be hidden) then the formula in F2 will be:
=IF(NOT(ISERROR(VLOOKUP(VALUE(LEFT($E2,4)),A$2:A$100,1,FALSE)))=TRUE,$E2,"")
The formula can then be copied across and down. This will find your matches.
In order to then remove the blanks from the data you can use the following formula in I2 and again copy across and down. Depending on how many numbers you want to add in, you may want to extend the range A$2:A$100 in the top formula and F$2:F$100 in the bottom formula
=IFERROR(INDEX(F$2:F$100,AGGREGATE(15,6,(ROW(F$2:F$100)-ROW(F$2)+1)/(F$2:F$100<>""),ROWS(I$2:I2))),"")
I want to be able to build a table based upon the answer to 2 questions, with Question 1 "How many risks are in the current process?" to determine the number of columns (i.e. one per risk) and the second question "How many controls in the current process?" determines the number of rows to use (i.e one per control). Is there an easy way to build a table to show a matrix that can then be used for risk/control relationships?
This was a fun one, so I'll plan to make a YouTube tutorial on this later tonight and come back here to post my link. But here's a quick explanation of what I did.
I started by using A2 cell for # of rows, and the B2 cell for # of columns. Then I created a button of which I will assign it to a macro, explained in a bit.
Next I created the base layout for the table. This includes:
D5 to hold "Control ID"
E5 to hold "Control Description"
F3 to hold "Risk ID"
F4 to hold "Risk Description"
Also, let's start by adding the first Control and Risk blocks, as every table would presumably start with at least 1 control and 1 risk. So
D6 will have "C1"
E6 will have "Control 1 Description"
G3 will have "R1"
G4 will have "Risk 1 Description"
Then to keep consistent with your table, I put a black highlight on cells F5 and G5.
Now we can create the macro, using the following code:
Sub CreateTable()
' create variable x to hold # of rows from A2
Dim x As Integer
x = Range("A2").Value
' calculate the row range from x
Let RowRange = "7:" & 7 + x - 2
' copy row 6 into each row in the calculated range
Rows("6:6").Copy Range(RowRange)
' update the text in the newly created rows to match
' the corresponding control number
For i = 2 To x
Let ControlIdRow = 5 + i
Cells(ControlIdRow, 4).Value = "C" & i
Cells(ControlIdRow, 5).Value = "Control " & i & " Description"
Next i
Dim y As Integer
y = Range("B2").Value
Columns("G:G").Copy Range(Columns(8), Columns(8 + y - 2))
For i = 2 To y
Let RiskIdCol = 6 + i
Cells(3, RiskIdCol).Value = "R" & i
Cells(4, RiskIdCol).Value = "Risk " & i & " Description"
Next i
End Sub
Basically what's happening is that we create a variable x and assign it to be the number of rows, as input from cell A2. Then we use that to calculate the row range starting at row 7 (which will start as Control 2 since Control 1 is on row 6). Then we just copy the entire row 6 up until the specified range. Now (starting at the For loop), we need to edit the text in the cells to match the corresponding names (i.e. the second control will be C2, Control 2 Description, the third will be C3, Control 3 Description 3, and so on). Then just essentially repeat that same block, changing the respective values to match the Risks.
Then don't forget to assign the button to the new macro. Now you should be able to enter in a value for rows (A2) and a value for columns (B2) and click the button, and it should automatically create the table for you.
As mentioned, I'll create a YouTube video later tonight detailing this more and update this answer to point there.
Update
I noticed your picture has a checkmark in it, so here's the code to be able to just select a cell and have a green checkmark appear in the cell. Then clicking the cell again will remove the checkmark.
Open up the visual basic editor, and click the Sheet 1 code from the left. Then apply the following code in there:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If ActiveCell.Row > 5 And ActiveCell.Column > 6 Then
If ActiveCell.Value = "" Then
Target.Value = ChrW(&H2713)
Else
If ActiveCell.Value = ChrW(&H2713) Then
Target.Value = ""
End If
End If
End If
End Sub
Link to YouTube Tutorial on this answer
I am trying to set conditional formatting in 18 cells in third column ("C"). I have merged each 6 cells in first column ("A"), and unmerged (normal) cells in second column ("B"). I am trying to check for each next cell in row of column "C" if there is a "yes" in first row of column "A" or whether there is a "no" in "A" column and "pass" in "B" column. The trick is, I want to check only first row of "A" column, seventh, thirteenth and nineteenth (so with the step = 6) and check every row in "B" column. I try something like this:
Sub try()
Dim i As Integer
Dim j As Integer
i = 1
For j = 1 To 12
With Range("C1:C18")
.FormatConditions.Delete
.FormatConditions.Add Type:=xlExpression, Formula1:="=OR(Cells(i, 1) = ""Yes""; AND(Cells(i, 1) = ""No""; Cells(j, 2) = ""Pass""))"
End With
If j Mod 6 = 0 Then
i = i + 6
Next j
End Sub
But it does not work like that, I saw examples with specific Cells like "A1" or "A3" but I want a number to increase with every loop (so I tried it with Cells(row,column)).
You can do it in one statement on the whole range by using relative addresses, so what applies to C1 relatively to A1 and B1 will follow automatically in the subsequent rows of the range.
The only trick is to retrieve the value in column A, since this value is only available in cells A1, A7, etc. This is achieved by the expression OFFSET(A1,-MOD(ROW(C1)-1,6),0).
Sub doIt()
With Sheet1.Range("C1:C30").FormatConditions
.Delete
.Add(xlExpression, , _
"=OR(OFFSET(A1,-MOD(ROW(C1)-1,6),0)=""yes"",AND(OFFSET(A1,-MOD(ROW(A1)-1,6),0)=""no"",B1=""pass""))") _
.Interior.ColorIndex = 6
End With
End Sub
You can also do it from the GUI using the same formula; select cell C1 then select the whole range C1:C30, and click
Conditional Fomatting -> New rule -> Use a formula... and enter the same formula.
BTW, the expression can be further simplified if you dont care to check for "no", meaning if column A is assured to be either "yes" or "no".
Sorry if this is a stupid question(I searched and couldn't find a answer.) I was trying to find out if this was possible with functions but it seems like I will need to use a macro, I don't have any experience with them but can learn.
I am trying to compare 2 cells in sheet 1, Resource name and project code(C and L) against two of the same named columns in sheet 2(where they are A and D). The Resource name is formatted like: Lanier, Joe so its last name comma space first name. Project code is a mix of letters and numbers with no spaces. If they are the same, I would like to copy a range of cells in sheet 1(T through Y) into the matching row's columns X through AC in sheet 2. It would overwrite any data in those cells.
If it is also possible, if there was a way to highlight the cells or rows that don't have a match that would be such a great help so my boss would know what he needed to manually copy over. Thanks so much!
EDIT: Included below macro that seems like it should work but isn't. It is highlighting all of the cells. Any idea what could be changed?
Sub ertert()
Dim i&, j&, s$, col As New Collection
Application.ScreenUpdating = False
On Error Resume Next
With Sheets("Sheet2")
For i = 1 To .Cells(Rows.Count, 3).End(xlUp).Row
s = .Cells(i, 1) & "~" & .Cells(i, 3)
If IsEmpty(.Item(s)) Then col.Add i, s
Next i
End With
With Sheets("Sheet1")
.Columns(1).Interior.Color = xlNone
For i = 1 To .Cells(Rows.Count, 1).End(xlUp).Row
s = .Cells(i, 3) & "~" & .Cells(i, 12)
If IsEmpty(col.Item(s)) Then
.Cells(i, 1).Interior.Color = vbYellow
Else
j = col.Item(s)
Sheets("Sheet2").Cells(j, 5).Resize(, 6).Value = .Cells(i, 24).Resize(, 6).Value
End If
Next i
End With: Application.ScreenUpdating = True
End Sub
edited July 23 - 10:30EST
no VBA or macro needed you can use simple formulas and some copy and paste
on sheet2, at the end of the data columns, create a new column (AD?) with this formula
=IF(AND(IFERROR(VLOOKUP(A4,[book1]sheet1!$C$4:$C$14,1,FALSE),"")<>"",IFERROR(VLOOKUP(D4,[book1]sheet1!$L$4:$L$14,1,FALSE),"")<>""),[book1]sheet1!T4,X4)
and copy it over the next 6 rows (AD to AI)
I assumed the first row being 4 and the formula is searching 10 rows in sheet 1, adjust as needed then copy down to last of your data rows
if you have a match, the sheet1 data will be displayed otherwise, sheet2 data will be there
copy this chunk, go to X4 and use EDIT - PASTE SPECIAL - VALUES if excel 2003 or click the PASTE button on upper left and choose PASTE VALUES if Excel 2007+
I recommend you get information on VLOOKUP to better understand this solution
cheers
So, in Sheet1 I have base of some names and it looks like this:
In Sheet2 I'm working with these names from Sheet1. I'm doing that in a way that I'm entering Code value in column A and in column B I get the Name, in column C I get the Last Name. That looks like this:
I've done this with formulas, entering it in the formula bar. For column A(or Name) I've used this formula: =IFERROR(VLOOKUP(A2;Sheet1!A:C;2;FALSE);"") and for column B(or Last Name) I've used this one: =IFERROR(VLOOKUP(A2;Sheet1!A:C;3;FALSE);""). I've dragged these formulas to row 20 and it works great.
Now, what I'd like to do is to put these formulas into Excel VBA code and them to work for noted range. I've just started to use VBA and I don't know how to do it in it, tried something but doesn't work, ..., I've done this so far. I'm new to this Excel/Macro/VBA thing so any help would be appreciated.
The below code will work if you type in your Code values in sheet2 and highlight them, and run this macro:
Selection.Offset(0, 1).FormulaR1C1 = "=IFERROR(VLOOKUP(RC[-1],Sheet1!C[-1]:C,2,FALSE),"""")"
Selection.Offset(0, 2).FormulaR1C1 = "=IFERROR(VLOOKUP(RC[-2],Sheet1!C[-2]:C,3,FALSE),"""")"
Selection.Offset(0, 1).Value = Selection.Offset(0, 1).Value
Selection.Offset(0, 2).Value = Selection.Offset(0, 2).Value
Edit: If you are wanting to update values as you type use (thank you #PeterAlbert for added optimisation!):
Private Sub Worksheet_Change(ByVal Target As Range)
'end if the user made a change to more than one cell at once?
If Target.Count > 1 Then End
'stop system activating worksheet_change event while changing the sheet
Application.EnableEvents = False
'continue if column 1(A) was updated
'and
'dont continue if header or row 1 was changed
If Target.Column = 1 And Target.Row <> 1 Then
With Target.Offset(0, 1) 'alter the next cell, current column +1 (column B)
'RC1 = current row and column 1(A) e.g. if A2 was edited, RC1 = $B2
'C1:C2 = $A:$B
.FormulaR1C1 = "=IFERROR(VLOOKUP(RC1,Sheet1!C1:C2,2,FALSE),"""")"
.Value = .Value 'store value
End With
With Target.Offset(0, 2) 'alter the next cell, current column +2 (column C)
'C1:C3 = $A:$C
.FormulaR1C1 = "=IFERROR(VLOOKUP(RC1,Sheet1!C1:C3,3,FALSE),"""")"
.Value = .Value 'store value
End With
End If
Application.EnableEvents = True 'reset system events
End Sub
Explinatioin of RC:
The FormulaR1C1 formula types are good to use when referencing a cell with respect to the current cell. There a few rules to remember:
The R stands for Row and C is for Column and the integer after it, if any, defines the row or column;
As a basis the RC formula references itself;
Any number following the R or C wraped in [] is an offset to itself, e.g. if you are in cell A1 and use R[1]C[1] you would be referencing cell B2;
Also any number following the R and C is an exact, e.g. if you reference R2C2 no matter the cell you are in would also point to B2; and
To complicate things if you were in cell C5, e.g. using Range("C5").FormulaR1C1 = and coded the follwing:
"=RC[-1]" references cell B5
"=RC1" references cell A5, more rightly $A5
"=R[1]C[-2]" references cell A6
"=Sum(C[-1]:C5)" is =Sum(B:E), more rightly =Sum(B:$E)
If I understand your question and comments correctly, you want to ensure that columns B&C always show you the right values based on your formula, but also want to protect (and maybe even hide the formula) from the users.
I'd suggest you use sheet protection instead: all you need to do is to unlock the cells you want the users to edit, i.e. select column A and in the _ Format cells_ dialog uncheck "Locked" in the Protection tab. Similarly for columns B&C, check "Hidden". Now right click the sheet name and select Protect Sheet. Once this is done, the user can edit column A - but will not see the formula in B&C and cannot edit those cells.
If for some reasons you need to ensure this in VBA, use the following code:
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False 'to prevent endless loop
With Target.Offset(, 2 - Target.Column).Resize(, 2)
.FormulaR1C1 = "=IFERROR(VLOOKUP(RC1,Sheet1!C1:C3,COLUMN(RC),0),"""")"
.Value = .Value
End With
Application.EnableEvents = True
End Sub
You need to place this in the module of the worksheet.