Select and retrieve a record - C Business Function - Pls help

rosy

Member
Hi,
I am new in developing C business function. I have some knowledge in C/C++ programming. In JDE, i would like to develop a C business function and test it.
I tried some coding. The function should pass the parameter as the workorder number and retrieves its corresponding record from table F00165.
like, SELECT GDCRTU FROM F00165 WHERE GDOBNM='GT00092' AND GDTXKY='somevalue';
'somevalue' is passed as a parameter and retrieve its corresponding GDCRTU.
Here is my code,
Code:
/************************************************************************
    *  Variable declarations
    ************************************************************************/
	HUSER			hUser;
	JDEDB_RESULT	eJDBReturn;
	JDEDB_RESULT	eReturn;
	HREQUEST		hRequestF00165 = (HREQUEST) NULL;
	int  			i;
	char            *p;
	typedef struct
{
   char           gdobnm[11];          /* 0 to 10 */
   char           gdtxky[255];         /* 11 to 265 */
   char           gdcrtu[11];          /* 266 to 278 */
   
} F00165, FAR *LPF00165;

	F00165			dsF00165 = {0};
	eJDBReturn = JDB_InitBhvr (lpBhvrCom, &hUser, (char *) NULL, 
								JDEDB_COMMIT_AUTO);
   
	if (eJDBReturn != JDEDB_PASSED)
	{
	 return (ER_ERROR);
	}

	/* Open File */
	eJDBReturn = JDB_OpenTable(hUser, 
							   NID_F00165,
							   ID_F00165_I00165,
							   NULL,
							   (ushort) 0,
							   NULL,
							   &hRequestF00165);


	/* Check Open Table success */
	if (eJDBReturn == JDEDB_PASSED) 
	{
/*strncpy(dsF00165.gdobnm, lpDS->szNameObject, 
			sizeof(dsF00165.gdobnm) );
		strncpy(dsF00165.gdtxky, lpDS->GenericTextKey, 
			sizeof(dsF00165.gdtxky) );
p = dsF00165.gdtxky;
		printf(p);
		printf("JDEDB PASSED.");
if (eJDBReturn == JDEDB_FAILED)
		{
			JDB_FreeBhvr(hUser);
			JDB_CloseTable(hRequestF00165);
			printf("JDEDB FAILED.");
			return (ER_ERROR);
		}

	} /* endif */
	else

    {
		printf("JDEDB.");
	    JDB_CloseTable(hRequestF00165);
		JDB_FreeBhvr(hUser);
	    return (ER_ERROR);
    }
   /************************************************************************
    * Function Clean Up
    ************************************************************************/
	JDB_CloseTable(hRequestF00165);
	JDB_FreeBhvr(hUser);
   return (ER_SUCCESS);
}
I also created the data structure and paste it on the header file.
Code:
#ifndef DATASTRUCTURE_D55MEDI
#define DATASTRUCTURE_D55MEDI

typedef struct tagDSD55MEDI
{
  char              szNameObject[11];                    
  char              GenericTextKey[255];                 
  char              szCreatedByUser[11];                 
} DSD55MEDI, *LPDSD55MEDI;

#define IDERRszNameObject_1                       1L
#define IDERRGenericTextKey_2                     2L
#define IDERRszCreatedByUser_3                    3L

#endif
Please help me how do i need to check if it is connected with the table and print some message it is connected with the JDEDB. I am testing this code in DV7333.
My Question is:
1. how do i need to call/use the API. JDB_OpenTable,.....
2. how do i need to connect to the DB - coding.
3. how to check if it is connected with the DB or not.
4. Select a column based on the input.
5. How i can view the result.
Please help.
Thanks,
Rosy
 
Are you planning on running this in JDE? any particular reasons why you are not using a named event rule (NER) instead. The table IO is so much easier to deal with then C BF.
Jeff
 
Please include your system configuration information to help JDELISTers in identifying the problem and thereby to help you.

Looking at your requirement, given below is the code that you'll need. I've added comments before specific parts of code which will answer your questions.

Note that if you are not on Unicode, you'll need to remove the "_J" wrappers and change the JCHAR to CHAR.
i.e jdeStrcpy((JCHAR *)(lpDS->szErrorNumber_DTAI),(const JCHAR *)_J("P76E023"));
will become jdeStrcpy((CHAR *)(lpDS->szErrorNumber_DTAI),(const CHAR *) ("P76E023"));

Code:-

/************************************************************************
* Variable declarations
************************************************************************/
ID idJDBReturn = JDEDB_PASSED;
ID idJDEDBReturn = JDEDB_PASSED;
HUSER hUser = (HUSER) NULL;

