Summary
Description
Contents
NOTE: Only members of the UK Sage Developer Programme have access to the developer tools for Sage 50 Accounts.
Sage Data Objects
Sage Data Objects (SDO) is a collection of ActiveX dynamic link libraries (.DLLs), the SDK delivers an object-based interface with methods and properties designed to simplify communications between compliant development tools and the Sage 50 Accounts database.
Objects are available to provide access to data throughout Sage 50 Accounts.
As a result, it is possible to read, create, edit and delete records such as:
- Customers and Supplier Records
- Bank and Nominal Accounts
- Sales and Purchase Invoices, Credits, Sales and Purchase Orders, Quotes and Proformas
- Stock Records, Stock Transactions, Goods Delivery Notes and Goods Received Notes
- Audit Trail Transactions such as Sales and Purchase Invoices and Credits, Bank Transactions, Journals, receipts and Payments
The SDO is supported for use in C# .NET and Visual Basic .NET.
Although unsupported, it is compatible with VB6, PHP, Delphi, Java and many other languages as the technology is COM based.
NOTE: Members of the Developer Programme are provided with help files that provide an extensive collection of examples and document every available object including fields and methods.
Create Customer Records
Using Sage 50 Accounts
Open the Customers module and select New.
Customer information is held across several tabs. Some details are inherited from your Customer Defaults settings. Any defaults that were defined in the settings are applied automatically to each account. You can keep or change them as you create each account. Each customer has their own account record with a unique account reference number. After adding the new customer’s details clicking save will create the customer record.
Using the SDO
A new customer can be added using the AddNew() method on the SalesRecord object. This returns a new Customer object. There are mandatory fields that need to be specified for a customer record to be successfully created via the SDO. The list of mandatories is documented on the SalesRecord object within the developer help files.
The following examples demonstrate how to create a new customer using the AddNew() method, setting the relevant fields and finally calling the update method to create the customer record.
C# Example:
//Leaving the username and password blank generates a login dialog
oWS.Connect(szDataPath, "", "", "Example");
//Instantiate Sales Record Object
oSalesRecord = (SageDataObject260.SalesRecord)oWS.CreateObject("SalesRecord");
//Try to add a new record
if (oSalesRecord.AddNew())
{
//Populate Record Fields
SDOHelper.Write(oSalesRecord, "ACCOUNT_REF", (String)"SAGEGRP");
SDOHelper.Write(oSalesRecord, "NAME", (String)"The Sage Group Plc");
SDOHelper.Write(oSalesRecord, "ADDRESS_1", (String)"Building 3");
SDOHelper.Write(oSalesRecord, "ADDRESS_2", (String)"North Park");
SDOHelper.Write(oSalesRecord, "ADDRESS_3", (String)"Newcaslte Upon Tyne");
SDOHelper.Write(oSalesRecord, "ADDRESS_4", (String)"Tyne and Wear");
SDOHelper.Write(oSalesRecord, "ADDRESS_5", (String)"NE13 9AA");
SDOHelper.Write(oSalesRecord, "CONTACT_NAME", (String)"Chris Reed");
SDOHelper.Write(oSalesRecord, "TELEPHONE", (String)"0800 111 7733");
SDOHelper.Write(oSalesRecord, "FAX", (String)"0800 245 0294");
SDOHelper.Write(oSalesRecord, "ANALYSIS_1", (String)"");
SDOHelper.Write(oSalesRecord, "ANALYSIS_2", (String)"");
SDOHelper.Write(oSalesRecord, "ANALYSIS_3", (String)"");
SDOHelper.Write(oSalesRecord, "TERMS", (String)"30 Days");
SDOHelper.Write(oSalesRecord, "DEF_NOM_CODE", (String)"4000");
SDOHelper.Write(oSalesRecord, "VAT_REG_NUMBER", (String)"");
SDOHelper.Write(oSalesRecord, "COUNTRY_CODE", (String)"GB");
//Update the record
if (oSalesRecord.Update())
{
MessageBox.Show("Account " + SDOHelper.Read(oSalesRecord,"ACCOUNT_REF") +
" has been created successfully", "Success!");
}
else
{
MessageBox.Show("The account could not be created", "SDO Examples");
}
}
//Disconnect
oWS.Disconnect();
VB.NET Example:
' Try to Connect - Will Throw an Exception if it Fails
If oWS.Connect(szDataPath, "", "", "Example") Then
' Create an Instance of the SalesRecord Object
oSalesRecord = oWS.CreateObject("SalesRecord")
' Try to Add a New Record
If oSalesRecord.AddNew Then
oSalesRecord.Fields.Item("ACCOUNT_REF").Value = CStr("SAGEGRP")
oSalesRecord.Fields.Item("NAME").Value = CStr("The Sage Group plc")
oSalesRecord.Fields.Item("ADDRESS_1").Value = CStr("Building 5")
oSalesRecord.Fields.Item("ADDRESS_2").Value = CStr("North Park")
oSalesRecord.Fields.Item("ADDRESS_3").Value = CStr("Newcastle Upon Tyne")
oSalesRecord.Fields.Item("ADDRESS_4").Value = CStr("Tyne and Wear")
oSalesRecord.Fields.Item("ADDRESS_5").Value = CStr("NE13 9AA")
oSalesRecord.Fields.Item("CONTACT_NAME").Value = CStr("Mark Steel")
oSalesRecord.Fields.Item("TELEPHONE").Value = CStr("0800 1117733")
oSalesRecord.Fields.Item("FAX").Value = CStr("0800 2450294")
oSalesRecord.Fields.Item("ANALYSIS_1").Value = CStr("")
oSalesRecord.Fields.Item("ANALYSIS_2").Value = CStr("")
oSalesRecord.Fields.Item("ANALYSIS_3").Value = CStr("")
oSalesRecord.Fields.Item("TERMS").Value = CStr("30 Days")
oSalesRecord.Fields.Item("DEF_NOM_CODE").Value = CStr("4000")
oSalesRecord.Fields.Item("VAT_REG_NUMBER").Value = CStr("")
oSalesRecord.Fields.Item("COUNTRY_CODE").Value = CStr("GB")
' Update the Record
If oSalesRecord.Update Then
' The Update was Successful
MsgBox("Account " & oSalesRecord.Fields.Item("ACCOUNT_REF").Value & " was created successfully.", MsgBoxStyle.OKOnly, "SDO Examples")
Else
' The Update was Unsuccessful
MsgBox("The account could not be created.", MsgBoxStyle.OKOnly, "SDO Examples")
End If
End If
' Disconnect
oWS.Disconnect()
End If
Create Sales Orders
Using Sage 50 Accounts
Open the Sales Orders module and select New.
Customer orders are central to your business as a supplier. These are contractual agreements between you, the supplier, and the customer. They define the terms (prices and quantities) by which you will deliver products or provide services.
Sales orders are created using customer details and the goods and services you supply that are held in your Sage 50 Accounts system. The detail section of the sales order consists of lines, these lines itemise the goods and services requested, including any additional charges incurred and are categorised by line type. Stock can then be allocated and despatched with a despatch note.
Using the SDO
This example demonstrates how to post a sales order via the SDO. This example shows how to populate both header and split fields. Once populated you can then attempt to update the sales order by using the Update method. For more information about this example, please refer to the Sales Order Processing section of the help files.
C# Example:
//Leaving the username and password blank generates a login dialog
oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");
//Instantiate objects
oSalesRecord = (SageDataObject260.SalesRecord)oWS.CreateObject("SalesRecord");
oStockRecord = (SageDataObject260.StockRecord)oWS.CreateObject("StockRecord");
oSopPost = (SageDataObject260.SopPost)oWS.CreateObject("SopPost");
//Read the first customer
oSalesRecord.MoveFirst();
//Populate the order Header Fields
SDOHelper.Write(oSopPost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));
SDOHelper.Write(oSopPost.Header, "NAME", (String)SDOHelper.Read(oSalesRecord, "NAME"));
SDOHelper.Write(oSopPost.Header, "ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_1"));
SDOHelper.Write(oSopPost.Header, "ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_2"));
SDOHelper.Write(oSopPost.Header, "ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_3"));
SDOHelper.Write(oSopPost.Header, "ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_4"));
SDOHelper.Write(oSopPost.Header, "ADDRESS_5", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_5"));
SDOHelper.Write(oSopPost.Header, "DEL_ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_1"));
SDOHelper.Write(oSopPost.Header, "DEL_ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_2"));
SDOHelper.Write(oSopPost.Header, "DEL_ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_3"));
SDOHelper.Write(oSopPost.Header, "DEL_ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_4"));
SDOHelper.Write(oSopPost.Header, "DEL_ADDRESS_5", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_5"));
SDOHelper.Write(oSopPost.Header, "CUST_TEL_NUMBER", (String)SDOHelper.Read(oSalesRecord, "TELEPHONE"));
SDOHelper.Write(oSopPost.Header, "CONTACT_NAME", (String)"Contact Name");
SDOHelper.Write(oSopPost.Header, "GLOBAL_TAX_CODE", (Int16)SDOHelper.Read(oSalesRecord, "DEF_TAX_CODE"));
//Populate other header information
SDOHelper.Write(oSopPost.Header, "ORDER_DATE", (DateTime)DateTime.Today);
SDOHelper.Write(oSopPost.Header, "NOTES_1", (String)"");
SDOHelper.Write(oSopPost.Header, "NOTES_2", (String)"");
SDOHelper.Write(oSopPost.Header, "NOTES_3", (String)"");
SDOHelper.Write(oSopPost.Header, "TAKEN_BY", (String)"Taken by Name ");
// If anything is entered in the GLOBAL_NOM_CODE, all the updated invoice’s splits will have this nominal code, and this will force anything entered in the GLOBAL_DETAILS field into the all the splits details field.
SDOHelper.Write(oSopPost.Header, "GLOBAL_NOM_CODE", (String)"");
SDOHelper.Write(oSopPost.Header, "GLOBAL_DETAILS", (String)"");
//Create and order item
oSopItem = (SageDataObject260.SopItem)SDOHelper.Add(oSopPost.Items);
//Read the first stock code
oStockRecord.MoveFirst();
SDOHelper.Write(oSopItem, "STOCK_CODE", (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));
SDOHelper.Write(oSopItem, "DESCRIPTION", (String)SDOHelper.Read(oStockRecord, "DESCRIPTION"));
SDOHelper.Write(oSopItem, "NOMINAL_CODE", (String)SDOHelper.Read(oStockRecord, "NOMINAL_CODE"));
SDOHelper.Write(oSopItem, "TAX_CODE", (Int16)SDOHelper.Read(oStockRecord, "TAX_CODE"));
//Populate other fields required for SOP Item
//From 2015 the update method now wraps internal business logic
//that calculates the VAT amount if a net amount is given.
//If you wish to calculate your own Tax values you will need to ensure that you set the TAX_FLAG to 1 and set the TAX_AMOUNT value on the item line
//***Note if an NVD is set the item line values will be recalculated
//regardless of the Tax_Flag being set to 1***
SDOHelper.Write(oSopItem, "QTY_ORDER", (Double)2);
SDOHelper.Write(oSopItem, "UNIT_PRICE", (Double)100);
SDOHelper.Write(oSopItem, "NET_AMOUNT", (Double)200);
SDOHelper.Write(oSopItem, "FULL_NET_AMOUNT", (Double)200);
SDOHelper.Write(oSopItem, "COMMENT_1", (String)"");
SDOHelper.Write(oSopItem, "COMMENT_2", (String)"");
SDOHelper.Write(oSopItem, "UNIT_OF_SALE", (String)"");
SDOHelper.Write(oSopItem, "TAX_RATE", (Double)20);
SDOHelper.Write(oSopItem, "TAX_CODE", (Int16)1);
//Update the SO
if (oSopPost.Update())
{
MessageBox.Show("Sales Order Created Successfully");
}
else
{
MessageBox.Show("Sales Order Not Created");
}
//Disconnect
oWS.Disconnect();
VB.NET Example:
' Connect to Data Files
If oWS.Connect(szDataPath, "", "", "Example") Then
' Create an Instance of SOPPost & Record Objects
oSalesRecord = oWS.CreateObject("SalesRecord")
oStockRecord = oWS.CreateObject("StockRecord")
oSOPPost = oWS.CreateObject("SOPPost")
' Read the first customer
oSalesRecord.MoveFirst()
' Populate the Order Header Fields
oSOPPost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
oSOPPost.Header("NAME").Value = CStr(oSalesRecord.Fields.Item("NAME").Value)
oSOPPost.Header("ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_1").Value)
oSOPPost.Header("ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_2").Value)
oSOPPost.Header("ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_3").Value)
oSOPPost.Header("ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_4").Value)
oSOPPost.Header("ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_5").Value)
oSOPPost.Header("DEL_ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_1").Value)
oSOPPost.Header("DEL_ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_2").Value)
oSOPPost.Header("DEL_ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_3").Value)
oSOPPost.Header("DEL_ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_4").Value)
oSOPPost.Header("DEL_ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_5").Value)
oSOPPost.Header("CUST_TEL_NUMBER").Value = CStr(oSalesRecord.Fields.Item("Telephone").Value)
oSOPPost.Header("CONTACT_NAME").Value = CStr("Contact Name")
oSOPPost.Header("GLOBAL_TAX_CODE").Value = CShort(oSalesRecord.Fields.Item("DEF_TAX_CODE").Value)
' Populate other Order Header Information
oSOPPost.Header("ORDER_DATE").Value = CDate(Today)
oSOPPost.Header("NOTES_1").Value = CStr("NOTES 1")
oSOPPost.Header("NOTES_2").Value = CStr("NOTES 2")
oSOPPost.Header("NOTES_3").Value = CStr("NOTES 3")
oSOPPost.Header("TAKEN_BY").Value = CStr("Taken By Name")
oSOPPost.Header("CUST_ORDER_NUMBER").Value = CStr("")
' If anything is entered in the GLOBAL_NOM_CODE, all of the updated invoice’s splits will have this nominal code and
' also, this will force anything entered in the GLOBAL_DETAILS field into the all the splits details field.
oSOPPost.Header("GLOBAL_NOM_CODE").Value = CStr("")
oSOPPost.Header("GLOBAL_DETAILS").Value = CStr("")
' Create an Order Item
oSOPItem = oSOPPost.Items.Add()
' Read the first Stock Code
oStockRecord.MoveFirst()
oSOPItem.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
oSOPItem.Fields.Item("DESCRIPTION").Value = CStr(oStockRecord.Fields.Item("DESCRIPTION").Value)
oSOPItem.Fields.Item("NOMINAL_CODE").Value = CStr(oStockRecord.Fields.Item("NOMINAL_CODE").Value)
oSOPItem.Fields.Item("TAX_CODE").Value = CShort(oStockRecord.Fields.Item("TAX_CODE").Value)
' Populate other fields required for SOP Item
' From 2015 the update method now wraps internal business logic
' that calculates the vat amount if a net amount is given.
' If you wish to calculate your own Tax values you will need
' to ensure that you set the TAX_FLAG to 1 and set the TAX_AMOUNT value on the item line
' ***Note if an NVD is set the item line values will be recalculated
' regardless of the Tax_Flag being set to 1***
oSOPItem.Fields.Item("QTY_ORDER").Value = CDbl(2)
oSOPItem.Fields.Item("UNIT_PRICE").Value = CDbl(100)
oSOPItem.Fields.Item("NET_AMOUNT").Value = CDbl(100)
oSOPItem.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(200)
oSOPItem.Fields.Item("COMMENT_1").Value = CStr("")
oSOPItem.Fields.Item("COMMENT_2").Value = CStr("")
oSOPItem.Fields.Item("UNIT_OF_SALE").Value = CStr("")
oSOPItem.Fields.Item("TAX_RATE").Value = CDbl(20)
' Update the Invoice
If oSOPPost.Update Then
MsgBox("Sales Order Created Successfully", MsgBoxStyle.OkOnly, "SDO Examples")
Else
MsgBox("Sales Order Not Created", MsgBoxStyle.OkOnly, "SDO Examples")
End If
' Disconnect
oWS.Disconnect()
End If
What Next?
If you have any further questions relating to the developer tools, please get in touch with us via email at [email protected].
If you wish to join the UK Sage Developer Programme, please contact [email protected].