Sort a Column in Another Sheet Without Selecting That Sheet - vba

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")

Related

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.

Excel Macro not sorting correctly

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.

Unprotecting then Protecting Sheet

Part 1
I have put together the following code in order to sort data on a sheet.
However, users keep deleting rows from the sheet which ruins the rest of my workbook so I have protected the sheet but then the macro will not longer run.
Can someone help me with the code to unprotect the sheet, run the macro and re protect the sheet at the end?
Sub CustSort1()
Range("a14").Select
Range(Selection, ActiveCell.SpecialCells(xlLastCell)).Select
Selection.Sort Key1:=Range("a14"), Order1:=xlAscending, Key2:=Range( _
"k14"), Order2:=xlAscending, _
Header:=xlGuess, OrderCustom:=1, MatchCase:=False, Orientation:= _
xlTopToBottom, DataOption1:=xlSortNormal, DataOption2:=xlSortNormal, _
DataOption3:=xlSortNormal
Range("a14").Select
End Sub
I have found similar posts but my level of knowledge is pretty low.
All help appreciated.
Part 2
Ok so small issue has come up! What if I still want the user to be able to insert cells?
I can see I need to use this "AllowInsertingRows" but dont understand where i insert it.
Absolutely agree with #vba4all. Another way of writing is to unprotect the worksheet before you call CustSort1 sub routine and then protect the worksheet again.
Sub pMainCode()
'Considering Sheet1 to be where you want to apply sorting
Worksheets("Sheet1").Unprotect "Password"
Call CustSort1
Worksheets("Sheet1").Protect "Password"
End Sub

Run an Excel VBA script on only the active worksheet and not the entire book?

I am using a VBA script to essentially find/replace. Right now when I run the VBA script it applies to all open sheets in the workbook. I wish for the VBA script to only apply in the active sheet and not touch the rest.
Here is my current macro code:
Sub ReplaceCC()
'
' ReplaceCC Macro
' Add CC to Distributor, Reseller, Government and Retail.
'
'
Range("A1").Select
Cells.Replace What:="Distributor", Replacement:="DistributorCC", LookAt:= _
xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
Cells.Replace What:="Reseller", Replacement:="ResellerCC", LookAt:=xlPart _
, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
Cells.Replace What:="Government", Replacement:="GovernmentCC", LookAt:= _
xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
Cells.Replace What:="Retail", Replacement:="RetailCC", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
End Sub
Here is the entire VBA script with all subs.
I got the same problem. It depends of the Find/Replace history: if in the previous manual use of Find/Replace, you specified "Options > Search in Workbook", your macro will apply to all sheets. Otherwise, with the default "In Sheet", the macro will stay in the original Worksheet. I still don't know how to fix that from within the macro, though.
Interesting question. I believe that you could do what you're trying to do by simply placing "ActiveSheet" before each object reference in your code.
For example: Instead of Range("A1").Select use ActiveSheet.Range("A1").select
If you set up your code like this, whenever you execute, it should carry out its actions on the worksheet you currently have active.
EDIT: You should check to see which module you have this code placed in. If it is in an inserted module, I think you should be fine. On the other hand, if you've inserted it in one of the sheet modules it will only modify the sheet it is attached to. If you insert ActiveSheet before your cell references and the rest it will still modify the active sheet instead of the sheet the code is attached to.
It seems the macro was not recognizing the active sheet properly since the sheets were copies of each other. If you copy the content on Sheet 1 and create a new sheet then paste the content on it this will work. Each sheet needed to be unique and not just a copy of the original.
This is due to a VBA bug. When you use "Find" in VBA, the parameter "LookAt:=xlPart" or "LookAt:=xlWhole" works as expected. But when you use "Replace", the coded parameter is ignored and the replace uses the last MANUAL setting for its scope. The workaround is to do a "Find" operation right before the "Replace" operation, since "Find" uses the coded "LookAt" scope (thereby making the "Find"'s scope the last setting used, so the "Replace" will then use the scope coded into the "Find").
Solution from http://www.vbaexpress.com/forum/showthread.php?11444-Solved-Replace-in-a-sheet-and-not-the-entire-workbook
Dim dummy As Range
Set dummy = Worksheets(1).Range("A1:A1").Find("Dummy", LookIn:=xlValues)
Then you can post REPLACE functions underneath these lines of codes