/************************************************************************
* Declare structures
************************************************************************/
NID szF00165TableID = NID_F00165;
ID idF00165IndexID = ID_F00165_I00165B;
F00165 dsF00165 = {0};
KEY3_F00165 dsF00165Key = {0};
HREQUEST hRequestF00165 = (HREQUEST) NULL;
DBREF dbRef = {0};

/************************************************************************
* Declare pointers
************************************************************************/
PJSTR lpErrorCode = (PJSTR) NULL;

/************************************************************************
* Check for NULL pointers
************************************************************************/
if ((lpBhvrCom == (LPBHVRCOM) NULL) ||
(lpVoid == (LPVOID) NULL) ||
(lpDS == (LPDSD55MEDI) NULL))
{
jdeErrorSet (lpBhvrCom, lpVoid, (ID) 0, _J("4363"), (LPVOID) NULL);
return ER_ERROR;
}

/************************************************************************
* Set pointers
************************************************************************/
/* Open the Database - if error(s) detected, issue error msg. */

idJDEDBReturn = JDB_InitBhvr(lpBhvrCom,
&hUser,(JCHAR *) NULL, JDEDB_COMMIT_AUTO);
if (idJDEDBReturn != JDEDB_PASSED)
{
jdeSetGBRError (lpBhvrCom, lpVoid, (ID) 0, _J("3143"));
return ER_ERROR;
}
lpErrorCode = (PJSTR) NULL;

/************************************************************************
* Main Processing
************************************************************************/

/* Open F00165 Table */

idJDBReturn = JDB_OpenTable(hUser, szF00165TableID, idF00165IndexID, NULL, (short)0, (JCHAR*) NULL, &hRequestF00165);

if (idJDBReturn == JDEDB_FAILED)
{
jdeStrcpy((JCHAR *)(lpDS->szErrorNumber_DTAI),(const JCHAR *)_J("P76E023"));
JDB_FreeBhvr(hUser);
return ER_ERROR;
}

/* Build F00165 Key */
jdeStrncpy((JCHAR *)(dsF00165Key.gdobnm), (const JCHAR *) (lpDS->szNameObject), DIM(dsF00165Key.gdobnm)-1);
jdeStrncpy((JCHAR *)(dsF00165Key.gdtxky), (const JCHAR *)(lpDS->GenericTextKey), DIM(dsF00165Key.gdtxky)-1);

/* Fetch the record from F00165 */
idJDBReturn = JDB_FetchKeyed(hRequestF00165, idF00165IndexID, (void *) &dsF00165Key, (short) 2, (void *) &dsF00165, (int) 0);
if (idJDBReturn == JDEDB_FAILED)
{
jdeStrcpy((JCHAR *)(lpDS->szErrorNumber_DTAI),(const JCHAR *)_J("013G"));
JDB_CloseTable(hRequestF00165);
JDB_FreeBhvr(hUser);
return(ER_ERROR);
}

/* Return Field value to calling program */

jdeStrncpy (lpDS->szCreatedByUser, (const JCHAR *)(dsF00165.gdcrtu),
DIM(lpDS->szCreatedByUser);

/* Close the F00165 Table */

JDB_CloseTable(hRequestF00165);

/************************************************************************
* Function Clean Up
************************************************************************/
JDB_FreeBhvr(hUser);
return (ER_SUCCESS);
}

------------------------------------
Regards,

Shailesh
 
Hi,
Thanks for your reply.
Actually i tried running the coding.
I created the DataStructure,
/*****************************************************************************
* DS Template Type Definitions
****************************************************************************/
/*****************************************
* TYPEDEF for Data Structure
* Template Name: Data Structure for Media Object
* Template ID: D55MEDI
* Generated: Mon May 07 14:32:23 2007
*
* DO NOT EDIT THE FOLLOWING TYPEDEF
* To make modifications, use the OneWorld Data Structure
* Tool to Generate a revised version, and paste from
* the clipboard.
*
**************************************/

#ifndef DATASTRUCTURE_D55MEDI
#define DATASTRUCTURE_D55MEDI

typedef struct tagDSD55MEDI
{
char szNameObject[11];
char GenericTextKey[255];
char szCreatedByUser[11];
} DSD55MEDI, *LPDSD55MEDI;

#define IDERRszNameObject_1 1L
#define IDERRGenericTextKey_2 2L
#define IDERRszCreatedByUser_3 3L

#endif

