How to avoid pasting duplicate Range from one worksheet to another - excel

I want to copy data from a worksheet named "copySheet" to the first blank row in a sheet named "pasteSheet".
If the data in cell A2 of copySheet is in first column of pasteSheet then provide an error message "data is already existed and avoid pasting" otherwise paste the copy range from copySheet to pasteSheet.
I have written code as below however, IF loop is not working correctly. The value in A2 cell found in first column of pasteSheet but code is ignoring the loop and pastes the range again.
Sub Macro1()
'
' Macro1 Macro
'
Dim copySheet As Worksheet
Dim pasteSheet As Worksheet
Set copySheet = Worksheets("Sheet1")
Set pasteSheet = Worksheets("Sheet2")
copySheet.Columns("A:D").Select
Selection.ClearContents
ActiveSheet.Paste Destination:=copySheet.Range("A1")
Dim FoundRange As Range
Dim Search As String
Search = copySheet.Cells(2, 1).Select
Set FoundRange = pasteSheet.Columns(0, 1).Find(Search, LookIn:=xlValues, LookAt:=xlWhole)
If Foundcell Is Nothing Then
Dim N As Long
N = copySheet.Cells(1, 1).End(xlDown).Row
Range("A2:E" & N).Select
Selection.Copy
pasteSheet.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
Else
MsgBox "Data Exists" & " data found at cell address " & Foundcell.Address
End If
Application.CutCopyMode = False
Application.ScreenUpdating = True
End Sub

Try this. A few problems with your code:
as noted above, your Columns syntax was off
you defined FoundRange but then referred to FoundCell - use Option Explicit to flag up these errors
avoid Select wherever possible
Option Explicit
Sub Macro1()
Dim copySheet As Worksheet
Dim pasteSheet As Worksheet
Set copySheet = Worksheets("Sheet1")
Set pasteSheet = Worksheets("Sheet2")
With copySheet
.Columns("A:D").ClearContents
Dim FoundRange As Range
Dim Search As String
Search = .Cells(2, 1)
Set FoundRange = pasteSheet.Columns(1).Find(Search, LookIn:=xlValues, LookAt:=xlWhole)
If FoundRange Is Nothing Then
Dim N As Long
N = .Cells(Rows.Count, 1).End(xlUp).Row + 1
.Range("A2:E" & N).Copy
pasteSheet.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
Else
MsgBox "Data Exists" & " data found at cell address " & FoundRange.Address
End If
End With
End Sub

Related

Copy paste date value to last row in nested loop

Got a bunch of worksheets in the same workbook that have a specific range of interest that starts with finding string 'Green'. Let's call this Range (A) that I'm interested in copying and pasting into a master sheet to form a database in same workbook. I found some useful code and got this part to work gr8!
There is a date value in each worksheet in cell(3,3). What's missing is adding this date value from each worksheet and past it to column B in the master sheet 'Main' such that the date value extends to match the length of the pasted Range (A).
all help is appreciated
Sub FindRangeHistory()
'// in MainDB workbook for each trade sheet, copy and paste specific range into 'Main' sheet
Dim fnd As String, faddr As String
Dim rng As Range, foundCell As Range
Dim ws As Worksheet
Dim ws_count As Integer, i As Integer
ws_count = ThisWorkbook.Worksheets.Count
For i = 1 To ws_count
With ThisWorkbook
'initialize main sheet and keyword search
Set ws = .Worksheets("Main")
fnd = "New Life"
'Search for keyword in sheet
With .Worksheets(i)
Set foundCell = .Cells.Find(What:=fnd, after:=.Cells.SpecialCells(xlCellTypeLastCell), _
LookIn:=xlFormulas, LookAt:=xlWhole, _
SearchOrder:=xlByRows, SearchDirection:=xlNext)
'Test to see if anything was found
If Not foundCell Is Nothing Then
faddr = foundCell.Address
Set rng = .Range(foundCell, foundCell.End(xlDown))
Do
Set rng = Union(rng, .Range(foundCell, foundCell.End(xlDown)).Resize(, 7))
Set foundCell = .Cells.FindNext(after:=foundCell)
Loop Until foundCell.Address = faddr
Set rng = rng.Offset(1, 0)
rng.Copy
ws.Cells(Rows.Count, "C").End(xlUp).PasteSpecial Paste:=xlPasteValues
Worksheets(i).Cells(3, 3).Copy
ws.Cells(Rows.Count, "B").End(xlUp).PasteSpecial Paste:=xlPasteValuesAndNumberFormats
End If
End With
End With
Next i
End Sub
You could do it like this:
'...
'...
Dim nextRowC As Long, lastRowC As Long
nextRowC = ws.Cells(Rows.Count, "C").End(xlUp).Row + 1 'first empty row in ColC before paste
rng.Copy
ws.Cells(nextRowC, "C").PasteSpecial Paste:=xlPasteValues
lastRowC = ws.Cells(Rows.Count, "C").End(xlUp).Row 'last used row in ColC after paste
.Worksheets(i).Cells(3, 3).Copy
ws.Range(ws.Cells(nextRowC, "B"), ws.Cells(lastRowC, "B")). _
PasteSpecial Paste:=xlPasteValuesAndNumberFormats
'...
'...

