Thursday, September 8, 2016

Under the covers of the SELRCD function type


Hi,

This blog touches on the design challenges when using select record (SELRCD) function type and makes some recommendations for best practices.  Disclaimer:  These are from personal experience and may not cover all scenarios.  I would be happy to hear of any ideas/improvements that can be made to this post.

SELRCDs can cause quite a few issues if you are not aware of the quirks of how Synon generates the code.

Let's cut straight to the problem domain at hand.  In my sample model you will see that I have two files declared.  You will see that "Lee's File" Refer to "Lee's Reference File" which will mean that if I have a PMTRCD or EDTFIL etc over Lee's file we will be able to prompt for the reference data.


The functions I have over the reference file are as follows, I have removed the default EDTFIL and renamed the database primitive functions inline with our internal development standards.

 The main file has numerous test functions so I have filtered on Edit file only.


The screens (Edit File and Select Records) in the blog post have been tidied (ever so slightly) to ensure that all the fields fit nicely on the screen.

I have generated up the code for the EDTFIL.

Reviewing the generated code.

By default you will see that Synon has generated code to call the SELRCD function upon prompting the field and Synon has chosen my SELRCD based on the reference file.

You will also notice that the parameters for the SELRCD have been defaulted to fields based on the RCD context of the calling program.  In this instance it was an EDTFIL.


This is pretty standard and works a treat.

Now we will add a few additional SELRCDs, you will see these below.  Note the naming of these was deliberate in order to ensure that they appeared after 'Select Lee's Reference Fi'.


In terms of impact analysis you will notice that the SELRCD is showing no usages although we have generated code above that proves the object is called.


This is due to implicit code generation that is automatically added if the field is a result of a foreign key constraint AND is input capable AND a select record exists on the reference file.  If you deleted the SELRCD at this stage and generated the code again the prompt and call logic will not be generated.  Give it a try!


Above is a screen image of the default Synon setup.  Notice the two subfile options at the bottom of the screen.  S allows you to select the SELRCD that should be used, T clears this value and leaves the generator to choose the default SELRCD.


After taking the S option and selecting my SELRCD from the reference file you will see that this is indicated above.  Because we have made an explicit reference to the SELRCD in the device design it will now appear as a usage within Synon.


You will see below that the generated code is as before which is great :-)


In order to help with the blog narrative, please now deselect the SELRCD by taking the subfile option T for default behaviour.   This will clear the reference to the dedicated SELRCD.


Now we will create another SELRCD (again deliberately named).  You will see that it sits above the current (default) select record for the EDTFIL.


If we generate the EDTFIL again we will see that the outcome is no longer the same. The generator now puts a call into the higher ordered SELRCD on the reference file.  We didn't intend for this to happen and a developer doing a regeneration could easily pick this up without knowing.  Quite dangerous....


In this instance, as the keys on the SELRCD are identical there is NOT too much to worry about.  However, in the real world 2nd and subsequent SELRCD functions will typically be over an alternate access path with a different key structure or may have additional parameters or specialist action diagram functionality which may not be the preferred default behaviour.

In order to demonstrate this let's add some fields to the model which we will then associate with a new SELRCD function.


Create yet another SELRCD function over the referenced file.  Note again I have named it deliberately so it appears at the top of a refreshed EDIT FUNCTIONS panel.


I have extended the parameters for this SELRCD to add our five new fields.


Let's generate up the EDTFIL once again and look at the generated code.

Ouch!!  Houston we have a problem.

You will see below that all of the new parameters have been defaulted to CON.  This is because the fields were not found in context for the relationship. i.e. in this case, not part of the RCD context. And because this is a warning message only it may go unnoticed.  Preferably Synon should mark these as errors and only allow the correct context ones to generate correctly i.e RCD example above.

Also we have now picked up yet another SELRCD.  One can conclude that anytime a new SELRCD is added and it appears higher up in the EDIT FUNCTION panel the next time a referencing function is generated it will generate code to call the new SELRCD and not the previous one.  Imagine a highly reference file and the chaos this could bring.


We can do somehing to help here.  Whilst we cannot get at the parameters at the point the implicit call to the SELRCD is made, we can put these fields in the context and populate them accordingly.

