2016-03-22 2 views
0

Der Titel meiner Frage kann ein wenig mehrdeutig sein. Zuvor möchte ich "vollständige Liste der Unterverzeichnisse" erhalten und dann die Dateien in diesen Unterverzeichnissen in Stata lesen (siehe this post und this post). Dank @Roberto Ferrers großem Vorschlag gelingt es mir fast, dies zu tun. Aber dann stoße ich auf ein anderes Problem. Da ich so viele separate Dateien habe, scheint die Länge des lokalen Makros seine Obergrenze zu erreichen. Die Stata eine Fehlermeldung local n:word count nach Befehl sendenWie wird die maximale Anzahl von Strings automatisch dem Makro zugewiesen?

macro substitution results in line that is too long 
    The line resulting from substituting macros would be longer than allowed. The maximum allowed length is 645,216 characters, which is calculated on the basis of set maxvar. 

    You can change that in Stata/SE and Stata/MP. What follows is relevant only if you are using Stata/SE or Stata/MP. 

    The maximum line length is defined as 16 more than the maximum macro length, which is currently 645,200 characters. Each unit increase in set maxvar increases the length maximums by 129. The 
    maximum value of set maxvar is 32,767. Thus, the maximum line length may be set up to 4,227,159 characters if you set maxvar to its largest value. 
r(920); 

als ich endlich die Zahl der subdirs bis 5 reduzieren, arbeitet die Stata in Ordnung. Da ich ungefähr 100 Unterverzeichnisse habe, nehme ich an, dass die Aktionen 20 Mal wiederholt werden. Nun, es ist überschaubar, aber ich möchte immer noch wissen, ob ich diesen Prozess vollständig automatisieren kann, genauer gesagt, um die maximale zulässige Makrolänge zu "erschöpfen", importieren Sie die Dateien und fügen Sie eine weitere Gruppe von Unterverzeichnissen das nächste Mal. Vielen Dank. Im Anschluss an meinem Code

//==================================== 
//=== 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 
     } 

Antwort

2

Sie brauchen nicht die ganze Liste der Dateien in einem Makro zu speichern. filelist erstellt eine Datenbank mit Dateien, mit denen Sie arbeiten möchten. Speichern Sie es einfach und laden Sie es für jede Datei neu, die Sie bearbeiten möchten. Sie verwenden auch einen sehr ineffizienten Weg, um Datensätze anzuhängen. Wenn das angehängte Dataset anwächst, werden die Kosten für das erneute Laden und Speichern sehr hoch und können den gesamten Prozess auf einen Crawl-Vorgang verlangsamen.

Hier ist eine Skizze, wie Sie Ihre Excel-Dateien

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 
+0

Entschuldigung für die verzögerte Antwort zu verarbeiten. Danke, @ Robert Picard, Ihr Ansatz funktioniert perfekt. Noch eine Sache, die beachtet werden muss, wenn jemand eine große Anzahl von Dateien wie mich importieren möchte: Sie sollten besser "cap noi" vor dem Befehl hinzufügen, um eine unerwartete Beendigung der do-Datei zu verhindern – zlqs1985