How to load the case with given primary id

Discussions about CSEntry
Forum rules
New release: CSPro 8.0
manishcspro
Posts: 67
Joined: June 26th, 2017, 2:15 pm

How to load the case with given primary id

Post by manishcspro »

I have created a data entry application to collect the monthly progress and cumulative progress of the community development works related to 23 different departments. The data is captured starting from April to March for each financial year. When the number of case increase the data entry becomes slow as the cursor moves slowly from one field to another. I want to create such an application which loads or open only the desired case or cases based on case id provided in identification menu rather than loading all the cases exist in data file.
The reason behind is data entry goes slow after number of case increases.

Is it possible to filter the cases when data entry opens.

Please guide about the solution.

Thanks..
sherrell
Posts: 397
Joined: April 2nd, 2014, 9:16 pm
Location: Washington, DC

Re: How to load the case with given primary id

Post by sherrell »

Hi Manish,

You can filter what cases a user can access by using the "CaseListingFilter" in your pff file as described here:

https://www.csprousers.org/help/CSPro/r ... entry.html

However, that shouldn't have any impact, for the data file size remains the same. Slowness is likely due to display/refresh issues, which usually happens when you have a large roster under the hood. If you'd like to send us your application to try out, please zip it with at least one case and send it to us at cspro@lists.census.gov

I'll also be sending you a direct message, so please look for that.

Sherrell
htuser
Posts: 631
Joined: December 19th, 2011, 6:26 pm
Location: Silver Spring Area, MD, USA

Re: How to load the case with given primary id

Post by htuser »

Dear Manish,
I want to create such an application which loads or open only the desired case or cases based on case id provided in identification menu rather than loading all the cases exist in data file.
I already doing something similar. Here's the way that i followed.
a) I'm using a menu to manage this;
b) I'm writing a PFF using pff object with followings specifications
b.1.- I'm using sql query to select cases that i want to display;
b.2.- I fill a list with the result of the sqlquery and using list.show for giving a way for end user to choose the exact questionnaire to open;
b.3.- I store this result of the choice in a specific variable who'll be used for the pff, for example, i named it questKey and i used it with
with pff properties CaseListingFilter and StartMode.
IpbPff_modify.setproperty ("ShowInApplicationListing","Never");
.setproperty ("CaseListingFilter",maketext("%s",questKey));
.setproperty ("StartMode",maketext("Modify;%v",questKey));
Here's an example of logic for this task. I'm upgrading and cleaning it using latest features. But it worked.
I used the same logic for add,verify and modify.
function EntryPffIpb_modification(function controller(string))
pff IpbPff_modify;
string  usern;
list string listeMenage;
list  string listeKeys;
    {if not setfile(outputFile,strip(pffFilenameIpb),create) then
        errmsg(101);
    endif;}
   
if getos()>0 then
        if getos
() <=20 then
           
codetablet=getdeviceid();
        endif;
        if getos()=30 then
            string
codeTabletUwp= getdeviceid();
            codetablet=codeTabletUwp[2:36];
        endif;
        numeric i=tblrow(CodeNomMachine);
        numeric j= tblcol(CodeNomMachine);
        do numeric ctr = 1 while ctr <= i
            string codeMachine =CodeNomMachine(ctr,1);
            if codeMachine=getdeviceid()
                then
               
//Errmsg  ("Le code %v est trouve",codeOp);
                  
