|
Microsoft Office Application Development
|
|
Transposing the Formulas in a Table of CellsRecently someone asked me if it was possible to transpose a table of cells, but in such a way that the formula of each cell is kept intact. I decided VBA was the way to go and produced a small but very useful little routine for that. Imagine the following table:
Now I'd like to transform that table into this one (see highlighted range):
If you try a copy > paste special > formulas > transpose, this is what you get:
But it is not what we want, is it. With the following piece of VBA, you can easily transpose your table, without garbling your formulas: Option Explicit So how does this work? First we check whether a range of cells has been selected, otherwise the code will produce a runtime error: If TypeName(Selection) <> "Range" Then Next, we store the selected cells in an object variable (which is not really necessary), so we can work with that set of cells: Set oSel = Selection Now the formulas of these cells are pulled into a variable of type Variant in one go: vFormulas = oSel.Formula If you step through the code (using my example) the Locals window of the Visual Basic Editor (VBE) shows this for the variable vFormulas after executing the statement above:
As you can see, vFormulas is a 4*3 array. Next we want to swap rows and columns of the vFormulas variable, for which I use the Transpose worksheet function: vFormulas = Application.WorksheetFunction.Transpose(vFormulas) The structure of vFormulas changes to this:
Presto! We now have a 4 * 3 array. Finally, we need to push back the formulas to the worksheet. To be able to do that, we must specify a target range of the exact dimensions as the array variable. For that I use the Resize method. Note I also move down a couple of cells using Offset, so the copy of the table is placed 2 rows below the original: oSel.Offset(oSel.Rows.Count + 2).Resize(oSel.Columns.Count, oSel.Rows.Count).Formula = vFormulas Done! CommentsPlease rate this page: (Rated: 550 times, average rating: 6.2)![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Showing last 15 comments of 21 in total (Show All Comments):Comment by: Jan Karel Pieterse (9/28/2006 6:26:41 AM)Hi Chris, Good point. I do use this on occasion, because I prefer it to an If-Then-Else construct that spans almost the entire subroutine. I find those to more confusing than a sparsely used Exit sub when a certain "vital" test fails. But that is a matter of personal preference I guess. Comment by: Ufuk (1/18/2007 1:04:41 AM)That's perfect, this macro help me a lot to complate a work, thank you very much! Comment by: Derek Turner (1/27/2007 7:55:12 AM)Sub TransposeSelection() ' TransposeFormulae Selection End Sub Sub TransposeFormulae(oSelection As Object) ' If TypeName(oSelection) = "Range" Then With oSelection .Offset(.Rows.Count + 2).Resize(.Columns.Count, .Rows.Count).Formula = Application.Transpose(.Formula) End With Else MsgBox "Please select a range of cells first.", vbOKOnly + vbInformation, "Transpose formulae" End If End Sub However, this fails in Excel 2002 with a Type Mismatch if any cell contains a string longer than 255 characters. It will also fail with multiple selections but this can be trapped with .Areas.Count Comment by: Cale Maddy (4/7/2007 10:22:29 AM)Thank you so much for the select range, Ctrl-H method. I don't have a clue about visual basic and you just saved me an enormous amount of time. Comment by: lennox de ronde (5/31/2007 5:11:48 PM)it can be don much more simple when you make the formula use $+cell reference and then perform the transpose depending on the tranposeyou use cell$ of $cell lennox, thanks anyway Comment by: Jan Karel Pieterse (5/31/2007 9:25:21 PM)Hi Lennox, You're correct if you did set up those absolute references properly. But how often have people NOT done that... And my example always works, even with mixed references. Comment by: John Salkeld (7/19/2007 3:45:15 AM)Very interesting - It would be of interest to include array formulae in this application Comment by: rodstar (1/9/2008 6:30:32 AM)great solution! any tutorial teaching how to program this code into Excel? I know a little about coding, but never did anything using VBE. Other option is offer a xls to download and use the macro. thanks. r Comment by: Jan Karel Pieterse (1/9/2008 10:41:14 AM)Hi rodstar, Just open the VBE (alt+F11), insert a module (Insert, Module) and paste in the code shown above. Then return to Excel. Select the range you want processed, hit alt+F8 to get to the macro list and run the macro called TransposeFormulas Comment by: Daničle Questiaux (4/18/2008 12:35:54 AM)As you say very well, your example first is useful(!), but is also one of those examples that clarifies the steps used in VBA, and that is priceless! Thanks! All the added comments are also a great idea to have for novices at VBA (I/m one of them). Comment by: colin (4/21/2008 7:45:15 AM)Thanks Lennox, the original answer was a little intimidating for the layman Comment by: Robert (6/8/2008 5:20:56 AM)This works great. However it does not work with array formulas (the type you have to press Comment by: Jan Karel Pieterse (6/8/2008 9:49:27 PM)Hi Robert, Indeed, it fails with array formulas. For single cell array formulas, this workaround works: Sub TransposeFormulas() Dim vFormulas As Variant Dim oSel As Range Dim oCell As Range If TypeName(Selection) <> "Range" Then MsgBox "Please select a range of cells first.", _ vbOKOnly + vbInformation, "Transpose formulas" Exit Sub End If Set oSel = Selection vFormulas = oSel.Formula vFormulas = Application.WorksheetFunction.Transpose(vFormulas) oSel.Offset(oSel.Rows.Count + 2).Resize(oSel.Columns.Count, oSel.Rows.Count).Formula = vFormulas For Each oCell In oSel.Offset(oSel.Rows.Count + 2).Resize(oSel.Columns.Count, oSel.Rows.Count).Cells oCell.FormulaArray = oCell.Formula Next End Sub Comment by: peter nthiga (7/1/2008 5:58:41 AM)pliz help on how to transpose access table rows to column in vb 6 Comment by: Jan Karel Pieterse (7/1/2008 10:22:35 AM)For help with Access I suggest you try the microsoft Access newsgroups. Add a comment too!!! | ||||||||||||||
|
Use the contact page to issue
questions or comments about this website. |