How to paste data to specific cell range? - vba

I'm new to vba and need a little help. I have a sheet named "Archive" which will have 12 sets of data displayed/structured in somewhat of a table format. My goal is to pull data from other sheets within the same workbook and paste it in a specific range that corresponds to the appropriate "table" for that data. Here is my code for data that is being pulled from a sheet named "Daily DB" and is being pasted to the "Archive" sheet.
Sub GetDailyDataByWeek()
Dim cw As Integer ' current week
Dim lr As Long 'last row of data
Dim i As Long ' row counter
'Clear exsisting contents
Worksheets("Archive").Range("A5:E11").ClearContents
'Get week number and year of current date
cw = Format(Date, "ww")
With Worksheets("Daily DB")
' Find last row of data
lr = .Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
For i = 2 To lr
If Format(.Cells(i, 1).Value, "ww") = cw Then
.Range(.Cells(i, 1), .Cells(i, 5)).Copy
Worksheets("Archive").Range("a" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial xlPasteFormulasAndNumberFormats
End If
Next i
End With
Application.CutCopyMode = False
End Sub
This code does what I want it to do. The line that I need help in fixing is:
Worksheets("Archive").Range("a" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial xlPasteFormulasAndNumberFormats
As this line looks for the last row of data, which in my case would be the header row of the 12th table. However, I'd like this particular data to go into the first table which after the header row starts at "A5", but I'm not sure how to go about that. Any and all help is greatly appreciated.

If you want to replicate the data from another cell or range into the same workbook I would use the "Value" method of the Range object, like this:
Worksheets("Archive").Range("A" & i).Value = Worksheets("XXX").Range("Z" & j).Value
By doing it like this you would avoid doing all the copy and paste operations.
If you dont want to specify a Range for each value, you could activate the firs cell of the first row and then "offset" your way through, like this:
Worksheets("Archive").Range("A" & i).Activate
ActiveCell.Value = blah blah blah
ActiveCell.Offset(1, 0).Activate 'If you want to move to the next row (same column)
ActiveCell.Offset(0, 1).Activate 'If you want to move to the next column (Same row)

Related

Compare two columns from multiple sheets ans extract values

It may be a repeated question, but I couldn't find an effective solution anywhere.
One of my clients needs a weekly update on projects. They download an excel from their ERP consisting of multiple columns and I have to comment status on the last column.
Every week I will get a fresh copy and all my previous entries will be cleared, then its a repeated job for me. I just want to see what I commented last week and copy paste the same in the new sheet.
Problems:
The new sheet will be in a mixed order.
Some new rows will be there and some rows disappear.
Sheet 1
Sheet 2
For the new rows in Sheet 2, I will update the comments manually.
But please help me on copying the repeated rows, which I entered on sheet1
Looking for some expert solutions
Thanks
Try the below code. It worked for me.
Input sheet (Sheet1):
Below is the code:
Sub Comapre()
Dim TotalNames As Integer
Dim NameInSheet2 As String, PO As String
TotalNames = Worksheets("Sheet2").Range("A1").End(xlDown).Row
For i = 2 To TotalNames
NameInSheet2 = Worksheets("Sheet2").Range("A" & i).Value
PO = Worksheets("Sheet2").Range("B" & i).Value
Worksheets("Sheet1").Activate
'Finds the cell value in Sheet1
Set cell = Cells.Find(What:=NameInSheet2, LookIn:=xlFormulas, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False)
If cell Is Nothing Then
Else
'If it found the name then it will compare the PO value
If cell.Offset(, 1).Value = PO Then
'If Name and Po value matched then comment will be copied to sheet2.
Worksheets("Sheet2").Range("C" & i) = cell.Offset(, 2).Value
End If
End If
Next
End Sub
Output Sheet(Sheet2):
Please let me know if my answer fits your question.
If I understand you right a simple VLOOKUP() should do the job.
I am assuming the PO numbers in a table are unique.
You take new sheet and look for the last comment you had for this PO.
in the Sheet2 eg in cell C2 you would type like:
=VLOOKUP(B2,Sheet1!B:C,2,FALSE)
This will look up your PO nr 4500253 in the Sheet1 Column B (with an exact match) and return the matched row value from Column C. An error is returned if no match is found.
using Dictionary object
Option Explicit
Sub main()
Dim dict As Object
Dim cell As Range
Set dict = CreateObject("Scripting.Dictionary")
With Worksheets("Sheet1")
For Each cell In .Range("A1", .Cells(.Rows.Count, 1).End(xlUp))
dict.Item(cell.Value2 & "|" & cell.Offset(, 1).Value2) = cell.Offset(, 2).Value2
Next
End With
With Worksheets("Sheet2")
For Each cell In .Range("A1", .Cells(.Rows.Count, 1).End(xlUp))
If dict.exists(cell.Value2 & "|" & cell.Offset(, 1).Value2) Then cell.Offset(, 2).Value = dict.Item(cell.Value2 & "|" & cell.Offset(, 1).Value2)
Next
End With
End Sub

First blank ("") cell in column with IF formula

I have a macro that exactly copies one sheet's data into another.
Sub QuickViewRegMgmt()
("Reg Management").Select
Cells.Select
Selection.Copy
Sheets("Quick View Reg Mgmt").Select
Cells.Select
ActiveSheet.Paste
End Sub
I would like for this macro to also go to the last non-blank cell in Column C (or first blank, I really don't care either way). I tried simple end/offset code, e.g.
Range("A1").End(xldown).Offset(1,0).Select
My problem, however, is that the direct copy macro also copies the underlying formulas, which for Column C is an IF formula. Therefore, no cell in the column is actually empty, but rather they all have an IF formula resulting in a true/false value (respectively, a "" or VLOOKUP).
=IF(VLOOKUP('Reg Management'!$Y260,'Reg Guidance'!$A:$V,3,FALSE)=0,"",VLOOKUP('Reg Management'!$Y260,'Reg Guidance'!$A:$V,3,FALSE))
That means the end/offset code goes to the last cell in the column with the formula (C1000) instead of going to the first cell that has a value of "" (which is currently C260).
What code can I add to this macro to select the first cell that contains an IF formula resulting in a value of "" ---- which has the appearance of being blank?
After trying to be fancy with SpecialCells(), or using Find() or something I couldn't get it ...so here's a rather "dirty" way to do it:
Sub test()
Dim lastRow As Long, lastFormulaRow As Long
lastRow = Range("A" & Rows.Count).End(xlUp).Row
Dim i As Long
For i = lastRow To 1 Step -1
If Cells(i, 1).Formula <> "" And Cells(i, 1).Value = "" Then
lastFormulaRow = i
Exit For
End If
Next i
End Sub
Edit2: Here's one using .SpecialCells(). Granted I think we can whittle this down more, I like it better:
Sub lastRow()
Dim tempLastRow As Long
tempLastRow = Range("C" & Rows.Count).End(xlUp).Row
Dim lastRow As Range
Set lastRow = Columns(3).SpecialCells(xlCellTypeFormulas).Find(What:="", LookIn:=xlValues, LookAt:=xlWhole, searchdirection:=xlPrevious, after:=Range("C" & tempLastRow))
Debug.Print lastRow.Row
End Sub
It returns 10 as the row.
Edit: Be sure to add the sheet references before Range() and Cells() to get the last row. Otherwise, it's going to look at your active sheet to get the info.

Matching and inserting records in excel

I have two sheets of data. One sheet has Primary Id with 4 fields and other has primary Id with 2 fields.
Sheet A Sheet B
ID Name Price Type Category ID Name Price
1 S Normal 2 Aus 500
2 N Default 1 Ind 400
Basically I need to match the ID of both sheets and copy the corresponding Name and Price in sheet A form Sheet B. I have tried the following code,
Sub Copy()
lastrowA = Worksheets("SheetA").Cells(Rows.Count, "A").End(xlUp).Row + 1
Set rngA = Range("A2" & lastrowA)
lastrowB = Worksheets("SheetB").Cells(Rows.Count, "A").End(xlUp).Row + 1
Set rngB = Range("A2" & lastrowB)
For Each x In rngB
For Each y In rngA
If x.Value() = y.Value Then
' Copy paste name and price form B to A
End If
Next
Next
End Sub
It's never a good idea to use a reserved word as the name of your macro. Particularly so if you plan to use a .Copy operation within the macro.
Sub MyCopy()
Dim lastrowA As Long
With Worksheets("SheetA")
lastrowA = .Cells(Rows.Count, "A").End(xlUp).Row
With .Range("B2:C" & lastrowA)
.Formula = "=IFERROR(VLOOKUP($A2, 'SheetB'!$A:$C, COLUMN(B:B), FALSE), """")"
.Value = .Value
End With
End With
End Sub
That bulk populates the entire region with the appropriate formula without looping then converts the returned values to raw values. Any non-matches will be blank rather than #N/A errors.
Does it have to be done without using formulas? I'm not sure if I'm missing something, but surely you can just use either a Vlookup or an Index Match?
If entering the formula from VBA:
Cells(2,2).FormulaR1C1 = "=INDEX(Sheet2!R2C2:R3C3,MATCH(RC[-1],Sheet2!RC[-1]:R[1]C[-1],0),1)"
Cells(2,3).FormulaR1C1 = "=INDEX(Sheet2!R2C2:R3C3,MATCH(RC[-2],Sheet2!R2C1:R3C1,0),2)"
Then you can find the last row in the ID column on sheet 1, and fill the formula down both of the columns. Once the formula has been filled down, just copy and paste as values.
Dim lstRow As Long
lstRow = Sheets("Sheet 1").Cells(Rows.Count, 1).End(xlUp).Row '' find last row
Range(Cells(2, 2), Cells(lstRow, 3)).FillDown
Range(Cells(2, 2), Cells(lstRow, 3)).Copy
Cells(2, 2).PasteSpecial Paste:=xlPasteValues
Edit: You can use the lstRow variable within the VBA formula to make sure the formula is covering the whole range everytime the automation is run. You can use the 'Record Macro' button within excel to get the code for a formula, if you are not comfortable creating them yourself.
The Problem with your code is that
Set rngA = Range("A2" & lastrowA)
evaluates to Range("A25") for lastRowA=5.
If you want to address multiple cells, use
Set rngA = Range("A2:A" & lastrowA)
to get Range("A2:A5") for lastRowA = 5.
Besides that, formulas as already mentioned are an elegant solution as well.

VBA: Placing a forumula down a column using a vlookup formula

Below I am attempting to place the formula just to the right of the last column, beginning at row 2. I know the For statement works, as well as the searching for last column/ row as i've used this in a previous macro when placing a formula down a column. The only question I have is how do I make the VLookup formula work properly?
End goal:
1) Forumla on column to the right of last one
2) Vlookup looksup the value in the last column on the given row within the For statement on a tab called "Lookup"
3) On this Lookup tab, column A is where the value will be found, but I need to return the second column value.
Please zero in on the forumula beginning with the "=iferror(...". I currently receive the error, "Application Defined or Object-Defined" error.
EThree = Cells(Rows.Count, 4).End(xlUp).Row
NumThree = Evaluate("=COUNTA(9:9)")
For r = 2 To EThree
Cells(r, NumThree + 2).Formula = "=IFERROR(((Vlookup(" & Cells(r, 14).Value & ",Lookup!$A:$B,2,0)""))))"
Next
You can place your formula in one go; no need to loop.
Try this:
With Sheets("NameOfWorksheet") '~~> change to suit
'~~> first get the last row and column
Dim lrow As Long, lcol As Long
lrow = .Range("D" & .Rows.Count).End(xlUp).Row
lcol = .Cells(9, .Columns.Count).End(xlToLeft).Column
Dim rngToFillFormula As Range, mylookup As String
'~~> get the lookup value address
mylookup = .Cells(2, lcol).Address(False, False, xlA1)
'~~> set the range you need to fill your formula
Set rngToFillFormula = .Range(.Cells(2, lcol), Cells(lrow, lcol)).Offset(0, 1)
rngToFillFormula.Formula = "=IFERROR(VLOOKUP(" & mylookup & _
",Lookup!A:B,2,0),"""")"
End With
What we did is explained in the comments. HTH.

Copy and Paste in VBA using relative references? (Error Code 1004)

New to this forum so sorry if this is off. I'm trying to do a simple copying of cell values from one worksheet in a book to another worksheet, but need to use relative cell references as the number of rows that will be copy/pasted changes depending on the data inputted.
The (very simple) code so far is:
Sub SuitorList()
'Defining Variables
Dim Row As Integer
Row = Sheets("References").Cells(6, 2).Value
'Copying Statistics
Sheets("Charts").Range(Cells(1, 1), Cells(Row, 1)).Value = _
Sheets("Data").Range(Cells(1, 1), Cells(Row, 1)).Value
End Sub
This code works fine when I use absolute cell references (i.e. "B1:B7") but when I use a relative reference I receive error code 1004: Application-defined or object-defined error.
Any thoughts?
Alternative Solution:
If you are not a fan of Loops, use Worksheet.Cells Property
Sub SuitorList()
'Defining Variables
Dim Row As Integer
Set wd = ThisWorkbook.Worksheets("Data")
Set wc = ThisWorkbook.Worksheets("Charts")
Row = Sheets("References").Cells(6, 2).Value
'Copying Statistics
Range(wd.Cells(1, 1), wd.Cells(Row, 1)).Copy Destination:=Range(wc.Cells(1, 1), wc.Cells(Row, 1))
End Sub
If you are copying data from one sheet to another and the amount of data to be copied/pasted is always changing then I would do something like this. Which is filtering the data from your selection sheet then copying it and pasting it to your destination sheet by finding the first blank cell. You may have to mess with this a bit, but it is a good start.
'Defining Variables
Dim Row As Integer
Row = Sheets("References").Cells(6, 2).Value
'switches the sheet
Sheets("Charts").Select
'filters a table based on the value of the Row variable
ActiveSheet.ListObjects("Table1").range.AutoFilter Field:=1, Criteria1:= _
range("Row"), Operator:=xlAnd
'moves to the first cell in the filtered range
range("A1").Select
'selects all values in the range and copies to clipboard
range(Selection, Selection.End(xlDown)).Select
Application.CutCopyMode = False
Selection.Copy
'switches the sheet back to data sheet
Sheets("Data").Select
'finds the first blank cell in the declared range you want to paste into
ActiveSheet.range("A:A").Find("").Select
'pastes the selection
ActiveSheet.Paste
Thanks for the help. I was able to find a work around using the following code:
Sub SuitorList()
'Defining Variables
Dim Row As Integer
Row = Sheets("References").Cells(6, 2).Value
'Copying Statistics
For i = 1 To Row
Sheets("Charts").Range("A" & i).Value = Sheets("Data").Range("A" & i).Value
Next
End Sub