Excel VBA Course
Excel VBA Course - From Beginner to Expert

200+ Video Lessons
50+ Hours of Video
200+ Excel Guides

Become a master of VBA and Macros in Excel and learn how to automate all of your tasks in Excel with this online course. (No VBA experience required.)

View Course

Speed up Transpose

0

Hi,

I watched your video on how to use the VBA code to transpose the data and this seems to be working for me but it slows down the excel. Can you please advise what can be done to speed it up? The qty of the rows to be transposed are different every day. 

Sub Transpose()
Application.ScreenUpdating = False
xRow = Selection.Rows.Count
xCol = Selection.Column
nextRow = 1
'ColumnHeaders
Range("E1").Value = "Company Name"
Range("F1").Value = "AR Number"
Range("G1").Value = "Description"
stepValue = 6
For i = 1 To xRow Step stepValue
Cells(i, xCol).Resize(stepValue).Copy
Cells(1, xCol).Offset(nextRow, 3).PasteSpecial Paste:=xlPasteAll, Transpose:=True
nextRow = nextRow + 1
Next
Application.CutCopyMode = False
Application.ScreenUpdating = True
'SelectARcolumn
Range("F2", Range("F2").End(xlDown)).Select
Selection.NumberFormat = "0"
End Sub
   
Answer
Discuss

Discussion

I looked at your code and saw nothing in it that might slow down your workbook. This code should run in an instant, even if the selection is large. Note thast the last thought should be expressed without selecting anything, like this:- 
Range("F2", Range("F2").End(xlDown)).umberFormat = "0"

Since it isn't this code what's slowing down your workbook? Extensive use of the OFFSET or INDIRECT worksheet functions would do that or a lot of conditional formatting would do that. CF easily gets fragmented, where you only have a single range, like one column, that's formatted but Excel treats each cell or small group of cells separately. Such a condition might result from conditionally formatted cells being copied by your macro.
Variatus (rep: 4889) Feb 3, '21 at 6:58 pm
Hi,
Thank you for your prompt reply however, It runs slow causing "no responding" in Excel. I do not have any conditional formatting or any other functions in this file and cannot understand what should be done to correct this (maybe the copy of the file will help)?. Also, can you please advise if the manual selection/copy of the cells to transpose can be changed to the range (dynamic)? 
Thank you!
Fara6ka (rep: 2) Feb 5, '21 at 3:22 pm
Yes, mixing user selection with VBA isn't a good way. If you can describe what you select, define the criteria by which the selection is made, that part is easy to program. Meanwhile, one macro getting hung up is completely different from the application becoming slow. Definitely, edit your question to attach the workbook and let's take a look.
Variatus (rep: 4889) Feb 5, '21 at 6:57 pm
Hi,
I apologize if I sound dumb as I'm totally new to VBA and this forum. I don't see the option to upload the file (will appreciate it if you can advise) In a few words i need the following steps to be run by Macro:
1. Manually copy the data from email.
2. Paste using "match destination formating"
3. Delete column A &B (Here i wanted the macro to start working but all my attempts were unsuccessful)
4. Select column A (the amount of data is always different) I think here the dynamic range option can be used instead of 'manual selection"
5. Transpose data
6. Format column "F" (number, no decimal places)
Thank you for your help!
Have a good day!
 

Fara6ka (rep: 2) Feb 9, '21 at 4:57 pm
Add to Discussion

Answers

0
Selected Answer

Your question lacks a work flow. Therefore I have created one for you. It may not be what you want, or even what you can use, but if we don't have anything to discuss we have no way to improve. This is the flow I have imagined:-

  1. You have a workbook that contains your database. That is a tab where you add entries every day. In the attached workbook I called it "Database".
  2. The same workbook also contains the code. Therefore it's of xlsm format (unlike the workbook you posted).
  3. There is a sheet in this same workbook called "DataToTranspose". Every day you copy data from your email to this sheet.
  4. Then you run the code, which transfers the new data in transposed format to the "Database" sheet.
  5. The data on the "DataToTranspose" tab are then deleted in preparation for the next day's batch.

Here is the code that does the transferring. It's very fast because it doesn't waste time reading from the sheet or writing to it. It just reads once and writes only once, doing all the transforming work on copies.

