How do I Cut a range from one worksheet to Paste to a second and make sure future lines go to the next blank row? - excel

Two questions:
1) I have a spreadsheet (TC) that has data on one page that will be updated daily. There are 28 columns. Essentially I am looking to have the line (row) data cut and paste into a second spreadsheet (Archive) when Col. 28 has a value entered in it. I have the base coding but for some reason it causes Excel to be non-responsive.
I think it might be because the coding goes cell by cell rather than row by row. Can anyone point me in the right direction? (Again, keep in mind, this is a snippet of the coding - I have each Cut and Paste up to Column 28.)
2) The second part of my question is: Will what I have written make sure that when the Command Button is pressed next time, the data will cut and paste to the next blank line. Thank you!
Private Sub CommandButton1_Click()
a = Worksheets("TC").Cells(Rows.Count, 2).End(xlUp).Row
'Dim rng As Range
'Set rng = Worksheets("Archived").Range("A1")
b = 1
For i = 2 To a
If Worksheets(“TC”).Cells(i, 28).Value <> "" Then
'Change # to be the number column of Pt Name
Worksheets(“TC”).Cells(i, 1).Cut
'Change ,# to be the number column of where you want it pasted.
Worksheets(“TC”).Paste Destination:=Worksheets(“Archive”).Cells(b + 1, 1)
'Change ,# to be the number column of SOC
Worksheets(“TC”).Cells(i, 2).Cut
'Change ,# to be the number column of where you want it pasted.
Worksheets(“TC”).Paste Destination:=Worksheets(“Archive”).Cells(b + 1, 2)
b = b + 1
End If
Next
Application.CutCopyMode = False
ThisWorkbook.Worksheets(“TC”).Cells(1, 1).Select
End Sub

You can do something like this:
Private Sub CommandButton1_Click()
Dim i as long, b As Long, shtTC as worksheet, shtArch as worksheet
Set shtTC = Worksheets("TC")
Set shtArch = Worksheets("Archive")
'find the first empty row
b = shtArch.Cells(Rows.Count, 2).End(xlUp).Row + 1 'pick a column which will always be populated
For i = 2 To shtTC.Cells(Rows.Count, 2).End(xlUp).Row
If shtTC.Cells(i, 28).Value <> "" Then
'cut the row
shtTc.Cells(i, 1).Resize(1, 28).Cut shtArch.Cells(b, 1)
b = b + 1
End If
Next
Application.CutCopyMode = False
shtTC.Cells(1, 1).Select
End Sub

Here's an example of how to create the kind of copy results you're looking for. Notice that, unless you specifically want to copy/paste all of the formatting with the data, you don't need to use copy/paste. You can perform the copy by assigning the values of the ranges.
Option Explicit
Private Sub CommandButton1_Click()
CopyData ThisWorkbook.Sheets("TC"), ThisWorkbook.Sheets("Archived")
End Sub
Public Sub CopyData(ByRef source As Worksheet, _
ByRef dest As Worksheet, _
Optional ByVal deleteSource As Boolean = False)
'--- calculate and create the source data range
Const TOTAL_COLUMNS As Long = 1
Dim srcRange As Range
Dim lastRow As Long
With source
lastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
Set srcRange = .Range("A1").Resize(lastRow, TOTAL_COLUMNS)
End With
'--- determine where the data should go
Dim destRange As Range
With dest
lastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
If lastRow > 1 Then lastRow = lastRow + 1
Set destRange = .Cells(lastRow, 1)
Set destRange = destRange.Resize(srcRange.Rows.Count, TOTAL_COLUMNS)
End With
'--- now copy the data
destRange.Value = srcRange.Value
'--- optionally delete the source data
If deleteSource Then
srcRange.Clear
End If
End Sub

Related

How to conditional copy unique values only?

