Sheet size and memory usage in excel - vba

Each worksheet is getting to large memory wise, I found that if I copied the rows and columns that had data in them and put into a new sheet then deleted the old one and renamed the new one the same name I could shrink my workbook size by 1 to 3 megabytes, its not a memory problem exactly but my code seems to run quicker when the book is smaller. I downloaded a program that is sopposed to delete all unused cells but cannot get it to work.
Sub Reset_LastCell()
' http://support.microsoft.com/default...&Product=xlw2K
' Save the lastcell and start there.
Dim Sh As Worksheet
Dim A As Integer
For Each Sh In Worksheets
A = A + 1
If A >= 28 Then
Sh.Activate
Set lastcell = Cells.SpecialCells(xlLastCell)
' Set the rowstep and column steps so that it can move toward
' cell A1.
rowstep = -1
colstep = -1
' Loop while it can still move.
While (rowstep + colstep <> 0) And (lastcell.Address <> "$A$1")
' Test to see if the current column has any data in any
' cells.
If Application _
.CountA(Range(Cells(1, lastcell.Column), lastcell)) _
> 0 Then colstep = 0 'If data then stop the stepping
' Test to see if the current row has any data in any cells.
' If data exists, stop row stepping.
If Application _
.CountA(Range(Cells(lastcell.Row, 1), lastcell)) _
> 0 Then rowstep = 0
' Move the lastcell pointer to a new location.
Set lastcell = lastcell.Offset(rowstep, colstep)
' Update the status bar with the new "actual" last cell
' location.
Application.StatusBar = "Lastcell: " & lastcell.Address
Wend
' Clear and delete the "unused" columns.
With Range(Cells(1, lastcell.Column + 1), "IV65536")
Application.StatusBar = "Deleting column range: " & _
.Address
.Clear
.Delete
End With
' Clear and delete the "unused" rows.
With Rows(lastcell.Row + 1 & ":65536")
Application.StatusBar = "Deleting Row Range: " & _
.Address
.Clear
.Delete
End With
' Select cell A1.
' Reset the status bar to the Microsoft Excel default.
Application.StatusBar = False
If A >= 35 Then Exit Sub
Range("AI2").Select
End If
Next
End Sub

One very easy means of reducing the workbook size is to save the file as a .xlsb. All code and all functions continue to work exactely the same. The only limitation is that the workbook can no longer be opened by Libre Office and other open source spreadsheet applications.
I have found that it also helps to speed up calculations of formulas... it may help with code.
UPDATE
Your code works fine on my machine, the only thing I needed to do was add Dim to the code because i use Option Explicit. Add the following to your code at the top:
Dim lastcell As Range
Dim colstep As Long
Dim rowstep As Long

Related

VBA code works in debug mode but fails to run as macro

