VBA Absolute Formula range changing when running a copy + Paste macro - vba

I am running a copy paste macro but when I run it, it keeps changing the range of my formula to the last of row.
For example, my original VLOOKUP formula looks from $D$2:$G$5000, but when I run my macro it will change it to $D$2:$G$1254 where 1254 is the last row where data resides.
Here is the copy + paste function:
Sub START1()
Dim shCurrentWeek As Worksheet
Dim shPriorWeek As Worksheet
Dim lr As Long
Set shCurrentWeek = ActiveWorkbook.Sheets("Current Week")
Set shPriorWeek = ActiveWorkbook.Sheets("Prior Week")
lr = shCurrentWeek.Range("A" & Rows.Count).End(xlUp).Row
'Copies Current Week into Prior Week and deletes Rows in Prior week
shCurrentWeek.Range("A4:X" & lr).Copy
shPriorWeek.Range("A2").PasteSpecial xlPasteValues
shPriorWeek.Range("A" & lr - 2 & ":A10000").EntireRow.Delete
End Sub
any ideas?

You can use the INDIRECT() function so the formula will always reference the rows you wish. Here's a simple example (please see this link for way more detailed info):
=SUM(INDIRECT("A1:A6"))

For a start you are using pastevalues so you will not be getting any formulas on your second page but your error lies with the last row of your code
shPriorWeek.Range("A" & lr - 2 & ":A10000").EntireRow.Delete
Because your formula overlaps this range that you are deleting excel automatically adjusts the vlookup formula.
I would suggest deleting your data before pasting the values.
*edit after reading the comments if the formulas are already on the page then this solution will not work and I would use clearcontents instead as per tim's suggestion.

Related

Insert SUMIF formula in vba without defined range

I have a database sheet (Sheet1) where the datas submitted automatically with userform. everytime a data has been submitted, it will appear on the last row of database. Then I have a column in another sheet (Sheet2) that should show SUMIF formula when the data has been submitted on the Sheet1.
The formula is =SUM.IF(Sheet1!E..:N..,"TRUE",Sheet1!$E$5:$N$5), the problem is The range or row in the formula is not static which means my VBA code has to give the exact row range where a data submitted on the lastrow of Sheet1.
I'm trying to use the formula as a string, But I don't know how to define a dynamic range in my code. The bref code below;
Dim LastRow, LastRow2 As Long
LastRow = Sheet1.Range("B2").Value + 6 (I already put counta formula in the column B2)
LastRow2 = Sheet2.Range("B1").Value + 4 (same here)
Sheet2.Range("E" & LastRow2).Formula = "=SUM.IF(Sheet1!E56:N56,""VRAI"",Sheet1!$E$5:$N$5)"
(the code where i wanna put my formula, and the problem there is on E56:N56 because it must be not static)
I tried with -
Sheet2.Range("E" & LastRow2).Formula = "=SUM.IF(Sheet1!E"&LastRow&":N"&LastRow&",""VRAI"",Sheet1!$E$5:$N$5)"
But it doesn't work.

How do I automate copying data from one worksheet in Excel and append it to an existing table in another worksheet?

I have two sheets of data. The first sheet is imported data that will show total users to my site from the day before. The second sheet is a table with all historical data from those daily reports. I'd like to automate a way to copy the data from my first sheet (that data will always be in the same cell) to a new row at the bottom of my existing table. Here's what I have:
Sub Insert_New_Rows()
Dim Lr As Integer
Lr = Range("AF" & Rows.Count).End(xlUp).Row
Rows(Lr + 1).Insert Shift:=xlDown
Cells(Lr + 1, "AF") = Cells(Lr, "AF") + 1
Sheets("Day Before").Range("$A$12:$B$12").Copy
Sheets("Historical").Cells(Lr + 1, "AF").Paste
Application.CutCopyMode = False
End Sub
In this, you'll see that my table is in columns AF and AG. When I run this macro, it only adds a row, it does not copy and paste the information.
I am not really sure where your table starts on the sheet "Day Before". So, I am assuming that it starts in row 1. Based on this assumption here is a little revision to your code:
Option Explicit
Sub Insert_New_Rows()
Dim lngNextEmptyRow As Long
Dim lngLastImportRow As Long
Dim shtYstrdy As Worksheet
Set shtYstrdy = ThisWorkbook.Worksheets("Day Before")
With ThisWorkbook.Worksheets("Historical")
lngNextEmptyRow = .Cells(.Rows.Count, "AF").End(xlUp).Row + 1
.Rows(lngNextEmptyRow).Insert Shift:=xlDown
.Cells(lngNextEmptyRow, "AF").Value2 = _
.Cells(lngNextEmptyRow - 1, "AF").Value2 + 1
lngLastImportRow = shtYstrdy.Cells(shtYstrdy.Rows.Count, "A").End(xlUp).Row
shtYstrdy.Range("A1:B" & lngLastImportRow).Copy _
Destination:=.Cells(lngNextEmptyRow, "AF")
End With
End Sub
Changes:
Explicit coding as suggested by #findwindow stating the workbook and the sheet before each Range, Cells, reference.
Copy and paste in one line of code (before three lines of code).
Using lngNextEmptyRow instead of LastRow so be can skip all these +1.
Determine the size (last row) of the table on the sheet "Day Before", so we know how much we need to copy over.
I hope this is the answer you've been looking for. Let me know if I misunderstood something or if anything requires more explanations.
There is no need to Active or Select Ranges. It is best to work with the Ranges directly. Rarely should you use ActiveCell, ActiveWorkSheet, or Selection.
This is how Copy and Paste work
Here is the shorthand for Copy and Paste
Range(SourceRange).Copy Range(DestinationRange)
Know that this will work for you:
Sheets("Day Before").Range("$A$12:$B$12").Copy Sheets("Historical").Cells(Rows.Count, "AF").End(xlUp).Offset(1)

