Using CFront in C#

BWillisBWillis Member Posts: 9
edited 2006-01-31 in Navision Attain
My first experiment with CFront. I can read from a Navision 3.01b database using CFRONT (cfront.dll dated 8/7/2002) within C#. However, if I try to modify a record with the AssignField() function, I get a "type mismatch" error returned from mscorlib.dll. However, even doing explicit typecasting still generates the error....I can't see where I'm going wrong. Has anyone used CFront from within C# to write back to a Navision 3.01b (or 3.10) DB?

Here's a snippet of code I used behind a button on a Windows form(bombs on the AssignField() function):

int tablenum, rechandle,myfieldno;
object fData;
bool workedOK = false;
CFRONTLib._DCFRONT cf = new CFRONTLib.CFRONTClass();

cf.ConnectServer("MYSERVER","tcp");
tablenum = cf.TableNo("Event");
if (!cf.Login("me","you"))
MessageBox.Show("Bad Login");
cf.OpenCompany("MYCO");

if (!cf.OpenTable(ref tablenum,13) )
MessageBox.Show("Salesperson table could not be opened.");


rechandle = cf.AllocRec(tablenum);
cf.InitRec(tablenum,rechandle);
cf.BWT();
cf.AllowRecordNotFound();
cf.LockTable(tablenum,false);

if (cf.FindRec(tablenum,rechandle,"-") )
{ myfieldno = cf.FieldNo(tablenum,"Name");
fData = cf.GetFieldData(tablenum,rechandle,myfieldno)
fData = (object)"Anything";

try
{
cf.AssignField(tablenum,rechandle,myfieldno,ref fData);
}
catch(Exception ex)
{
MessageBox.Show("Error on AssignField is: " + ex.Message + "; Source: " + ex.Source);
}


try
{
workedOK = cf.ModifyRec(tablenum,rechandle);
}
catch(Exception ex)
{
MessageBox.Show("Error on ModifyRec is: " + ex.Message + "; Source: " + ex.Source);
}


cf.EWT();
cf.FreeRec(rechandle);
cf.CloseTable(tablenum);
cf.CloseCompany();
cf.CloseDatabase();
MessageBox.Show("Done!");
}