nomtablet=CodeNomMachine(ctr,2);
            endif;
        enddo;

            usern = nomtablet;

    endif;
    string nomCsdb=strip(usern)+".csdb";
    string cheminCsdb=maketext (pathname(Application) + "Applications\IPB_V1"+"\Data\"+nomCsdb);
   
//Errmsg  ("Le chemin du ficher est %v",cheminCsdb);
   
if fileexist(cheminCsdb) then
        if filesize
(cheminCsdb) > 0
       
then
        string
listeMenage_query_formatter=maketext("SELECT cases.label FROM 'level-1' JOIN cases ON cases.id = `level-1`.`case-id` WHERE cases.deleted = 0 and `level-1`.codevicq = %v;",numVicq());//and cases.label<>''
        //Errmsg  ("la requete label est %v",listeMenage_query_formatter);
           
sqlquery(cheminCsdb,listeMenage,listeMenage_query_formatter);
               
   
    string listeCleMenage_query_formatter=maketext("SELECT cases.key FROM 'level-1' JOIN cases ON cases.id = `level-1`.`case-id` WHERE cases.deleted = 0 and `level-1`.codevicq = %v;",numVicq());//and cases.label<>''
    //Errmsg  ("la requete cle est %v",listeCleMenage_query_formatter);
    
sqlquery (cheminCsdb,listekeys,listeCleMenage_query_formatter);
     numeric tailleListeMenage = listeMenage.length();
     string cleQuestionnaire;
     if tailleListeMenage>0 then
    numeric
idQuestionnaireIndex=listeMenage.show (tr (1124));
     cleQuestionnaire=listekeys(idQuestionnaireIndex);
    else
    Errmsg 
("Vous n'avez aucune liste de menages a modifier!");
        controller("F");
    endif;
    //Errmsg  ("le cle du questionnaire est %v",cleQuestionnaire);
   
         //Errmsg  ("La version est%10.2f",tonumber (strip (diagnostics("version"))));
        
#if exists(MENU_GV_DICT)
   
    IpbPff_modify.load("IPB_mV1.pff");
    string univers=edit("99",numVicq());
                IpbPff_modify.setproperty ("Description","Formulaire Electronique IPB");
                IpbPff_modify.setproperty ("ShowInApplicationListing","Never");
                IpbPff_modify.setproperty ("CaseListingFilter",maketext("%s",cleQuestionnaire));
                IpbPff_modify.setproperty ("OperatorID",maketext("%v",strip(MENU_GV_DICT.CODE_UTILISATEUR)));
                //IpbPff_modify.setproperty ("Key",maketext("%v",strip(cleQuestionnaire)));
               
IpbPff_modify.setproperty ("StartMode",maketext("Modify;%v",cleQuestionnaire));
                IpbPff_modify.setproperty ("AutoAdd","No");
                IpbPff_modify.setproperty ("Lock","Add,Verify");
                IpbPff_modify.setproperty ("NoFileOpen","Yes");
                IpbPff_modify.setproperty ("Application",maketext("%v",strip(applicationName)));
                IpbPff_modify.setproperty ("InputData",maketext("%v",concat(strip(dataFolder),strip(usern),".csdb")));
                IpbPff_modify.setproperty ("Paradata",maketext("%v",concat(strip(dataFolder),strip(usern),".cslog")));
                IpbPff_modify.setproperty ("CommonStore",maketext("%v",concat(strip(RessourcesFolder),strip(usern),".db")));
                {EnqLegerePff_add.setproperty ("[ExternalFiles]");}
               
IpbPff_modify.setproperty ("RAPPORT_EXT_DICT",maketext("%v",concat(strip(dataFolder),strip(usern),"_ext",".csdb")));
                {EnqLegerePff_add.setproperty ("[Parameters]");}
               
IpbPff_modify.setproperty ("OnExit","IPB_m2V1.pff");
                IpbPff_modify.exec();
        #endif;
    endif;
    endif;
end;
Note that, this display a group of questionnaire based on some criteria and give the end user a way to open exactly the questionnaire he want to open: verify or modify. But, using the same thinking, there's a way to give end user a screen where to manually write a questionnaire key or ID Items and open it. The latest is more simple since it not require using sqlquery.

Hope this help you!
G.VOLNY, a CSProuser from Haiti, since 2004
manishcspro
Posts: 67
Joined: June 26th, 2017, 2:15 pm

Re: How to load the case with given primary id

Post by manishcspro »

Actually the data entry slows down due to the another listing file used to display the cumulative value based on the value of current month value and previous month value.

I have mailed the data entry application with data file.
Is their any faster way to display the cumulative value.

Please suggest the solution.
sherrell
Posts: 397
Joined: April 2nd, 2014, 9:16 pm
Location: Washington, DC

Re: How to load the case with given primary id

Post by sherrell »

Hi Manish,

Did you send your application to cspro@lists.census.gov? For I don't see anything there yet.

We've been having problems with our mailer for the past 2 weeks, and while the problem is supposed to be resolved, maybe it isn't. If you sent it to the lists, then it sounds like you better send it to me via PM on this forum as well, as we might still be having problems.

Thanks,
Sherrell
manishcspro
Posts: 67
Joined: June 26th, 2017, 2:15 pm

Re: How to load the case with given primary id

Post by manishcspro »

Hi Sir,

I have send the application to cspro@lists.census.gov.

Thanks..
sherrell
Posts: 397
Joined: April 2nd, 2014, 9:16 pm
Location: Washington, DC

Re: How to load the case with given primary id

Post by sherrell »

Hi Manish,

Thanks for sending your app. You wrote below:

>Actually the data entry slows down due to the another listing file used to display the cumulative
>value based on the value of current month value and previous month value.

However, what I think is slowing down the roster is the high number of calls to curocc(). There are 591 calls to curocc(), many of which are within loops, which means they'll be called even more times. Also, you're repeating the assignment to ACH_ITEM in both the preproc and postproc--but since ACH_ITEM is a protected field, and DEPT, upon which the value of ACH_ITEM partly depends, doesn't seem to be changing, you shouldn't need to do this. And, because DEPT is determined on a previous form, all of the logic should just be hardcoded in the preproc for the roster upon which ACH_ITEM appears so it just gets executed once, instead of all of this getting executed for every entry into the ACH_ITEM field. Therefore, instead of doing this in the preproc (& postproc) of PROC ACH_ITEM:

Code: Select all

IF DEPT='01' THEN
IF	CUROCC()	=	1	THEN	$	=	"0101101"	ENDIF;
IF	CUROCC()	=	2	THEN	$	=	"0101102"	ENDIF;
IF	CUROCC()	=	3	THEN	$	=	"0101103"	ENDIF;
IF	CUROCC()	=	4	THEN	$	=	"0101104"	ENDIF;
:
ENDIF:

IF DEPT='02' THEN
IF	CUROCC()	=	1	THEN	$	=	"0201101"	ENDIF;
IF	CUROCC()	=	2	THEN	$	=	"0201102"	ENDIF;
IF	CUROCC()	=	3	THEN	$	=	"0201103"	ENDIF;
IF	CUROCC()	=	4	THEN	$	=	"0201104"	ENDIF;
IF	CUROCC()	=	5	THEN	$	=	"0201105"	ENDIF;
:
ENDIF:

IF DEPT='03' THEN
:
You should do this:

Code: Select all

PROC ACH000
preproc

IF DEPT='01' THEN
	ACH_ITEM(1)="0101101";
	ACH_ITEM(2)="0101102";
	ACH_ITEM(3)="0101103";
	ACH_ITEM(4)="0101104";
	:
ELSEIF DEPT='02' THEN
	ACH_ITEM(1)="0201101";
	ACH_ITEM(2)="0201102";
	ACH_ITEM(3)="0201103";
	ACH_ITEM(4)="0201104";
	:
ELSEIF DEPT='03' THEN
	ACH_ITEM(1)="0301101";
	:
ENDIF;
Write back if this doesn't fix your problem, but I think it will.

Sherrell
manishcspro
Posts: 67
Joined: June 26th, 2017, 2:15 pm

Re: How to load the case with given primary id

Post by manishcspro »

I tried the solution but the problem remains the same. I am sure that large case list file slows down the data entry.
Is their any way to load the external case list file or to create the cumulative value based on previous month's value.

Thanks...
sherrell
Posts: 397
Joined: April 2nd, 2014, 9:16 pm
Location: Washington, DC

Re: How to load the case with given primary id

Post by sherrell »

Hi Manish,

>I tried the solution but the problem remains the same. I am sure that large case list file slows down the data entry.

The case listing data file is not that big, barely 1,300 entries. However, you're doing a lot of IO on the caselist.dat file, some of which seems unnecessary. For example, in PROC ACH_CP you're making a call to the showat() function in both the preproc and postproc. It's not clear to me if that is necessary. And within the showcp() function itself, it's difficult to tell exactly what matches you're looking for, as the logic could be optimized by using if-elseif-elseif-<etc>-endif blocks, rather than retesting the same condition several times. For example, instead of terminating the initial IF statement, it should be removed and the subsequent IF NOT should be an ELSEIF to continue the flow.

Code: Select all

IF (ACH_ITEM(I) IN "0601101","0602101","0603101","1602103","1701103",
			"1805101":"1805104","1807101":"1807103","1808101":"1808103",
			"1809101":"1809103","1810101":"1810103","1901101":"1901104") THEN
	ACH_CP(I) = ACH_MP(I);
ENDIF;

IF NOT(ACH_ITEM(I) IN "0601101","0602101","0603101","1602103","1701103",
			"1805101":"1805104","1807101":"1807103","1808101":"1808103",
			"1809101":"1809103","1810101":"1810103","1901101":"1901104") THEN
>Is their any way to load the external case list file or to create the cumulative value based on previous month's value.

Since this is a longitudinal survey, I don't know exactly how you're trying to run things/build the roster each time, especially with the PROC ACH_CP function being so long/unoptimized as mentioned above (and so difficult to parse without spending a significant amount of time on this). Can you construct the rosters from the prior month's data before sending the enumerators back out to the field to conduct the next month's survey? If so, that's what I would suggest to you, so that the rosters are ready to go.

Sherrell
manishcspro
Posts: 67
Joined: June 26th, 2017, 2:15 pm

Re: How to load the case with given primary id

Post by manishcspro »

Hi sir,

Used the customized code as suggested but still the problem exist.

Presently the application reads the previous month data from external data file created by data entry application using Write case function.

As each time the data entry starts first it creates case-list file from primary data file and then then loads this list file as external file to display cumulative value for based on previous month value.

I there another way to display the previous month vale while entering in current month without using external data file?

Thanks..
Post Reply