/*****************************************************************************
AND in the .c source file, i copied the program that you sent to me. i got some errors.
KEY3_F00165 dsF00165Key = {0};
C:\B7\DV7333\source\B55MAA.c(64) : error C2065: 'KEY3_F00165' : undeclared identifier


jdeStrcpy((CHAR *)(lpDS->szErrorNumber_DTAI),(const CHAR *)("P76E023"));
C:\B7\DV7333\source\B55MAA.c(121) : error C2039: 'szErrorNumber_DTAI' : is not a member of 'tagDSD55MEDI'
C:\B7\DV7333\source\B55MAA.c(114) : error C2224: left of '.gdobnm' must have struct/union type
C:\B7\DV7333\source\B55MAA.c(114) : warning C4013: 'DIM' undefined; assuming extern returning int

Do i need to include any header files or do i need to declare any datastructures?
Please help.
Thanks,
Rosy.
 
If you are new to creating BSFNs in JDE why do you not create one using the NER method and then see what the C code generated looks like? Can you explain why you would not want to go this route?

This should be much easier as was advised by Jeff and you can learn all the pieces you need without worrying about debugging the C syntax.

Then once you have mastered the BSFN structures in general you can extend out to making the C funtions.

Also, you could start by looking at an existing function closely matching what you need and using that as a base to work from.

Let us know how the NER attempt goes.
 
As Tom & Jeff have rightly pointed out, the easiest way would have been to create a NER.

Anyways to clear the build errors,

1) I wrote the code based on my current 8.12 F00165 Header file.

In XE, there is only one table key and hence in the 'Declare Structures' section you'll need to change,

ID idF00165IndexID = ID_F00165_I00165B; to ID idF00165IndexID = ID_F00165_I00165;

and

KEY3_F00165 dsF00165Key = {0}; to KEY1_F00165 dsF00165Key = {0};

2) In the "/* Build F00165 Key */" portion of code, add the following line,

jdeGetUserLanguagePreference(dsF00165Key.gdlngp);

The table key in XE contains the F000165.GDLNGP as the third key value and hence the above code.

3) Change the number 2 in the Fetch Keyed statement,

idJDBReturn = JDB_FetchKeyed(hRequestF00165, idF00165IndexID, (void *) &dsF00165Key, (short) 2, (void *) &dsF00165, (int) 0);

to

idJDBReturn = JDB_FetchKeyed(hRequestF00165, idF00165IndexID, (void *) &dsF00165Key, (short) 3, (void *) &dsF00165, (int) 0);


4) To clear the other errors, delete the

jdeStrcpy((JCHAR *)(lpDS->szErrorNumber_DTAI),(const JCHAR *)_J("P76E023"));

and

jdeStrcpy((JCHAR *)(lpDS->szErrorNumber_DTAI),(const JCHAR *)_J("013G")); lines from the code.

Regards,

Shailesh
 
Hi,
Thanks for the reply.
I would like to thank Tom & Jeff for mentioning about the NER, the easiest way.
The problem is Actually, i dont know anything about NER.
And whether is it the easy way or not.
One of my colleague is developing program in NER.
I have knowledge in programming C/C++. But not much worked on Pointers and with JDE.
The reason why i choose C BSFN is , i need to write a C BSFN, which should
read/retrieve field(MXRTRD3000) from F5500092 based on MXDOCO(Orderno) and search for the
same (orderno)GDTXKY in F00165 based on criteria GDOBNM='GT00092' and if it matches,then write the text into GDTXVC, if it is new or append text in that field.

For ease of understanding,
passing the value as order number from "NER" and i have to get the order number in c BSFN, then do all operations,
SELECT MXRTRD3000 FROM F5500092 WHERE MXDOCO='100'
INSERT INTO F00165 SET GDTXVC=MXRTRD3000 WHERE GDOBNM='GT00092' AND GDTXKY=MXDOCO.

In F00165, GDTXKY value is stored as "CL|WO|||100|0||" format. (delimited by pipe symbol)
i need to parse or get only '100' and compare if the orderno is same as with that of MXDOCO.
If it is same, Insert the text value of MXRTRD3000 into GDTXVC.
else if it already have the value, Append the value.

(From F5500092 to F00165.)
Is it advisable to write the function in C or using NER?
How do i need to parse the Workorder number in F00165 "CL|WO|||100|0||" and get only the '100' for comparing?

Please explain
Thanks,
Rosy
 
Rosy,

All that you need can be done in a NER except for the portion where you need to insert into the TXVC field. This is a variable length string field and you'll not be able to do a direct insert using the usual 'F00165.Insert' or 'F00165.Update' ER.

I see that there are basically two things that you wish to do.
1) Retrieve the record from F00165 whose gdobnm = 'GT00092' and gdtxky = F5500092.mxdoco.