Add the fields to the 'Subfile Record' format RCD.  You will notice I set these to hidden.


Then in the action diagram you can set these values using a standard *MOVE built-in function.



Generate the function once more and the generated code now shows the moved and also defaults to the RCD context meaning that you no the parameters are populated with your values and NOT CON blank or Zero.



But I remind you at this stage that these were warnings in the code only.  How many people check the generated source for warnings.  I don't, do you?

Another way to do this is to switch off default processing and take control of the prompting yourself in the action diagram coding.  Back in the EDTFIL function again set the relation checking to 'USER'.




Note: This switches off all referential integrity checking so in the real world you'll also need to add action diagram code for the OPTIONAL/MANDATORY as well as foreign key constraints.  For the purposes of this blog I am only focused on the prompting and calling of the select record.

You can then monitor for prompting on your field and call ANY SELRCD function you think is appropriate.


With this method you get a nice parameter interface for the SELRCD and more importantly it is obvious to another developer that you are initialising the fields for an explicitly called SELRCD rather than an implicitly called on.  Some comments might be useful if you choose the other method.


This highlights the many options you have for calling a SELRCD and should help you decide what is best for your model, team etc.

Once last issue with SELRCDs.  I mentioned earlier that Synon (by default) will chose the highest SELRCD based on the referenced file.  Due to no usages showing it is possible that code will be generated to call an object that hasn't been created or has been removed by a developer thinking it is not used.  This will mean you'll get a 'resolve to object' call error which isn't a good look.


Best tip is to generate up a standard SELRCD for each reference file and implement it at the time the file is created.  If you decide that a file doesn't need prompting, then remove ALL SELRCDs from the file so this code doesn't get generate implicitly.  As you can see from above the code will get generated if the function exists regardless of whether the object exists or not.

Best Practices Summary

  1. Come up with a naming convention for the default SELRCD so that it is first in the list on the EDIT FUNCTIONS panel.  We use '*SLT xxxxxxxxxxxxxxx'.
  2. Always ensure you generate up and implement ALL SELRCD functions.
  3. Always keep the default SELRCD keys the same at the RTV access path.
  4. Always name 2nd and subsequent SELRCD so they appear lower in the EDIT FUNCTIONS panel.
  5. It is recommended you set explicitly the SELRCD you want to call either by the 'S' option or via action diagram coding.
  6. Never delete any SELRCD objects without checking the generated source files or by exploring all file references.

Thanks for reading.
Lee.

Monday, September 5, 2016

CHGOBJ and easy file maintenance

Today I want to write about a neat little method of setting up CHGOBJ DBF internal functions to assist with long term file maintenance.  I have touched on this before in my standards posts but decided that as I keep seeing people do this incorrectly (wherever I work) that it deserved a blog post of its own.

Imagine a nice simple file being added to your data model.  I have added one below.


As you can see above it has one key and a few neatly named attributes.


The file was a reference file but for cleanliness I have removed the default edit file and select record functions.  Also in our shop we have a standard of preceding the primitive DBF functions with an asterisk so I have done this also.

The parameter structure for the CHGOBJ is as expected for a full record CHGOBJ.  Nothing spectacular here.  This thankfully is default 2E behaviour.



In order to show the proposed methods I want you to use, we need to imagine how we are going to modify the data in this file.  Typically we won't change the entire record with the exception being an EDTFIL/EDTTRN which will as default use the full record update or if you have created a W/W + PMTRCD maintenance suite which is quite common. type function .  

In the real world we update a total amount, a status, or more typically a subset of relevant data.  To do this we often create individual CHGOBJ's named something like 'Change Account Status' or 'Update Address Only'. 

Below I have created two separate CHGOBJ's to update the status field on this file.  I have imaginatively named as below.


Method 1 is (as defaulted) passing the entire file structure as RCD.  The parameters at the detail level are setup as follows.  Note that I have set the parameters we are not updating as NEITHER and turned off the MAP role  Nothing gets me more irritated in Synon coding than leftover MAP roles...


