Excel Macro not sorting correctly - vba

I have this script and it sorts MT-001 - MT-999 recently I added two more entries "MT-1000" and "MT-1001" and this is how my Macro is sorting.....
MT-099
MT-100
MT-1000
MT-1001
MT-102
MT-103
My macro for sorting is the following:
Sub FILTERMT()
Selection.AutoFilter Field:=2, Criteria1:="=*MT*", Operator:=xlAnd
Range("A7:BZ65536").Sort Key1:=Range("B6"), Order1:=xlAscending, Header:= _
xlGuess, OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal
End Sub
Can someone post a code that corrects this error? THX for contributing to this community!

If you notice, MT-099 has a leading zero to ensure it sorts before MT-100 while MT-102 does not have a leading zero to ensure it sorts before MT-1000.
You will need to modify your data to support 4-digit, left zero-padded numbers, or come up with a way to split the numeric portion off into a different column for sorting purposes.

Choose a 3rd column, that may even be a many columns to the right if necessary.
Fill the cells of this column with this formula:
=RIGHT(B6;LEN(B6)-FIND("-");B6))*1
Here, I assume that the top of your list ("MT-099") ist at field B6.
The right expression cuts the number out of the string. The *1 is to really convert to a number. You need only the number treated as a number in order to sort the right way.
Se the formula e.g. in C6 and copy the content downwards to the end row of your list.
Then simply alter your code; here I assume that your new column is C:
Range("A7:BZ65536").Sort Key1:=Range("C6"), Order1:=xlAscending, Header:= _
xlGuess, OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal
To clarify, here is how it looks like after sorting:
If necessary, you may narrow your 3rd column to zero length, so it is invisible.

Related

Variable Multiple Criteria for Autofilter in VBA

I'm looking to use VBA autofilter to better sort my data as I work through it. I have around a 1000 rows each with a unique number and I'd like to be able to filter that data to the ID numbers I need at that moment. Basically, the autofilter code below does the job for those 5 specific entries, but is there a way of making that a more flexible?
ActiveSheet.Range("$A$13:$Y$1045").AutoFilter Field:=1, Criteria1:=Array( _
"1776", "1870", "2029", "2051", "2086"), Operator:=xlFilterValues
I picture using something along the lines of:
ActiveSheet.Range("$A$13:$Y$1045").AutoFilter Field:=1, Criteria1:=Array( _
TexBox2.Value, TextBox2.Value), Operator:=xlFilterValues
but no joy. I'm a bit of a newbie, so huge apologies if this is a huge waste of time. Many thanks in advance for any help!
I think you should be little more precise:
ActiveSheet.Range("$A$13:$Y$1045").AutoFilter Field:=1, Criteria1:=Array( _
UserForm1.TexBoxt1.Value, UserForm1.TextBox2.Value) _
, Operator:=xlFilterValues
where UserForm1 is the name of your userform. Be sure that you did not unloaded it before running this piece of code (you may .Hide it and still have access to the controls).

VBA Sort method of Range class failed

