How can Template #AT %DatasectionBeforeReport insert a variable def if not already declared?

How do I construct an #AT(%DataSectionBeforeReport) such that it will add a particular local variable only to the UnivReport procedures that do not already define the variable?

The code I have tried that does not work is:

#AT(%DataSectionBeforeReport),Where(%DisableBPForcePDF=0 and %DisableBPForcePDFLocal=0 and %ProcedureTemplate='UnivReport'),Description('BPForcePDF - Declare LocRptHeader'),PRIORITY(4212)
  #IF(INSTRING('LOCRPTHEADER',UPPER(%LocalData),1,1)=0)
LocRptHeader STRING('%Procedure') ! TODO: This var injected by BPForcePDF.tpl. [%LocalData]
  #ENDIF
#ENDAT

The [%LocalData] comes out blank with the above template code. Is there a template command to call in order to get the %LocalData populated with current info for the procedure that the #AT is acting upon.
-Rich F.

#LocalData
Loc:myvar string(1)
#EndLocalData

#Extension(IS_BlankColumn,‘IS_BlankColumn - Add a local string variablr to be a blank column in listboxes/browses’),Application(IS_BlankColumnLocal)
sheet
#Tab(‘’)
#Display(‘Create a local variable so it can be’)
#Display(‘used as a blank column in list boxes/browses.’)
#EndTab
#EndSheet

#Extension(IS_BlankColumnLocal,‘IS_BlankColumn - Add a local string variable to be a blank column in a list box/browse’)),Procedure
sheet
#Tab(‘’)
#Display('create a local variable so it can be ')
#Tab(‘used as a blank column in list boxes/browses.’)
#EndTab
#EndSheet

#LocalData
Loc:BlankColumn String(1)
#EndLocalData

Im writing this from my phone but if you copied the above to a tpl that template adds a local var to every procedure so from there you could add you restrictions like procedure type. My phone keyboard plays up on certain websites like this one and then I have to reboot my phone, and sometimes the virtual keyboard just dissappears!

#at(%embed),where(%ProcedureCategory=‘Browse’ or %ProcedureCategory=‘Form’)
#if(condition)
Some cw code
#endif
#endat

You might want to use

,where(%ProcedureTemplate=‘Source’)

and swap source for your report template. I think thats CPCS template but I never examined it in any detail so dont know how Larry named his templates per se.

Wow, you typed that on your phone!
I’m looking for a way to conditionally add the local variable to the procedure if it does not already exist in the data pad. From what I can tell your templates does not check to see of the variable has already been defined by the programmer in the data pad for the procedure. If only the Clarion language “OMIT” would work like the “C” language “#ifndef” then I could wrap the variable declaration with that. There must be a way to get the %LocalData variable set in the #AT but I cannot remember what it is.

You wouldnt believe the amount of hacking my computers have had. At one stage I was able to account for every packet of data going over the network but it still got hacked! Caught the TV trying to access my desktop! I wonder if that was a local TV OTA update attack as there would be little to no trace and I was surrounded by USAF and UK MOD personnel where I lived when that happened.

Do a loop through the local data looking for its name inside the local extension #prepare/#endprepare

Something like
#prepare
#declare(%addvar,long)
#Set(%addvar,%true)
#for(%localdata),where(%localdata=‘var’)
#set(%addvar,%false)
#endfor
#endprepare

To be honest I think this would be best exporting to a txa and just remove all instances found using a search and replace then the blankcol template would work nicely and it would be quick to do what you want then.

Yes, doing a #FOR like you suggested worked. And, yes, going in and just modifying these reports to be consistent would be best. But, I’m not a fan a monotonous work and there are 202 reports to go through across several .app files. Here’s the template code I ended up with:

  #! TEMPORARY FIX for reports that do not define the "LocRptHeader" variable
  #AT(%DataSectionAfterWindow),Where(%DisableBPForcePDF=0 and %DisableBPForcePDFLocal=0 and %ProcedureTemplate='UnivReport'),Description('BPForcePDF - Declare LocRptHeader'),PRIORITY(4212)
  #INSERT(%BPInjectLocVarRptHdr),NOINDENT
  #ENDAT
  #!------------------------------------------------------------------------------
  #GROUP(%BPInjectLocVarRptHdr),AUTO,PRESERVE
   #DECLARE(%MyVarIsHere)
   #SET(%MyVarIsHere,0)
   #FOR(%LocalData)
     #IF(%LocalData='LocRptHeader')
       #SET(%MyVarIsHere,1)
       #BREAK
     #END
   #ENDFOR
   #IF(%MyVarIsHere=1)
  ! *** BP ForcePDF already had LocRptHeader var
   #ELSE
  LocRptHeader STRING('%Procedure') ! TODO: This var injected by BPForcePDF.tpl.
   #ENDIF
1 Like

But you lose a bit of speed with the extra template code having to run everytime you generate and compile. Anyway, glad the #for helped.

This should work:

#Group(%BPInjectLocVarRptHdr),AUTO
    #EQUATE(%LocRptHeader, 'LocRptHeader')
    #IF(~INLIST(%LocRptHeader, %LocalData))
%[20]LocRptHeader STRING('%Procedure')
    #ENDIF

INLIST( Item , Multi-Valued Symbol ) is one of the Built-in Template Procedures

2 Likes

Oh, of course, why didn’t I think to use INLIST instead of INSTRING. INLIST works great.

1 Like

I like this, its eloquent.

Is it faster than using #for and all the other lines or much of a muchness?

Yes it’s faster, but doesn’t really make any difference. Mostly it’s more legible, and code should always tell a simpler story, if possible. :slight_smile:

1 Like

Totally agree, I havent used inlist in any code, keep forgetting about it but the difference between the template language and clarion language probably doesnt help.

1 Like

BTW, I often use #EQUATE in this situation. LocRptHeader was a magic string that was repeated twice. In that situation, I prefer to define it once (in this case using #EQUATE), then refer to the new symbol elsewhere.

The side benefit is that I can use this formatting technique to automatically align the data type in the variable declaration:

%[20]LocRptHeader STRING('%Procedure')