Method 2 has the data passed differently.  I am using two parameter blocks.  The first one for the keys or key in our case.  The second line for the data attributes where I have set the status filed we wish to update as input.  Again I switched off that darn MAP role.




Both these CHGOBJ's (Method 1 and Method 2) now have the same interface as far as calling programs are concerned.  i.e. two fields.  The key 'MSF My Key' and the fields we want to update i.e. the status field 'MSF Attribute 03 (STS)'.

There is one caveat though.  Method 2 won't work. 

Not yet anyway.  Let me explain why...

There is action diagram code inside all CHGOBJ's that implies the function moves the data passed in via the parameters (PAR) to the database record (DB1) just prior to update.  You can see this in the picture below.


However, the Synon generator has been written (by design/bug/undocumented feature) to only move fields passed in the first parameter block.

Yes.  Shortsighted I know but it is a known limitation.  Go ahead try it for yourself.

This means that in this instance it will only move the values passed in the highlighted row below.  In our example for Method 2 this would be the key only.


The way we get around this is to do the move ourselves in the user point immediately after the badly generated code.


This now moves the attributes into the DB1 context from PAR.

Job done.  This function will perform valiantly and won't let you down.  However, at this stage there is no advantage doing the CHGOBJ this way.  Why would you separate the parameters and add extra complexity forcing developers to add the *MOVE ALL if the two functions are now (functionally) identical?

If your shop has standards then it's likely you've learned the hard way.  Remember the average application spends 90% of its functioning life in maintenance, and therefore, it is these activities that cost the real pounds/dollars and take the time to implement.

Change is inevitable and most files will require some form of change during their lives and the most common type of change for a file is adding new fields. This is where method 2 outshines method 1.


Let's make some basic adjustments to the file.  In the example below we are adding three extra fields which have been appropriately named.


So how has this impacted our functions that we have created in the blog post?  The standard CHGOBJ (the *CHG) for the entire record has the three additional parameters automatically added.  We just need to visit its usages and set the values accordingly.



Our two examples (Method 1 and Method 2) fair quite differently.  Let's discuss these below.

First;y, I will quickly remind you that the two methods for the CHGOBJs were only updating a subset of fields of this file rather than the entire record, in our case the status field 'MSF Attribute 03 (STS)'.

Method 1 has had the extra fields added automatically which is not ideal or what we want.  We now need set these to NEITHER.  Forget this at you peril.  Note: I also removed the MAP!


Method 2 however, keeps the existing input parameter structure.  There are no changes to be made other than regeneration due to the changed file.


So on the surface it would appear that method 2 is best for CHGOBJ's where a subset of data is changed.

At this point I would recommend you utilise *Template if you haven't already looked at them.  I even have templates for a standard RTVOBJ so I don't forget the *MOVE ALL for CON and DB1.

Below is an example of how I implemented method 2.

Function name.


Parameter block.


Detail for parameter block 1 .


Detail for parameter block 2.


Add the AD code for the move all.


That's the template completed.   Use Shift F9 to create the function from the EDIT FUNCTIONS screen.  Select the template type and then name it appropriately.


Set the parameters you want to include in the CHGOBJ.


Switch off the map and you are up and running. 


The Action Diagram code has automatically been added to your new function as long as you put the *MOVE ALL in the *Template.

In Summary.

It hasn't got to be a one size fits all approach.  There is no harm in choosing a hybrid approach, so.
  • Use Method 1 for full record updates.
  • Use Method 2 for subset or single field updates.
  • Consider using templates to enforce your standards and to reduce any mistakes or omissions.

Thanks for reading.
Lee.

Saturday, September 6, 2014

Opportunities

Hi All, 


My current employer is always on the lookout for quality 2E people.  All enquiries welcome.  Just link in with me (See button on this blog) or PM me.  Please mention this on the invite.


Preference will be given to those either in Australia or eligible to work in Australia.  (No remote working as yet).


We are also interested in young junior/mid range level programmers to compliment the team.


Thanks for reading.
Lee.

Sunday, November 17, 2013

Why the notepad is such a cool feature in 2E

The notepad feature in 2E is used by most of us during our development.

