使用数据工具时如何显示当前行之前的下一行?

使用数据工具时如何显示当前行之前的下一行?

我使用 datatool,想在当前数据之前显示下一个数据,可以吗?我需要帮助编写代码“在此显示(AAACoding+1)、CCCCoding+1...)的数据”

我的最少编码:

\documentclass[a5paper,oneside,8pt]{article}
\usepackage[a5paper,landscape,left=1.0cm,right=0.3cm,top=0.5cm,bottom=0.5cm]{geometry}
\usepackage{datatool}
\usepackage{filecontents}
\begin{filecontents*}{fileabc.tex}
AAA|BBB|CCC|DDD|
1|100|NT|E1|
2|109|NT|EE|
3|210|AT|E|
4|340|NT|E30|
5|12|AT|E31|
6|410|AT|E44|
7|234|NT|E77|
8|012|AT|E88|
\end{filecontents*}
\usepackage{datatool}
\DTLsetseparator{|}
\DTLsetdelimiter{"}
\DTLloaddb[autokeys=false]{fileabc}{fileabc.tex}

\newcommand{\printCCCCoding}[1]{%
 \par

 \DTLforeach*
 [\DTLiseq{\CCCCoding}{#1}]%
 {fileabc}% Database
 {\CCCCoding=CCC,\AAACoding=AAA, \BBBCoding=BBB,\DDDCoding=DDD}{%
 Next row: diplay here data of (AAACoding+1), CCCCoding+1...)
 \\
 Current row: \AAACoding \\
 \noindent \CCCCoding \hspace{0.1cm} 2 \AAACoding \hspace{0.1cm}  3 \BBBCoding \hspace{0.1cm} 4 \DDDCoding \par\\
 -----------\\
   }% 
}

\begin{document}

%\DTLdisplaydb{fileabc}
%\newpage
\\
\printCCCCoding{NT}

\end{document}

请参阅图片 在此处输入图片描述 谢谢

答案1

这是一个使用 LaTeX3 的解决方案。它的工作原理是将最后两行保持在滑动窗口中加载datatool。您可以将此滑动窗口视为数据库行的缓冲区。它以 LaTeX3 标记列表序列的形式实现,其中每个标记列表只包含数据库每列的一个项目。

\RequirePackage{filecontents}
\begin{filecontents*}{fileabc.tex}
AAA|BBB|CCC|DDD|
1|100|NT|E1|
2|109|NT|EE|
3|210|AT|E|
4|340|NT|E30|
5|12|AT|E31|
6|410|AT|E44|
7|234|NT|E77|
8|012|AT|E88|
\end{filecontents*}

\documentclass{article}
\usepackage{xparse}
\usepackage{datatool}

\DTLsetseparator{|}
\DTLsetdelimiter{"}
\DTLloaddb[autokeys=false]{fileabc}{fileabc.tex}

\ExplSyntaxOn

% Sliding window encoding at most two database rows. Each <item> of the seq
% corresponds to a database row and is a token list that contains as many
% subitems as there are columns in the database.
\seq_new:N \l__lforti_window_seq

\cs_new_protected:Npn \lforti_load_db_row:nnnn #1#2#3#4
  {
    % Append the new row as a token list containing one <item> per database
    % column.
    \seq_put_right:Nn \l__lforti_window_seq { {#1} {#2} {#3} {#4} }
  }

\tl_new:N \l__lforti_current_row_tl
\tl_new:N \l__lforti_next_row_tl
\str_new:N \l__lforti_tested_field_str

% Process the first row loaded in the sliding window, if any. The second row
% is the next one, and is used too in case the first row is a match.
%
% #1: index (starting from 1) of the field to test
% #2: value to compare to (a string)
\cs_new_protected:Npn \lforti_process_one_db_row:nn #1#2
  {
    \seq_pop_left:NN \l__lforti_window_seq \l__lforti_current_row_tl

    \tl_if_eq:NNF \l__lforti_current_row_tl \q_no_value
      {
        \str_set:Nx \l__lforti_tested_field_str
          { \tl_item:Nn \l__lforti_current_row_tl {#1} }

        \str_if_eq:VnT \l__lforti_tested_field_str {#2}
          { % There is a match on the tested field, get the next row
            \seq_set_eq:NN \l_tmpa_seq \l__lforti_window_seq
            \seq_pop_left:NN \l_tmpa_seq \l__lforti_next_row_tl

            \tl_if_eq:NNF \l__lforti_next_row_tl \q_no_value
              {
                \par \noindent Next~row:~
                \lforti_display_row:nN { \c_false_bool } \l__lforti_next_row_tl
                \\
              }

            \noindent Current~row:~
            % Full display of the current row
            \lforti_display_row:nN { \c_true_bool } \l__lforti_current_row_tl
            \\[1ex]
            \rule { 4cm } { 0.4pt }
            \par \skip_vertical:n { 1ex }
          }
      }
  }

% #1: boolean expression indicating whether to do full display of the row
% #2: token list variable corresponding to the row contents (one <item> per
%     field)
\cs_new_protected:Npn \lforti_display_row:nN #1#2
  {
    \bool_if:nT {#1}            % Full display?
      { \tl_item:Nn #2 { 1 } \\ }

    \tl_item:Nn #2 { 3 }
    \hspace{0.1cm} 2~
    \tl_item:Nn #2 { 1 }
    \hspace{0.1cm} 3~
    \tl_item:Nn #2 { 2 }
    \hspace{0.1cm} 4~
    \tl_item:Nn #2 { 4 }
  }

\cs_generate_variant:Nn \lforti_load_db_row:nnnn { oooo }

% #1: column number for the tested value (1 for the first column, 2 for the
%     second one, 3 for the third [CCC], etc.)
% #2: value to test against
\NewDocumentCommand \printCoding { m m }
  {
    \par
    \seq_clear:N \l__lforti_window_seq

    \DTLforeach* { fileabc } % database
      {\CCCCoding=CCC, \AAACoding=AAA, \BBBCoding=BBB, \DDDCoding=DDD }
      {
        \lforti_load_db_row:oooo
          { \AAACoding } { \BBBCoding } { \CCCCoding } { \DDDCoding }

        % Process the sliding window contents here only if it's full (the
        % “current row” for \lforti_process_one_db_row:nn is always the first
        % item of \l__lforti_window_seq; the second item, if any, is processed
        % after the \DTLforeach* loop).
        \int_compare:nNnT { \seq_count:N \l__lforti_window_seq } = { 2 }
          { \lforti_process_one_db_row:nn {#1} {#2} }
      }

    % Process the last row, if any (it is now the first element of
    % \l__lforti_window_seq).
    \lforti_process_one_db_row:nn {#1} {#2}
  }

% Convenience user macro
\NewDocumentCommand \printCCCCoding { m }
  {
    \printCoding {3} {#1}
  }

\ExplSyntaxOff

\begin{document}

\printCCCCoding{NT}

\end{document}

截图

应正确处理边缘情况(当匹配位于最后一行时不打印“下一行”等):

\begin{filecontents*}{fileabc.tex}
AAA|BBB|CCC|DDD|
1|100|NT|E1|
2|109|NT|EE|
3|210|AT|E|
4|340|NT|E30|
5|12|AT|E31|
6|410|AT|E44|
7|234|NT|E77|
8|012|AT|E88|
9|777|NT|E99|
\end{filecontents*}

包含多行的屏幕截图,最后一行是匹配项

空数据库或一行数据库也能正确处理。例如:

\begin{filecontents*}{fileabc.tex}
AAA|BBB|CCC|DDD|
9|777|NT|E99|
\end{filecontents*}

匹配时截图只有一行

注意:您可以非常轻松地调整 的定义,\printCCCCoding以便使用来自其他列的值执行行选择测试( 的第一个参数\printCoding是用于此目的的列号,从 1 开始)。当然,您可以\printCoding在文档中使用任意多次。

相关内容