我有一个我在stata宏中创建的手册列表,类似于
global list1 "a b c d"
Run Code Online (Sandbox Code Playgroud)
我后来用类似的东西迭代
foreach name in $list1 {
action
}
Run Code Online (Sandbox Code Playgroud)
我试图将其更改为数据库驱动列表,因为列表变得越来越大并且快速变化,我使用以下命令创建一个新的$ list1
odbc load listitems=items, exec("SELECT items from my_table")
levelsof listitems
global list1=r(levels)
Run Code Online (Sandbox Code Playgroud)
每个项目都是相同的,但是这个列表似乎有所不同,当我有太多项目时,它会在for循环中出现错误
{ required
r(100);
Run Code Online (Sandbox Code Playgroud)
此外,当我只运行listitems级别时,我得到输出
`"a"' `"b"' `"c"' `"d"'
Run Code Online (Sandbox Code Playgroud)
看起来与其他宏看起来有点不同.
我已经坚持了一段时间.同样,只有当项目数量变大(超过15)时才会失败,任何帮助都会非常感激.
小智 7
解决方案1:
levelsof listitems, clean local(list1)
foreach name of local list1 {
...action with `name'...
}
Run Code Online (Sandbox Code Playgroud)
解决方案2:
levelsof listitems, clean
global list1 `r(levels)'
foreach name of global list1 {
...action with `name'...
}
Run Code Online (Sandbox Code Playgroud)
说明:
当你输入
foreach name in $list1 {
Run Code Online (Sandbox Code Playgroud)
然后在Stata看到它之前,$ list1中的任何内容都被替换为内联.如果全局宏列表1包含很长的事物列表,那么Stata会看到
foreach name in a b c d e .... very long list of things here ... {
Run Code Online (Sandbox Code Playgroud)
告诉Stata你有一个全局或本地宏中的事物列表,并且你想要循环这些事情是更有效的.您不必在命令行上展开它们.那是什么
foreach name of local list1 {
Run Code Online (Sandbox Code Playgroud)
和
foreach name of global list1 {
Run Code Online (Sandbox Code Playgroud)
是给.你可以在-achp foreach-中阅读foreach的其他功能.
另外,您最初编码
levelsof listitems
global list1=r(levels)
Run Code Online (Sandbox Code Playgroud)
而且你注意到你看到了
`"a"' `"b"' `"c"' ...
Run Code Online (Sandbox Code Playgroud)
结果是.这些是Stata所说的"复合引用"字符串.复合引号字符串可让您有效地嵌套引用的内容.所以,你可以有类似的东西
`"This is a string with `"another quoted string"' inside it"'
Run Code Online (Sandbox Code Playgroud)
你说你不需要它,所以你可以使用levelsof的"clean"选项来不引用结果.(有关此选项的更多信息,请参阅-help levelsof.)此外,您之后将levelsof的返回结果(在r(级别)中)分配给全局宏.事实证明-levelsof-实际上有一个名为-local()的选项 - 您可以在其中指定本地(非全局)宏的名称以直接输入结果.因此,您只需键入
levelsof listitems, clean local(list1)
Run Code Online (Sandbox Code Playgroud)
省略复合引号并直接将结果放在名为list1的本地宏中.
最后,如果由于某种原因你不想使用那个local()选项并希望坚持将列表放在一个全局宏中,你应该编码
global list1 `r(levels)'
Run Code Online (Sandbox Code Playgroud)
而不是
global list1=r(levels)
Run Code Online (Sandbox Code Playgroud)
区别在于后者将r(级别)视为一个函数,并通过Stata的字符串表达式解析器运行它.在Stata中,字符串(字符串,而不是包含字符串的宏)的限制为244个字符.另一方面,包含字符串的宏可以包含数千个字符.所以,如果r(级别)中有超过244个字符,那么
global list1=r(levels)
Run Code Online (Sandbox Code Playgroud)
最终将以244个字符截断存储在list1中的结果.
当你改为代码时
global list1 `r(levels)'
Run Code Online (Sandbox Code Playgroud)
然后在执行命令之前,内联扩展r(级别)的内容.所以,Stata看到了
global list1 a b c d e ... very long list ... x y z
Run Code Online (Sandbox Code Playgroud)
并且宏名称(list1)之后的所有内容都被复制到该宏名称中,无论它有多长.