Loop Copy based on Criteria then Transpose - excel

I have hit a brick wall with this. This code works in stages, probably not very efficiently.
Step 1 looks at the data on sheet1 if row13 contains a yes then it copies that columns row17,20,21 to sheet2 this part I have got to work fine through a loop.
Step 2 selects the data on sheet2 looking at the last column and row and then should transpose it to sheet3. This part doesn't work at all. If i could skip the sheet3 and transpose direct onto sheet2 with the loop that would be even better.
Here is a screen shot of sheet1 the blanks do have data in the final sheet but are not applicable for this so have been removed.
Here is a screen shot of sheet2 this is currently how it appears after the loop.
This is how i imagine it looks when it is transposed sheet3
Here is my code so far: -
Sub Collect()
ThisWorkbook.Worksheets("Sheet2").Range("B1:U9999").ClearContents
Dim i As Integer
For i = 2 To 21
If Cells(13, i) = "Yes" Then
ThisWorkbook.Worksheets("Sheet1").Select
ThisWorkbook.Worksheets("Sheet1").Cells(17, i).Copy 'Name
ThisWorkbook.Worksheets("Sheet2").Select
ThisWorkbook.Worksheets("Sheet2").Cells(1, Columns.Count).End(xlToLeft).Offset(0, 1).PasteSpecial 'Paste Name
ThisWorkbook.Worksheets("Sheet1").Select
ThisWorkbook.Worksheets("Sheet1").Cells(20, i).Copy 'Lines
ThisWorkbook.Worksheets("Sheet2").Select
ThisWorkbook.Worksheets("Sheet2").Cells(2, Columns.Count).End(xlToLeft).Offset(0, 1).PasteSpecial 'Paste Name
ThisWorkbook.Worksheets("Sheet1").Select
ThisWorkbook.Worksheets("Sheet1").Cells(21, i).Copy 'Quantity
ThisWorkbook.Worksheets("Sheet2").Select
ThisWorkbook.Worksheets("Sheet2").Cells(3, Columns.Count).End(xlToLeft).Offset(0, 1).PasteSpecial 'Paste Quantity
ThisWorkbook.Worksheets("Sheet1").Select
End If
Next i
ThisWorkbook.Worksheets("Sheet3").Range("A1:U9999").ClearContents
ThisWorkbook.Worksheets("Sheet2").Select
Dim lRow As Long, lCol As Long
lRow = Worksheets("Sheet2").Range("A" & Rows.Count).End(xlUp).Row
lCol = Worksheets("Sheet2").Cells(1, Columns.Count).End(xlToLeft).Column
Worksheets("Sheet2").Range(Cells(lRow, 1), Cells(lRow, lCol)).Select 'it errors here
Selection.Copy
ThisWorkbook.Worksheets("Sheet3").Range("A1").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
End Sub
I have highlighted where it has an error.
I have tried recording a macro to get the transpose part, which gave this result: -
Sub Transpose()
'
' Transpose Macro
Range("A1:F3").Select
Selection.Copy
Sheets("Sheet3").Select
Range("A1").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
End Sub
So i would like help getting the selection on sheet2 which can vary to copy and transpose. If anyone has any suggestions on how to make it slicker would also be appreciate.
If you can explain what you do, this will help me learn, thank you!
Any help would be greatly appreciated.

Read this on how to avoid Select, which makes your code more efficient and tidier.
The immediate cause of your error was not fully qualifying ranges by adding worksheet references.
This should work.
Sub x()
Dim c As Long
With Worksheets("Sheet1")
For c = 1 To .Cells(13, Columns.Count).End(xlToLeft).Column
If .Cells(13, c).Value = "Yes" Then
Union(.Cells(17, c), .Cells(20, c), .Cells(21, c)).Copy
Sheet2.Range("A" & Rows.Count).End(xlUp)(2).PasteSpecial Transpose:=True
End If
Next c
End With
End Sub

