MSORT(array,[ignore],[ignore_mode],[sort_orders],[sort_by_row])
array
Required. Specifies the function input and can be any cell/array/range.
ignore
Optional. Specifies the unsortable data type(s) that are intended to be ignored while sorting and takes one of eight arguments: 0 or omitted, for not ignoring any unsortable data types; 1, for ignoring blanks; 2, for ignoring errors; 3, for ignoring logicals; 4, for ignoring blanks and errors; 5, for ignoring blanks and logicals; 6, for ignoring errors and logicals; and 7, for ignoring blanks, errors, and logicals.
ignore_mode
Optional. Specifies the placement location, within the output array, of the unsortables that are not ignored and takes one of three arguments: 0 or omitted, for keeping unsortables in their original places; 1, for piling the unsortables at the bottom or right depending on whether the input array is sorted by columns or rows, respectively; and 2, for piling the unsortables at the top or left depending on whether the input array is sorted by columns or rows, respectively.
sort_orders
Optional. Specifies the sort order(s) for the columns or rows and takes one of four arguments: omitted, for the default ascending sort order; -1, for descending sort order(s); 1, for ascending sort order(s); and "", for skipping sort order(s) within an array of sort orders.
sort_by_row
Optional. Specifies whether the rows or columns of the input array are sorted and takes one of two arguments: 0 or omitted or FALSE, for sorting by columns; and 1 or TRUE or any number other than 0, for sorting by rows.

MSORT is a powerful and versatile array sorting solution that allows for sorting all or a subset of the columns (or rows) together or independently as well as having various options for dealing with the unsortables (blanks, logicals, and errors)

Rnkhch

Well-known Member
Joined
Apr 28, 2018
Messages
578
Office Version
  1. 365
Platform
  1. Windows
MSORT is a powerful and versatile array sorting solution that allows for sorting all or a subset of the columns (or rows) together or independently as well as having various options for dealing with the unsortables (blanks, logicals, and errors)

MSORT takes five parameters, one required and four optional, as follows:
A) The first parameter, required, specifies the function input and can be any cell/array/range

Note that the input array can contain any type of data, i.e. numbers, texts, blanks, logicals, and errors (for a full list of all data types, refer to the latest update of XTYPE); however, only numbers and texts are really sortable; thus, MSORT provides various options for treating the unsortables (blanks, logicals, and errors) (see sections B and C below)

B) The second parameter, optional, specifies the unsortable data type(s) that are intended to be ignored while sorting and takes one of eight arguments:
0 or omitted, for not ignoring any unsortable data types
1, for ignoring blanks
2, for ignoring errors
3, for ignoring logicals
4, for ignoring blanks and errors
5, for ignoring blanks and logicals
6, for ignoring errors and logicals
7, for ignoring blanks, errors, and logicals

Note that this parameter handles the placement location of the unsortables within the output array (which is the same exact size as the input array); any cell(s) containing ignored data type(s) will be either a) kept in their original places relative to the input array or b) piled at the spots indicated by the "ignore_mode" parameter, while the other unsortables will change places when sort order is changed between ascending and descending (see section C below)

Note that only one argument can be entered in this parameter; entering more than one number via array brackets "{}" would lead to a #VALUE! error

Note that besides being omitted, only the specified eight arguments can be used in this array; entering anything else will lead to a #VALUE! error

C) The third parameter, optional, specifies the placement location, within the output array, of the unsortables that are not ignored and takes one of three arguments:
0 or omitted, for keeping unsortables in their original places relative to the input array
1, for piling the unsortables at the bottom or right of the output array depending on whether the input array is sorted by columns or rows, respectively
2, for piling the unsortables at the top or left of the output array depending on whether the input array is sorted by columns or rows, respectively

Note that only one argument can be entered in this parameter; entering more than one number via array brackets "{}" would lead to a #VALUE! error

Note that besides being omitted, only the specified three arguments can be used in this array; entering anything else will lead to a #VALUE! error

D) The fourth parameter, optional, specifies the sort order(s) for the columns or rows and takes one of four arguments:
omitted, for the default ascending sort order
-1, for descending sort order(s)
1, for ascending sort order(s)
"", for skipping sort order(s) within an array of sort orders

Note that whether the columns or rows are sorted at the specified order is specified via the "sort_by_row" parameter (see section E below)

Note that if this parameter is left omitted, the default ascending sort order will be applied to all columns or rows

