cancel
Showing results for 
Search instead for 
Did you mean: 

UI SDK with C# - problems implementing the ToolBarCtrl example

Former Member
0 Kudos

I've been implementing the UI SDK samples in C#. They have all worked fine except for the ToolBarCtrl sample. When the SBO_Application.MenuEvent fires, I get the following exception: "query interface for SAPbobsCOM.IRecordset failed" whenever the oRecordSet MoveNext, MoveFirst, MoveLast, MovePrevious methods are called. Further experiments with this code raise an exception whenever an object/interface in SAPbobsCOM are called from Application.MenuEvent.

Is anyone else experiencing the same problem in C# or know of a solution around this?

Accepted Solutions (0)

Answers (1)

Answers (1)

Former Member
0 Kudos

I think you are also using DI-API Record set, we faced a problem, when we used DI-API Record set object in VB, it is conflicting with ADODB.Recordset. If my thinking is correct, confirm me, I ll try to give the solution.

Former Member
0 Kudos

Yes, you're correct, I am using the DI API IRecordset. However I can succesfully using the IRecordset interface in other parts of the same program, just not in the Application MenuEvent method

Former Member
0 Kudos

I've written something similar in C# which uses the first/previous/next/last menu buttons with a recordset, although the code that uses the recordset is wrapped in methods to handle the "if EoF then move to first record", etc.

If you want I can post the code on here, or let me know your email address and I'll mail the c# project to you.

Former Member
0 Kudos

Hi Simon, if you could post the code here to this forum, that would be great!!

Former Member
0 Kudos

OK, here goes - the following code wants to go into a class called Class1:

<i>using System;

namespace WindowsApplication3