Hey i have a small problem that i can´t seam to solve... Im not the first to have this problem i found but none of the existing solutions worked on my code. so im stuck... The problem is that my code runs faster then what the functions can execute.
My code adds all worksheets that are of the same type together in a new sheet. And to indicate when how long every file is in the new sheet i want to change the interior of the last row to another color. My code can do that now but only in debug mode... and i don´t know how to "slow it down" so that i works whit my macro. Iv tried a delay function, DoEvent and adding a timer but none worked... Would really appreciate some tips on how to solve this or if there is a better way to do this. Thanks!
Sub MergeSheets()
Dim WorkSheetSource As Worksheet
Dim WorkSheetDestination As Worksheet
Dim RangeSource As Range
Dim RangeDestination As Range
Dim lngLastCol As Long
Dim lngSourceLastRow As Long
Dim lngDestinationLastRow As Long
Dim SheetName As String
Dim SkipSheets As String
'Set references up-front
Set WorkSheetDestination = ThisWorkbook.Worksheets("Import")
lngDestinationLastRow = LastOccupiedRowNum(WorkSheetDestination) '<~ defined below (and in Toolbelt)!
lngLastCol = LastOccupiedColNum(WorkSheetDestination) '<~ defined below (and in Toolbelt)!
'Set the initial destination range
Set RangeDestination = WorkSheetDestination.Cells(lngDestinationLastRow + 1, 1)
' (lngDestinationLastRow + 2) = what row to start adding on, 1 = start from column
' Skip this sheets ' the 2 makes a blank row between sheeeeets
SkipSheets = ("Import, Cover sheet, Control, Column description, Charts description")
'Loop through all sheets
For Each WorkSheetSource In ThisWorkbook.Worksheets ' Here i coud add a function where i can choose my Sheets?
DoEvents
'Make sure we skip the "Import" destination sheet!
If InStr(1, SkipSheets & ",", WorkSheetSource.Name & ",", vbTextCompare) = 0 Then
' Skip all Charts sheets
If InStr(WorkSheetSource.Name, "Status") Then
'Identify the last occupied row on this sheet
lngSourceLastRow = LastOccupiedRowNum(WorkSheetSource)
'Store the source data then copy it to the destination range
With WorkSheetSource
Set RangeSource = .Range(.Cells(3, 1), .Cells(lngSourceLastRow, lngLastCol)) ' 3 = what start row , 2 = how many columns
RangeSource.Copy Destination:=RangeDestination
End With
'Redefine the destination range now that new data has been added
LongDestinationLastRow = LastOccupiedRowNum(WorkSheetDestination)
Set RangeDestination = WorkSheetDestination.Cells(LongDestinationLastRow + 1, 1)
'LongDestinationLastRow.EntireRow.Interior.ColorIndex = 15
End If
' Find last row and give it colour
'Range("A" & Rows.Count).End(xlUp).Select
'ActiveCell.EntireRow.Interior.ColorIndex = 15
' don´t work... only in debugmode
End If
' **** Here the code works in debug mode but not in macro!*****
' Find last row and give it colour
Range("A" & Rows.Count).End(xlUp).Select
ActiveCell.EntireRow.Interior.ColorIndex = 15
'*************************************************************
Next WorkSheetSource
MsgBox "Done"
End Sub

Excel/VBA - Extracting a range of rows from a selected sheet to a new book

