Due to the 30000-character-limit I needed to split my answer in two parts.
This is part 2 of my answer.
Part 1 contains considerations, explanations and thoughts.
Part 2 contains a compilable example which is referred in part 1.
If you wish to upvote, please upvote only one of the two parts. This prevents unfair reputation-gain. If you wish to downvote, dovnvote whichever part(s) you like to downvote.
The promised example:
%\listfiles
%\errorcontextlines=10000
\documentclass[final,a4paper,11pt,oneside,openany]{memoir}
%\documentclass[final,a4paper,11pt,oneside,openany]{book}
\usepackage{datatool}
\usepackage{xparse}
\usepackage{hyperref}
\usepackage{atveryend}
\usepackage{rerunfilecheck}
\usepackage{verbatim}
\makeatletter
%========================================================================
% \immediategroup{<balanced text>}%
%------------------------------------------------------------------------
% A local scope wherein <balanced text> is carried out while \write,
% \closeout and \openout are patched to work in terms of \immediate.
%------------------------------------------------------------------------
\newcommand\immediategroup[1]{%
\begingroup
@ifdefinable\MyStuffsavedwrite{\let\MyStuffsavedwrite\write}%
@ifdefinable\MyStuffsavedopenout{\let\MyStuffsavedopenout\openout}%
@ifdefinable\MyStuffsavedcloseout{\let\MyStuffsavedcloseout\closeout}%
\def\write{\immediate\MyStuffsavedwrite}%
\def\openout{\immediate\MyStuffsavedopenout}%
\def\closeout{\immediate\MyStuffsavedcloseout}%
#1%
\endgroup
}%
%========================================================================
% \DATABASEFILECreateIfNotExistent{<base-name of databases and of .csv-file>}%
% {<separator>}%
% {<delimiter>}%
% - Creates database of name: <base-name of databases and of .csv-file>DataFromPreviousLaTeXRun
% - Creates database of name: <base-name of databases and of .csv-file>DataToBeWrittenAtEndOfThisLaTeXRun
% These databases exist in TeX's memory during the LaTeX-run.
% - Triggers the writing of file <base-name of databases and of .csv-file>.csv
% at the end of the LaTeX-run from the content of the database
% <base-name of databases and of .csv-file>DataToBeWrittenAtEndOfThisLaTeXRun
% - Initializes Counter-macro <base-name of databases and of .csv-file>DataToBeWrittenAtEndOfThisLaTeXRunCnt
% to 0. That counter-macro is to hold the value of the field "PrimaryKey" of the data-base
% <base-name of databases and of .csv-file>DataToBeWrittenAtEndOfThisLaTeXRun
% and is incremented always right before writing another line/row to the that database.
%
% The memory-database <base-name of databases and of .csv-file>DataFromPreviousLaTeXRun is
% used for retrieving data. In case the file <base-name of databases and of .csv-file>.csv
% exists that database is initialized by reading that file. Otherwise it is
% initialized empty.It is not modified during the LaTeX-run.
% The data stems from the previous LaTeX-run.
%
% The memory-database <base-name of databases and of .csv-file>DataToBeWrittenAtEndOfThisLaTeXRun is
% used for writing/storing entries during the LaTeX-run. It is initialized empty.
% It is modified during the LaTeX-run. At the end of the LaTeX-run it is saved as
% file <base-name of databases and of .csv-file>.csv .
%
% At the end of the LaTeX-run both databases are compared. If they differ, then
% something has changed and you are informed that you need to do another LaTeX-run.
%
% <separator> is the separator of values in the .csv-file. Usually this is comma (,)
% , but in your question you specified that you wish to use semicolon (;).
%
% <delimiter>: In case a value contains <separator> it needs to be nested
% between two instances of <delimiter>. <delimiter> usually is the quotes-character (").
%------------------------------------------------------------------------
\newcommand\DATABASEFILECreateIfNotExistent[3]{%
\DTLifdbexists{#1DataFromPreviousLaTeXRun}{}{%
\begingroup
\DTLsetseparator{#2}%
\DTLsetdelimiter{#3}%
\IfFileExists{#1.csv}{%
\DTLloaddb{#1DataFromPreviousLaTeXRun}{#1.csv}%
}{%
\DTLgnewdb{#1DataFromPreviousLaTeXRun}%
}%
\endgroup
}%
\DTLifdbexists{#1DataToBeWrittenAtEndOfThisLaTeXRun}{}{%
\DTLgnewdb{#1DataToBeWrittenAtEndOfThisLaTeXRun}%
% --- Counter-macro for primary-key of database ---
\expandafter@ifdefinable\csname#1DataToBeWrittenAtEndOfThisLaTeXRunCnt\endcsname{%
\expandafter\long\expandafter\gdef\csname#1DataToBeWrittenAtEndOfThisLaTeXRunCnt\endcsname{0}%
}%
% -------------------------------------------------
\AfterLastShipout{%
% This will save the ..DataToBeWrittenAtEndOfThisLaTeXRun-
% database to file after the last \shipout. The last \shipout
% is triggered by \end{document}/\enddocument.
\immediategroup{%
\DTLsetseparator{#2}%
\DTLsetdelimiter{#3}%
\RerunFileCheck{#1.csv}{}{Database #1' may have changed. Rerun LaTeX to get listings of database-entries etc right}% \DTLsavedb{#1DataToBeWrittenAtEndOfThisLaTeXRun}{#1.csv}% }% %% Check if content of database-token-register stemming from %% database-file of previous LaTeX-run differs from content of %% database-token-register stemming from database-file of %% the current LaTeX-run. %% If so, something changed and you need to re-run LaTeX. %% Probably this should be omitted with large databases. %% Therefore this is turned into comments and a tesr via %% \RerunFileCheck is used instead. %\begingroup %\DTLsetseparator{#2}% %\DTLsetdelimiter{#3}% %\DTLgcleardb{#1DataToBeWrittenAtEndOfThisLaTeXRun}% %\DTLnewdbonloadfalse %\DTLloaddb{#1DataToBeWrittenAtEndOfThisLaTeXRun}{#1.csv}% %\edef\tempa{% % \the\csname dtldb@#1DataFromPreviousLaTeXRun\endcsname % \the\csname dtlkeys@#1DataFromPreviousLaTeXRun\endcsname % \the\csname dtlrows@#1DataFromPreviousLaTeXRun\endcsname % \the\csname dtlcols@#1DataFromPreviousLaTeXRun\endcsname %}% %\edef\tempb{% % \the\csname dtldb@#1DataToBeWrittenAtEndOfThisLaTeXRun\endcsname % \the\csname dtlkeys@#1DataToBeWrittenAtEndOfThisLaTeXRun\endcsname % \the\csname dtlrows@#1DataToBeWrittenAtEndOfThisLaTeXRun\endcsname % \the\csname dtlcols@#1DataToBeWrittenAtEndOfThisLaTeXRun\endcsname %}% %\ifx\tempa\tempb % \endgroup %\else % \endgroup % \@latex@warning@no@line{% % Database#1' may have changed.
% Rerun to get listings of entries etc right%
% }%
%\fi
}%
}%
}%
%=========================================================================
% Infrastructure for triggering a warning in case the value of a document-
% wide property was requested at a moment in time when the property didn't
% exist (yet).
%-------------------------------------------------------------------------
\AfterLastShipout{\PropertyValuesNotFound}%
\newcommand\PropertyValuesNotFound{}%
\newcommand\PropertyValuesNotFoundTrue{%
\gdef\PropertyValuesNotFound{@latex@warning@no@line {There were undefined properties}}%
}%
\ExplSyntaxOn
%=========================================================================
% Property-List for properties that are to be maintained document-wide
% during the LaTeX-run. Values can change during the LaTeX-run.
% If you want to store the values which some properties have at a specific
% moment in time during the LaTeX-run, you can use the macro
% \DatabaseRowFromSomeOfThisDocumentsProperties
% for storing these properties' current values as another row of a
% database of name <base-name of databases and of .csv-file>DataToBeWrittenAtEndOfThisLaTeXRun
%-------------------------------------------------------------------------
\prop_new:N {\g__MyStuff_ThisDocumentsProperties_prop}
\prop_gput:Nnn \g__MyStuff_ThisDocumentsProperties_prop{Primary-Key}{0}
%=========================================================================
% expl3-scratch-variables:
%-------------------------------------------------------------------------
\tl_new:N {\l__MyStuff_ExtractedProperty_tl}
\clist_new:N{\l__MyStuff_PropertyNames_clist}
\bool_new:N \g__MyStuff_NewDatabaseRow_bool
\cs_new:Nn __MyStuff_ExpandedDatabaseName: {}
%=========================================================================
% Set document-wide properties' values globally by providing a
% <property1>=<value1>, <property2>=<value2>, ..., <propertyN>=<valueN>-list:
% \SetSomeOfThisDocumentsPropertiesFromKeyValList{%
% <property1>=<value1>, <property2>=<value2>, ..., <propertyN>=<valueN>
% }%
%
% If a property doesn't exist it is created anew automatically.
% If a property does exist, its value is overridden.
%-------------------------------------------------------------------------
\NewDocumentCommand{\SetSomeOfThisDocumentsPropertiesFromKeyValList}{m}{
\keyval_parse:NNn __MyStuff_GSetSomeOfThisDocumentsPropertiesFromKeyValList:n
__MyStuff_GSetSomeOfThisDocumentsPropertiesFromKeyValList:nn
{#1}
}
\cs_new:Nn __MyStuff_GSetSomeOfThisDocumentsPropertiesFromKeyValList:n {
__MyStuff_GSetSomeOfThisDocumentsPropertiesFromKeyValList:nn {#1}{\DTLstringnull}
}
\cs_new:Nn __MyStuff_GSetSomeOfThisDocumentsPropertiesFromKeyValList:nn {
\group_begin:
\cs_set:Npn \protect { \noexpand\protect\noexpand }
\exp_args:Nnx \use:n
{
\exp_args:Nnx \use:n
{ \prop_gput:Nnn \g__MyStuff_ThisDocumentsProperties_prop }
{#1}
}
{#2}
% \prop_gput:Nxx \g__MyStuff_ThisDocumentsProperties_prop{#1}{#2}
\group_end:
}
%=========================================================================
% Create a row of a database
% <base-name of databases and of .csv-file>DataToBeWrittenAtEndOfThisLaTeXRun
% from current values of document-wide properties by specifying a comma-
% separated list of property-names.
% Names of properties will be used as names of fields/columns of the database.
% If a field/column doesn't yet exist in the database, it will be created automatically.
% If the database itself doesn't exist, it will be created automatically
% by \DATABASEFILECreateIfNotExistent. (That's why you need to specify
% <separator> and <delimiter>.)
% If a property doesn't exist, an error-message is raised and datatool's
% null-value for strings is provided as value to the database.
%
% \DatabaseRowFromSomeOfThisDocumentsProperties{<base-name of databases and of .csv-file>}%
% {<separator>}%
% {<delimiter>}%
% {<Property1>, <Property2>,..., <PropertyN>}%
%
%-------------------------------------------------------------------------
\NewDocumentCommand{\DatabaseRowFromSomeOfThisDocumentsProperties}{mmmm}{
\bool_gset_true:N \g__MyStuff_NewDatabaseRow_bool
\cs_set:Nx __MyStuff_ExpandedDatabaseName: {#1DataToBeWrittenAtEndOfThisLaTeXRun}
\exp_args:Nx \DATABASEFILECreateIfNotExistent{#1}{#2}{#3}
\clist_set:Nn \l__MyStuff_PropertyNames_clist {#4}
\cs_gset:cpx {__MyStuff_ExpandedDatabaseName: Cnt}
{\number\numexpr\use:c{__MyStuff_ExpandedDatabaseName: Cnt}+1\relax}
\exp_args:Nnx \use:n
{
\prop_gput:Nnn \g__MyStuff_ThisDocumentsProperties_prop {PrimaryKey}
}
{\use:c{__MyStuff_ExpandedDatabaseName: Cnt}}
% \prop_gput:Nxx \g__MyStuff_ThisDocumentsProperties_prop {PrimaryKey} {\use:c{__MyStuff_ExpandedDatabaseName: Cnt}}
__MyStuff_DatabaseEntryFromThisDocumentsProperty:n {PrimaryKey}
\clist_map_function:NN \l__MyStuff_PropertyNames_clist __MyStuff_DatabaseEntryFromThisDocumentsProperty:x
}
\cs_new:Nn __MyStuff_DatabaseEntryFromThisDocumentsProperty:n {
\prop_get:NnN \g__MyStuff_ThisDocumentsProperties_prop {#1} \l__MyStuff_ExtractedProperty_tl
\exp_args:NV \quark_if_no_value:nTF \l__MyStuff_ExtractedProperty_tl {
\protect\PropertyValuesNotFoundTrue
% I am too lazy to delve into expl3's l3msg
@latex@warning{Macro~ \token_to_str:N\DatabaseRowFromSomeOfThisDocumentsProperties:\space
Property~#1'~undefined~-~using~value~\DTLstringnull\space instead~-} \tl_set:Nn \l__MyStuff_ExtractedProperty_tl {\DTLstringnull} }{} \__MyStuff_DatabaseRowFromPropertyAndValue:onV \__MyStuff_ExpandedDatabaseName: {#1} \l__MyStuff_ExtractedProperty_tl } \cs_generate_variant:Nn \__MyStuff_DatabaseEntryFromThisDocumentsProperty:n {x} \cs_new:Nn \__MyStuff_DatabaseRowFromPropertyAndValue:nnn { \DTLifhaskey{#1}{#2}{}{ \DTLaddcolumn{#1}{#2} } \bool_if:NTF \g__MyStuff_NewDatabaseRow_bool{ \DTLnewrow{#1} }{} \bool_gset_false:N \g__MyStuff_NewDatabaseRow_bool \group_begin: % \cs_set:Npn \protect { \noexpand\protect\noexpand } \cs_set:Npn \protect { \token_to_str:N } \exp_args:Nnx \use:n {\DTLnewdbentry{#1}{#2}} {#3} \group_end: } \cs_generate_variant:Nn \__MyStuff_DatabaseRowFromPropertyAndValue:nnn{onV} %========================================================================= % Retrieve the current value of a document-wide property. % % \GetDocumentsPropertyValue{<Property>} % % If a property doesn't exist, an error-message is raised and the % tokens \textsf{??} are provided. % % Not used in the following code. But I wasn't aware of that at the time % of composing all this. Probably it may be useful in other scenarios. %------------------------------------------------------------------------- \NewDocumentCommand{\GetDocumentsPropertyValue}{m}{ \__GetDocumentsPropertyValue:x{#1} } \cs_new:Nn \__GetDocumentsPropertyValue:n { \prop_get:NnN \g__MyStuff_ThisDocumentsProperties_prop {#1} \l__MyStuff_ExtractedProperty_tl \exp_args:NV \quark_if_no_value:nTF \l__MyStuff_ExtractedProperty_tl { \protect\PropertyValuesNotFoundTrue % I am too lazy to delve into expl3's l3msg \@latex@warning{Macro~\token_to_str:N\GetDocumentsPropertyValue:\space Property~#1'~undefined~-~using~value~\token_to_str:N\textsf{??}~instead~-}
\tl_set:Nn \l__MyStuff_ExtractedProperty_tl {\textsf{??}}
}{}
\tl_use:N \l__MyStuff_ExtractedProperty_tl
}
\cs_generate_variant:Nn __GetDocumentsPropertyValue:n {x}
%=========================================================================
% Via datatool-package's \DTLforeach iterate on the rows
% of the database <base-name of databases and of .csv-file>DataFromPreviousLaTeXRun.
%
% If the database itself doesn't exist, it will be created automatically
% by \DATABASEFILECreateIfNotExistent. (That's why you need to specify
% <separator> and <delimiter>.)
%
% \DoWithDatabaseProperties{<base-name of databases and of .csv-file>}%
% {<separator>}%
% {<delimiter>}%
% [<condition>]%
% {<assign list>}%
% {<text>}%
%
% <base-name of databases and of .csv-file>, <separator> and <delimiter> are
% the same as above.
% <condition>, <assign list> and <text> are the same as with \DTLforeach
% of the datatool-package.
%-------------------------------------------------------------------------
\NewDocumentCommand\DoWithDatabaseProperties{mmmo}{
\exp_args:Nx \DATABASEFILECreateIfNotExistent {#1}{#2}{#3}
\IfNoValueTF{#4}{\exp_args:Nnx \use:n {\DTLforeach}}
{\exp_args:Nnx \use:n {\DTLforeach[{#4}]}}
{#1DataFromPreviousLaTeXRun}
}
\ExplSyntaxOff
\makeatother
%=========================================================================
% Now the individual building blocks of the infrastructure for managing
% document-wide properties via databases and .csv files are in place.
% They can now be used for implementing the macros at user level, which
% is straightforward:
%=========================================================================
% \ListOf...-commands can easily be implemented in terms of
% \DoWithDatabaseProperties.
%
% A scratch-switch which can be initialized by the \ListOf...-command
% and toggled by \DoWithDatabaseProperties's <text>-argument. This
% switch is intended to indicate whether at least one row of the
% database already ended up as an entry of the list.
%
% E.g., only in this case a heading for the list in question is needed.
% Only in this case starting/ending some environment is needed, e.g.,
% description or tabular.
%
\newif\ifNoDatabaseEntryEndedUpInTheListYet
\global\NoDatabaseEntryEndedUpInTheListYettrue
%=========================================================================
% An example of how to implement \ListOfFenster by means of
% nested description-environments and \DoWithDatabaseProperties (whose
% underlying macro is \DTLforeach):
%-------------------------------------------------------------------------
\newcommand\ListOfFenster{%
\global\NoDatabaseEntryEndedUpInTheListYettrue
\DoWithDatabaseProperties{Parts}{;}{"}%
[{\equal{Fenster}{\ArtDesTeils}}]%
{%
\PrimaryKey=PrimaryKey,%
\NummerDesTeils=NummerDesTeils,%
\ArtDesTeils=ArtDesTeils,%
\Stockwerkname=Stockwerkname,%
\Zimmer=Zimmer,%
\Ausmasze=Ausmasze,%
\Ausfuehrung=Ausfuehrung,%
\Insektenschutz=Insektenschutz,%
\Kommentar=Kommentar,%
\Destination=Destination%
}%
{%
\ifNoDatabaseEntryEndedUpInTheListYet
\global\NoDatabaseEntryEndedUpInTheListYetfalse
\section*{Liste der Fenster}%
\begin{description}%
\fi
\item[\hyperlink
{\Destination}%
{%
\PrintAssignListElement\NummerDesTeils
~(\PrintAssignListElement\Stockwerkname,
\PrintAssignListElement\Zimmer)%
}]\hfill\null
\begin{description}%
\AssignListElementDescriptionItem{\Ausmasze}{Maße}%
\AssignListElementDescriptionItem{\Ausfuehrung}{Ausführung}%
\AssignListElementDescriptionItem{\Insektenschutz}{Insektenschutz}%
\AssignListElementDescriptionItem{\Kommentar}{Kommentar}%
\end{description}%
}%
\ifNoDatabaseEntryEndedUpInTheListYet\else\end{description}\fi
}%
\newcommand\PrintAssignListElement[1]{\DTLifnull{#1}{\textsf{??}}{#1}}%
\newcommand\AssignListElementDescriptionItem[2]{%
\DTLifnullorempty{#1}{%
\DTLifnull{#1}{\item[{#2:}]\PrnProp\textsf{??}}{}%
}{%
\item[{#2:}]#1%
}%
}%
%=========================================================================
% Some elements of your database of parts shall come from the arguments
% of commands like \chapter or \section.
% One could patch these commands to also fulfill the purpose of
% setting the corresponding document-wide properties' values.
% Instead I define variants of these commands with slightly different
% names which set the corresponding document-wide properties' values
% and call the corresponding sectioning-commands:
%=========================================================================
\newcommand\FloorChapter[1]{%
\SetSomeOfThisDocumentsPropertiesFromKeyValList{Stockwerkname=#1}%
\chapter{#1}%
}
\newcommand\RoomSection[1]{%
\SetSomeOfThisDocumentsPropertiesFromKeyValList{Zimmer=#1}%
\section{#1}%
}%
%=========================================================================
% The \Fenster-Command sets some document-wide properties from its
% arguments, delivers an RQ-environment, sets some other document-wide
% property from the current value of the counter underlying the RQ-environment
% and then creates a(nother) database-row from the current values of
% the document-wide properties:
%=========================================================================
\newcommand\Fenster[4]{%
\SetSomeOfThisDocumentsPropertiesFromKeyValList{%
ArtDesTeils=Fenster,
Ausmasze=#1, Ausfuehrung=#2, Insektenschutz=#3, Kommentar=#4%
}%
\begin{RQ}
Fenster mit 3-Scheiben Isolierverglasung, mit Rolladen und Fensterbank.\
Ausmaße: #1.\
Ausführung: #2.\
Insektenschutz: #3.\
\textit{Farbe: Innen Weiß, Außen weiß; Beschlag: Silber.}%
\ifcat$\detokenize{#4}$\else\Kommentar: #4\fi
\end{RQ}
\SetSomeOfThisDocumentsPropertiesFromKeyValList{%
NummerDesTeils=Neu\protect~\thereqcounter,
Destination=\csname @currentHref\endcsname
}%
\DatabaseRowFromSomeOfThisDocumentsProperties{Parts}{;}{"}{%
NummerDesTeils, ArtDesTeils, Stockwerkname, Zimmer, Ausmasze,
Ausfuehrung, Insektenschutz, Kommentar, Destination,
}%
}%
\usepackage[naustrian]{babel}
\usepackage[thmmarks]{ntheorem}
\usepackage{thm-restate}
\newcounter{reqcounter}
\newtheorem{RQ}[reqcounter]{Neu}
\begin{document}
\ListOfFenster
\FloorChapter{Erdgeschoss}
\RoomSection{Toilette}
\Fenster{50/80}{1 flg Keinkipp mitte}{Fixrahmen von aussen einsehbar}{Kommentar zu diesem Fenster}
\FloorChapter{Dachgeschoss}
\RoomSection{Wohnzimmer}
\Fenster{130/150}{1 flg Drehkipp rechts}{Fixrahmen von innen abnehmbar}{}
This is the content of the automatically created .csv-file \verb|Parts.csv|,:
\begingroup
\tiny
\verbatiminput{Parts.csv}
\endgroup
And once more:
\ListOfFenster
\end{document}
Images of the .pdf-output:

The file Parts.csv, which is written automatically during LaTeX-runs:
PrimaryKey;NummerDesTeils;ArtDesTeils;Stockwerkname;Zimmer;Ausmasze;Ausfuehrung;Insektenschutz;Kommentar;Destination
1;Neu~1;Fenster;Erdgeschoss;Toilette;50/80;1 flg Keinkipp mitte;Fixrahmen von aussen einsehbar;Kommentar zu diesem Fenster;RQ.1
2;Neu~2;Fenster;Dachgeschoss;Wohnzimmer;130/150;1 flg Drehkipp rechts;Fixrahmen von innen abnehmbar;;RQ.2
TeX-distribution/format/documentclass/packages/files in use - excerpt from the .log-file, created while uncommenting the \listfiles-command:
pdfTeX, Version 3.14159265-2.6-1.40.21 (TeX Live 2020) (preloaded format=pdflatex)
LaTeX2e <2020-10-01> patch level 4
L3 programming layer <2021-02-18>
memoir.cls -- 2020/10/04 v3.7n configurable book, report, article document class
(
Package abstract [2008/07/23] emulated by memoir.
Package appendix [2008/07/23] emulated by memoir.
Package booktabs [2016/05/16] emulated by memoir.
Package ccaption [2008/07/23] emulated by memoir.
Package changepage [2008/07/23] emulated by memoir.
Package chngcntr [2008/07/23] emulated by memoir.
Package chngpage [2008/07/23] emulated by memoir.
Package crop emulated by memoir.
Package enumerate [2008/07/23] emulated by memoir.
Package epigraph [2008/07/23] emulated by memoir.
Package ifmtarg [2008/07/23] emulated by memoir.
Package index [2008/07/23] emulated by memoir.
Package makeidx [2008/07/23] emulated by memoir.
Package moreverb [2008/07/23] emulated by memoir.
Package mparhack [2008/07/23] emulated by memoir.
Package needspace [2008/07/23] emulated by memoir.
Package newfile [2008/07/23] emulated by memoir.
Package nextpage [2008/07/23] emulated by memoir.
Package pagenote [2008/07/23] emulated by memoir.
Package parskip [2008/07/23] emulated by memoir.
Package patchcmd [2008/07/23] emulated by memoir.
Package setspace [2008/07/23] emulated by memoir.
Package shortvrb [2008/07/23] emulated by memoir.
Package showidx [2008/07/23] emulated by memoir.
Package titleref [2008/07/23] emulated by memoir.
Package titling [2008/07/23] emulated by memoir.
Package tocbibind [2008/07/23] emulated by memoir.
Package tocloft [2008/07/23] emulated by memoir.
Package tocvsec2 [2008/07/23] emulated by memoir.
Package verbatim [2008/07/23] emulated by memoir.
Package verse [2008/07/23] emulated by memoir.
)
aliasctr.sty -- 2020/08/01 v0.72
amsbsy.sty -- 1999/11/29 v1.2d Bold Symbols
amsgen.sty -- 1999/11/30 v2.0 generic functions
amsmath.sty -- 2020/09/23 v2.17i AMS math features
amsopn.sty -- 2016/03/08 v2.02 operator names
amstext.sty -- 2000/06/29 v2.01 AMS text
array.sty -- 2020/10/01 v2.5c Tabular extension package (FMi)
atbegshi-ltx.sty -- 2020/08/17 v1.0a Emulation of the original atbegshi package with kernel methods
atveryend-ltx.sty -- 2020/08/19 v1.0a Emulation of the original atvery package with kernel methods
auxhook.sty -- 2019-12-17 v1.6 Hooks for auxiliary files (HO)
babel.sty -- 2021/02/22 3.54 The Babel package
bigintcalc.sty -- 2019/12/15 v1.5 Expandable calculations on big integers (HO)
bitset.sty -- 2019/12/09 v1.3 Handle bit-vector datatype (HO)
datatool-base.sty -- 2019/09/27 v2.32 (NLCT)
datatool-fp.sty -- 2019/09/27 v2.32 (NLCT)
datatool.sty -- 2019/09/27 v2.32 (NLCT)
dcolumn.sty -- 2014/10/28 v1.06 decimal alignment package (DPC)
defpattern.sty -- 1994/10/12
delarray.sty -- 2014/10/28 v1.01 array delimiter package (DPC)
etexcmds.sty -- 2019/12/15 v1.7 Avoid name clashes with e-TeX commands (HO)
etoolbox.sty -- 2020/10/05 v2.5k e-TeX tools for LaTeX (JAW)
expl3.sty -- 2021-02-18 L3 programming layer (loader)
fp-addons.sty -- 1995/03/15
fp-basic.sty -- 1996/05/13
fp-eqn.sty -- 1995/04/03
fp-eval.sty -- 1995/04/03
fp-exp.sty -- 1995/04/03
fp-pas.sty -- 1994/08/29
fp-random.sty -- 1995/02/23
fp-snap.sty -- 1995/04/05
fp-trigo.sty -- 1995/04/14
fp-upn.sty -- 1996/10/21
gettitlestring.sty -- 2019/12/15 v1.6 Cleanup title references (HO)
hpdftex.def -- 2021-02-10 v7.00j Hyperref driver for pdfTeX
hycolor.sty -- 2020-01-27 v1.10 Color options for hyperref/bookmark (HO)
hyperref-langpatches.def -- 2021-02-10 v7.00j Hyperref: patches for babel languages
hyperref.sty -- 2021-02-10 v7.00j Hypertext links for LaTeX
iftex.sty -- 2020/03/06 v1.0d TeX engine tests
ifthen.sty -- 2014/09/29 v1.1c Standard LaTeX ifthen package (DPC)
infwarerr.sty -- 2019/12/03 v1.5 Providing info/warning/error messages (HO)
intcalc.sty -- 2019/12/15 v1.3 Expandable calculations with integers (HO)
kvdefinekeys.sty -- 2019-12-19 v1.6 Define keys (HO)
kvoptions.sty -- 2020-10-07 v3.14 Key value format for package options (HO)
kvsetkeys.sty -- 2019/12/15 v1.18 Key value parser (HO)
l3backend-pdftex.def -- 2021-02-18 L3 backend support: PDF output (pdfTeX)
letltxmacro.sty -- 2019/12/03 v1.6 Let assignment for LaTeX macros (HO)
ltxcmds.sty -- 2020-05-10 v1.25 LaTeX kernel commands for general use (HO)
mem11.clo -- 2008/01/30 v0.3 memoir class 11pt size option
memhfixc.sty -- 2019/10/24 v1.18 nameref/hyperref package fixes for memoir class
nameref.sty -- 2021-04-02 v2.47 Cross-referencing by name of section
naustrian.ldf -- 2020/07/21 v2.12 German support for babel (post-1996 orthography)
ntheorem.sty -- 2011/08/15 1.33
parseargs.sty -- 2020/08/01 v0.72
pd1enc.def -- 2021-02-10 v7.00j Hyperref: PDFDocEncoding definition (HO)
pdfescape.sty -- 2019/12/09 v1.15 Implements pdfTeX's escape features (HO)
pdftexcmds.sty -- 2020-06-27 v0.33 Utility functions of pdfTeX for LuaTeX (HO)
puenc.def -- 2021-02-10 v7.00j Hyperref: PDF Unicode definition (HO)
refcount.sty -- 2019/12/15 v3.6 Data extraction from label references (HO)
rerunfilecheck.sty -- 2019/12/05 v1.9 Rerun checks for auxiliary files (HO)
substr.sty -- 2009/10/20 v1.2 Handle substrings
tabularx.sty -- 2020/01/15 v2.11c `tabularx' package (DPC)
textcase.sty -- 2019/09/14 v1.00 Text only upper/lower case changing (DPC)
thm-autoref.sty -- 2020/08/01 v0.72
thm-kv.sty -- 2020/08/01 v0.72
thm-listof.sty -- 2020/08/01 v0.72
thm-ntheorem.sty -- 2020/08/01 v0.72
thm-patch.sty -- 2020/08/01 v0.72
thm-restate.sty -- 2020/08/01 v0.72
thmtools.sty -- 2020/08/01 v0.72
uniquecounter.sty -- 2019/12/15 v1.4 Provide unlimited unique counter (HO)
url.sty -- 2013/09/16 ver 3.4 Verb mode for urls, etc.
xfor.sty -- 2009/02/05 v1.05 (NLCT)
xkeyval.sty -- 2020/11/20 v2.8 package option processing (HA)
xkeyval.tex -- 2014/12/03 v2.7a key=value parser (HA)
xparse-2020-10-01.sty -- 2020-10-01
xparse.sty -- 2021-01-09 L3 Experimental document command parser
theorem? A table (float) environment wrapped around atabularenvironment seems more straightforward. And then,\NewDocumentCommand{\Fenster}{mmmm}{<common code using #1, #2, #3, #4>}. – Erwann Apr 04 '21 at 07:11\fenster). You can create the CSV file with any set of information that you want/need. Here is a line with six arguments: Fenster mit 3-Scheiben Isolierverglasung; mit Rolladen und Fensterbank, 130/150, 1 flg Drehkipp rechts, Fixrahmen von innen abnehmbar, , Farbe: Innen Weiß, Außen weiß; Beschlag: Silber. You can pull from this CSV file whatever you need/want in whatever order. An added advantage is to manage the CSV file in a database app. – Jeffrey J Weimer Apr 05 '21 at 13:32lipsumpackage to put dummy text for example. Provide a brute-force-generated example of what you want for the macro to produce as an appendix. I still see this as being best solved as a database -> LaTeX problem rather than as a LaTeX -> database problem. – Jeffrey J Weimer Apr 06 '21 at 14:52