More often than not its a case of loading the notepad via the NR or NA commands and then navigate to the target function and insert the logic using the NI command.   We generally use it as a Copy function across function boundaries.

This is pretty neat but there is a particular flaw with this.

The notepad in its default configuration is session bound.  i.e. log in tomorrow and it'll be empty.  In fact its slightly worse than that.  Once you have exited all open programs the notepad is cleared.  This means you may often find yourself reloading the notepads with the relevant code.

Imagine a maintenance scenarios where you are visiting 10, 20, 50 or 250 programs to apply the same maintenance......

Thankfully, our friends at Synon/CA have had a little hidden gem for years and years and it amazes me that nearly every site I go to, no one has ever heard of this little feature.

Firstly, let's understand the science.  The notepad is basically and execute internal function that isn't saved.  What the developers did was to effectively allow us to configure a function that will be saved.

Here's how to go about setting this up at your site.
  • Create a structure called #Notepads or any other name that suits your site standards.  I prefer to have a structure file so all developers notepads are in one place rather than added to a business entity.
  • Create a function similar to those in the screen print below.  The choice is yours how you name it of whether its an EIF or EEF.
  • Now go to the services menu (The F17 one) and take option 11 Edit model profile (YEDTMDLPRF).  Towards the bottom of the screen you will see a section for configuring your notepad.

And that it pretty much it.  You will now get asked if you wish to save the notepad when you use it but it remains over many sessions.  You will also have guessed that you can have many of these 'code snippets' waiting for you.

About the only fly in the ointment is that the notepad can get locked out with multiple sessions but if using for cut and paste I believe the benefits outweigh this.

Thanks for reading.
Lee.

Monday, June 10, 2013

Those pesky little 2E errors we all make

After 8 months in the Plex and 2E badlands (employment break).  I am back working in the 2E space for a fantastic company based in Sydney.  I've been super busy with this work and have had little spare time to blog.  Sorry!

I've dusted off my old tips and technique guides and thought it was about time I finished off some of the 2E stuff that I had planned.

Today I'd thought I'd touch on a few 101's.  You know the simple errors we have all made.  The content is aimed a junior or new developers but I encourage the very experienced to also contribute to the debate as I am sure there are other examples.

If you do choose to comment and add to this.  Thank You.

Room 101!

I started writing this list a few months ago and it was added to every time I or a colleague (main culprits) made one of those simple mistakes!  In no particular order....


  1. If you want your RTVOBJ to return the values of a 'RTV All Record' call then it is important to put the *MOVE ALL from DB1 to PAR inside. ;-)  I guarantee that every 2E site on the planet has a set of these.
  2. If you want to promote your programs via CM, then ensure they are on the correct model list, otherwise the stay where they are. :-)
  3. If you want to edit a source member ensure that you use '2' to edit and not '5' to display. :-)
  4. It's not really that important to worry about change control when files are in QTEMP :-)
  5. When debugging ensure you have the option for debugging production files set to *YES :-P
  6. If calling a 2E program via a CLP wrapper (API), remember to put the *return code in the parameter interface.
  7. *QUIT in a Internal Function is NOT a good thing to do if you were trying to exit the code block quicker.
  8. When waiting around for a generate and compilation to complete make sure that you have pressed enter and confirmed!!!!
  9. Don't try to generate a function you have open in another session :-)
  10. If your program relies on a new file or access path, make sure that it is compiled AND/OR moved to the correct library first :-)
  11. If you plan to do a rollback using Test Bench ensure that you have set the checkpoint in the first place.
This list will be expanded over time......


Thanks for reading.
Lee.

Thursday, September 20, 2012

Game creation tools. New domain, same conversation.

Some gaming on the side.....

Yeap.  For the 2E and Plexers out there I am afraid I am between opportunities at the moment so am not using the tools on a daily basis.  In the meantime I have turned my hand to a second love of mine.

Making computer games.  

Some of you may know that I have written games in the past.  I remember demonstrating/hassling my colleagues way back when I was working in London as I was creating a game.  6 months of sweat (some tears) later...... I published a shoot em up (Galaxian style) in 1999 for my cousin who was 13 and totally chuffed when he realised that he could blow up his parents on Level 5 (Phase III).