Comments

  • PrebenRasmussenPrebenRasmussen Member Posts: 137
    I had the exact same problem some time ago.

    The problem ís the fieldnum which is supposed to be of type LONG.

    Also when doing calcfields wich excpects an array of LONGs there is a problem.

    So far I haven't found a solution, sorry. But I would be very interested in hearing from you if you get a breakthrough.

    I have tried fooling around with
    System.Runtime.InteropServices.Marshal.GetNativeVariantForObject()
    
    but I can't make it work anyhow.

    Also the same problem exists with VB.NET.
  • BWillisBWillis Member Posts: 9
    Thanks for the reply.....I thought maybe I was overlooking the obvious. I may play around with it some more within the next couple of weeks. If I get a breakthrough, I'll be sure to notify you......please do the same.

    Thanks again!
  • PrebenRasmussenPrebenRasmussen Member Posts: 137
    Of course...
  • Alexey_PavlovAlexey_Pavlov Member Posts: 10
    I had same problems with CalcFields method of CFRONT.

    I solve this problem with "proxy" ActiveX. In this ActiveX i have replaced all possibe 'Variant' usages.

    CalcFields(Long,Long,Variant) was replaced with
    CalcFlowFieldValue(hTable as Long,hRec as Long,FieldName As String).

    All (almost) other methods was reimplemented or changed to normal data types (GetTextFieldValue, GetDecimalFieldValue , etc).

    It helps me because old 'Variant' type is not fully incompatible with new 'object'.

    My component written in VB6 and perfectly works in .NET Studio as reference (as pseudo-replacement of original CFRONT.OCX).

    I can email it to you.
    Real programmers don't comment their code.
    If it was hard to write, it should be hard to understand.
  • hansdegraafhansdegraaf Member Posts: 9
    Hello,

    string fieldvalue = cf.GetFieldDataByName(hTable,hRecord,columnname).ToString();

    I'm getting the error {"Object reference not set to an instance of an object." }.


    Regards,

    Hans de Graaf
  • PoweRoyPoweRoy Member Posts: 43
    *big kick*

    I am trying get cfront working in c# .net only "i get a Object reference not set to an instance of an object" error

    the dll imports (isnt there an easier way?)
    [DllImport("cfront.dll", CallingConvention = CallingConvention.Cdecl)] 
    		private static extern int DBL_FindRec(ref int hTablePtr, int record, string Method);
    
    		[DllImport("cfront.dll", CallingConvention = CallingConvention.Cdecl)] 
    		private static extern int DBL_AllocRec(int hTable);
    
    		[DllImport("cfront.dll", CallingConvention = CallingConvention.Cdecl)] 
    		private static extern int DBL_NextRec(int hTable, ref int record, int step);
    
    		[DllImport("cfront.dll", CallingConvention = CallingConvention.Cdecl)] 
    		private static extern int DBL_RecCount(int hTable);
    
    		[DllImport("cfront.dll", CallingConvention = CallingConvention.Cdecl)] 
    		private static extern void DBL_InitRec(int hTable, int record);
    
    		[DllImport("cfront.dll", CallingConvention = CallingConvention.Cdecl)] 
    		private static extern void DBL_FreeRec(int hTable);
    
    		[DllImport("cfront.dll", CallingConvention = CallingConvention.Cdecl)] 
    		private static extern string DBL_GetFieldData(int hTable, int record, int fieldnr);
    

    the parser
    public ArrayList ExecuteCommand(string _command)
    			// command parsing		{
    			ArrayList result = new ArrayList();
    			string command = "";
    			string query = "";
    			
    			command = _command.Substring(0,2); 
    			if (_command.Length > 3)
    			{
    				query = _command.Substring(3,_command.Length-3);
    			}
    			switch (command)
    			{
    				case "lc" :	//list company
    					string compname = DBL_NextCompany(null);
    					while (compname != null) 
    					{
    						result.Add(compname);
    						compname = DBL_NextCompany(compname);
    					}
    					break;
    
    				if (query != "")
    					{
    						DBL_OpenCompany(query);
    						result.Add(query +" opened");
    						
    					}
    					else result.Add("geen company opgegeven");
    					break;
    				
    				case "cc" : //close company
    					DBL_CloseCompany();
    					break;
    
    				case "lt" : //list tables
    					int tablenr = DBL_NextTable(0);
    					while (tablenr != 0)
    					{
    						DBL_OpenTable(ref htable, tablenr);
    						string name = DBL_TableName(htable);
    						result.Add(tablenr + " : " + name);
    						DBL_CloseTable(htable);
    						tablenr = DBL_NextTable(tablenr);
    					}
    					break;
    
    				case "ot" : //open table
    					if (query != "")
    					{
    						if (DBL_OpenTable(ref htable, Convert.ToInt32(query)) != 1)
    						{
    							Console.WriteLine("open table " + query + "failed");
    						}
    						else result.Add(query +" opened. " + Convert.ToString(DBL_RecCount(htable)) + " records found");
    					}
    					else result.Add("geen table opgegeven");
    					break;
    
    				case "ct" : //close table
    					DBL_CloseTable(Convert.ToInt32(query));
    					break;
    			
    				case "lr" : //list records
    					int record = DBL_AllocRec(htable);
    					DBL_InitRec(htable, record);
    
    					if ( DBL_FindRec( ref htable, record ,"-") == 1 )  //here it crashes
    					{						result.Add(DBL_GetFieldData(htable, record,2)); 
    						while( DBL_NextRec(htable, record, 1) != 0 )
    						{
    							result.Add(DBL_GetFieldData(htable,record,1)); 
    						}
    					}
    					else result.Add("Geen records gevonden");
    					DBL_FreeRec(record);
    					break;
    			}	
    			
    			return result;
    		}
    

    Anyone know what the prob is?
  • atarisataris Member Posts: 109
    I want to get to grips with c/front. Whats a good way to get into learning it as i need to understand it for my exam
Sign In or Register to comment.