Copy column from one sheet to another using VBA (with loop) - excel

I am trying to copy columns from Sheet 1 and paste them in Sheet 2, particularly in the next empty column on sheet 2 (so that I don't overwrite data). In total, I need to copy columns 3-81.
Here is the code I have so far:
Dim col As Integer
For i = 3 To 81
Worksheets("Sheet1").Columns(i).Copy Destination:=Sheets("Sheet 2").Column(i).
Since I apply a function to every pasted column before copying and pasting the next one, I cannot simply denote the destination as column (i) because it will simply overwrite that last column of calculated data.
How can I change the destination so that I do not have this problem?
This question has been asked many times before however I cannot find my solution since I seem to be the only one using a loop and assigning col as i.

Dim i As Long, j As Long
j = 3
For i = 3 To 81
Worksheets("Sheet1").Columns(i).Copy _
Destination:=Sheets("Sheet 2").Columns(j)
j = j + 2
Next i

Related

Iterate a For Loop from bottom to top to delete rows

I have a range of cells where each cell contains a different value (Call this range1) and looks against a template file.
I copy all sheets of the template file (3 sheets), these first 2 steps work.
I need to loop from the bottom to top and look on all 3 sheets to delete all rows where the value in a column (Call this range2) <> the value in Range1.
I anticipate creating three loops, but the above premise is the same for all loops, just with different ranges. (I know a lastRow code could be used, but I'm not confident in having the last row be different for 3 sheets with varying row counts.)
Here is an example from the first loop I wrote, which runs Top -> bottom and ends up skipping every other line because it deletes the active row, cells shift up a row, then moves on to the next row.
BrNoRng = range1 described above.
Dim x As Integer
Dim BrNo As String
Dim BrNoRng As Range
Dim c As Range, rng
Set BranchRange = Range("B2:B35") 'this range is in separate file
Set BrNoRng = Range("B2") ' ^^ this range is in separate file
BrNo = BrNoRng.Value
'******Begin Loop 1***************
For x = 1 To 34 'Loop 1 is fine to run top -> bottom
'******Begin Loop 2****************** 'Loop 2 Needs to run Bottom -> Top
Sheets1.Activate 'Not actual name of the sheet, used as a placeholder sheet name,
'this is where the rows need to delete
Set rng = Range("C3:C2500")
For Each c In rng.Rows
If c.Value <> BrNoRng.Value Then
c.Value.EntireRow.Delete
End If
Next c
'*****End loop 2**********
Next x
'*****End Loop 1*************

Delete specific rows in Excel sheet

I have a table with multiple columns. I would like to delete specific rows within the table. The logic to delete is the following:
If in column B one cell contains a specific value, let's stick to "example" for this case, I would like to delete the following two rows after the row(s) which matched the criteria.
It is important to note that the criteria might appear several times within the table and that the table might have different lengths.
My idea was the following:
1. Identify all rows which contain "example" in column B
2. Store the row numbers in a variable
3. Go through the variable and create a new one which has twice the length of the first one and write the two following rows into the 2nd variable
4. Use the 2nd variable to delete the rows with that numbers.
Unfortunately, I am totally new to VBA and was not able to code it. I also tried to copy code together but I couldn't find a solution for my specific topic.
This is a very slight mod to your approach
starting from the bottom of column B, work upwards.
if we encounter "example", delete the two rows below
So if row#7 contains "example", delete row#7 and row#8
Before:
The code:
Sub RowKiller()
Dim N As Long, i As Long, t As String
t = "example"
N = Cells(Rows.Count, "B").End(xlUp).Row
For i = N To 1 Step -1
If Cells(i, "B") = t Then
Range(Cells(i + 1, "B"), Cells(i + 2, "B")).EntireRow.Delete
End If
Next i
End Sub
and after:
I think, instead, the best way to handle this is:
Loop through all of the populated rows from the last to the first. (this insures we don't pull the rug out from under us when deleting rows).
If "Example" is found in column B of that row, delete the two rows after it (we've already traversed those rows so deleting shouldn't be any big deal
Thats it.
Sub deleteRows()
Dim lastRow as Long
'get the last row
lastRow = Sheet1.Range("B" & Sheet1.Rows.Count).End(xlUp).Row
'Now work backwards
Dim i As Long
For i = lastRow to 1 Step -1 'change that 1 to whatever your first row is
If Sheet1.Cells(i, 2).value = "Example" Then
Sheet1.Rows(i + 1 & ":" & i + 2).Delete
End If
Next i
End Sub
I haven't tested that, but it looks right. You may have to tweak some things in there, but it will definitely get you in the ballpark.

Copy and remove lines in Excel depending on cell value

I have two sheets:
Sheet1 contains many rows with a lot of data in them. Each row has a unique number in column A.
All these data from the rows in sheet1 is copied to sheet2 with a simple =sheet1!$A$1 ect.
Sometimes/a lot of times I need more than one copy of the row (exact copy) in sheet2 and at the moment I am manually inserting a new line in sheet2 and I am copying the above row to the newly created row.
Now, it would be very nice and very time saving for me, if I in sheet1 could insert a new column, in which I could define how many copies that would have to be created in sheet2. It would also be nice, if I could change the number of copies afterwards (in sheet1), if I by mistake had punched in the wrong number there, and then excel automaticly would delete the number of copies that where to much, starting by the last row created.
Any ideas on how this could be made?
Code I have tried:
Sub copy()
Set i = Sheets("Sheet1")
Set e = Sheets("Sheet2")
Dim d
Dim j
d = 1
j = 2
Do Until IsEmpty(i.Range("Q" & j))
If i.Range("Q" & j) = "TERM" Then
d = d + 1
e.Rows(d).Value = i.Rows(j).Value
End If
j = j + 1
Loop
End Sub
This wouldn't be very efficient, but the way you could do that would be to have TWO extra columns in Sheet1.
As you stated, column B would be the number of repetitions you'd want the value from column A to be.
You'd want column C to be a cumulative count. To do this, you'd have:
C1: =B1
C2: =C1+B2
Drag C2 down
Now, in sheet 2, you could put in the following formula AS AN ARRAY FORMULA
A1: =INDEX(Sheet1!A:A,MATCH(TRUE,Sheet1!C:C>=ROW(),0))
(To make it an array formula, once you type it in, finish with ctrl + shift + enter.)
Drag, Sheet 2, A1 down for a lot of rows and that will update as you change the values in column B of sheet 1 (the number of times to repeat the value in Column A)
Hope this does the trick!

Macro to insert blank cells below if value >1 and copy/paste values from cell above

This site already has something similar: Copy and insert rows based off of values in a column
but the code doesn't take me quite where I need to go, and I haven't been able to tweak it to make it work for me.
My user has a worksheet with 4 columns, A-D. Column A contains specific contract numbers, column B is blank, column C has part numbers, and column D has the entire range of contract numbers. My user wants to count the number of times the entire range contract numbers has duplicates so I entered the formula =countif($D$2:$D$100000,A2) in cell E2 and copied down, giving me the number of times the specific contract in column A appears in column D. The numbers range from 1 to 11 in this workbook but the number may be higher in other workbooks this method will be used in.
The next thing I need to do is to enter blank cells below all values in column E that are greater than 1, very much like the example in the previously asked question. I then also need to copy in the same row and insert copied cells exactly to match in the same row in column A. Example: Cell E21 has the number 5 so I need to shift cells in column E only so that there are 4 blanks cells directly below it. In column A, I need to copy cell A21 and insert copied cells in four rows directly below.
Just trying to get the blank cells to insert has been a trial, using the code as given in the previous question.
Dim sh As Worksheet
Dim lo As ListObject
Dim rColumn As Range
Dim i As Long
Dim rws As Long
Set sh = ActiveSheet
Set lo = sh.ListObjects("Count")
Set rColumn = lo.ListColumns("Count").DataBodyRange
vTable = rColumn.Value
For i = rColumn.Rows.Count To 1 Step -1
If rColumn.Cells(i, 1) > 1 Then
rws = rColumn.Cells(i, 1) - 1
With rColumn.Rows(i)
.Offset(1, 0).Resize(rws, 1).Cells.Insert
.EntireRow.Copy .Offset(1, 0).Resize(rws, 1).Cells
.Offset(1, 0).Resize(rws, 1).EntireRow.Font.Strikethrough = True
End With
End If
Next
I would be very grateful for any help as I have been fighting with this monster for a week.
While this is indeed possible to do, it might be a good idea to look into moving the list of all contract numbers from column D to a different sheet. Even though it is quite simple to loop through a range and insert rows based on cell values - it'll also create holes in columns D and E.
Here's code for simply adding the rows and copying the values as you specified.
Sub Main()
'---Variables---
Dim source As Worksheet
Dim startRow As Integer
Dim num As Integer
Dim val As String
Dim i As Long
'---Customize---
Set source = ThisWorkbook.Sheets(1) 'The sheet with the data
startRow = 2 'The first row containing data
'---Logic---
i = startRow 'i acts as a row counter
Do While i <= source.Range("E" & source.Rows.Count).End(xlUp).Row
'looping until we hit the last row with a value in column E
num = source.Range("E" & i).Value 'Get number of appearances
val = source.Range("A" & i).Value 'Get the value
If num > 1 Then 'Number of appearances > 1
Do While num > 1 'Create rows
source.Range("A" & i + 1).EntireRow.Insert 'Insert row
source.Range("A" & i + 1) = val 'Set value
num = num - 1
i = i + 1 'Next row
Loop
End If
i = i + 1 'Next row
Loop
End Sub
Of course you could also remove the holes from column D after inserting the new rows and modify the formula in column E so that it remains copyable and doesn't calculate for the copied rows.
Generally it makes things easier if a single row can be thought of as a single object, as creating or deleting a row only affects that one single object. Here we have one row represent both a specific contract and a contract in the all contracts list - this could end up causing trouble later on (or it could be totally fine!)

Extract data from single row and paste into new worksheet

I have some data in a worksheet in a single row (row 44) where the required data is in columns C,F,I,L and so on (i.e. data required every 3rd column starting from C).
This ends at column 'ET'
I need to extract this and paste it into another worksheet row where there are no column spaces.
I've looked around for solutions but its usually columns but this is data i need in one row.
Assuming this needs to be done even when the data in row 44 changes, you could do a macro. In a procedure, the following code could work as a guideline:
Public Sub copyover()
Dim c As Long
For c = 1 To 50
Worksheets("Sheet2").Cells(1, c).Value = _
Worksheets("Sheet1").Cells(44, c * 3).Value
Next
End Sub
Does this have to be a macro? Put this in the first destination cell on the other worksheet:
=INDEX(Sheet1!$C$44:$ET$44,1,3*(COLUMN(A1)-1)+1)
Then copy right

Resources