Removing duplicates within a row - excel

Friends,
I have an excel table that repeats for a few thousand rows. 3 categories of columns, which may repeat, such as in the second row shown below
Is there a way to have excel cycle through a row and remove the duplicates within the row, so that it ultimately looks like the second table shown below?

I am not sure but is this what you are trying?
Option Explicit
Sub Sample()
Dim wsI As Worksheet
Dim lastRow As Long, lastCol As Long, i As Long, j As Long
Dim sVal1, sVal2, sVal3
'~~> Input Sheet
Set wsI = Sheets("Sheet1")
With wsI
lastRow = .Cells.Find(What:="*", After:=.Range("A1"), _
Lookat:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, MatchCase:=False).Row
lastCol = .Cells.Find(What:="*", After:=.Range("A1"), _
Lookat:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, MatchCase:=False).Column
For i = 1 To lastRow
sVal1 = .Cells(i, 1).Value
sVal2 = .Cells(i, 2).Value
sVal3 = .Cells(i, 3).Value
For j = 4 To lastCol Step 3
If .Cells(i, j).Value = sVal1 And _
.Cells(i, j + 1).Value = sVal2 And _
.Cells(i, j + 2).Value = sVal3 Then
.Cells(i, j).ClearContents
.Cells(i, j + 1).ClearContents
.Cells(i, j + 2).ClearContents
End If
Next j
Next i
End With
End Sub

Here's how i solved for it. Not the prettiest but it works:
Removing duplicates phones from row
Sub PhoneDedupByRow()
Dim Loopcounter As Long
Dim NumberOfCells As Long
Application.ScreenUpdating = False
'Range starting at A1
Worksheets("Sheet1").Activate
NumberOfCells = Range("A2", Range("A2").End(xlDown)).Count
For Loopcounter = 1 To NumberOfCells
'copies each section...I need to select the proper offsets for cells with the ph#'
Range(Range("A1").Offset(Loopcounter, 10), Range("A1").Offset(Loopcounter, 19)).Copy
'This is where the past/transpose will go...push it out to a far out column to avoid errors
Range("W1").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Application.CutCopyMode = False
'Knowing the range is 10 cells, i added 11 because gotospecial with no blanks causes an error
Range("W1:W11").Select
Selection.SpecialCells(xlCellTypeBlanks).Select
Selection.Delete Shift:=xlUp
ActiveSheet.Range("W1:W10").RemoveDuplicates Columns:=1, Header:=xlNo
ActiveSheet.Range("W1:W10").Select
Selection.Copy
Range(Range("A1").Offset(Loopcounter, 10), Range("A1").Offset(Loopcounter, 19)).Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Application.CutCopyMode = False
ActiveSheet.Range("W1:W10").Select
Selection.ClearContents
Next Loopcounter
Application.ScreenUpdating = True
End Sub

Related

Macro that adds new column and applies formula