I am pleased to say that some years later he turned out to be of sound character so killing his virtual parents never crossed contaminated his real word views. :-)

At the time I used a tool called "The Games Factory".  This was a IDE and engine rolled into one and it allowed you to create a game (at that time it targeted windows).  This tool has had a second version and updates ever since and has also been superseded by a tool called "Multimedia Fusion 2".

Nowadays, this tool can create games for Web, Android, iOS (iPad and iPhone) as well as XNA for windows devices.

I decide to blog a little about this as the concept of these types of tools is not too far removed from the ideals behind the 2E and Plex tools (technology insulation, templates, productivity) to name a few of the key features over raw coding.  I am currently using two additional tools from www.gamesalad.com and www.stencyl.com.  Both tools are aimed for lowering the threshold to get into games creation for your favourite devices.

The irony for me is the forums I take part in have the same debates that defenders of 2E and Plex have endured over the years.  i.e. 3GL coding versus 4GL code generation.  Numerous times I have had to draw the comparisons for this generation Y or whatever we are calling youth now.

In one camp is the (take Apple) XCode only guys who have hand crafted every element of the game engine and experience, whereas, on the other side are Stencylites or Saladers who believe in gameplay and quality graphics etc etc.

As always it depends on the project, timescale, developer capability and you guessed it, no one solution to fit all scenarios or game types, they all have there limits, learning curves and price point.

The grand daddy of 3d games in this space (hobby, Independent to Studio) is Unity but that also comes with a price tag to match.  Still all of these are cheaper than licensing a 3rd party engine like Unreal.

On the gaming side of my life at the moment I hit issues with game performance that require tuning, features that are not yet in the tools but on the roadmap and eagerly awaiting updates, 3GL vs 4GL debates within forums etc etc.    In a way a parallel universe to my professional life using 2E and Plex.

If any of you 2E and Plex guru's out there fancy doing something a little different you'd not do much better than the tools I have mentioned.  Unless you are a coder coder and therefore you can utilise some of the SDK's and chose your relevant physics engine for example :-)

Now I just need an excuse to integrate a Plex or 2E server application within a game and be the first person to integrate these technologies......

When the game I am building hits the stores I'll be sure to let you know.

Thanks for reading.
Lee.

Edit 1 - Fixed up a few typo's
Edit 2 - There is also another SDK of interest called CoronaSDK which bridges the gap between the 3GL approach and the 4GL approach.  It's effectively uses and intermediate language that then compiles and uses runtimes for the relevant devices, all packaged neatly and available to download from an app store near you.  Check it out www.coronalabs.com

Wednesday, June 6, 2012

Job Opportunities

Local or Remote.
Casual or Contract.

No harm getting in touch.




You may also be interested in other areas of skill and expertise so take a look at the LinkedIn profile (in the links section on the right ------>).


My new company (launching in June 2012) will be specialising in custom software development for:-


Business Applications
Web & Cloud Solutions
Mobile Apps
Games


For more information message me at the above email address.


Thanks for reading.
Lee.

Monday, April 30, 2012

You either read my blog because you are a CA Plex and/or CA 2E programmer and you are keen for a different perspective or you may have googled Plex and landed on my site instead of the other technology out there called Plex and not CA Plex.

Anyhow, a few things have happened in the CA Plex and CA 2E marketplace in recent weeks so I though a quick round up would be in order.

  1. Plex 7.0 has been released with the new .NET Client generator option.
  2. 2E version 8.6 has been released with the marquee feature of passing arrays as parameters and therefore ability to easily deal with result sets.   For both of these look at the CA website for details on how to download etc as well as accompanying web casts and PowerPoint presentations.
  3. Is a nice article about Plex.  http://www.mcpressonline.com/dev-tools/ca-plex-could-be-the-best-development-tool-of-all-reader-says.html   There may well be more to come with this.
  4. Is that Websydian are launching the latest version of their patterns (version 6.5), that webcast is tonight my time here in New Zealand.
  5. The Plex-XML guys are quite busy working in the background as this framework begins to make strong traction in the CA Plex community.

Thanks for reading.
Lee.

Sunday, March 11, 2012

