Skip to content
logo Knowledgebase

Sage 50 Accounts - Development Basics

Created on  | Last modified on 

Summary

This guide provides an overview of the technical aspects of the developer tools that we supply for Sage 50 Accounts.

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.

Image

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.

Image

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.

Image

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.

Image

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].