I am very new to Excel, VBA and Macros... I am trying to create a macro that added column named "XXX" at last i.e. after the last column and then in that newly added column macro should find 2 columns...
1.Copy and paste the Header Format
.Cells(1, LastCol).Copy
.Cells(1, LastCol + 1).PasteSpecial Paste:=xlPasteFormats
Application.CutCopyMode = False
Apply Formula to "Response Time" column range
For i = 2 To LastRow
.Cells(i, LastCol + 1).Formula = .Cells(i, col2) - .Cells(i, col1)
Next i
Convert Decimal Number to Time format
.Cells(i, LastCol + 1).NumberFormat = "hh:mm:ss"
EDIT: [Full Code]
Option Explicit
Sub addformula()
Dim LastRow As Long
Dim LastCol As Long
Dim iRow As Long
Dim wsh As Worksheets
Dim col1 As Long, col2 As Long
With ActiveWorkbook.Worksheets("Formula testing")
'Find Full Out Gate at Inland or Interim Point (Destination)_actual and Full Out Gate at Inland or Interim Point (Destination)_recvd
With ActiveWorkbook.Worksheets("Formula testing")
col1 = .Cells.Find(What:="Full Out Gate at Inland or Interim Point (Destination)_actual", _
After:=Range("A1"), LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Column
col2 = .Cells.Find(What:="Full Out Gate at Inland or Interim Point (Destination)_recvd", _
After:=Range("A1"), LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Column
With ActiveWorkbook.Worksheets("Formula testing")
LastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
LastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
.Cells(1, LastCol + 1).Value = "Response Time"
' Copy Header Fromat
.Cells(1, LastCol).Copy
.Cells(1, LastCol + 1).PasteSpecial Paste:=xlPasteFormats
Application.CutCopyMode = False
' Apply Formula to "Response Time" column range
For i = 2 To LastRow
.Cells(i, LastCol + 1).Formula = .Cells(i, col2) - .Cells(i, col1)
.Cells(i, LastCol + 1).NumberFormat = "hh:mm:ss"
Next i
End With
End With
End With
ActiveWorkbook.Worksheets("Formula Testing").UsedRange.Columns.AutoFit
End Sub
I have changed your formula line to below line of code.
Range(Cells(2, LastCol + 1).Address & ":" & Cells(LastRow, LastCol + 1).Address).Formula = "=" & Cells(2, col2).Address(0, 0) & "-" & Cells(2, col1).Address(0, 0)
Please try the below code.
Option Explicit
Sub addformula()
Dim LastRow As Long
Dim LastCol As Long
Dim iRow As Long
Dim wsh As Worksheets
Dim col1 As Long, col2 As Long
With ActiveWorkbook.Worksheets("Formula testing")
With ActiveWorkbook.Worksheets("Formula testing")
col1 = .Cells.Find(What:="Full Out Gate at Inland or Interim Point (Destination)_actual", _
After:=Range("A1"), LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Column
col2 = .Cells.Find(What:="Full Out Gate at Inland or Interim Point (Destination)_recvd", _
After:=Range("A1"), LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Column
With ActiveWorkbook.Worksheets("Formula testing")
LastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
LastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
.Cells(1, LastCol + 1).Value = "Response Time"
Range(Cells(2, LastCol + 1).Address & ":" & Cells(LastRow, LastCol + 1).Address).Formula = "=" & Cells(2, col2).Address(0, 0) & "-" & Cells(2, col1).Address(0, 0)
End With
End With
End With
ActiveWorkbook.Worksheets("Formula Testing").UsedRange.Columns.AutoFit
End Sub

transpose dynamic range exel VBA

having 25 columns and n number rows in sheet Input_Excel as in the image "DATA" and transposing the same into another sheet as in the image "Output" in my requited specific format . My code is working perfectly when the input_excel having minimal data and giving expected output where as the data being more than 2600 is giving bad output as in the image "Wrong"
I am hanging and struggling a lot to fix the issue. please help me to find out the problem in my below code. is there any maximum limit in handling arrays in excel VBA?
Correct me if am dealing any wrong method/calling. will be a great help and thanks in advance.
Dim ws As Worksheet
Dim toWs As Worksheet
Dim vDB, vR()
Dim strShName As Variant
Dim r As Long, i As Long, n As Long, lastRow As Long, cc As Long, req_id As String
Dim k As Integer, j As Integer
Dim sc As Range, lr As Long, lc As Long, rg As Range, myRange As Range
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
Application.ScreenUpdating = False
Set ws = Sheets("Input Excel")
Set sc = ws.Range("A1")
lr = sc.SpecialCells(xlCellTypeLastCell).Row
lc = sc.SpecialCells(xlCellTypeLastCell).Column
strShName = ActiveSheet.Name
If strShName = "Data" Then
Application.DisplayAlerts = False
Sheets("Data").Delete
Application.DisplayAlerts = True
End If
Sheets.Add.Name = "Data"
Columns("A:c").Select
Selection.NumberFormat = "#"
Range("A1").Select
Set rg = ws.Range("A1").CurrentRegion
Set toWs = Sheets("Data") '<~~ Result Sheet
ws.Activate
Range("D1:Y1").Select
Selection.NumberFormat = "0"
Range("A1").Select
toWs.Activate
vDB = ws.Range(sc, ws.Cells(lr, lc)).Value
r = UBound(vDB, 1)
cc = ws.Range(sc, ws.Cells(lr, lc)).Columns.Count
For i = 2 To r
If vDB(i, 1) <> "" Then ' row
For j = 4 To cc
n = n + 1
ReDim Preserve vR(1 To cc, 1 To n)
For k = 1 To 3
vR(k, n) = vDB(i, k)
Next k
vR(4, n) = vDB(1, j)
vR(5, n) = vDB(i, j)
Next j
End If
Next i
With toWs
.UsedRange.Offset(1).Clear
.Range("A2").Resize(n, 10) = WorksheetFunction.Transpose(vR)
End With
Range("A3:C3").Select
Selection.Copy
Range("A2").Select
ActiveCell.PasteSpecial
Range("A1").Value = "Sales Org"
Range("B1").Value = "Soldto"
Range("C1").Value = "TE Part Number"
Range("D1").Value = "Demand_Date"
Range("E1").Value = "Values"
toWs.Select
lastRow = Cells(Rows.Count, "A").End(xlUp).Row
Set myRange = Range("E2:E" & lastRow)
myRange.Select
On Error GoTo eh
Selection.SpecialCells(xlCellTypeBlanks).Select
Selection.EntireRow.Delete
eh:
lastRow = Cells(Rows.Count, "A").End(xlUp).Row
Set myRange = Range("d2:d" & lastRow)
Range("J1").Select
ActiveCell.FormulaR1C1 = "=IFERROR(FIND(""."",R[1]C[-6],1),0)"
Range("J1").Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
If Range("J1").Value > 0 Then
myRange.Select
Selection.Replace What:=".", Replacement:="/", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=True
End If
Range("J1").Select
Selection.ClearContents
Columns("E:E").Select
Selection.Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
Range("E2").Select
ActiveCell.FormulaR1C1"=
DAY(RC[-1])&""/""&MONTH(RC[-1])&""/""&YEAR(RC[-1])"
lastRow = Cells(Rows.Count, "A").End(xlUp).Row
Set myRange = Range("E2:E" & lastRow)
myRange.Select
Selection.FillDown
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone,
SkipBlanks:=False, Transpose:=False
Range("D1").Select
Application.CutCopyMode = False
Selection.Copy
Range("E1").Select
ActiveSheet.Paste
Columns("D:D").Select
Application.CutCopyMode = False
Selection.Delete Shift:=xlToLeft
Range("f2").Select
ActiveCell.FormulaR1C1 = "=IF(RC[-5]=""NA"",RC[-5],IF(LEN(RC[-5])=
2,CONCAT(""00"",RC[-5]),IF(LEN(RC[-5])=3,
CONCAT(0,RC[-5]),IF(LEN(RC[-5])=1,CONCAT(""000"",RC[-5]),RC[-5]))))"
lastRow = Cells(Rows.Count, "A").End(xlUp).Row
Set myRange = Range("F2:F" & lastRow)
myRange.Select
Selection.FillDown
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone,
SkipBlanks:=False, Transpose:=False
myRange.Select
Selection.Copy
Range("A2").Select
ActiveSheet.Paste
Columns("F:f").Select
Application.CutCopyMode = False
Selection.Delete Shift:=xlToLeft
Dim v As Integer
Range("A1").Select
Range(Selection, Selection.End(xlToRight)).Select
Range(Selection, Selection.End(xlDown)).Select
Range("A:E").EntireColumn.AutoFit
req_id = InputBox("Please enter request ID which is generated in your
application")
If req_id = "" Then
Application.DisplayAlerts = False
Sheets("Data").Delete
Application.DisplayAlerts = True
End If
Sheets("SaveFile").Select
End If
Range("F1").Select
ActiveCell.FormulaR1C1 = "Case_ID"
Range("F2").Select
lastRow = Cells(Rows.Count, "A").End(xlUp).Row
Set myRange = Range("F2:F" & lastRow)
myRange.Value = req_id
lastRow = Cells(Rows.Count, "A").End(xlUp).Row
Set myRange = Range("A1:F" & lastRow)
myRange.Select
Dim t As Integer
If t = 0 Then
Dim tbl As ListObject
Set tbl = ActiveSheet.ListObjects.Add(xlSrcRange, Selection, , xlYes)
tbl.TableStyle = "TableStyleMedium15"
End If
t = 1
Set myRange = Range("A2:B" & lastRow)
myRange.Replace What:="NA", Replacement:="", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
Range("D1").Value = "Demand_Date"
Dim DTAddress As String
DTAddress = CreateObject("WScript.Shell").SpecialFolders("Desktop") & "\"
ActiveWorkbook.SaveAs Filename:=DTAddress & req_id &
"_Upload_LTF_Monthly", FileFormat:=6
MsgBox "Please check file is saved in your desktop and upload the same
desktop saved file"
ws.Activate
Range("D1:Y1").Select
Selection.NumberFormat = "mmm-yy"
Range("A1").Select
toWs.Activate
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
Application.ScreenUpdating = True
'ActiveWorkbook.Close False
End Sub
DATA
Output
Wrong
Transpose Data Range Using Arrays
Adjust the values in the constants section (Source, Target and Other).
I've added the headers to be copied to column "H". If you don't want them copied, remove the 3rd element (, "H") in tgtCols and delete the line Target(2)(k, 1) = Source(1, j).
The Code
Option Explicit
Sub transposeDataOnly()
' Source
Const srcName As String = "Input_Excel"
Const srcFirstCell As String = "A1"
Const srcFirstCol As Long = 3
' Target
Const tgtName As String = "Data"
Dim tgtCols As Variant
tgtCols = VBA.Array("C", "E", "H") ' 'VBA' ensures zero-based.
Const tgtFirstRow As Long = 2
' Other
Dim wb As Workbook
Set wb = ThisWorkbook ' The workbook containing this code.
' Write values from Source Range to Source Array.
Dim src As Worksheet
Set src = wb.Worksheets(srcName)
Dim Source As Variant
Source = src.Range(srcFirstCell).CurrentRegion.Value
' Define Jagged Target Array.
Dim ubC As Long: ubC = UBound(tgtCols)
Dim Target As Variant: ReDim Target(0 To ubC)
Dim ubS1 As Long: ubS1 = UBound(Source, 1)
Dim ubS2 As Long: ubS2 = UBound(Source, 2)
Dim Help As Variant
ReDim Help(1 To (ubS1 - 1) * (ubS2 - srcFirstCol), 1 To 1)
Dim j As Long ' Columns Array Element Counter, Source Array Columns Counter
For j = 0 To ubC
Target(j) = Help
Next j
' Write values from Source Array to arrays of Jagged Target Array.
Dim i As Long ' Source Array Rows Counter
Dim k As Long ' Arrays of Jagged Target Array Rows Counter
For i = 2 To ubS1
If Not IsEmpty(Source(i, srcFirstCol)) Then
For j = srcFirstCol + 1 To ubS2
If Not IsEmpty(Source(i, j)) Then
k = k + 1
Target(0)(k, 1) = Source(i, srcFirstCol) ' TE Part Number
Target(1)(k, 1) = Source(i, j) ' Values
Target(2)(k, 1) = Source(1, j) ' Headers
End If
Next j
End If
Next i
' Write values from Jagged Target Array to Target Range.
Dim tgt As Worksheet
Set tgt = wb.Worksheets(tgtName)
'tgt.Cells.ClearContents
For j = 0 To ubC
tgt.Cells(tgtFirstRow, tgtCols(j)).Resize(k).Value = Target(j)
Next j
End Sub

How do I copy from each value from a column to specific cell?

I am trying to copy and paste these values into a format our software understands. The order of the number column doesn't change but the location does every time. It could be starting everywhere on A1 for example: 15 is now on A2 but could be on A56 next time.
The numbers
Example of the file:
I am new to vba and this is what I have written so far but this is not efficient at all.
Because the columns never change, and only the rows. I have used find to find the value and move one cell down then copy and paste it into the format on the AU column. The format is as shown:
The only way I can think of is by trying this.
Cells.Find(What:="ex1", After:=ActiveCell, LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False).Activate
ActiveCell.Offset(1, 0).Select
Selection.Copy
Range("AU1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
I hoped this is possible using a loop or a more efficient way to copy those values. The end result needs to look like the format.
This is a very quick way to do it using arrays which make the processing a lot faster
Option Explicit
Public Sub demo()
Dim InArr As Variant, OutArr As Variant, headers As Variant
Dim i As Long, j As Long, OutArrCounter As Long
' Update with your sheet reference
With ActiveSheet
headers = Application.Transpose(Application.Transpose(.Range(.Cells(1, 1), .Cells(1, 9)).Value2))
InArr = .Range(.Cells(2, 1), .Cells(.Cells(.Rows.Count, 1).End(xlUp).Row, .Cells(1, .Columns.Count).End(xlToLeft).Column)).Value2
ReDim OutArr(1 To 4, 1 To UBound(InArr, 1) * (UBound(InArr, 2)))
For i = LBound(InArr, 1) To UBound(InArr, 1)
For j = LBound(headers) + 1 To UBound(headers)
OutArrCounter = OutArrCounter + 1
OutArr(1, OutArrCounter) = 1
OutArr(2, OutArrCounter) = InArr(i, 1)
OutArr(3, OutArrCounter) = headers(j)
OutArr(4, OutArrCounter) = IIf(InArr(i, j) = vbNullString Or Trim(InArr(i, j)) = "-", 0, InArr(i, j))
Next j
Next i
ReDim Preserve OutArr(1 To 4, 1 To OutArrCounter)
' Update with your destination
.Cells(1, 44).Resize(UBound(OutArr, 2), UBound(OutArr, 1)).Value2 = Application.Transpose(OutArr)
End With
End Sub
Try this. I haven't done column AR as not sure if that is 1 all the way down. Also, pending clarification of comment above about dashes, may need some tweaking.
Sub x()
Dim r As Long, c As Long
c = Range("A1").CurrentRegion.Columns.Count
Application.ScreenUpdating = False
For r = 2 To Range("A" & Rows.Count).End(xlUp).Row
Cells(r, "A").Copy
Range("AS" & Rows.Count).End(xlUp)(2).Resize(c - 1).PasteSpecial Transpose:=True
Cells(1, 2).Resize(, c - 1).Copy
Range("AT" & Rows.Count).End(xlUp)(2).Resize(c - 1).PasteSpecial Transpose:=True
Cells(r, 2).Resize(, c - 1).Copy
Range("AU" & Rows.Count).End(xlUp)(2).Resize(c - 1).PasteSpecial Transpose:=True
Next r
Application.ScreenUpdating = True
End Sub

Find cell with value, offset and copy range then paste basing data's date, then loop to findnext

With th following Excel Sheet.
I'm trying to do the following:
Find the cell with Value, let's say "Sam", in range("B17:B25")
Offset(0,5).resize(,8).copy
Find the Date value of the Data row, and paste Data to range("B4:M4") according to the data's Date.
Loop to find next.
Here is what I got so far, don't know how to loop:
Sub getDat()
Dim myFind As Range
Dim pasteLoc As Range
Dim payee, pasteMon As String
Range("B5:M12").ClearContents
With Sheet3.Cells
payee = Range("B2").Text
Set myFind = .Find(What:=payee, After:=Range("B16"), LookIn:=xlValues, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=True, SearchFormat:=False)
If Not myFind Is Nothing Then
myFind.Offset(0, 3).Resize(, 8).Copy
pasteMon = myFind.Offset(0, 1).Text
With Range("B4:M4")
Set pasteLoc = .Find(What:=pasteMon, LookIn:=xlValues, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=True, SearchFormat:=False)
If Not pasteLoc Is Nothing Then
pasteLoc.Offset(1, 0).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=True
End If
End With
End If
End With
End Sub
Here is simplified version (not tested)
Sub getDat()
Range("B5:M12").ClearContents
Dim c As Range, r As Range
For Each c in Range("B16").CurrentRegion.Columns(1).Cells
If c = Range("B2") Then
Set r = Range("B4:M4").Find(c(, 2))
If Not r Is Nothing Then
r(2).Resize(8) = Application.Transpose(c(, 4).Resize(, 8))
End If
End If
Next
End Sub
Something like this For loop would work as well:
Sub getDat()
Dim payee As String
Dim lastrow As Long
lastrow = Cells(Rows.Count, "B").End(xlUp).Row
payee = Range("B2").Value
Range("B5:M12").ClearContents
For x = 17 To lastrow
If Cells(x, 2).Value = payee Then
For y = 2 To 13
If Cells(4, y).Value = Cells(x, 3).Value Then
Range("E" & x & ":L" & x).Copy
ActiveSheet.Range(Cells(5, y), Cells(12, y)).PasteSpecial Transpose:=True
Exit For
End If
Next y
End If
Next x
End Sub

Fetching the column data from different sheets and making it as row data in MainSheet

Following is the code to fetch the data from the last column of each sheet and display it in the sheet "MainSheet". Since the last column has merged cells this code also deletes the cells in between
This code displays the data as verical view in the MainSheet and I want to make it horizontal i.e data from the last column of each sheet should be fetched to the rows in the MainSheet and also the merged cells should be taken care of
Sub CopyLastColumns()
Dim cnt As Integer, sht As Worksheet, mainsht As Worksheet, col As Integer, rw As Integer
ActiveSheet.Name = "MainSheet"
Set mainsht = Worksheets("MainSheet")
cnt = 1
For Each sht In Worksheets
If sht.Name <> "MainSheet" Then
sht.Columns(sht.Range("A1").CurrentRegion.Columns.Count).Copy
mainsht.Columns(cnt).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
mainsht.Cells(150, cnt) = sht.Range("A2")
cnt = cnt + 1
End If
Next sht
With mainsht
For col = 1 To cnt
For rw = .Cells(65536, col).End(xlUp).row To 1 Step -1
If .Cells(rw, col) = "" Then
.Cells(rw, col).Delete Shift:=xlUp
End If
Next rw
Next col
End With
End Sub
Thanks in advance
This code copies the last column from every sheet and pastes them as rows in the MainSheet keeping the merged cells intact.
Option Explicit
Sub Sample()
Dim wsI As Worksheet, wsO As Worksheet
Dim wsOLrow As Long, wsILrow As Long, wsILcol As Long
On Error GoTo Whoa
Application.ScreenUpdating = False
Set wsO = Sheets("MainSheet")
wsOLrow = wsO.Cells.Find(What:="*", _
After:=wsO.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row + 1
For Each wsI In ThisWorkbook.Sheets
If wsI.Name <> wsO.Name Then
With wsI
wsILrow = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
wsILcol = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
.Range(Split(Cells(, wsILcol).Address, "$")(1) & "1:" & _
Split(Cells(, wsILcol).Address, "$")(1) & _
wsILrow).Copy .Range(Split(Cells(, wsILcol + 1).Address, "$")(1) & "1:" & _
Split(Cells(, wsILcol + 1).Address, "$")(1) & wsILrow)
.Activate
With .Range(Split(Cells(, wsILcol + 1).Address, "$")(1) & "1:" & _
Split(Cells(, wsILcol + 1).Address, "$")(1) & wsILrow)
.UnMerge
.Cells.SpecialCells(xlCellTypeBlanks).Delete shift:=xlUp
End With
wsILrow = .Range(Split(Cells(, wsILcol).Address, "$")(1) & Rows.Count).End(xlUp).Row
With .Range(Split(Cells(, wsILcol + 1).Address, "$")(1) & "1:" & _
Split(Cells(, wsILcol + 1).Address, "$")(1) & wsILrow)
.Copy
wsO.Cells(wsOLrow, 1).PasteSpecial Paste:=xlPasteAll, _
Operation:=xlNone, SkipBlanks:=False, Transpose:=True
.Delete
End With
wsOLrow = wsOLrow + 1
End With
End If
Next
LetsContinue:
Application.ScreenUpdating = True
MsgBox "Done"
Exit Sub
Whoa:
MsgBox Err.Description
Resume LetsContinue
End Sub

Resources