*! version 1.0.3 ARB 12oct99 (STB-53: dm63.1) * Dialog which allows the user to browse, edit or enter observations *! Now with drop-down list option, find button and written for 6.0 program define winshow version 6.0 #delimit ; syntax [varlist] [if] [in] [, MAXdisp(integer 14) EDit new del FInd STrict nopreserve call(str) log(varlist) dateord(str) noNUm noVAr noDEsc noTYpe HEADer(varlist max=1) CAPtion(str) drop(integer 60) LSpace(integer 11)]; #delimit cr marksample touse, novarlist if !missing("`dateord'") { if date("01/01/01","`dateord'") == . { /* check valid date order */ disp in r "Invalid date order specified" exit } global GWSdord `dateord' /* date order */ } else { global GWSdord dmy /* default order */ } if !missing("`call'") { cap `call' cause an error quickly if _rc == 199 { disp in r "File `call'.ado not found" exit 601 } } * These options are used in sub-routines so need to be global: global GWScall `call' global GWSlog `log' global GWSstrt = ("`strict'" == "strict") /* 1 if strict, 0 if not */ global GWSedit = ("`edit'" == "edit") /* 1 if edit, 0 if not */ global GWSdd `drop' /* depth of drop-down lists */ global GWSls `lspace' /* line spacing */ global GWStouse `touse' /* sample marker */ qui count if `touse' global GWSnmax = _result(1) /* No of observations to be displayed */ if $GWSnmax == 0 { exit } if !missing("`header'") { global GWShvar `header' local hdesc : variable label `header' if missing("`hdesc'") { global GWShtxt "`header':" } else { global GWShtxt "`hdesc':" } } disp in b "Initialising." _cont global GWSsm : set more /* remember set more setting */ set more off global GWSfrec 1 /* Observation no of first record */ while `touse'[$GWSfrec] == 0 { global GWSfrec = $GWSfrec + 1 } global GWSobsno $GWSfrec /* Current observation number */ global GWSlrec = _N /* Observation no of last record */ while `touse'[$GWSlrec] == 0 { global GWSlrec = $GWSlrec - 1 } * Chop up varlist into pages (var1, var2 etc..). Also creates * new characteristics for each variable: * [vtype] str, lon, byt etc... + new type dat (date) * [no] variable order number * [deslen] length of variable decription label in pixels * [len] length of edit box in characters * [edlen] length of edit box in pixels local maxdes 0 /* maximum description length */ local maxebl 5 /* maximum edit box length */ local maxcon 5 /* maximum control length */ local no 1 /* Variable order */ global GWSpage 1 /* page counter */ global GWSlpage 1 /* Last page no */ global GWSmod 0 /* Modified dataset trip switch */ global GWSnew 0 /* Data-entry mode flag */ tokenize `varlist' while !missing("`1'") { global GWSlpage $GWSpage /* Last page no */ local var$GWSpage "`var$GWSpage' `1'" * Create variable description global macro if missing("`num'") { global GWSvd`no' "`no'. " local slen 3 } else { global GWSvd`no' local slen 0 } if missing("`var'") { global GWSvd`no' "${GWSvd`no'}`1', " local slen = `slen' + 8 } if missing("`desc'") { local varlab : variable label `1' if "`varlab'" == upper("`varlab'") { local varlab = lower("`varlab'") } global GWSvd`no' "${GWSvd`no'}`varlab' " local slen = `slen' + length("`varlab'") } local vartype : type `1' if missing("`type'") { global GWSvd`no' "${GWSvd`no'}(`vartype')" local slen = `slen' + 8 } local slen = int(`slen' * 3.6) /* pixel width of description */ if `slen' > `maxdes' { local maxdes `slen' } char `1'[deslen] `slen' * Create macro lists for drop-down controls local ctyp : char `1'[contype] /* Type of control */ if "`ctyp'" == "2" { /* drop-down list */ getvl `1' GWSml`no' GWSwid /* Get list of value labels */ } else if "`ctyp'" == "3" { /* check box */ cap assert `1'==1 | `1'==0 if _rc { di in red _n "`1' is not coded 0 or 1 - cannot use check box." cleanup exit 182 } char `1'[len] 2 /* set character length */ } else if "`ctyp'" == "4" { /* radio buttons */ cap assert `1'==1 | `1'==2 | `1'==3 | `1'==4 if _rc { di in red _n "`1' has codes not in the set {1,2,3,4} - cannot use radio button." cleanup exit 182 } local vlab : value label `1' if `"`vlab'"' == "" { di in red _n "`1' not labeled - cannot use radio button." cleanup exit 182 } local i 1 local slen 0 global GWSrn`no' 4 while `i' <= 4 { local vallab : label `vlab' `i' if `"`vallab'"'=="`i'" { global GWSrn`no' = `i'-1 local i 5 /* exit loop at first blank label */ } else { global GWSr`i'`no' = substr(`"`vallab'"',1,12) local slen = `slen' + length(`"${GWSr`i'`no'}"') + 3 local i = `i' + 1 } } if ${GWSrn`no'} < 2 { di in red _n "`1' must have values 1 and 2 labelled - cannot use radio button." cleanup exit 182 } local slen = `slen' - 16 /* don't have RHS label on radio buttons */ char `1'[len] `slen' /* set character length */ } local vtype = substr("`vartype'",1,3) local varform : format `1' if substr("`varform'",1,2) == "%d" { /* date */ local vtype dat } char `1'[vtype] `vtype' local slen : char `1'[len] if missing("`slen'") { if "`ctyp'" == "2" { /* drop-down list */ local slen = $GWSwid + 5 } else if "`vtype'" == "str" { local slen = substr("`vartype'",4,.) if `slen' > 35 { local slen 35 /* Truncate edit region */ } } else if "`vtype'" == "dat" { local slen 10 } else { summ `1', mean local max = _result(6) local slen = length("`max'") + 2 } char `1'[len] `slen' /* Char edit box width */ } local slen = `slen' * 4 + 3 /* pixel edit box width */ if `slen' > `maxebl' { local maxebl `slen' } char `1'[edlen] `slen' char `1'[no] `no' macro shift if `no' == $GWSpage * `maxdisp' { global GWSpage = $GWSpage + 1 disp in b "." _cont } local no = `no' + 1 } disp _newline if $GWSpage == 1 { local hgt = `no' * $GWSls + 50 + 10*(!missing("$GWShtxt")) /* Height of dialog */ } else { local hgt = `maxdisp' * $GWSls + 59 + 10*(!missing("$GWShtxt")) } local wdt = `maxdes' + `maxebl' + 80 /* Width of dialog */ if `wdt' < 170 { local wdt 170 /* Minimum width of dialog */ } if ($GWSedit | "`del'" == "del" | "`new'" == "new") & "`preserv'" == "" { preserve disp in g "- preserve" } window control clear global GWSpage 1 if !missing("`var2'") { local next next } * Populate values and value labels for current page: pop `var1' global GWS_del "branch, rc(10)" global GWS_np "branch `var1', rc(3007)" global GWS_bp "na" ****************************************************************** * MAIN CONTROL LOOP (START) ****************************************************************** cap exit 3100 while _rc > 3000 { if _rc == 3007 { /* Next page */ global GWSpage = $GWSpage + 1 global GWS_bp "branch `var$GWSpage', rc(3008)" if $GWSpage == $GWSlpage { global GWS_np "na" } pop `var$GWSpage' } else if _rc == 3008 { /* Back a page */ global GWSpage = $GWSpage - 1 global GWS_np "branch `var$GWSpage', rc(3007)" if $GWSpage == 1 { global GWS_bp "na" } pop `var$GWSpage' } if _rc == 3017 { /* Next page in data-entry mode */ global GWSpage = $GWSpage + 1 global GWS_bp "exit 3018" if $GWSpage == $GWSlpage { global GWS_np "na" } global GWSpgtxt "Page $GWSpage of $GWSlpage" } else if _rc == 3018 { /* Back a page in data-entry mode */ global GWSpage = $GWSpage - 1 global GWS_np "exit 3017" if $GWSpage == 1 { global GWS_bp "na" } global GWSpgtxt "Page $GWSpage of $GWSlpage" } else if _rc == 3009 { /* New */ global GWSnew 1 newob `varlist' } else if _rc == 3010 { /* Find */ cap find `varlist' pop `var$GWSpage' } if _rc == 3001 | _rc == 3010 { /* Reset next and back */ global GWS_bp "branch `var$GWSpage', rc(3008)" global GWS_np "branch `var$GWSpage', rc(3007)" if $GWSpage == $GWSlpage { global GWS_np "na" } if $GWSpage == 1 { global GWS_bp "na" } } if missing("`caption'") { if $GWSedit { global GWScapt "Editing $GWSnmax observations" } else { global GWScapt "Browsing $GWSnmax observations" } } else { global GWScapt "`caption'" } setbox `var$GWSpage' , `next' `new' `del' `find' wdt(`wdt') hgt(`hgt') cap nois window dialog "$GWScapt" . . `wdt' `hgt' } ****************************************************************** * MAIN CONTROL LOOP (END) ****************************************************************** if _rc == 0 { /* User closed using x */ if "${GWSnew}" == "Submit" { window stopbox note "The new observation will be discarded as it was not submitted." } else { branch `var$GWSpage', rc(0) } } if $GWSmod == 1 & missing("`preserv'") { cap window stopbox rusure "Exit window:" "OK to accept changes." "Cancel to Restore last Preserve" if _rc { restore /* User cancelled */ disp in g "- restore" } } cap restore, not /* prevent auto restore on close */ cleanup /* Tidy up before exiting */ end * Subroutine called by show. Sets up the dialogue box for one record * Options to display back, next, new, find and delete buttons. * Width & height of box must be supplied in wdt() and hgt(). program define setbox version 6.0 syntax varlist [,next new del find wdt(integer 170) hgt(integer 45)] local x 5 /* x co-ord of labels */ if missing("$GWShtxt") { local y 12 /* y co-ord of first line */ } else { window control static GWShead `x' 12 150 7 /* Header */ local y 22 } local maxdes 0 /* maximum variable description length */ tokenize `varlist' local vno : char `1'[no] /* variable counter */ while !missing("`1'") { /* Find max description length */ local slen : char `1'[deslen] if `slen' > `maxdes' { local maxdes `slen' } macro shift } local xe = `maxdes' +7 /* x co-ord of edit boxes */ window control static GWSobtxt `x' 2 140 7 /* observation no */ local xp = `wdt' - 80 window control static GWSpgtxt `xp' 2 70 7 right /* page no */ tokenize `varlist' while !missing("`1'") { local we : char `1'[edlen] /* width in pixels of edit region */ local len : char `1'[len] /* width in characters */ local xv = `xe' + `we' + 5 /* x co-ord of value label */ window control static GWSvd`vno' `x' `y' `maxdes' 7 local ctyp : char `1'[contype] /* Type of control */ local noed : char `1'[noedit] /* Can variable be edited? */ if "`noed'" == "1" { /* No */ window control static GWSvv`vno' `xe' `y' `we' 7 } else if "`ctyp'" == "2" { /* drop-down list */ local xe = `xe'-1 local y = `y'-2 window control scombo GWSml`vno' `xe' `y' `we' $GWSdd GWSvv`vno' parse(|) local xe = `xe'+1 local y = `y'+2 } else if "`ctyp'" == "3" { /* checkbox */ window control check "" `xe' `y' 20 7 GWSvv`vno' } else if "`ctyp'" == "4" { /* radio button */ local we = 4 * (length(`"${GWSr1`vno'}"') + 3) window control radbegin `"${GWSr1`vno'}"' `xe' `y' `we' 7 GWSvv`vno' local xe2 = `xe' + `we' + 5 local i 2 while `i' < ${GWSrn`vno'} { local we = 4 * (length(`"${GWSr`i'`vno'}"') + 3) window control radio `"${GWSr`i'`vno'}"' `xe2' `y' `we' 7 GWSvv`vno' local i = `i' + 1 local xe2 = `xe2' + `we' + 5 } local we = 4 * (length(`"${GWSr`i'`vno'}"') + 3) window control radend `"${GWSr`i'`vno'}"' `xe2' `y' `we' 7 GWSvv`vno' } else { /* edit box */ window control edit `xe' `y' `we' 7 GWSvv`vno' maxlen `len' } if "`ctyp'" != "4" { window control static GWSvl`vno' `xv' `y' 60 7 } macro shift local y = `y' + $GWSls local vno = `vno' + 1 } local y = `hgt' - 45 /* Y co-ord of buttons */ local bx1 = int(`wdt'/2) - 44 /* X co-ords of buttons */ local bx2 = int(`wdt'/2) - 21 local bx3 = int(`wdt'/2) + 1 local bx4 = int(`wdt'/2) + 24 local bx5 = int(`wdt'/2) + 51 local bx6 = int(`wdt'/2) - 81 local bx7 = int(`wdt'/2) - 48 local bx8 = int(`wdt'/2) - 15 local bx9 = int(`wdt'/2) + 18 local bx10 = int(`wdt'/2) - 32 local bx11 = int(`wdt'/2) + 2 if "`next'" == "next" { if "$GWS_np" != "na" { window control button "More -->" `bx5' `y' 30 11 GWS_np } if "$GWS_bp" != "na" { window control button "<-- Back" `bx6' `y' 30 11 GWS_bp } } window control button "|<" `bx1' `y' 20 11 GWS_fst window control button "<" `bx2' `y' 20 11 GWS_prev window control button ">" `bx3' `y' 20 11 GWS_next window control button ">|" `bx4' `y' 20 11 GWS_last local y = `y' + 15 /* Y co-ord of buttons */ local butn = ("`del'" == "del") + $GWSedit + ("`new'" == "new") + ("`find'" == "find") local butn = `butn' + (!$GWSedit & "`new'" == "new") /* new button implies submit button */ if `butn' == 0 { local bx6 `bx8' /* close button */ } else if `butn' == 1 { local bx6 `bx10' /* close button */ local bx5 `bx11' /* submit button */ local bx7 `bx11' /* delete button */ local bx8 `bx11' /* new button */ local bx9 `bx11' /* find button */ } else if `butn' == 2 { local bx6 `bx7' /* close button */ local bx5 `bx9' /* submit button */ local bx7 `bx8' /* delete button */ if ($GWSedit | "`new'" == "new") { local bx9 `bx8' /* move find button if submit present */ } } if $GWSnew { window control button "Cancel" `bx6' `y' 30 11 GWS_can escape } else { window control button "Close" `bx6' `y' 30 11 GWS_can escape } if "`del'" == "del" { window control button "Delete" `bx7' `y' 30 11 GWS_del } if "`new'" == "new" { window control button "New" `bx8' `y' 30 11 GWS_new } if "`find'" == "find" { window control button "Find" `bx9' `y' 30 11 GWS_find } if $GWSedit | "`new'" == "new" { window control button "Submit" `bx5' `y' 30 11 GWS_sub } end * Subroutine. Populates the global macros in the dialogue * box with the nth observation of the variables given. * Also defines the commands associated with the navigation buttons. program define pop version 6.0 syntax varlist local N = _N global GWSobtxt "Observation number: $GWSobsno of `N'" global GWSpgtxt "Page $GWSpage of $GWSlpage" if !missing("$GWShtxt") { local hval = $GWShvar[$GWSobsno] global GWShead "$GWShtxt `hval'" /* Header */ } tokenize `varlist' local vno : char `1'[no] while !missing("`1'") { global GWSvv`vno' = `1'[$GWSobsno] /* value */ global GWSov`vno' `"${GWSvv`vno'}"' /* original value */ global GWSvl`vno' /* value label */ local vtype : char `1'[vtype] if "`vtype'" == "dat" { local varform : format `1' global GWSvl`vno' : display `varform' ${GWSvv`vno'} } else if "`vtype'" != "str" { local vallab : value label `1' if !missing("`vallab'") { global GWSvl`vno' : label `vallab' ${GWSvv`vno'} * Truncate to 16 characters: global GWSvl`vno' = substr(`"${GWSvl`vno'}"',1,16) } } macro shift local vno = `vno' + 1 } global GWS_can branch `varlist', rc(3000) global GWS_new branch `varlist', rc(3009) global GWS_find branch `varlist', rc(3010) global GWS_fst branch `varlist', rc(1) global GWS_prev branch `varlist', rc(2) global GWS_next branch `varlist', rc(3) global GWS_last branch `varlist', rc(4) global GWS_sub branch `varlist', rc(11) if $GWSobsno == $GWSfrec { global GWS_fst branch, rc(5) global GWS_prev branch, rc(5) } if $GWSobsno == $GWSlrec { global GWS_next branch, rc(6) global GWS_last branch, rc(6) } end * Act according to last button pressed on dialog program define branch version 6.0 syntax [varlist] [, rc(integer 3000)] if `rc' == 5 { window stopbox note "Already at first observation" exit } else if `rc' == 6 { window stopbox note "Already at last observation" exit } else if `rc' == 7 { window stopbox note "Already at last page" exit } else if `rc' == 8 { window stopbox note "Already at first page" exit } * Strip labels off drop-down box entries: tokenize `varlist' local vno : char `1'[no] while !missing("`1'") { local ct : char `1'[contype] if "`ct'" == "2" { global GWSvv`vno' : word 1 of ${GWSvv`vno'} } macro shift local vno = `vno' + 1 } if $GWSnew { /* in data-entry mode */ if `rc' == 10 { /* User pressed delete */ cap window stopbox rusure "Are you sure you want to delete this new observation?" "Press OK to continue." if _rc { /* User cancelled */ exit } global GWSnew 0 pop `varlist' } else if `rc' == 3009 { /* User pressed New */ window stopbox stop "You cannot create a new observation until" "this one has been dealt with." } else if `rc' == 3010 { /* User pressed Find */ cap window stopbox rusure "This new observation will be discarded if you search now." "Press OK to continue anyway." if _rc { /* User cancelled */ exit } global GWSnew 0 } else if `rc' == 11 { /* User pressed Submit */ cap checkval `varlist' /* Standard checks */ if _rc { /* Invalid value */ exit } if !missing("$GWScall") { cap $GWScall `varlist' /* User checking routine */ set trace off if _rc ==1 { /* Invalid value */ exit } else if _rc > 1 { nois disp in bl "The following error occurred in your checking program " in w "$GWScall" in bl ":" cap nois error _rc exit } } local n = _N + 1 disp in g "- set obs `n'" qui set obs `n' global GWSlrec `n' global GWSobsno `n' global GWSnmax = $GWSnmax + 1 saveval `varlist' global GWSmod 1 /* Modified dataset trip switch */ } else { cap window stopbox rusure "This new observation will be discarded if you" "continue as it has not been submitted successfully." "Press OK to continue anyway." if _rc { /* User cancelled */ exit } global GWSnew 0 } if `rc'<=3000 { local redraw yes /* Force re-draw of dialog */ } if `rc'==3000 { local rc 11 } /* if cancelled do not quit whole dialog */ } else { /* In editing mode */ if `rc' == 10 { /* User pressed delete */ if $GWSnmax == 1 { cap window stopbox rusure "This is the only observation in the dataset - are you sure you want to delete it?" "Press OK to continue." } else { cap window stopbox rusure "Are you sure you want to delete the" "current observation?" "Press OK to continue." } if _rc { /* User cancelled */ exit } else { if !missing("$GWSlog") { logdisp /* Display identifiers of curr obs */ disp "was deleted on $S_DATE at " substr("$S_TIME",1,5) "." } qui drop in $GWSobsno disp in g "- drop in $GWSobsno" global GWSmod 1 /* modified dataset tripswitch */ global GWSfrec 1 /* Observation no of first record */ while $GWStouse[$GWSfrec] == 0 { global GWSfrec = $GWSfrec + 1 } global GWSlrec = _N /* Observation no of last record */ while $GWStouse[$GWSlrec] == 0 { global GWSlrec = $GWSlrec - 1 } if $GWSobsno > $GWSlrec { global GWSobsno $GWSlrec } global GWSnmax = $GWSnmax - 1 /* No of observations to be displayed */ pop `varlist' /* Populate dialog box */ if $GWSnmax == 0 { exit 3000 } else { exit 3001 /* force re-draw of dialog */ } } } tokenize `varlist' local vno : char `1'[no] while !missing("`1'") { /* Check original values against current */ if `"${GWSov`vno'}"' != `"${GWSvv`vno'}"' { local updvars "`updvars' `1'" } macro shift local vno = `vno' + 1 } if !missing("`updvars'") { if $GWSedit { cap checkval `updvars' /* Standard checks */ if _rc == 0 { if !missing("$GWScall") { cap $GWScall `updvars' /* User checking routine */ set trace off } if _rc == 0 { saveval `updvars' } else if _rc != 1 { nois disp in bl "The following error occurred in your checking program " in w "$GWScall" in bl ":" cap nois error _rc } } } else { window stopbox note "You are in browse mode. Changes in the following" "variables were ignored:`updvars'" } } } if `rc' == 1 { /* First record */ global GWSobsno $GWSfrec } else if `rc' == 2 { /* Previous record */ global GWSobsno = $GWSobsno - 1 while $GWStouse[$GWSobsno] == 0 { global GWSobsno = $GWSobsno - 1 } } else if `rc' == 3 { /* Next record */ global GWSobsno = $GWSobsno + 1 while $GWStouse[$GWSobsno] == 0 { global GWSobsno = $GWSobsno + 1 } } else if `rc' == 4 { /* Last record */ global GWSobsno $GWSlrec } if `rc'==11 & $GWSnew { newob `varlist' /* continue with new obs in data-entry mode */ } else if (`rc' > 0 & `rc' < 5) | `rc'==11 { pop `varlist' /* Populate dialog box */ } if "`redraw'" == "yes" { exit 3001 } else { exit `rc' } end * Check values for validity * return code of 1 if any illegal values encountered program define checkval version 6.0 syntax varlist tokenize `varlist' if $GWSnew { /* data entry mode: */ local endtex1 This observation is not accepted. local endtex2 Press OK to submit anyway. } else { /* in editing-browsing mode: */ local endtex1 This change will not be saved. local endtex2 Press OK to make change anyway, cancel to restore previous value. } * Check all values are suitable local anyacc 0 /* 0 = no values accepted, 1 = at least 1 value accepted */ while !missing("`1'") { local accept 1 /* 0 = value not accepted, 1 = value accepted */ local vno : char `1'[no] local req : char `1'[req] local varlab : variable label `1' if !missing("`varlab'") { local varlab " (`varlab')" } local vtype : char `1'[vtype] if "`vtype'" != "str" & missing("${GWSvv`vno'}") { global GWSvv`vno' . /* Set blank numbers to missing */ } if "`vtype'" == "dat" { cap confirm integer number ${GWSvv`vno'} if _rc { /* If not number intepret as text date */ local dtext ${GWSvv`vno'} if "`dtext'"!= "" & "`dtext'"!="." { local dcode = date("`dtext'","$GWSdord") if missing(`dcode') { #delimit ; window stopbox rusure `"The text ("`dtext'") you entered into the `1' variable`varlab'"' "does not evaluate to a date. Remember that the year must" "contain the century (yyyy format)." "Press OK to continue anyway (a missing value will be entered)."; #delimit cr } global GWSvv`vno' `dcode' } } } if "`req'" == "1" & missing("${GWSvv`vno'}") { /* Check for required */ cap window stopbox stop "You must enter a value in the `1' variable`varlab'." "`endtex1'" if $GWSnew { exit 1 } else { global GWSvv`vno' ${GWSov`vno'} local accept 0 } } local nomiss : char `1'[nomiss] local ch1 = substr("${GWSvv`vno'}",1,1) if "`nomiss'"=="1" & ("`ch1'" == "" | "`ch1'" == ".") { /* check for missing */ cap window stopbox stop "Missing values are not allowed in the `1' variable`varlab'." "`endtex1'" if $GWSnew { exit 1 } else { global GWSvv`vno' ${GWSov`vno'} local accept 0 } } if "${GWSov`vno'}" != "${GWSvv`vno'}" { /* Check original values against current */ local vallab : value label `1' if !missing("`vallab'") & !missing("${GWSvv`vno'}") { /* Check for legal value */ local labtext : label `vallab' ${GWSvv`vno'} if $GWSstrt & `"`labtext'"' == "${GWSvv`vno'}" & `"`labtext'"' != "." { cap window stopbox stop "`labtext' is not a valid code for the `1' variable`varlab'." "`endtex1'" if $GWSnew { exit 1 } else { global GWSvv`vno' ${GWSov`vno'} local accept 0 } } else if "`labtext'" == "${GWSvv`vno'}" & "`labtext'" != "." { cap window stopbox rusure "`labtext' is not a valid code for the `1' variable`varlab'." "`endtex2'" if _rc & $GWSnew { exit 1 } else if _rc { global GWSvv`vno' ${GWSov`vno'} local accept 0 } } } } local range : char `1'[range] if !missing("`range'") { local value ${GWSvv`vno'} local ranglo : word 1 of `range' local ranghi : word 2 of `range' local rtype : word 3 of `range' if `value' < `ranglo' | `value' > `ranghi' { if "`vtype'" == "dat" { local varform : format `1' local value : display `varform' `value' local ranglo : display `varform' `ranglo' local ranghi : display `varform' `ranghi' } if "`rtype'" == "strict" { cap window stopbox stop "`value' is outside the permitted range of values (`ranglo' to `ranghi') for `1'`varlab'." "`endtex1'" if $GWSnew { exit 1 } else { global GWSvv`vno' ${GWSov`vno'} local accept 0 } } else if ${GWSvv`vno'} != . { /* note missing allowed if non-strict range */ cap window stopbox rusure "`value' is outside the permitted range of values (`ranglo' to `ranghi') for `1'`varlab'." "`endtex2'" if _rc & $GWSnew { exit 1 } else if _rc { global GWSvv`vno' ${GWSov`vno'} local accept 0 } } } } local anyacc = `anyacc' | `accept' macro shift local vno = `vno' + 1 } exit !`anyacc' end * Save changes program define saveval version 6.0 syntax varlist if !missing("$GWSlog") { logdisp /* Display identifiers of curr obs */ disp "was edited on $S_DATE at " substr("$S_TIME",1,5) "." } tokenize `varlist' while !missing("`1'") { local vno : char `1'[no] if "${GWSvv`vno'}" != "${GWSov`vno'}" { local vtype : char `1'[vtype] if "`vtype'" == "str" { cap replace `1' = "${GWSvv`vno'}" in $GWSobsno if _rc == 0 { disp in g "- replace `1' = " _quote "${GWSvv`vno'}" _quote " in $GWSobsno" global GWSmod 1 /* Modified dataset trip switch */ } } else { cap replace `1' = ${GWSvv`vno'} in $GWSobsno if _rc == 0 { disp in g "- replace `1' = ${GWSvv`vno'} in $GWSobsno" global GWSmod 1 /* Modified dataset trip switch */ } } if _rc { local vartype : type `1' cap window stopbox stop "${GWSvv`vno'} cannot be stored in the `vartype' variable `1'" global GWSvv`vno' ${GWSov`vno'} /* restore old value */ } else if !missing("$GWSlog") { disp "The variable `1' was changed from ${GWSov`vno'} to ${GWSvv`vno'}" _newline } global GWSov`vno' ${GWSvv`vno'} } macro shift } end * Set up dialog to add a new observation to the dataset program define newob version 6.0 syntax varlist * Note: this is the complete varlist tokenize `varlist' * Load default values local vno 1 while !missing("`1'") { local def : char `1'[default] local vtype : char `1'[vtype] if !missing("`def'") { if "`def'" == "todays date" { local def = date("$S_DATE","dmy") } global GWSvv`vno' `def' global GWSov`vno' if "`vtype'" == "dat" { local varform : format `1' global GWSvl`vno' : display `varform' ${GWSvv`vno'} } else if "`vtype'" != "str" { local vallab : value label `1' if !missing("`vallab'") { global GWSvl`vno' : label `vallab' ${GWSvv`vno'} } } } else { if "`vtype'" == "str" { global GWSvv`vno' global GWSov`vno' } else { global GWSvv`vno' global GWSov`vno' } global GWSvl`vno' } macro shift local vno = `vno' + 1 } global GWSobtxt "NEW observation" global GWShead global GWSpage 1 global GWSpgtxt "Page $GWSpage of $GWSlpage" global GWS_np "exit 3017" global GWS_bp "na" global GWS_sub branch `varlist', rc(11) global GWS_can branch `varlist', rc(3000) end * Verbose logging of edits program define logdisp version 6.0 disp "Observation no $GWSobsno in dataset $S_FN" disp "with the following identifiers:" tokenize $GWSlog while !missing("`1'") { local ident = `1'[$GWSobsno] local vtype : char `1'[vtype] local label if "`vtype'" == "dat" { local varform : format `1' local label : display `varform' `ident' local label "(`label')" } else if "`vtype'" != "str" { local vallab : value label `1' if !missing("`vallab'") { local label : label `vallab' `ident' local label `"(`label')"' } } disp "`1':" _col(11) `"`ident' `label'"' mac shift } end * Get value label list of variable `1' and put into global `2' * Put maximum label length (in characters) into global `3' program define getvl version 6.0 global `3' 0 local vlab : value label `1' if missing(`"`vlab'"') { di in red _n "`1' not labeled - cannot use drop down list." cleanup exit 182 } tempfile values qui { label save `vlab' using `values' preserve infix str s 1-80 using `values', clear } local i 1 while `i' <= _N { local si = s[`i'] local sin : word 4 of `si' local sit : word 5 of `si' local sil = length("`sit'") if `sil' > ${`3'} { global `3' `sil' } global `2' "${`2'}`sin' `sit'|" local i = `i' + 1 } restore local nomiss : char `1'[nomiss] if "`nomiss'" != "1" { global `2' "${`2'}. Missing" } end program define find version 6.0 syntax varlist if missing("$GWSvars") { /* only need to do this code first time around */ tokenize `varlist' while !missing("`1'") { local varlab : variable label `1' if !missing("`varlab'") { local varlab "(`varlab')" } global GWSvars "${GWSvars}`1' `varlab'|" mac shift } } global GWSfcan "exit 3000" global GWSfok "findok" global GWStf1 "Search for:" global GWStf2 "in variable:" global GWStf3 "Search from:" global GWStf4 "At last/first observation:" window control static GWStf1 10 5 50 8 window control edit 10 15 80 8 GWSftext window control static GWStf2 105 5 80 8 window control ssimple GWSvars 105 15 140 80 GWSfvar parse(|) window control static GWStf3 10 30 50 8 window control radbegin "next record forward" 10 40 90 8 GWSfdir window control radend "previous record backward" 10 50 90 8 GWSfdir window control static GWStf4 10 65 70 8 window control radbegin "continue at first/last obs." 10 75 90 8 GWSfcyc window control radend "stop searching" 10 85 90 8 GWSfcyc window control button "Find" 80 100 50 12 GWSfok default window control button "Cancel" 140 100 50 12 GWSfcan escape window dialog "Find" . . 260 130 end program define findok version 6.0 tempvar match obsno local fvar : word 1 of $GWSfvar local vtype : char `fvar'[vtype] if "`vtype'" == "str" { /* string var*/ if missing("$GWSftext") { mark `match' if missing("$GWSftext") } else { mark `match' if index(lower(`fvar'),lower("$GWSftext"))>0 } } else if "`vtype'" == "dat" { /* date var */ local ftext $GWSftext cap confirm integer number `ftext' if _rc { /* If not number intepret as text date */ local ftext = date("`ftext'","$GWSdord") } mark `match' if `fvar' == `ftext' } else { /* numeric var */ if missing("$GWSftext") { global GWSftext . } if "$GWSftext" != "." { cap confirm number $GWSftext if _rc { /* search string not numeric */ window stopbox note "$GWSfvar is a numeric variable." "Please type a number in the search for box" exit } } mark `match' if `fvar' == $GWSftext } gen double `obsno' = _n if $GWSfdir==1 { /* forward */ summ `obsno' if `obsno'>$GWSobsno & `match' & $GWStouse if r(N)==0 & $GWSfcyc==1 { /* continue from first obs */ summ `obsno' if `obsno'<=$GWSobsno & `match' & $GWStouse } local goto = r(min) } else { /* backward */ summ `obsno' if `obsno'<$GWSobsno & `match' & $GWStouse if r(N)==0 & $GWSfcyc==1 { /* continue from last obs */ summ `obsno' if `obsno'>=$GWSobsno & `match' & $GWStouse } local goto = r(max) } if r(N)==0 { window stopbox stop "No matching observations found." /* stopbox auto exits */ } global GWSobsno `goto' exit 3000 end program define cleanup version 6.0 if $GWSsm == 0 { set more on /* remember set more setting */ } macro drop GWS* end