Seite 1 von 1
Leeres Enviroment
Verfasst: Di 10. Nov 2009, 10:45
von 123DrivenHoliday
Hallo,
der Code unten erzeugt den Feher "! Extra }, or forgotten \endgroup <template> \unskip \hfil } \hskip \tabcolsep \endtemplate " und ich versteh einfach nicht warum. Wahrscheinlich habe ich nur ne Kleinigkeit übersehen, wäre nett wenn mir jemand auf die Sprünge helfen könnte.
\documentclass{article}
\begin{document}
\newenvironment{env}%
{%
}{%
}
\begin{tabular}{ccc}
\begin{env}
bla & bli & blubb \\
bla & bli & blubb \\
bla & bli & blubb \\
\end{env}
\end{tabular}
\end{document}
Verfasst: Di 10. Nov 2009, 12:34
von Schweinebacke
Wie bestimmt auch hier im Forum schon mehrfach zu lesen war, ist jede Zelle einer Tabelle eine eigene Gruppe. Du hast also im Endeffekt so etwas:
{% Anfang der ersten Zelle der Tabelle
\begin{env}
bla
}% Ende der ersten Zelle der Tabelle
{bli}{blubb}
{bla}{bli}{blubb}% Zweite Tabellenzeile
{bla}{bli}{blubb}% Dritte Tabellenzeile
{% Anfang einer Zelle einer weiteren Tabellenzeile
\end{env}
}
Wie Du sofort sehen solltest, stimmt also die Gruppenschachtelung nicht. Du musst also entweder jede einzelne Zelle in die Umgebung env-packen oder die gesamte Tabelle. Es geht hingegen nicht, dass Du mehrere Zellen einer Tabelle zusammen in eine Umgebung packst.
Verfasst: Di 10. Nov 2009, 13:26
von 123DrivenHoliday
Danke! Das ist gut zu wissen.
Jetzt ist die Frage wie ich mein Programm dann umsetzte. Ich würde gerne ein Script für eine Zeittabelle schreiben. Die Tabelle soll mehrere Phase beinhalten, die wiederum aus mehreren Vorgänge bestehen. In der Zeittabelle sollen dann die Gesamtstunden pro Phase ausgerechnet werden. Ich stelle mir die Benutzung etwa so vor:
\begin{zeittabelle}
\begin{phase}{Vorbereitung}
\vorgang{Mehl holen}{2}
\vorgang{Eier kaufen}{1}
\end{phase}
\begin{phase}{Backen}
\vorgang{Mehl und Eier verrühren}{2}
\vorgang{Teig backen}{8}
\end{phase}
\begin{phase}{Servieren}
\vorgang{Kuchen glasieren}{2}
\vorgang{Kuchen schneiden}{1}
\end{phase}
\end{zeittabelle}
Es kann natürlich aus ganz anders aussehen, aber das war meine erste Idee. Wichtig ist, dass das Ergebnis wie das Dokument im Anhang aussieht.
Lässt sich sowas überhaupt umsetzten?
Verfasst: Di 10. Nov 2009, 20:34
von phi
Du musst die geöffnete Gruppe einfach gleich wieder schließen und umgekehrt sowie den Konsistenzcheck austricksen:
\makeatletter
\newenvironment{env}{%
\endgroup
\ignorespaces
}{%
\ignorespacesafterend
\begingroup
\def\@currenvir{env}%
}
\makeatother
Verfasst: Mi 11. Nov 2009, 09:29
von Schweinebacke
Ich finde, das ist ein ziemlicher Hack. Man kann das auch sauber machen:
\documentclass{article}
\usepackage[latin1]{inputenc}
\usepackage[table]{xcolor}
\usepackage{booktabs}
\makeatletter
\newcommand*{\zeittabellenzeilen}{}
\newcommand*{\phasenzeilen}{}
\newcounter{Dauer}
\newenvironment{zeittabelle}{%
\global\let\zeittabellenzeilen\@empty
\newenvironment{phase}[1]{%
\setcounter{Dauer}{0}%
\global\let\phasenzeilen\@empty
\g@addto@macro\zeittabellenzeilen{%
\rowcolor{gray!50}\textbf{##1} & \bfseries
}%
\newcommand*{\vorgang}[2]{%
\addtocounter{Dauer}{####2}%
\g@addto@macro\phasenzeilen{\quad ####1 & ####2\tabularnewline}%
}%
}{%
\edef\@tempa{\theDauer}%
\expandafter\g@addto@macro\expandafter\zeittabellenzeilen
\expandafter{\@tempa\,Std.\tabularnewline}%
\expandafter\g@addto@macro\expandafter\zeittabellenzeilen
\expandafter{\phasenzeilen}%
}%
}{%
\begin{tabular}{lr}
\toprule
\textbf{Vorgang} & \textbf{Dauer}\tabularnewline
\midrule
\zeittabellenzeilen
\bottomrule
\end{tabular}
}
\makeatother
\begin{document}
\begin{zeittabelle}
\begin{phase}{Vorbereitung}
\vorgang{Mehl holen}{2}
\vorgang{Eier kaufen}{1}
\end{phase}
\begin{phase}{Backen}
\vorgang{Mehl und Eier verrühren}{2}
\vorgang{Teig backen}{8}
\end{phase}
\begin{phase}{Servieren}
\vorgang{Kuchen glasieren}{2}
\vorgang{Kuchen schneiden}{1}
\end{phase}
\end{zeittabelle}
\end{document}
Der Witz dabei ist, dass die Zeilen nach und nach aufgesammelt und erst ganz zum Schluss zu einer Tabelle montiert werden. Am Ende jeder Phase wird auch automatisch die Dauer ermittelt, etwas was innerhalb einer Tabelle auch nicht ganz trivial ist.
Nachteil dabei ist, dass man die Tabellen und Phasen nicht schachteln darf. Will man das noch, muss man mit \protected@edef statt mit \g@addto@macro arbeiten, wobei man sich genau überlegen muss, was mit \protect zu schützen ist. Das betrifft dann eventuell auch Material in der Tabelle, was bei obigem eher unproblematisch sein sollte.
Ich habe das übrigens nicht komplett alleine gebastelt. Insbesondere bei der richtigen Anzahl an # bei den innen definierten Anweisungen und auch bei der Grundidee mit dem Aufsammeln von Tabellenzeilen habe ich frühere Antworten von KOMA und das Wiki zu Rate gezogen. Deshalb hat mich die Antwort auch etwas Zeit gekostet.
Verfasst: Mi 11. Nov 2009, 13:15
von 123DrivenHoliday
Hallo,
Vielen Dank Schweinebacke^^
Das ist fast schon das was ich brauche. Ich würde jetzt gerne noch eine Spalte einfügen, sodass man eine Soll- und eine Ist-Zeit hat. Ich habs gerade selber probiert, aber nicht hinbekommen. Wäre nett wenn du das noch mal eben machen könntest.
Wenn du ganz viel Lust hast, kannst du auch noch ne Funktion einbauen, die Vorgänge rot makiert, die zuviel Zeit benötigt haben und welche die weniger Zeit gebraucht haben grün. Aber das kriege ich vielleicht auch selber hin.
Verfasst: Do 12. Nov 2009, 13:01
von 123DrivenHoliday
Hallo,
ich hab es alleine hinbekommen. Hier der Code:
\makeatletter
\definecolor{darkGreen}{rgb}{0.45,0.65,0.25}
\newcommand*{\zeittabellenzeilen}{}
\newcommand*{\phasenzeilen}{}
\newcounter{Soll}
\newcounter{Ist}
\newenvironment{zeittabelle}{%
\global\let\zeittabellenzeilen\@empty
\newenvironment{phase}[1]{%
\setcounter{Soll}{0}%
\setcounter{Ist}{0}%
\global\let\phasenzeilen\@empty
\g@addto@macro\zeittabellenzeilen{%
\rowcolor{gray!50}\textbf{##1} & \bfseries
}%
\newcommand*{\vorgang}[3]{%
\addtocounter{Soll}{####2}%
\addtocounter{Ist}{####3}%
\ifnum####2<####3%
\g@addto@macro\phasenzeilen{\quad ####1 & ####2 Std. & \textcolor{red}{####3 Std.}\tabularnewline}%
\else%
\ifnum####2>####3
\g@addto@macro\phasenzeilen{\quad ####1 & ####2 Std. & \textcolor{darkGreen}{####3 Std.}\tabularnewline}%
\else%
\g@addto@macro\phasenzeilen{\quad ####1 & ####2 Std. & ####3 Std. \tabularnewline}%
\fi%
\fi%
}%
}{%
\edef\@tempa{\theSoll}%
\edef\@tempb{\theIst}%
\ifnum\theIst<\theSoll%
\def\@farb{\color{darkGreen}}%´
\else%
\ifnum\theIst>\theSoll%
\def\@farb{\color{red}}%´
\else%
\def\@farb{\color{black}}%´
\fi%
\fi%
\expandafter\g@addto@macro\expandafter\zeittabellenzeilen
\expandafter{\@tempa\,Std. & \bfseries}%
\expandafter\g@addto@macro\expandafter\zeittabellenzeilen
\expandafter{\@farb}%
\expandafter\g@addto@macro\expandafter\zeittabellenzeilen
\expandafter{\@tempb\,Std. \tabularnewline}%
\expandafter\g@addto@macro\expandafter\zeittabellenzeilen
\expandafter{\phasenzeilen}%
}%
}{%
\begin{tabular}{lrr}
\toprule
\textbf{Vorgang} & \textbf{geplante Dauer} & \textbf{tatsächliche Dauer} \tabularnewline
\midrule
\zeittabellenzeilen
\bottomrule
\end{tabular}
}
\makeatother
Ist bestimmt nicht die eleganteste Lösung, aber es funktioniert.
Verfasst: Do 12. Nov 2009, 13:17
von Schweinebacke
Man sollte nicht \theZähler miteinander vergleichen, weil das ja bereits die formatierte Ausgabe eines Zählers ist, sondern eher \value{Zähler}.