Du möchtest die Macros expandieren, bevor du sie übergibst. Dies geht am einfachsten mittels eines Helfer-Macros:
\documentclass[margin=5mm]{standalone}
\usepackage{tikz}
\newcounter{dummy}
\makeatletter
\def\getNoOfElements#1#2{%
\begingroup
\edef\tmp{#1}%
\expandafter
\endgroup
\expandafter\getNoOfElements@b\expandafter{\tmp}{#2}%
}
\def\getNoOfElements@b#1#2{%
\setcounter{dummy}{0}%
\foreach\dummy in {#1}{\stepcounter{dummy}}%
\edef#2{\arabic{dummy}}
}
\makeatother
\begin{document}
Geht:
\getNoOfElements{a,b,c,d,e,f}\No % save the value in \No
\No
~~Geht nicht:
\def\Liste{1,2,3,4}
\getNoOfElements{\Liste}\No
\No
\end{document}
**Zu Prokrastinierungszwecken:**
Eine vollständig expandierbare Version des Zählens, die genau 2 Expansionen benötigt. Es gibt zwei Varianten, `\getNoOfElements` und `\getNoOfElementsE`, die Erste zählt das Argument unverändert, die Zweite expandiert den ersten Token einmalig. Ich hoffe, der Code ist ausreichend kommentiert.
\documentclass[margin=5mm]{standalone}
\makeatletter
% \q@stop ist ein Marker und markiert das Ende der Liste
\def\q@stop{\q@stop}
% führt sein Argument nach \fi aus (schneller als \expandafter\@firstofone)
\long\def\@afterfi#1\fi{\fi#1}
\def\getNoOfElements#1%
{%
% \romannumeral ist nicht zwingend notwendig, sorgt aber dafür, dass genau 2
% Expansionen ausreichen.
\romannumeral-`\0%
irgendwas mit Zahlen
\the\numexpr
% ein leeres Argument führt zum Ergebnis 0
\if\relax\detokenize{#1}\relax
0%
\else
% sonst zählen wir die Anzahl an Kommata und addieren 1 hinzu
\@afterfi{\the\numexpr1\getNoOfElements@#1,\q@stop}%
\@afterfi{1\getNoOfElements@#1,\q@stop}%
\fi
% \relax beendet \romannumeral
\numexpr
\relax
}
% zweite Variante, die das Argument einmal expandiert
\def\getNoOfElementsE#1%
{%
% erneut \romannumeral für die Expandierbarkeit in 2 Schritten
\romannumeral-`\0%
% irgendwas mit Zahlen
\the\numexpr
% ein leeres Argument überprüfen
führt zum Ergebnis 0
\if\relax\detokenize\expandafter{#1}\relax
0%
\else
% Ausführen des Zählens nach einmaliger Expansion
\@afterfi{\the\numexpr1\expandafter\getNoOfElements@#1,\q@stop}%
sonst zählen wir die Anzahl an Kommata und addieren 1 hinzu
\@afterfi{1\expandafter\getNoOfElements@#1,\q@stop}%
\fi
% beenden von \romannumeral
\relax beendet \numexpr
\relax
}
\def\getNoOfElements@#1,#2%
{%
% überprüfen, ob das Zeilenende hinter #2 ist absichtlich nicht auskommentiert und beendet
% die \numexpr
\ifx\q@stop#2
Ende der Liste erreicht ist
\ifx\q@stop#2%
\else
% ist die Liste noch nicht beendet, addiere 1 und suche das nächste Komma
\@afterfi{+1\getNoOfElements@}%
\fi
}
\makeatother
\usepackage{unravel}
\begin{document}
Geht:
\getNoOfElements{a,b,c,d,e,f} % save the value in \No
~~Geht nicht:
\def\Liste{1,2,3,4}
\getNoOfElementsE{\Liste}
\end{document}