2) To this record, you wish to append or add the F5500092.mxrtrd3000 value to the TXVC value.

For Point 1) you can,

a) Read all F00165 records of GT00092 with a Select and Fetch Next clause. Then extract the

document number from the TXKY field by using the B98220D Business Function.

Parse Delimited String
VA szF00165_TXKY -> szInputObjectID
VA szDoco <- szOutputObjectSegment
4 -> mnSegmentNumber
'|' -> cDelimiter

Check if the szDoco value matches your custom table value and make your updation.

or

b) Create a TXKY search value yourself by using the Concat() function like,

VA szTXKY = concat('CL','|')
VA szTXKY = concat(VA szTXKY,'WO') and so on.

Fetch the F00165 record directly using the above variable and two other keys (obnm + lngp) and make your updation.

For Point 2), you can get the TXVC value into a variable length field in the earlier fetch. To insert the MXRTRD3000 value however, you'll need to use a C function. Look at B0500047 to understand how to do this.

Regards,

Shailesh
 
Thank you so much for the idea and information. I too looked at both(B98220D & B0500047) the BSFN and its corresponding .h (header) files.
You explained that first i need to parse the variable string value of GDTXKY (delimiter '|'). I viewed the B98220D.c and its .h file.
I have a clarification on parsing the GDTXKY value.
#ifndef DATASTRUCTURE_D98220J
#define DATASTRUCTURE_D98220J

typedef struct tagDSD98220J
{
char szInputObjectID[201];
char szOutputObjectSegment[201];
MATH_NUMERIC mnSegmentNumber;
char cDelimiter;
} DSD98220J, *LPDSD98220J;

#define IDERRszInputObjectID_1 1L
#define IDERRszOutputObjectSegment_2 2L
#define IDERRmnSegmentNumber_3 3L
#define IDERRcDelimiter_4 4L

#endif

how do i need to create the data structure for a field GDTXKY to parse- creating the parameters and typedef like below.
VA szF00165_TXKY -> szInputObjectID
VA szDoco <- szOutputObjectSegment
4 -> mnSegmentNumber
'|' -> cDelimiter

How szInputObjectID is assigned to TXKY and szOutputObjectSegment is assigned to DOCO, mnSegmentNumber and cDelimiter? - this is the combination of two tables(F00165 and F5500092)

or
Do i need to use the same C BSFN in my program?
like calling the B98220D BSFN in my program and include in my header file.?

First i could program based on the information, steps provided for select and fetch the record for F00165 based on the criteria GT00092.
Next, parse the GDTXVC.
Next, Get the text - ordernumber and check with F5500092 DOCO.
Next, if exists and equal, retrieve RTRD3000 value.

Please explain me how do i need to create a function for parsing similar to B98220D.
Thanks,
Rosy.
 
Hi,
I tried the coding based on the logic, you have given.
I attach the coding, please advise , how i can parse the TXKY and check the value is same as DOCO.
How do i give the search key 'GT00092' as the constant value to search and retrieve all records having GDOBNM as GT00092. Below is my code.
Code:
HREQUEST hRequest = NULL;
JDEDB_RESULT idJDEDBReturn;
HREQUEST		hRequestF00165 = (HREQUEST) NULL;
ID idIndex = ID_F00165_I00165;
KEY1_F00165 dsKeySentStruct = {0};
F00165 dsKeyStructAll = {0};
short nNumKeys = 1;
int nNotUsed = 0;
ParseNumericString(&dsKeySentStruct.gdobnm,"GT00092");
idJDEDBReturn = JDB_OpenTable(hUser, NID_F00165, ID_F00165_I00165, NULL,  (ushort)0, 
(char *)NULL, &hRequestF00165);
while((idJDEDBReturn = JDB_FetchKeyed(hRequest, idIndex, & dsKeySentStruct, nNumKeys, & dsKeyStructAll, nNotUsed)) == 

JDEDB_PASSED)
{
	/* Process the fetched records */
strcpy(lpDS->GenericTextKey,dsF00165.gdtxky);	
/*pass the parameter as gdtxky to a function (ParseString-B98220D BSFN)and that function will parse the gdtxky for all the 

records fetched - return true if match occurs - The value parsed in GDTXKY(F00165) is equal to MXDOCO(F5500092)*/
 /*Parse Delimited String*/
VA szF00165_TXKY -> szInputObjectID
VA szDoco <- szOutputObjectSegment
4 -> mnSegmentNumber
'|' -> cDelimiter

} /* END WHILE */

