Copy every 4 column and paste in another sheet Microsoft excel - vba

I am new to VBA. Actually, my objective is to copy every 4 columns with 5 rows one after one to a new worksheet named USD.
Below is my code but it is not working in a loop.
Sub CopyColumns()
Range("A5:D9").Select '**I want to add 4 columns till the end of last column with data**
Selection.Copy
Sheets("Test").Select
Sheets.Add.Name = "USD"
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("Test").Select
**'Sceond loop should be like below**
Range("E5:H9").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("USD").Select
Range("A6").Select '**I need to paste data after last row used every time**
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End Sub

you need a loop and a way to move your selection. For loop look up While because you dont know exactly how many times you want to repeat the code and for variables you can use Offset or directly put them into Cells to specify the selection.
Sub CopyColumns()
Dim iCycle As Long
iCycle = 0
Sheets.Add.Name = "USD"
Sheets("Test").Select
While Range("A5").Offset(0, iCycle * 4).Value <> "" 'checks if there are any values left to be copied
Range("A5:D9").Offset(0, iCycle * 4).Copy 'Offset moves whole selection by 4 columns to the right every time
Sheets("USD").Select
Sheets("USD").Range(Cells(1 + iCycle * 5, 1), Cells(1 + iCycle * 5, 4)).PasteSpecial Paste:=xlPasteValues 'Cells can also be used to specify selection based on variable
Sheets("Test").Select
iCycle = iCycle + 1
Wend
End Sub

Related

Excel Macro- How to delete cell values after a row number?

Columns A to K have entries till a specific number which may vary. Columns L to Q have entries till 1,50,000. I want to delete all entries after the last entry in Column A (this number is variable)
The code that I got after recording macro is given below.
The issue with the code is that it is hardcoding
Application.Goto Reference:="R70086C1"
Sub ExtraDelete()
' ExtraDelete Macro
Range("AN1").Select
ActiveCell.FormulaR1C1 = "=COUNTIF(C[-39], ""*"")"
Range("AN1").Select
Selection.Copy
Range("AN3").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
Selection.ClearContents
Range("AN1").Select
Selection.Copy
Application.Goto Reference:="R70086C1"
Rows("70087:70087").Select
Range(Selection, Selection.End(xlDown)).Select
Application.CutCopyMode = False
Selection.ClearContents
Range("A70082").Select
ActiveWorkbook.Save
End Sub
I want to delete all entries after the last entry in Column A.
Typically, you would start at the bottom on column A and look up to find the last populated cell. It's like starting at A1048576 and tapping ctrl+<up arrow>.
Range.Select is almost never needed and rarely the best method. (read this)
Sub ExtraDelete()
' ExtraDelete Macro
with worksheets("sheet1")
.range(.cells(.rows.count, "A").end(xlup).offset(1, 0), _
.cells(.rows.count, "A")).entirerow.clear
.parent.Save
end with
End Sub

do while loop in VBA

