Thread: Effective From and Thru Date Change In a Work File.

  1. #1
    Registered User
    Join Date
    Sep 2018
    Posts
    26

    Question Effective From and Thru Date Change In a Work File.

    Hi All,

    Figure A is how the work file currently looks; I would like to update it to resemble figure B:

    Figure A:
    Line# 1 Item# Branch Uom Effective From Effective Thru
    1 123 50 EA 2/15/2023 12/31/2049
    2 123 50 EA 4/23/2023 12/31/2049
    3 123 50 EA 8/7/2023 12/31/2049
    Figure B:
    Line# 1 Item# Branch Uom Effective From Effective Thru
    1 123 50 EA 2/15/2023 4/22/2023
    2 123 50 EA 4/23/2023 8/6/2023
    3 123 50 EA 8/7/2023 12/31/2049


    As always...
    Thank you,
    FrankCLT

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,667
    So did you learn anything from your previous thread?
    Read Table Record and Write to Array

    What exactly are you stuck on?
    - reading the file
    - how to copy "effective from" from the n+1 line to the "effective thru" on line n.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Sep 2018
    Posts
    26
    I did, I will post my code for the above exercise. Just need to see if I'm on the right track.

    Thank you,
    FrankCLT

  4. #4
    Registered User
    Join Date
    Sep 2018
    Posts
    26
    This is probably gibberish since its C with a JD Edwards twist to some of the commands.

    This code works, but just not sure how someone with actual C programming would read from the table that looks like Figure A and end up Figure B. Would you even use an array? Is there a more efficient way to achieve this? Just

    This code reads a table F564015 fills an array that looks like figure A above.

    Then I read the array backwards and process the data to where the data begins to look like Figure B (record at a time).




    Code:
    /* Other Processing Takes Place Here That Does Not Affect Below Code */
    
    /* I read data from the table and write to below Array this section is in a loop. - Ascending Order*/
    /* &aF564015MCU1[MCU1] = The array and &dsF564015. = Read table */
    MathCopy(&aF564015MCU1[MCU1].mnAddressNumber, &dsF564015.otan8);
    MathCopy(&aF564015MCU1[MCU1].mnIdentifierShortItem, &dsF564015.otitm);
    jdeStrncpy(aF564015MCU1[MCU1].szOrderTemplate, dsF564015.otortp, DIM(aF564015MCU1[MCU1].szOrderTemplate));
    jdeStrncpy(aF564015MCU1[MCU1].szCostCenter, dsF564015.otmcu, DIM(aF564015MCU1[MCU1].szCostCenter));
    JDEDATECopy(&aF564015MCU1[MCU1].jdDateEffectiveJulian1, &dsF564015.oteftj);
    JDEDATECopy(&aF564015MCU1[MCU1].jdDateExpiredJulian1, &dsF564015.otexdj);
    JDEDATECopy(&aF564015MCU1[MCU1].jdDateEntered1, &dsF564015.otentj);
    MathCopy(&aF564015MCU1[MCU1].mnTimeEntered, &dsF564015.otentt);
    MCU1++;
    
    
    /* Other Processing Takes Place Here That Does Not Effect Below Code */	
    
    						
    
    							
    while (MCU1 > 0)
    { 
    	/* Validate current and prior Array records are the same before update happens (Key Fields) */
    	if ((jdestrcmpwithnull(aF564015MCU1[MCU1].szOrderTemplate, aF564015MCU1[MCU1-1].szOrderTemplate) == 0)
    		&& (MathCompare(&aF564015MCU1[MCU1].mnAddressNumber, &aF564015MCU1[MCU1-1].mnAddressNumber) == 0)
    		&& (MathCopy(&aF564015MCU1[MCU1].mnIdentifierShortItem, &aF564015MCU1[MCU1-1].mnIdentifierShortItem) == 0)
    		&& (jdestrcmpwithnull(aF564015MCU1[MCU1].szCostCenter, aF564015MCU1[MCU1-1].szCostCenter) == 0))
    		{
    			/* Take current Effective Date EFTJ and minus 1. This will become the new expired date for the prior record. */
    			RTK_CER_AddDays( &NewDateExpiredEXDJ ,
    			&aF564015MCU1[MCU1].jdDateEffectiveJulian1 , -1 );
    			
    			/* Make sure the dates are NOT equal */		
    			if (SingleValueComp((LPVOID)&aF564015MCU1[MCU1-1].jdDateExpiredJulian1,
    			(LPVOID)&NewDateExpiredEXDJ,EVDT_JDEDATE)!=0)
    			{
    				/* Setup Key For UPDATE*/
    				jdeStrcpy((JCHAR *)(dsF564015Key1U.otortp), (const JCHAR *)(aF564015MCU1[MCU1-1].szOrderTemplate));
    				MathCopy(&dsF564015Key1U.otan8, &aF564015MCU1[MCU1-1].mnAddressNumber);
    				MathCopy(&dsF564015Key1U.otitm, &aF564015MCU1[MCU1-1].mnIdentifierShortItem);
    				jdeStrcpy((JCHAR *)(dsF564015Key1U.otmcu), (const JCHAR *)(aF564015MCU1[MCU1-1].szCostCenter));
    				JDEDATECopy (&dsF564015Key1U.otentj, &aF564015MCU1[MCU1-1].jdDateEntered1);
    				MathCopy(&dsF564015Key1U.otentt, &aF564015MCU1[MCU1-1].mnTimeEntered);
    				
    				JDEDBReturn = JDB_FetchKeyed(hReqF564015, (ID) 0, (void *)(&dsF564015Key1U),
    				(unsigned short)(6), (void *)(&dsF564015), FALSE);
    				if (JDEDBReturn == JDEDB_PASSED)
    				{
    					/* Gather and assign Audit Field data to be Updated into F564015 */
    					jdeCallObject( _J("GetAuditInfo"), NULL, lpBhvrCom, lpVoid, &dsGetAuditInfo, (CALLMAP*) NULL, (int) 0, (JCHAR*) NULL, 
    					(JCHAR*) NULL, (int) 0 );
    					jdeStrcpy((JCHAR *)(dsF564015.otuser), (const JCHAR *)(dsGetAuditInfo.szUserName));
    					memcpy((void *)(&dsF564015.otupmj), (const void *)(&dsGetAuditInfo.jdDate), sizeof(JDEDATE));
    					MathCopy(&dsF564015.otupmt, &dsGetAuditInfo.mnTime);
    					jdeStrcpy((JCHAR *)(dsF564015.otpid), (const JCHAR *)(_J("B564015X")));
    					jdeStrcpy((JCHAR *)(dsF564015.otjobn), (const JCHAR *)(dsGetAuditInfo.szWorkstation_UserId));
    					
    					/* New Effective Thru Date into F564015 */
    					JDEDATECopy (&dsF564015.otexdj, &NewDateExpiredEXDJ);
    							
    					/* Update F564015 with audit fields and new expiration date(s) */
    					JDEDBReturn = JDB_UpdateTable(hReqF564015, szTableIDF564015, (ID) 0,
    					(ID)(idIndexF564015), (void *)(&dsF564015Key1U),(6),
    					(void *)(&dsF564015));								
    					if (JDEDBReturn == JDEDB_PASSED)
    						{
    							lpDS->cErrorCode = _J('0');
    							jdeStrcpy((JCHAR *)(lpDS->szDescript01), (const JCHAR *)(_J("End1")));
    						}			
    				}
    			}
    		}
    		MCU1--;
    	}
    }

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,667
    Well that's pretty unreadable.

    I'm not sure it works, you have a MathCopy call where you should have a MathCompare call.
    It would seem odd that MathCopy actually compiles in a boolean context.

    Also, use some functions to separate grunt work from the logic.
    Code:
    /* Other Processing Takes Place Here That Does Not Effect Below Code */  
    
    bool compareRecord(T aF564015MCU1[], int MCU1) {
      return (jdestrcmpwithnull(aF564015MCU1[MCU1].szOrderTemplate, aF564015MCU1[MCU1-1].szOrderTemplate) == 0)
          && (MathCompare(&aF564015MCU1[MCU1].mnAddressNumber, &aF564015MCU1[MCU1-1].mnAddressNumber) == 0)
          && (MathCompare(&aF564015MCU1[MCU1].mnIdentifierShortItem, &aF564015MCU1[MCU1-1].mnIdentifierShortItem) == 0) //!! was MathCopy !!//
          && (jdestrcmpwithnull(aF564015MCU1[MCU1].szCostCenter, aF564015MCU1[MCU1-1].szCostCenter) == 0)
    }
    
    void updateRecord(T *dsF564015Key1U, T *aF564015MCU1) {
      jdeStrcpy  ((JCHAR *)(dsF564015Key1U->otortp), (const JCHAR *)(aF564015MCU1->szOrderTemplate));
      MathCopy   (&dsF564015Key1U->otan8, &aF564015MCU1->mnAddressNumber);
      MathCopy   (&dsF564015Key1U->otitm, &aF564015MCU1->mnIdentifierShortItem);
      jdeStrcpy  ((JCHAR *)(dsF564015Key1U->otmcu), (const JCHAR *)(aF564015MCU1->szCostCenter));
      JDEDATECopy(&dsF564015Key1U->otentj, &aF564015MCU1->jdDateEntered1);
      MathCopy   (&dsF564015Key1U->otentt, &aF564015MCU1->mnTimeEntered);
    }
    
    void updateAudit(T *dsF564015, T *dsGetAuditInfo) {
      jdeStrcpy ((JCHAR *)(dsF564015->otuser), (const JCHAR *)(dsGetAuditInfo->szUserName));
      memcpy    ((void *)(&dsF564015->otupmj), (const void *)(&dsGetAuditInfo->jdDate), sizeof(JDEDATE));
      MathCopy  (&dsF564015->otupmt, &dsGetAuditInfo->mnTime);
      jdeStrcpy ((JCHAR *)(dsF564015->otpid), (const JCHAR *)(_J("B564015X")));
      jdeStrcpy ((JCHAR *)(dsF564015->otjobn), (const JCHAR *)(dsGetAuditInfo->szWorkstation_UserId));
    }
                  
    while (MCU1 > 0)
    { 
      /* Validate current and prior Array records are the same before update happens (Key Fields) */
      if (compareRecord(aF564015MCU1,MCU1))
      {
          /* Take current Effective Date EFTJ and minus 1. This will become the new expired date for the prior record. */
          RTK_CER_AddDays(&NewDateExpiredEXDJ, &aF564015MCU1[MCU1].jdDateEffectiveJulian1, -1);
          
          /* Make sure the dates are NOT equal */    
          if (SingleValueComp((LPVOID)&aF564015MCU1[MCU1-1].jdDateExpiredJulian1,
                              (LPVOID)&NewDateExpiredEXDJ,EVDT_JDEDATE)!=0)
          {
            /* Setup Key For UPDATE*/
            updateRecord(&dsF564015Key1U, &aF564015MCU1[MCU1-1]);
            
            JDEDBReturn = JDB_FetchKeyed(hReqF564015, (ID) 0, (void *)(&dsF564015Key1U),
                                         (unsigned short)(6), (void *)(&dsF564015), FALSE);
            if (JDEDBReturn == JDEDB_PASSED)
            {
              /* Gather and assign Audit Field data to be Updated into F564015 */
              jdeCallObject( _J("GetAuditInfo"), NULL, lpBhvrCom, lpVoid, &dsGetAuditInfo, (CALLMAP*) NULL, (int) 0, (JCHAR*) NULL, (JCHAR*) NULL, (int) 0 );
    
              updateAudit(&dsF564015, &dsGetAuditInfo);
              
              /* New Effective Thru Date into F564015 */
              JDEDATECopy (&dsF564015.otexdj, &NewDateExpiredEXDJ);
                  
              /* Update F564015 with audit fields and new expiration date(s) */
              JDEDBReturn = JDB_UpdateTable(hReqF564015, szTableIDF564015, (ID) 0,
                                            (ID)(idIndexF564015), (void *)(&dsF564015Key1U), (6),
                                            (void *)(&dsF564015));                
              if (JDEDBReturn == JDEDB_PASSED)
              {
                lpDS->cErrorCode = _J('0');
                jdeStrcpy((JCHAR *)(lpDS->szDescript01), (const JCHAR *)(_J("End1")));
              }      
            }
          }
        }
        MCU1--;
      }
    }
    Also a tip for posting code on forums (or anywhere).
    Use spaces rather than hard tabs for indentation. It stops the code zooming off to the right for one thing.

    > Would you even use an array? Is there a more efficient way to achieve this?
    I've no idea.

    On the face of it, it seems like you only ever need two records in memory at once.
    If you've only got 1000's of records, it's probably not a big deal.
    If you've got millions of records, the temporary memory requirement is looking to be a problem.

    Efficiency is another problem entirely.
    Examples.
    It runs once a day, and takes 10 seconds to run.
    Are you going to bust a gut trying to get it down to 1 second?

    It runs once a day, and takes an hour to run. But you run it overnight anyway.
    Are you going to bust a gut trying to get it down to minutes so you have time to grab a coffee while it finishes?

    The short answer is write something clear and maintainable that does the job.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    Sep 2018
    Posts
    26
    This does work, and its actually quite fast. I've got this code being called after the user clicks "OK" on an iterative screen, so when the user does go back into the application and review the criteria again, the data has been adjusted correctly.

    I did leave out a good bit of code that doesn't relate to the snippet with the array.

    As for the MathCopy and MathCompare, thank you, the reason why this works is that those records should be the same 99.99% of the time. Just added for peace of mind.

    Again, not being a C developer by trade, just a simple ERP JD Edwards Developer, I was curious how a C developer would accomplish something like this?

    When the user clicks OK, the below function executes which is the code from the above examples.

    Code:
    FixExpirationDate(B564015X.FIXEXPIRATIONDATE)
    |    FC OrderTemplateFC [ORTP] -> szOrderTemplate [ORTP]
    |    VA frm_PassAddressNbr_AN8 [AN8] -> mnAddressNumber [AN8]
    |    VA frm_PassShortItem_ITM [ITM] -> mnIdentifierShortItem [ITM]
    |    SL DateToday -> jdDateExpiredJulian1 [EXDJ]

    Thanks again,
    FrankCLT

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Change the way firmware updater program work
    By slimon in forum Tech Board
    Replies: 3
    Last Post: 10-07-2016, 01:39 PM
  2. Change the way firmware updater program work
    By slimon in forum C++ Programming
    Replies: 0
    Last Post: 10-06-2016, 03:06 PM
  3. Change file date created or modified (linux/unix/osx)
    By therealmuffin in forum C Programming
    Replies: 1
    Last Post: 03-30-2012, 03:40 AM
  4. Change the Date for all objects of a class
    By ShadowDragon in forum C++ Programming
    Replies: 4
    Last Post: 12-07-2011, 05:28 PM
  5. Replies: 1
    Last Post: 08-22-2005, 09:21 PM

Tags for this Thread