How to turn a column of data into an 8x12 grid? - excel

I'm trying to put values from 1 column into an 8x12 grid.
With the first value starting in the top left of the grid, moving to the right 12 cells, then offsetting 1 row from starting cell and having the data continue filling cells in this format.
I'm trying to replace
roneWS.Range("E6:N6") = Application.Transpose(ptWS.Range("B4:B13"))
roneWS.Range("C7:N7") = Application.Transpose(ptWS.Range("B14:B25"))
roneWS.Range("C8:N8") = Application.Transpose(ptWS.Range("B26:B37"))
roneWS.Range("C9:N9") = Application.Transpose(ptWS.Range("B38:B49"))
roneWS.Range("C10:N10") = Application.Transpose(ptWS.Range("B50:B61"))
roneWS.Range("C11:N11") = Application.Transpose(ptWS.Range("B62:B73"))
roneWS.Range("C12:N12") = Application.Transpose(ptWS.Range("B74:B85"))
roneWS.Range("C13:N13") = Application.Transpose(ptWS.Range("B86:B97"))
with an array/loop.
I came up with:
Dim ptWS As Worksheet, roneWS As Worksheet, rtwoWS As Worksheet, rthreeWS As Worksheet, rfourWS As Worksheet
Dim ptRng As Range, destRng As Range
Dim i As Integer
Dim ptArr() As Variant
Set ptWS = ThisWorkbook.Worksheets("PT")
Set roneWS = ThisWorkbook.Worksheets("WS1")
Set rtwoWS = ThisWorkbook.Worksheets("WS2")
Set rthreeWS = ThisWorkbook.Worksheets("WS3")
Set rfourWS = ThisWorkbook.Worksheets("WS4")
i = 4
Set ptRng = ptWS.Range("B4:B97") 'data that needs to be moved to other worksheets B4:B97 = 1st WS, C4:C97 = 2nd WS, D4:D97 = 3rd WS, E4:E97 = 4th WS
Set destRng = roneWS.Range("E6") 'destination range for WS1-WS4 starts at E6
ptArr = ptRng.Value 'setting all values for the WS1 to ptArr
For i = LBound(ptArr) To UBound(ptArr)
If ptArr(i, 1) = ptWS.Cells(14, 2) Then 'move my way across the columns until I hit Col O then, offset back to Col C and repeat until the end (N13) is reached
Set destRng = destRng.Offset(1, -12)
destRng = ptArr(i, 1)
Set destRng = destRng.Offset(0, 1)
ElseIf ptArr(i, 1) = ptWS.Cells(26, 2) Then
Set destRng = destRng.Offset(1, -12)
destRng = ptArr(i, 1)
Set destRng = destRng.Offset(0, 1)
ElseIf ptArr(i, 1) = ptWS.Cells(38, 2) Then
Set destRng = destRng.Offset(1, -12)
destRng = ptArr(i, 1)
Set destRng = destRng.Offset(0, 1)
ElseIf ptArr(i, 1) = ptWS.Cells(50, 2) Then
Set destRng = destRng.Offset(1, -12)
destRng = ptArr(i, 1)
Set destRng = destRng.Offset(0, 1)
ElseIf ptArr(i, 1) = ptWS.Cells(62, 2) Then
Set destRng = destRng.Offset(1, -12)
destRng = ptArr(i, 1)
Set destRng = destRng.Offset(0, 1)
ElseIf ptArr(i, 1) = ptWS.Cells(74, 2) Then
Set destRng = destRng.Offset(1, -12)
destRng = ptArr(i, 1)
Set destRng = destRng.Offset(0, 1)
ElseIf ptArr(i, 1) = ptWS.Cells(86, 2) Then
Set destRng = destRng.Offset(1, -12)
destRng = ptArr(i, 1)
Set destRng = destRng.Offset(0, 1)
Else: destRng = ptArr(i, 1)
Set destRng = destRng.Offset(0, 1)
End If
Next i
It gives me what I want for WS1. However I have to repeat this for the 3 other worksheets.
For the other 3 worksheets, the total range is the same as posted above, just offset by 1 column.
WS1 = ptWS.Range("B4:B97")
WS2 = ptWS.Range("C4:C97")
WS3 = ptWS.Range("D4:D97")
WS4 = ptWS.Range("E4:E97")
The destination starting point on all 4 worksheets are the same Range(E6").
How do I add a loop through the worksheets once all cells on WS1 have been set, while also offsetting the column by 1 from ptWS. I'm wondering if this can be done without copy/pasting the existing array code 3 more times and just changing the ranges.
I achieved the same result by looping through the data on ptWS by using a series of Do Until loops but then eventually ran into the same issue.

Here's one appraoch:
Sub Tester()
Dim i As Long
For i = 1 To 4
ColToMatrix ThisWorkbook.Worksheets("PT").Range("B4:B97").Offset(0, i - 1), _
ThisWorkbook.Worksheets("WS" & i).Range("C6")
Next i
End Sub
'pass in the column to be mapped and the top-left destination cell for the matrix
Sub ColToMatrix(rngCol As Range, rngTL As Range)
Dim arr, mtx(1 To 8, 1 To 12), i As Long, r As Long, c As Long, n As Long
arr = rngCol.Value
For i = 1 To UBound(arr, 1)
n = i + 2 'account for starting 3 cells in
r = 1 + ((n - 1) \ 12)
c = ((n - 1) Mod 12) + 1
mtx(r, c) = arr(i, 1)
Next i
rngTL.Resize(8, 12).Value = mtx
End Sub

To do this, better way is doing a sub to transpose data, and then call it for every worksheet.
I'm excluding roneWS.Range("E6:N6") = Application.Transpose(ptWS.Range("B4:B13")) because it's not part of the 7x12 array, due to different size (it's 10 values, not 12).
So we focus on 7x12, this part of your code:
roneWS.Range("C7:N7") = Application.Transpose(ptWS.Range("B14:B25"))
roneWS.Range("C8:N8") = Application.Transpose(ptWS.Range("B26:B37"))
roneWS.Range("C9:N9") = Application.Transpose(ptWS.Range("B38:B49"))
roneWS.Range("C10:N10") = Application.Transpose(ptWS.Range("B50:B61"))
roneWS.Range("C11:N11") = Application.Transpose(ptWS.Range("B62:B73"))
roneWS.Range("C12:N12") = Application.Transpose(ptWS.Range("B74:B85"))
roneWS.Range("C13:N13") = Application.Transpose(ptWS.Range("B86:B97"))
This sub will as for:
A source range like ptWS.Range("B14:B97"), 84 values (7x12)
A destiny range like roneWS.Range("C7:N13"), a 7x12 grid
The code is:
Sub GET_VALUES(ByVal vRngSource As Range, ByVal vRngDestiny As Range)
Dim vMatriz As Variant
Dim ZZ As Long
Dim ThisColumn As Long, ThisRow As Long
ThisColumn = 1
ThisRow = 1
vMatriz = vRngSource.Value
For ZZ = 1 To UBound(vMatriz) Step 1
vRngDestiny.Cells(ThisRow, ThisColumn).Value = vMatriz(ZZ, 1)
If ThisColumn = 12 Then
ThisColumn = 1
ThisRow = ThisRow + 1
Else
ThisColumn = ThisColumn + 1
End If
Next ZZ
Erase vMatriz
End Sub
To call it, you can just do:
Sub test()
GET_VALUES Range("B14:B97"), Range("C7:N13")
End Sub
Now you just need to call it once for every worksheet. I would use a For each loop combined with Select Case, so you can choose for every worksheet what to do, like this:
Sub TEST()
Application.ScreenUpdating = False
Dim WK As Worksheet
Dim ptWS As Worksheet
Set ptWS = ThisWorkbook.Worksheets("PT")
For Each WK In ThisWorkbook.Worksheets
Select Case WK.Name
Case "WS1"
GET_VALUES ptWS.Range("B14:B97"), WK.Range("C7:N13")
WK.Range("E6:N6") = Application.Transpose(ptWS.Range("B4:B13"))
Case "WS2"
GET_VALUES ptWS.Range("C14:C97"), WK.Range("C7:N13")
WK.Range("E6:N6") = Application.Transpose(ptWS.Range("C4:C13"))
Case "WS3"
GET_VALUES ptWS.Range("D14:D97"), WK.Range("C7:N13")
WK.Range("E6:N6") = Application.Transpose(ptWS.Range("D4:D13"))
Case "WS4"
GET_VALUES ptWS.Range("E14:E97"), WK.Range("C7:N13")
WK.Range("E6:N6") = Application.Transpose(ptWS.Range("E4:E13"))
Case Else
'we do nothing
End Select
Next WK
Application.ScreenUpdating = True
End Sub
Hope you can adapt this to your needs.

Related

Loop to multiple sheets with multiple criteria to get the price

I have a workbook with several worksheets. The main worksheet is the Data worksheet.
The search criteria are in the Data worksheet B2,C2 and D2.The other sheets are cross tabs in which the prices are located. The prices I am looking for should be transferred in sheet Data column G2. I stuck with following code.
Dim wks As Worksheet
Dim wksData As Worksheet: Set wksData = Sheets("Data")
Dim lngrow As Long
Dim lngrow2 As Long
Dim lngSpalte As Long
For lngrow = 2 To wksData.Cells(Rows.Count, 2).End(xlUp).Row
Select Case wksData.Cells(lngrow, 2).Value
Case "Standard"
Set wks = Sheets("Standard")
Case "Express Plus"
Set wks = Sheets("Express Plus")
Case "Express Saver"
Set wks = Sheets("Express Saver")
End Select
For lngrow2 = 2 To wks.Cells(Rows.Count, 2).End(xlUp).Row
If Trim(wks.Cells(lngrow2, 2).Value) = Trim(wksData.Cells(lngrow, 3).Value) Then
For lngSpalte = 2 To 10
If Trim(wks.Cells(lngSpalte, 3).Value) = Trim(wksData.Cells(lngrow, 4)) Then
wksData.Cells(lngrow, 7).Value = wks.Cells(lngrow2, lngSpalte).Value
Exit For
End If
Next
End If
Next
Next
Is anyone able to help? Thank you!
EDIT - based on your sample workbook...
Sub Tester()
Dim wksData As Worksheet, wks As Worksheet
Dim lngrow As Long
Dim delType, delZone, delWeight, mCol, rv
Dim rngWts As Range, arrWts, rngZones As Range, i As Long, w As Double
Set wksData = Sheets("Data")
For lngrow = 2 To wksData.Cells(Rows.Count, 2).End(xlUp).Row
delType = Trim(wksData.Cells(lngrow, "B").Value) 'use some descriptive variables!
delZone = wksData.Cells(lngrow, "C").Value
delWeight = CDbl(Trim(wksData.Cells(lngrow, "D").Value))
rv = "" 'clear result value
Select Case delType
Case "Standard", "Express Plus", "Express Saver"
Set wks = Sheets(delType) 'simpler...
Set rngWts = wks.Range("A3:A" & wks.Cells(Rows.Count, "A").End(xlUp).Row)
arrWts = rngWts.Value
'loop over the weights data
For i = 1 To UBound(arrWts, 1) - 1
If delWeight >= arrWts(i, 1) And delWeight < arrWts(i + 1, 1) Then
Set rngZones = wks.Range("B2", wks.Cells(2, Columns.Count).End(xlToLeft)) 'zones range
mCol = Application.Match(delZone, rngZones, 0) 'find the matching Zone
If Not IsError(mCol) Then 'got zone match?
rv = rngWts.Cells(i).Offset(0, mCol).Value
Else
rv = "Zone?"
End If
Exit For 'stop checking weights column
End If
Next i
If Len(rv) = 0 Then rv = "No weight match"
Case Else
rv = "Delivery type?"
End Select
wksData.Cells(lngrow, "G").Value = rv 'populate the result
Next
End Sub

Find 2 cells' values based on max value found in range

I have a multiplication style table with values inside x and y axis'. After the initial macro is run, I want to search for the max value, then find the corresponding x and y cells. Example...
enter image description here
In this example, the red text is the highest value, so it should find the 1 and the .015. But, there are some tables that might return multiple numbers, so I just want to pick the first cell found. Here is the full code.
Private Sub CommandButton6_Click()
Dim c As Range
Dim rng As Range
Dim balanceValue As Range
Dim dayValue As Range
Dim multValue As Range
Dim lCol As Long
Dim lRow As Long
Dim whereRow As Long
Dim AddressOfMaxH As Variant
'Dim AddressOfMaxV As Range
'Set rng = Sheets("MacroTesting").Range("B91:CD110")
Set rng = Sheets("MacroTesting").Range("B91:C92")
Set balanceValue = Sheets("Header").Range("B4")
Set dayValue = Sheets("Header").Range("E17")
Set multValue = Sheets("Header").Range("F17")
getRow = Sheets("MacroTesting").Range("B91").Row
getCol = Sheets("MacroTesting").Range("B91").Column
whereRow = 90
lCol = Cells(whereRow, Columns.Count).End(xlToLeft).Column
rng.Clear
For Each c In rng
If ActiveCell.Column = lCol Then
getRow = getRow + 1
getCol = 2
End If
getRow = Sheets("MacroTesting").Cells(getRow, 1)
dayValue = getRow
getCol = Sheets("MacroTesting").Cells(whereRow, getCol)
multValue = getCol
c = balanceValue.Copy
c.Select
c = FormatCurrency(c, 0)
Selection.PasteSpecial Paste:=xlPasteValues
getCol = ActiveCell.Column + 1
getRow = ActiveCell.Row
Next
With rng.FormatConditions.AddTop10
.TopBottom = xlTop10Top
.Rank = 1
.Percent = False
With .Font
.Bold = True
.ColorIndex = 3
End With
End With
Set AddressOfMaxH = rng.Cells(WorksheetFunction.Match(WorksheetFunction.Max(rng), rng, 0))
Set AddressOfMaxV = rng.Cells(WorksheetFunction.Match(WorksheetFunction.Max(rng), rng, 0))
AddressOfMaxHoriz = Cells(whereRow, AddressOfMaxH.Column)
AddressOfMaxVerti = Cells(AddressOfMaxV.Row, 1)
dayValue = AddressOfMaxVerti
multValue = AddressOfMaxHoriz
Application.CutCopyMode = False
End Sub
Here is the part where I'm trying to find the relevant cell.
Set AddressOfMaxH = rng.Cells(WorksheetFunction.Match(WorksheetFunction.Max(rng), rng, 0))
Set AddressOfMaxV = rng.Cells(WorksheetFunction.Match(WorksheetFunction.Max(rng), rng, 0))
AddressOfMaxHoriz = Cells(whereRow, AddressOfMaxH.Column)
AddressOfMaxVerti = Cells(AddressOfMaxV.Row, 1)
dayValue = AddressOfMaxVerti
multValue = AddressOfMaxHoriz
Dim rng As Range, f As Range
Set rng = Range("C6:G13")
Set f = rng.Find(Application.Max(rng), lookat:=xlWhole)
Debug.Print Cells(rng(1).Row - 1, f.Column).Value 'column header
Debug.Print Cells(f.Row, rng(1).Column - 1).Value 'row header

Replacing pos,neg values to another sheet

Screenshot#1
So i have to replace positive & negative numbers in column "A", from sheet "1" to sheet second[positive] and third sheet[negative].
Here is what i tried:
Sub Verify()
Dim row As Long
For row = 1 To 20
If ActiveSheet.Cells(row,1) <> "" Then
If ActiveSheet.Cells(row,1) > 0 Then
ActiveSheet.Cells(row,2) = ActiveSheet.Cells(row,1)
End If
End If
Next
End Sub
Here is what that program do:
Screenshot#2
So as we see i am getting positive values in column "B" sheet 1.
Your code is not currently working because you are only using ActiveSheet, rather than placing data on other worksheets as required. Below is some VBA code that loops column A in your original sheet, and outputs the data to column A in two different sheets as required:
Sub sSplitPositiveNegative()
Dim wsOriginal As Worksheet
Dim wsPositive As Worksheet
Dim wsNegative As Worksheet
Dim lngLastRow As Long
Dim lngPositiveRow As Long
Dim lngNegativeRow As Long
Dim lngLoop1 As Long
Set wsOriginal = ThisWorkbook.Worksheets("Original")
Set wsPositive = ThisWorkbook.Worksheets("Positive")
Set wsNegative = ThisWorkbook.Worksheets("Negative")
lngLastRow = wsOriginal.Cells(wsOriginal.Rows.Count, "A").End(xlUp).Row
lngNegativeRow = 2
lngPositiveRow = 2
For lngLoop1 = 1 To lngLastRow
If wsOriginal.Cells(lngLoop1, 1).Value > 0 Then
wsPositive.Cells(lngPositiveRow, 1) = wsOriginal.Cells(lngLoop1, 1)
lngPositiveRow = lngPositiveRow + 1
Else
wsNegative.Cells(lngNegativeRow, 1) = wsOriginal.Cells(lngLoop1, 1)
lngNegativeRow = lngNegativeRow + 1
End If
Next lngLoop1
Set wsPositive = Nothing
Set wsNegative = Nothing
Set wsOriginal = Nothing
End Sub
You will need to change the names of the worksheets referenced in the code to match those in your workbook.
Regards
Made the code a little reusable for you. Feel free to change sheet names or the last_row variable. The last_pos_val and last_neg_val are used so you won't have empty rows on the second and third sheet. You didn't specify what to do with zero, so it's currently added to the negative sheet.
Sub Verify()
Dim row As Long, last_row As Long, last_pos_val As Long, last_neg_val As Long
Dim ws_source As Worksheet, ws_pos As Worksheet, ws_neg As Worksheet
Dim wb As Workbook
Set wb = ThisWorkbook
Set ws_source = wb.Sheets("Sheet1")
Set ws_pos = wb.Sheets("Sheet2")
Set ws_neg = wb.Sheets("Sheet3")
last_pos_val = 1
last_neg_val = 1
last_row = 20
For row = 1 To last_row
If ws_source.Cells(row,1) <> "" Then
If ws_source.Cells(row,1) > 0 Then
ws_pos.Cells(last_pos_val,1) = ws_source.Cells(row,1)
last_pos_val = last_pos_val + 1
Else
ws_neg.Cells(last_neg_val,1) = ws_source.Cells(row,1)
last_neg_val = last_neg_val + 1
End If
End If
Next
End Sub
Split Positive & Negative
Adjust the values in the constants section.
Both subs are needed. The first sub calls the second one.
The Code
Option Explicit
Sub SplitPN()
Const Source As String = "Sheet1"
Const Positive As String = "Sheet2"
Const Negative As String = "Sheet3"
Const FirstRow As Long = 1
Const SourceColumn As Long = 1
Const PositiveFirstCell As String = "A1"
Const NegativeFirstCell As String = "A1"
Dim rngSource As Range
Dim rngPositive As Range
Dim rngNegative As Range
With ThisWorkbook
With .Worksheets(Source)
Set rngSource = .Columns(SourceColumn).Find(What:="*", _
LookIn:=xlFormulas, SearchDirection:=xlPrevious)
If rngSource Is Nothing Then Exit Sub
If rngSource.Row < FirstRow Then Exit Sub
Set rngSource = .Range(.Cells(FirstRow, SourceColumn), rngSource)
End With
Set rngPositive = .Worksheets(Positive).Range(PositiveFirstCell)
Set rngNegative = .Worksheets(Negative).Range(NegativeFirstCell)
End With
SplitPosNeg rngSource, rngPositive, rngNegative
End Sub
Sub SplitPosNeg(SourceRange As Range, PositiveFirstCell As Range, _
NegativeFirstCell As Range)
Dim Source, Positive, Negative
Dim UB As Long, i As Long
Source = SourceRange
UB = UBound(Source)
ReDim Positive(1 To UB, 1 To 1)
ReDim Negative(1 To UB, 1 To 1)
For i = 1 To UBound(Source)
Select Case Source(i, 1)
Case Is > 0: Positive(i, 1) = Source(i, 1)
Case Is < 0: Negative(i, 1) = Source(i, 1)
End Select
Next
PositiveFirstCell.Resize(UB) = Positive
NegativeFirstCell.Resize(UB) = Negative
End Sub

Transposing Sets of Columns on Top of Each Other in Excel

So I have multiple sets of 3 columns. Each set is always in the same column order ("SKU", "Sales". "Date".)
I am wondering is there is a VBA script or other method that would do the following:
1.) Copy G:I
2.) Paste into A:C
3.) Copy J:L
4.) Paste into A:C (Underneath G:I's data)
5.) Copy M:O
6.) Paste into A:C (underneath J:L's data)
7.) Repeat (I would like it to repeat every 3 columns forever, but if that's not possible I'll manually input the columns if I have
to.)
This is a visual of what I'm looking for: http://i.imgur.com/AagLIm8.png
I also uploaded the workbook in case you need it for reference: https://www.dropbox.com/s/wea2nr4xbfo4934/Workbook.xlsx?dl=0
Thanks for the help!
The code below does what you want, and I've included some ".select" lines to help you understand. I suggest you step through it to become clear, as in the animated gif. Then, remove all the ".select" lines of code.
Option Explicit
Sub moveData()
Dim rSource As Range, rDest As Range, r As Range
Dim tbl As Range, rowNum As Integer
Const colNum = 3
Set rDest = Range("A1")
Set rSource = Range("G1")
Set r = rSource
While r <> ""
Set r = Range(r, r.End(xlDown))
Set tbl = Range(r, r.Offset(0, colNum - 1))
tbl.Select
Set tbl = Range(tbl, tbl.End(xlDown).Offset(1, 0))
tbl.Select
tbl.Copy
rDest.Select
rDest.PasteSpecial (xlPasteAll)
Set rDest = rDest.Offset(tbl.Rows.Count, 0)
Set r = r(1, 1)
r.Select
Set r = r.Offset(0, colNum)
r.Select
Wend
End Sub
try to do this:
Sub CopyColumns()
Dim actualRow As Integer
Dim actualColumn As Integer
Dim rowFrom As Integer
Dim myColumns As Integer
Dim startColumn As Integer
myColumns = 3 'the number of columns before start repeating (in your case is SKU, Sales, Date, so there are 3 columns)
startColumn = 7 'the column where start de data. In your example is the Column G
actualRow = 1
actualColumn = 1
rowFrom = 1
Dim eoRows As Boolean
eoRows = False
While eoRows = False
'verify if there's no more data
If Cells(rowFrom, startColumn) = "" Then
eoRows = True
Else
'verify if there's no more row
While Cells(rowFrom, startColumn) <> ""
For i = startColumn To startColumn + myColumns - 1
Cells(actualRow, actualColumn) = Cells(rowFrom, i)
actualColumn = actualColumn + 1
Next
rowFrom = rowFrom + 1
actualRow = actualRow + 1
actualColumn = 1
Wend
rowFrom = 1
startColumn = startColumn + myColumns
End If
Wend
End Sub

