I have a worksheet with columns A:M and rows 1 to 5000. I would like to copy rows to another worksheet when a number greater then 0 is added to column L and M. I also only require columns A:F and K:M on the new worksheet
you'll need to name the source and target worksheets, but below code should do the trick.
Sub SheetTransfer()
Dim i As Long
Dim j As Long
Dim t As Double
Dim LastRow As Long
Dim ws1 As String
Dim ws2 As String
'name source worksheet here
ws1 = "Sheet1"
'name target worksheet here
ws2 = "Sheet2"
'set the threshold value for a row to be copied over
t = 0
' set to column L
j = 12
For i = 1 To 5000
If Worksheets(ws1).Cells(i, j).Value > 0 Or Cells(i, j + 1).Value > t Then
'find last row of target worksheet
With Worksheets(ws2)
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
End With
'copy/paste columns A-F
Worksheets(ws1).Range(Cells(i, 1), Cells(i, 6)).Copy
Worksheets(ws2).Cells(LastRow + 1, 1).PasteSpecial xlPasteValues
'copy paste columns K-M
Worksheets(ws1).Range(Cells(i, 11), Cells(i, 13)).Copy
Worksheets(ws2).Cells(LastRow + 1, 11).PasteSpecial xlPasteValues
End If
Next i
End Sub
Copy Data to Other Worksheet
Adjust the values in the constants section to fit your needs.
The Code
Sub AM5000()
' Source
Const cVntSource As Variant = "Sheet1" ' Source Worksheet Name/Index
Const cStrRange1 As String = "A1:F5000" ' Source 1 Range Address
Const cStrRange2 As String = "K1:M5000" ' Source 2 Range Address
Const cIntCol1 As Integer = 2 ' Source Range Criteria Column 1
Const cIntCol2 As Integer = 3 ' Source Range Criteria Column 2
' Target
Const cVntTarget As Variant = "Sheet2" ' Target Worksheet Name/Index
Const cStrTarget As String = "A1" ' Target First Cell Address
Dim vnt1 As Variant ' Source 1 Array
Dim vnt2 As Variant ' Source 2 Array
Dim vntTarget As Variant ' Target Array
Dim i As Integer ' Source Arrays Row Counter
Dim j As Integer ' Arrays Column Counter
Dim k As Integer ' Target Array Row Counter
' Paste Source Ranges into Source Arrays.
With Worksheets(cVntSource)
vnt1 = .Range(cStrRange1)
vnt2 = .Range(cStrRange2)
End With
' Count the number of rows for Target Array.
For i = 1 To UBound(vnt2)
If vnt2(i, cIntCol1) > 0 And vnt2(i, cIntCol2) > 0 Then
k = k + 1
End If
Next
' Write Source Arrays to Target Array.
ReDim vntTarget(1 To k, 1 To UBound(vnt1, 2) + UBound(vnt2, 2))
k = 0
For i = 1 To UBound(vnt2)
If vnt2(i, cIntCol1) > 0 And vnt2(i, cIntCol2) > 0 Then
k = k + 1
For j = 1 To UBound(vnt1, 2)
vntTarget(k, j) = vnt1(i, j)
Next
For j = 1 To UBound(vnt2, 2)
vntTarget(k, j + UBound(vnt1, 2)) = vnt2(i, j)
Next
End If
Next
' Paste Target Array into Target Range.
With Worksheets(cVntTarget).Range(cStrTarget)
'.Parent.Cells.ClearContents
.Resize(UBound(vntTarget), UBound(vntTarget, 2)) = vntTarget
End With
End Sub
Related
I need to copy every row 12 times from sheet1 to sheet 2.
Right now I copy the first row 12 times but row 2 is only copied once. I have provided a sample of the sheet and my code. Hope you guys can help.
My data starts in row a13
As a bonus I need to transpone the values in columns E:P
The reason why I need to do this is because all values in E:P is the value for each month and the values in A:C is the attributes that is necessary to identify the values in month to a certain car with year, registrations number and service
Sub copyEachRow()
Dim i As Integer
For i = 1 To 12
Sheets("asheet1").Range("A13").CurrentRegion.Copy Sheets("sheet2").Cells(i + 13, "a")
Next i
End Sub
Copy Transpose
Option Explicit
Sub copyEachRow()
Const srcName As String = "Sheet1"
Const sFirst As String = "A13"
Const dstName As String = "Sheet2"
Const dFirst As String = "A13"
Dim wb As Workbook
Set wb = ThisWorkbook
' Source Range to Source Array.
Dim Source As Variant
Source = wb.Worksheets(srcName).Range(sFirst).CurrentRegion.Value
Dim rCount As Long
rCount = UBound(Source, 1)
Dim Dest As Variant
ReDim Dest(1 To rCount * 12, 1 To 4)
' Write headers
Dim j As Long
For j = 1 To 3
Dest(1, j) = Source(1, j)
Next j
Dest(1, 4) = "Value"
' Write body.
Dim i As Long
Dim k As Long
Dim n As Long
For i = 2 To UBound(Source, 1)
For n = 1 To 12
k = k + 1
For j = 1 To 3
Dest(k, j) = Source(i, j)
Next j
Dest(k, 4) = Source(i, 3 + n)
Next n
Next i
' Destination Array to Destination Range.
With wb.Worksheets(dstName).Range(dFirst).Resize(, 4)
.Resize(.Worksheet.Rows.Count - .Row + 1).ClearContents
.Resize(k).Value = Dest
End With
End Sub
Sub copyEachRow()
Range("A1:C32").Select
Selection.Copy
Sheets("Sheet2").Select
Range("A1").Select
ActiveSheet.Paste
Dim I As Long
Dim xCount As Integer
xCount = 11
For I = Range("A" & Rows.CountLarge).End(xlUp).Row To 1 Step -1
Rows(I).Copy
Rows(I).Resize(xCount).Insert
Next
Application.CutCopyMode = False
End Sub
you can adapt this piece of code to your need:
Sub copyEachRow()
Dim cel As Range
With Sheet2
For Each cel In Sheet1.Range("A13", Sheet1.Cells(.Rows.Count, 1).End(xlUp))
cel.EntireRow.Copy .Cells(.Rows.Count, 1).End(xlUp).Offset(1).Resize(12)
Next
End With
End Sub
just place a header in Sheet2 column A cell after which you want to paste data from
My code blow, was made for only 3 years, (2016, 2017 & 2018). but now i have added 4 more years, but i dont know how to fit the description, so that i adds 4 more classes and four more on row Q Ark1. So that it fits with years 2016 to 2022. The code is added below, it transposes the information from Ark2 to Ark1.
I really hope you can help.
Sub TransposeAH()
Const cSheet1 As Variant = "Ark2" ' Sheet1 Name/Index
Const cSheet2 As Variant = "Ark1" ' Sheet2 Name/Index
Const cFirst As Integer = 23 ' First Row Number
Const cCol1First As Variant = "A" ' Range1 First Column Letter/Number
Const cCol1Last As Variant = "C" ' Range1 Last Column Letter/Number
Const cCol2First As Variant = "E" ' Range2 First Column Letter/Number
Const cCol2Last As Variant = "G" ' Range2 Last Column Letter/Number
Const cColumns As Integer = 1 ' Number of New Columns
Const cFirstCell As String = "N1" ' Target Range First Cell Address
Dim vntH As Variant ' Range2 Headers
Dim vnt2 As Variant ' Range2 Array
Dim vnt3 As Variant ' Range1 Temp Array (if value is "")
Dim vnt1 As Variant ' Range1 Array
Dim vntT As Variant ' Target Array
Dim LastUR As Long ' Last Used Row
Dim i As Long ' Arrays Row Counter
Dim j As Integer ' Arrays Column Counter
Dim k As Long ' Target Array Rows Counter
Dim m As Integer ' Range1 Temp Array Column Counter
' From Sheet1 to Arrays.
With Worksheets(cSheet1)
' Calculate Last Used Row.
With .Range(.Cells(cFirst, cCol1First), .Cells(.Rows.Count, cCol2Last))
If .Find("*", .Cells(.Rows.Count, .Columns.Count), -4123, , 1) _
Is Nothing Then Exit Sub
LastUR = .Find("*", , , , , 2).Row
End With
' Paste ranges into arrays.
vnt1 = .Range(.Cells(cFirst, cCol1First), .Cells(LastUR, cCol1Last))
vnt2 = .Range(.Cells(cFirst, cCol2First), .Cells(LastUR, cCol2Last))
vntH = .Range(.Cells(cFirst - 1, cCol2First), _
.Cells(cFirst - 1, cCol2Last))
End With
' Resize Target Array.
ReDim vntT(1 To UBound(vnt2) * UBound(vnt2, 2), _
1 To cColumns + UBound(vnt1, 2))
' Write Range2 Array to Target Array.
For i = 1 To UBound(vnt2)
For j = 1 To UBound(vnt2, 2)
k = k + 1
vntT(k, 1) = vntH(1, j)
vntT(k, 2) = vnt2(i, j)
Next
Next
' Resize Range1 Temp Array (if value is "")
ReDim vnt3(1 To 1, 1 To UBound(vnt1, 2))
' Copy first line of Range1 Array to Range1 Temp Array.
For m = 1 To UBound(vnt3, 2)
vnt3(1, m) = vnt1(1, m)
Next
' Write Range1 Array to Target Array.
k = 0
For i = 1 To UBound(vnt1)
For j = 1 To UBound(vnt1, 2)
k = k + 1
For m = 1 To UBound(vnt2, 2)
If vnt1(i, m) <> "" Then
If vnt1(i, m) <> vnt3(1, m) Then
vnt3(1, m) = vnt1(i, m)
End If
End If
vntT(k, m + cColumns) = vnt3(1, m)
Next
Next
Next
' Paste Target Array into Target Range resized
' from Target Range First Cell Address.
With Worksheets(cSheet2).Range(cFirstCell)
.Resize(UBound(vntT), UBound(vntT, 2)) = vntT
End With
End Sub
I have a list of words in column A of the 2nd sheet, and I need a script for excel that does the following:
Checks the first word of column A on 2nd sheet and then filters column B 1st sheet by cells that contain that word.
Deletes all the already filtered rows that don't contain that word also on column C.
And then it iterates with the next word from the column A 2nd sheet list until it went through all the words.
Example:
Column A 2nd sheet:
hav
Column B 1st sheet:
have
Column C 1st sheet:
must
In this case it would delete all the row because altough column B contains "hav", column C doesn't.
Your description is rather poor, but I gave it a shot. Try this code on "Sheet1". Replace "Sheet2" with the name of the second Sheet. This will look into each work on "Sheet2" and delete all rows on Sheet1 whose column B contains that word. Not sure what you mean by column C, but that condition should be easy to add.
Let me know.
Sub Test()
Dim LastRow As Long
Dim LastRowS2 As Long
Dim Word As String
LastRowS2 = ThisWorkbook.Sheets("Sheet2").Cells(1, 1).End(xlDown).Row
LastRow = Cells(1, 1).End(xlDown).Row
For i = 2 To LastRowS2
For j = 2 To LastRow
Word = Split(ThisWorkbook.Sheets("Sheet2").Cells(i, "A").Text, " ")(0)
If InStr(Cells(j, "B").Text, Word) > 0 Then
If InStr(Cells(j, "C").Text, Word) > 0 Then
'Do nothing
Else
Cells(j, "B").EntireRow.Delete
j = j - 1
End If
End If
Next j
Next i
End Sub
Delete Column By Criteria
Links
Workbook Download
The Code
Sub DeleteColumnCriteria()
' Worksheet 1
Const csheet1 As Variant = "Sheet1" ' Worksheet Name/Index
Const cFirstR1 As Long = 2 ' First Row
Const cCol1 As Variant = "B" ' Criteria Column 1
Const cCol2 As Variant = "C" ' Criteria COlumn 2
' Worksheet 2
Const cSheet2 As Variant = "Sheet2" ' Worksheet Name/Index
Const cFirstR2 As Long = 2 ' First Row
Const cCol As Variant = "A" ' Criteria Column
' Worksheet 1
Dim rngU As Range ' Union Range
Dim LastR1 As Long ' Last Row Number
Dim i As Long ' Row Counter
' Worksheet 2
Dim ws2 As Worksheet ' Worksheet 2
Dim LastR2 As Long ' Last Row Number
Dim j As Long ' Row Counter
Application.ScreenUpdating = False
' Calculate Last Row of Worksheet 2.
Set ws2 = ThisWorkbook.Worksheets(cSheet2)
LastR2 = ws2.Cells(ws2.Rows.Count, cCol).End(xlUp).Row
With ThisWorkbook.Worksheets(csheet1)
' Calculate Last Row of Worksheet 1.
LastR1 = .Cells(.Rows.Count, cCol1).End(xlUp).Row
' Accumulate ranges into Union Range.
For i = cFirstR2 To LastR2 ' Loop through rows in Worksheet 2.
For j = cFirstR1 To LastR1 ' Loop through rows in Worksheet 1.
' When value in cCol in Worksheet 2 is equal to cCol1 and
' not in cCol2 in Worksheet 1.
If ws2.Cells(i, cCol) <> "" Then
If ws2.Cells(i, cCol) = .Cells(j, cCol1) _
And ws2.Cells(i, cCol) <> .Cells(j, cCol2) Then
If Not rngU Is Nothing Then ' All other times.
Set rngU = Union(rngU, .Cells(j, 1))
Else ' First time only.
Set rngU = .Cells(j, 1)
End If
End If
End If
Next
Next
End With
' Delete rows in one go.
If Not rngU Is Nothing Then
rngU.EntireRow.Delete ' Hidden = True
End If
Application.ScreenUpdating = True
End Sub
In the picture of the sheet I get my data from "Ark2" and the sheet I get the data to "Ark1". In Ark1 I want want to give an ID for the data. I show an example in yellow, grey, green and blue colours. I want the text ID to stand as it does in the example row "K".
the code is added at the end..
Sub MyProcedure()
a = Worksheets("ark1").Cells(Rows.Count, 1).End(xlUp).Row
MsgBox (a)
End Sub
Private Sub CommandButton1_Click()
Dim nøgletal As String, år As Integer
Worksheets("Ark2").Select
nøgletal = Range("B2")
år = Range("C2")
Worksheets("Ark1").Select
Worksheets("Ark1").Range("A4").Select
ThisWorkbook.Worksheets("Ark1").Range("A1:A100").Value = ThisWorkbook.Worksheets("Ark2").Range("A12:A100").Value
ThisWorkbook.Worksheets("Ark1").Range("B1:B100").Value = ThisWorkbook.Worksheets("Ark2").Range("B12:B100").Value
ThisWorkbook.Worksheets("Ark1").Range("C1:C100").Value = ThisWorkbook.Worksheets("Ark2").Range("C12:C100").Value
ThisWorkbook.Worksheets("Ark1").Range("E1:E100").Value = ThisWorkbook.Worksheets("Ark2").Range("E12:E100").Value
ThisWorkbook.Worksheets("Ark1").Range("G1:G100").Value = ThisWorkbook.Worksheets("Ark2").Range("M12:M100").Value
ThisWorkbook.Worksheets("Ark1").Range("F1:F100").Value = ThisWorkbook.Worksheets("Ark2").Range("N12:N100").Value
ThisWorkbook.Worksheets("Ark1").Range("H1:H100").Value = ThisWorkbook.Worksheets("Ark2").Range("O12:O100").Value
If Worksheets("Ark1").Range("A4").Offset(1, 0) <> "" Then
Worksheets("Ark1").Range("A4").End(xlDown).Select
End If
ActiveCell.Offset(1, 0).Select
ActiveCell.Value = nøgletal
ActiveCell.Offset(0, 1).Select
ActiveCell.Value = år
Worksheets("Ark2").Select
Worksheets("Ark2").Range("B2", "B16").Select
End Sub
Sub x()
Dim lngDataColumns As Long
Dim lngDataRows As Long
lngDataColumns = 3
lngDataRows = 15
For t = 1 To lngDataRows
Range("l2").Offset(((t - 1) * lngDataColumns) - 1, 0).Resize(lngDataColumns, 1).Value = _
Application.Transpose(Range("f1:h1").Value)
Range("M2").Offset(((t - 1) * lngDataColumns) - 1, 0).Resize(lngDataColumns, 1).Value = _
Application.Transpose(Range("f1:h1").Offset(t).Value)
Next t
End Sub
A Special Transpose Vol. 2
Adjust the values in the constants section to fit your needs.
The first data row in Range1 (A2:C2) has to have values.
The Code
Sub TransposeAH()
Const cSheet1 As Variant = "Ark1" ' Sheet1 Name/Index
Const cSheet2 As Variant = "Ark1" ' Sheet2 Name/Index
Const cFirst As Integer = 2 ' First Row Number
Const cCol1First As Variant = "A" ' Range1 First Column Letter/Number
Const cCol1Last As Variant = "C" ' Range1 Last Column Letter/Number
Const cCol2First As Variant = "F" ' Range2 First Column Letter/Number
Const cCol2Last As Variant = "H" ' Range2 Last Column Letter/Number
Const cColumns As Integer = 2 ' Number of New Columns
Const cFirstCell As String = "L1" ' Target Range First Cell Address
Dim vntH As Variant ' Range2 Headers
Dim vnt2 As Variant ' Range2 Array
Dim vnt3 As Variant ' Range1 Temp Array (if value is "")
Dim vnt1 As Variant ' Range1 Array
Dim vntT As Variant ' Target Array
Dim LastUR As Long ' Last Used Row
Dim i As Long ' Arrays Row Counter
Dim j As Integer ' Arrays Column Counter
Dim k As Long ' Target Array Rows Counter
Dim m As Integer ' Range1 Temp Array Column Counter
' From Sheet1 to Arrays.
With Worksheets(cSheet1)
' Calculate Last Used Row.
With .Range(.Cells(cFirst, cCol1First), .Cells(.Rows.Count, cCol2Last))
If .Find("*", .Cells(.Rows.Count, .Columns.Count), -4123, , 1) _
Is Nothing Then Exit Sub
LastUR = .Find("*", , , , , 2).Row
End With
' Paste ranges into arrays.
vnt1 = .Range(.Cells(cFirst, cCol1First), .Cells(LastUR, cCol1Last))
vnt2 = .Range(.Cells(cFirst, cCol2First), .Cells(LastUR, cCol2Last))
vntH = .Range(.Cells(cFirst - 1, cCol2First), _
.Cells(cFirst - 1, cCol2Last))
End With
' Resize Target Array.
ReDim vntT(1 To UBound(vnt2) * UBound(vnt2, 2), _
1 To cColumns + UBound(vnt1, 2))
' Write Range2 Array to Target Array.
For i = 1 To UBound(vnt2)
For j = 1 To UBound(vnt2, 2)
k = k + 1
vntT(k, 1) = vntH(1, j)
vntT(k, 2) = vnt2(i, j)
Next
Next
' Resize Range1 Temp Array (if value is "")
ReDim vnt3(1 To 1, 1 To UBound(vnt1, 2))
' Copy first line of Range1 Array to Range1 Temp Array.
For m = 1 To UBound(vnt3, 2)
vnt3(1, m) = vnt1(1, m)
Next
' Write Range1 Array to Target Array.
k = 0
For i = 1 To UBound(vnt1)
For j = 1 To UBound(vnt1, 2)
k = k + 1
For m = 1 To UBound(vnt2, 2)
If vnt1(i, m) <> "" Then
If vnt1(i, m) <> vnt3(1, m) Then
vnt3(1, m) = vnt1(i, m)
End If
End If
vntT(k, m + cColumns) = vnt3(1, m)
Next
Next
Next
' Paste Target Array into Target Range resized
' from Target Range First Cell Address.
With Worksheets(cSheet2).Range(cFirstCell)
.Resize(UBound(vntT), UBound(vntT, 2)) = vntT
End With
End Sub
I currently have two if then VBA codes, that are running extremely slow for my large data set and am looking for ways to optimize and speed them up.
The first formula is looking in a range of cells in column J that have a value in column A, and if they are blank in J then entering in a formula that contains a user defined function.
The second code is looking to see if any of the values in column J end in a , and if they do then remove that comma. Any help would be greatly appreciated!
Sub FillEmpty()
Dim r As Range, LastRow As Long
LastRow = Cells(Rows.Count, 1).End(xlUp).row
For Each r In Range("J2:J" & LastRow)
If r.Text = "" Then r.FormulaR1C1 = _
"=IFERROR((IF(LEFT(RC[-9],6)=""master"", get_areas(RC[-7]), """")),"""")"
Next r
End Sub
Sub NoComma()
Dim c As Range
For Each c In Range("J:J")
With c
If Right(.Value, 1) = "," Then .Value = Left(.Value, Len(.Value) - 1)
End With
Next c
End Sub
Speedup: Arrays
1. Code
It is unbelievable that you do not need formulaR1C1 to get a formula into the range when pasting from the array into range. But it's working on my computer. To conclude, the same principle from the second code is applied on the first: Range into Array, Loop and Array into Range. It doesn't get faster than this. The other idea for the first code was to create a range union and then paste the formula in one go.
Sub FillEmpty()
Const cCol As Variant = "J" ' Column Letter/Number
Const cFirst As Long = 2 ' First Row
Dim vntFE As Variant ' Range Array
Dim i As Long ' Range Array Rows Counter
' Paste range into array.
vntFE = Cells(cFirst, cCol).Resize(Cells(Rows.Count, cCol) _
.End(xlUp).Row - cFirst + 1)
' Loop through array and perform calculation.
For i = 1 To UBound(vntFE)
If vntFE(i, 1) = "" Then vntFE(i, 1) = "=IFERROR((IF(LEFT(RC[-9],6)" _
& "=""master"", get_areas(RC[-7]), """")),"""")"
Next
' Paste array into range.
Cells(cFirst, cCol).Resize(Cells(Rows.Count, cCol) _
.End(xlUp).Row - cFirst + 1) = vntFE
End Sub
Sub FillEmptyEasy()
Const cCol As Variant = "J" ' Column Letter/Number
Const cFirst As Long = 2 ' First Row
Dim rng As Range ' Range
Dim vntFE As Variant ' Range Array
Dim LastRow As Long ' Last Row
Dim i As Long ' Range Array Rows Counter
' Calculate Last Row.
LastRow = Cells(Rows.Count, cCol).End(xlUp).Row
' Calculate Range.
Set rng = Cells(cFirst, cCol).Resize(LastRow - cFirst + 1)
' Paste range into array.
vntFE = rng
' Loop through array and perform calculation.
For i = 1 To UBound(vntFE)
If vntFE(i, 1) = "" Then vntFE(i, 1) = "=IFERROR((IF(LEFT(RC[-9],6)" _
& "=""master"", get_areas(RC[-7]), """")),"""")"
Next
' Paste array into range.
rng = vntFE
End Sub
2. Code
Sub NoComma()
Const cCol As Variant = "J" ' Column Letter/Number
Const cFirst As Long = 2 ' First Row
Dim vntNoC As Variant ' Range Array
Dim i As Long ' Range Array Rows Counter
' Paste range into array.
vntNoC = Cells(cFirst, cCol).Resize(Cells(Rows.Count, cCol) _
.End(xlUp).Row - cFirst + 1)
' Loop through array and perform calculation.
For i = 1 To UBound(vntNoC)
If Right(vntNoC(i, 1), 1) = "," Then _
vntNoC(i, 1) = Left(vntNoC(i, 1), Len(vntNoC(i, 1)) - 1)
Next
' Paste array into range.
Cells(cFirst, cCol).Resize(Cells(Rows.Count, cCol) _
.End(xlUp).Row - cFirst + 1) = vntNoC
End Sub
Sub NoCommaEasy()
Const cCol As Variant = "J" ' Column Letter/Number
Const cFirst As Long = 2 ' First Row
Dim rng As Range ' Range
Dim vntNoC As Variant ' Range Array
Dim lastrow As Long ' Last Row
Dim i As Long ' Range Array Rows Counter
' Calculate Last Row.
lastrow = Cells(Rows.Count, cCol).End(xlUp).Row
' Calculate Range.
Set rng = Cells(cFirst, cCol).Resize(lastrow - cFirst + 1)
' Paste range into array.
vntNoC = rng
' Loop through array and perform calculation.
For i = 1 To UBound(vntNoC)
If Right(vntNoC(i, 1), 1) = "," Then _
vntNoC(i, 1) = Left(vntNoC(i, 1), Len(vntNoC(i, 1)) - 1)
Next
' Paste array into range.
rng = vntNoC
End Sub