Try,
Sub test()
Dim vDB, vResult()
Dim Ws As Worksheet, toWs As Worksheet
Dim j As Integer, n As Integer, c As Integer
Set Ws = Sheets(1)
Set toWs = Sheets(2)
With Ws
c = .Cells(13, Columns.Count).End(xlToLeft).Column
vDB = .Range("b13", .Cells(21, c))
End With
For j = 1 To UBound(vDB, 2)
If vDB(1, j) = "Yes" Then
n = n + 1
ReDim Preserve vResult(1 To 3, 1 To n)
vResult(1, n) = vDB(5, j)
vResult(2, n) = vDB(8, j)
vResult(3, n) = vDB(9, j)
End If
Next j
With toWs
.Range("a1").CurrentRegion.Clear
.Range("a1").Resize(1, 3) = Array("Name", "Lines", "Quantity")
If n Then
.Range("a2").Resize(n, 3) = WorksheetFunction.Transpose(vResult)
End If
End With
End Sub

Related

vba code to find a predetermined range, copy and transpose

I'm working on a excel document with multiple seperate data, all in a single column (A1 to A10160).
All the data begins in a cell with the text NC/xx/xxxx/x (x being variable) and ending in a cell containing different dates but the cell above it always has the text "Start Date". Some data covers 49 cells others cover 51 cells so it's not contained in a fixed number of cells in the column.
I need to copy the range from NC/xx/xxxx/x to Start Date plus one for each data "set", transpose it and paste all the data in the column in a new sheet.
Really haven't found anything useful so far but I am fumbling with this one:
Sub Find()
Dim Search, End, Start, i As Integer, j As Integer, L
Search = Cells(1, 1)
End = Cells(2, 1)
For i = 1 To 10160
If Left(Cells(i, 1), 3) = Search Then
Start = i - 0
End If
Next i
For j = 1 To 10160
If Cells(j, 1) = End Then
L = j + 1
End If
Sheet4.Select
Range(Cells(Start, 1), Cells(L + 2, 1)).Select
Selection.Copy
Sheet4.Range("BB23").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=True
Application.CutCopyMode = False
End
Next j
End Sub
Would really appreciate any help I can get!
Thanks!
It looks like you haven't had much interest in your question, so I've taken a look at it. It's one of those fiddly jobs - not terribly technical but tricky to get the flow of logic right. The code below gives you what you've outlined in your question. You've said transpose it - so that's what the code does. Try it and let me know how you go.
Option Explicit
Sub Copy2Sheet2()
'Declare all your variables
Dim ws1 As Worksheet, ws2 As Worksheet
Dim topRow As Long, BottomRow As Long, LastRow As Long
Dim PasteToRow As Long, i As Long, c As Range
'Set the sheet variables
Set ws1 = Sheets(1)
Set ws2 = Sheets(2)
'Initial row settings
LastRow = ws1.Cells(Rows.Count, 1).End(xlUp).Row
PasteToRow = ws2.Cells(Rows.Count, 1).End(xlUp).Row + 1 '<~~ assumes headers on sheet2
'Start the loop
For i = 1 To LastRow
'Find the bottom row of the first block of data
Set c = ws1.Range("A" & i & ":A" & LastRow).Find(What:="Start Date", LookIn:=xlValues)
BottomRow = c.Row + 1
'Define and copy the range to sheet2
ws1.Range("A" & i & ":A" & BottomRow).Copy
ws2.Range("A" & PasteToRow).PasteSpecial Transpose:=True
Application.CutCopyMode = False
'Redefine the 'paste to' row
PasteToRow = ws2.Cells(Rows.Count, 1).End(xlUp).Row + 1
'Redefine the top row of the next block of data
i = BottomRow
'Repeat the process
Next i
End Sub

Pasting columns from other sheets as row on different sheet