Beginners Guide to the CA Plex Model API using C# .NET - Part IV – ‘Some DotNet Tips and Tricks’


I have written about the inspiration behind using the ModelAPI and alluded to some good examples of where it is being used in the real world including my own ‘Entity Creator’ project.

I have covered the concepts behind the ModelAPI and its relation to the Plex IDE and in particular to the Model Editor and Object Properties windows in Plex which are critical in helping you understand the ModelAPI.

I have blogged about some of the methods that are available to Plex developers to manipulate and extract information from the underlying model.  

Plex 7.0 is here now (available via electronic download and going GA soon) and it introduces 5 new methods that would be useful for us ModelAPI converts.


  • FindRealObj
  • FindOrAddRealObj
  • ShowObjHelp
  • GetObjSurrogate
  • GetObjPackageName


To my surprise after a count in Plex 7.0 (Version 4.0 of the Model API) there is now a staggering 92 methods and I have enhancement requests in the pipeline for a further 3.

The Tutorial

Part IV in this series I promised to walk you through a C#.NET tutorial for building your first (basic) ModelAPI program outside of Plex.  If you prefer to use Java or even Plex then some of the concepts and the code outline will help but you are on your own from the implementation syntax perspective.

To keep it simple we are going to create a standard WinForm application.  

Assumptions

This tutorial assumes you are using CA Plex 6.1 and will work with all build levels.  If you are serious about the ModelAPI then upgrade to build 32 ASAP, there have been lots of improvements made in the API and some critical fixes to some of the methods.  You could also upgrade to 7.0 too.

Visual Studio 2008 is used in this tutorial.  I would suggest that 2010 can also be used although the screen layouts and some menu options may differ.  

Directory locations implied or pictured may need to be altered for your environment depending on your own personal setup.

I assume that you have some Visual Studio programming knowledge and are aware of the control types of TextBox, Label and DataGridView and basic syntax like declaring of fields in C#.  However, I think that you will be able to follow this through as I have written with the 100% novice in mind.
Disclaimer

This is my crappy C# coding.  I haven’t been formally trained and there may be better ways of achieving some of the coding I have created but I am willing to receive feedback and will adjust as required.

Let the tutorial begin.

A screen print of the finished tutorial is below so you know what you are creating and you can add your controls to forms canvas in a similar manner. 



Links to these posts, a PDF document consolidating all posts and a ZIP archive for the completed source code will be available on the Plex Wiki.

1. Create a new folder on your C:\ called C:\PlexTutorials
2. Open Visual Studio
3. From the main menu select File, New, Project
4. Complete the New Project dialog as follows



Note: If C# doesn’t appear then you will need to look at your Visual Studio installation.  
Also understand that your screen might be slightly different depending on what project templates you have installed in your environment.

5. Click Ok to confirm
6. Your screen should like something like this



The key windows are Toolbox, Solution Explorer and Properties.  If you don’t get these showing you can toggle them on via the View menu or by using the keyboard shortcuts.



If these are not shown it might be that they are hidden on the screen.  In which case like this example with a hidden toolbox you need to click as below.



You need to click the Toolbox tab and it will automatically reveal.  Then just toggle the Auto Hide option.



GUI Layout

7. If you haven’t already, click on the Form1 in the main canvas.  It will now have the control handles around the outside if you have, then  adjust the following properties in the properties window (See screen below) – Note they are in bold if different from the default.  Same as Plex and the L (local) override indicator.
a. Text = Show Field Triples
b. Size = 600,400




8. Now let’s add the controls we need to the Form.  In the Toolbox click on the Label control and drag it across to the canvas, let go of mouse and then set its properties as follows
a. Text = Field name:

9. Now add a TextBox next to the label on the Form and set the following properties (Remember the complete image above)
a. Name = TextBoxFieldName
b. Size = 250,20
10. Now ‘Double Click’ the Button control in the ToolBox and it will automatically be added to the Form.

11. Now drag this new button to be to the right of the TextBox just added and set its properties as follows:-
a. Name = ButtonShowTriples
b. Text = Show Triples
c. Size = 100,23

The Form should look something like this...