{

/// <summary>

/// Summary description for Class1.

/// </summary>

public class Class1

{

private SAPbouiCOM.Application SBO_Application;

private SAPbobsCOM.Company SBO_Company;

private string msFormUID = "MySimpleForm";

private SAPbobsCOM.Recordset mors = null;

public Class1(SAPbouiCOM.Application oApp , SAPbobsCOM.Company oCmp )

{

SBO_Application = oApp;

SBO_Company = oCmp;

this.SBO_Application.MenuEvent += new SAPbouiCOM._IApplicationEvents_MenuEventEventHandler(this.SBO_Application_MenuEvent);

// load the data

mors = (SAPbobsCOM.Recordset)SBO_Company.GetBusinessObject(SAPbobsCOM.BoObjectTypes.BoRecordset);

if (mors != null)

{

mors.DoQuery("SELECT CardCode, CardName FROM OCRD ORDER BY CardCode");

}

}

public void Close()

{

SBO_Application = null;

SBO_Company = null;

}

public void CreateMySimpleForm()

{

SAPbouiCOM.Form oForm;

SAPbouiCOM.Item oItem;

//'// *******************************************

//'// we will use the following objects to set

//'// the specific values of every item

//'// we add.

//'// this is the best way to do so

//'//*********************************************

SAPbouiCOM.Button oButton ;

SAPbouiCOM.EditText oEdit;

//'// add a new form

oForm = SBO_Application.Forms.Add(msFormUID, SAPbouiCOM.BoFormTypes.ft_Fixed, 1);

//'// add a User Data Source to the form

oForm.DataSources.UserDataSources.Add("EditSource", SAPbouiCOM.BoDataType.dt_SHORT_TEXT, 20);

oForm.DataSources.UserDataSources.Add("CombSource", SAPbouiCOM.BoDataType.dt_SHORT_TEXT, 20);

//'// set the form properties

oForm.Title = "Simple Form";

oForm.Left = 400;

oForm.Width = 350;

oForm.Top = 100;

oForm.Height = 100;

//'//*****************************************

//'// Adding Items to the form

//'// and setting their properties

//'//*****************************************

oItem = oForm.Items.Add("txtCode", SAPbouiCOM.BoFormItemTypes.it_EDIT);

oItem.Left = 6;

oItem.Width = 65;

oItem.Top = 20;

oItem.Height = 14;

oForm.DataSources.UserDataSources.Add("txtCode", SAPbouiCOM.BoDataType.dt_SHORT_TEXT, 100);

oEdit = (SAPbouiCOM.EditText)oItem.Specific;

oEdit.DataBind.SetBound(true, "", "txtCode");

oItem = oForm.Items.Add("txtName", SAPbouiCOM.BoFormItemTypes.it_EDIT);

oItem.Left = 75;

oItem.Width = 65;

oItem.Top = 20;

oItem.Height = 14;

oForm.DataSources.UserDataSources.Add("txtName", SAPbouiCOM.BoDataType.dt_SHORT_TEXT, 100);

oEdit = (SAPbouiCOM.EditText)oItem.Specific;

oEdit.DataBind.SetBound(true, "", "txtName");

//'/**********************

//'// Adding an Ok button

//'//*********************

//'// We get automatic event handling for

//'// the Ok and Cancel Buttons by setting

//'// their UIDs to 1 and 2 respectively

oItem = oForm.Items.Add("1", SAPbouiCOM.BoFormItemTypes.it_BUTTON);

oItem.Left = 6;

oItem.Width = 65;

oItem.Top = 51;

oItem.Height = 19;

oButton = (SAPbouiCOM.Button)oItem.Specific;

oButton.Caption = "Ok";

//'//************************

//'// Adding a Cancel button

//'//***********************

oItem = oForm.Items.Add("2", SAPbouiCOM.BoFormItemTypes.it_BUTTON);

oItem.Left = 75;

oItem.Width = 65;

oItem.Top = 51;

oItem.Height = 19;

oButton = (SAPbouiCOM.Button)oItem.Specific;

oButton.Caption = "Cancel";

//'//*************************

//'// enable buttons

//'//*************************

oForm.EnableMenu("1288", true);

oForm.EnableMenu("1289", true);

oForm.EnableMenu("1290", true);

oForm.EnableMenu("1291", true);

//'//*************************

//'// set the form as visible

//'//*************************

oForm.Visible = true;

}

private void SBO_Application_MenuEvent(ref SAPbouiCOM.MenuEvent pVal, out bool BubbleEvent)

{

BubbleEvent = true;

// Get the menu events, so that we can see if the next record / previous record has been pressed

if (!pVal.BeforeAction)

{

switch (pVal.MenuUID)

{

case "1290":

{

// first record

if (this.NavigateToFirstRecord())

{

LoadDetails();

}

break;

}

case "1289":

{

// prev record

if (this.NavigateToPreviousRecord())

{

LoadDetails();

}

break;

}

case "1288":

{

// next record

if (this.NavigateToNextRecord())

{

LoadDetails();

}

break;

}

case "1291":

{

// last record

if (this.NavigateToLastRecord())

{

LoadDetails();

}

break;

}

}

}

}

#region Record Navigation

/// <summary>

/// Move to the first record

/// </summary>

/// <returns>true if found</returns>

private bool NavigateToFirstRecord()

{

bool bRecordFound = false;

// search for a record

if (mors != null)

{

mors.MoveFirst();

bRecordFound = (!mors.EoF);

}

// return

return bRecordFound;

}

/// <summary>

/// Move to the last record

/// </summary>

/// <returns>true if found</returns>

private bool NavigateToLastRecord()

{

bool bRecordFound = false;

// search for a record

if (mors != null)

{

mors.MoveLast();

bRecordFound = (!mors.EoF);

}

// return

return bRecordFound;

}

/// <summary>

/// Move to the previous record

/// </summary>

/// <returns>true if found</returns>

private bool NavigateToPreviousRecord()

{

bool bRecordFound = false;

// search for a record

if (mors != null)

{

if (mors.BoF)

{

// we are at the begining of the file - move to the last record

mors.MoveLast();

}

else

{

mors.MovePrevious();

}

bRecordFound = (!mors.EoF);

}

// return

return bRecordFound;

}

/// <summary>

/// Move to the next record

/// </summary>

/// <returns>true if found</returns>

private bool NavigateToNextRecord()

{

bool bRecordFound = false;

// search for a record

if (mors != null)

{

if (mors.EoF)

{

// we are at the end of the file - move to the first record

mors.MoveFirst();

}

else

{

mors.MoveNext();

// Check to see if we have moved past the end of the file

if (mors.EoF)

{

// yes we have, go back to the beginning

mors.MoveFirst();

}

}

bRecordFound = (!mors.EoF);

}

// return

return bRecordFound;

}

#endregion

private void LoadDetails()

{

SAPbouiCOM.Form frm = SBO_Application.Forms.Item(msFormUID);

frm.Freeze(true);

if (!mors.EoF)

{

frm.DataSources.UserDataSources.Item("txtCode").Value = mors.Fields.Item("CardCode").Value.ToString();

frm.DataSources.UserDataSources.Item("txtName").Value = mors.Fields.Item("CardName").Value.ToString();

}

frm.Freeze(false);

frm.Update();

}

}

}

</i>

and this code goes into Form1:

<i>using System;

using System.Drawing;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

using System.Data;

namespace WindowsApplication3