I am trying to write a script that will take data from columns on two different sheets and paste them into a row on a third sheet without overwriting each other.
Private Sub CommandButton1_Click()
Dim InRangex1 As Range
Dim OutRangex1 As Range
Dim i As Long
Set InRangex1 = Sheets("Line 1").Range("L4:L204")
Set OutRangex1 = Sheets("Numeric Plot").Range("B1")
InRangex1.Worksheet.Activate
InRangex1.Select
Selection.Copy
OutRangex1.Worksheet.Activate
OutRangex1.Select
Selection.PasteSpecial Paste:=xlPasteValues, SkipBlanks:=True, Transpose:=True
Dim InRangex2 As Range
Dim OutRangex2 As Range
Set InRangex2 = Sheets("Line 3").Range("L4:L204")
Set OutRangex2 = Sheets("Numeric Plot").Range("B1").End(xlToRight).Offset(0, 1).Select
InRangex2.Worksheet.Activate
InRangex2.Select
Selection.Copy
OutRangex2.Worksheet.Activate
OutRangex2.Select
Selection.PasteSpecial Paste:=xlPasteValues, SkipBlanks:=True, Transpose:=True
End Sub
I am getting a 424 "Object required" error when the second half of the script runs. Not sure where the problem is.
Test this code, please. It it simpler, avoids Select, Activate, Copy and Paste and is very fast...
Private Sub CommandButton1_Click()
Dim arr1 As Variant, arr2 As Variant, OutRangex2 As Range
arr1 = Sheets("Line 1").Range("L4:L204").Value
Sheets("Numeric Plot").Range("B1").Resize(1, UBound(arr1, 1)).Value = WorksheetFunction.Transpose(arr1)
arr2 = Sheets("Line 3").Range("L4:L204").Value
Set OutRangex2 = Sheets("Numeric Plot").Range("B1").End(xlToRight).Offset(0, 1)
OutRangex2.Resize(1, UBound(arr2, 1)).Value = WorksheetFunction.Transpose(arr2)
End Sub
I think the duplicates removal should be consider like being object of a new question, according to our rules...
Please test the next code. It works also using arrays and should be very speedy. Please let me know how it works. It could be integrated in the first sub, but I made it from scratch...
Sub removeDuplicate()
Dim arrSort As Variant, lastCol As Long, lastRow As Long, arrSorted As Variant, sh As Worksheet
Set sh = Sheets("Numeric Plot")
lastCol = sh.Cells(1, sh.Cells.Columns.count).End(xlToLeft).column 'last col on the first row
arrSort = sh.Range(sh.Cells(1, 2), sh.Cells(1, lastCol)).Value 'put the row values in an array
'transpose the array in a column after the last one of the rows 1:
sh.Cells(1, lastCol + 1).Resize(UBound(arrSort, 2), 1).Value = WorksheetFunction.Transpose(arrSort)
'remove duplicates with Excel function:
sh.Range(sh.Cells(1, lastCol + 1), sh.Cells(UBound(arrSort, 2), lastCol + 1)).RemoveDuplicates Columns:=1, Header:=xlNo
lastRow = sh.Cells(sh.Cells.Rows.count, lastCol + 1).End(xlUp).row 'Last row after dupplicate elimination
arrSorted = sh.Range(sh.Cells(1, lastCol + 1), sh.Cells(lastRow, lastCol + 1)).Value 'The cleared column pun in an array
sh.Range(sh.Cells(1, 2), sh.Cells(1, lastCol)).Clear 'clearing the data of the first row
sh.Range(sh.Cells(1, lastCol + 1), sh.Cells(lastRow, lastCol + 1)).Clear 'clearing the data of temporary column
Dim finalRng As Range
Set finalRng = sh.Range("B1").Resize(1, UBound(arrSorted))
finalRng.Value = WorksheetFunction.Transpose(arrSorted) 'transpose the fiterred array
'sort the resulted range:
finalRng.Sort Key1:=finalRng, Order1:=xlAscending, Orientation:=xlLeftToRight
End Sub

