I'm not that familiar with VBA, so please bear with me.
My question is related to this link: Double-click autofill - dynamic based on adjacent cell
enter image description here
However, the attributes are located in another column (for example Column E). I've tried tweaking the code, but to no avail.
Does this work for you?
Sub FillBlanks()
Dim lr As Long
lr = Cells(Rows.Count, "E").End(xlUp).Row 'Assuming Attributes are in Column E
On Error Resume Next
'Assuming you want to fill blanks in column A
With Range("A1:A" & lr).SpecialCells(xlCellTypeBlanks)
.Formula = "=R[-1]C"
.Value = .Value
End With
End Sub
Related
The below code does vlookup then autofills the data then applies the filter to #N/A. Here I need to do another VLOOKUP in the same column with the filter as #N/A but I am not sure about this as how do we select the cells below F1 and apply VLOOKUP on the visible data. Could you help me out with this?
Sub Vlookup()
Worksheets("error rate").Activate
Range("F2") = "=Vlookup(B2,'sales'!B:C,2,0)"
Range("F2").Select
Range("F2").AutoFill Range("F2:F" & Range("B" & Rows.Count).End(xlUp).Row)
Range("F:F").Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues
Range("B1").AutoFilter Field:=6, Criteria1:="#N/A"
Range = Rng.Offset(1).SpecialCells(xlCellTypeVisible).Cells(1, 6)
End Sub
Few things
Avoid using Activate/Select. You may want to see How to avoid using Select in Excel VBA
Define and work with objects. Becomes much easier to work with your code.
Instead of entering formula in one cell and then autofilling it, simply enter the formula in the entire range in one go as shown below.
I see the objective is to get all the values. Then there is no need to enter a formula, filter and renter the formula. Use a single nested formula using IFERROR and IF. For example, if the formula "=Vlookup(B2,'sales'!B:C,2,0)" doesn't give you the result and you want to pull up the values from say column D then use the formula =IFERROR(VLOOKUP(B2,Sales!B:C,2,0),VLOOKUP(B2,Sales!B:D,3,0)). I have simply nested VLOOKUP(B2,Sales!B:D,3,0) inside IFERROR(). What the formula does is checks if there is an error with VLOOKUP(B2,Sales!B:C,2,0) and if there is, then it attempts to find the value using VLOOKUP(B2,Sales!B:D,3,0)
CODE
Option Explicit
Sub Sample()
Dim ws As Worksheet
Dim lRow As Long
'~~> Set this to the relevant sheet
Set ws = ThisWorkbook.Sheets("error rate")
With ws
'~~> Find last row
lRow = .Range("B" & .Rows.Count).End(xlUp).Row
'~~> Work with the relevant range
With .Range("F2:F" & lRow)
'~~> Enter the formula in the entire range in one go
.Formula = "=IFERROR(VLOOKUP(B2,Sales!B:C,2,0),VLOOKUP(B2,Sales!B:D,3,0))"
'~~> OPTIONAL
'~~> Instead of copy and paste as values use this.
'.Value = .Value
End With
End With
End Sub
I'm trying to change all letters into capital letters in all cells holding data in column B2 and down. Got this VBA.
Sub CapitalLettersColumnB()
'Capital Letters to names in column B (from B2 and down)
'Column B holds headers!
With Range("B2", Cells(Rows.Count, "B").End(xlUp))
.Value = Evaluate("INDEX(UPPER(" & .Address(External:=True) & "),)")
End With
End Sub
When my sheet holds 2 rows of data (and more), not counting headers, the vba works just fine.
But when my sheet only holds 1 row of data, not counting headers, name in column B (cell B2) is replaced with #VALUE!.
Anyone that can help spot what's wrong, and how to correct my vba?
The problem is INDEX. The funtion returns a position in a Range or Array, not a single value. If you would evaluate the formula it would come down to this:
=INDEX("VALUE",)
Instead of a correct:
=INDEX({"VALUE1","VALUE2"},)
Not feeding the INDEX a range or array will then return the error
To correct your code you need to make sure there is always a range object larger than one cell, so for example:
Sub CapitalLettersColumnB()
With Range("B1", Cells(Rows.Count, "B").End(xlUp))
.Value = Evaluate("IF(ROW(" & .Address & ")>1,INDEX(UPPER(" & .Address & "),)," & .Address & ")")
End With
End Sub
This will now work from B1 onwards, but will leave that cell intact through the ROW test in our IF statement.
Another small note, I would definately use an explicit cell reference (including at least a worksheet)
Honestly not sure what is wrong. (I think it's the same reason as range("B2:B2"). You can't set a range spanning the same cell)
Your Cells(Rows.Count, "B").End(xlUp) returns the value of the last cell which I'm not sure how that works.
But you could change the code to do a with the range to lastrow.
But if the lastrow is 2 the code will fail, so the if goes to else and it only changes the Ucase of cell B2.
If Cells(Rows.Count, "B").End(xlUp).Row > 2 Then
' more than one row after B2
With Range("B2:B" & Cells(Rows.Count, "B").End(xlUp).Row)
.Value = Evaluate("INDEX(UPPER(" & .Address(external:=True) & "),)")
End With
Else
' no rows past B2
Range("B2").Value = UCase(Range("B2").Value)
End If
I have columns in excell with data in format A1=a;b;c and i want to divide it into three cells as B1=a,C1=b & D1=c . Please help
Select your intended cell(s) > Go to Data Menu > Text To Columns > Delimited > Choose semicolon >
Finish
If you are continually pasting information into the A column and you are looking for a formula solution, you could do this
=TRIM(MID(SUBSTITUTE($A1,";",REPT(" ",LEN($A1))),(COLUMNS($B:B)-1)*LEN($A1)+1,LEN($A1)))
That assumes your first bit of Data starts in cell A1 and you are placing your separated values starting in column B. Copy the formula to the right as for as many entries as you have.
The simpler method is to use Excel's text to columns option if it is available to you as pointed out by Ron Rosenfeld.
If you wish to have a VBA solution. Please try this :
Sub Transpose_Q8582()
Dim pasteRng As Range
Dim i As Long
With ActiveSheet
Set pasteRng = .Range("B1:D1")
With .Range("A1:A" & .Cells(.Rows.Count, "A").End(xlUp).Row)
For i = 1 To .Rows.Count Step 3
pasteRng.Offset(i - 1).Value = Application.Transpose(.Cells(i, 1).Resize(3))
Next i
End With
End With
End Sub
EDIT
There was an oversight in understanding OP requirement. I have revised VBA code to meet OP requirement.
Sub Test1()
Dim values As Variant
For i = 1 To Cells(Rows.Count, 1).End(xlUp).Row
values = Split(Cells(i, 1).Value, ";")
Cells(i, 1).Offset(0, 1).Resize(1, UBound(values) + 1).Value = values
Next
End Sub
Write this formula in B1 and drag it towards right and for below rows
=IF(COLUMN()=2,LEFT($A1,1),IF(COLUMN()=3,MID($A1,3,1),RIGHT($A1,1)))
VBA newbie here. I have a dynamic list of multiple groups. Each group lists the leader of the group at the top with the members of the group below. There is a primary key in Column A next to each listed person. I want to take the leader's key # and apply it to Column F for the leader and each member of the group, such that each member has their own primary key # in Column A and is associated with their leader's primary key # in Column F. Here are two images of what I need for the before and after:
Before
After
Here is the code I am playing around with conceptually:
Sub Apply_Leader_Code()
Dim wSht As Worksheet
Dim lStart As Long, lEnd As Long, lLdrID As Long
Set wSht = ThisWorkbook.Sheets("Upload")
With wSht.Range("A1:G" & Range("A" & Rows.Count).End(xlUp).Row)
lStart = .Rows.Find("78") 'Find the first row for each group
lEnd = .Rows.FindNext("78") - 1 'Find the last row for each group
If .Range("G" & lStart & ":G" & lEnd).Value = "" Then
'If there is no leader ID yet, then continue...
lLdrID = .Cells(lStart, 1).Value 'Assign leader's primary key to the variable
.Cells(lStart, 7).Value = lLdrID 'Place lLdrID value into Column G
.Range("F" & lStart & ":F" & lEnd).FillDown 'Fill value to end of group range
Else
'..otherwise, set start/end rows for next group.
lStart = .Rows.FindNext("Leader")
lEnd = .Rows.FindNext("Leader") - 1
End If
End With
End Sub
The above code isn't actually applicable, but I hope represents what I think is a reasonable way to solve this problem. I can (maybe?) figure out how to do this for the first group, but how do I then perform the same .FillDown function for each subsequent group?
--EDIT--
In regards to Siddarth Rout's answer below, here is my newer code:
Range("G2").Select
ActiveCell.FormulaR1C1 = "=RC[-6]"
Range("G3").Select
ActiveCell.FormulaR1C1 = "=IF(RC[-1]=78,RC[-6],R[-1]C)"
Range("G3").Select
Selection.AutoFill Destination:=Range("G3:G" & Range("G" & Rows.Count).End(xlUp).Row)
I used the Macro creator in Excel and then edited it to what I thought would enable it to have a dynamic range instead of a set range. Now I'm getting a 400 error. Any ideas why? Any ideas on how to input the formulas w/o "selecting" the range? I am gathering that many programmers think that selecting cells is bad programming...
Do you need VBA for this? This can be achieved using excel formulas
Formula in Cell G2
=A2
Formula in Cell G3
=IF(F3=78,A3,G2)
now simply copy the formula from G3 down to G14
If you still need VBA then simply record a macro for the above steps and amend it :)
FOLLOWUP (From Comments)
Yes .Select should be avoided.
INTERESTING READ
Also no need to use R1C1 format. You can directly specify the formula
And one more thing. You don't need to use Autofill. You can skip that step by directly filling all the relevant cells with the relevant formula in ONE GO
Is this what you are trying?
Option Explicit
Sub Sample()
Dim ws As Worksheet
Dim lRow As Long
'~~> Change this to the relevant sheet
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
'~~> Find the last cell in Col A which has data
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
'~~> Enter first formula
.Range("G2").Formula = "=A2"
'~~> Enter 2nd formula in all the
'~~> cells in one go rather than autofill
.Range("G3:G" & lRow).Formula = "=IF(F3=78,A3,G2)"
End With
End Sub
I am trying to figure out how to use VBA to do the following in Excel versions 2003, 2007, 2010 (hopefully it's the same for all of them):
Search for the last cell in column A with a constant value in it.
Select all data from A2:I2 to the row with the last constant data value in it from the search above.
For example, if the last row with constant data in column A is A13, then I would want to select A2:I2 through A13:I13.
Edit
Now 'lastRow' will find the last used cell in column A even if there are blanks up above. This assumes the equations are in other columns as your comment suggested.
Sub SelectRange()
lastRow = Cells(Rows.Count, "A").End(xlUp).Row
Range("A2:I" & lastRow).Select
End Sub
See this post for how to find last cell in different versions of excel.
Say you did have to evaluate the cells in column A for formulas versus constants you can use the HasFormula method like this:
Sub SelectRange()
lastRow = Cells(Rows.Count, "A").End(xlUp).Row
Do While Range("A" & lastRow).HasFormula <> False
lastRow = Cells(lastRow - 1, "A").End(xlUp).Row
Loop
Range("A2:I" & lastRow).Select
End Sub