<>
"-_request()- will store the result in a local macro if you prefix its name
with an underscore"
I spent most of the few minutes required for my reply wondering why I could
not get the -local- -macro- route to work. Now that Bill has pointed out the
solution, I appreciate that the last example, in [P] on p. 102, does say
exactly what you are supposed to do to make this work. And yet: Is it not
highly unusual that the user has to supply the underscore for the -local-?
(I cannot think of another command that requires this treatment). This fact
could be given more prominence in the manual entry, as normally Stata would
prepend the underscore for you, as is obvious from:
***
ma drop _allv
local a 1
ma di
***
HTH
Martin
-----Original Message-----
From: [email protected]
[mailto:[email protected]] On Behalf Of William Gould,
StataCorp LP
Sent: Donnerstag, 29. Oktober 2009 20:03
To: [email protected]
Subject: Re: st: Submitting a command in a couples of pieces
Adrian Sayers <[email protected]> asks,
> [...] i want stata to ask me a question, then i want to key the
> response, and then i want stata to run a program. It sounds a little
> pointless but i am trying read in 3000 odd data files plot them and then
> trim the file to the relevant section.
>
> eg.
> di "What is the first day of data collection?"
> Type 3
> di "Day of first data collection = 3"
> drop if day<3
Martin Weiss <[email protected]> replied,
> *************
> di "What is the first day of data collection?" _request(day)
> 3
> di "Day of first data collection =$day "
> drop if day<$day
> *************
Exactly right. Let me add a few details.
-_request()- will store the result in a local macro if you prefix its name
with an underscore, so Martin's answer could have read,
di "What is the first day of data collection?" _request(_day)
3
di "Day of first data collection =`day' "
drop if day<`day'
Note that I put -_day- in the -_request()-, but even so, after that, I
referred to -`day'- just as I usually would.
Here's Martin's answer put into a -program-, which might be an ado-file:
program trythis
version 11
di "What is the day of the data collection? " _request(_day)
di "Day of the first data collection = `day'"
drop if day<`day'
end
I next suggest to Adrian that if he is going to ask more than one question,
he must anticipate that users will sometimes mistype their answers.
Most commonly, they will hit Return before typing any answer. As I result,
I recommend creating a subroutine to get answers:
program trythis
version 11
askquestion "What is the day of the data collection?"
local day "`s(answer)'"
di "Day of the first data collection = `day'"
drop if day<`day'
end
program askquestion, sclass
args last_line_of_text
while (1) {
di as txt "`last_line_of_text' -> " _request(_answer)
if ("`answer'"=="") {
di as txt "Please answer question, or type" ///
as res "qq" as txt "to break."
}
else if ("`answer'"=="qq") {
exit 1
}
else {
sreturn local answer "`answer'"
exit
}
}
end
In the above code, if the user just presses Return, the question is asked
again. The user can type -qq- to have the code break (stop asking
questions).
If I were Adrian, I would also check the lexical class of the answer in
subroutine -askquestion-. Sometimes answers can be text, even blank,
and other times they must be numbers, and even integers. Adrian needs
to think about the types of the answers he will need. As a simple example,
we might modify -askquestion- to allow the caller to specify one of the
following lexical types:
text (meaning a non-blank string)
number (any number, and only a number)
integer (any number that is an integer)
I would then construct code that looks something like this,
program askquestion, sclass
args lex_class last_line_of_text
while (1) {
sreturn clear
askqustion_ask "`last_line_of_text'"
local answer "`s(answer)'"
if ("`answer'"=="qq") {
exit 1
}
if ("`answer'"!="") {
askquestion_check `lex_class' "`answer'"
if (`"s(invalid)'"=="") {
sreturn local answer "`answer'"
exit
}
}
else {
di as txt "Please answer question, or type" ///
as res "qq" as txt "to break."
}
}
end
program askquestion_ask, sclass
args text
di as txt "`text'" -> " _request(_answer)
sreturn local answer "`answer'"
end
program askquestion_check, sclass
args lex answer
if ("`lex'"=="text") {
exit
}
if ("`lex'"=="number") {
capture confirm number `answer'
if (_rc) {
di "You must answer with a number"
sreturn local invalid invalid
}
exit
}
if "`lex'"=="integer") {
capture confirm number `answer'
if (_rc) {
di "You must answer with an integer"
sreturn local invalid invalid
}
exit
}
di as error "Invalid lexical class -`lex'-"
di as error "caller has error"
exit 198
end
All that said, there's nothing wrong with Martin's original answer if
Adrian will only be asking a few questions and asking them of himself.
-- Bill
[email protected]
*
* For searches and help try:
* http://www.stata.com/help.cgi?search
* http://www.stata.com/support/statalist/faq
* http://www.ats.ucla.edu/stat/stata/
*
* For searches and help try:
* http://www.stata.com/help.cgi?search
* http://www.stata.com/support/statalist/faq
* http://www.ats.ucla.edu/stat/stata/