'Range' of object'_Global' failed VBA - excel

There are two date ranges which are set. Once this range is set, I click my refresh data macro which will then extract the data from within these two date ranges. (i.e. Date 1 - 1/1/2017. Date 2 - 31/1/2017) However I have noticed as soon as I go beyond the date range 19/1/2017 it will throw an error indicating the range of the object has failed. I cannot seem to understand the significance of this date.
I have checked that my ranges are not unqualified as I have set the Worksheet to "Outage Schedule ->" and I have not changed the sheet name.
Does anyone have any idea why this is the case?
Sub SortFinalTable(numRows As Long)
Dim sht As Worksheet
Dim rng As Range
Set sht = Worksheets("Outage Schedule ->")
Set rng = sht.Range("A5").Resize(numRows + 1, 52)
sht.AutoFilterMode = False
rng.AutoFilter
On Error Resume Next
sht.AutoFilter.Sort.SortFields.Clear
On Error GoTo 0
sht.AutoFilter.Sort.SortFields.Add Key:=Range("A5:A" & numRows - 4), SortOn:=xlSortOnValues, Order:=xlDescending, _
DataOption:=xlSortNormal
sht.AutoFilter.Sort.SortFields.Add _
Key:=Range("B5:B" & numRows - 4), SortOn:=xlSortOnValues, Order:=xlAscending, _
DataOption:=xlSortNormal
With sht.AutoFilter.Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub

The issue was that the numRows variable was recording a 0 or negative value which meant that when I tried to set the range below:
sht.range("A5")>Resize(numRows +1, 52)
....
....
....
sht.AutoFilter.Sort.SortFields.Add Key=Sht.Range("A5:A" & numRows - 4),...
The range would always fail as the numbers were negative. I addressed this by ensuring the numRows always stays +ve so the lowest number the range could ever drop to is 1.
This seems to have resolved the issue for now.

Related

How to sort a range based on non-empty cells in each row?

As it's shown in the image, rows in the range with highest number of non-empty cells move to the top position.
Here's code that will sort the way you explain.
Sub SortByCountA()
' 136
Dim Ws As Worksheet
Dim Rng As Range
Dim C As Long ' helper column
Set Ws = Worksheets(1) ' change to suit
With Ws.UsedRange
C = .Columns.Count + 1
Set Rng = .Resize(, C)
End With
Application.ScreenUpdating = False
With Rng
.Cells(.Row, C).FormulaR1C1 = "=COUNTA(RC[" & (1 - C) & "]:RC[-1])"
.Columns(C).FillDown
End With
With Ws.Sort
With .SortFields
.Clear
.Add2 Key:=Ws.Cells(Rng.Row, C), _
SortOn:=xlSortOnValues, _
Order:=xlDescending, _
DataOption:=xlSortNormal
End With
.SetRange Rng
.Header = xlNo
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Ws.Columns(C).EntireColumn.Delete
Application.ScreenUpdating = True
End Sub
The difficulty in this task is to define the range that needs to be sorted. The above code sorts the entire UsedRange. It doesn't expewct to encounter any tables and it expects to start in column A. The Sort.Header property is set to xlNo. An easy modification would be to set it to xlYes. If you have a more difficult range it isn't difficult to adapt the above code to work with such a range once it is defined.
In Output table E2, formula copied across and down :
=IFERROR(1/(1/INDEX(A$2:A$5,MATCH(IFERROR(AGGREGATE(15,6,$A$2:$A$5/($B$2:$B$5<>""),ROW(A1)),AGGREGATE(15,6,$A$2:$A$5/($B$2:$B$5=""),COUNT($A$2:$A$5)-COUNT(E$1:E1))),$A$2:$A$5,0))),"")
=SORT(SORT(SORT(A1:C4;1;1);2;1);3;1)
In office 365 you can use sort over sort over sort. It sorts by column A, than column B, then C.

VBA Excel sort the data from A to Z in one column with all data table changes