Sub TransferData()
    ' 170

    Dim Ws          As Worksheet        ' source data sheet
    Dim Source      As Variant          ' data to transpose
    Dim Output      As Variant          ' the transposed data
    Dim Rs          As Long             ' loop counter: rows (Source)
    Dim C           As Long             ' loop counter: columns (Source)
    Dim Rout        As Long             ' rows (Output)
    Dim Cout        As Long             ' columns (Output)

    ' read the data to transpose into memory
    Set Ws = Worksheets("DataToTranspose")
    With Ws
        ' from A1 to end of column + 2 rows (searching from last sheet row up)
        Source = .Range(.Cells(1, 1), .Cells(.Rows.Count, 1).End(xlUp).Offset(2))
        ' this will be 2 2D array with many rows and 1 column
    End With

    ' dimension the output array:-
    ' 5 columns wide x as many rows as in the source data
    ReDim Output(1 To 5, 1 To UBound(Source))
    For Rs = 1 To (UBound(Source)) Step 6
        Rout = Rout + 1
        Output(1, Rout) = Date          ' add the current date to each row
        Cout = 1
        For C = 0 To 3                  ' 4 loops
            ' omit the 3rd column
            If C <> 2 Then
                Cout = Cout + 1
                Output(Cout, Rout) = Source(Rs + C, 1)
            End If
        Next C
    Next Rs

    ' erase unused portion of Output array
    ReDim Preserve Output(LBound(Output) To UBound(Output), 1 To Rout)

    With Worksheets("Database")
        .Cells(.Rows.Count, "A").End(xlUp).Offset(1) _
               .Resize(UBound(Output, 2), UBound(Output)).Value = Application.Transpose(Output)
        .Range(.Columns(1), .Columns(4)).AutoFit        ' adjust column widths
    End With

'    If Err.Number = 0 Then Ws.ClearContents
End Sub

There are a few peculiarities that require your attention beyond the creation of the workbook itself, synching the tab names with the code and saving the whole thing correctly.

  1. The "Database" tab already exists. In the attached workbook it already has column captions. My code doesn't add captions like yours.
  2. My workbook has an extra column for the current date. This isn't to suggest that you need a date but to show you where in the code to add information to each row. It could be a serial number or anything else, and t doesn't need to be in the first column, either.
  3. Observe the column management in the loop. First the extra information (Date) is written to the appropriate column (1 = A). Then the inside loop For C = 0 To 3 takes over. That copies 4 rows from the source data but one of them is skipped. I don't know if this is really what you intend but I took the hint as cause to show you how it can be done. As a result C and Cout (the column counter for the Output array) aren't identical. Of course, Cout must match the columns on the Database sheet.
  4. .Range(.Columns(1), .Columns(4)).AutoFit adjusts the widths of the sheet columns on every run. If you don't like the effect, remove the line. It's very useful while testing.
  5. The last line in the code is If Err.Number = 0 Then Ws.ClearContents.  I never used it because I wanted to preserve the data. You always have a backup in the email you received. Therefore data preservation is less critical. Please enable that line when you are ready.

Meanwhile, the attached workbook is fully functionable. You can run the code repeatedly. Each run will append the new data to the existing.

Discuss

Discussion

Correct, the selection is not part of the Excel, I was trying to give a full picture of the process. 
Finally, I was able to find where and how to upload the file:) Thank you! So, the file includes the raw data as it appears after I paste it in Excel for further transpose (usually it is more than 500 lines).  
Fara6ka (rep: 2) Feb 9, '21 at 9:18 pm
Your question was about speed and we end up talking about work flow. That's because you can't speed up that doesn't exist. However, I think we hit the target (speed) in the process. Please try the code I posted.
Variatus (rep: 4889) Feb 10, '21 at 8:47 pm
Thank you for your help! I appreciate the time you spent on it! Column 3 that  contains the $ amount information is omitted in the code. I tried to skip this step but then the code stops working, sure I'm doing something wrong. Can you please explain how to skip this step?
Thank you!
Fara6ka (rep: 2) Feb 12, '21 at 4:34 pm
Skip the skipping, haha. 
            If C <> 2 Then
                Cout = Cout + 1
                Output(Cout, Rout) = Source(Rs + C, 1)
            End If

The code will write to Output when C unequals 2. To remove that condition delete that line and the "End If" 2 lines down that goes with it. That will give you an extra column in the output. Change the 4 to 5 in this line.
.Range(.Columns(1), .Columns(4)).AutoFit

Please also remember to mark the answer as "Selected" when you got it working for you.
Variatus (rep: 4889) Feb 12, '21 at 9:46 pm
               ' omit the 3rd column
            'If C <> 2 Then
            '    Cout = Cout + 1
            '    Output(Cout, Rout) = Source(Rs + C, 1)
            'End If
 


Hi, sorry to bother you again. I tried to delete this part of the code that omits column 3 however the code does not work properly then. Am I missing something here?
Fara6ka (rep: 2) Feb 19, '21 at 1:39 pm
Haha. You should learn to read code. It says "If the loop number <> 2 Then do the following". It means that the "following" will be done for all loops except #2. So, to make the correct modification you should not remove the "following", only the condition. If you remove the condition the "following" will be done in every loop without exception.
Of course, the condition is If C <> 2 Then and the syntax of this one line requires the End If 2 lines further down, which must also be removed. The 2 lines in between are the "following" and must be retained.
Good luck!
Variatus (rep: 4889) Feb 19, '21 at 8:51 pm
Hi, yes, you are right I'm not good at all reading codes but I want to learn and searching for the course online. I will do my best to make the code working and really appreciate your patience and help! 
Fara6ka (rep: 2) Feb 22, '21 at 10:27 am
Add to Discussion


Answer the Question

You must create an account to use the forum. Create an Account or Login