Complex parsing of arguments in new environments

Here's an implementation with LaTeX3 macros.

\documentclass{article}
\usepackage{longtable}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentEnvironment{invoicetable}{mm} % #1 = columns, #2 = column names
 {
  \travers_invoicetable:n { #2 }
 }
 {
  \begin{longtable}{#1}
  \l_travers_tablehead_tl
  \hline
  \endhead
  \l_travers_table_tl
  \end{longtable}
 }

\NewDocumentCommand{\theading}{m}
 {
  \travers_makeline:Nn \l_travers_tablehead_tl { #1 }
 }

\NewDocumentCommand{\tline}{m}
 {
  \travers_makeline:Nn \l_travers_table_tl { #1 }
 }


\tl_new:N \l_travers_tablehead_tl
\tl_new:N \l_travers_table_tl
\tl_new:N \l__travers_linetemp_tl
\tl_new:N \l_travers_lastcol_tl
\seq_new:N \l_travers_colnames_seq

%%% what to do with unknown keys    
\keys_define:nn { travers/invoice }
 {
  unknown .code:n =
 }

% absorb the list of column names and define the keys
\cs_new_protected:Npn \travers_invoicetable:n #1
 {
  \seq_set_split:Nnn \l_travers_colnames_seq { , } { #1 }
  \seq_map_inline:Nn \l_travers_colnames_seq
   {
    \keys_define:nn { travers/invoice }
     {
      ##1 .tl_set:c = { l__travers_name_##1_tl }
     }
   }
  % detach the last column
  \seq_pop_right:NN \l_travers_colnames_seq \l_travers_lastcol_tl
 }

% each line processes the key-value pairs and adds to the table
\cs_new_protected:Npn \travers_makeline:Nn #1 #2
 {
  \tl_clear:N \l__travers_linetemp_tl
  \keys_set:nn { travers/invoice } { #2 }
  \seq_map_inline:Nn \l_travers_colnames_seq
   {
    \tl_put_right:Nv \l__travers_linetemp_tl { l__travers_name_##1_tl }
    \tl_put_right:Nn \l__travers_linetemp_tl { & }
   }
  \tl_put_right:Nv \l__travers_linetemp_tl { l__travers_name_\l_travers_lastcol_tl _tl }
  \tl_put_right:Nn \l__travers_linetemp_tl { \\ }
  \tl_put_right:NV #1 \l__travers_linetemp_tl
 }

\cs_generate_variant:Nn \tl_put_right:Nn { Nv }

\ExplSyntaxOff

\begin{document}
\begin{invoicetable}{r|llr|r}{
  runningnumber,
  description,
  qty,
  sellprice,
  linetotal
}
\theading{
  runningnumber=\#,
  partnumber=Part number,
  description=Description,
  qty=Qty,
  sellprice=Price,
  linetotal=Total
}
\tline{
  runningnumber=1,
  partnumber=A-12232,
  description={Test part, some data},
  qty=4,
  sellprice=14.99,
  linetotal=59.96
}
\end{invoicetable}

\begin{invoicetable}{r|llrr|r}{
  runningnumber,
  partnumber,
  description,
  qty,
  sellprice,
  linetotal
}
\theading{
  runningnumber=\#,
  partnumber=Part number,
  description=Description,
  qty=Qty,
  sellprice=Price,
  linetotal=Total
}
\tline{
  runningnumber=1,
  partnumber=A-12232,
  description={Test part, some data},
  qty=4,
  sellprice=14.99,
  linetotal=59.96
}
\end{invoicetable}

\begin{invoicetable}{r}{
  linetotal
}
\theading{
  runningnumber=\#,
  partnumber=Part number,
  description=Description,
  qty=Qty,
  sellprice=Price,
  linetotal=Total
}
\tline{
  runningnumber=1,
  partnumber=A-12232,
  description={Test part, some data},
  qty=4,
  sellprice=14.99,
  linetotal=59.96
}
\end{invoicetable}

\end{document}

enter image description here


Here is a solution involving xtring:

\documentclass{article}
\usepackage{xstring,longtable}
\makeatletter
\def\line#1{%
    \global\let\tab@keys@i\tab@keys
    \gdef\line@content{#1,}%
    \line@i
}

\def\line@i{%
    \StrCut\tab@keys@i,\current@key\tab@keys@i
    \global\let\tab@keys@i\tab@keys@i
    \IfSubStr\line@content\current@key
        {\StrBehind\line@content\current@key[\current@key]%
        \StrBetween\current@key=,%
        }
        \relax
    \ifx\@empty\tab@keys@i\\%
    \else&\expandafter\line@i
    \fi
}

\def\heading#1{\line{#1}\endhead}

\newenvironment{invoicetable}[2]%
    {\edef\tab@keys{#2,}%
    \expandarg\noexploregroups
    \longtable{#1}%
    }
    \endlongtable

\makeatother
\begin{document}
\begin{invoicetable}{r|llrr|r}{runningnumber,description,qty,sellprice,linetotal}
    \heading{runningnumber=\#,partnumber=Partnumber,description=Description,qty=Qty,sellprice=Price,linetotal=Total}
    \line{runningnumber=1,partnumber=A-12232,description={Test part, some data},qty=4,sellprice=14.99,linetotal=59.96}
\end{invoicetable}
\end{document}