我不知道如何使用“datatool”从数据库中的一行读取变量,并将它们传递给我的文本进行格式化。我不想制作表格,但互联网上似乎只有这些示例。
我有一个 CSV 文件,内容如下:
name|points
John|172
Sue|120
Mike|64
盯着数据工具手册看了两天后,我取得了以下成功:
\documentclass{memoir}
\usepackage{datatool}
\DTLsetseparator{|}
\begin{document}
\DTLloaddb{players}{database.csv}
\DTLforeach*{players}{\name=name,\points=points}
\subsection{\name}
\textit{\points}
\end{document}
这会以我想要的格式打印所选变量,但只打印数据库中的最后一个条目。我猜“\dtlgetrowforvalue{players}{1}{John}”可用于在数据库中查找 John 的行,但我不明白如何将其与读取和显示变量的命令集成。
我不熟悉手册中使用的许多术语,也找不到我想要实现的示例,我通过反复试验来解决问题的尝试失败了。我不一定需要一个可行的示例,但我非常希望有人至少能告诉我适当的命令。
答案1
\DTLforeach
需要三个强制参数,而不是像您的示例中那样需要两个。这修复了您的示例:
\documentclass{memoir}
\usepackage{datatool}
\DTLsetseparator{|}
\DTLloaddb{players}{database.csv}
\begin{document}
\DTLforeach*
{players}% database label
{\name=name,\points=points}% assignment
{% Stuff to do at each iteration:
\subsection{\name}
\textit{\points}
}
\end{document}
得出的结果为:
编辑:
\DTLforeach
是一个重复(循环)命令,旨在对每一行数据执行特定操作。如果您只想从一行数据中查找信息,则有多种方法可以做到这一点。以下是一些示例:
\documentclass{memoir}
\usepackage{datatool}
\DTLsetseparator{|}
\DTLloaddb{players}{database.csv}
\begin{document}
Sue's points: \DTLfetch{players}{name}{Sue}{points}.
Pull information from row 3.
\DTLassign{players}{3}{\name=name,\points=points}
Here's the information: Name: \name. Points: \points.
Pull information from the first row where the name column has the
value ``John''.
\DTLassignfirstmatch{players}{name}{John}{\name=name,\points=points}
Here's the information: Name (we already know this anyway): \name.
Points: \points.
\newcommand{\PlayerName}{John}
As above, but the required name (\PlayerName) is given by a command:
\xDTLassignfirstmatch{players}{name}{\PlayerName}{\name=name,\points=points}
Here's the information: Name (we already know this anyway): \name.
Points: \points.
\end{document}
得出的结果为:
Sue 的分数:120。
从第 3 行提取信息。
以下是信息:姓名:Mike。分数:64。
从姓名列的值为“John”的第一行提取信息。
以下是信息:姓名(反正我们已经知道了):John。分数:172。
与上述相同,但所需的姓名(John)由命令提供:
以下是信息:姓名(反正我们已经知道了):John。分数:172。
答案2
2016 年 11 月解决方案(不使用datatool
):
该解决方案使用我最近更新的readarray
包,该包现在使用强大的listofitems
包来解析和访问数据。
\documentclass{article}
\usepackage{filecontents}
\begin{filecontents*}{database.csv}
name,points,d3,d4,d5,d6,d7,d8,d9,d10,d11
John,172,yes,black,23,0.000,89,big,32,A,Z
Sue,120,no,red,26,0.002,97,medium,36,B,W
Mike,64,maybe,green,89,0.567,154,small,42,C,X
\end{filecontents*}
\usepackage{readarray}[2016-11-07]
\usepackage{ifthen}
\newcounter{recordindex}
\newcommand\findrecord[1]{%
\def\matchrecord{0}
\setcounter{recordindex}{0}%
\whiledo{\therecordindex<\datacellROWS}{%
\stepcounter{recordindex}%
\ifthenelse{\equal{#1}%
{\datacell[\therecordindex,1]}}
{\xdef\matchrecord{\therecordindex}\setcounter{recordindex}{\datacellROWS}}%
{}%
}%
}
\begin{document}
\readarraysepchar{,}
\readdef{database.csv}{\mydata}
\readarray\mydata\datacell[-,\ncols]
The whole array is\arraydump\datacell
\datacellROWS\ records total\par
\datacell[3,6] is the 6th cell of the 3rd row\par
\datacell[4,11] is the 11th cell of the 4th row\par
\findrecord{Sue}
\datacell[\matchrecord,4] is Sue's 4th data cell
\end{document}
我正在删除我之前的解决方案,因为它们依赖于我的tabstackengine
和readarray
包中的内部代码,而这在最近的包更新中已经发生了变化。
答案3
偶然中,我找到了一个解决方案。不过,我让它工作的方式似乎有点冗长,所以我认为可能还有更好的方法,只是我还没想出来。
数据库.csv...
name,points,other
John,172,yes
Sue,120,no
Mike,64,maybe
文档.tex...
\documentclass{memoir}
\usepackage{datatool}
\DTLloaddb{players}{database.csv}
\newcommand{\player}[1]{%
\dtlgetrowforvalue{players}{\dtlcolumnindex{players}{name}}{#1}%
\input{./template.tex}%
}
\begin{document}
\player{Sue}
\end{document}
模板.tex...
% read variables into commands
\dtlgetentryfromcurrentrow{\name}{1}
\dtlgetentryfromcurrentrow{\points}{2}
\dtlgetentryfromcurrentrow{\other}{3}
% use commands in text
\subsubsection{\name}
\textit{\points}
\other