/* if true, retrieve add MXRTRD3000 FROM F5500092  and write the content to GDTXVC in F00165*/
/* Open File */
	eJDBReturn = JDB_OpenTable(hUser, 
							   NID_F00165,
							   ID_F00165_I00165,
							   NULL,
							   (ushort) 0,
							   lpDS->szTargetDataSource,
							   &hRequestF00165);


	/* Check Open Table success */
	if (eJDBReturn == JDEDB_PASSED) 
	{
		strncpy(dsF00165.gdobnm, lpDS->szOBNM, 
			sizeof(dsF00165.gdobnm) );
		strncpy(dsF00165.gdtxky, lpDS->szTXKY, 
			sizeof(dsF00165.gdtxky) );
		strncpy(dsF00165.gdtxvc, lpDS->szTXVC, 
			sizeof(dsF00165.gdtxvc) );

		
		i = strlen( dsF00165.gdtxvc ) + 1;
		IntToMathNumeric( i, &dsF00165.gdtxtl );

		
		/* remove spaces in key */
		p = dsF00165.gdtxky;
		for (i=0; i < (int) strlen(dsF00165.gdtxky); ++i)
		{
			if( dsF00165.gdtxky[i] != ' ' )
			{
				*p = dsF00165.gdtxky[i];
				++p;
			}
		}
		*p = '\0';
/* Add DS info to file */
		eJDBReturn = JDB_InsertTable(hRequestF00165,
					 NID_F00165,
					 (ID) 0, 
					 (void *) &dsF00165);

}
Thanks.
 
Just to add my 2 cents.

If you are trying to learn the JDE Base API you might want to pick a different table. In Xe (and I assume later versions) F00165 is the media objects table and there is a whole other set of C api to read/write to the media objects that should most likely be used instead of the JDE Base API. For simply learning, you might just want to use the address book table F0101.
 
Its not just learning, i have to insert or append the GDTXVC field based on the workorder number passed as a parameter. So prior to that one i just want to do some selection based on the workorder number. I have to write a C BSFN to insert a record or append the GDTXVC field.
So please give me the guidence of how i can write the c function to read the field from MXRTRD3000 and write to GDTXVC.
Thanks,
Rosy.
 
You might want to look into the following API calls (again this is relevant in Xe... things may be different on your release).

GetGenericTextEx
AddGenericTextEx
ModifyGenericTextEx
DeleteGenericTextEx
 
Thanks and i will try out with GetGenericText. Where i can get a proper documentation for using GetEnericText - like syntax. Could you please send me the documentation that i could try.
Thanks.
 
I dont have any documentation for this api (someone else here might have something). what i have done in the past in cases like this is look where JDE has used it in their BSFNs and reverse engineer how to use it. That along simply looking at the function definition in the header file you can sometimes figure out how to call it... it can sometimes be a lot of expirmenting before you learn how to use a particular JDE api function.

Attached is some sample code that uses GetGenericTextEx to retrieve a sales order header attachment (I actually called GetGenericTextNameEx... GetGenericTextEx is just a macro that actually calls GetGenericTextNameEx).
 

Attachments

  • 121008-GetText_Example_c.txt
    2.5 KB · Views: 265
Hi, I am new C Business Functions. I have Data Structure in .h
typedef struct tagDSD5501A3A
{
MATH_NUMERIC mnInput1;
MATH_NUMERIC mnInput2;
MATH_NUMERIC mnOutput;
JCHAR cOperator;
JCHAR szErrorId[11];
JCHAR szErrorMessage[81];
} DSD5501A3A, *LPDSD5501A3A;

I just want to add, subtract inputs and than later save them in mnOutput. I don't know if this code is correct or not.
if(LPDSD5501A3A->cOperator=='+')
{
LPDSD5501A3A->mnOutput=LPDSD5501A3A->mnInput1+LPDSD5501A3A->mnInput2;
}
else if(LPDSD5501A3A->cOperator=='-')
{
LPDSD5501A3A->mnOutput=LPDSD5501A3A->mnInput1-LPDSD5501A3A->mnInput2;
}
else if(LPDSD5501A3A->cOperator=='*')
{
LPDSD5501A3A->mnOutput=LPDSD5501A3A->mnInput1*LPDSD5501A3A->mnInput2;
}
else if(LPDSD5501A3A->cOperator=='/')
{
LPDSD5501A3A->mnOutput=LPDSD5501A3A->mnInput1/LPDSD5501A3A->mnInput2;
}
Will any body able to guide this will gonna work. Someone told me strcpy and Mathcpy will be used but I have no clue how. Looking forward to guidance. Thanks in advance.
 
Back
Top