Simple editable maintenance form  Topic is solved

Discussions relating to plugin development, and the Jiwa API.

Simple editable maintenance form

Postby DannyC » Wed Apr 06, 2022 4:29 pm

Hi,

Based on this example viewtopic.php?f=27&t=498
I'm wanting to create a pretty basic form which will allow users to edit the GL_Segments table. This gives me an opportunity for GL reports consolidated on the first segment, and the users can write a segment description.

For some reason I am getting a "object reference not set to an instance of an object" on line 173 which is
Code: Select all
base.OnRead();


I've been meticulous in following the example but I don't have a couple of cols, no need for IsDefault, and don't need the rowhash either. Aside from that, as far as I can see it's basically a copy of the example with the collections named differently and the columns named differently too.

Wouldn't mind some assistance to get this working!
Attachments
Plugin Sample Plugin - GL Segment Maintenance.xml
(52.46 KiB) Downloaded 47 times
User avatar
DannyC
Senpai
Senpai
 
Posts: 636
Joined: Fri Mar 22, 2013 12:23 pm
Topics Solved: 30

Re: Simple editable maintenance form

Postby SBarnes » Wed Apr 06, 2022 5:04 pm

Hi Danny,

I've just tried your plugin in a demo database and added a System.Diagnostics.Debugger.Launch(); to the form constructor and then break pointed the line in question and got no exception and the form came up.

Are you doing this in a demo db or one with other plugins loading as this could be a side effect from another plugin and not the actual code in the plugin you have posted.
Regards
Stuart Barnes
SBarnes
Shihan
Shihan
 
Posts: 1619
Joined: Fri Aug 15, 2008 3:27 pm
Topics Solved: 175

Re: Simple editable maintenance form

Postby DannyC » Wed Apr 06, 2022 5:20 pm

Jiwa demo database. I only have a few other plugins enabled, nothing which would/should interfere.
So basically it's working for you?
User avatar
DannyC
Senpai
Senpai
 
Posts: 636
Joined: Fri Mar 22, 2013 12:23 pm
Topics Solved: 30

Re: Simple editable maintenance form

Postby Scott.Pearce » Wed Apr 06, 2022 5:22 pm

The error occurs when you enter data. The form comes up fine. It's because Danny is not using our factories. I'm just putting together a post with what he needs to do...
Scott Pearce
Senior Analyst/Programmer
Jiwa Financials
User avatar
Scott.Pearce
Senpai
Senpai
 
Posts: 742
Joined: Tue Feb 12, 2008 11:27 am
Location: New South Wales, Australia
Topics Solved: 221

Re: Simple editable maintenance form

Postby SBarnes » Wed Apr 06, 2022 5:50 pm

Which of course means no manager in the objects which of course gives the null reference exception.
Regards
Stuart Barnes
SBarnes
Shihan
Shihan
 
Posts: 1619
Joined: Fri Aug 15, 2008 3:27 pm
Topics Solved: 175

Re: Simple editable maintenance form

Postby Scott.Pearce » Wed Apr 06, 2022 6:03 pm

In grdLines_Change the sample is incorrectly using new to instantiate a Jiwa object:

Code: Select all
   private void grdLines_Change(object sender, FarPoint.Win.Spread.ChangeEventArgs e)
   {
      string Key = null;
      string ColID = grdLines.ActiveSheet.Columns[e.Column].Tag.ToString();

      if (ColID == "SegContents") {
         if (e.Row == grdLines.ActiveSheet.RowCount - 1) {
            GLSegment GLSegment = new GLSegment();
            GLSegment.SegContents = grdLines.get_GridText("SegContents", e.Row).ToString();
            BusinessLogic.Add(GLSegment);
         } else {
            Key = grdLines.get_GridText("GLSegmentID", e.Row).ToString();
            BusinessLogic[Key].SegContents = grdLines.get_GridText("SegContents", e.Row).ToString();
         }
      } else if (ColID == "SegContentsDesc") {
         if (e.Row == grdLines.ActiveSheet.RowCount - 1) {
            GLSegment GLSegment = new GLSegment();
            GLSegment.SegContentsDesc = grdLines.get_GridText("SegContentsDesc", e.Row).ToString();
            BusinessLogic.Add(GLSegment);
         } else {
            Key = grdLines.get_GridText("GLSegmentID", e.Row).ToString();
            BusinessLogic[Key].SegContentsDesc = grdLines.get_GridText("SegContentsDesc", e.Row).ToString();
         }
      }
   }


NO! You must always use a factory for Jiwa or Jiwa-derived objects. A factory is essentially a way of "new"-ing an object which does additional fancy stuff when setting up that object for you. In our case we give your object a JiwaApplication.Manager instance. Very important. Read here: https://docs.jiwa.com.au/display/J7UG/How+to+convert+plugins+or+code+to+be+compatible+with+7.00.177.00+or+later

Here is the corrected function:

