More complicated code, but way simpler syntax:
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[danish]{babel}
\usepackage{xparse,siunitx,booktabs}
\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\nederst}{m}
{
\fp_eval:n { #1 * (#1+1)/2 }
}
\DeclareExpandableDocumentCommand{\iAlt}{m}
{
\fp_eval:n { #1 * ( #1 + 1 ) * ( #1 + 2 ) / 6 }
}
\NewDocumentCommand{\printtable}{smmmm}
{% * = transpose
% #2 = number of iterations
% #3 = column/row headers
% #4 = table preamble
% #5 = entry specs
\svend_preparetable:nnn { #2 } { #3 } { #5 }
\IfBooleanTF{#1}
{ \__svend_make_table_rows:nn { #3 } { #4 } }
{ \__svend_make_table_columns:nn { #3 } { #4 } }
}
\tl_new:N \l_svend_tablebody_tl
\prop_new:N \l_svend_entries_prop
\int_new:N \l_svend_rows_int
\int_new:N \l_svend_columns_int
\cs_new:Npn \svend_prop_item:Nnn #1 #2 #3
{
\prop_item:Nn #1 { #2, #3 }
}
\cs_generate_variant:Nn \svend_prop_item:Nnn { Nnf , Nfn }
\cs_new_protected:Npn \svend_preparetable:nnn #1 #2 #3
{% #1=iterations; #2=column/row headers; #3=specs
\int_set:Nn \l_svend_columns_int { \clist_count:n { #2 } }
\int_set:Nn \l_svend_rows_int { #1 }
\prop_clear:N \l_svend_entries_prop
\int_step_inline:nnnn { 1 } { 1 } { \l_svend_rows_int }
{
\int_step_inline:nnnn { 1 } { 1 } { \l_svend_columns_int }
{
\prop_put:Nnf \l_svend_entries_prop { ##1,####1 }
{
\clist_item:nn { #3 } { ####1 }
}
}
}
}
\cs_generate_variant:Nn \prop_put:Nnn { Nnf }
\cs_new_protected:Npn \__svend_make_table_columns:nn #1 #2
{
% start making the table body
\tl_set:Nn \l_svend_tablebody_tl
{
\begin{tabular}{ #2 }\toprule
}
% the header row
\int_step_inline:nnnn { 1 } { 1 } { \l_svend_columns_int }
{
\tl_put_right:Nx \l_svend_tablebody_tl
{
\int_compare:nF { ##1 == 1 } { & }
{ \clist_item:nn { #1 } { ##1 } }
}
}
\tl_put_right:Nn \l_svend_tablebody_tl { \\ \midrule } % finish the row
% the table body proper
\int_step_inline:nnnn { 1 } { 1 } { \l_svend_rows_int }
{
\int_step_inline:nnnn { 1 } { 1 } { \l_svend_columns_int }
{
\tl_put_right:Nx \l_svend_tablebody_tl
{
\int_compare:nF { ####1 == 1 } { & }
\svend_prop_item:Nnn \l_svend_entries_prop { ##1 } { ####1 }
}
}
\tl_put_right:Nn \l_svend_tablebody_tl { \\ }
}
% finish up the table body
\tl_put_right:Nn \l_svend_tablebody_tl { \bottomrule \end{tabular} }
% produce the table
\tl_use:N \l_svend_tablebody_tl
}
\cs_new_protected:Npn \__svend_make_table_rows:nn #1 #2
{
% start building the table body
\tl_set:Nn \l_svend_tablebody_tl
{
\begin{tabular}{ #2 }\toprule
}
% the table body proper
\int_step_inline:nnnn { 1 } { 1 } { \l_svend_columns_int }
{
\tl_put_right:Nx \l_svend_tablebody_tl
{
\clist_item:nn { #1 } { ##1 } &
}
\int_step_inline:nnnn { 1 } { 1 } { \l_svend_rows_int }
{
\tl_put_right:Nx \l_svend_tablebody_tl
{
\int_compare:nF { ####1 == 1 } { & }
\svend_prop_item:Nnn \l_svend_entries_prop { ####1 } { ##1 }
}
}
\tl_put_right:Nn \l_svend_tablebody_tl { \\ }
}
% finish up the table body
\tl_put_right:Nn \l_svend_tablebody_tl { \bottomrule \end{tabular} }
% produce the table
\tl_use:N \l_svend_tablebody_tl
}
\cs_generate_variant:Nn \prop_item:Nn { Nx }
\ExplSyntaxOff
\begin{document}
\printtable
{6}
{ Long text A, Long text B, Long text C, Long text D, Long text E }
{ *{3}{S[table-format = 1]} *{2}{S[table-format = 2]} }
{ #1,#1,#1,\nederst{#1},\iAlt{#1} }
\bigskip
\printtable*
{6}
{ Opstillingsnummer, Antal lag, Antal bægre i bundes side,
Antal bægre i nederste lag, Antal bægre i optillingen }
{ l *{6}{S[table-format = 2]} }
{ #1,#1,#1,\nederst{#1},\iAlt{#1} }
\bigskip
\printtable
{7}
{ Long text A, Long text B, Long text C, Long text D, Long text E }
{ *{3}{S[table-format = 1]} *{2}{S[table-format = 2]} }
{ #1,#1,#1,\nederst{#1},\iAlt{#1} }
\bigskip
\printtable*
{7}
{ Opstillingsnummer, Antal lag, Antal bægre i bundes side,
Antal bægre i nederste lag, Antal bægre i optillingen }
{ l *{7}{S[table-format = 2]} }
{ #1,#1,#1,\nederst{#1},\iAlt{#1} }
\end{document}

The table entries are computed and stored in a property list, indexed by row,column.
Then the table is printed columnwise (no *) or rowwise, gathering the appropriate index from the property list.
The first argument is the number of iteration, the second argument is the comma separated list of column or row headers (used for determining the number of columns/rows), the third argument is the table preamble; finally come the specifiers, where #1 is used for the current integer.
,) instead of a full stop (.) as decimal separator in the entries? (I can of course wrap the entries in the fifth argument to\printtablein a\numfromsiunitxbut I would like to not have to do this every time (do to laziness).) – Svend Tveskæg Mar 14 '15 at 15:54siunitxfeatures, you should try issuing\sisetup{output-decimal-marker={,}}in the document preamble. – egreg Mar 14 '15 at 15:57