Transpose VBA Excel Macro based on condition

I am trying to copy & transpose values from one Sheet to another Sheet based on a condition, only transpose the first 4 lines looping in large range.
From this:
To this :
I've found a transpose macro and adapt it but I couldn't apply the condition.
Sub Test()
Set rng = Range("B5", Range("B5").End(xlDown))
Sheets("Example #2").Range(rng).Value = WorksheetFunction.Transpose()
EndSub
Anyone can guide me? Any help would be greatly appreciated!
Please, test the next code. It uses arrays, works in memory and will be much faster than copying. This can be easier observed on a large range:
Sub CopyTranspose4rows()
Dim sh1 As Worksheet, sh2 As Worksheet, lastR As Long, arr, arrSl, i As Long
Set sh1 = ActiveSheet 'use here the sheet you need to copy from
Set sh2 = sh1.Next 'use here what sheet you need to paste
lastR = sh1.Range("B" & sh1.rows.count).End(xlUp).row 'last row sh1
arr = sh1.Range("B5:B" & lastR).Value 'put the range in an array for fast iteration
For i = 1 To UBound(arr) Step 4 'iterate from four to four
With Application
'create a slice array
arrSl = .Transpose(.Index(arr, Evaluate("row(" & i & ":" & i + 4 & ")"), 1))
End With
'drop the slice array content in the second sheet
sh2.Range("A" & sh2.rows.count).End(xlUp).Offset(1).Resize(1, 4).Value = arrSl
Next i
sh2.Activate 'activate the sheet where pasted
End Sub
#FaneDuru's array solution is more elegant, but here's another alternative. You would need to replace the sheet names and the starting cell numbers.
Sub TestTranspose()
Dim sht1 As Worksheet
Dim sht2 As Worksheet
Dim LR1 As Long
Dim x As Long
Set sht1 = ThisWorkbook.Worksheets("Sheet1")
Set sht2 = ThisWorkbook.Worksheets("Sheet2")
LR1 = sht1.Cells(Rows.Count, 2).End(xlUp).Row
y = 1
For x = 1 To LR Step 4
sht1.Range(sht1.Cells(x, 2), sht1.Cells(x + 3, 2)).Copy
sht2.Cells(y, 1).PasteSpecial Paste:=xlPasteAll, Transpose:=True
y = y + 1
Next x
End Sub
With this code you can have different number of answers per question.
Sub Tranpose_Questions()
Dim fnd As String, FirstFound As String
Dim FoundCell As Range, rng As Range
Dim myRange As Range, LastCell As Range
Dim transRng As Range ' range to transpose
Dim dstRng As Range: Set dstRng = ActiveSheet.Range("C1") ' destination cell
' Value find
fnd = "Question"
Set myRange = ActiveSheet.Range("A1", Range("A1").End(xlDown))
Set LastCell = myRange.Cells(myRange.Cells.Count)
Set FoundCell = myRange.Find(what:=fnd, after:=LastCell)
' Test to see if anything was found
If Not FoundCell Is Nothing Then
FirstFound = FoundCell.Address
Else
GoTo errHandler
End If
Set rng = FoundCell
' Loop
Do Until FoundCell Is Nothing
' Find next cell
Set FoundCell = myRange.FindNext(after:=FoundCell)
Debug.Print rng.Address, FoundCell.Address
' Test to see if cycled through to first found cell
If FoundCell.Address = FirstFound Then
Set transRng = Range(rng, rng.End(xlDown))
If rng.Offset(1, 0) <> "" Then
transRng.Select: transRng.Copy
dstRng.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=True
Application.CutCopyMode = False
End If
Exit Do
End If
' Transpose
Set transRng = rng.Resize(FoundCell.Row - rng.Row, 1)
transRng.Copy
dstRng.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=True
Application.CutCopyMode = False
' update rng position
Set rng = FoundCell
' update destination range
Set dstRng = dstRng.Offset(1, 0)
Loop
Exit Sub
' Error Handler
errHandler:
MsgBox "No 'Question' found!"
End Sub