I have data that looks like the table shown below. The number of observations in this dataset varies each month. The columns remain the same. I would like to loop my code through each row until the row is empty. I think a do while loop would be appropriate, but I have not been successful in executing it thus far (of note, I am a complete VBA newbie.)
A couple of other notes: The only thing that will change as the code runs through each observation of data is the Range selected in line 2 (I will want to move down to the next row of observations) and the final range selected for the Paste Special step in the final line of the code (again, I will want to move down to the next row of observations with each iteration).
Sample Data:
Sex Age Race Total Cholesterol HDL-Cholesterol Systolic Blood Pressure Treatment for High Blood Pressure Diabetes Smoker
F 50 AA 300 90 200 Y Y Y
M 55 AA 290 90 200 Y Y Y
F 50 AA 300 90 200 N N N
Code that I need to loop through each non-empty row:
Sub ASCVD()
Sheets("Sheet1").Select
Range("A2:I2").Select
Selection.Copy
Sheets("Omnibus").Select
Range("C3").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Range("B13").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Sheet1").Select
Range("J2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End Sub
Thank you very much in advance for your help!!!
On second thought, what you are really asking is how to use a Do While loop:
Sub ASCVD()
Dim row As Integer
row = 2
Do While ThisWorkbook.Sheets("Sheet1").Cells(row, 1) <> "" 'Loop until first cell is empty
ThisWorkbook.Sheets("Sheet1").Range("A" & row & ":I" & row).Select
Selection.Copy
Sheets("Omnibus").Select
Range("C3").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Range("B13").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Sheet1").Select
Range("J" & row).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
row = row + 1
Loop
End Sub
The code loops throw rows 2, 3, 4, 5 .... and stops when it finds a row where the first cell is empty
Create an example of your desired end result, it is extremely unclear what you want to achieve at the moment. (Right now you are only describing a mess of implementation, not what the big picture is)
Anyway I am assuming all you want to do is transpose your data, this code does the job:
Sub ASCVD()
Dim Data() As Variant
Dim nrow As Integer
Data() = ThisWorkbook.Sheets("Sheet1").Range("A1").CurrentRegion.Value
nrow = UBound(Data(), 1)
ThisWorkbook.Sheets("Omnibus").Activate
DoEvents
'Previous two lines needed so that the .Range(Cells(3.3), ... part works below
ThisWorkbook.Sheets("Omnibus").Range(Cells(3, 3), Cells(16 + 2, nrow + 2)) = Application.WorksheetFunction.Transpose(Data())
'Cells(rownumber, columnnumber). Cells(1,1) is cell A1
'Cells(3, 3) is same as cell C3.
'Cells(16 + 2, nrow + 2) in your example case will be cell F18, the last cell of your data.
'+2 because you want to start from C3, meaning all your data is shifted two cells down and two cells right
End Sub

Code Cleanup for Combining Sheets

I do not have much experience with VBA but I will start by explaining my situation.
I have a workbook with 341 sheets. Each sheet is identical in layout in that they occupy the space A1:J48. I need to combine all of these into one sheet called "COMBINATION". The information of relevance is from A10:J48. I also need to have the cells from A1:J9 as they are the title which is shared across all the sheets.
What I did was write a code that copies A1:J48 for Sheet1 (to get the title and info) and pastes it into "COMBINATION" with the paste special as text, then a code that goes to Sheet2 and copies from A10:J48 and pastes it in the first empty cell in column A of "COMBINATION".
This brings me to my problem. I have realized that there must be an easier way of doing this instead of copying the code 339 more times for each of the sheets.
See below the code. It does what I want correctly but as mentioned, I would like to find a way to not do this 339 more times...
Sheets("Sheet1").Select
Range("A1:J48").Select
Selection.Copy
Sheets("COMBINATION").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Selection.Columns.AutoFit
Sheets("Sheet2").Select
Range("A10:J10").Select
Range("J10").Activate
Range(Selection, Selection.End(xlDown)).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("COMBINATION").Select
NextFree = Range("A10:A" & Rows.Count).Cells.SpecialCells(xlCellTypeBlanks).Row
Range("A" & NextFree).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
I would use code like the following:
Dim ws As Worksheet
Dim r As Long
'Copy A1:J9 from the first sheet
Worksheets("Sheet1").Range("A1:J9").Copy
WorkSheets("COMBINATION").Range("A1").PasteSpecial Paste:=xlPasteValues, _
Operation:=xlNone, _
SkipBlanks:=False, _
Transpose:=False
'Now loop through every sheet (except "COMBINATION") copying cells A10:J48
r = 10 ' first sheet will be copied to row 10 in COMBINATION
For Each ws In Worksheets
If ws.Name <> "COMBINATION" Then
ws.Range("A10:J48").Copy
Worksheets("COMBINATION").Range("A" & r).PasteSpecial Paste:=xlPasteValues, _
Operation:=xlNone, _
SkipBlanks:=False, _
Transpose:=False
'Set pointer ready for next sheet
r = r + 39
End If
Next
'Set column widths
Worksheets("COMBINATION").Columns.AutoFit
If your sheets don't always have data in all 39 rows (10 to 48), replace r = r + 39 with
r = Worksheets("COMBINATION").Range("A" & Worksheets("COMBINATION").Rows.Count).End(xlUp).Row + 1
Put the repeating code into a loop (untested):
Dim i as Integer
For i=2 to 341
Sheets(i).Select
Range("A10:J10").Select
Range("J10").Activate
Range(Selection, Selection.End(xlDown)).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("COMBINATION").Select
NextFree = Range("A10:A" & Rows.Count).Cells.SpecialCells(xlCellTypeBlanks).Row
Range("A" & NextFree).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Next i
Range.PasteSpecial xlPasteValues is convenient but slow. It is much faster to define your 'Target' range to be the same size as your source range and do a direct assignment.
Sub CombineData()
Application.ScreenUpdating = False
Dim ws As Worksheet
Dim Target As Range
With Worksheets("COMBINATION")
.Range("A1:J9").Value = Worksheets("Sheet1").Range("A1:J49").Value
For Each ws In Worksheets
If ws.Name <> .Name Then
Set Target = .Range("A" & .Rows.Count).End(xlUp).Offset(1)
Target.Resize(39, 10).Value = ws.Range("A10:J48").Value
End If
Next
End With
Application.ScreenUpdating = True
End Sub

VBA transpose multiple times

I am currently working on a big set of data downloaded from Morningstar Direct. I need help with a macro that can change the exported document from horizontal to vertical. I have tried all the functions in excel without any luck, so i think i need a macro for this operation.
For example:
From:
Data1-2000 Data1-2001 Data1-2002 ... Data1-2016 Data2-2000 Data2-2001 and so on
To:
Data1-2000
Data1-2001
...
Data1-2016
Data2-2000
Data2-2001
...
Every datavariable goes from 2000 to 2016. We have more then 500 tickers that need the same transformation. Is there any VBA code that can do this for me? It will save my life (at least my Easter)!
**Addedum from OP's answer post:
I have made this macro:
Sub Flip()
'
' Flip Macro
'
Sheets("S&P 500 Constituents").Select
Range("I2:X2").Select
Selection.Copy
Sheets("Sheet1").Select
Range("D2").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Sheets("S&P 500 Constituents").Select
Range("AB2:AQ2").Select
Selection.Copy
Sheets("Sheet1").Select
Range("E2").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Sheets("S&P 500 Constituents").Select
Range("AR2:BG2").Select
Selection.Copy
Sheets("Sheet1").Select
Range("F2").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Sheets("S&P 500 Constituents").Select
Range("BH2:BW2").Select
Selection.Copy
Sheets("Sheet1").Select
Range("G2").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Sheets("S&P 500 Constituents").Select
Range("BX2:CM2").Select
Selection.Copy
Sheets("Sheet1").Select
Range("H2").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
End Sub
As you can see everything is taken from row 2 in my S&P500 sheet, and then transposed into sheet1.
How can i make this macro repeat the same operation on row 3, 4, 5 ... 518?
Try the INDEX function.
=INDEX($1:$1, 1, ROW(1:1))
  
Addendum: VBA strip & transpose
Dumping the values from the S&P 500 Constituents worksheet into a two-dimensioned variant array and processing the reorientation in-memory to a second array would be the most expedient method.
Sub Flip()
' Flip Macro
Dim v As Long, val As Variant, vals As Variant
Dim a As Long, b As Long, stp As Long
stp = 16
ReDim val(1 To stp, 1 To 1)
With Worksheets("S&P 500 Constituents")
With .Range(.Cells(2, "I"), .Cells(Rows.Count, "CM").End(xlUp))
vals = .Value2
End With
End With
With Worksheets("Sheet1")
For a = LBound(vals, 1) To UBound(vals, 1)
For b = LBound(vals, 2) To UBound(vals, 2) - stp Step stp
For v = 1 To stp
val(v, 1) = vals(a, b - ((b > 1) * 3) + (v - 1))
Next v
.Cells(2, "D").Offset((a - 1) * stp, Int(b / stp)).Resize(stp, 1) = val
Next b
Next a
End With
End Sub
I've intentionally avoided the use of the native TRANSPOSE function as it has limitations for size that are more suited to an .xls than an .xlsx. The maths that supply the looped reorientation have been derived from your sample code's first row.

VBA to Copy and Past into next blank cell within a set range

I have the below vba code created to copy and paste data. The report I'm creating captures historical data to be updated every hour. I need to be able to paste into the next available cell below B10 but cannot figure out how to do that, any suggestions? Thanks!
Range("A7").Select
Selection.Copy
Range("B10").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
The code assumes that you want the value in cell "A7" to be sent to the first available(blank) cell below B10:
Sub Next_Available()
Dim nextAvailableCell As Long
nextAvailableCell = Application.WorksheetFunction.Max(Cells(Rows.Count, "B").End(xlUp).row + 1, 11)
Range("B" & nextAvailableCell) = Range("A7")
End Sub