I want to copy unique values over to my destination worksheet but I'm getting an error with my Range. Originally I wrote a RemoveDuplicates code with exact same Range values and it worked perfectly fine. I'm assuming the issue is in my AdvancedFilter line but I can't figure out what's wrong with it.
Edit;
I qualified my ranges and that fixed the issue(updated code). Now I realize that I need at least 2 source rows to filter from. I'm thinking I ditch using AdvancedFilter and try a different approach. Is there a way for me to use the Unique parameter or something similar without AdvancedFilter?
Private Sub moveData()
Dim wb As Workbook
Dim wksData As Worksheet
Dim wksDestination As Worksheet
Dim lastColumn As Integer
Dim lastRow As Integer
Dim destinationRow As Integer
Set wksData = Worksheets("ProspectiveCandidates")
Set wksDestination = Worksheets("Active Candidate Information")
destinationRow = 2
lastColumn = wksData.Range("B" & Columns.Count).End(xlToLeft).Column
lastRow = wksData.Range("B" & Rows.Count).End(xlUp).Row
For i = lastRow To 1 Step -1 'go 'up' the worksheet
If wksData.Cells(i, 8).Value = "Move Forward" Then 'check for Move Forward Value in the current row
'if TRUE, copy row to wksDestination and filter for Unique
wksData.Range(wksData.Cells(i, 2), wksData.Cells(i, 5)).AdvancedFilter _
Action:=xlFilterCopy, _
CopyToRange:=wksDestination.Range(wksDestination.Cells(destinationRow, 2), wksDestination.Cells(destinationRow, 5)), _
Unique:=True
'increment the output row
destinationRow = destinationRow + 1
End If
Next i
End Sub
Edit2;
I updated my For loop and took out AdvancedFilter. I'm having trouble skipping over duplicates and pasting copied values once no duplicates have been detected.
For i = lastRow To 1 Step -1 'go 'up' the worksheet
If wksData.Cells(i, 8).Value = "Move Forward" Then 'check for Move Forward Value in the current row
'if TRUE, copy cells column 2-5 in row i
wksData.Activate
wksData.Range(Cells(i, 2), Cells(i, 5)).Copy
'check for duplicates on wksDestination
For Each xlCell In xlRange
If xlCell.Value = wksData.Cells(i, 2) Then Exit For
Next xlCell
'if no duplicates detected then paste values
wksDestination.Activate
wksDestination.Range(Cells(destinationRow, 2), Cells(destinationRow, 5)).Select
ActiveSheet.Paste
'increment the output row
destinationRow = destinationRow + 1
End If
Next i
Edit3
Here is a partial screenshot of my sheet with the source data:
ProspectiveCandidates
When the status is updated to "Move Forward", I want just the "Candidate Name", "Source", "Team", and "Level" to be copied over to my second sheet("Active Candidate Information").
For this to run automatically, in the sheet code I have
Private Sub Worksheet_Change(ByVal Target As Range)
Application.Run "Module3.moveData"
End Sub
I want to make sure that anytime new values are copied over that they go to the next empty row. I was having issues with an earlier code that would rewrite and mess up the order of my data.

Copy Data From Sheet1 to Sheet2, Inserting Row When Value in Column Changes

How can I use VBA to copy data from sheet1 to sheet 2, with a condition that if the value from column G changes, I insert a new row on sheet 2 below the row holding that last value but above the row holding the next value? Sample input is given, with sample output highlighting the inserted row. Getting all the right columns on the output sheet I can do myself, but the logic for the row insert is giving me trouble.
Dim dataSheet As Worksheet
Dim lastRow As Long, r As Long
Set dataSheet = ActiveSheet 'Worksheets("Sheet1")
With dataSheet
lastRow = .Cells(Rows.Count, "A").End(xlUp).Row
For r = lastRow To 2 Step -1
'compare current row column G to previous row column G, if not the same value, insert row between the two rows
.Rows(r + 1).Resize(UBound + 1).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
End If
Next
Insert Between Groups
Option Explicit
Sub InsertBetweenGroups()
With ActiveSheet.Range("A1").CurrentRegion
Dim rCount As Long: rCount = .Rows.Count
Dim cCount As Long: cCount = .Columns.Count
Dim r As Long
For r = rCount To 2 Step -1
With .Cells(r, "G")
If .Value <> .Offset(1).Value Then
With .Offset(1).EntireRow.Resize(, cCount)
.Insert xlShiftDown, xlFormatFromLeftOrAbove
With .Offset(-1)
.Value = .Offset(-1).Value
.Columns("B").Value = "Data Remote..."
.Columns("G").Value = "Hardware"
.Columns("E:F").ClearContents
.Interior.Color = vbYellow
End With
End With
End If
End With
Next r
End With
End Sub
I have come up with a solution that seems to work for getting the desired output, but it is quite messy compared to #VBasic2008's. I use formulas to fill my empty rows on another sheet; for example:
Worksheets("InvoiceData").Range("V1").Value = "LineDescription"
Worksheets("InvoiceData").Range("V2").Formula2 = "=IF(ISBLANK(A2)=TRUE, ""Hardware"",E2)"
And the VBA to insert the rows:
Sub test()
Dim lRow As Long
'Create InvoiceData sheet to manipulate data
Sheets.Add.Name = "InvoiceData"
'Copy and Paste ABSData sheet as Values
Sheets("ABSData").Cells.Copy
Sheets("InvoiceData").Cells.PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
End Sub

How to traverse to each Column in the same Row in Excel VBA

I'm trying to traverse each column in the same row, I'm new to VBA and any help would be appreciated..
Here's my code:
Sub dural()
Dim i As Long
Dim j As Long
i = 2
Cells(1, i).Select
For i = 2 To Columns.Count
Cells(1, i + j).Select
'Selection.Copy
j = i + 1
Next i
End Sub
Luan Yi,
Your question states "trying to traverse each column in the same row";
the code below shows how to loop through each Column, or loop through
each cell in Row 1 and use .EntireColumn to do something; without using .Select
'Use the With statement that meets your needs
'define your variables
Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Sheet1") 'change worksheet name as needed
Dim lCol As Long: lCol = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column 'define last used column in row 1
For i = 2 To lCol
'If you want to loop through each column, you can use...
With ws.Columns(i)
'you can do something, for example using .Delete or .Copy, etc.
End With
'or
'If you want to loop through each cell in row 1, the you can use...
With ws.Cells(1, i)
'you can do something, for example using .EntireColumn.Delete or .EntireColumn.Copy, etc.
End With
Next i

