Datatool \DTLnewdbentry 不接受关键列的值

Datatool \DTLnewdbentry 不接受关键列的值

我对以下情况感到很沮丧:我正在编写一份文档,其中的需求以需求 ID 作为行首(我在枚举环境中使用这些需求)。我想在 DATATOOL 数据库中收集需求,并在文档末尾以表格形式输出这些需求。

无论我尝试什么,以下宏都可以正常工作,因为它会在枚举环境中添加具有正确需求 ID 的需求行,但是当我在最后显示表格时,它不会在“reqKey”列中添加输出需求 ID - 我怀疑对“\@reqID”变量访问的某些东西不起作用。

非常感谢您的帮助。

\DTLnewdb{reqs}
\DTLnewdbcolumn{reqs}{reqKey}
\DTLnewdbcolumn{reqs}{reqText}

...

\makeatletter
    \newcommand\req@nomen@count[1]{%
      \@ifundefined{c@#1}
        {% the counter doesn't exist
         \newcounter{#1}\setcounter{#1}{1}%
        }
        {% the counter exists
         \stepcounter{#1}%
        }%
    }
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % markers for requirements
    \newcommand{\req}[2][0]{%
        \req@nomen@count{#2}%
        \ifthenelse{\equal{#1}{0}}
        {REQ.#2.\padzeroes[3]{\decimalnum{\value{#2}}}}
        {REQ.#2.\padzeroes[3]{\decimalnum{\value{#2}}}.\padzeroes[2]{\decimalnum{#1}}}
    }
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%
    \newcommand{\@reqID}{}
    \newcommand{\itemReq}[3][0]{
        \DTLnewrow{reqs}
        \ifthenelse{\equal{#1}{0}}
        {\renewcommand{\@reqID}{\req{#2}}}
        {\renewcommand{\@reqID}{\req{#1}{#2}}}
        \item[\textcolor{blue}{[\@reqID]}]#3%
        \DTLnewdbentry{reqs}{reqKey}{\@reqID}
        \DTLnewdbentry{reqs}{reqText}{#3}
        }
    \makeatother
...
\begin{document}
\begin{enumerate}
\itemReq{reqCategory}{Requirement text, can be lengthy}
\end{enumerate}
...
\DTLdisplaylongdb{reqs}
\end{document}

该代码的输出如下所示: 上述代码的输出


根据要求编辑我想分享一个最小调整(根据 esdd 的解决方案)的示例:

\documentclass{article} 
\usepackage{enumitem}
\usepackage{fmtcount}
\usepackage{datatool}

\DTLnewdb{reqs}
\DTLaddcolumn{reqs}{reqKey}
\DTLaddcolumn{reqs}{reqText}

\makeatletter
% macro creating a new latex counter for every new entitiy name and requirement
\newcommand\req@nomen@count[1]{%
  \@ifundefined{c@#1}
    {% the counter doesn't exist
     \newcounter{#1}\setcounter{#1}{1}%
    }%
    {% the counter exists
     \stepcounter{#1}%
    }%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% markers for requirements
\newcommand{\req}[2][0]{%
        \ifthenelse{\equal{#1}{0}}
          {REQ.#2.\padzeroes[3]{\decimalnum{\value{#2}}}}
          {REQ.#2.\padzeroes[3]{\decimalnum{\value{#2}}}.\padzeroes[2]{\decimalnum{#1}}}%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newcommand{\@reqID}{}

\newcommand{\itemReq}[3][0]{
    \req@nomen@count{#2}%
    \DTLnewrow{reqs}%
    \ifthenelse{\equal{#1}{0}}
          {\renewcommand{\@reqID}{\req{#2}}}
          {\renewcommand{\@reqID}{\req[#1]{#2}}}%
    \item[{[\@reqID]}]#3%
    \dtlexpandnewvalue%
    \DTLnewdbentry{reqs}{reqKey}{\@reqID}%
    \DTLnewdbentry{reqs}{reqText}{#3}%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
\begin{enumerate}
\itemReq{CategoryA}{Requirement category 1 text 1.}
\itemReq{CategoryA}{Requirement category 1 text 2.}
\itemReq{CategoryB}{Requirement category 1 text 1.}
\end{enumerate}
\DTLdisplaydb{reqs}
\end{document}

这段代码还有另一个问题:表中的ID始终是文本中计数器最高的ID。

答案1

更新

\dtlexpandnewvalue似乎只展开一次。因此,您必须使用附加参数来执行\req该操作\arabic{<countername>}

使用您更改的示例:

\documentclass{article} 
\usepackage{fmtcount}
\usepackage{datatool}

\DTLnewdb{reqs}
\DTLaddcolumn{reqs}{reqKey}
\DTLaddcolumn{reqs}{reqText}

\makeatletter
% macro creating a new latex counter for every new entitiy name and requirement
\newcommand\req@nomen@count[1]{%
  \@ifundefined{c@#1}
    {% the counter doesn't exist
     \newcounter{#1}\setcounter{#1}{1}%
    }%
    {% the counter exists
     \stepcounter{#1}%
    }%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% markers for requirements
\newcommand{\req}[3][0]{%
        \ifthenelse{\equal{#1}{0}}
          {REQ.#2.\padzeroes[3]{\decimalnum{#3}}}
          {REQ.#2.\padzeroes[3]{\decimalnum{#3}}.\padzeroes[2]{\decimalnum{#1}}}%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newcommand{\@reqID}{}

\newcommand{\itemReq}[3][0]{%
    \req@nomen@count{#2}%
    \DTLnewrow{reqs}%
    \ifthenelse{\equal{#1}{0}}
          {\renewcommand{\@reqID}{\req{#2}{\arabic{#2}}}}
          {\renewcommand{\@reqID}{\req[#1]{#2}{\arabic{#2}}}}%
    \item[{[\@reqID]}]#3%
    \dtlexpandnewvalue%
    \DTLnewdbentry{reqs}{reqKey}{\@reqID}%
    \DTLnewdbentry{reqs}{reqText}{#3}%
}
\makeatother
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
\begin{enumerate}
\itemReq{CategoryA}{Requirement category 1 text 1.}
\itemReq{CategoryA}{Requirement category 1 text 2.}
\itemReq{CategoryB}{Requirement category 1 text 1.}
\end{enumerate}
\DTLdisplaydb{reqs}
\end{document}

结果:

在此处输入图片描述

但也许你可以避免命令的嵌套:

\documentclass{article} 
\usepackage{fmtcount}
\usepackage{datatool}

\DTLnewdb{reqs}
\DTLaddcolumn{reqs}{reqKey}
\DTLaddcolumn{reqs}{reqText}

\makeatletter
\newcommand{\@reqID}{}
\newcommand{\itemReq}[3][0]{%
  \@ifundefined{c@#2}{\newcounter{#2}}{}%
  \stepcounter{#2}%
  \DTLnewrow{reqs}%
  \ifthenelse{\equal{#1}{0}}
    {\renewcommand{\@reqID}{REQ.#2.\padzeroes[3]{\decimalnum{\arabic{#2}}}}}
    {\renewcommand{\@reqID}{REQ.#2.\padzeroes[3]{\decimalnum{\arabic{#2}}}.\padzeroes[2]{\decimalnum{#1}}}}%
  \item[{[\@reqID]}]#3%
  \dtlexpandnewvalue%
  \DTLnewdbentry{reqs}{reqKey}{\@reqID}%
  \DTLnewdbentry{reqs}{reqText}{#3}%
}
\makeatother

\begin{document}
\begin{enumerate}
\itemReq{CategoryA}{Requirement category 1 text 1.}
\itemReq{CategoryA}{Requirement category 1 text 2.}
\itemReq{CategoryB}{Requirement category 1 text 1.}
\end{enumerate}
\DTLdisplaydb{reqs}
\end{document}

结果和上面一样。


旧答案

使用以下代码时,打印数据库时仅使用计数器的最后一个值。

datatool默认不展开添加的值。显示表格时原有定义有效。所以打印出来的键都是空的。

要在添加到数据库时扩展值,reqs请使用\dtlexpandnewvalue的定义\@regID

此外,我认为您不想介入计数器,\req因为\req每次执行两次\@regID:一次作为参数打印\item,一次添加到数据库。

并且我改变了另一行代码,因为\req它采用了一个可选参数和一个强制参数(而不是两个强制参数)。

在下面的例子中,我还使用包enumitem来定义自己的 listenvironment reqDecsr

\documentclass{article}
\usepackage{fmtcount}
\usepackage{xcolor}
\usepackage{longtable}
\usepackage{enumitem}
\newlist{reqDescr}{description}{1}
\setlist[reqDescr]{leftmargin=8em}

\usepackage{datatool}


\DTLnewdb{reqs}
\DTLaddcolumn{reqs}{reqKey}
\DTLaddcolumn{reqs}{reqText}

\makeatletter
    \newcommand\req@nomen@count[1]{%
      \@ifundefined{c@#1}
        {% the counter doesn't exist
         \newcounter{#1}\setcounter{#1}{1}%
        }
        {% the counter exists
         \stepcounter{#1}%
        }%
    }
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % markers for requirements
    \newcommand{\req}[2][0]{%
        %\req@nomen@count{#2}% <- remove it here
        \ifthenelse{\equal{#1}{0}}
          {REQ.#2.\padzeroes[3]{\decimalnum{\value{#2}}}}
          {REQ.#2.\padzeroes[3]{\decimalnum{\value{#2}}}.\padzeroes[2]{\decimalnum{#1}}}%
    }
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%
    \newcommand{\@reqID}{}
    \newcommand{\itemReq}[3][0]{%
        \req@nomen@count{#2}% <- use it here
        \DTLnewrow{reqs}%
        \ifthenelse{\equal{#1}{0}}
          {\renewcommand{\@reqID}{\req{#2}}}
          {\renewcommand{\@reqID}{\req[#1]{#2}}}% <- changed
        \item[\textcolor{blue}{[\@reqID]}]#3%
        \dtlexpandnewvalue% <- added
        \DTLnewdbentry{reqs}{reqKey}{\@reqID}%
        \DTLnewdbentry{reqs}{reqText}{#3}%
        }
    \makeatother
\begin{document}
\begin{reqDescr}
\itemReq{reqCategory}{Requirement text, can be lengthy.}
\end{reqDescr}
...
\DTLdisplaylongdb{reqs}
\end{document}

结果:

在此处输入图片描述

如果条目较长,那么您可以替换

\DTLdisplaylongdb{reqs}

比如

\begin{longtable}{lp{.65\textwidth}}
  \textbf{reqKey}&\multicolumn{1}{l}{\textbf{reqText}}\\
  \endhead
  \DTLforeach*{reqs}{\Key=reqKey,\Text=reqText}{\DTLiffirstrow{}{\tabularnewline}\Key&\Text}
\end{longtable}

在此处输入图片描述

顺便说一句:请始终提供 MWE。这样我们就不必猜测编译您的代码需要哪些包。

相关内容