It might be such a duplicate question with:
VBA Sort A-Z on One Column
However I want to have the stuff clarified.
I tried to use this code for my purpose:
Sub SortAsc2()
Dim LastRow As Long
LastRow = Cells(Rows.Count, "M").End(xlUp).Row
'Columns("D:D").Select
ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add Key:=Range("D"), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("Sheet1").Sort
.SetRange Range("D2:D" & LastRow)
.Header = xlGuess
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub
where I got an error:
1004 Method 'Range' of object_Global failed
I tried another code then
Sub SortDataWithoutHeader()
Range("D1:D12").Sort Key1:=Range("D1"), Order1:=xlAscending, Header:=xlNo
End Sub
But the sort happens only within the column, whereas the other data is unaffected.
I want to have values from other cells corresponding to the data sort.
Is anyone able to help?
Give this a try.
Read code's comments and adjust it to fit your needs
Code:
Public Sub SortAsc2()
Dim targetSheet As Worksheet
Dim targetRange As Range
Dim lastRow As Long
' Set a reference to the sheet
Set targetSheet = ThisWorkbook.Worksheets("Sheet1")
' Find the last non empty row (based on column A)
lastRow = targetSheet.Cells(targetSheet.Rows.Count, "A").End(xlUp).Row
' Set the range to be sorted (A2= begins in row 2 and ends in column K?)
Set targetRange = targetSheet.Range("A2:K" & lastRow)
' Clear current sorting fields
targetSheet.Sort.SortFields.Clear
' You are missing a 1 after "D" in Range in your code
targetSheet.Sort.SortFields.Add Key:=Range("D1"), _
SortOn:=xlSortOnValues, _
Order:=xlAscending, _
DataOption:=xlSortNormal
With targetSheet.Sort
.SetRange targetRange
.Header = xlGuess
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub
Let me know if it works

Sorting within specified range and loop until done - VBA Excel Marcro

It's me again. I've been trying different alternatives to sort the rows based on Col D per collection.
This is the closest one, yet there are 2 bugs found.
1- Loop and not able to exit when it reaches the last used rows.
It keeps sorting until I press to force quitting
2- It's unable to sort where there is only one SKUs per collection
It sort the next collection as well. Sometimes 3 collections sorted.
e.g. Before Run - Row 9, 29, 32, 35, 45....
Here is my code. What's wrong with my code?
Sub SortingCollectionOnColD
With ActiveSheet.Range("A:A")
Set FindSubtotal = .Find("Subtotal", After:=.Range("A1"), LookIn:=xlValues)
If Not FindSubtotal Is Nothing Then
firstOne = FindSubtotal.Address
Do
With FindSubtotal
Range("A" & FindSubtotal.Row - 1).Select
Set SortRange = Range(Selection, Selection.End(xlUp)).EntireRow
ActiveSheet.Sort.SortFields.Clear
ActiveSheet.Sort.SortFields.Add Key:=Range("C" & FindSubtotal.Row) _
, SortOn:=xlSortOnValues, Order:=xlAscending
With ActiveSheet.Sort
.SetRange SortRange
.Header = xlNo
.Orientation = xlTopToBottom
.Apply
End With
End With
Set FindSubtotal = .FindNext(FindSubtotal)
Loop While Not FindSubtotal Is Nothing And FindSubtotal.Address <> firstOne
End If
End With End Sub
Before the run
Expected Result
After the run. highlighted the major failures
Please test the next code, please. I could not reproduce your sheet and I changed the reference to sheet instead of A:A range, where it looks logic to me, but not knowing very well what you wanted to do, it would not be impossible to not return what exactly you need. Please let me know if/how it fits your need.
Sub LoopSubtotal()
Dim FindSubtotal As Range, sh As Worksheet, firstOne As String
Dim SortRange As Range
Set sh = ActiveSheet
With sh.Range("A:A")
Set FindSubtotal = .Find("Subtotal", After:=.Range("A1"), LookIn:=xlValues)
If Not FindSubtotal Is Nothing Then
firstOne = FindSubtotal.Address
Do
sh.Range("A" & FindSubtotal.row - 1).Select
Set SortRange = Range(Selection, Selection.End(xlUp)).EntireRow
sh.Sort.SortFields.Clear
sh.Sort.SortFields.Add Key:=sh.Range("C" & FindSubtotal.row) _
, SortOn:=xlSortOnValues, Order:=xlAscending
With sh.Sort
.SetRange SortRange
.Header = xlNo
.Orientation = xlTopToBottom
.Apply
End With
Set FindSubtotal = .FindNext(FindSubtotal): Debug.Print FindSubtotal.Address
Loop While Not FindSubtotal Is Nothing And FindSubtotal.Address <> firstOne
End If
End With
End Sub
Try, please, running it line by line, pressing F8 and see what it does.