12. Now add a DataGridView (Grid) control to the Form.  These are located further down the toolbox in the Data folder.  Add to the form and accept the defaults from the DataGridView Tasks pane for now.

13. If not selected, select the grid and set the following properties:-
a. Size = 560,280
b. Location = 14,70
c. Name = GridTripleDetails
d. AllowUserToAddRows = False
e. AllowUserToDeleteRows = False

14. You will notice that the Grid has a small right facing arrow at the top right hand side.  Click this to show the Tasks pane again and then select Edit Columns... to bring up the editor for the grid control.  (The tasks pane shows the most common properties and editor for a particular control).





15. Currently we have no columns.  As you can see with our completed project we want one column in the Grid called Triple Details where we show the full triple details for the YesNo field.

16. Click Add to add a new column and complete the Add Column dialog as below and the press Add button.



17. Now click the Close button to close the Add Column dialog which returns you to the edit Columns dialog.

18. Now set the Column Width property to 500 and press the OK button to close.

19. Your form should now have a Grid Header row with ‘Triple Details’ and the width of the field should cover most of the grid.

20. That’s it for now with the Form Design to this would be a good time to save progress so far using the familiar save icon on the toolbar.


Coding

Now for the coding but before we start I’ll give you a quick overview of what we are about to do.

We are going to declare the Plex ModelAPI and then instantiate it in C#.
Then we are going to write the code that reacts to the ‘Show Triples’ button being pressed.  As with Plex we link the act of clicking the button to a logical event that executes the code.  If you have used Visual Basic or Access you would have done this a hundred times.

21. Right click anywhere on the Form but not on a control and select the View Code menu shortcut.


If you have more menu items than this then it is likely you have selected a control and NOT the form.  Anyhow, View code will open a new tab and show the Form as Code View.  It should as below.





22. In order to program against the CA Plex Model API COM Component Visual Studio must know about it.  This is what we call a reference.

23. In the Solution Explorer window (The one on the right hand side of the code window), right click on the ShowFieldTriples project and the select ‘Add Reference’ menu option.  You could also have selected Project from the Main Menu and selected Add Reference from there.



24. WAIT....This will bring up the Add Reference dialog but depending on the speed of your system and the number of potential references that can be added this might take a few seconds to appear (over 30 seconds elapsed on my laptop).  See below.


If you have by now upgraded to Plex 7.0 then this might say PlexAPI 4.0 Type Library (Depending on what CA do here).

25. Click on COM tab and then scroll down to select the PlexAPI Library.
26. Click OK to add the reference.
27. PlexAPILib should now appear in the Solutions explorer under the References folder.



28. Back to the Code View tab and immediately under the last using statement enter the following.


using PlexAPILib; //Declare Plex Model API

29. After

public Form1()
        {
            InitializeComponent();
  }

        Enter

    //Instantiate a version of the Model API in memory and refer to it as "_Plex" from now on.
    private static PlexAPIClass _Plex = new PlexAPILib.PlexAPIClass();

Note:  For Visual Studio 2010 you will need the following instead.

    //Instantiate a version of the Model API in memory and refer to it as "_Plex" from now on.
    private static PlexAPI _Plex = new PlexAPILib.PlexAPI();

30. Your code should now look like this


Screen print is for Visual Studio 2008 solution – see note above.

Recap.

Now Visual Studio references the Plex API and will load a copy of the interface into memory when the application is run and is named _Plex.  All we have to do now is react to the form and interrogate the model via the API methods and display them in the grid.  Simple!!!!


31. Click on the Form1.cs [Design] tab above your code window
32. Double Click the Show Triples button to create the ButtonShowTriples_Click event handler.  The following should now be shown in your code window.

        private void ButtonShowTriples_Click(object sender, EventArgs e)
        {


        }

33. Position your cursor between the braces and enter the following.

        //This is the area where I declare ALL the variables that are used by this program
        int MyFieldObjID = 0;

The MyFieldObjID field above may be underlined green (like the Word grammar checker) at this point. Don’t worry about this, this is just Visual Studio telling you that a field has been declared but is not used.