I'm trying to build a new VBA function for Excel. I've got a book of sheets with a front page that always loads first, on this page I've got a combo box that lists all the other sheets in the book and a nice extract button that will pull out the chosen sheet to a new book. (Thanks to those here who helped with that). Now I need a new function that will use the same combo box, but instead only extract a small subset of the chosen sheet.
Unfortunately, that subset isn't on the same rows for every sheet, nor is the number of rows the same (so one sheet, the subset might be 10 rows, on another it might be 12, on another it might be 20, etc etc etc).
On the plus side, there are merged rows (from column A to G) at the start and end of each subset - with specific text, which could be used to search for.
After some back and forth, I've got a better bit of code that I think is almost working:
Sub ZCPS_Extract()
Dim StartRow
Dim EndRow
Dim Zws As Worksheet
Dim wbkOriginal As Workbook
Set wbkOriginal = ActiveWorkbook
StartRow = 1
EndRow = 1
'sets site details into the header of the ZCPS checksheet
Worksheets(Sheet1.CmbSheet.Value).Range("B3").Value = Worksheets("front page").Range("E6")
Worksheets(Sheet1.CmbSheet.Value).Range("D3").Value = Worksheets("front page").Range("N6")
Worksheets(Sheet1.CmbSheet.Value).Range("F3").Value = Worksheets("front page").Range("K6")
Set Zws = Sheets(Sheet1.CmbSheet.Value)
'selects ZCPS block from select estate sheet
StartRow = (Zws.Cells.Find("**** ZCPS Installation").Row) + 1
EndRow = (Zws.Cells.Find("**** Aztec Hotfixes").Row) - 1
'copy above block and paste into Z-MISC starting at row 5
Worksheets(Sheet1.CmbSheet.Value).Range(Cells(StartRow, 1), Cells(EndRow, 7)).Copy Worksheets("Z-MISC").Range("A5")
With ActiveWorkbook.Sheets("Z-MISC")
.Copy
ActiveWorkbook.SaveAs _
"C:\temp\" _
& ActiveWorkbook.Sheets("Z-MISC").Cells(3, 2).Text _
& " ZCPS CheckSheet " _
& Format(Now(), "DD-MM-YY") _
& ".xlsm", _
xlOpenXMLWorkbookMacroEnabled, , , , False
End With
'code to close the original workbook to prevent accidental changes etc
Application.DisplayAlerts = False
wbkOriginal.Close
Application.DisplayAlerts = True
End Sub
It's error on the line for copying, I'm getting a runtime error of "Application-defined or object-defined error" which to my limited knowledge isn't helping me. Any assistance/pointers/suggestions are welcomed.
Sub ismerged()
Dim start As Integer, finish As Integer
For i = 1 To Range("A655").End(3).Row + 1
If Cells(i, "A").MergeCells = True Then
start = i
Exit For
End If
Next
For i = start To Range("A655").End(3).Row + 1
If Cells(i, "A").MergeCells = True Then
finish = i
End If
Next
MsgBox start
MsgBox finish
End Sub
Then I guess you can select your data as you wish.
I'm not sure about the way you reference your sheet. I will assume 'comboboxvalue' contains the name or the number of the sheet you are selecting. Your code should be something like the following.
Sub Z_Extract()
Dim StartRow
Dim EndRow
Dim ws As Worksheet
Set ws = Sheets(comboboxvalue)
StartRow = ws.Cells.Find("**** ZC").Row
EndRow = ws.Cells.Find("****").Row
'Im assuming you have values up to column G
ws.Range(ws.Cells(StartRow, 1), Cells(EndRow, 7)).Copy
'Now that you have the correct Range selected you can copy it to your new workbook
'SelectedRange.Copy Etc.....
'Cleanup
Set ws = Nothing
End Sub
Got it working.
Set Zws = Sheets(Sheet1.CmbSheet.Value)
'selects ZCPS block from selected estate sheet
StartRow = (Zws.Cells.Find("**** ZCPS Installation").Row)
EndRow = (Zws.Cells.Find("**** Aztec Hotfixes").Row) - 1
'copy above block and paste into Z-MISC starting at row 10
Sheets(Sheet1.CmbSheet.Value).Activate
ActiveSheet.Range(Cells(StartRow, 1), Cells(EndRow, 7)).Select
Selection.Copy
Sheets("Z-MISC").Select
Range("A10").Select
ActiveSheet.Paste

Excel VBA delete entire row if cell in column D is empty