Note that if only one number (i.e. -1 or 1) is entered, the ascending or descending sort order will be applied to all columns or rows; for this to happen, the single number must not be in array brackets "{}"; if the single number is within array brackets, the specified sort order will be applied only to the first column or row (see notes below)

Note that each of the columns or rows can be sorted independently of the others by specifying multiple sort orders

Note that if more than one sort order need to be entered, they must be included in array brackets "{}" per native syntax

Note that if fewer sort orders than the total count of columns or rows of the input array are entered, the remaining columns or rows that do not correspond to sort orders will be left unsorted in the output array

Note that if more sort orders than the total count of columns or rows of the input array are entered, the sort order(s) past the last point of correspondence to the columns or rows will be ignored by the function; thus, if the input array is later expanded, those additional sort orders will be applied to the input array

Note that one or more columns or rows at any position within the input array can be left unsorted by skipping the sort order(s) corresponding to those columns or rows, and this is achieved by entering blanks, i.e. "", within the sort order array (e.g. {"",1,-1,"",-1,"","",1})

Note that if the blank symbol "" is used outside of the array brackets, i.e. as a single sort order argument, the function will return a #VALUE! error; thus, its use is meant only for when multiple sort orders need to be entered via array brackets "{}"

Note that besides being omitted, only the specified three arguments can be used in this array; entering anything else will lead to a #VALUE! error

E) The fifth parameter, optional, specifies whether the rows or columns of the input array are sorted and takes one of two arguments:
0 or omitted or FALSE, for sorting by columns
1 or TRUE or any number other than 0, for sorting by rows

Note that besides being omitted, only one real number or TRUE/FALSE can be entered in this parameter; entering more than one number or logical will cause the function to crash to a #VALUE! error

Note that if anything other than the specified allowed arguments is entered, the function will return a #VALUE! error


This function was essentially coded for by @djclements as discussed in the following thread especially starting at post #5; I only made minor changes and added some code for argument checking of the parameters

Special thanks to @djclements for this fabulous code.

(You can download my template from the link in my signature below, which makes it easier to obtain/test the functions compared to manually pasting from the text/XL2BB)


Note that the final IF function in the formula is intended only for argument checking of the parameters and is not strictly required for the core function to work

MSORT
Excel Formula:
=LAMBDA(array,[ignore],[ignore_mode],[sort_orders],[sort_by_row],
   LET(
      a,IF(TRIM(array)="","",array),
      m,ignore_mode,
      o,sort_orders,
      c,NOT(IF(IO(sort_by_row),0,INDEX(sort_by_row,1))),
      cλ,LAMBDA(t,f,IF(c,t,f)),
      h,ROWS(a),
      w,COLUMNS(a),
      i,SEQUENCE(h),
      j,SEQUENCE(,w),
      x,CHOOSE(ignore+1,
         0,
         IFERROR(a="",0),
         ISERROR(a),
         ISLOGICAL(a),
         IFERROR(a,"")="",
         IFERROR(a="",0)+ISLOGICAL(a),
         ISERROR(a)+ISLOGICAL(a),
         (IFERROR(a,"")="")+ISLOGICAL(a)
      ),
      z,TOCOL(IF({1},cλ(EXPAND(TAKE(TOROW(o),,w),,w,0),EXPAND(TAKE(TOCOL(o),h),h,,0)),a),,c),
      s,IF(
         OR(x),
         LET(
            y,NOT(x),
            vλ,LAMBDA(arr,incl,FILTER(TOCOL(arr,,c),TOCOL(incl,,c))),
            nλ,LAMBDA(arr,incl,TOCOL(IFS(incl,arr),2,c)),
            sλ,LAMBDA(one,two,IF(m=2,VSTACK(two,one),VSTACK(one,two))),
            _v1,vλ(a,y),
            _v2,vλ(a,x),
            _n1,nλ(cλ(j,i),y),
            _b1,sλ(_n1,nλ(cλ(j,i),x)),
            _b2,IF(m,EXPAND(1,h*w,,1),VSTACK(nλ(cλ(i,j),y),nλ(cλ(i,j),x))),
            IF(
               TYPE(o)=64,
               SWITCH(z,
                  1,SORTBY(sλ(SORTBY(_v1,_n1,1,_v1,1),_v2),_b1,1,_b2,1),
                  -1,SORTBY(sλ(SORTBY(_v1,_n1,1,_v1,-1),_v2),_b1,1,_b2,1),
                  TOCOL(a,,c)),
               SORTBY(sλ(SORTBY(_v1,_n1,1,_v1,o),_v2),_b1,1,_b2,1)
            )
         ),
         LET(
            v,TOCOL(a,,c),
            n,TOCOL(IF({1},cλ(j,i),a),,c),
            IF(
               TYPE(o)=64,
               SWITCH(z,
                  1,SORTBY(v,n,1,v,1),
                  -1,SORTBY(v,n,1,v,-1),
                  v
               ),
               SORTBY(v,n,1,v,o)
            )
         )
      ),
      IF(
         AND(
            ISNUMBERS(ignore,1,1),
            ISNUMBERS(ignore_mode,1,1,{0,1,2,3,4,5,6,7}),
            ISNUMBERS(sort_orders,1,,{1,-1,""},1),
            ISNUMBERS(sort_by_row,1,1,{TRUE,FALSE},2)
         ),
         cλ(WRAPCOLS(s,h),WRAPROWS(s,w)),
         #VALUE!
      )
   )
)