Code: Select all
   private void grdLines_Change(object sender, FarPoint.Win.Spread.ChangeEventArgs e)
   {
      string Key = null;
      string ColID = grdLines.ActiveSheet.Columns[e.Column].Tag.ToString();

      if (ColID == "SegContents") {
         if (e.Row == grdLines.ActiveSheet.RowCount - 1) {
            GLSegment GLSegment = Manager.CollectionItemFactory.CreateCollectionItem<GLSegment>();
            GLSegment.SegContents = grdLines.get_GridText("SegContents", e.Row).ToString();
            BusinessLogic.Add(GLSegment);
         } else {
            Key = grdLines.get_GridText("GLSegmentID", e.Row).ToString();
            BusinessLogic[Key].SegContents = grdLines.get_GridText("SegContents", e.Row).ToString();
         }
      } else if (ColID == "SegContentsDesc") {
         if (e.Row == grdLines.ActiveSheet.RowCount - 1) {
            GLSegment GLSegment = Manager.CollectionItemFactory.CreateCollectionItem<GLSegment>();
            GLSegment.SegContentsDesc = grdLines.get_GridText("SegContentsDesc", e.Row).ToString();
            BusinessLogic.Add(GLSegment);
         } else {
            Key = grdLines.get_GridText("GLSegmentID", e.Row).ToString();
            BusinessLogic[Key].SegContentsDesc = grdLines.get_GridText("SegContentsDesc", e.Row).ToString();
         }
      }
   }


An additional problem is that it appears that a ListMaintenance form *must* have a RecID column, or the base class blows up. So I changed your grid setup to use the column name "RecID" instead of "GLSegmentID", and then changed that string throughout the plugin.

Then I hit a problem with the Save() function. In c# if a string is not initialized it is null, if you do not enter a value in one of the fields, the save gets upset. So I've initiated the privates to be the empty string.

Then I hit another problem with the save function. You were generating a RecID, which is not required. We do that upon add to the collection. Further, the "GLSegmentID" column in the GL_Segments table (into which we are pushing RecID) is a CHAR(20) field, not a uniqueidentifier as per the sample, so I had to change that parameter type in iSave, as well as set RecIDIsGUID to false in the constructor of the GLSegmentCollection class.
Code: Select all
   public GLSegmentCollection() : base()
   {
      base.ClientClassName = "GLSegmentCollection";
      base.RecIDIsGUID = false;
   }


Now when you save, you are left with an error because you cannot insert a null into GL_Segment.SegmentNo. Your plugin does not provide support for defining a segment number yet. So I'll leave that bit for you.

Here is the plugin with my changes:

Plugin Sample Plugin - GL Segment Maintenance.xml
(53.45 KiB) Downloaded 44 times


Great effort though and good to see you coding in c#!
Scott Pearce
Senior Analyst/Programmer
Jiwa Financials
User avatar
Scott.Pearce
Senpai
Senpai
 
Posts: 742
Joined: Tue Feb 12, 2008 11:27 am
Location: New South Wales, Australia
Topics Solved: 221

Re: Simple editable maintenance form

Postby Mike.Sheen » Wed Apr 06, 2022 6:49 pm

Scott.Pearce wrote:You must always use a factory for Jiwa or Jiwa-derived objects.


In Danny's defense, the plugin we provided as a sample was not doing this - I've now updated the topic with an updated plugin which does use the factories.
Mike Sheen
Chief Software Engineer
Jiwa Financials

If I do answer your question to your satisfaction, please mark it as the post solving the topic so others with the same issue can readily identify the solution
User avatar
Mike.Sheen
Overflow Error
Overflow Error
 
Posts: 2445
Joined: Tue Feb 12, 2008 11:12 am
Location: Perth, Republic of Western Australia
Topics Solved: 757

Re: Simple editable maintenance form

Postby DannyC » Wed Apr 06, 2022 6:50 pm

Thanks for taking the time Scott, really appreciate it.

If we need factories to instantiate objects, then the sample in viewtopic.php?f=27&t=498 will also need changing. I just grabbed that plugin and used it as the basis. (I see Mike has mentioned this).

I have the plugin successfully writing a record to the GL_Segments table but as soon as I save, I get this error. It happens when the form is refreshed as I get the same error if I exit the form & reload it.
So basically if there is data already in the GL_Segments table, the form errors when loading/refreshing.

GetOrdinal.png
GetOrdinal.png (4.51 KiB) Viewed 333 times


Plugin attached
Attachments
Plugin Sample Plugin - GL Segment Maintenance.xml
(52.55 KiB) Downloaded 47 times
User avatar
DannyC
Senpai
Senpai
 
Posts: 636
Joined: Fri Mar 22, 2013 12:23 pm
Topics Solved: 30

Re: Simple editable maintenance form

Postby SBarnes » Wed Apr 06, 2022 6:55 pm

It may also be helpful to be aware that if you actually have any Jiwa objects like say Staff out of entities if you had a Last Updated By field inside the collection item object then you should override the Setup function and create those objects there again with the factory as at that point the manager is connected to the collection item object.

If you tried to set them up in the constructor you would also run into the same error inside the collection item object i.e. the manager would be null.

This works because the last thing the factory calls on the collection item object is setup after its created it and attached the manager.
Regards
Stuart Barnes
SBarnes
Shihan
Shihan
 
Posts: 1619
Joined: Fri Aug 15, 2008 3:27 pm
Topics Solved: 175

Re: Simple editable maintenance form

Postby SBarnes » Wed Apr 06, 2022 6:59 pm

You are getting that error because you have code like

Code: Select all
db.Sanitise(SQLReader, "RecID").ToString();


where the SQL doesn't have RecID for instance


Code: Select all
SELECT GLSegmentID, SegContents, SegContentsDesc
               FROM GL_Segments WHERE SegmentNo = 1
               ORDER BY SegContents


in the read
Regards
Stuart Barnes
SBarnes
Shihan
Shihan
 
Posts: 1619
Joined: Fri Aug 15, 2008 3:27 pm
Topics Solved: 175

Next

Return to Technical and or Programming

Who is online

Users browsing this forum: No registered users and 13 guests

cron