Can anyone walk me through how to write a script to delete the entire row if a cell in column D = "" on sheet 3 in range D13:D40.
Also, how to prevent the user from accidentally running the script again once those cells in the range are already deleted and other cells are now on the D13:D40 range?
Solution: This is working for me:
Sub DeleteRowsWithEmptyColumnDCell()
Dim rng As Range
Dim i As Long
Set rng = ThisWorkbook.ActiveSheet.Range("D13:D40")
With rng
' Loop through all cells of the range
' Loop backwards, hence the "Step -1"
For i = .Rows.Count To 1 Step -1
If .Item(i) = "" Then
' Since cell is empty, delete the whole row
.Item(i).EntireRow.Delete
End If
Next i
End With
End Sub
Explanation: Run a for loop through all cells in your Range in column D and delete the entire row if the cell value is empty. Important: When looping through rows and deleting some of them based on their content, you need to loop backwards, not forward. If you go forward and you delete a row, all subsequent rows get a different row number (-1). And if you have two empty cells next to each other, only the row of the first one will be deleted because the second one is moved one row up but the loop will continue at the next line.
No need for loops:
Sub SO()
Static alreadyRan As Integer
restart:
If Not CBool(alreadyRan) Then
With Sheets("Sheet3")
With .Range("D13:D40")
.AutoFilter 1, "="
With .SpecialCells(xlCellTypeVisible)
If .Areas.Count > 1 Then
.EntireRow.Delete
alreadyRan = alreadyRan + 1
End If
End With
End With
.AutoFilterMode = False
End With
Else
If MsgBox("procedure has already been run, do you wish to continue anyway?", vbYesNo) = vbYes Then
alreadyRan = 0
GoTo restart:
End If
End If
End Sub
Use AutoFilter to find blank cells, and then use SpecialCells to remove the results. Uses a Static variable to keep track of when the procedure has been run.
Here's my take on it. See the comments in the code for what happens along the way.
Sub deleterow()
' First declare the variables you are going to use in the sub
Dim i As Long, safety_net As Long
' Loop through the row-numbers you want to change.
For i = 13 To 40 Step 1
' While the value in the cell we are currently examining = "", we delete the row we are on
' To avoid an infinite loop, we add a "safety-net", to ensure that we never loop more than 100 times
While Worksheets("Sheet3").Range("D" & CStr(i)).Value = "" And safety_net < 100
' Delete the row of the current cell we are examining
Worksheets("Sheet3").Range("D" & CStr(i)).EntireRow.Delete
' Increase the loop-counter
safety_net = safety_net + 1
Wend
' Reset the loop-counter
safety_net = 0
' Move back to the top of the loop, incrementing i by the value specified in step. Default value is 1.
Next i
End Sub
To prevent a user from running the code by accident, I'd probably just add Option Private Module at the top of the module, and password-protect the VBA-project, but then again it's not that easy to run it by accident in the first place.
This code executes via a button on the sheet that, once run, removes the button from the worksheet so it cannot be run again.
Sub DeleteBlanks()
Dim rw As Integer, buttonID As String
buttonID = Application.Caller
For rw = 40 To 13 Step -1
If Range("D" & rw) = "" Then
Range("D" & rw).EntireRow.Delete
End If
Next rw
ActiveSheet.Buttons(buttonID).Delete
End Sub
You'll need to add a button to your spreadsheet and assign the macro to it.
There is no need for loops or filters to find the blank cells in the specified Range. The Range.SpecialCells property can be used to find any blank cells in the Range coupled with the Range.EntireRow property to delete these. To preserve the run state, the code adds a Comment to the first cell in the range. This will preserve the run state even if the Workbook is closed (assuming that it has been saved).
Sub DeleteEmpty()
Dim ws As Excel.Worksheet
Set ws = ActiveSheet ' change this as is appropriate
Dim sourceRange As Excel.Range
Set sourceRange = ws.Range("d13:d40")
Dim cmnt As Excel.Comment
Set cmnt = sourceRange.Cells(1, 1).Comment
If Not cmnt Is Nothing Then
If cmnt.Text = "Deleted" Then
If MsgBox("Do you wish to continue with delete?", vbYesNo, "Already deleted!") = vbNo Then
Exit Sub
End If
End If
End If
Dim deletedThese As Excel.Range
On Error Resume Next
' the next line will throw an error if no blanks cells found
' hence the 'Resume Next'
Set deletedThese = sourceRange.SpecialCells(xlCellTypeBlanks)
On Error GoTo 0
If Not deletedThese Is Nothing Then
deletedThese.EntireRow.Delete
End If
' for preserving run state
If cmnt Is Nothing Then Set cmnt = sourceRange.Cells(1, 1).AddComment
cmnt.Text "Deleted"
cmnt.Visible = False
End Sub
I've recently had to write something similar to this. I'm not sure that the code below is terribly professional, as it involves storing a value in cell J1 (obviously this can be changed), but it will do the job you require. I hope this helps:
Sub ColD()
Dim irow As long
Dim strCol As String
Sheets("sheet2").Activate
If Cells(1, 10) = "" Then
lrun = " Yesterday."
Else: lrun = Cells(1, 10)
End If
MsgBox "This script was last run: " & lrun & " Are you sure you wish to continue?", vbYesNo
If vbYes Then
For irow = 40 To 13 step -1
strCol = Cells(irow, 4).Value
If strCol = "" Then
Cells(irow, 4).EntireRow.Delete
End If
Next
lrun = Now()
Cells(1, 10) = lrun
Else: Exit Sub
End If
End Sub