Is it possible to have a dynamic sort range?

I was wondering if I can create a macro that sorts my worksheet with a range that is constantly changing? Instead of the last row constantly changing, the top row count will be changing.
Is it possible to have my .setrange be a variable which gets updated with the new range based on arguments?
For example the current code I have sets my range starting at A5 but if rows 6 - 10 have an interior color of green I want it to leave those at the top and only sort starting from A11.
activesheet.Sort.SortFields.Clear
activesheet.Sort.SortFields.Add Key:=Range("M6"), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With activesheet.Sort
.SetRange Range("A5:O150") ' I want this range to change constantly without me manually changing, for example it would be from ("A10:0150") now
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
This UDF will return a range object representing your sort range as defined by the first row of data in the fifth column containing a "white" interior (not including the first row, unless that is the ONLY row with a white interior):
Option Explicit
Private Function SortRange(baseRange As Range) As Range
Dim firstCell As Range, lastCell As Range, C As Range
With baseRange
Set lastCell = .Worksheet.Cells(.Row + .Rows.Count - 1, .Column + .Columns.Count - 1)
End With
With Application.FindFormat
.Clear
.Interior.Color = vbWhite
End With
'find the first cell in fifth column that is white
'As implemented, this should be column E, but if you move the range, it will adjust to the 5th column
'after the first row in baseRange
With baseRange
Set firstCell = .Columns(5).Find(what:="*", after:=.Cells(1, 5), searchorder:=xlByRows, searchdirection:=xlNext, searchformat:=True)
If Not firstCell Is Nothing Then
With .Worksheet
Set SortRange = .Range(.Cells(firstCell.Row, 1), lastCell)
End With
Else
MsgBox "no cells to sort"
Exit Function
End If
End With
End Function
You could then use it like:
.SetRange SortRange(activesheet.range("A3:O150"))
but I would suggest replacing activesheet with the actual worksheet.

Using Sort in VBA for a Range that Changes

I have a range of cells in VBA that changes each time the code is run. I am trying to write code so that this range is sorted by column F.
The problem I am having is that it can only be this specific range of cells. There are other cells underneath this range that I do not want sorted, and this range changes in size. Part of the code is below. This is what I have tried so far with no luck.
Range(Selection, Selection.End(xlToRight)).Select
Range(Selection, Selection.End(xlDown)).Select
vtools = Selection
ActiveWorkbook.Worksheets("Exceptions Weekly Summary").Sort.SortFields.Add Key _
:=Range(vtools), SortOn:=xlSortOnValues, Order:=xlAscending, _
DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("Exceptions Weekly Summary").Sort
.SetRange Range("B11:H14")
.Header = xlGuess
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
This does not work.
I cannot directly reference the cells (I cannot use Range("F2:F5") for example) because these cells are in different places each time the code is run. I know how to find what I need sorted, and even select it, but I am having trouble telling the sort function which column to sort by.
Can someone help me with this? Thank you so much in advance!
If I understood correctly this will help. It finds out the row numbers of the selected area and then makes a range in column F with these numbers and uses this as the key for ordering.
Sub sortOnlySelectedArea()
Dim actSheet As Worksheet
Dim upper, lower As Integer
Dim tempString As String
Dim selectedArea As Range
Set actSheet = Application.Worksheets("Sheet1")
' here you have to put in your part to make the right selection
actSheet.Range("E5:G6").Select
Set selectedArea = Selection
upper = selectedArea.Row
lower = upper + selectedArea.Rows.Count - 1
tempString = "F" & CStr(upper) & ":F" & CStr(lower)
actSheet.Sort.SortFields.Clear
actSheet.Sort.SortFields.Add Key:=Range(tempString), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With actSheet.Sort
.SetRange selectedArea
.Header = xlGuess
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub

Resources