Worksheetfunction.Transpose – changed behaviour in Excel 2013 and 2016

It is (fairly) well known that when using Worksheetfunction.Transpose on an array in VBA the array must be no more than 65,536 (2^16) rows long, or it will return an error.

Recently when using Excel 2016 (32 bit) I thought this limitation had been fixed; I was able to transpose arrays with up to the maximum number of rows allowed by Excel (1,048,576 0r 16 * 2^16), without generating any error.  Then I checked the end of the returned arrays, and discovered that they had in fact been truncated at 65,536 rows.  A closer look revealed that the truncation is in fact done in blocks of 2^16 rows, so if you transpose an array of 65,537 rows the operation will delete all but 1 of them, with no indication that anything unusual has happened.

To investigate what is happening I wrote 7 functions to split an array into single columns, then transpose them, the intent being to generate 1D arrays, which are much faster when transferring large data sets to other programs.  The variations were:

  • Splitarray: Split a 3 column array into 3 single columns, with no transpose.
  • Splitarray-a: Split and transpose in a single operation.
  • Splitarray-b: Redim the output arrays first, then split and transpose in a single operation.
  • Splitarray-c: Redim the output arrays first, then split into three variant arrays, then transpose.
  • Splitarray-d: Transpose without splitting, creating a 3 row array.
  • Splitarray-e: Split into single columns, then copy to 1D arrays with a loop.
  • Splitarray-f:  Convert the input range to a variant array, then split and transpose with a loop.

The functions were modified to return the following information:

  • Row 1:  Run time
  • Rows 2-4:  The number of values in the returned arrays, or in the case of Splitarray-d the  number of rows, then the number of columns.

In the case of Splitarray-c and Splitarray-f, which had a two stage operation, two columns were returned, with times and array sizes at the end of each step.

The results for Excel 2016 are shown below for four different array sizes:

65,536 rows; all functions return all the input data


1,048,576 rows: the first function (which did not transpose) and the last two (which used loops) return all the data, but all the others truncate the output to 65,536 values.


65,537 rows: The second to fifth functions have all truncated the data to just one value.


1,048577 rows: Now all the functions return #VALUE! errors (as in previous versions of Excel), because the specified range size exceeds the maximum number of rows.  Note that VBA arrays can have a much greater number of rows (limited by available memory), but if you are reading data from the spreadsheet the range limit on number of rows applies.


Comparing with Excel 2010; results for 65536 rows are the same:


With 1 additional row up to 1,048, 576 rows, all the functions that use Transpose return #VALUE! errors:



And with 1 or more rows past the range limit all the functions return errors:


It was my recollection that Excel 2013 worked the same as 2010, but checking with 65,537 rows I found that the arrays were truncated to one value, when Transpose was used, as for Excel 2016.


So the conclusions are:

  1. In Excel 2013 and 2016 (32 bit) using Worksheetfunction.Transpose in any VBA routine will truncate the array without warning if it has more than 65536 rows, so if you must use this function be sure to check the size of the array first.
  2. But really, there is no good reason for using it at all.  It can be replaced by a short VBA routine using loops, which will return the full array up to 1,048,576 rows (or larger if working entirely in VBA), and is actually faster than the Transpose version (at least for arrays of the size used in these tests).
This entry was posted in Arrays, Excel, UDFs, VBA and tagged , , , , , , , . Bookmark the permalink.

One Response to Worksheetfunction.Transpose – changed behaviour in Excel 2013 and 2016

  1. Alan Elston says:

    Thanks for bringing this behaviuor up.
    I recently decided for this reason , along with the speed aspects, to always use my own functions for transposing Arrays.
    I have also often noticed that working with single dimension Arrays can be very quick.
    You mentioned splitting your Array into columns before transposing each one. I have found that splitting an Array can be very quick.
    However one is limited again to the earlier Worksheets size.
    And I do not know of a quick way to join rows
    So, a couple of questions:
    _1 ) I expect there would be no advantage doing this in an Array Transpose Function.
    I am a VBA Novice / part timer, so just thought I would check that I have not missed anything?
    _2) I do not have above XL 2010. It is not clear to me immediately what I “lose”. When it “Truncate”, what values does it transpose, do they include the rows above the truncated, so you never get the rows above 65,536 , or does it truncate as it were from the bottom-
    For example, if I try to transpose 65537 rows, I get 1 column,- Correct? But, do I get row number 1 or row number 65537 transposed as my final result.
    P.s. I do note that some of these functions work very efficiently with a Spreadsheet, and that sometimes not always the Array Methods are the best


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s