{

/// <summary>

/// Summary description for Form1.

/// </summary>

public class Form1 : System.Windows.Forms.Form

{

/// <summary>

/// Required designer variable.

/// </summary>

private System.ComponentModel.Container components = null;

private Class1 myForm = null;

public Form1()

{

//

// Required for Windows Form Designer support

//

InitializeComponent();

//

// TODO: Add any constructor code after InitializeComponent call

//

Class_Initialize_Renamed();

}

/// <summary>

/// Clean up any resources being used.

/// </summary>

protected override void Dispose( bool disposing )

{

if( disposing )

{

if (components != null)

{

components.Dispose();

}

}

base.Dispose( disposing );

}

#region Windows Form Designer generated code

/// <summary>

/// Required method for Designer support - do not modify

/// the contents of this method with the code editor.

/// </summary>

private void InitializeComponent()

{

this.button1 = new System.Windows.Forms.Button();

this.SuspendLayout();

//

// button1

//

this.button1.Location = new System.Drawing.Point(80, 80);

this.button1.Name = "button1";

this.button1.TabIndex = 0;

this.button1.Text = "button1";

this.button1.Click += new System.EventHandler(this.button1_Click);

//

// Form1

//

this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);

this.ClientSize = new System.Drawing.Size(292, 266);

this.Controls.AddRange(new System.Windows.Forms.Control[] {

this.button1});

this.Name = "Form1";

this.Text = "Form1";

this.ResumeLayout(false);

}

#endregion

/// <summary>

/// The main entry point for the application.

/// </summary>

[STAThread]

static void Main()

{

Application.Run(new Form1());

}

//**********************************************************

// This parameter will use us to manipulate the

// SAP Business One Application a

// and the Company on which we are working

//**********************************************************

private SAPbouiCOM.Application SBO_Application;

private SAPbobsCOM.Company oCompany;

private System.Windows.Forms.Button button1;

// private Class1 myForm;

private void SetApplication()

{

//'*******************************************************************

//'// Use an SboGuiApi object to establish connection

//'// with the SAP Business One application and return an

//'// initialized appliction object

//'*******************************************************************

SAPbouiCOM.SboGuiApi SboGuiApi;

string sConnectionString;

SboGuiApi = new SAPbouiCOM.SboGuiApi();

//'// by following the steps specified above, the following

//'// statment should be suficient for either development or run mode

sConnectionString = "0030002C0030002C00530041005000420044005F00440061007400650076002C0050004C006F006D0056004900490056";

//'// connect to a running SBO Application

SboGuiApi.Connect(sConnectionString);

//'// get an initialized application object

SBO_Application = SboGuiApi.GetApplication(0);

}

private int SetConnectionContext()

{

string sCookie;

string sConnectionContext;

//'// First initialize the Company object

oCompany = new SAPbobsCOM.Company();

//'// Acquire the connection context cookie from the DI API.

sCookie = oCompany.GetContextCookie();

//'// Retrieve the connection context string from the UI API using the

//'// acquired cookie.

sConnectionContext = SBO_Application.Company.GetConnectionContext(sCookie);

//'// Set the connection context information to the DI API.

return oCompany.SetSboLoginContext(sConnectionContext);

}

private int ConnectToCompany()

{

//'// Establish the connection to the company database.

return oCompany.Connect();

}

//'UPGRADE_NOTE: Class_Initialize was upgraded to Class_Initialize_Renamed. Click for more: 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="vbup1061"'

private void Class_Initialize_Renamed()

{

//'//*************************************************************

//'// set SBO_Application with an initialized application object

//'//*************************************************************

SetApplication();

//'//*************************************************************

//'// Set The Connection Context

//'//*************************************************************

if (!( SetConnectionContext() == 0))

{

SBO_Application.MessageBox("Failed setting a connection to DI API", 1, "OK", "", "");

}

//'//*************************************************************

//'// Connect To The Company Data Base

//'//*************************************************************

if (!(ConnectToCompany() == 0))

{

SBO_Application.MessageBox("Failed connecting to the company's Data Base", 1, "OK", "", "");

}//' Terminating the Add-On Application

//'//*************************************************************

//'// send an "hello world" message

//'//*************************************************************

SBO_Application.MessageBox("DI Connected To: " + oCompany.CompanyName + "\r\nHello World!", 1, "OK", "", "");

}

private void button1_Click(object sender, System.EventArgs e)

{

myForm = new Class1(SBO_Application, oCompany);

myForm.CreateMySimpleForm();

}

}

}

</i>

You'll need a button called button1 on form1.

Former Member
0 Kudos

Thanks very much for the code Simon!