I have been searching an efficient way to copy data from one spreadsheet to another and always paste one row below. Someone helped me with this code, but unfortunately it is not working for the columns i need. So I need to copy data from E2:P2 on sheet "Dividends" and paste firstly on C11:N11, then tomorrow if I run again should paste on C12:N12 and always one row below... When I run the code, it pastes the data on C111:N111, and if I run again still paste on the same range, so does not work for me. I would appreciate your help.
Sub Copy_range()
' edit line below to change where data will be copied from
Worksheets("Dividends").Range("E2:P2").Copy ' copy the value
' select the first cell on the "Draft" sheet
Worksheets("Draft").Select
ActiveSheet.Range("C11").Select
Dim count As Integer
count = 1
'skip all used cells
Do While Not (ActiveCell.value = None)
ActiveCell.Offset(1, 0).Range("C11").Select
count = count + 1
Loop
Worksheets("Draft").Range("C11" & count & ":N11" & count).PasteSpecial ' paste the value
End Sub
Using ActiveCell and Offset can often lead to unexpected results and makes the code hard to read. You can have the counting loop working without all of this, by simply going through column C cells starting at C11 and looking for empty one.
One of possible ways is
Sub Copy_range
Dim count As Integer
count = 11
Do While Worksheets("Draft").Range("C" & count).Value <> ""
'<>"" means "is not empty", as long as this happens we go down looking for empty cell
count = count + 1
Loop
'Now count is row with first empty cell outside of top 10 rows in column C
Worksheets("Dividends").Range("E2:P2").Copy
Worksheets("Draft").Range("C" & count).PasteSpecial xlPasteValues
End Sub
I would say that you could most likely just solve this with a Vlookup Formula autofilled to the target area. But the below code should do it.
Option Explicit
Sub moveDividends()
Dim wsF As Worksheet 'From
Dim wsD As Worksheet 'Destination
Dim i As Long
Dim LastRow As Long
Set wsF = ThisWorkbook.Sheets("Sheet1")
Set wsD = ThisWorkbook.Sheets("Sheet2")
With wsD
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
LastRow = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).row
Else
LastRow = 1
End If
End With
With wsD
LastRow = LastRow + 1
wsD.Cells(LastRow, "C").Value = wsF.Cells(2, 5).Value
wsD.Cells(LastRow, "D").Value = wsF.Cells(2, 6).Value
wsD.Cells(LastRow, "E").Value = wsF.Cells(2, 7).Value
wsD.Cells(LastRow, "F").Value = wsF.Cells(2, 8).Value
wsD.Cells(LastRow, "G").Value = wsF.Cells(2, 9).Value
wsD.Cells(LastRow, "H").Value = wsF.Cells(2, 10).Value
wsD.Cells(LastRow, "I").Value = wsF.Cells(2, 11).Value
wsD.Cells(LastRow, "J").Value = wsF.Cells(2, 12).Value
wsD.Cells(LastRow, "K").Value = wsF.Cells(2, 13).Value
wsD.Cells(LastRow, "L").Value = wsF.Cells(2, 14).Value
wsD.Cells(LastRow, "M").Value = wsF.Cells(2, 15).Value
wsD.Cells(LastRow, "N").Value = wsF.Cells(2, 16).Value
End With
End Sub
all method are rigth, or simply use:
Sub Copy_range()
Dim lastRow As Long
' edit line below to change where data will be copied from
Worksheets("Dividends").Range("E2:P2").Copy ' copy the value
' find the 1th not-used rows
lastRow = Worksheets("Draft").Cells(1048576, 3).End(xlUp).Row + 1
lastRow = IIf(lastrows < 11, 11, lastrows) 'optional if is possible that the rows 10, 9, 8,.... are empty
Worksheets("Draft").Range("C" & lastRow).PasteSpecial xlPasteValues ' paste the value
End Sub
Use the below
Sub Copy_range()
' edit line below to change where data will be copied from
Worksheets("Dividends").Range("E2:P2").Copy ' copy the value
'count cells and add 1 for next row
last_row = Worksheets("Draft").Range("C" & Worksheets("Draft").Rows.Count).End(xlUp).Row + 1
If last_row > 1000000 Then last_row = 1
Worksheets("Draft").Range("C" & last_row ).PasteSpecial
' paste the value only need to ref first cell
End Sub
Related
I have a question regarding this post (VBA copy rows that meet criteria to another sheet)
His script:
Sub LastRowInOneColumn()
'Find the last used row in a Column: column A in this example
Worksheets("Sheet2").Activate
Dim LastRow As Long
With ActiveSheet
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
End With
MsgBox (LastRow)
For i = 1 To LastRow
If Worksheets("Sheet2").Cells(i, 1).Value = "X" Then
ActiveSheet.Row.Value.Copy _
Destination:=Hoja1
End If
Next i
End Sub
I wonder if there are multiple conditions in just 1 If statement. The idea is to copy and paste data to another sheet if column1 = "X", or column2 ="Y", or (column1 = "X" and column2 = "Y").
I changed by myself and run, but the output sheet looks quite weird.
If Worksheets("Sheet2").Cells(i, 1).Value = "X" Or _
Worksheets("Sheet2").Cells(i, 2).Value = "Y" Or _
(Worksheets("Sheet2").Cells(i, 1).Value = "X" And _
Worksheets("Sheet2").Cells(i, 2).Value = "Y") Then
Hope You are all Safe
I'm trying to calculate MAX, MIN and AVG Values of filled cells which are continued without blank cell (As you can see it in the left side of the sample image ).
I'm facing problem in selecting these randomly placed cells and calculate the above values and also "From" and "To" values of respective range.
Please let me know how to do it. So far I've constructed following code
Dim Cel As Range
Dim lastrow As Long
Dim destSht As Worksheet
Set destSht = Worksheets("Final")
With Worksheets("Source")
lastrow = .Range("B" & .Rows.Count).End(xlUp).Row
For Each Cel In .Range("C2:C" & lastrow)
If .Cells(Cel.Row, "C") <> "" Then
Cel.Offset(0, -1).Copy Destination:=destSht.Cells(destSht.Rows.Count, 1).End(xlUp).Offset(0, 1)
'It will give "From" Column
'' Plz suggest for "To" Column
Range("G5").Select
ActiveCell.FormulaR1C1 = "=MAX(RC[-4]:R[4]C[-4])" 'It will give values "MAX" Column
Range("H5").Select
ActiveCell.FormulaR1C1 = "=MIN(RC[-5]:R[4]C[-5])" 'It will give values "MIN" Column
Range("I5").Select
ActiveCell.FormulaR1C1 = "=AVERAGE(RC[-6]:R[4]C[-6])" 'It will give values "AVG" Column
End If
Next
Did some quick, which should work.
I don't know what you want to do in the "Final" worksheet, so haven't focused on that line.
Logic is to have one big loop (For i...) that go through the whole Column C. When a value is found in column C (If .Cells(i, "C") <> "" Then), we perform a "small loop" (For j = i To lastrow + 1) to check next empty cell to decide the "small group" range. When that range is decided we perform the To, From, MAX, MIN and AVG formulas, which has to be dynamic.
Option Explicit
Sub trial()
Dim lastrow As Long
Dim destSht As Worksheet
Dim i As Long, j As Long
Set destSht = Worksheets("Final")
With Worksheets("Source")
lastrow = .Range("B" & .Rows.Count).End(xlUp).Row
For i = 2 To lastrow + 1 'loop whole range (column C)
If .Cells(i, "C") <> "" Then 'If column C is not empty then
For j = i To lastrow + 1 'Loop "group" range to find next empty cell. Start from current loop i to last row and add one row to get to next empty cell.
If .Cells(j, "C") = "" Then 'When next empty cell is found (i.e. end of small group range) then apply formulas
.Cells(i, "E").Value = .Cells(i, "B").Value 'From
.Cells(i, "F").Value = .Cells(j - 1, "B").Value 'To
.Cells(i, "G").Formula = "=MAX(C" & i & ":C" & j - 1 & ")" 'MAX
.Cells(i, "H").Formula = "=MIN(C" & i & ":C" & j - 1 & ")" 'MIN
.Cells(i, "I").Formula = "=AVERAGE(C" & i & ":C" & j - 1 & ")" 'AVG
Exit For
End If
Next j
End If
Next i
End With
End Sub
Result:
i have a macro where i copy paste a range, which also has buttons in there.
Now i dont want the buttons to get copied. How can i do that?
I copy the whole table and insert it again at A32.
lrow = .Cells(Rows.Count, 1).End(xlUp).row
Do While counter = 0
For i = 32 To lrow
If .Cells(i, 1).Value = "Review Participants" And counter = 1 Then
lastrev = lrowrev
lrowrev = i - 1 'row where the second last review starts
aboveR = lrowrev - lastrev
Exit For
ElseIf .Cells(i, 1).Value = "Review Participants" And counter <> 1 Then
counter = counter + 1
lrowrev = i
lcol = 11 'hardcode last col ~~ Alt: 'lcol = .Cells(i + 1, .Columns.Count).End(xlToLeft).Column 'last meeting of the review is our reference for lastcol
ElseIf counter = 1 And i = lrow Then
lrowrev = i + 2
aboveR = (i + 2) - 32
Exit For
End If
Next
Loop
lastcolumn = Split(Cells(, lcol).Address, "$")(1)
Set rngtocopy = .Range("A" & 32 & ":" & lastcolumn & lrowrev)
Debug.Print rngtocopy.Address
'aboveR = .Range("A" & 32 & ":" & lastcolumn & lrowrev - 1).Rows.Count ' amount of rows copied
Set rngins = .Range("A32").EntireRow
Debug.Print rngins.EntireRow.Resize(aboveR + 2).Address
rngins.EntireRow.Resize(aboveR + 2).Insert xlShiftDown 'insert the amount of rows, we copied
'Range("A" & lrow).Offset(5).EntireRow.Hidden = False
Set rngins = .Range("A32")
Debug.Print rngins.Address
rngtocopy.Copy
rngins.PasteSpecial Paste:=xlPasteAll
Try this code, please:
Sub copyRangeNoButt()
Dim sh As Worksheet, rng As Range, arrRng As Variant
Set sh = ActiveSheet
Set rng = sh.Range("D2:E10"): rng.Copy
arrRng = rng.value
With sh.Range("H2").Resize(UBound(arrRng, 1), UBound(arrRng, 2))
.value = arrRng
.PasteSpecial xlPasteFormats'comment this line if format is not needed. It takes much more time than all the rest of the code, in case of a big range...
End With
End Sub
Of course, you must adapt the code to use your range to be copied definition and the cell where to be pasted (even if in another worksheet).
Now i dont want the buttons to get copied. How can i do that?
You can also use PasteSpecial. You can take advantage of XlPasteType enumeration to copy and paste only relevant part. For example, here is a one liner in case you want to paste
A. Everything except the image
rng.PasteSpecial Paste:=xlPasteAllUsingSourceTheme
B. Only Values
rng.PasteSpecial Paste:=xlPasteValues
In action
enter image description hereThere are 2 sheets, Sheet1 and Sheet2.
Sheet1 contain 10 columns and 5 rows with data including blank.
The requirement is to copy the data from Sheet 1 and to put in another sheet Sheet 2, wherein only populate the cell which is not blank.
I get the run time error 1004 - Application or object defined error.
The code snippet is:-
Set wsht1 = ThisWorkbook.Worksheets("Sheet1")
Set wsht2 = Sheets("Sheet2")
finalrow = wsht1.Cells(wsht1.Rows.Count, 1).End(xlUp).Row
For i = 1 To finalrow
If wsht1.Cells(i, 1).Value <> " " Then
Range(Cells(i, 2), Cells(i, 2)).Copy
Worksheets("Sheet2").Select
wsht2.Range(Cells(1, i)).PasteSpecial Paste:=xlPasteFormats
End If
Next i
Can u help me in sorting this out?
You cannot define a range like that:
wsht2.Range(Cells(1, i))
you might use:
wsht2.Cells(1, i).PasteSpecial Paste:=xlPasteFormats
BTW: with this code you won't find empty cells:
If wsht1.Cells(i, 1).Value <> " " Then
you should use:
If wsht1.Cells(i, 1).Value <> "" Then
(the difference is a missing space between the quotes)
if you want to copy the values only and to make it with a loop I'd do the following:
Sub copying()
Set wsht1 = ThisWorkbook.Worksheets("Sheet1")
Set wsht2 = Sheets("Sheet2")
finalrow = wsht1.Cells(wsht1.Rows.Count, 1).End(xlUp).Row
For i = 1 To finalrow
If wsht1.Cells(i, 1).Value <> "" Then
For j = 1 To 5
wsht2.Cells(i, j).Value = wsht1.Cells(i, j).Value
Next j
End If
Next i
End Sub
If you only have 5 cells with data in Sheet 1 and only want those 5 rows copying to Sheet 2 use the following, similar to Shai's answer above with an extra counter for the rows in Sheet 2.
Sub copying()
Set wsht1 = ThisWorkbook.Worksheets("Sheet1")
Set wsht2 = Sheets("Sheet2")
finalrow = wsht1.Cells(wsht1.Rows.Count, 1).End(xlUp).Row
k = 1
For i = 1 To finalrow
If wsht1.Cells(i, 1).Value <> "" Then
For j = 1 To 5
wsht2.Cells(k, j).Value = wsht1.Cells(i, j).Value
Next j
k = k + 1
End If
Next i
End Sub
EDIT
As per your comment if you want to dynamically change j replace For j = 1 To 5 with
For j = 1 To wsht1.Cells(i, Columns.Count).End(xlToLeft).Column
The code below will copy only values in Column A (non-empty cells) from Sheet 1 to Sheet2:
Dim j As Long
Set wsht1 = ThisWorkbook.Worksheets("Sheet1")
Set wsht2 = Sheets("Sheet2")
finalrow = wsht1.Cells(wsht1.Rows.Count, 1).End(xlUp).Row
j = 1
For i = 1 To finalrow
With wsht1
' if you compare to empty string, you need to remove the space inside the quotes
If .Cells(i, 1).Value <> "" And .Cells(i, 1).Value <> " " Then
.Cells(i, 1).Copy ' since you are copying a single cell, there's no need to use a Range
wsht2.Range("A" & j).PasteSpecial Paste:=xlPasteValues, Paste:=xlPasteFormats
j = j + 1
End If
End With
Next i
Struggling a bit with this code, I haven't ever had to reference one column and copy and paste to another tab in VBA so here goes..
I have an excel document with a table on it similar to below:
I need my code to look in column A find the first name, in this case, Nicola. I then want it to look at column B and check to see if she has the word "Internet" appear in any of the records stored against her, as she does the code will ignore her and move down to the next name on the list, in this case, Graham. It will then look to column B and check if he has the word "Internet". As he doesn't, the code needs to copy the Information from column A & B in relation to this persons name and paste the information into another sheet in the workbook.
Sub Test3()
Dim x As String
Dim found As Boolean
Range("B2").Select
x = "Internet"
found = False
Do Until IsEmpty(ActiveCell)
If ActiveCell.Value = x Then
found = True
Exit Do
End If
ActiveCell.Offset(1, 0).Select
Loop
If found = False Then
Sheets("Groupings").Activate
Sheets("Groupings").Range("A:B").Select
Selection.Copy
Sheets("Sheet1").Select
Sheets("Sheet1").Range("A:B").PasteSpecial
End If
End Sub
Any help would be greatly appreciated.
Thanks
Paula
Private Sub Test3()
Application.ScreenUpdating = False
Set sh1 = Sheets("Groupings") 'data sheet
Set sh2 = Sheets("Sheet1") 'paste sheet
myVar = sh1.Range("D1")
Lastrow = sh1.Range("B" & Rows.Count).End(xlUp).Row
For i = 2 To Lastrow '2 being the first row to test
If Len(sh1.Range("A" & i)) > 0 Then
Set myFind = Nothing
If WorksheetFunction.CountA(sh1.Range("A" & i, "A" & Lastrow)) > 1 Then
If Len(sh1.Range("A" & i + 1)) = 0 Then
nextrow = sh1.Range("A" & i).End(xlDown).Row - 1
Else
nextrow = nextrow + 1
End If
Set myFind = sh1.Range("B" & i, "B" & nextrow).Find(What:=myVar, LookIn:=xlFormulas, LookAt:=xlWhole)
Else
nextrow = Lastrow
Set myFind = sh1.Range("B" & i, "B" & nextrow).Find(What:=myVar, LookIn:=xlFormulas, LookAt:=xlWhole)
End If
If myFind Is Nothing Then
sh1.Range("A" & i, "B" & nextrow).Copy
sh2.Range("A" & sh2.Range("B" & Rows.Count).End(xlUp).Row + 1).PasteSpecial xlPasteValues
Application.CutCopyMode = False
End If
End If
Next
End Sub
I don't clearly see the structure of your data, but assuming the original data is in Worksheet Data, I think the following is going to do what you want (edited to search for two conditions).
Private Sub Test3()
Dim lLastRow as Long
Dim a as Integer
Dim i as Integer
Dim sText1 As String
Dim sText2 As String
sText1 = Worksheets("Data").Cells(1, 5).Value 'search text #1, typed in E1
sText2 = Worksheets("Data").Cells(2, 5).Value 'search text #2, typed in E2
lLastRow = Cells(Rows.Count, 1).End(xlUp).Row
a = 1
For i = 2 To lLastRow
If (Worksheets("Data").Cells(i, 1).Value <> "") Then
If (Worksheets("Data").Cells(i, 2).Value <> sText1 And Worksheets("Data").Cells(i + 1, 2).Value <> sText1 And Worksheets("Data").Cells(i, 2).Value <> sText2 And Worksheets("Data").Cells(i + 1, 2).Value <> sText2) Then
Worksheets("Groupings").Cells(a, 1).Value = Worksheets("Data").Cells(i, 1).Value
Worksheets("Groupings").Cells(a, 2).Value = Worksheets("Data").Cells(i, 2).Value
Worksheets("Groupings").Cells(a, 3).Value = Worksheets("Data").Cells(i + 1, 2).Value
a = a + 1
End If
End If
Next
End Sub