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.
Related
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
Hy i have a recorded macro, i am trying to use it using loop so that i can transpose multiple rows and columns in one click. The idea is that i have a number 10000 rows with columns 1000 in which emails are there.i want to use macro that transpose my rows data into columns using do while or loop. I have record the macro but it only work for one one row and column. The code is there.
Sheets("Mastersheet").Select
Range("J2:XFD2").Select
Selection.Copy
Sheets("Sheet2").Select
Range("A1").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
You can resolve your problem faster if you at least try and search for answers and information.
Excel VBA - Range.Copy transpose paste
Code:
Option Explicit
Sub test()
Dim master_sheet As Worksheet
Set master_sheet = ThisWorkbook.Sheets("Mastersheet")
Dim output_sheet As Worksheet
Set output_sheet = ThisWorkbook.Sheets.Add
Dim start_row As Long
start_row = 2
Dim last_row As Long
With master_sheet
last_row = .Cells(.Rows.Count, "J").End(xlUp).Row
.Range("J" & start_row & ":XFD" & last_row).Copy
End With
With output_sheet
.Range("A1").PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:=False, Transpose:=True
End With
End Sub
Try this:
Sub Macro9()
t = 2
Do Until t = 10000
Sheets("Mastersheet").Range("J" & t & ":XFD" & t).Copy
Sheets("Sheet2").Select
Sheets("Sheet2").Cells(1, t).Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
t = t + 1
Loop
End Sub
There are 10 Sheets (Sheet1...Sheet10) with tables in the same range (C25:G34 & C42:N51).
The rows have to be copied if the 'Total Weight' column has value > 0. The copied rows go to two summary tables:
To Westrock Table -> Westrock Summary Table
To DNP Table -> DNP Summary Table
Summary Table:
Westrock
Summary Table:
DNP
I'm on Mac, so PowerQuery is not an option. I'm new to VBA; this is what I have so far:
Sub ToDNP()
Application.ScreenUpdating = False
Worksheets("Jupiter").Activate
Range("C42:N51").Select
Selection.Copy
Worksheets("To DNP").Activate
Range("C11").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'Application.CutCopyMode = False
Worksheets("Windsor").Activate
Range("C42:N51").Select
Selection.Copy
Worksheets("To DNP").Activate
Range("C21").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Worksheets("Orlando").Activate
Range("C42:N51").Select
Selection.Copy
Worksheets("To DNP").Activate
Range("C31").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Worksheets("Woodland").Activate
Range("C42:N51").Select
Selection.Copy
Worksheets("To DNP").Activate
Range("C41").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Dim rRow As Integer, rCol As Integer
Dim cRow As Integer, cCol As Integer
rCol = 3
rRow = 11
cCol = 14
cRow = 11
For cRow = 11 To 50
If Cells(cCol, cRow).Value = "0" Then
Range(Cells(rCol, rRow), Cells(cCol, cRow)).ClearContents
End If
rRow = rRow + 1
Next cRow
End Sub
This is giving me an error:
Error: Cannot change part of a merged Cell
You're getting the error because you have the row and column values swapped around. The row parameter comes first and then comes the column parameter.
Your code should read as follows:
If Cells(cRow, cCol).Value = "0" Then
Range(Cells(rRow, rCol), Cells(cRow, cCol)).ClearContents
End If
You are trying to clear column 11 from rows 3 to 14 of the "To DNP" worksheet, which obviously contains merged cells.
For anyone else that stops by; here is simple code to clear a specific range in a row if one cell contains a specific value.
For Each cell In Range("C11:N50")
If cell.Value2 = "0" Then
Set cRng = Range("C" & cell.Row & ":" & "O" & cell.Row)
' Or Set clearRng = Range("C" & cell.Row & ":O" & cell.Row)
cRng.Clear
End If
Next
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
I want to copy a defined number (lets say 10) of rows from one sheet ("Data") and paste it in another sheet ("Input). This will cause a bunch of stuff to calculate. Then I want to copy said calculated data (6 rows) from ("Input") to ("Data") and paste in a results table. THen I would repeat this a defined number of times for a certain number of columns (lets say 10).
I tried writing the code but it has literally been years since I have written code.
I used the Record Marco thing and got this:
Sub Macro2()
'
' Macro2 Macro
'
'
Range("C5:C14").Select
Selection.Copy
Sheets("Input").Select
Range("C5").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("P12:P19").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Data").Select
Range("C22").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("D5:D14").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Input").Select
Range("C5").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("P12:P19").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Data").Select
Range("D22").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("G16").Select
End Sub
I hope this makes sense
Sub Macro2()
Const NUM_TIMES As Long = 10
Dim shtInput As Worksheet, shtData As Worksheet
Dim rngCopy As Range, i As Long
Set shtInput = Sheets("Input")
Set shtData = Sheets("Data")
Set rngCopy = shtData.Range("C5:C15")
For i = 1 To NUM_TIMES
With shtInput
.Range("C5").Resize(rngCopy.Rows.Count, 1).Value = rngCopy.Value
.Calculate
rngCopy(1).Offset(17, 0).Resize(8, 1).Value = .Range("P12:P19").Value
End With
Set rngCopy = rngCopy.Offset(0, 1)
Next i
End Sub