You can avoid using many arguments. Here's an implementation of your \cmd where you specify the arguments as a comma separated list; with \selectorder you can decide what order is used in the output.
Note that \cmd will happily accept any number of items in the list; all you need is to specify the correct number of columns in the tabular and precede it with the suitable \selectorder command. I demonstrated this with two tables with four and five columns respectively.
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\cmd}{m}
{
\gablin_cmd:n { #1 }
}
\NewDocumentCommand{\selectorder}{m}
{
\seq_gset_split:Nnn \g_gablin_order_seq { , } { #1 }
}
\prop_new:N \l_gablin_arg_prop
\seq_new:N \l_gablin_output_seq
\seq_new:N \g_gablin_order_seq
\int_new:N \l_gablin_input_int
\cs_new_protected:Npn \gablin_cmd:n #1
{
% clear the variables' contents (it isn't really necessary)
\prop_clear:N \l_gablin_arg_prop
\seq_clear:N \l_gablin_output_seq
\int_zero:N \l_gablin_input_int
% map through the items in the argument
\clist_map_inline:nn { #1 }
{
% the integer variable is used to number the items
\int_incr:N \l_gablin_input_int
% items are stored in a property list
\prop_put:Nfn \l_gablin_arg_prop { \int_to_arabic:n { \l_gablin_input_int } } { ##1 }
}
% map through the items stating the order of items in columns
\seq_map_inline:Nn \g_gablin_order_seq
{
% put the items in a new sequence
\seq_put_right:Nx \l_gablin_output_seq
{
\prop_get:Nn \l_gablin_arg_prop { ##1 }
}
}
% use the sequence, separating arguments with &
\seq_use:Nn \l_gablin_output_seq { & }
}
% we need a variant of \prop_put:Nnn store a number in the key
\cs_generate_variant:Nn \prop_put:Nnn { Nf }
\ExplSyntaxOff
\begin{document}
\selectorder{1,2,3,4}
\begin{tabular}{*{4}{c}}
\cmd{aa,ab,ac,ad} \\
\cmd{ba,bb,bc,bd} \\
\cmd{ca,cb,cc,cd} \\
\end{tabular}
\bigskip
\selectorder{5,4,3,2,1}
\begin{tabular}{*{5}{c}}
\cmd{aa,ab,ac,ad,ae} \\
\cmd{ba,bb,bc,bd,be} \\
\cmd{ca,cb,cc,cd,ce} \\
\end{tabular}
\end{document}
The setting defined by \selectorder will remain valid until countermanded by another choice and is global, so it doesn't matter if it's issued in a table environment. So this code is very flexible.

;-)– egreg Apr 07 '14 at 21:08