As mentioned in a previous post all objects in CA Plex have a unique internal number.  In order to obtain this we use the FindObj method from the ModelAPI.  You will recall it takes three parameters the object name, object type and returns the ID of the object.

34. Leave a couple of lines gap after the last entry and now let’s enter the following code snippet.

       _Plex.FindObj(TextBoxFieldName.Text.Trim(), 6, ref MyFieldObjID);





Here is a summary of what this line is doing....Using the _Plex ModelAPI that we instantiated into memory call, its FindObj method (function) and pass in the contents of the TextBoxFieldName after trimming any trailing blanks.  Let the FindObj API know we are looking only for a field (Object Type = 6) and then store the returned ID of the object (if found) to my new field MyFieldObjID.

35. If an object is found that matches the name and type then the internal ID is returned, otherwise it will be 0.  We only want to proceed if an object exists otherwise we will send a message to the user.  Enter the following immediately below the FindObj statement.

            if (MyFieldObjID != 0)
            {


            }
            else
                MessageBox.Show("Field " + TextBoxFieldName.Text.Trim() + " not found in this local model");

36. If everything has gone to plan then your code window should look like the image below.




37. If not already open, Open Plex and a local model of your choice.  If all is well you can run the tutorial program from inside Visual Studio by pressing the debug button.



38. This will build the project and execute the code.  Try entering a field you know doesn’t exist and you will see our error message and when you type a correct field like YesNo then the message will not appear.



39. Now you have tested what we have so far.  Stop the debugger by clicking on the stop button or close the application using the Windows Close X button.

Now we have covered the basics of ModelAPI and Visual Studio I’ll expedite the completion of this tutorial now by asking you to enter the following two snippets of code.  The first snippet is the declaration of all the variables that we’ll be using and initialisation code to clear the grid after each invocation.  The second snippet is the heavy lifting to interrogate the API and append the details to the Grid.  The comments in the code should suffice.



40. Under the line int MyFieldObjID = 0; Enter the following.

      int MyFieldTriples = 0;   //The enumerator ID for the triples associated with the Field.
      int MyTriple = 0;         //When we loop through the triples this stores the Model ID for the Triple.
      string TripleNameDetails = ""; //The actual Triple returned from the GetTripleName method.
      int NumberOfTriples = 0;   //Stores the count of triples associated with the Field in the enumerator.
      int MyCounter = 0;         //Start point for the loop.


      //Clear the Grid
      GridTripleDetails.Rows.Clear();

Again the green underline will probably appear.  Again don’t worry.

41. Place the cursor inside the braces as below

   if (MyFieldObjID != 0)
       {

       }
       else
       MessageBox.Show("Field " + TextBoxFieldName.Text.Trim() + " not found in this local model");

42. Insert the following code snippet

      //Get all (0 = all i.e. no Verb selection like 'ENT has FLD') triples associated
      //with the object. In this case an entity
      _Plex.EnumTriplesBySource(MyFieldObjID, 0, ref MyFieldTriples);
      //An enumerator is basically an array(list).  
      //In this case it has all the triple(s) surrogate ID in the model
      //We subsequently create a loop to read through the enumerator but before that we 
      //calculate how many to loop through.
      _Plex.GetCountOfItemsInEnumerator(MyFieldTriples, ref NumberOfTriples);
           do
           {
               //Get the next triple in the enumerator (returns its ID)
               _Plex.GetNextTriple(MyFieldTriples, ref MyTriple);
               //Get the Full Triple Name Details
               _Plex.GetTripleName(MyTriple, ref TripleNameDetails);
               //Add to the grid control.
               string[] NewGridRow = new string[] { TripleNameDetails };
               GridTripleDetails.Rows.Add(NewGridRow);
               MyCounter++;  //Increment Counter that is looping through the enumerator (array).
           }
           while (MyCounter < NumberOfTriples); //When done stop querying the enumerator i.e. Exit Loop
           //Destroy the enumerator (Free up memory)
           _Plex.EndEnum(ref MyFieldTriples);   

43. If everything has gone to plan the code snippet for the button click should now look like the following image.



44. Press the debug button again and enter a valid field like YesNo and you should get the following.







Thanks for reading.
Lee.