Finding multiple cell values from list

I have a workbook with 2 sheets.
Sheet1 contains a list of Product Codes in column A and Column R is Current Stock Level.
Sheet2 contains a list of Product Codes in column A and Column B contains the New Stock Level.
What I want to do is replace the Current Stock Levels in Sheet1 with the New Stock Level from Sheet2.
I found some code on this site already (below) which I have adapted slightly for my purpose and it works fine but only for one Product Code (as it references A1 and B1). What I would like to do is add a Loop so it works down all products in Sheet2 but I'm not sure how to and haven't been able to adapt any similar loops I've found online for this purpose.
Any help would be appreciated, my backup plan is to just do a v-lookup in Sheet1 to bring in the Sheet2 New Stock Level values and then replace the original column but I would like to get this other way working if possible.
Private Sub CommandButton1_Click()
Dim search_range As Range, search_value As Range, _
lastcell As Range, foundcell As Range
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")
Set search_range = ws.Range("A1", ws.Range("A" & Rows.Count).End(xlUp))
Set lastcell = search_range.Cells(search_range.Cells.Count)
Set search_value = ThisWorkbook.Sheets("Sheet2").Range("A1")
Set foundcell = search_range.Find(What:=search_value, After:=lastcell,
LookIn:=xlValues, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If Not foundcell Is Nothing Then foundcell.Activate Else MsgBox "Not Found"
ActiveCell.Offset(0, 17).Value = Sheets("Sheet2").Range("B1").Value
End Sub
How about the following:
Private Sub CommandButton1_Click()
Dim search_range As Range, search_value As Range, lastcell As Range, foundcell As Range
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")
Set search_range = ws.Range("A1", ws.Range("A" & Rows.Count).End(xlUp))
Set lastcell = search_range.Cells(search_range.Cells.Count)
For i = 1 To lastcell.Row
Set search_value = ThisWorkbook.Sheets("Sheet2").Range("A" & i)
Set foundcell = search_range.Find(What:=search_value, After:=lastcell, LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext)
If Not foundcell Is Nothing Then foundcell.Activate Else MsgBox "Not Found"
ActiveCell.Offset(0, 17).Value = Sheets("Sheet2").Range("B" & i).Value
Next i
End Sub
The idea is the following - you have two types of ranges - ranges where you search and ranges where your value should be. They are called Target and Search.
In the code below you loop through all cells in column A of the first worksheets and you look for their value in column A of the second worksheet. If you find the value, you write the value in column B of the second worksheet to the 17. column in the first worksheet:
Private Sub CommandButton1_Click()
Dim targetRange As Range
Dim targetValue As Range
Dim searchRange As Range
Dim lastSearchCell As Range
Dim foundCell As Range
Dim wsTarget As Worksheet
Dim wsSearch As Worksheet
Dim myCell As Range
Set wsTarget = ThisWorkbook.Worksheets(1)
Set wsSearch = ThisWorkbook.Worksheets(2)
With wsTarget
Set targetRange = .Range("A1", .Range("A" & .Rows.Count).End(xlUp))
End With
With wsSearch
Set searchRange = .Range("A1", .Range("A" & .Rows.Count).End(xlUp))
End With
Set lastSearchCell = searchRange.Cells(searchRange.Cells.Count)
For Each myCell In targetRange
Set foundCell = searchRange.Find(What:=myCell, After:=lastSearchCell).Offset(0, 1)
If Not foundCell Is Nothing Then
myCell.Offset(0, 17) = foundCell
Else
MsgBox "Not Found"
End If
Next myCell
End Sub

Excel vba: Find a row based on a unique id, pull it, edit it, then import it back to the same spot with revisions

I'm working on a large data table in excel and I'm trying to create a new sheet (Sheet2) that uses vba/macros to allow for the manipulation of data in sheet1. I've already created functionality to add a new row to the bottom of the table (see below) but now I'm trying to figure out a way to pull a row, based on its' ID (column A in Sheet1), then have the user edit or revise it, and export it back into Sheet1 in its' original location (I've also attached a picture).
Sub Import()
'
' Import Macro
'
' Keyboard Shortcut: Ctrl+Shift+I
'
Application.ScreenUpdating = False
Dim copySheet As Worksheet
Dim pasteSheet As Worksheet
Set copySheet = Worksheets("Sheet3")
Set pasteSheet = Worksheets("Sheet2")
copySheet.Range("B7:R7").Copy
With pasteSheet.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0)
.PasteSpecial xlPasteValues
.PasteSpecial xlPasteFormats
Application.CutCopyMode = False
Application.ScreenUpdating = True
End With
End Sub
Any help is greatly appreciated!
You need to add a function to find the ID. Once you have the ID, only thing left is to copy from sheet3 to sheet2 and later back to sheet 3. I have implemented functions to find the ID and copy data. The structure for Import and Export are basically same but the copy from and paste to parameters to the functions have interchanged
Sub Import()
Dim copySheet As Worksheet
Dim pasteSheet As Worksheet
Set copySheet = Worksheets("Sheet3")
Set pasteSheet = Worksheets("Sheet2")
Dim idRow As Integer
idRow = findId(pasteSheet.Range("C3"))
If (idRow = 0) Then
MsgBox ("ID not found")
End
End If
'implement a function that finds the ID and saves the row number in idRow
Call CopyPaste(copySheet.Range("B" & idRow & ":R" & idRow), _
pasteSheet.Range("A" & Rows.Count).End(xlUp).Offset(1, 0))
End Sub
Sub Export()
Dim copySheet As Worksheet
Dim pasteSheet As Worksheet
Set copySheet = Worksheets("Sheet3")
Set pasteSheet = Worksheets("Sheet2")
Dim idRow As Integer
idRow = findId(pasteSheet.Range("C3"))
If (idRow = 0) Then
MsgBox ("ID not found")
End
End If
'implement a function that finds the ID and saves the row number in idRow
Call CopyPaste(pasteSheet.Range("A" & Rows.Count).End(xlUp).Resize(1, 17), _
copySheet.Range("B" & idRow & ":R" & idRow))
End Sub
Function findId(ids As String) As Integer
Dim findRow As Range
Sheets("Sheet3").Select
'Range("A1:A" & Rows.Count).Select
Columns("A:A").Select
Set findRow = Selection.Find(What:=ids, After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If Not findRow Is Nothing Then
findId = findRow.Row
Else
findId = 0
End If
End Function
Sub CopyPaste(from As Range, copyTo As Range)
from.Copy Destination:=copyTo
Application.CutCopyMode = False
End Sub

Match a Date between 2 Worksheets then Copy and Paste Specific Data

I have 2 work sheets.
In Sh1 I enter a date in Cell 'R2'.
The macro
should then search Sh2 column 'C' for a match.
When a match is found
it will copy from 2 cells below my match & 74 cells down then
PasteSpecial xlPasteValues in Sh1 Cell 'R3'.
The Below example does something similar but not the desired result.
Option Explicit
Sub FindStr()
Dim rFndCell As Range
Dim strData As String
Dim stFnd As String
Dim fCol As Integer
Dim sh As Worksheet
Dim ws As Worksheet
Set ws = Sheets("CTN ORIGINAL")
Set sh = Sheets("Ctn Daily - (enter data here)")
stFnd = ws.Range("R2").Value
With sh
Set rFndCell = .Range("C:C").Find(stFnd, LookIn:=xlValues)
If Not rFndCell Is Nothing Then
fCol = rFndCell.Column
ws.Range("B3:B33").Copy
sh.Cells(6, fCol).PasteSpecial xlPasteValues
Else 'Can't find the item
MsgBox "No Find"
End If
End With
End Sub
Here, I got one for you, if it is not working let me know. I already tested it and it perfectly work for me.
Option Explicit
Sub findAndCopy()
Dim foundCell As Range
Dim strFind As String
Dim fRow, fCol As Integer
Dim sh1, sh2 As Worksheet
'Set sheets
Set sh1 = Sheets("Sheet1")
Set sh2 = Sheets("Sheet2")
'Get find string
strFind = sh1.Range("R2").Value
'Find string in column C of Sheet2
Set foundCell = sh2.Range("C:G").Find(strFind, LookIn:=xlValues)
'If match cell is found
If Not foundCell Is Nothing Then
'Get the row and column
fRow = foundCell.Row
fCol = foundCell.Column
'copy data from Sheet2 (from 2 cell below & 74 cells down)
sh2.Range(Cells(fRow + 2, fCol).Address & ":" & Cells(fRow + 76, fCol).Address).Copy
'paste in range R3 of Sheet1
sh1.Range("R3").PasteSpecial xlPasteValues
'Clear cache
Application.CutCopyMode = False
'If not found, show message.
Else
Call MsgBox("Not found the match cell!", vbExclamation, "Finding String")
End If
End Sub

Resources