Why is my VBA code not iterating to the next i?

Trying to populate a sheet with only instances that meet a criteria. Here the criteria is a 1 in the last column of the dataset.
Current code is only pulling the first iteration. Does not go to next i. Next i in the current dataset is an instance that should be pulled so that is not the issue.
Sub Cleaned()
Dim LastRow As Integer, c As Long, i As Integer, erow As Integer
Worksheets("SPData").Activate
LastRow = ActiveSheet.Range("A" & Rows.Count).End(xlUp).Row
c = ActiveSheet.Cells(1, Columns.Count).End(xlToLeft).Column
For i = 1 To 600
If Cells(i, c) = 1 Then
Range(Cells(i, 1), Cells(i, c)).Select
Selection.Copy
Worksheets("CleanedData").Select
erow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Offset(1, 1).Row
ActiveSheet.Cells(erow, 1).Select
ActiveSheet.Paste
Application.CutCopyMode = False
End If
Next i
End Sub
Also tried:
Sub Moving()
Dim r As Long, c As Long, i As Integer, erow As Integer
Worksheets("SPData").Activate
r = ActiveSheet.Cells(Rows.Count, 2).End(xlUp).Row
c = ActiveSheet.Cells(1, Columns.Count).End(xlToLeft).Column
For i = 2 To r
If Cells(i, c) = 1 Then
Range(Cells(i, 1), Cells(i, c)).Select
Selection.Copy
Worksheets("CleanedData").Select
erow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Offset(1, 1).Row
ActiveSheet.Cells(erow, 1).Select
ActiveSheet.Paste
End If
Next i
End Sub
Correct me if I am wrong - you want to copy the entire row if the value in the last column is equal to 1?
If so then this code works:
Sub Moving()
Dim r As Long
Dim c As Long
Dim i As Integer
Dim erow As Integer
With Worksheets("SPData")
r = .Cells(.Rows.Count, 2).End(xlUp).Row
c = .Cells(1, .Columns.Count).End(xlToLeft).Column
For i = 2 To r
If .Cells(i, c) = 1 Then
.Range(.Cells(i, 1), .Cells(i, c)).Copy
With Worksheets("CleanedData")
erow = .Cells(.Rows.Count, 1).End(xlUp).Offset(1, 0).Row
.Paste Destination:=.Cells(erow, 1)
End With
End If
Next i
End With
End Sub
I would strongly advise you to avoid using .Select in VBA whenever you can.
Also it is usually much better to refer to the actual sheet rather than using ActiveSheet.

copy and paste as values to another sheet, excel macro

