I'm learning to avoid using .Select and I just cant figure out how to rewrite my .AutoFill code.
I have two different sheets, one where i collect data from, paste that in the other sheet, and I need the autofill to run on the second sheet without activating it.
This is my working code now, works because I Select the sheet and the cell "A30"
Selection.AutoFill Destination:=Range("A30:M30").Resize(NumRows1), Type:=xlFillDefault
This works perfectly, but I would like to NOT activate the sheet and select the cell.
To give you a starting point, here are some examples of using autofill on another sheet after copy/paste.
First - Copy the range you are going to use to the other worksheet
Second - Select the range on the worksheet you are going to autofill
Third - When using Resize the number has to be bigger then the range because when selecting a range the focus is on the first cell in the range. e.g. If not greater
then Range("A1:A10").resize(5).Select the selected range will be Range("A1:A5"), thus not autofill action.
Different ways to Resize are:
Sheets("Sheet3").Range("A1:B10").AutoFill Destination:=Sheets("Sheet3").Range("A1:B10").Resize(20), Type:=xlFillDefault
Or
Dim lr As Long
lr = Sheets("Sheet1").Range("A1").CurrentRegion.Rows.Count
'the lr must be grater then the autofill range
Sheets("Sheet3").Range("A1:B10").AutoFill Destination:=Sheets("Sheet3").Range("A1:B10").Resize(lr), Type:=xlFillDefault
You can also use the With statement
With Sheets("Sheet3").Range("A1:B10")
.AutoFill Destination:=.Resize(.CurrentRegion.Rows.Count + .CurrentRegion.Rows.Count), Type:=xlFillDefault
End With
'the `.CurrentRegion.Rows.Count' doubles the range for the autofill, you can replace the second one with a specific number e.g. `.CurrentRegion.Rows.Count + 5'
Related
I'm attempting to find a column using the column header name, then select all the data from the column (including the blank cells) & paste into another range.
Currently I can only copy until the 1st blank cell. I have seen similar problems on the board but the solutions I have seen are coming from the angle of knowing which column it is in first & then finding the last row from the bottom of the worksheet.
Workbooks("PS & Config - Actuals & FC.xlsm").Worksheets(2).Range("A3").CurrentRegion.Find(What:="FFA Name").Select
Range(ActiveCell, ActiveCell.End(xlDown)).Select
Range("A3").Select
ActiveSheet.Paste
To find the column use Match wit the column header name. Once you have that column, set the values in the destination range to be the same as that column. Selecting, copying, and pasting in VBA are unnecessary as the values themselves can be moved--plus it adds load.
I don't have Office anymore so I'm running this from memory. I hope it helps.
dim wb as workbook, ws1, ws2 as worksheet, myCol, myRow as long
set wb=excel.thisworkbook 'assuming this code goes in that workbook
set ws1=wb.sheets(2) 'set variables
myCol=worksheetfunction.match("FFA Name",ws1.[a1:zz1],0) 'search through 1st row
myRow=ws1.[a3].currentregion.rows.count 'grab last row containing data in this set
'do not select, nor copy and paste, if it can all be done with VBA. This can.
set ws2=wb.sheets.add 'a little rusty on this line, you can get the method from the macro recorder
ws2.cells(1,1).resize(myrow).value=ws1.cells(1,myCol).resize(myrow).value
The reason your original code stops when there's a blank cell is because the .end() method simulates pushing the end key and then an arrow, which goes to the first/last contiguous cell with data.
Range(ActiveCell, ActiveCell.End(xlDown)).Select
I am having an issue with a formula being placed onto my worksheet via vba. The formula interacts with data on a pivot table. When placed in cell Y8 on the worksheet the following formula functions as desired (non vba):
=IF(OR(L8="(blank)",L8=""),IF((K8-$A$2)/(365/12)<0,0,(K8-$A$2)/(365/12)),IF((L8-$A$2)/(365/12)<0,0,(L8-$A$2)/(365/12)))
The idea is to check if L8 is either null or (blank), if it is then use this formula: IF((K8-$A$2)/(365/12)<0,0,(K8-$A$2)/(365/12)). If L8 has a value (will be a date) then I want to use this slightly differnt formula: IF((L8-$A$2)/(365/12)<0,0,(L8-$A$2)/(365/12))).
Columns L and K are in a pivot table.
I used activecell.formulaR1C1 to translate my on sheet formula to R1C1. The only change I made was adding a set of quotation marks around "(blank)" --> ""(blank)"".
I am still getting a run-time 1004 message on my formula line of vba.
My VBA Code is here:
Sub PerformFormulas()
Dim LastRow As Long
LastRow = Worksheets("Calculator").Range("C" & Rows.Count).End(xlUp).Row
Worksheets("Calculator").Range("Y8:Y" & LastRow - 1).FormulaR1C1 = "=IF(OR(RC[-13]=""(blank)"",RC[-13]=""),IF((RC[-14]-R2C1)/(365/12)<0,0,(RC[-14]-R2C1)/(365/12)),IF((RC[-13]-R2C1)/(365/12)<0,0,(RC[-13]-R2C1)/(365/12)))"
End Sub
I checked that LastRow and Calculator are being recognized correctly and they are (I changed to a simple .select formula and that portion of the code works alright).
Thanks in advance for any help!
You didn't escape the other pair of quotes:
"=IF(OR(RC[-13]=""(blank)"",RC[-13]=""), ...
should be
"=IF(OR(RC[-13]=""(blank)"",RC[-13]=""""), ...
I have two excel columns in a worksheet, consider as A(left) and B(right) and I have recorded a macro where it will calculate a formula and copy/paste it to all the right side columns till where the left side column has data. but when next time some extra data is added to the left column and when I run a macro to copy/paste then it is only considering the previous range but not extending to the newly added cells.
example : A1:A5 is left side and B1:B5 is the right side and my formula in B range which is right range calculate based on A1:A5 and my macro works fine and restricted only to B1:B5 even when I added new data like A1:A10 only copying B1:B5. what is the method I can use my macro automatically till the data range of A side column?
Better next time, you provide a screenshot of your data & also VBA code in question.
You are using a static range, while you require is dynamic range.
try this
Sub test()
Dim i As Integer
i = WorksheetFunction.CountA(Range("A:A"))
Range("B1:b" & i).Select 'instead of selecting you can provide your formula to whole range.
End Sub
For any other issue, feel free to comment
As per your description just try below.
Sub FillFormula()
Dim i As Long
i = Range("A1").End(xlDown).Row
Range("B1").FormulaR1C1 = "=RC[-1]+5"
Range("B1").AutoFill Destination:=Range("B1:B" & i)
End Sub
As part of my project I have a Table which includes lookup formulas in each column that are dragged down the whole table. Depending on the case only the first x rows return values. I included an iferror so that the lookups that don't return values return "".
Now I want to copy the rows of the table that return values to the first empty row in a different table in a different worksheet.
The code I have so far:
Sub Copy_Results()
Application.ScreenUpdating = False
Dim copySheet As Worksheet
Dim pasteSheet As Worksheet
Set copySheet = Worksheets("Sheet1")
Set pasteSheet = Worksheets("Sheet2")
copySheet.Range("Table1").Copy
pasteSheet.ListObjects("Table2").Range.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
Application.CutCopyMode = False
Application.ScreenUpdating = True
End Sub
Now the big problem is that I want to be able to execute this macro multiple times, each time the values from Table 1 should be pasted below the preexisting values in table 2.
The point being that each time the lookup values change meaning I get new results I want to paste them in a table where all the results are documented.
Issues that I had so far:
The first Copy Paste usually works, but when I copy again the values get pasted way below the first ones outside of the table. Usually the full length of the table away. I guess this is because the whole copy table is filled with formulas.
The easiest way to do this is to restrict the cells that you are going to copy using the SpecialCells method:
https://msdn.microsoft.com/en-us/library/office/ff196157.aspx
In this case you only want to copy the formulas that have numbers as the values, so this would be the syntax:
SpecialCells(xlCellTypeFormulas, xlNumbers)
Put into your code it would be:
copySheet.Range("Table1").SpecialCells(xlCellTypeFormulas, xlNumbers).Copy
You can see this in action outside of your code by selecting the complete range in your source sheet then pressing F5, selecting the "Special" button at the bottom of the dialog that pops up, then select "Formulas" and "Numbers".
To make sure it pastes in the next available row, use the CurrentRegion property:
https://msdn.microsoft.com/en-us/library/office/ff196678.aspx?f=255&MSPPError=-2147217396
This code will tell you what the last row is in the used area defined by cell A1:
pasteSheet.cells(1,1).CurrentRegion.Rows.Count
I believe the paste command you're looking for will be close to this (hard to test exactly without your spreadsheet):
pasteSheet.cells(pasteSheet.cells(1,1).CurrentRegion.Rows.Count + 1, 1).PasteSpecial xlPasteValues
I'm a new convert from Experts-Exchange since I noticed they increased the 'Free Premium Services' points threshold.
It seems that Excel 2003 has issues with the End(xlup) command when using it in a worksheet that contains an Excel 'List'.. If I select a cell outside the 'list' boundary, and then try to select the last cell in the worksheet by using VBA, I have to call the .Select function twice to make sure I am getting the correct cell. If the original cell is inside the 'list' boundary then i only need one .Select. My hacked together solution is below, with two selects, as I can never be sure what cell may be selected on save. I include a version check at open to run different code in Excel 2007 (this code fails in 2007, where the .End(xlUp) command works properly).
Is there a more eloquent way to handle this?
Thanks for any help!
.Range("A1").Select
.Cells(.Rows.Count, "A").End(xlUp).Select
.Cells(.Rows.Count, "A").End(xlUp).Select
'two .Selects needed to select correct cell in Excel 2003 list because original selection (A1) was not in list'
.Range("A1").Select
.Cells(.Rows.Count, "T").End(xlUp)(-2, 1).Select
.Cells(.Rows.Count, "T").End(xlUp)(-2, 1).Select
'two .Selects needed to select correct cell in Excel 2003 list because original selection (A1) was not in list'
.Cells(.Rows.Count, "T").End(xlUp)(-3, 1).Select
'only one select needed here because original selection above was within the list'
See how this does:
Sub Example()
Dim rngLstCell As Excel.Range
Set rngLstCell = GetLastCell(Excel.Worksheets("Sheet1"))
MsgBox "The last cell is: " & rngLstCell.Address, vbInformation
End Sub
Public Function GetLastCell(ByVal ws As Excel.Worksheet) As Excel.Range
Dim rngRtnVal As Excel.Range
With ws.UsedRange
Set rngRtnVal = .Find("*", .Cells(1, 1), , , xlByRows, xlPrevious)
If rngRtnVal Is Nothing Then
Set rngRtnVal = .Cells(1, 1)
End If
End With
Set GetLastCell = rngRtnVal
End Function
Using find may seem weird at first but it ends up being the most reliable way due to some vagaries in the way empty cells are handled.
This may not be perfect if your data is non-normalized (jagged).
I found that my use of .End(xlUp).Select prior to acting on the .End(xlUp) cell was causing the problem. If I simply avoid the .End(xlUp).Select prior to operating on the .End(xlUp) cell, the problem is less complex. It can be easily solved by preceding any .End(xlUp) operation with .Range("A1").Select. See the code for explanation. This doesn't really fix the problem with improper .End(xlUp) cell 'selection' - but I'm not interested in 'selecting' the cells, just operating on them. I must mention that I use .Range("A1").Select because A1 is outside of the 'list' that I'm manipulating via VBA.
'commented out - just need to add a ".Range("A1").Select" prior to any .End(xlUp) usage (besides .End(xlUp).Select) to make it work in Excel 03
'.Range("A1").Select
'.Cells(.Rows.Count, "A").End(xlUp)(0, 1).Select
'.Cells(.Rows.Count, "A").End(xlUp)(0, 1).Select
''two .Selects needed to select correct cell in Excel 2003 'Lists'
'Set EntryDate = Cells(.Rows.Count, "A").End(xlUp)(0, 1) 'no need to select cell first, then operate on it, as in the code above
'fixed code below
.Range("A1").Select 'needed for Excel 03 to select correct cell
Set EntryDate = Cells(.Rows.Count, "A").End(xlUp) 'just operate on the cell instead of selecting it first
Are you sure the ranges that you were working with were identical? You shouldn't get different results using the End property in Excel 2007 versus 2003.
Looking at your code:
.Range("A1").Select
.Cells(.Rows.Count, "A").End(xlUp).Select
.Cells(.Rows.Count, "A").End(xlUp).Select
Each of these lines of code have exactly zero impact on one another. No honest explanation can be offered about why the End property is giving you different results based on the code you've provided. From what's written, you should get the same results each time. (That's assuming you're working with identical ranges.) I'd be suspicious of any other code that's being executed. I can offer a couple general tips though: If you use End starting with a blank cell, it will stop at the first non-blank cell. If you start with a non-blank cell, the opposite is true. Looking at the screenshot below:
Range("B13").End(xlUp).Select 'selects B12
Range("B12").End(xlUp).Select 'selects B2
Range("A12").End(xlUp).Select 'selects A6
So whether or not your list is contiguous is an issue. Also, it is not necessary to select a range before you do something to it. Telling Excel to select cell A1 does not impact how it executes .Cells(.Rows.Count, "A").End(xlUp).Select. Assuming that line is within a With block that refers to a worksheet, that line of code is the same thing as navigating to cell A65536 (or A1048576 in Excel 2007) and pressing Ctrl + Up. Assuming that cell is blank, Excel will navigate upwards until it finds the first non-blank cell in column A. If your With block refers to a range object, then that line of code will go to the first column, bottom row of that range and navigate upwards until it comes to the first blank or non-blank cell.