I need to transpose vertical data from column B to horizontal data.
My table looks like this:
85.98 | | | | | |
-------|--------|--------|--------|--------|--------|
97.62 | | | | | |
-------|--------|--------|--------|--------|--------|
100.00 | | | | | |
-------|--------|--------|--------|--------|--------|
100.00 | | | | | |
-------|--------|--------|--------|--------|--------|
| | | | | |
-------|--------|--------|--------|--------|--------|
89.81 | | | | | |
-------|--------|--------|--------|--------|--------|
78.70 | | | | | |
-------|--------|--------|--------|--------|--------|
100.00 | | | | | |
-------|--------|--------|--------|--------|--------|
| | | | | |
-------|--------|--------|--------|--------|--------|
94.32 | | | | | |
-------|--------|--------|--------|--------|--------|
| | | | | |
-------|--------|--------|--------|--------|--------|
| | | | | |
-------|--------|--------|--------|--------|--------|
| | | | | |
-------|--------|--------|--------|--------|--------|
90.91 | | | | | |
-------|--------|--------|--------|--------|--------|
0.00 | | | | | |
-------|--------|--------|--------|--------|--------|
88.54 | | | | | |
-------|--------|--------|--------|--------|--------|
76.96 | | | | | |
-------|--------|--------|--------|--------|--------|
94.32 | | | | | |
-------|--------|--------|--------|--------|--------|
89.11 | | | | | |
-------|--------|--------|--------|--------|--------|
And I want it to look like this:
85.98 | 97.62 | 100.00 | 100.00 | | |
-------|--------|--------|--------|--------|--------|
89.81 | 78.70 | 100.00 | | | |
-------|--------|--------|--------|--------|--------|
94.32 | | | | | |
-------|--------|--------|--------|--------|--------|
| | | | | |
-------|--------|--------|--------|--------|--------|
90.91 | 0.00 | 88.54 | 76.96 | 94.32 | 89.11 |
I am using the following code:
Sub Transpose()
Dim t As Range, u As Range
c = ActiveCell.Column
fr = ActiveCell.Row
lr = Cells(Rows.Count, c).End(xlUp).Row
r = fr
Do
Set t = Cells(r, c)
Set u = t.End(xlDown)
Range(t, u).Copy
t.Offset(, 1).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=True
r = u.End(xlDown).Row
Loop While r < lr
Application.CutCopyMode = False
End Sub
The problem is .End(xlDown) doesn't work because there are single rows of data. Is there a solution for this?
What you are trying to achieve can be accomplished with this...
Sub TransposeData()
Dim lr As Long
Dim rng As Range
Application.ScreenUpdating = False
lr = Cells(Rows.Count, 3).End(xlUp).Row
'Change the first row as required. C1 in the below line assumes that the data start from Row1 in Column C.
For Each rng In Range("C1:C" & lr).SpecialCells(xlCellTypeConstants, 1).Areas
rng.Copy
rng.Cells(1).Offset(0, 1).PasteSpecial xlPasteAll, Transpose:=True
Next rng
Application.CutCopyMode = 0
Application.ScreenUpdating = True
End Sub
I have sheet with data, i want to get data in other sheet but with conditions. This is what my source data looks like:
-------------------------------------------------
| Cell A | Cell B | Cell C | Cell D|Cell E |
|------------------------------------------------|
| Sku |Order_ID|Customer_ID | Price |Status |
|------------------------------------------------|
| TW22 | 123 | 1 |221 | D |
|------------------------------------------------|
| TS44 | 124 | 2 |221 | D |
|------------------------------------------------|
| Ts11-ab | 33 | 3 |211 | D |
|------------------------------------------------|
| Ts11 | 231 | 4 |231 | D |
|------------------------------------------------|
| Ts11-ab | 33 | 3 |211 | R |
|------------------------------------------------|
| Ts11 | 231 | 4 |231 | R |
|------------------------------------------------|
If there are two rows with the same order ID I want to remove the first row (with status D) and only keep the second row (status R). The desired output for the above data would be:
--------------------------------------------------
| Cell A | Cell B | Cell C | Cell D|Cell E |
|------------------------------------------------|
| Sku |Order_ID|Customer_ID | Price |Status |
|------------------------------------------------|
| TW22 | 123 | 1 |221 | D |
|------------------------------------------------|
| TS44 | 124 | 2 |221 | D |
|------------------------------------------------|
| Ts11-ab | 33 | 3 |211 | R |
|------------------------------------------------|
| Ts11 | 231 | 4 |231 | R |
|------------------------------------------------|
This is the formula I tried:
=IFERROR(INDEX(Sheet1!E$2:E$5,(MATCH($B2,Sheet1!B$2:B$5,0))),-1)
got answer from aditya .. thanks here is what he provide
Sub copy_sheet()
Dim raw_data, new_data As Worksheet
Set raw_data = ThisWorkbook.Sheets("raw_data")
Set new_data = ThisWorkbook.Sheets("new_data")
raw_data.Activate
Range("A1:E1").Select
Range(Selection, Selection.End(xlDown)).Copy
new_data.Activate
Range("A1").PasteSpecial xlPasteValues
Range("A1").Sort key1:=Range("E1"), order1:=xlDescending, Header:=xlYes
Range("A1:E1").Select
Range(Selection, Selection.End(xlDown)).RemoveDuplicates Columns:=Array(1, 2, 3), Header:=xlYes
Range("A1").Sort key1:=Range("E1"), order1:=xlAscending, Header:=xlYes
Range("A1").Activate
End Sub
I do not know what you have already tried, but as I understand it the row with "R" always comes after the row with "D", right? You could go through your table in reverse order and remember all rows with an R. In pseudo code something like:
size = yourTable.Rows.Count
Dim col As New Collection
For column = size To 1 Step -1
If StatusOfCurrentRow = "R" Then
Copy Row to Sheet2
col.Add Value of Sku
Else
If SkuOfCurrentRow not in col
Copy Row to Sheet2
End If
End If
Next
I have a table looks like this:
+---+---+---+---+---+---+
| | a | b | c | d | e |
+---+---+---+---+---+---+
| f | 1 | 3 | 3 | 2 | 2 |
| g | 3 | 1 | 3 | 2 | 1 |
| h | 3 | 3 | 1 | 3 | 3 |
| i | 2 | 2 | 3 | 1 | 2 |
| j | 2 | 1 | 3 | 2 | 1 |
+---+---+---+---+---+---+
And I want it to be like this:
+---+---+---+
| a | f | 1 |
| a | g | 3 |
| a | h | 3 |
| a | i | 2 |
| a | j | 2 |
| b | f | 3 |
| b | g | 1 |
| b | h | 3 |
| b | i | 2 |
| b | j | 1 |
| c | f | 3 |
| c | g | 3 |
| c | h | 1 |
| c | i | 3 |
| c | j | 3 |
| d | f | 2 |
| d | g | 2 |
| d | h | 3 |
| d | i | 1 |
| d | j | 2 |
| e | f | 2 |
| e | g | 1 |
| e | h | 3 |
| e | i | 2 |
| e | j | 1 |
+---+---+---+
I'm using this macro:
Sub ColumnCopy()
Sheets("test").Cells.Clear
Dim tRow As Long
Dim source As String
Dim target As String
source = "test1" 'Set your source sheet here
target = "test" 'Set the Target sheet name
'tRow = 2 'Define the start row of the target sheet
'Get Last Row and Column
lastRow = Sheets(source).Range("A" & Rows.Count).End(xlUp).Row
lastCol = Sheets(source).Cells(1, Columns.Count).End(xlToLeft).Column
tRow = 2
colBase = 2
Do While colBase < lastCol
For iRow = 2 To lastRow
Sheets(target).Cells(tRow, 1) = Sheets(source).Cells(1, colBase)
Sheets(target).Cells(tRow, 2) = Sheets(source).Cells(iRow, 1)
Sheets(target).Cells(tRow, 3) = Sheets(source).Cells(iRow, colBase)
tRow = tRow + 1
Next iRow
colBase = colBase + 1
Loop
End Sub
But i'm getting result missing the "column e":
+---+---+---+
| a | f | 1 |
| a | g | 3 |
| a | h | 3 |
| a | i | 2 |
| a | j | 2 |
| b | f | 3 |
| b | g | 1 |
| b | h | 3 |
| b | i | 2 |
| b | j | 1 |
| c | f | 3 |
| c | g | 3 |
| c | h | 1 |
| c | i | 3 |
| c | j | 3 |
| d | f | 2 |
| d | g | 2 |
| d | h | 3 |
| d | i | 1 |
| d | j | 2 |
+---+---+---+
I can't find what's causing this issue. I'm really new to excel macro.
Thanks for the help!
change this: Do While colBase < lastCol to this:
Do While colBase <= lastCol
I currently have the following formula inside a column of cells but as you can see its large and messy and I am afraid that the cells might get edited by someone working in the workbook accidentally.
So I have tried to code it in VBA but I keep getting a Run-Time Error '91'. And I am stuck as to what I need to adjust to make it operate.
thanks for your help
Current Formula
=IF(B7=$H$5,"1",IF(B7=$H$6,".75",IF(B7=$H$7,".75",IF(B7=$H$8,"1",IF(B7=$H$9,"1",IF(B7=$H$10,"1",IF(B7=$H$11,".5",IF(B7=$H$12,".5",IF(B7=$H$13,".5",IF(B7=$H$14,".5",IF(B7=$H$15,"1",IF(B7=$H$16,".75",IF(B7=$H$17,"1",IF(B7=$H$18,"1",IF(B7=$H$19,".75",IF(B7=$H$20,"1",IF(B7=$H$21,"1",IF(B7=$H$22,"1",IF(B7=$H$23,"1",IF(B7=$H$24,".75",IF(B7=$H$25,"1",IF(B7=$H$26,".75",IF(B7=$H$27,".5",IF(B7=$H$28,"1",IF(B7=$H$29,".75",IF(B7=$H$30,".5",IF(B7=$H$31,"1",IF(B7=$H$32,"1",IF(B7=$H$33,"1",IF(B7=$H$34,".5",IF(B7=$H$35,"1",IF(B7=$H$36,".25",IF(B7=$H$37,"1",IF(B7=$H$38,"1",IF(B7=$H$39,"1",IF(B7=$H$40,"1",IF(B7=$H$41,"1",IF(B7=$H$42,"1",IF(B7=$H$43,"1",IF(B7=$H$44,"1",IF(B7=$H$45,"1",IF(B7=$H$46,"1",IF(B7=$H$47,"1",IF(B7=$H$48,"1",IF(B7=$H$49,"1",IF(B7=$H$50,".5",IF(B7=$H$51,"1",IF(B7=$H$52,".25",IF(B7=$H$53,"1",IF(B7=$H$54,".75",IF(B7=$H$55,"1",IF(B7=$H$56,"1",IF(B7=$H$57,"1")))))))))))))))))))))))))))))))))))))))))))))))))))))
My attempt at turning it into VBA code
Sub Macro()
Dim Whole as long
Dim Third as long
Dim half as long
Dim quarter as long
Dim lookat as range
Dim answer as range
Whole = 1
third = .75
Half = .5
Quarter = .25
Lookat = Worksheets("sheet1".Range("B2:B300")
Answer = worksheets("Sheet1").range("C2:C300")
If Lookat = "AAAA" Or "AAAB" Or "AAAC" Or "AAAD" Or "AAAE" Or "AAAF" Or "AAAG" Or "AAAH" Or "AAAI" Or "AAAJ" Or "AAAK" Or "AAAL" Or "AAAM" Or "AAAN" Or "AAAO" Or "AAAP" Or "AAAQ" Or "AAAR" Or "AAAS" Or "AAAT" Or "AAAU" Or "AAAV" _
Or "AAAW" Or "AAAX" Or "AAAY" Or "AAAZ" Or "BBBA" Or "BBBB" Or "BBBC" Or "BBBD" Or "BBBE" Or "BBBF" Or "BBBG" Then
Answer.value=whole
ElseIf Lookat = "AAA" Or "AAB" Or "AAC" Or "AAD" Or "AAE" Or "AAF" Or "AAG" Or "AAH" Then
Answer.Value = Third
ElseIf Lookat = "AA" Or "AB" Or "AC" Or "AD" Or "AE" Or "AF" Or "AG" Or "AH" Then
Answer.Value = Half
ElseIf Lookat = "A" Or "B" Then
Answer.Value = Quarter
end if
End Sub
1 Protect your Workbook Link or hide it in a worksheet
2 Create your DataBase (your 'H' column)
3 In 'I' Column put your Weight [whole, third, half, quarter]. Sample:
+---------+--------+
| COL 'H' | HEIGHT |
+---------+--------+
| 6 | 1 |
| 9 | 0,5 |
| 4 | 0,75 |
| 6 | 1 |
| 8 | 0,5 |
| 1 | 0,75 |
| 5 | 1 |
| 4 | 0,5 |
| 5 | 0,75 |
| 7 | 1 |
| 4 | 0,5 |
| 9 | 0,75 |
| 1 | 1 |
| 8 | 0,5 |
| 1 | 0,75 |
| 5 | 1 |
| 1 | 0,5 |
| 4 | 0,75 |
| 4 | 1 |
| 1 | 0,5 |
| 7 | 0,75 |
+---------+--------+
4 Change your current formula to:
=VLOOKUP(B8,H:I,2,FALSE)
PS: You can try to name your Database to make your code better to understand Link.
Something like this may suit:
+----+-----+------+
| | A | B |
+----+-----+------+
| 1 | H10 | 1 |
| 2 | H14 | 0.5 |
| 3 | H15 | 1 |
| 4 | H16 | 0.75 |
| 5 | H18 | 1 |
| 6 | H19 | 0.75 |
| 7 | H23 | 1 |
| 8 | H24 | 0.75 |
| 9 | H25 | 1 |
| 10 | H26 | 0.75 |
| 11 | H27 | 0.5 |
| 12 | H28 | 1 |
| 13 | H29 | 0.75 |
| 14 | H30 | 0.5 |
| 15 | H33 | 1 |
| 16 | H34 | 0.5 |
| 17 | H35 | 1 |
| 18 | H36 | 0.25 |
| 19 | H49 | 1 |
| 20 | H5 | 1 |
| 21 | H50 | 0.5 |
| 22 | H51 | 1 |
| 23 | H52 | 0.25 |
| 24 | H53 | 1 |
| 25 | H54 | 0.75 |
| 26 | H57 | 1 |
| 27 | H7 | 0.75 |
+----+-----+------+
located in a sheet on its own in the same workbook and the array named say Vt of Workbook Scope.
This might then be used as the lookup table with a formula such as:
=VLOOKUP(A1,Vt,2)
where A1 contains a value such as "H10" for the purposes of this example.
It is important to sort A:B of the 'other' (to-be-hidden/protected) sheet in ascending order of ColumnA if to take advantage of a table that does not specifically equate every possible value. The lack of a fourth parameter in the VLOOKUP formula (though often causing problems!) means that an approximate match will be found where there is no exact match.
If I have a value from sqlDataReader as below:
| YEAR1 | NAM1 | CRDT1 | SEMER1 | YEAR2 | NAM2 | CRDT2 | SEMER2 |
-----------------------------------------------------------------------
| 1 | Name1 | 1 | 1 | 1 | Name10 | 1 | 2 |
| 1 | Name2 | 4 | 1 | 1 | Name5 | 4 | 2 |
| 1 | Name3 | 2 | 1 | 1 | Name6 | 3 | 2 |
| 1 | Name4 | 7 | 1 | 1 | Name7 | 6 | 2 |
| (null) | (null) | (null) | (null) | 1 | Name8 | 1 | 2 |
| (null) | (null) | (null) | (null) | 1 | Name9 | 1 | 2 |
| 2 | Name11 | 3 | 1 | 2 | Name14 | 2 | 2 |
| 2 | Name12 | 6 | 1 | 2 | Name15 | 1 | 2 |
| 2 | Name13 | 4 | 1 | 2 | Name16 | 1 | 2 |
| (null) | (null) | (null) | (null) | 2 | Name17 | 1 | 2 |
| 3 | Name18 | 5 | 1 | 3 | Name18 | 5 | 2 |
| 3 | Name19 | 1 | 1 | 3 | Name19 | 1 | 2 |
| 3 | Name20 | 1 | 1 | 3 | Name20 | 1 | 2 |
I like to merge year column to become only one column. If any columns is null then it will merge into one column and If any the current rows and the next rows is null then it will merge.
I want to output like this:
| YEAR1 | NAM1 | CRDT1 | SEMER1 | YEAR2 | NAM2 | CRDT2 | SEMER2 |
-----------------------------------------------------------------------
| | Name1 | 1 | 1 | | Name10 | 1 | 2 |
| 1 | Name2 | 4 | 1 | 1 | Name5 | 4 | 2 |
| | Name3 | 2 | 1 | | Name6 | 3 | 2 |
| | Name4 | 7 | 1 | | Name7 | 6 | 2 |
| (null) | | Name8 | 1 | 2 |
| | | Name9 | 1 | 2 |
| | Name11 | 3 | 1 | | Name14 | 2 | 2 |
| 2 | Name12 | 6 | 1 | 2 | Name15 | 1 | 2 |
| | Name13 | 4 | 1 | | Name16 | 1 | 2 |
| (null) | | Name17 | 1 | 2 |
| | Name18 | 5 | 1 | | Name18 | 5 | 2 |
| 3 | Name19 | 1 | 1 | 3 | Name19 | 1 | 2 |
| | Name20 | 1 | 1 | | Name20 | 1 | 2 |
How can I create a html table which can output the result as above in vb.net?
Spin through the result set adding a new table row for each record. Use variables to keep track of when you need to add all of your cells (some with rowspans) or just the ones displayed on every row. Here's 90% of the code for you. You should be able to figure out the rest.
'Convert DataReader into DataTable.
Dim dtResults As New DataTable
dtResults.Load(drResults)
'You can define this in your .Aspx
Dim tblStudents As New Table
'These will help you with your table building logic.
Dim intCurrentYear1 As Integer = 0
Dim intRowSpan As Integer = 0
Dim bolDetermineRowSpan = True
For intRowCursor As Integer = 0 To (dtResults.Rows.Count - 1)
If bolDetermineRowSpan Then
'First get the current year (Nulls will be set to 0, but not displayed as such.)
If dtResults.Rows(intRowCursor).Item("Year1") Is DBNull.Value Then
intCurrentYear1 = 0
Else
intCurrentYear1 = CInt(dtResults.Rows(intRowCursor).Item("Year1"))
End If
If intCurrentYear1 > 0 Then
'Get the total number of records with this year, so we know how many cells to merge.
intRowSpan = (From d As DataRow In dtResults.Rows _
Where Not d.Item("Year1") Is DBNull.Value AndAlso _
CInt(d.Item("Year1")) = intCurrentYear1).Count()
Else
'Figure out how many null records until the next year, so we know how many to merge.
Dim bolNextYear As Boolean = False
Dim intTempCursor As Integer = intRowCursor + 1
intRowSpan = 1
Do Until bolNextYear = True OrElse intTempCursor = dtResults.Rows.Count
If Not dtResults.Rows(intTempCursor).Item("Year1") Is DBNull.Value Then
bolNextYear = True
End If
intTempCursor += 1
intRowSpan += 1
Loop
End If
End If
Dim tr As New TableRow
If intCurrentYear1 > 0 Then
If bolDetermineRowSpan = True Then
'Add all cells to this Table Row, using RowSpan property to merge desired fields.
Dim tdYear1 As New TableCell
tdYear1.RowSpan = intRowSpan
tdYear1.Text = intCurrentYear1
tdYear1.VerticalAlign = VerticalAlign.Middle
tr.Cells.Add(tdYear1)
Dim tdName1 As New TableCell
tdName1.Text = CStr(dtResults.Rows(intRowCursor).Item("NAM1"))
tr.Cells.Add(tdName1)
'Add the rest of your cells here (omitted).
'Update this variable to keep sound logic.
bolDetermineRowSpan = False
Else
'Do not add the Year1 Cell because of RowSpan/"Merging".
Dim tdName1 As New TableCell
tdName1.Text = CStr(dtResults.Rows(intRowCursor).Item("NAM1"))
tr.Cells.Add(tdName1)
'Do for rest of cells.
'Update this variable to keep sound logic.
bolDetermineRowSpan = False
End If
Else
'Same logic as other half of this If Statement block, just doing more
'cells with RowSpans. (These are the null records.)
If bolDetermineRowSpan = True Then
'Add all cells (with rowspans)
Else
'Add just cells that are displayed on every row.
End If
End If
'Add the row to the table.
tblStudents.Rows.Add(tr)
'Do we need to reset our boolean flag to determine row span?
If bolDetermineRowSpan = False AndAlso dtResults.Rows.Count < (intRowCursor + 1) AndAlso _
Not dtResults.Rows(intRowCursor + 1).Item("Year1") Is DBNull.Value AndAlso _
dtResults.Rows(intRowCursor + 1).Item("Year1") <> intCurrentYear1 Then
bolDetermineRowSpan = True
End If
Next