I'm new with Macro and I want to create a simple copy and paste excel formula from one sheet to another. But the thing is the main data has a formula inside the cell and it wont let me copy and paste as values it to another cell.
Sub selectpasting()
Dim Lastrow As Long, erow As Long
Lastrow = Sheets("attendance").Cells(Rows.Count, 1).End(xlUp).Row
For i = 3 To Lastrow
If Sheets("attendance").Cells(i, 3) = "absent" Then
Sheets("attendance").Cells(i, 1).copy
erow = Sheets("forpasting").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
Sheets("attendance").Paste Destination:=Sheets("forpasting").Cells(erow, 1)
Sheets("attendance").Cells(i, 3).copy
Sheets("attendance").Paste Destination:=Sheets("forpasting").Cells(erow, 2)
End If
Next i
Application.CutCopyMode = False
Sheets("forpasting").Columns.AutoFit
Range("A1").Select
End Sub
Change this row:
Sheets("attendance").Paste Destination:=Sheets("forpasting").Cells(erow, 1)
To:
Sheets("forpasting").Cells(erow, 1).PasteSpecial xlValues
The complete code would be:
Sub selectpasting()
Dim Lastrow As Long, erow As Long
Dim i As Long
Lastrow = Sheets("attendance").Cells(Rows.Count, 1).End(xlUp).Row
For i = 3 To Lastrow
If Sheets("attendance").Cells(i, 3) = "absent" Then
Sheets("attendance").Cells(i, 1).Copy
erow = Sheets("forpasting").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
Sheets("forpasting").Cells(erow, 1).PasteSpecial xlValues
Sheets("attendance").Cells(i, 3).Copy
Sheets("forpasting").Cells(erow, 2).PasteSpecial xlValues
End If
Next i
Application.CutCopyMode = False
Sheets("forpasting").Columns.AutoFit
Range("A1").Select
End Sub
The code above is quite slow (try both the codes and you would notice that the below is way faster).. The reason is that in the above excel needs to determine/evaluate if the the cell properties needs to be pasted or not due to ".copy". It's one approach when you need to copy/paste cell formats etc.
In your case you only interested in the value the cells shows. So you could just pick the value and copy it.
I would therefore recommend you to change it to:
Sub selectpasting_2()
Dim Lastrow As Long, erow As Long
Dim i As Long
Lastrow = Sheets("attendance").Cells(Rows.Count, 1).End(xlUp).Row
For i = 3 To Lastrow
If Sheets("attendance").Cells(i, 3) = "absent" Then
erow = Sheets("forpasting").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
Sheets("forpasting").Cells(erow, 1) = Sheets("attendance").Cells(i, 1)
Sheets("forpasting").Cells(erow, 2) = Sheets("attendance").Cells(i, 3)
End If
Next i
Application.CutCopyMode = False
Sheets("forpasting").Columns.AutoFit
Range("A1").Select
End Sub

to open workbook from an array

this is my code where users can select multiple files and then they are compared with headers in master file and then data is copy pasted. the problem is that i do not know how to reference the workbooks from the array to run the code, one workbook at a time. previously for a single workbook i used the activate statement but i do not know how to do it for multiple workbooks in the array. the book names are stored in arrNames. Temp calc is the sheet where all the data has to be stored. any suggestions ?
thanks,
Mathew
Sub Test()
Dim lastCol, lastRow As Long, k As Long, a As Variant, b As Variant, cmpRng As Range
Dim mastCol As Long, mastRng As Range, n As Long
Dim Wbk As Workbook
Dim fileone
Dim SelectedFiles As Object
Dim arrNames As Variant
Dim indx As Long
Application.ScreenUpdating = False
Sheets("Temp Calc").Select
'Clear existing sheet data except headers
Rows(1).Offset(1, 0).Resize(Rows.Count - 1).ClearContents
arrNames = Application.GetOpenFilename(Filefilter:="Workbooks (*.xlsx),*.xlsx", MultiSelect:=True)
For i = 1 To UBound(arrNames, 1)
Worksheets("Temp Calc").Select
lastCol = Worksheets("Temp Calc").Cells(1, Columns.Count).End(xlToLeft).Column
lastRow = Worksheets("Temp Calc").Cells(Rows.Count, 1).End(xlDown).Row
Set cmpRng = Range(Cells(1, 1), Cells(1, lastCol))
a = cmpRng
mastCol = Cells(1, Columns.Count).End(xlToLeft).Column
Set mastRng = Range(Cells(1, 1), Cells(1, mastCol))
b = mastRng
For k = 1 To lastCol
For n = 1 To mastCol
If UCase(a(1, k)) = UCase(b(1, n)) Then
Here i need the code to open workbook in array
Worksheets("Sheet1").Range(Cells(2, n), Cells(lastRow, n)).Copy
Windows("Dashboard_for_Roshan.xlsm").Activate
Worksheets("Temp Calc").Select
Cells(2, k).PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=False
Exit For
End If
Next
Next
Next
'Else
'End If
Application.ScreenUpdating = True
Exit Sub
'Next
End Sub
you could try
sPath="C:\"
workbooks(sPath & arrNames(i)).open
where i is your loop counter through the array returned by GetOpenFileName and arrNames is your array

Resources