Paste to row based on row number value in cell - excel

I am trying to write a macro that copies data from a form (Contractor Entry Form, range "U5:AT5") and pastes it to a database (CONTRACTOR DATABASE).
When a record is edited, it requests the Employee ID# and finds that row on the database, and pastes that row number reference temporarily into cell Contractor Entry Form "L1".
I need to then paste the copied data to the database on that row number (-1) that is referenced in cell "L1". If there is no value in "L1" that means it is a new entry and should then just paste to the last row -- as opposed to pasting over a previous record row.
Help, please. My code is here--
Sub ContractorEntry
Range("U5:AT5").Copy
Sheets("CONTRACTOR_DATABASE").Select
Dim R As Integer
R = Worksheets("CONTRACTOR ENTRY").Range("L1").value
'note-- if there is a value in CONTRACTOR ENTRY L1>0 then
' (it represents a row number --- paste value to that row -1 onto
' Contractor Database sheet.
If Worksheets("CONTRACTOR ENTRY").Range("L1") > 0 Then
Sheets("CONTRACTOR_DATABASE").Cells (R -1, 1)
Selection.PasteSpecial
End If
Else
'if there is no value in cell L1 then the following to just paste to the next blank row
lMaxRows = Cells(Rows.Count, "A").End(xlUpSelection.PasteSpecial.Row
Range("A" & lMaxRows + 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, _
SkipBlanks :=False, Transpose:=False
'This returns to the contractor entry form and clears contents
Sheets("CONTRACTOR ENTRY").Select
Range("D3:M1").Select
Selection.ClearContents
'Should go back to Contractor Entry Form for Name and a new entry in cell D3
Range("D3").Select
End Sub

There's almost never any need to use Select/Activate see here for guidelines on how to improve your code: How to avoid using Select in Excel VBA
Something like this should work:
Sub ContractorEntry()
Dim rw, wsInput As Worksheet, wsDB As Worksheet
'use worksheet varaibles for easier maintenance
Set wsInput = ThisWorkbook.Worksheets("CONTRACTOR ENTRY")
Set wsDB = ThisWorkbook.Worksheets("CONTRACTOR_DATABASE")
rw = wsInput.Range("L1").Value - 1
'if row not present then get next empty row
If rw < 1 Then rw = wsDB.Cells(Rows.Count, "A").End(xlUp).Row + 1
'copy over values directly (no copy/paste)
With wsInput.Range("U5:AT5")
wsDB.Cells(rw, "A").Resize(.Rows.Count, .Columns.Count).Value = .Value
End With
With wsInput
.Activate
.Range("D3:M1").ClearContents
.Range("D3").Select
End With
End Sub

Related

Setting a dynamic paste range within a nested loop

I have code that creates a bunch of new sheets, names them, and then loops through them searching a dataset for the name of the sheet and transposing data rows with a value matching the name of the sheet.
I've gotten it to work transposing each row to the next column to the right, but for printing purposes, I'd like it to move to the bottom of the last pasted cell, skip a row (or better yet, insert a page break), and then paste the next one.
Something about the way I've tried to tell it to count the rows, move down, and then start again, isn't working. It appears to be pasting multiple times over previously pasted data.
I've tried several different ways of counting the rows and adding a row, or inserting a page break, but I can't get it working. I thought maybe I needed to move the rowcount function out of the IF statement, but that didn't work either.
Sub Franchise_Data4()
'searches Raw Data sheet for the Franchise ID associated with each sheet name; then transposes each relevant row onto the associated sheet'
Dim Scol As Range, Cell As Object, rawdata As Worksheet, ws As Worksheet, lc As Long, rowcountA As Integer, startR As Integer, labels As Range
Set rawdata = ThisWorkbook.Worksheets("Raw Data")
Set Scol = rawdata.Range("$C$2:$C$2000") 'Franchise ID column on Raw Data sheet'
Set labels = ThisWorkbook.Worksheets("Raw Data").Range("A1:AZ1")
For Each ws In ThisWorkbook.Worksheets
If ws.Name <> "Raw Data" And ws.Name <> "Pivot" Then
With ws 'cycles through all of the sheets with Franchise ID's as the name
startR = 0
For Each Cell In Scol 'should scan the C column on the Raw Data sheet'
If IsEmpty(Cell) Then Exit For
If Cell.Value = ws.Name Then 'checks for cells that contain the same Franchise ID as the current sheet in the cycle'
Cell.EntireRow.Copy
ws.Cells(startR + 1, 2).PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Operation:= _
xlNone, SkipBlanks:=False, Transpose:=True
labels.Copy
ws.Cells(startR + 1, 1).PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Operation:= _
xlNone, SkipBlanks:=False, Transpose:=True
End If
rowcountA = Cells(Cells.Rows.Count, "A").End(xlUp).Row
startR = rowcountA + 1
Next
End With
End If
Next ws
Application.CutCopyMode = False
End Sub
It appears to paste the first data set correctly, then move down 1 row (instead of the rowcount+1) and paste again. Then I guess it either stops, or it continues pasting the rest in the same spot.
You need to fully qualify the Worksheet that the Cells are on.
rowcountA = Cells(Cells.Rows.Count, "A").End(xlUp).Row
There's an implicit ActiveSheet here, not a reference to ws as you would want. You already have a With ws...End With so change this line to:
rowcountA = .Cells(.Rows.Count, "A").End(xlUp).Row
Note that there are other instances where you are "repeating" the ws instead of fully taking advantage of the With ws...End With.

Loop in Excel 2013

I am having problems with getting a loop to run.
I have a Source1 spreadsheet with a list of values in Column A on the CC's tab. Each number is to be copied individually into Cell B1 on the Template tab of the Source2 spreadsheet.
Cell B1 triggers a consolidation of information (mainly indexed info) and displays it in a template - an aggregate picture of lots of background data. I then Copy A1:K71, and paste this into the Output tab of the Source1 spreadsheet.
I want to work down the list in Column A of the CC's tab, and append each output from the Source2 spreadsheet into the Output tab automatically.
I have the copy/paste working, but I am having problems with the loop.
Selection.Copy
Windows("Source2.xlsx").Activate
Range("B1").Select
ActiveSheet.Paste
Range("A1:K71").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Source1.xlsm").Activate
Sheets("Ouput").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
ActiveWindow.SelectedSheets.HPageBreaks.Add Before:=ActiveCell
#Andrew, after reading and re-reading your question, I don't think a loop of any kind is necessary. The macro-recorder results you gave above provide information about how you can solve this. I tested this by creating a Source1 Workbook with values placed in column A on a sheet labeled CC's. I also added a sheet labeled Output. Then, I opened a second Workbook with a sheet labeled Template. Here is the sub-procedure I used to produce the result I think you are describing above:
Sub AndrewProject()
' COMMENT: Declare variables used throughout this procedure
Dim InitialVals As Range
Dim OutputVals As Range
Dim FinalResults As Range
Dim FinalOutput As Range
Dim cell As Variant
' COMMENT: Set the range objects so they are easier to manipulate
Set InitialVals = Workbooks("Source1").Worksheets("CC's").Range("A2:A72")
Set OutputVals = Workbooks("Source2").Worksheets("Template").Range("B2:B72")
Set FinalResults = Workbooks("Source2").Worksheets("Template").Range("A2:K72")
Set FinalOutput = Workbooks("Source1").Worksheets("Output").Range("A2:K72")
' COMMENT: This line copies the values in Source1 Workbook and pastes them into Source2 Workbook
InitialVals.Copy
OutputVals.PasteSpecial xlPasteValues
' COMMENT: Additional code goes here to create the desired output. To simplify things, I put a
' function in Source2, column K that concatenates the string "Output" with InitialVals copied
' from Source1. To emulate your Source2 Template, I placed random values between 1 and 1000 in
' Cells A2:A72 and C2:J72.
' COMMENT: Copy the FinalResults from Source2 "Template" tab into the Source1 "Output" tab
FinalResults.Copy
FinalOutput.PasteSpecial xlPasteAll
End Sub
OK #Andrew...this has got to be my last attempt. I believe this answers your question.
Sub AutomateIt()
' Declare your variables
Dim cell As Range
Dim Src1CC As Range
Dim Src2Template As Range
Dim Src2Calcs As Range
Dim Src1Output As Range
Dim NextRow As Long
Dim count As Integer
' Set the ranges so they can be manipulated
Set Src1CC = Workbooks("Source1").Worksheets("CC").Range("A1")
Set Src2Template = Workbooks("Source2").Worksheets("Template").Range("B1")
Set Src2Calcs = Workbooks("Source2").Worksheets("Template").Range("A1:K72")
Set Src1Output = Workbooks("Source1").Worksheets("Output").Range("A1:K72")
Src2Template.ClearContents
count = 0
' Loop through all the cells and calculate stuff
For Each cell In Src1CC.Range(Src1CC, Src1CC.End(xlDown))
'Determine the next empty row (plus a space for readability)
NextRow = Cells(Rows.count, 1).End(xlUp).Row + 2
'Send a copy of the Src1CC cell value to the Src2Template
cell.Copy Src2Template
'Re-calculate A1:K72 based on cell value
Src2Calcs.Calculate
'Copy Src2Calcs results and paste to Source1 Output
Src2Calcs.Copy
Src1Output.PasteSpecial xlPasteValues
count = count + 1
MsgBox "You have pasted " & count & " results."
'Change Src1Output Range so that the next paste is the next blank row
'plus one additional row for readability.
Set Src1Output = Workbooks("Source1").Worksheets("Output").Range(Cells(NextRow, 1), Cells(NextRow, 11))
Next cell
End Sub

Code to copy and paste one range to another, multiple times in VBA excel

I have written the following code to copy and paste range w21:W1759 into range AD21:
Sub CommandButton1_Click()
Dim i As Integer, j As Integer
For j = 1 To Range("d7")
Range("d8") = j
'Calculate
Range("w21:W1759").Select
Selection.Copy
Range("AD21").Select
Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=False
Next j
End Sub
My data in range w21:W1759 is set to change (due to random sampling) on every click and I want the new data in this range to be copied and pasted to range "ae" (the adjacent column). Then on the next click to "af" and so on and so on. What code do I need to add to the above to achieve this?
Thanks very much for the help
This will depend somewhat on what is to the right of column AC. If column Ad is the first empty column then it is easy to copy to. Subsequent copying operations can use the same next-empty-column method to fill columns AE, AF, etc.
Sub CommandButton1_Click()
Dim i As Long, j As Long
With Worksheets("Sheet1")
For j = 1 To .Range("d7")
.Range("d8") = j
.Calculate
With .Range("w21:w1759")
.Parent.Cells(21, Columns.Count).End(xlToLeft).Offset(0, 1).Resize(.Rows.Count, .Columns.Count) = .Value
End With
Next j
End With
End Sub
I've altered your Copy, PasteSpecial Values method to be a direct value transfer. This is faster and does not involve the clipboard.

Find last non-empty cell of a row, then copy till that cell and paste

VBA code which finds the last non empty cell of Row 5, copies the data till that cell of Row 5 and pastes that data as values after transposing. I tried to record a macro by copying the data but it didn't work.
I'm assuming you're talking about excel vba. The below code copies from a range in sheet1 column A, down to the last data in the row ( you can change this to be only to row 5 if you have data after 5 that you don't want to copy). Then it transposes it on to sheet2.
update to only go to 5
Sub someMacro()
Dim answerRange As Range
Dim checkBlankRange As Range
Dim lastRowInRange As Long
Dim lastcolumn As Long
Set checkBlankRange = Worksheets("Sheet1").Range("A1:A5") 'changed to 1 to 5
lastRowInRange = 5 ' default to 5
lastcolumn = Sheets("Sheet1").Cells.Find(What:="*", SearchDirection:=xlPrevious, SearchOrder:=xlByColumns).Column
'or you can use line below for last column
'lastcolumn = Sheets("Sheet1").Cells(1, Sheets("Sheet1").Columns.Count).End(xlToLeft).Column
For Each cell In checkBlankRange
If cell.Value = "" Then 'first empty cell
lastRowInRange = cell.row 'get the row number of the empty cell
Exit For
End If
Next cell
Set answerRange = Sheets("Sheet1").Range(Sheets("Sheet1").Cells(1, 1), Sheets("Sheet1").Cells(lastRowInRange, lastcolumn))
answerRange.Copy
ActiveWorkbook.Sheets("Sheet2").Range("A1").PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:=False, Transpose:=True
End Sub
if the data is always going to be in those colums you wont need alot of the code and you can just use what you had in your recorded macro - cleaned up to remove selects
Sub simpleVersion()
Sheets("Sheet1").Range("A1:F5").Copy
Sheets("Sheet2").Range("A1").PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:=False, Transpose:=True
End Sub

Copy data from one column, paste in first empty column

I have data in COLUMN H2. . I want to copy them somewhere else on the same spreadsheet.
But where I copy it will change one COLUMN at a time, as each column below gets filled, by the macro.
My existing macro successfully searches for, and pastes this column of data into an empty column below, such as B31. When I have 10 new pieces of data, the next time I run the macro, I want it to paste it into C31, in Column C (being the next empty row) The next time, D31.......etc.. My macro repeatedly grabs the data in H2:H11 and pastes it into B31, but overwrites that column each time I run the macro again. It is not "seeing" column B already having data placed there by running the macro before.... What is wrong with the code?
Range("H2:H11").Select Selection.Copy
Range("A31").Select
Range("A31:M31").End(xlToLeft).Offset(0, 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
ActiveCell.Rows("1:10").EntireRow.Select
Application.CutCopyMode = False
Range("A31:M31").End(xlToLeft).Offset(0, 1).Select
should be
Range("M31").End(xlToLeft).Offset(0, 1).Select
Alternative solution is below (i've not tested it, as i'm not on my MS PC, sorry)
dim lRow as Long 'Output Row
lRow = 31 'Start at row 31
For i = 2 to 13 'Column B to Column M
'Count if there is any values in the columns
'(if there is a header then change the 0 to 1)
If Application.WorksheetFunction.CountA(ActiveSheet.Columns(i)) = 0 Then
For Each c in Range("H2:H11") 'Cycle through output values
ActiveSheet.Cells(lRow, i).value = c.Value 'Assign values
lRow = lRow + 1 'Increment row number
next c
exit for 'exit column loop
end if
next i

Resources