How to autofill formula for known number of columns but variable number of rows in excel macro

I writing a macro within which I need to autofill some rows with formulas, across multiple columns.
The number of columns is fixed, but each time the macro runs, the number of rows is variable. I use the "record macro" function and the current macro only ever fills my rows to row 16. Below is the code:
Range("D3:P3").Select
Selection.AutoFill Destination:=Range("D3:P16")
I obviously need to change the "P16" to something dynamic.
I have tried to use the following:
Dim LR As Long
LR = Range("D3:P3" & Rows.Count).End(xlUp).Row
Range("B3:P3").AutoFill Destination:=Range("B3:P" & LR)
I am unsure whether the "Dim LR as Long" has to be placed at the very beginning of my macro - or can it just be placed anywhere?
I am getting an error anyway with what i attempted above giving me an "autofill selectio error" (sorry i cant remember the exact error message.
Would someone be able to point me in the right direction?
LR can be declared anywhere before where you first use it, but it's best to do it at the beginning. Your range for LR is incorrect.
LR = Range("D3:P3" & Rows.Count).End(xlUp).Row
Should be
LR = Range("D3:P3").End(xlUp).Row
You should use xlDown if you are trying to find the end of a range BELOW D3:P3
LR = Range("D3:P3").End(xlDown).Row
Would give you the last row with data in all columns D:P in it below D3:P3
I think you're looking for this:
LR = Range("D3:P" & Rows.Count).End(xlUp).Row
but note that this finds the last row with any content in Column D - if there are later rows with content in Cols E-P but not in Col D then those rows will be ignored.
So I used the information provided to me and managed to get the following:
Dim LR As Long
LR = Range("C3:P" & Rows.Count).End(xlDown).Row
Range("D3:P3").AutoFill Destination:=Range("D3:P" & LR)
ActiveSheet.ListObjects.Add(xlSrcRange, Range("$D$2:P" & LR), , xlYes).Name = _
"Table10"
This allowed me to count the number of rows that had already been populated in column "C", and then take the formulas that already existed in cells D3:P3 and autofill them down through the range until the last populated row of column C.
I then used that structure to make the whole range a table, in this case named "Table10".
Great stuff guys - your help allowed me to get exactly what I wanted. Thanks

Excel VBA - Insert Row & Insert Column Macros

I have a "Task Tracker" workbook that uses columns A:J to display and calculate task information (A:E are for user-entered data, F:J contain formulas that use the information in C:E and perform calculations. F:J are hidden cells in the user view.) The remainder of the columns display a heat map of where the tasks fall on a timeline, and whether or not they are running on time, are behind, or are complete.
There are two buttons for users to use: one to insert a new row, and one to insert a new column. The InsertRow() macro inserts a row into the list, then copies the formulas down from the above row. The InsertColumn() macro locates the last used column in the worksheet and copies everything over from the column to the left of it.
Originally, I had a macro for InsertRow using Range that copied from Column F (where the formulas start) to Column XFD. However, once I created the InsertColumn macro I realized that I cannot do InsertRow like that because InsertColumn needs to locate the last data-containing column in the worksheet and add a new one to the right...and if InsertRow gets run first, InsertColumn won't work because the value for lastColumn comes back as the index of column XFD.
What I am looking for help with:
I need to locate the lastColumn value in my InsertRow macro, then use that value as part of the Range when the program executes the Copy/Paste portion of the code. I think that the problem I'm having has to do with the fact that the code I'm using to find the last column returns the index, and the Range function needs the name of the column.
Here is what I have for both macros:
Sub InsertTaskRow()
' InsertTaskRow Macro
'
' This macro inserts a new row below whatever role the user currently has selected, then
' copies the formulas and formatting from above down to the new row
Dim lastColumn As Long
Dim currrentRow As Long
Dim newRow As Long
lastColumn = ActiveSheet.Range("A1").SpecialCells(xlCellTypeLastCell).Column
currentRow = ActiveCell.Row
newRow = currentRow + 1
ActiveCell.Offset(1).EntireRow.Insert Shift:=xlDown
Range("F" & currentRow & ":" & lastColumn & currentRow).Copy Destination:=Range("F" & newRow & ":" & currentRow & newRow)
End Sub
Sub InsertColumn()
' InsertColumn Macro
'
' This macro copies the formulas and formatting from the last data-containing column
' in the worksheet, and pastes it into the next column to the right.
Dim lastColumn As Long
lastColumn = ActiveSheet.Range("A1").SpecialCells(xlCellTypeLastCell).Column
MsgBox lastColumn
Columns(lastColumn).Copy Destination:=Columns(lastColumn + 1)
End Sub
You can try changing your lastColumn occurances to the following:
lastColumn = ActiveSheet.Range("A1").End(xlToRight).Column
This will stretch your range to all used cells. I tried using the clCellTypeLastCell, but it was pulling further than necessary for no apparent reason; even after deleting the entire columns it claimed were applicable. Just an FYI, there is no issue with using indexes or column names when utilizing Range() - even interchangibly, they are both fully qualified.

Macro to create dynamic range with variable rows and columns

Very simple scenario: One spreadsheet where the columns and rows will change every time I update it; the spreadsheet will always begin on A1.
Here is the code I have now that is not working:
Dim LR As Long
LR = Range("A" & Rows.Count).End(xlUp).Row
Range("A1l:BM" & LR).Select
Can you please let me know what needs to be changed so that it will always capture the current region of columns x rows?
Thanks!
If you want to select the entire used range in you sheet, you can simply do it by using:
ActiveSheet.UsedRange.Select