Copy cells in excel with vba

I have a code that reads in the new arrangement of columns from a text file and then rearrange the original columns by copying it in at the correct place, however there is a bug in my code. Instead of copying just 1 column it seems to copy all columns to the right of the column that i want to copy..
so i guess the error is here
'copy the old range
ws.Range(ws.Cells(Settings.rowHeader + 1, CounterCol), ws.Cells(lrow, CounterCol)).Copy
I want to copy the range AW3:AW80 to A3:A80, but do i need to copy AW:AW to A:A instead? If i do so the stuff in row 1 will be deleted, below is the full code:
Sub insertColumns()
Call Settings.init
Dim i As Integer
Dim ws As Worksheet
Dim lrow As Integer
Dim columNames As Object
Dim temp As Variant
'fill dictionary with columnnames from text file
Set columNames = FileHandling.getTypes(Settings.columnFile)
Set ws = ActiveWorkbook.Sheets("List")
'Get max column and row number
lColumn = HelpFunctions.getLastColumn(ws, Settings.rowHeader)
lrow = HelpFunctions.getLastRow(ws, HelpFunctions.getColumn("*part*", ws, Settings.rowHeader))
'Insert all new columns in reverse order from dictionary
temp = columNames.keys
For i = columNames.Count - 1 To 0 Step -1
ws.Columns("A:A").Insert Shift:=xlToRight
ws.Range("A" & Settings.rowHeader).Value = temp(i)
Next i
'last column
lastColumn = lColumn + columNames.Count
'we loop through old cells
CounterCol = columNames.Count + 1
Do While CounterCol <= lastColumn
j = 0
'through each elemnt in dictionary
For Each element In temp
j = j + 1
'compare the old rowheader with any of the rowheader in DICTIONARY
If UCase(ws.Cells(Settings.rowHeader, CounterCol).Value) = element Then
'copy the old range
ws.Range(ws.Cells(Settings.rowHeader + 1, CounterCol), ws.Cells(lrow, CounterCol)).Copy
'paste it
ws.Cells(Settings.rowHeader + 1, j).Select
ws.Paste
'format the new row
ws.Cells(Settings.rowHeader + 1, j).EntireColumn.AutoFit
'Delete the old row
ws.Columns(CounterCol).EntireColumn.Delete
'decrease the last column by one since we just deleted the last column
lastColumn = lastColumn - 1
found = True
'Exit For
End If
Next element
'Prompt the user that the old column does not match any of the new column
If Not found Then
MsgBox (UCase(ws.Cells(Settings.rowHeader, CounterCol)) & " was not a valid column name please move manually")
End If
'reset the found
found = False
'go to nect column
CounterCol = CounterCol + 1
Loop
End Sub
Below is a screenshot of the dictionary.
After the first iteration/first copy it should have only copied over the part number column, but as can been seen it has copied over more than just the first column(everything except of drawing number)
Q: I want to copy the range AW3:AW80 to A3:A80, but do i need to copy AW:AW to A:A instead?
A: No. Any range can be copied.
Rather than trying to debug your code, I'll give you a hint about how to debug such a thing. Lines like
ws.Range(ws.Cells(Settings.rowHeader + 1, CounterCol), ws.Cells(lrow, CounterCol)).Copy
are hard to debug because they are trying to do too much. You have 4 instances of the dot operator and suspected that the problem was with the last one (.Copy). The problem is almost certainly that your code isn't grabbing the range that you think it is grabbing. In other words, one or more of your method invocations earlier in the line needs debugging. In such a situation it is useful to introduce some range variables, set them equal to various values and print their addresses to the immediate window to see what is happening. As an added benefit, having set range variables allows you to use the full power of intellisence in the VBA editor. Something like:
Dim SourceRange As Range, Cell1 As Range, Cell2 As Range
'
'
'
Set Cell1 = ws.Cells(Settings.rowHeader + 1, CounterCol)
Set Cell2 = ws.Cells(lrow, CounterCol)
Set SourceRange = ws.Range(Cell1, Cell2)
Debug.Print Cell1.Address & ", " & Cell2.Address & ", " & SourceRange.Address
'
'Once the above is debugged:
'
SourceRange.Copy 'should work as expected
It is possible that you are copying the range that you want to copy but that your larger program still isn't working. In that case you have some sort of logic error and should be trying to copy some other range. Even then, the above exercise still helps because it makes it clear exactly what your original line was doing.
'go to nect column
CounterCol = CounterCol + 1
needed to be deleted. It has to do that the column shifts left when i deleted rows.
Thanks for the help. I hope the code can be used for others who might need to add columns, but still copy over content from old columnsin the right order.

