如何自动为宏指定最大字符串数量?

时间:2016-03-22 11:56:18

标签: stata stata-macros

我的问题的标题可能有点含糊不清。

以前,我想“获取完整的子目录列表”,然后将这些子目录中的文件读入Stata(请参阅this postthis post)。

感谢@Roberto Ferrer的伟大建议,我几乎设法做到这一点。但是我遇到了另一个问题。因为我有这么多单独的文件,本地宏的长度似乎达到了它的上限。命令local n: word count之后Stata发送错误消息:

  

宏替换导致行太长。

     

替换宏所产生的行将超过允许的行。允许的最大长度为645,216个字符,这是根据set maxvar计算的。您可以在Stata / SE和Stata / MP中更改它。只有在使用Stata / SE或Stata / MP时,以下内容才有意义。

     

最大行长度定义为最大宏长度16以上,目前为645,200个字符。设置maxvar中的每个单位增加会使长度最大值增加129.设置maxvar的最大值为32,767。因此,如果将maxvar设置为其最大值,则最大行长度可以设置为4,227,159个字符。

     

R(920);

当我将子目录数减少到5时,Stata工作正常。由于有大约100个子目录,我想复制动作20次。好吧,它是可管理的,但我仍然想知道我是否可以完全自动化此过程,更具体地说,“耗尽”最大允许宏长度,导入文件并在下次添加另一组子目录

您可以在下面找到我的代码:

//====================================
//=== read and clean projects data ===
//====================================
version 14
set linesize 80
set more off

clear
macro drop _all
set linesize 200
cd G:\Data_backup\Soufang_data


*----------------------------------
* Read all files within dictionary
*----------------------------------


* Import the first worksheets 1:"项目首页" 2:"项目概况" 3:"成交详情"
* worksheet1

filelist, directory("G:\Data_backup\Soufang_data") pattern(*.xlsx)

* Add pattern(*.xlsx) provent importing add file type( .doc or .dta)

gen tag = substr(reverse(dirname),1,6) == "esuoh/"
keep if tag==1
gen path = dirname+"\"+filename
qui valuesof path if tag==1
local filelist = r(values)

split dirname, parse("\" "/")
ren dirname4 citylist
drop dirname1-dirname3 dirname5
qui valuesof citylist if tag==1
local city = r(values)

local count = 1
local n:word count `filelist'

  forval i = 1/`n' {
      local file    : word `i' of `filelist'
      local cityname: word `i' of `city'

      ** don't add xlsx after `file', suffix has been added
      ** write "`file'" rather than `file', I don't know why but it works
      qui import excel using "`file'",clear
      cap qui sxpose,clear
      cap qui drop in 1/1
      gen city = "`cityname'"


      if `count'==1 {
          save house.dta,replace emptyok
         }
      else          {
          qui append using house
          qui save house.dta,replace emptyok
          }

      local ++count
      } 

谢谢。

1 个答案:

答案 0 :(得分:2)

您无需在宏中存储整个文件列表。 filelist创建您要使用的文件数据库。只需保存并为要处理的每个文件重新加载它。您还使用非常低效的方式来附加数据集。随着附加数据集的增长,重新加载和保存它的成本变得非常高,并且可以将整个过程减慢到爬行速度。

以下是如何处理Excel文件的草图

filelist, directory(".") pattern(*.xlsx)
save "myfiles.dta", replace

local n = _N

forval i = 1/`n' {

    use in `i' using "myfiles.dta", clear

    local f = dirname + "/" + filename

    qui import excel using "`f'",clear

    tempfile res`i'
    save "`res`i''"

} 

clear
forval i = 1/`n' {

    append using "`res`i''"

} 

save "final.dta", replace