ISNUMBERS
Excel Formula:
=LAMBDA(reference,[if_omitted],[single],[match_set],[extend_match],
   IF(
      IO(reference),
      IF(IO(if_omitted),FALSE,if_omitted),
      LET(
         k,TOCOL(IF(reference="","",reference)),
         l,TOCOL(IF(match_set="","",match_set)),
         m,IF(IO(extend_match),0,extend_match),
         Mλ,LAMBDA(w,IF(PRODUCT(ISNUMBER(w)*1),TRUE,FALSE)),
         Aλ,LAMBDA(u,IFERROR(ROWS(TOCOL(u)),1)),
         Bλ,LAMBDA(x,LET(v,Aλ(x),IF(v=1,IF(IFERROR(IF(IO(x),0,x),#VALUE!),TRUE,FALSE),#VALUE!))),
         Cλ,LAMBDA(r,s,IF(PRODUCT(NOT(ISERROR(MATCH(r,s,0)))*1),TRUE,FALSE)),
         Nλ,LAMBDA(o,LET(
               p,ROWS(o)*COLUMNS(o),
               IF(
                  IFERROR(p,1)>1,
                  FALSE,
                  IF((IF(ISERROR(o),IF(ERROR.TYPE(o)=14,1,0),0))+(IF(ISERROR(p),1,0))=2,TRUE,FALSE)
               )
            )
         ),
         f,Bλ(single),
         i,IF(
            IO(match_set),
            Mλ(k),
            SWITCH(m,
               0,LET(j,FILTER(l,ISNUMBER(l)),IF(Nλ(j),FALSE,Cλ(k,j))),
               1,Cλ(k,l),
               OR(
                  LET(g,FILTER(k,ISNUMBER(k)),IF(Nλ(k),1,Mλ(k))),
                  LET(q,FILTER(k,NOT(ISNUMBER(k))),IF(Nλ(q),1,Cλ(q,l)))
               )
            )
         ),
         b,IF(f,IF(Aλ(k)=1,i,FALSE),i),
         IF(AND(ISLOGICAL(f),Cλ(m,{0,1,2}),ISLOGICAL(Bλ(m))),b,#VALUE!)
      )
   )
)

IO (shortened form of ISOMITTED)
Excel Formula:
=LAMBDA(parameter,
   ISOMITTED(parameter)
)


MSORT.xlsx
ABCDEFGHIJKLMNOPQRS
1
2#CALC!
3
4input array:data types:
5108-1-3-2-14-511111111
6-84 94TRUE1011321141131
7book#N/A910#VALUE!8#REF!821671116311641
8-1-72FALSE02#NUM!111421311166
94#DIV/0!-90410FALSE-911621111421
10note-2-4 22TRUE21341331141
11-86-167 29111113311
12
13
14-8-7-9-4-2-12-9-5-3-2-1-14810
15-8-2-1-3022-5-844910TRUE
16-14-10482888910book#N/A#VALUE!#REF!
17462641049-7-1022FALSE#NUM!
1810899710-9-904410FALSE#DIV/0!
19book#N/A10FALSETRUE-4-222noteTRUE
20note#DIV/0!FALSE#VALUE!TRUE#REF!#NUM!-8-126679
21
22note#N/AFALSE#VALUE!TRUE#REF!#NUM!1084-1-1-2-3-5
23book#DIV/0!10FALSETRUETRUE10944-8
2410899710#N/A#VALUE!#REF!book10988
25462641049#NUM!FALSE220-1-7
26-14-104828#DIV/0!FALSE10440-9-9
27-8-2-1-3022-5TRUEnote22-2-4
28-8-7-9-4-2-12-997662-1-8
29
30note#N/A9FALSE#VALUE!TRUE#REF!#NUM!1084-1-1-2-3-5
31book#DIV/0!210710FALSETRUETRUE10944-8
32108-1948109#N/A#VALUE!#REF!book10988
3346-164248#NUM!FALSE220-1-7
34-14-900-12-5#DIV/0!FALSE10440-9-9
35-8-2-3-22-9TRUEnote22-2-4
36-8-7-4297662-1-8
37
38note8FALSETRUEFALSETRUE1084-1-1-2-3-5
39book610710TRUE10944-8
4010499449book10988#N/A#VALUE!#REF!
414-22641028FALSE220-1-7#NUM!
42-1-7-10082-5FALSE10440-9-9#DIV/0!
43-8#N/A-1-3-222-9TRUEnote22-2-4
44-8#DIV/0!-9-4#VALUE!-1#REF!#NUM!97662-1-8
45
46note#N/A10#VALUE!#REF!#NUM!1084-1-1-2-3-5
47book#DIV/0!91010944-8TRUE
481089671049#N/A#VALUE!#REF!book10988
4946204828#NUM!220-1-7FALSE
50-14-1-3422-5#DIV/0!10440-9-9FALSE
51-8-2-1-40-12-9note22-2-4TRUE
52-8-7-9FALSE-2TRUEFALSETRUE97662-1-8
53
54note89FALSE7TRUEFALSETRUE1084-1-1-2-3-5
55book6210410109TRUE10944-8
56104-194848book10988#N/A#VALUE!#REF!
574-2-16022-5FALSE220-1-7#NUM!
58-1-7-90-2-12-9FALSE10440-9-9#DIV/0!
59-8#N/A-3#VALUE!2TRUEnote22-2-4
60-8#DIV/0!-4#REF!#NUM!97662-1-8
61
62note#N/A910#VALUE!10#REF!#NUM!1084-1-1-2-3-5
63book#DIV/0!297810910944-8TRUE
64108-164248#N/A#VALUE!#REF!book10988
6546-104-12-5#NUM!220-1-7FALSE
66-14-9-30TRUE2-9#DIV/0!10440-9-9FALSE
67-8-2-4-22note22-2-4TRUE
68-8-7FALSEFALSETRUE97662-1-8
69
70note810101084-1-1-2-3-5
71book6974910944-8TRUE
721049641028book10988#N/A#VALUE!#REF!
734-220482-5220-1-7FALSE#NUM!
74-1-7-1-3022-910440-9-9#DIV/0!FALSE
75-8#N/A-1-4-2-1#REF!#NUM!note22-2-4TRUE
76-8#DIV/0!-9FALSE#VALUE!TRUEFALSETRUE97662-1-8
77
78note89107101091084-1-1-2-3-5
79book629484810944-8TRUE
80104-16422-5book10988#N/A#VALUE!#REF!
814-2-100-12-9220-1-7FALSE#NUM!
82-1-7-9-3-2TRUE210440-9-9#DIV/0!FALSE
83-8#N/A-4#VALUE!#REF!#NUM!note22-2-4TRUE
84-8#DIV/0!FALSEFALSETRUE97662-1-8
85
86note89107101091084-1-1-2-3-5
87book694TRUE410944TRUE-8
8810#N/A26#VALUE!8#REF!8book#N/A109#VALUE!8#REF!8
8944-1FALSE42#NUM!220FALSE-1-7#NUM!
90-1#DIV/0!-1002FALSE-510#DIV/0!440-9FALSE-9
91-8-2-3-12TRUEnote22-2-4TRUE
92-8-7-9-4-22-997662-1-8
93
94-8-79-47-12-9-5-3-2-1-14810
95-8-22-3422-5-844910TRUE
96-14-104828book10988#N/A#VALUE!#REF!
9746-1601049-7-1022FALSE#NUM!
98108-99-2TRUE1010440-9-9#DIV/0!FALSE
99book#N/A10#VALUE!#REF!#NUM!-4-222noteTRUE
100note#DIV/0!FALSEFALSETRUE-8-126679
101
MSORT
Cell Formulas
RangeFormula
B2B2=LAMBDA(array,[ignore],[ignore_mode],[sort_orders],[sort_by_row],LET(a,IF(TRIM(array)="","",array),m,ignore_mode,o,sort_orders,c,NOT(IF(IO(sort_by_row),0,INDEX(sort_by_row,1))),cλ,LAMBDA(t,f,IF(c,t,f)),h,ROWS(a),w,COLUMNS(a),i,SEQUENCE(h),j,SEQUENCE(,w),x,CHOOSE(ignore+1,0,IFERROR(a="",0),ISERROR(a),ISLOGICAL(a),IFERROR(a,"")="",IFERROR(a="",0)+ISLOGICAL(a),ISERROR(a)+ISLOGICAL(a),(IFERROR(a,"")="")+ISLOGICAL(a)),z,TOCOL(IF({1},cλ(EXPAND(TAKE(TOROW(o),,w),,w,0),EXPAND(TAKE(TOCOL(o),h),h,,0)),a),,c),s,IF(OR(x),LET(y,NOT(x),vλ,LAMBDA(arr,incl,FILTER(TOCOL(arr,,c),TOCOL(incl,,c))),nλ,LAMBDA(arr,incl,TOCOL(IFS(incl,arr),2,c)),sλ,LAMBDA(one,two,IF(m=2,VSTACK(two,one),VSTACK(one,two))),_v1,vλ(a,y),_v2,vλ(a,x),_n1,nλ(cλ(j,i),y),_b1,sλ(_n1,nλ(cλ(j,i),x)),_b2,IF(m,EXPAND(1,h*w,,1),VSTACK(nλ(cλ(i,j),y),nλ(cλ(i,j),x))),IF(TYPE(o)=64,SWITCH(z,1,SORTBY(sλ(SORTBY(_v1,_n1,1,_v1,1),_v2),_b1,1,_b2,1),-1,SORTBY(sλ(SORTBY(_v1,_n1,1,_v1,-1),_v2),_b1,1,_b2,1),TOCOL(a,,c)),SORTBY(sλ(SORTBY(_v1,_n1,1,_v1,o),_v2),_b1,1,_b2,1))),LET(v,TOCOL(a,,c),n,TOCOL(IF({1},cλ(j,i),a),,c),IF(TYPE(o)=64,SWITCH(z,1,SORTBY(v,n,1,v,1),-1,SORTBY(v,n,1,v,-1),v),SORTBY(v,n,1,v,o)))),IF(AND(ISNUMBERS(ignore,1,1),ISNUMBERS(ignore_mode,1,1,{0,1,2,3,4,5,6,7}),ISNUMBERS(sort_orders,1,,{1,-1,""},1),ISNUMBERS(sort_by_row,1,1,{TRUE,FALSE},2)),cλ(WRAPCOLS(s,h),WRAPROWS(s,w)),#VALUE!)))
K5:R11K5=XTYPE(B5:I11,3)
D6D6=IF(1,"")
C9C9=1/0
B14:I20B14=MSORT(B5:I11)
K14:R20K14=MSORT(B5:I11,,,,1)
B22:I28B22=MSORT(B5:I11,,,-1)
K22:R28K22=MSORT(B5:I11,,,-1,1)
B30:I36B30=MSORT(B5:I11,1,1,-1)
K30:R36K30=MSORT(B5:I11,1,,-1,1)
B38:I44B38=MSORT(B5:I11,2,1,-1)
K38:R44K38=MSORT(B5:I11,2,1,-1,1)
B46:I52B46=MSORT(B5:I11,3,1,-1)
K46:R52K46=MSORT(B5:I11,3,1,-1,1)
B54:I60B54=MSORT(B5:I11,4,1,-1)
K54:R60K54=MSORT(B5:I11,4,1,-1,1)
B62:I68B62=MSORT(B5:I11,5,1,-1)
K62:R68K62=MSORT(B5:I11,5,1,-1,1)
B70:I76B70=MSORT(B5:I11,6,1,-1)
K70:R76K70=MSORT(B5:I11,6,1,-1,1)
B78:I84B78=MSORT(B5:I11,7,1,-1)
K78:R84K78=MSORT(B5:I11,7,1,-1,1)
B86:I92B86=MSORT(B5:I11,7,,-1)
K86:R92K86=MSORT(B5:I11,7,,-1,1)
B94:I100B94=MSORT(B5:I11,7,1,{1,1,-1,1,-1,1,1,1})
K94:R100K94=MSORT(B5:I11,7,1,{1,1,-1,1,-1,1,1,1},1)
Dynamic array formulas.
 
Upvote 0

Forum statistics

Threads
1,223,882
Messages
6,175,165
Members
452,615
Latest member
bogeys2birdies

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top