How to select and cut an entire row from sheet1 and paste it in sheet2

Simple table in sheet1 with data in cells(A2:C4), column D is empty. I want to select the entire row, cut and paste it in sheet2 when a time is added in colum D.
When I clicked on the logout button, It will add a time punch in column D.
I want that entire row to be selected and then cut and paste in sheet2.
I want also to arrange the remaining entry to move up so that there's no spaces between.
Screenshot
Dim CM As Boolean
Private Sub cmdMove_Click()
Dim myLog As Worksheet
Dim myLogSheet As Range
Dim i As Long: i = 1
Set myLog = Sheets("Sheet1")
Set myLogSheet = myLog.Range("B:B").Find(txtID.Value, , , xlWhole)
'Dim LastRow As Long
'LastRow = Sheets("Sheet2").Range("A65536").End(xlUp).Row + 1
If Not myLogSheet Is Nothing Then
myLogSheet.Offset(0, 2) = Format(Now, "hh:mm:ss")
With ActiveSheet
For n = nLastRow To nFirstRow Step -1
If .Cells(n, "D") = "" Then
.Cells(n, "D").EntireRow.Cut Sheet2.Cells(i, "A")
.Cells(n, "D").EntireRow.Delete '~~> if you want to delete
i = i + 1
End If
Next
End With
Else
txtName.Value = "NO RECORD"
End If
End Sub
You need to remove your loop, and just use the row you found using the Find:
Dim CM As Boolean
Private Sub cmdMove_Click()
Dim myLog As Worksheet
Dim myLogSheet As Range
Dim myLogSheetRow As Long
Dim i As Long
i = 1
'Probably you want:
i = Sheet2.Cells(Sheet2.Rows.Count, "A").End(xlUp).Row + 1
Set myLog = Sheets("Sheet1")
Set myLogSheet = myLog.Range("B:B").Find(txtID.Value, , , xlWhole)
If Not myLogSheet Is Nothing Then
myLogSheetRow = myLogSheet.Row ' So we can delete the row later
myLogSheet.Offset(0, 2) = Format(Now, "hh:mm:ss")
myLogSheet.EntireRow.Cut Sheet2.Cells(i, "A")
myLog.Rows(myLogSheetRow).Delete
Else
txtName.Value = "NO RECORD"
End If
End Sub
Note that Excel exhibits very odd behaviour when deleting the row after the Cut. Using a statement of myLogSheet.EntireRow.Delete after the Cut causes Excel to delete the row in Sheet1 based on the new location of the cell in Sheet2. This is why a variable needs to be created to refer to the row prior to the Cut, so that it can be used in the Delete after the Cut.

VBA- How to copy and paste values to another sheet beginning on next available row

I have a vba code that copies rows on a sheet to another sheet depending if column A = 1 and it works perfectly. I am trying to make it paste to the next available row instead of overwriting the data that is already there in order to make a log. Here is the code I have already but I can't seem to figure out how to make it paste to the next available row. Any help would be greatly appreciated! Thanks in advance!
Sub Log()
Dim rng As Range
Dim lastRow As Long
Dim cell As Variant
Dim count As Long
count = 0
With ActiveSheet
lastRow = .Range("A" & .Rows.count).End(xlUp).Row
Set rng = .Range("A3:A" & lastRow)
For Each cell In rng
If cell.Value = "1" Then
Range(cell.Offset(0, 1), cell.Offset(0, 6)).Copy
Range("'Log'!B3").Offset(count, 0).PasteSpecial xlPasteValues
count = count + 1
End If
Next
End With
End Sub
You just need to loop through the source sheet.
Try using .Cells(row,col) instead of Range..
This example is heavy on the comments to help understand the looping process.
You will need a few additional Functions to make this work using this code.
LastRow Function
Function lastRow(sheet As String) As Long
lastRow = Sheets(sheet).Cells(Rows.Count, "A").End(xlUp).Row 'Using Cells()
End Function
LastCol Function
Function lastCol(sheet As String) As Long
lastCol = Sheets(sheet).Cells(2, Columns.Count).End(xlToLeft).Column
End Function
Code for solution: Assuming you have your target sheet's headers already set up AND the target and source sheet share the same formatting.
Sub Log()
Dim source As String, target As String
Dim sRow As Long, col As Long, tRow As Long
'Declare Sheets
source = "Sheet1"
target = "Sheet2"
'Loop through rows of source sheet
For sRow = 2 To lastRow(source)
'Get current last row of Target Sheet
tRow = lastRow(target) + 1
'Meet criteria for Column A to = 1 on Source
If Sheets(source).Cells(sRow, 1) = "1" Then
'Copy each column of source sheet to target sheet in same order
For col = 1 To lastCol(source)
Sheets(target).Cells(tRow, col) = Sheets(source).Cells(sRow, col)
Next col
End If
Next sRow
End Sub

Resources