I know there are several threads on this topic but none of the answers have helped resolved this error.
I am trying to sort a table using three keys but receive the error, "Run-time error '1004': Sort method of Range class failed"
I've tried changing "Range("L2")" to ".Range("L2")" and received the error, "Compile error: Invalid or unqualified reference"
I've tried specifying the actual range instead of using columns, I've removed the last two keys and tried just the first, still received the run-time error.
shtData.Activate
shtData.Range(Range("A2"), Range("Z8000").End(xlUp)).Sort _
Key1:=Range("L2"), Order1:=xlAscending, _
Key2:=Range("M2"), Order2:=xlAscending, _
Key3:=Range("B2"), Order3:=xlAscending, _
Header:=xlYes
If you have any suggestions, I'd greatly appreciate it. I had this working yesterday and my excel crashed and did not recover the changes I made, I cannot figure out why I can't get it to work today.
you most probably have no data in "Z" column
if data rows range can be safely sized by column "A" not empty cells then go like follows
Option Explicit
Sub main()
Dim shtData As Worksheet
Set shtData = Worksheets("Data") '<--| some setting of 'shtData'
With shtData
.Range("Z2", .Cells(.Rows.Count, "A").End(xlUp)).Sort _
Key1:=.Range("L2"), Order1:=xlAscending, _
Key2:=.Range("M2"), Order2:=xlAscending, _
Key3:=.Range("B2"), Order3:=xlAscending, _
Header:=xlYes
End With
End Sub
If it is possible you could end up changing amount of columns again in the future, you could do something like.
With shtData
Range(Range("A2"), Cells(Range("A8000").End(xlUp).Row, Range("ZZ2").End(xlLeft).Column)
That way it will automatically size the sort area for however many columns you are using as well as rows.

Sorting Multiple Keys in VBA; Runtime Error 450: Wrong number of arguments or invalid property assignment

I have been writing this VBA code to help me sort a database of information I have (Name, Invoice#, Address, etc). I recently learned how to sort in VBA without selecting the actual range in the worksheet and with that I tried sorting with multiple keys (key1, key2, key3), but no luck. I keep getting a Run time error 450: Wrong number of arguments or invalid property assignment when running this code. I want to be able to sort a range of data multiple times, so for instance sort a range (A:K) by column F, then by E, then by B etc.
Here is the code I have been using for sorting my columns:
ActiveSheet.Range("A:K").Sort _
Key1:=ActiveSheet.Range("F2"), Order1:=xlAscending, HEADER:=xlYes, Ordercustom:=1, MatchCase:=False, _
Orientation:=xlTopToBottom, DataOption1:=xlSortNormal, _
Key2:=ActiveSheet.Range("E2"), Order2:=xlAscending, HEADER:=xlYes, Ordercustom:=1, MatchCase:=False, _
Orientation:=xlTopToBottom, DataOption2:=xlSortNormal, _
Key3:=ActiveSheet.Range("D2"), Order3:=xlAscending, HEADER:=xlYes, Ordercustom:=1, MatchCase:=False, _
Orientation:=xlTopToBottom, DataOption3:=xlSortNormal
It is weird, because at first I tried running the first 2 keys (key1, key2) and it worked perfectly fine, then I copied and pasted down to create the next key (key3) and the error came up. When I try to debug, all the code above gets highlighted.
The only other way I can think of is to run the code where the range (A:K) gets selected in the worksheet, but I don't want to do that.
It looks like you are trying to rework some recorded macro code. The recorded code for a recorded Range.Find method is very verbose. Here is all that you should require.
With Sheets("Sheet1")
With Intersect(.Range("A1").CurrentRegion, .Range("A:K"))
.Cells.Sort Key1:=.Columns(6), Order1:=xlAscending, _
Key2:=.Columns(5), Order2:=xlAscending, _
Key3:=.Columns(4), Order3:=xlAscending, _
Orientation:=xlTopToBottom, Header:=xlYes
End With
End With
TBH, I do not know if you can simply add Ordercustom:=1 to each line of that. IIRC, custom sorts cannot be performed on more than a single field at a time. In that case, perform three sorts, each with a Ordercustom:=1 but remember to do it in reverse order; e.g. column D first, then E and finally the primary sort on column F.
Please note that there are a maximum of three columns to set the primary sort and secondary sorts to with this method. If you require more, sort on those first and run a subsequent sort on the last three prevalent columns.

Creating VBA code to reference cell text and create a dynamic Find & Replace

I work with multiple excel spreadsheets that require monthly updates for month end financial closing. I need to change references to outside workbooks so that it pulls in data from the current months file.
For example changing
"C:\Desktop\Folder\June"
to
"C:\Desktop\Folder\July"
I want to be able to enter the two months into specific cells in the worksheet and then run a VBA script to auto update the references throughout the workbook. I can record a "macro" for the Find & Replace function, but I can't figure out how to point the "Find" and "Replace" variables to the specific cells where I store the month values.
Here is the current code I have for conducting find and replace:
ActiveCell.Replace What:="Jun", Replacement:="Jul", LookAt:=xlPart, _
SearchOrder:=xlByColumns, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
Replace the literal text strings of "Jun" and "Jul" with a cell reference. For this, you can use Range("A1"). Of course, you would put in the actual range.
ActiveCell.Replace What:=Range("A1"), Replacement:=Range("B1"),LookAt:=xlPart, _
SearchOrder:=xlByColumns, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False`
What you should do is give those cells names then you can reference the cells
Range("find1").Select
ActiveCell.FormulaR1C1 = "July"
Range("find2").Select
ActiveCell.FormulaR1C1 = "July"

Sort a Column in Another Sheet Without Selecting That Sheet

Is it possible to sort columns in another sheet without selecting that sheet?
The problem is while I am running this code, I want this sheet to be hidden and I do not want it to flash over to it when I need to sort the table. Here is my code... This works, but it does obviously select the sheet and shows you the other sheet. Maybe something with 'make active sheet' would work can you do that then say 'make active cell'. I am not sure. Thanks guys.
Application.Worksheets("RawDataLines").Select
Application.Worksheets("RawDataLines").Range("Q5").Select
Application.Worksheets("RawDataLines").Range("A4:R1007").Sort Key1:=Range("Q5"), Order1:=xlAscending, Header:= _
xlGuess, OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal
Application.Worksheets("RawDataLines").Range("A5").Select
Application.Worksheets("RawDataLines").Range("A4:R1007").Sort Key1:=Range("A5"), Order1:=xlAscending, Header:= _
xlGuess, OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal
This:
Application.Worksheets("RawDataLines").Select
Application.Worksheets("RawDataLines").Range("Q5").Select
Application.Worksheets("RawDataLines").Range("A4:R1007").Sort ...
Could be this:
With Application.Worksheets("RawDataLines")
.Range("A4:R1007").Sort Key1:= .Range("A5")'...
End With
Add ScreenUpdating
Application.ScreenUpdating = False
#Your Code
Application.ScreenUpdating = True
Just make sure that you set the select back to the sheet you want it on prior to setting ScreenUpdating = True
Here the problem comes with the Key1 arguments of VBA sort method. Even though we explicitly pass range with relevant sheet, when it comes to Key1:=Range(…), VBA automatically take ActiveSheet.Range(…).
If We have selected some other sheet instead of the sheets of sort data, VBA shows runtime error.
To fix this problem change the code as Key1:=Your_Sheet_With_Data.Range(Your_Range). For Example, above referred code can be fixed changing the code as
Key1:=Worksheets("RawDataLines").Range("Q5")