I'm trying to copy down a formula down to the last row. I've got code for doing so but it won't work.
My code to find the last row is:
lRow = ws.Range("G" & ws.Rows.Count).End(xlUp).Row
The rest of my code is as follows:
Sub Inventory()
Dim lRow As Integer
lRow = ws.Range("G" & ws.Rows.Count).End(xlUp).Row
'Inventory Macro
Range("G2").Select
' Selects cell G2
Application.CutCopyMode = False
ActiveCell.FormulaR1C1 = "=RC[-5]-RC[-2]"
' Calculates Inventory for the first month by subtracting Production Units from Demand
Range("G3").Select
' Selects cell G3
Application.CutCopyMode = False
ActiveCell.FormulaR1C1 = "=RC[-5]-RC[-2]+R[-1]C"
' Calculates Inventory for the rest of the months by subtracting Production Units from Demand plus the previous month's Inventory
Range("G3").Select
Selection.AutoFill Destination:=Range("G3:G" & lRow)
Range("G3:G" & lRow).Select
End Sub
Your problem probably stems from the column in which you determine the last row. Here is another version of your code that avoids selecting anything.
Sub Inventory2()
'Inventory Macro
' Calculates Inventory for the rest of the months by subtracting
' Production Units from Demand plus the previous month's Inventory
Dim Ws As Worksheet
Dim lRow As Long
Set Ws = ActiveSheet ' better: name the sheet: Worksheets("Sheet1")
With Ws
lRow = .Cells(.Rows.Count, "A").End(xlUp).Row ' this can't be column G
.Cells(2, "G").FormulaR1C1 = "=RC[-5]-RC[-2]"
.Range(.Cells(3, "G"), .Cells(lRow, "G")).FormulaR1C1 = "=RC[-5]-RC[-2]+R[-1]C"
End With
End Sub
Related
New VBA user here, the below code matches the 1st column in a worksheet with the 1st column in another worksheet using vlookup then copies the first cell from 1st to 2nd as the screenshots.
Code
Sub solution()
Dim oldRow As Integer
Dim newRow As Integer
Dim lrow_output As Integer 'variable indicating last fulfilled row
Dim WB_Input As Workbook
Dim WB_Output As Workbook
Dim WS_Input As Worksheet
Dim WS_Output As Worksheet
Dim funcStr As String
Set WB_Input = Workbooks("input")
Set WB_Output = Workbooks("output1")
Set WS_Input = WB_Input.Worksheets("input")
Set WS_Output = WB_Output.Worksheets("Sheet1")
With WS_Output
lrow_output = .Cells(.Rows.Count, 1).End(xlUp).Row
End With
With WS_Input
funcStr = "=IFERROR(VLOOKUP(" & Cells(1, 1).Address(False, False) & "," & "'[" & WB_Input.Name & "]" & .Name & "'!" & Range(.Columns(1), .Columns(2)).Address & ",2,0),"""")"
End With
With WS_Output
.Cells(1, 2).Formula = funcStr
.Cells(1, 2).Copy
Range(.Cells(1, 2), .Cells(lrow_output, 2)).PasteSpecial xlPasteFormulas
WS_Output.Calculate
Range(.Cells(1, 2), .Cells(lrow_output, 2)).Copy
Range(.Cells(1, 2), .Cells(lrow_output, 2)).PasteSpecial xlPasteValues
Application.CutCopyMode = False
End With
End Sub
Problem: I need the code to copy and paste the all data in the row, not just the first cell.
Problem2:If possible I need the code to scan multiple sheets, not just one so it would be 1 input main workbook sheet and 4 output sheets in the output workbook.
Problem3(Optional): if possible I need the successfully matched and copied rows in the input workbook to be colored to tell them from the unsuccessful matches.
Thank you in advance, I really appreciate all the possible aid.
Here is a quick macro that will take the active cell row copy it and then select specified sheet and paste it in active cell row:
Sub CopyPaste()
'
' CopyPaste Macro
'
'
ActiveCell.Rows("1:1").EntireRow.Select
Selection.Copy
Sheets("Sheet#").Select
ActiveCell.Rows("1:1").EntireRow.Select
ActiveSheet.Paste
End Sub
I have written a short macro to delete all rows that have a value of "Not Applicable" in column I, for the "Budget" tab of my workbook.
The macro does not seem to be doing anything when I run it through my testing:
Sub Remove_NA_Macro_Round_2()
With Sheets("Budget") 'Applying this macro to the "Budget" sheet/tab.
'Establishing our macro range parameters
Dim LastRow As Long
Dim i As Long
'Setting the last row as the ending range for this macro
LastRow = .Range("I50").End(xlUp).Row
'Looping throughout all rows until the "LastRow" ending range set above
For i = LastRow To 1 Step -1
If .Range("I" & i).Value = "Not Applicable" Then
.Range("I" & i).EntireRow.Delete
End If
Next
End With
End Sub
I appreciate any help!
Alternatively, when deleting rows based on a condition, it is faster to use a filter then looping.
Dim rng As Range
Set rng = ThisWorkbook.Sheets("Sheet1").Range("A1:I" & Cells(Rows.Count, "I").End(xlUp).Row)
Application.DisplayAlerts = False
With rng
.AutoFilter
.AutoFilter field:=9, Criteria1:="Not Applicable"
rng.Resize(rng.Rows.Count - 1).Offset(1).SpecialCells(xlCellTypeVisible).Delete 'deletes the visible rows below the first row
.AutoFilter
End With
Application.DisplayAlerts = True
You are not actually referencing the With Sheets("Budget"). Add a period . before each instance of Range, otherwise there's an implicit ActiveSheet, which is not necessarily the Budget tab.
With Sheets("Budget")
...
LastRow = .Range("I50").End(xlUp).Row
...
If .Range("I" & i).Value = "Not Applicable" Then
.Range("I" & i).EntireRow.Delete
End If
...
End With
EDIT:
Based on commentary and your provided screenshot, change how LastRow is determined (get rid of the hard-coded I50):
LastRow = .Cells(.Rows.Count, "I").End(xlUp).Row
I am trying to transfer a row of data from one table to a new row at the bottom of another table when a date is entered into the cell(Column "AD").
When I try, data is transferred to the row under the last row of the table.
Sub TRANSFER_DATA()
For Each Cell In Worksheets("Sheet1").Range("AD2:AD1000")
If Cell.Value > 0 Then
matchRow = Cell.Row
Rows(matchRow & ":" & matchRow).Select
Selection.Cut
Sheets("Sheet2").Select
ActiveSheet.Range("A" & Rows.Count).End(xlUp).Offset(1).Select
ActiveSheet.Paste
Sheets("Sheet1").Select
End If
Next Cell
End Sub
If i understood your question you can try this code:
Execute the macro when you have the sheet1 active
Sub TRANSFER_DATA()
Dim lastrow, i As Long
Dim ADCell as Integer
ADCell=30 ' control the column AD
'control how many data there are in column A. If you want count how many rows
'with ColumnAD change 1 in 30 (lastrow = Cells(rows.count,30).End(xlUp).Row)
lastrow = Cells(rows.count, 1).End(xlUp).Row
For i = 2 To lastrow
If Cells(i, ADCell) > 0 Then
rows(i & ":" & i).Select
Selection.Cut Worksheets("Sheet2").Range("A" & rows.count).End(xlUp).Offset(1)
End If
Next i
End Sub
I tried the code and works.
UPDATED THE POST AFTER YOUR COMMENT
Sub TRANSFER_DATA()
Dim lastrow, i, ls As Long
Dim ADCell as Integer
ADCell=30 ' control the column AD
'control how many data there are in column A. If you want count how many rows
'with ColumnAD change 1 in 30 (lastrow = Cells(rows.count,30).End(xlUp).Row)
lastrow = Cells(rows.count, 1).End(xlUp).Row
For i = 2 To lastrow
If Cells(i, ADCell) > 0 Then
rows(i & ":" & i).Select
Selection.Cut Worksheets("Sheet2").Range("A" & rows.count).End(xlUp).Offset(1)
End If
Next i
With Sheets("sheet2")
ls = .Cells(.rows.count, ADCell).End(xlUp).Row
.ListObjects("TableName").Resize Range("$A$1:$AD$" & ls)
End With
End Sub
the updated code have another variable, ls. This variable has the number of not empty rows of sheet2. ListObjects.("name of your table") insert the new data (rows) into the table.
I hope this helps
I have two worksheets in one Excel workbook, and I only want to take the lines that have data in the cell (from worksheet1 into worksheet2) if Column A has data in it. My formula in worksheet 2 is =IF('Raw Data'!A2<>"", 'Raw Data'!A2,), but I actually don't want it to bring in the row at all if there is no data as shown in Rows 3 and 5. Right now it is bringing the whole row in:
In
you see that it is still bringing the row into worksheet 2 if there is no data. Any ideas how to only bring in the rows with the data?
Sub DataInCell()
Dim rw As Long
rw = 2
' Select initial sheet to copy from
Sheets("Raw Data").Select
' Find the last row of data - xlUp will check from the bottom of the spreadsheet up.
FinalRow = Cells(Rows.Count, 1).End(xlUp).Row
' For loop through each row
For x = 2 To FinalRow
If Cells(x, 1).Value <> 0 Then
Range("A" & x & ":C" & x).Copy
Sheets("Sheet1").Select
NextRow = Cells(Rows.Count, 1).End(xlUp).Row + 1 'Continue incrementing through the rows.
Cells(NextRow, 1).Select ' Find the next row.
ActiveSheet.Cells(NextRow, "A").PasteSpecial xlPasteAll ' Paste information.
Sheets("Raw Data").Select 'Reselect sheet to copy from. Probably uneccessary.
End If
Next x
End Sub
After you update the sheet names on the 3rd and 4th line, you will see that the code carries over the entire row. You can modify using Range(Cells, Cells) if you want partial ranges.
Option Explicit
Sub Non_Blanks()
Dim ms As Worksheet: Set ms = ThisWorkbook.Sheets("Sheet1") '<-- Master Sheet
Dim ns As Worksheet: Set ns = ThisWorkbook.Sheets("Sheet2") '<-- New Sheet
Dim i As Long, MoveMe As Range, LR As Long
For i = 2 To ms.Range("B" & ms.Rows.Count).End(xlUp).Row
If ms.Range("A" & i) = "*" Then
If Not MoveMe Is Nothing Then
Set MoveMe = Union(MoveMe, ms.Range("A" & i))
Else
Set MoveMe = ms.Range("A" & i)
End If
End If
Next i
If Not MoveMe Is Nothing Then
LR = ns.Range("A" & ns.Rows.Count).End(xlUp).Offset(1).Row
MoveMe.EntireRow.Copy
ns.Range("A" & LR).PasteSpecial xlPasteValuesAndNumberFormats
End If
End Sub
I have searched a lot of similar topics and have had some help but I cant find a way to do what I need (probably because of my limited experience with excel and vba), so here it goes:
I have a (Source)sheet 'offers' , which is populated daily, with the columns below:
columns: b c d e f g
header: offercode issue dt worktype customer sent dt confirmation dt
xxx.xx. 1/1/14 MI john 1/1/14 3/1/14
aaa.aa. 1/1/14 MD bob 2/1/14
bbb.bb 2/1/14 SI peter 2/1/14 3/1/14
what I need is to copy all rows that get a confirmation date (not blank) in another sheet"production orders"(destination)
where I generate production order codes and input other kind of data :
columns: b c d e f g
header: offercode productioncode worktype start end confirmation dt
xxx.xx. 1/1/14 MI 5/1/14 3/1/14
bbb.bb 2/1/14 SI 6/1/14 3/1/14
note that column b and b & c contain formulas (generates offer codes)
my problem is that data is populated daily, and offers(Source Sheet) should be sorted by issue date and once they get confirmed(input confirmation date->non blank) they should be copied in the other sheet but sorted (or polulate the next empty row) by confirmation date eg:
columns: b c d e f g
header: offercode productioncode worktype start end confirmation dt
xxx.xx. XX.XXX. MI 5/1/14 3/1/14
bbb.bb BB.BBB SI 6/1/14 3/1/14
aaa.aa. AA>AAA MD 4/1/14
another issue is how often or when is the second (Destination Sheet) list refreshs with new data, my guess is that a control button click after every data entry instance would work (and make sure that the list is up to date)
thank you in advance,
Angelos
So, this is what is working for me right now, its all based on #simoco's code:
I am checking in it for operational consistency, but the code works fine.
It copies and pastes only the columns of (my) interest where I need it and then sorts a dynamic range.
Sub copycolumnsonly()
Dim sh1 As Worksheet
Dim sh2 As Worksheet
Dim lastrow1 As Long
Dim lastrow2 As Long
Dim j As Long
Dim i As Long
Dim rng As Range
'set correct name of the sheet with your data'
Set sh1 = ThisWorkbook.Worksheets("ÐÑÏÓÖÏÑÅÓ")
'set correct name of the sheet where you need to paste data'
Set sh2 = ThisWorkbook.Worksheets("ÅÍÔÏËÅÓ ÐÁÑÁÃÙÃÇÓ")
'determining last row of your data in file ÁÁÁÁÁÁÁÁ.xlsx'
lastrow1 = sh1.Range("C" & sh1.Rows.Count).End(xlUp).Row
'determining last row of your data in file ÂÂÂÂÂÂÂÂ.xls'
lastrow2 = sh2.Range("F" & sh2.Rows.Count).End(xlUp).Row
'clear content in sheet2
sh2.Range("F11:F" & lastrow2).ClearContents
sh2.Range("G11:G" & lastrow2).ClearContents
sh2.Range("N11:N" & lastrow2).ClearContents
'suppose that in sheet2 data starts from row #11
j = 11
For i = 0 To lastrow1
Set rng = sh1.Range("G11").Offset(i, 0)
'check whether value in column D is not empy
If Not (IsNull(rng) Or IsEmpty(rng)) Then
sh1.Range("B" & i + 11).Copy
sh2.Range("F" & j).PasteSpecial xlPasteValues
sh1.Range("g" & i + 11).Copy
sh2.Range("G" & j).PasteSpecial xlPasteValues
sh1.Range("K" & i + 11).Copy
sh2.Range("N" & j).PasteSpecial xlPasteValues
j = j + 1
End If
Next i
Application.CutCopyMode = False
'sorting the new list, recorded macro tweaked to use a dynamic named range
ActiveWorkbook.Worksheets("ÅÍÔÏËÅÓ ÐÁÑÁÃÙÃÇÓ").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("ÅÍÔÏËÅÓ ÐÁÑÁÃÙÃÇÓ").Sort.SortFields.Add Key:=Range( _
"G:G"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
With ActiveWorkbook.Worksheets("ÅÍÔÏËÅÓ ÐÁÑÁÃÙÃÇÓ").Sort
.SetRange Range("PRODUCTIONORDERS")
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub
this is what I have come up with as a completly different approach,
I would greatly appreciate it if you could check it for error handling, or invalid input from users etc
(see comments in code)
`
Sub ActiveToLastRow()
Dim sh1 As Worksheet
Dim sh2 As Worksheet
Dim activerow As Long
Dim lastrow2 As Long
Dim rng As Range
Dim confirmation As Range
'set correct name of the sheet with your data
Set sh1 = ThisWorkbook.Worksheets("ÐÑÏÓÖÏÑÅÓ")
'set correct name of the sheet where you need to paste data
Set sh2 = ThisWorkbook.Worksheets("ÅÍÔÏËÅÓ ÐÁÑÁÃÙÃÇÓ")
'making sure the user selects the correct offercode via inputbox to get its rownumber --> see activerow variable
Set rng = Application.InputBox("dialeje prosfora", "epilogh prosforas", Type:=8)
'getting the information(confirmation date) via input box form the user
Dim TheString As String
Dim TheDate As Date
TheString = Application.InputBox("Enter A Date", "epibebaiwsh anathesis")
If IsDate(TheString) Then
TheDate = DateValue(TheString)
Else
MsgBox "Invalid date"
'need to end sub if user input is invalid
End If
'determining active row of your data in file ÁÁÁÁÁÁÁÁ.xlsx where data input occurs <-- user input via 1st input box
activerow = rng.Row
Set confirmation = sh1.Range("G" & activerow)
confirmation.Value = TheDate
'determining last row of your data in file ÂÂÂÂÂÂÂÂ.xls'
lastrow2 = sh2.Range("F" & sh2.Rows.Count).End(xlUp).Row
'determining what to copy and where
sh1.Range("B" & activerow).Copy
sh2.Range("F" & lastrow2 + 1).PasteSpecial xlPasteValues
sh1.Range("g" & activerow).Copy
sh2.Range("G" & lastrow2 + 1).PasteSpecial xlPasteValues
sh1.Range("K" & activerow).Copy
sh2.Range("N" & lastrow2 + 1).PasteSpecial xlPasteValues
Application.CutCopyMode = False
'activating destination sheet for testing purposes
sh2.Activate
End Sub`
It looks like you simply need to copy over only those rows with a value in the "Confirmation Date" column - if I read the above correctly.
If the sheet with the daily updates is called "First", and the resultant sheet with only the confirmed orders is called "Second", the following should do it...
Sub Macro1()
'
' Macro1 Macro
'
'
lastRow = 10 ' hard coded here; use whatever technique to get real value.
'Copy over the headers to the new sheet
Sheets("First").Select
Rows("1:1").Select
Selection.Copy
Sheets("Second").Select
Range("A1").Select
ActiveSheet.Paste
Application.CutCopyMode = False
Columns("A:F").ColumnWidth = 9
Columns("G:G").ColumnWidth = 12
Sheets("First").Select
' Range("G1").Select
Confirm_Count = 0
For Row = 1 To lastRow
If Len(Range("G1").Offset(Row, 0)) > 1 Then
Rows(Row + 1).Select
Selection.Copy
Sheets("Second").Select
Confirm_Count = Confirm_Count + 1
Range("A1").Offset(Confirm_Count, 0).Select
ActiveSheet.Paste
Application.CutCopyMode = False
Sheets("First").Select
End If
Next Row
End Sub