Excel data not displaying

I have data that doesnt seem to be merging all the rows! I need it to merge even with empty columns.
For example:
On Sheet CPW, Column W is blank. So when merged all the entries for CPW should show blank in Column W and the information from Sheet CCI would only show.
That's just one example. There are many more on these two sheets.
This is my code for the merge. How can it be edited to do what I require?
Sub Combine()
Dim J As Integer
Dim wrk As Workbook 'Workbook object - Always good to work with object variables
Dim r1, r2, r3, r4, ra, rb, rc, rd, re, rf, rg As Range
Sheets("Sheet2").Select
Set r1 = Range("A:C")
Set r2 = Range("E:X")
Set r3 = Range("Y:AW")
Set r4 = Range("AX:BK")
Sheets("Sheet3").Select
Set ra = Range("A:A")
Set rb = Range("C:C")
Set rc = Range("B:B")
Set rd = Range("D:G")
Set re = Range("I:AL")
Set rf = Range("AM:AP")
Set rg = Range("AQ:BK")
Set wrk = Workbooks.Add
ActiveWorkbook.Sheets(2).Activate
Sheets(2).Name = "CPW"
r1.Copy Range("A1")
r2.Copy Range("D1")
r3.Copy Range("Y1")
r4.Copy Range("AY1")
Range("A1:BK100").Font.ColorIndex = 3
ActiveWorkbook.Sheets(3).Activate
Sheets(3).Name = "CCI"
ra.Copy Range("A1")
rb.Copy Range("B1")
rc.Copy Range("C1")
rd.Copy Range("D1")
re.Copy Range("H1")
rf.Copy Range("AM1")
rg.Copy Range("AQ1")
On Error Resume Next
Sheets(1).Select
Sheets(1).Name = "Combined"
Sheets(2).Activate
Range("A2").EntireRow.Select
Selection.Copy Destination:=Sheets(1).Range("A1")
For J = 2 To Sheets.Count
Sheets(J).Activate
Range("A2").Select
Selection.CurrentRegion.Select
Selection.Offset(1, 0).Resize(Selection.Rows.Count - 1).Select
Selection.Copy Destination:=Sheets(1).Range("A65536").End(xlUp)(2)
Sheets(1).Select
Range("A1:BK1000").Sort _
Key1:=Range("E1"), Key2:=Range("J1"), Header:=xlYes
Next
End Sub
Use of Select and Activate is not recommended (unless essential to the code’s objectives) because they are slow commands and are confusing.
You have blank columns because your copies do not line up. With the creation of the source ranges so far from their use, this is not obvious.
My macro achieves the same result as yours. I have bought all the code for copying together so it is much more obvious where you have left gaps. I have included questions where I suspect your code does not do what you want. I have included comments explaining aspects of your code I do not like.
Work through my code and study how I have achieved the same effects as yours. Come back with questions as necessary but the more you can understand on your own, the faster you will develop your skills.
Option Explicit
Sub Combine()
' Here it does not really matter since J is only used in a small block of
' code but avoid names like J. When you return to update this macro in
' 12 months will you remember what J is? I have a system of names that I
' have used for years. I can look at a macro I wrote 5 years ago and
' immediately know what all the variables. This speeds the work of
' remembering what the macro did. If you do not like my naming system,
' design your own but have a system.
' "Integer" defines a 16-bit integer which requires special processing on
' a post-16-bit computer. Use Long which defines a 32-bit integer
'Dim J As Integer
Dim InxWsht As Long
Dim WbkThis As Workbook
Dim Rng As Range
Dim Row1Next As Long
Dim WbkNew As Workbook
Dim WshtNew2 As Worksheet
Dim WshtNew3 As Worksheet
Dim WshtThis2 As Worksheet
Dim WshtThis3 As Worksheet
' ThisWorkbook is the workbook containing the macro. It is not
' necessarily the active workbook
Set WbkThis = ThisWorkbook
Set WshtThis2 = WbkThis.Worksheets("Sheet2")
Set WshtThis3 = WbkThis.Worksheets("Sheet3")
Set WbkNew = Workbooks.Add
Set WshtNew2 = WbkNew.Worksheets(2)
Set WshtNew3 = WbkNew.Worksheets(3)
WshtNew2.Name = "CPW"
WshtThis2.Range("A:C").Copy Destination:=WshtNew2.Range("A1")
' Note columns E:X are written to columns D:W. X is left blank
WshtThis2.Range("E:X").Copy Destination:=WshtNew2.Range("D1")
WshtThis2.Range("Y:AW").Copy Destination:=WshtNew2.Range("Y1")
' Note the previous destination end in column AW while the next
' starts with AY. Column AX is left blank.
WshtThis2.Range("AX:BK").Copy Destination:=WshtNew2.Range("AY1")
' Why are only the first hundred rows coloured red?
' Why don't you colour column BL?
WshtNew2.Range("A1:BK100").Font.ColorIndex = 3
WshtNew3.Name = "CCI"
WshtThis3.Range("A:A").Copy Destination:=WshtNew3.Range("A1")
' Did you mean to reverse columns B and C?
WshtThis3.Range("B:B").Copy Destination:=WshtNew3.Range("C1")
WshtThis3.Range("C:C").Copy Destination:=WshtNew3.Range("B1")
WshtThis3.Range("D:G").Copy Destination:=WshtNew3.Range("D1")
WshtThis3.Range("I:AL").Copy Destination:=WshtNew3.Range("H1")
WshtThis3.Range("AM:AP").Copy Destination:=WshtNew3.Range("AM1")
WshtThis3.Range("AQ:BK").Copy Destination:=WshtNew3.Range("AQ1")
'On Error Resume Next
' This statement means ignore all errors which you should never do.
' Use this statement so:
'On Error Resume Next
'Statement that may fail for reasons you cannot control or stop
'On Error GoTo 0
'If Err.Number = 0 Then
' No error
'Else
' Display Err.Description or take corrective action according
' to value of Err.Number
'End If
'Selection.CurrentRegion.Select
' Since you have just created the worksheet it is probably safe to
' use "CurrentRegion". However, Excel's definition of CurrentRegion
' is not always what you might expect.
With WbkNew
With .Worksheets(1)
.Name = "Combined"
' Did you mean to copy row 2?
WshtNew2.Rows(2).Copy Destination:=.Rows(1)
End With
Row1Next = 3 ' Next free row in worksheets(1)
For InxWsht = 2 To Worksheets.Count
' This Find searches backwards from A1 by row for the first cell
' containing a value. This will give you what you expect more
' often that CurrentRegion
With Worksheets(InxWsht)
Set Rng = .Cells.Find(What:="*", After:=.Range("A1"), _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious)
If Rng Is Nothing Then
' Probably not necessary here but best to be safe. If a worksheet
' is empty Find will return Nothing
Else
.Rows("2:" & Rng.Row).Copy Destination:=WbkNew.Worksheets(1).Cells(Row1Next, 1)
' Unless I absolutely know that column A will be the last column with
' a value, I prefer to caluclate the next free row.
Row1Next = Row1Next + Rng.Row - 1
End If
End With
Next
' I do not see the point of having the Sort within the or Loop
With .Worksheets(1)
.Cells.Sort Key1:=.Range("E1"), Key2:=Range("J1"), Header:=xlYes
End With
End With
End Sub