使用xifthen

使用xifthen

読み取られるデータの各行に対して、次の処理を実装したいと思いますdatatool

if ( (\No = 5 and \B=11111) OR (\No = 5 and \B=22222) ):
  \inserpageA
else if ( (\No = 5) AND (\B not 11111) AND (\B not 22222) ): 
  \inserpageB
else: 
  \No \hspace{1cm} \B  \hspace{5cm} \A

私のコード:

\RequirePackage{filecontents}
\begin{filecontents*}{test.csv}
Acol, Bcol, NoCol
Ax,Bxxxx,1
Ay,By,3
A1,B22,2
A2,B44,4
A3,11111,5
Ax,B,1
Ay,By,3
A1,B22,2
A2,B44,4
A3,22222,5
Ax,Bxxxx,1
Ay,By,3
A1,B22,2
A2,B44,4
A3,33333,5
\end{filecontents*}

\documentclass{article}
\usepackage{datatool}
\DTLloaddb{mydata}{test.csv}
\newcommand{\inserpageA}[2]{%
\subsubsection*{AAA}
\newpage
}
\newcommand{\inserpageB}[2]{%
\subsubsection*{BBB}
\newpage
}
\begin{document}

\DTLforeach*{mydata}{\A=Acol, \B=Bcol, \No=NoCol}%
{%
 \No \hspace{1cm} \B  \hspace{3cm}  \A

}%

\end{document}

上記のルールを実装する方法を示してください。 ありがとうございます。

答え1

それにはいくつかの方法があります。私は を使用する方法xifthenと を使用する方法の2 つの解決策を提案します。の関数と 関数を使用してexpl3も実行できます。ifthendatatool

のテストでは\B、 とは逆に、内容が常に数値であるとは限らないため、文字列比較を使用していることに注意してください。論理式で\No1 ​​つ2222を に置き換えました22222(質問に間違いがあるようですね?)。

論理テストは記述どおりに実装しましたが、簡略化することもできます ( \No = 5 テストは除外できます)。

使用xifthen

\RequirePackage{filecontents}
\begin{filecontents*}{test.csv}
Acol, Bcol, NoCol
Ax,Bxxxx,1
Ay,By,3
A1,B22,2
A2,B44,4
A3,11111,5
Ax,B,1
Ay,By,3
A1,B22,2
A2,B44,4
A3,22222,5
Ax,Bxxxx,1
Ay,By,3
A1,B22,2
A2,B44,4
A3,33333,5
\end{filecontents*}

\documentclass{article}
\usepackage{xifthen}
\usepackage{datatool}
\DTLloaddb{mydata}{test.csv}

\newcommand{\inserpageA}{%
  \subsubsection*{AAA}
  \newpage
}
\newcommand{\inserpageB}{%
  \subsubsection*{BBB}
  \newpage
}

\begin{document}

\DTLforeach*{mydata}{\A=Acol, \B=Bcol, \No=NoCol}%
{%
  \ifthenelse{\(\cnttest{\No}{=}{5}\AND \equal{\B}{11111}\)\OR
              \(\cnttest{\No}{=}{5}\AND \equal{\B}{22222}\)}%
    {\inserpageA}%
    {\ifthenelse{\cnttest{\No}{=}{5}\AND
                 \NOT\equal{\B}{11111}\AND
                 \NOT\equal{\B}{22222}}%
       {\inserpageB}%
       {\No\hspace{1cm}\B \hspace{5cm}\A\par}%
    }%
}%

\end{document}

使用expl3

expl3おそらく、の方法の方が読みやすいことがわかるでしょう。 とは対照的に、 (これらのためのモジュール) のxifthenブール式は、 との標準的な優先順位規則(それぞれ論理 AND と論理 OR) を使用します。これは便利です。l3prgexpl3&&||

\ExplSyntaxOnとの間のスペースは無視されることに注意してください\ExplSyntaxOff。そこにスペースが必要な場合は、~または を使用してください\space。は~、制御ワードの後では、通常どおり無視される場合があります。たとえば、 は~無視\B ~されますが、が展開される\B \spaceとスペース トークンが挿入されます\space(明示的なスペース トークンに展開されるマクロです)。

\RequirePackage{filecontents}
\begin{filecontents*}{test.csv}
Acol, Bcol, NoCol
Ax,Bxxxx,1
Ay,By,3
A1,B22,2
A2,B44,4
A3,11111,5
Ax,B,1
Ay,By,3
A1,B22,2
A2,B44,4
A3,22222,5
Ax,Bxxxx,1
Ay,By,3
A1,B22,2
A2,B44,4
A3,33333,5
\end{filecontents*}

\documentclass{article}
\usepackage{xparse}
\usepackage{datatool}
\DTLloaddb{mydata}{test.csv}

\ExplSyntaxOn

\NewDocumentCommand \lfortiProcessOneRow { }
  {
    \bool_if:nTF
      { % The parentheses below are not necessary, because && has higher
        % priority than || in expl3 (l3prg) boolean expressions.
        ( \int_compare_p:nNn { \No } = { 5 } && \str_if_eq_p:Vn \B {11111} ) ||
        ( \int_compare_p:nNn { \No } = { 5 } && \str_if_eq_p:Vn \B {22222} )
      }
      { \inserpageA }
      {
        \bool_if:nTF
          { \int_compare_p:nNn { \No } = { 5 } &&
            ! \str_if_eq_p:Vn \B {11111}       &&
            ! \str_if_eq_p:Vn \B {22222}
          }
          { \inserpageB }
          { \No \hspace{1cm} \B \hspace{5cm} \A \par }
      }
  }

\ExplSyntaxOff

\newcommand{\inserpageA}{%
  \subsubsection*{AAA}
  \newpage
}
\newcommand{\inserpageB}{%
  \subsubsection*{BBB}
  \newpage
}

\begin{document}

\DTLforeach*{mydata}{\A=Acol, \B=Bcol, \No=NoCol}{\lfortiProcessOneRow}

\end{document}

両方の例の出力

出力

関連情報