Retrieve Column header depending on values present in an excel worksheet

I have two worksheets ( sheet 1 and sheet 2) . Sheet 1 has 500X500 table. I want to
- Loop through each row ( each cell )
- Identify the cells which have a value ' X' in it
- Pick the respective column header value and store it in a cell in worksheet 2
For example
AA BB CC DD EE FF GG HH
GHS X
FSJ X
FSA X
MSD
SKD
SFJ X X
SFJ
SFM X
MSF X
Is there a way of writing a macro which will pull values in the form of
GHS -> GG
FSJ->DD
.
.
SFJ->BB HH
I have tried looping algorithms but does not seem to work. Could anyone please help me as I am very new to macros.
Try this .. Assumed that GHS, FSJ ... in column A
Sub ColnItem()
Dim x, y, z As Integer
Dim sItem, sCol As String
Dim r As Range
z = 1
For y = 1 To 500
sItem = Cells(y, 1)
sCol = ""
For x = 2 To 500
If UCase(Cells(y, x)) = "X" Then
If Len(sCol) > 0 Then sCol = sCol & " "
sCol = sCol & ColumnName(x)
End If
Next
If Len(sCol) > 0 Then
Sheets("Sheet2").Cells(z, 1) = sItem & " -> " & sCol
z = z + 1
End If
Next
End Sub
Function ColumnName(ByVal nCol As Single) As String
Dim sC As String
Dim nC, nRest, nDivRes As Integer
sC = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
nC = Len(sC)
nRest = nCol Mod nC
nDivRes = (nCol - nRest) / nC
If nDivRes > 0 Then ColumnName = Mid(sC, nDivRes, 1)
ColumnName = ColumnName & Mid(sC, nRest, 1)
End Function
I have placed the values GG, etc., in separate columns of Sheet2, but the code could be modified to put all the information (for a row) in a single cell.
Sub GetColumnHeadings()
Dim ws1 As Worksheet, ws2 As Worksheet
Dim rng1 As Range, rng2 As Range, rng As Range
Dim off As Integer
Set ws1 = Worksheets("Sheet1")
Set ws2 = Worksheets("Sheet2")
Set rng1 = ws1.Range("A1").CurrentRegion
'CurrentRegion is the Range highlighted when we press Ctrl-A from A1
Set rng2 = ws2.Range("A1")
Application.ScreenUpdating = False
For Each rng In rng1
If rng.Column = 1 Then off = 0
If rng.Value = "X" Then
rng2.Value = rng.EntireRow.Cells(1, 1).Value
off = off + 1
rng2.Offset(0, off).Value = rng.EntireColumn.Cells(1, 1).Value
End If
'if we are looking at the last column of the Sheet1 data, and
'we have put something into the current row of Sheet2, move to
'the next row down (in Sheet2)
If rng.Column = rng1.Column And rng2.Value <> "" Then
Set rng2 = rng2.Offset(1, 0)
End If
Next rng
Application.ScreenUpdating = True
Set rng = Nothing
Set rng2 = Nothing
Set rng1 = Nothing
Set ws2 = Nothing
Set ws1 = Nothing
End Sub
I've also based in on the spreadsheet sample from the original post, where AA appears to be in cell A1.

Resources