About Sage Data Objects v12.01

Sage Data Objects for Sage 50 Accounts

The Software Development Kit for Sage 50 Accounts Developers

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. For example - the ‘SalesRecord’ object has methods to ‘Find’, ‘Edit’ and ‘Update’ a customer record, and properties to get and set the ‘Name’, ‘Credit_Limit’, and ‘Balance’.

Objects are available to provide access to data throughout Sage 50 Accounts including products, suppliers, sales and purchase orders, invoices and nominal ledger transactions.

This help file contains all the information you need to integrate your application with Sage 50 Accounts, including Common Questions and Answers and code samples for Microsoft Visual Basic .NET and C# .NET developers.

New to Sage 50 Accounts Development?

Here's a guide to getting started .

What's New in this Version?

Find out in What's New? .

Produced by: Developer Services, Sage (UK) Limited.
© Sage (UK) Ltd Click here to send feedback on this article.


What's New in Sage Data Objects 2020

What's New in Sage Data Objects for Sage 50 Accounts v30

Compatibility Update

This release of the SDK is a compatibility update for Sage 50 Accounts .
How to upgrade your current applications and take advantage of the SDK's functionality. Please let us know if you'd like to see more.

Whats New in update

Sage 50 Accounts: Now in 64-bit!

Introducing the 64-bit version of Sage 50 Accounts and Sage Data Objects (SDO) with Sage 50 Accounts v30.

The 64-bit upgrade ensures seamless compatibility with existing 32-bit applications. Beyond the conventional upgrade process, no further adjustments are needed. This opens the door for you to develop powerful 64-bit applications, reaping the benefits that come with this advanced architecture.

SDO Files Names

In Sage 50 Accounts v29, the file naming convention for the Sage Data Objects (SDO) libraries underwent a change. The files, namely SdoENDxxx.tlb and sg50SdoEnginexxx.dll, no longer include the version number. Instead, these files are now organised within a versioned SDO folder, eliminating the need for them to carry the version in their names.

With the release of Sage Data Objects version 30 (v30), these files are stored in the following directory:

  • 32-bit: C:\Program Files (x86)\Sage\Accounts\SDO\2024
  • 64-bit: C:\Program Files\Sage\Accounts\SDO\2024

The filenames are as follows:

  • SdoENG.tlb
  • sg50SdoEngine.dll

Sage 50 Accounts v30.0 Update

The table below contains all the changes to the SDO in

Object | Name | Description | Length | Type | Change
ACCESSDATA | CONNECTED_SERVICES | Connected Services | 1 | Byte | New Field
ACCESSDATA | CONNECTED_SERVICES_INVOICE_PAYMENTS | Connected Services - Invoice Payments | 1 | Byte | New Field
ACCESSDATA | CONNECTED_SERVICES_INVOICEFINANCE | Connected Services - Satago | 1 | Byte | New Field
ACCESSDATA | CONNECTED_SERVICES_SAGE_NETWORK | Connected Services - Sage Network settings | 1 | Byte | New Field
SETUPDATA | BANK_FEEDS_AUTOMATCH_IS_DISABLED | Disable Bank Feeds AutoMatch | 2 | SmallInteger | New Field
SETUPDATA | BANK_PAYMENT_DEFAULT_DEPARTMENT_CODE | User defined default department code for bank payments | 2 | SmallInteger | New Field
SETUPDATA | BANK_PAYMENT_DEFAULT_NOMINAL | User defined default nominal code for bank payments | 8 | String | New Field
SETUPDATA | BANK_PAYMENT_DEFAULT_TAX_CODE | User defined default tax code for bank payments | 2 | SmallInteger | New Field
SETUPDATA | BANK_RECEIPT_DEFAULT_DEPARTMENT_CODE | User defined default department code for bank receipts | 2 | SmallInteger | New Field
SETUPDATA | BANK_RECEIPT_DEFAULT_NOMINAL | User defined default nominal code for bank receipts | 8 | String | New Field
SETUPDATA | BANK_RECEIPT_DEFAULT_TAX_CODE | User defined default tax code for bank receipts | 2 | SmallInteger | New Field
WORKSPACE | DisconnectEx | Internal use method to support automated tests - Developers should continue to use the existing Disconnect method | System.Void | New Method


Common Questions and Answers

Getting Started and Support

  • Installation and Setup of SDO
  • Adding the SDO Reference to your Project
  • Enable 3rd Party Intergration
  • Upgrading from a Previous Version
  • Running a SDO application without Sage 50 Accounts installed
  • Windows 7/8 Considerations
  • Common Questions and Answers
  • Sage 50 Accounts Product Range
  • Concepts and Principles
  • Examples

Using the Help Files

Topics marked [image] in the Content view are new or have changed in this version of the Sage Data Objects. Within the help files, items coloured blue are new since the last version while items coloured red have been removed or become obsolete since the last version.

At the bottom of each article, you will find a link to send feedback on that particular article. Please use these links to send any feedback (good or bad) that you have as the only way that we can continue to improve the documentation is with your input.

Technical Support

Contact our Developer Support Team

Sage Developer Services are available to answer any queries you may have, and may be contacted via email between 9am and 5pm, Monday to Friday.

email: developers.programme@sage.com

Use the Sage Developers Forum

You can visit the Sage Developers Forum, available to members of the Developers Programme and moderated by Sage staff, to exchange development information, tips and techniques. Please click here and choose 'visit the forum'.

Updated articles, hints, tips and more:

Please visit the Sage 50 Accounts Developer Centre on a regular basis.

Downloads - Full Version and Updates

Please visit the Sage 50 Accounts Downloads page to download latest copies of the SDK and Sage 50 Accounts Developer Edition licences.

Please visit the Sage 50 Accounts Updates page to download the latest updates for Sage 50 Accounts.


Getting Started

Installation of the SDO

The SDO is installed as part of a standard Sage 50 Accounts installation, if you have not installed and setup Sage 50 Accounts you can find the required information in the links below.
If you intend to run your SDO application on a machine that does not have Sage 50 Accounts installed, please read this article, as there are some important considerations that you need to be aware of.

  • System Requirements
  • Installation Guide
  • Enable 3rd Party Application
From 2015, Sage 50 Accounts is no longer supported on Windows XP and earlier operating systems.

Sage Data Objects for Sage 50 Accounts

A collection of ActiveX Dynamic Link Libraries (.DLLs), the Software Development Kit (SDK) is compatible with many popular development environments. Sage Data Objects (SDO) for Sage 50 is fully documented with hints, tips and code samples for Microsoft .Net developers.

Supported Development Environments

  • Microsoft Visual Basic .Net
  • Microsoft C# .Net
Supported .Net Framewroks
  • Microsoft .Net Framework V2.0 and above

For a list of requirements to use these development environments, see Microsoft's System Requirements.

Important Notes:

  • In order that your customers can take advantage of any new objects or fixes supplied with this version of SDO they will need the updated Sg50SDOEngine.DLL file. This file should be shipped with your application and registered on the client's PC.
  • If you are developing an application with Sage 50 Accounts v29 and below and your application is to be deployed on 64-bit operating systems you will need to ensure that the cpu you target is the x86 as in the screen shot below.

Adding the SDO to your Visual Basic .NET/C# project

The type library file, SDOENG.tlb , is installed as part of the standard Sage 50 Accounts installation.

Note: Under normal circumstances, this file is only needed on your development PC; it does not need to be installed on your client's sites. It does appear, however, that development with some languages requires this file to be present on client PCs. If the file is not present, you may get a message "Query Interface for ISDOEngine Failed Error" when trying to instantiate the SDOEngine object.

To use the SDO in your Visual Studio project, you need to add SDOENG.tlb to the list of references.

In Visual Studio

Prior to adding the SDO to your Visual Studio .NET project, you may need to register the SDO Type Library. This can be done by running regtlibv12.exe passing SDOENG.tlb as a parameter.
Note: regtlibv12.exe is a Microsoft file and is not supplied by Sage Developer Services. Windows 10 operating systems do not have the regtlibv12.exe and you will need to copy regtlibv12.exe across from another machine.

To register the file you will need to locate the Regtlibv12.exe file in either (depending on the operating system):

  • C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727
  • C:\Windows\Microsoft.NET\Framework\v4.0.30319
From Start and run you can use the following to register the tlb (changing the paths accordingly for regtlibv12.exe):
  • C:\Windows\Microsoft.NET\Framework\v2.0.50727\regtlibv12.exe "C:\Program Files\Sage\Accounts\SDO\2024\SDOENG.tlb"
  • C:\Windows\Microsoft.NET\Framework\v4.0.303197\regtlibv12.exe "C:\Program Files (x86)\Sage\Accounts\SDO\2024\SDOENG.tlb"
On machines where UAC control is given we recommend that you run cmd.exe as administrator and register the TLB with the following command:
  • C:\Windows\Microsoft.NET\Framework\v4.0.30319\regtlibv12.exe "C:\Program Files (x86)\Sage\Accounts\SDO\2024\SDOENG.tlb"

Adding Reference

Visual Studio .NET project, select Add Reference, choose the COM tab and then select 'Sage Data Objects 30.0 '. Choose Select and then OK.
The first time you do this process you will need to browse to the TLB file to reference it, it is located in 32-bit: C:\Program Files (x86)\Sage\Accounts\SDO\2024 or 64-bit: C:\Program Files\Sage\Accounts\SDO\2024.

What Next?

SDO is now ready to use.
Examples are provided for Microsoft Visual Basic .NET and CSharp .NET developers, and if you'd like to see more, please let us know!


Enabling 3rd Party Integration (Registration)

Enable 3rd Party Integration (Registration)

Introduction

As with previous versions, it is necessary to register SDO (Enable 3rd Party Integration) on both your development and your clients' machines.

Note: In v24.1, it is now no longer necessary to register the SDO. The SDO is already activated and does not require the SDO serial number and activation key to be entered.

Important Note: If you intend to run your SDO application on a machine that does not have a Sage 50 installation, please read this article as there are some important considerations.

To Enable 3rd Party Integration

In Sage 50, go to Tools | Activation | Enable 3rd Party Integration. You will be prompted for the Serial Number and Activation key for the SDO.

Obtaining an SDO Serial Number and Activation Key

From Sage 50 Accounts v21 onwards, all SDO keys used are generic. To obtain a SDO key for Sage 50 Accounts v21 and above please see Ask Sage 14126, we have provided below the latest versions Serial Number and Activation Key.

Sage 50 Accounts v24.0

Serial Number: SAGESDO

Activation Key: ZHIEKPK

Prior to Sage 50 Acounts 2015 (v21) a serial number and activation key spefic to a customers account is required, if you require a serial number and activation key please request your customer to contact their local support team.

Note: Only customers with a registered copy of Sage 50 Accounts are eligible for a serial number and activation key.

Problems Registering?

If you are having problems registering SDO, please see Ask Sage 14126 for troubleshooting steps or click here for a list of possible reasons for the registration failing.
� Sage (UK) Ltd Click here to send feedback on this article.


Upgrading

Upgrading from Previous Versions

Introduction

Your customers will want and indeed expect your software to integrate with Sage 50 Accounts, so we've ensured that you're able to upgrade your current application developments quickly and easily.

How to upgrade your application

To upgrade existing Sage Data Objects enabled applications for Sage 50, all you need to do is:

  1. Install Sage 50 Accounts.
  2. Enable 3rd party integration.
  3. Copy and register the SDOENG.tlb and Sg50SDOEngine.DLL files from the Developer CD (see Getting Started).

    Note: Under normal circumstances, the SDOENG.tlb file is only needed on your development PC; it does not need to be installed on your client's sites. It does appear, however, that development with some .NET languages requires this file to be present on client PCs. If the file is not present, you may get a message "Query Interface for ISDOEngine Failed Error" when trying to instantiate the SDOEngine object.
  4. Add 'Sage Data Objects 30.0' to your Visual Basic project (see Getting Started).
  5. Make the following amendments to your code and recompile your application (xxx signifies the version your application will currently be using, e.g. 210, 220, 230 or 240):

Edit all SDOEngine, Workspace and Object declarations, e.g.:

Dim oSDO As New SageDataObjectxxx.SDOEngine

Dim oWS As SageDataObjectxxx.WorkSpace

Dim oSalesRecord As SageDataObjectxxx.SalesRecord

To read as follows:

Dim oSDO As New SageDataObject300.SDOEngine

Dim oWS As SageDataObject300.WorkSpace

Dim oSalesRecord As SageDataObject300.SalesRecord

NOTE : We have taken the opportunity to update the version of MFC (Microsoft Foundation Classes) used with Sage 50 to v8. These files are installed by default as part of the Sage 50 installation process. Should your application run on a PC where Sage 50 is not installed however, you are required to install these files manually. See Installing and Running SDO Applications on PCs with no Sage 50 Installation.

As you would expect, code examples are also provided to demonstrate how to upgrade existing application developments and take advantage of the Software Development Kit's (SDK) new functionality. Examples are provided for Microsoft Visual Basic .NET, CSharp .NET and Visual Basic v6 developers, and if you'd like to see more, please let us know.

How to take advantage of the new features and functionality in the version

See What's New?


Installing and Running SDO Applications on PCs with no Sage 50 Installation

Considerations

If you are going to run your application in this way, you need to consider the following:

  • Installing the SDO
  • Registering the SDO
  • Registering Sage 50 Accounts
  • Connecting to the Data

Installing the SDO

We have provided an installer that will install and register all of the DLLs and dependencies required for third party applications to run on a computer without Sage 50 Accounts installed. This file (Sage50Accounts_SDO.msi ) can be obtained from the root of the CD.

If the development of the third party software is to be done on such a machine, you will also need to copy the SDO Type Library (SDOENG.tlb ) file to your computer; this should be installed to . You also need to register this file; this can be done by running REGTLIBV12.EXE passing SDOENG.tlb as a parameter. REGTLIBV12.EXE is a Microsoft file and cannot be supplied by Sage Developer Services. It is however installed with Microsoft Visual Studio.

Under normal circumstances, this file is only needed on your development PC; it does not need to be installed on your clients' sites. It does appear, however, that development with some languages requires this file to be present on client PCs. If the file is not present, you may get a message "Query Interface for ISDOEngine Failed Error" when trying to instantiate the SDOEngine object.

Sage 50 Accounts 2015 on

Sage 50 Accounts 2015 saw the introduction of new architectural changes in the way Sage 50 Accounts connects to its data source and now requires the installation of a data service on machines using SDO without a Sage 50 Accounts installation. The executable(ClientServerSetup.exe) to install the data service is provided for both the developer and retail builds of the product.

Registering the SDO

You will need to register the SDO within your own application by using the Register method of the SDOEngine object.

Note: In v24.1, it is now no longer necessary to register the SDO. The SDO is already activated and does not require the SDO serial number and activation key to be entered.

Registering Sage 50 Accounts

SDO requires access to the Sage 50 Accounts registration file to connect. This is called Sage.usr, and is located in the Settings folder of an Accounts installation. To get the path of this folder, within Sage 50 Accounts choose Help | About | System Information | Directories. When deploying to a PC that has no Sage 50 Accounts installation, either:

  • Copy the Sage.usr file into the folder "C:\ProgramData\Sage\Accounts\2024\"
  • OR copy the Sage.usr file into the folder above the ACCDATA folder at the data location
    (for example, X:\Sage 50 Accounts Data\Company.000\ACCDATA),
  • OR on first connection via SDO, the user will be prompted to enter their Sage 50 Accounts serial number and activation key. This will create the registration file for you.
Connecting to the Data

Using the Connect Method:

If you are calling the Connect method directly, you need to ensure that the path to the data points to the machine that has the Sage 50 installation. The data path should point to the ACCDATA folder - for example "X:\Sage 50 Accounts Data\Company.000\ACCDATA".

Using the SelectCompany Method:

If you are using the SelectCompany method then there are further complications due to the fact that this method looks for the COMPANY file to get a list of data paths.

The problem here is that if you try to use the COMPANY file in the Sage 50 installation, the paths will relate to the C:\ drive of the machine with the Sage 50 installation and this will cause problems as your application will then try to connect to a dataset on the C:\ drive of the machine your application is on.

To overcome this, you need to create a COMPANY file on either each PC where your application runs or on a network location, and pass the path to that file to the SelectCompany method. So, for example, if the COMPANY file on the machine that has the Sage 50 installation had the following paths in it:

C:\ProgramData\Sage\Accounts\2024\COMPANY.000
C:\ProgramData\Sage\Accounts\2024\COMPANY.001

you would create a COMPANY file on the machine that has the SDO application installed or on a shared network location that has something like the following contents:

X:\Accounts\2024\COMPANY.000
X:\Accounts\2024\COMPANY.001

The only problem with this method is that if a company is added or deleted in Sage 50 then the COMPANY file that you have created will need to be amended to ensure the company list is valid.

Installation Files

The following files are installed by the Sage 50 Accounts application and by the Sage50Accounts_SDO.msi
and are required for SDO to work:

Sg50SDOEngine.DLL *
SGRegister.dll *
SGDt32.dll
SGIntl32.dll
SGLMInterface

MFCxx.dll #
MSVCRxx.dll #
MSVCPxx.dll #

*these files are registered by the Accounts / SDO installation.
#these are Microsoft files


Common Questions and Answers

This article lists the most common queries and issues reported to Developer Services.

  • I cannot register the SDO despite installing all the necessary files, why is this?
  • I cannot reference the SdoEng***.tlb in my project?
  • I'm getting errors in Sage 50 Accounts relating to the values of the invoices and orders, why is this?
  • Why would the FindFirst/FindNext methods fail?
  • How do I access the transactions for a particular customer account?
  • Can I run my SDO application on a PC that does not have Sage 50 Accounts installed?
  • How can I delete a transaction via the SDO?
  • How many users can be logged in concurrently?
  • I'm getting a COM class factory error?
  • How does Sage Drive affect the use of the SDO?
  • What is the Sage 50 Accounts Data Service and how does this affect the SDO?
  • Why is Sage 50 Accounts now asking for a manager password?
  • What is the maximum length for a user password? (Invalid Password)
  • Why cant I create Customer/Supplier with a space or special character?

I cannot register the SDO despite installing all the necessary files, why is this?

The following are the most common reasons for the Registration of the SDO failing:

  • Incorrect Serial number or Activation key, please see Enable 3rd Party Integration
  • The files Sg50SDOEngine.DLL and SGREGISTER.DLL have not been registered. To register the files, use REGSVR32.EXE.
  • The Windows User may not have the permissions necessary for the registration of the SDO, we would recommend logging in as an administrator in order to register the SDO.

It is also possible, under certain circumstances, that you will get the following dialog box asking for the Sage 50 Accounts Serial Number and Activation Key so if you have client experiencing problems, it is worthwhile checking that it's actually the SDO Serial Number and Activation Key causing the problem rather than those for Sage 50 Accounts.

I cannot reference the SdoEng***.tlb in my project?

If you receive the following error when referencing the SdoEng***.tlb in your project " A reference to 'C:\Windows\system32\SdoEng***.tlb' could not be added. Please make sure that the file is accessible, and that it is a valid assembly or COM component."

  • It will predominantly be due to the tlb not being registered by the Microsoft file regtlibv12.exe. To register the file you will need to locate the Regtlibv12.exe file in C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 on a Windows XP operating system or C:\Windows\Microsoft.NET\Framework\v4.0.30319 on Windows 7. From Start and run you can then use the following to register the tlb: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\regtlibv12.exe ""C:\Program Files\Sage\Accounts\SDO\2024\SDOENG.tlb"". On machines where UAC control is given we recommend that you run cmd.exe as administrator and register the TLB with the following command: C:\Windows\Microsoft.NET\Framework\v4.0.30319\regtlibv12.exe "C:\Program Files (x86)\Sage\Accounts\SDO\2024\SDOENG.tlb". Windows 10 machines do not have the regtlibv12.exe in these locations, it is necessary to copy this across from another machine before following the steps in this answer.

I'm getting errors in Sage 50 Accounts relating to the values of the invoices and orders, why is this?

Prior to passing monetary amounts, i.e. NET_AMOUNT and TAX_AMOUNT to the invoice and order posting objects, you should ensure that the values have rounded to 2 decimal places. Failure to do this can result in the Check Data option in Sage 50 Accounts reporting errors on the invoice amounts.

A similar error message relating to foreign currency amounts can occur if you are posting transactions to the Audit Trail with values to more than 2 decimal places.

Why would the FindFirst/FindNext methods Fail?

There are a number of reasons why these methods may fail as detailed below. You should also bear in mind that they are sequential searches so may take some time on a large dataset.

  • Ensure that you have specified a valid field and value.
  • The record may not exist.
  • If it is a string you are attempting to find, then to get an exact match you will need to pad the field with spaces to the correct length e.g. INV_REF is 30 characters long and you are attempting to find INV001. This would need to be followed by 24 spaces. If you only require a partial match you can use the wildcard e.g. INV* (you do not need to pad this out with spaces.) Wildcard searches will only work with the wildcard character at the end of the string i.e. INV*, you cannot run a wildcard search with the wildcard at the beginning i.e. *INV
How do I access the transactions for a particular customer account?

This can be done via the Link method of the SDORecordLinked object. For an example, click here. This applies equally to stock transactions and to items on invoices and orders.

This is covered in greater detail in the Understanding Transactions article in the Concepts and Principles section of this help file.

Can I run my SDO application on a PC that does not have Sage 50 Accounts installed?

You can do this but there a number of considerations that you need to be aware of. For details of how to do this, click here.

How can I delete a transaction via the SDO?

The SDO has no methods for directly deleting transactions. Although you can set the deleted flag on a transaction, each audit trail transaction affects a large number of other data files and also pointers within data files and, if these are not corrected, data corruption will occur.

If you wish to delete or reverse a transaction via the SDO you should post the transactions required for a manual error correction in Sage 50 Accounts. Details of manual error corrections can be found in the Sage 50 Accounts Help File or from Sage 50 Accounts Support (support@sage.com).

Concurrent users How many users can be logged in concurrently?

The number of concurrent user logins (via SDO and the application) is dependent on the Sage 50 Accounts version, variant and the end-users user licence. For example, Sage 50 Accounts Plus with 2 Users would allow an overall of 8 users logged in - 2 users logged in via the application (Sage UI), then an additional 6 via SDO.

Application Max UI Users# Max SDO Users Max Overall Users
Sage 50 Accounts Professional - v21 (2015) and above
20
Unlimited*
Unlimited*
Sage 50 Accounts Professional - v20 (2014) and below
10
Unlimited*
Unlimited*
Sage 50 Accounts Essentials, Sage 50 Accounts, Sage 50 Accounts Plus - v21 (2015) and above
2
6
8
Sage Instant Accounts Plus 2 Users, Sage 50 Accounts, Sage 50 Accounts Plus - v15 to v20
2
6
8
Sage Instant Accounts, Sage Instant Accounts Plus - v15 to v20
1
6
7

# The maximum UI users is dependent on the user licence - i.e. while Sage 50 Accounts Professional permits up to 20 users, an actual end-user licence may allow less.

* It is recommended that there are no more than 20 concurrent logins in v21 and above and no more than 10 concurrent logins in v20 and below to ensure stability.

I am getting a COM Class Factory error?

The error below is caused by the Target CPU being set to AnyCPU in the projects properties(in Visual Studio), whilst using a 64 bit operating system. Changing to x86 will resolve the issue.

How does Sage Drive affect the use of the SDO?

The simple answer is that Sage Drive does not have any bearing on use of the SDO. The Sage 50 Accounts data will still be held in a local or network location. This means that the SDO can connect to the data in the usual way. Once the data is posted from the SDO it will still sync with Sage Drive in the same way as if it had been entered through the Sage 50 Accounts UI.

What is the Sage 50 Accounts Data Service and how does this affect the SDO?

The Sage Accounts Data service was introduced for Sage 50 Accounts 2015(21). Earlier versions do not use the data service.

The Sage Accounts Data Service runs on the computer or server where your Sage Accounts data is held. The service acts as a gateway and controls the reading and writing of data. Using this service increases the robustness of the system, improves data security and helps to optimise performance.

The Sage Accounts Data Service automatically installs and starts when you install the Sage 50 Accounts software. This includes installation on single computers and network installations where the software is installed on the computer or server that holds the data.

If your data is held on a server that doesn't have a copy of Sage 50 Accounts, you must install the service separately.

The SDO will automatically take care of the transfer of data to the data service. There is no need to do anything different in apllications that integrate with Sage 50 Accounts 2015 and above. The connect method shown in examples in this helpfile will connect to the data in the usual way and postings made will get committed to the data via the data service without anything extra being added to the code or setup.

Why is Sage 50 Accounts now asking for a manager password?

By default in Sage 50 Accounts v23.0 and below the MANAGER user name has no password associated with it. To keep your data secure, it's now mandatory in Sage 50 Accounts 23.1 and above to add a password to the MANAGER user name. Just in case you forget the password, you also enter a security questions to answer in order to reset the password.

What is the maximum length for a user password? (Invalid Password)

By default in Sage 50 Accounts the password character length is set to 10. However, through the SDO it is possible to enter a password with a larger character length when attempting to connect to a company. In that scenario the SDO would look at all the characters of the password and return an "invalid password error". If a user believes they have a password with more then 10 characters even though that isn't possible through the program then you must use the first 10 characters to correctly login through the SDO.

Why cant I create Customer/Supplier with a space or special character?

Due to increased validation following the release of Sage50c it is now not possible to create Customer / Supplier records with an account reference that contains spaces or the following characters:

/:;?\|*"<>@

However, it should be possible to post transactions to existing Customer / Supplier records containing those characters.


Sage 50 Product Range

Sage 50 Accounts Product Range

Introduction

There are three applications to choose from in the Sage 50 Accounts range - Sage 50 Accounts Essentials, Standard and Professional. The table below details the modules available in each of the applications.

Ledger | Essentials | Standard | Professional
Customers | a | a | a
Suppliers | a | a | a
Nominal Ledger | a | a | a
Bank | a | a | a
Products | a* | a | a
Invoicing | a* | a | a
Sales Order Processing | a
Purchase Order Processing | a
Projects | a | a

* Limited modular funtionality.

Although the applications in the Sage 50 Accounts product range differ, the SDO remains the same. Modular functionality is switched on or off depending on the application.

As a developer you'd obviously need to know which application your customer has, so the SDO Workspace object exposes a ProgramType property which can be used to check which application is being used.


Concepts and Principles

Introduction

Although, for the most part, the SDO removes the need know which data is held in which underlying data files, there are instances where a knowledge of the Sage 50 Accounts structures and how they relate to the SDO objects can be useful. This section of the help file contains information about how data is stored and how it can be linked to other data within Sage 50 Accounts.

Articles

  • Understanding Transactions - This article explains how transactions are stored in Sage 50 Accounts and how the various data files link together. The principles described in this article apply equally to any record in Sage 50 Accounts that has transactions associated with it such as stock transactions and invoice/order item Lines.

  • Posting Foreign Currency Transactions - This article explains how to post transactions for foreign currency accounts.

  • Linking Invoices Entered in the Invoicing Module to Audit Trail Transactions - This article explains how to find the audit trail transactions resulting from the update of an invoice in the Invoicing module.

  • Checking VAT Schemes - This article explains the differences between the Standard Vat Scheme and the Vat Cash Accounting Vat scheme.

  • Improving Memory Usage - This article explains the usage and implementation of the .Net System.Runtime.InteropServices Namespace to allow for more efficient use of memory.


Examples - Visual Basic .NET

Examples

These examples demonstrate how to use the SDO to duplicate the business processes within Sage 50 Accounts. Some of the examples rely on specific records in the demo data set so may need to be amended if you intend to test them with your own datasets.

For examples of using the individual methods and properties of the objects, look under the documentation for the methods and properties for the object you are using.

General
  • Connecting and Disconnecting
  • Check Vat Scheme
  • Calculate total Straight Line Depreciation
  • Reading and Editing Department Names
  • Reading a User's Access Rights
  • Reading and Listing Tax Codes
  • Creating a Company Delivery Address
  • Reading Account Status Data
  • Reading Asset Category Data
  • Calculate total Straight Line Depreciation
  • Find unpaid bills
  • List Company names in a ComboBox
  • Add a new country code
  • List Credit Charge Data
  • Reading CourierWWWData
  • Reading which users are logged on
  • View incomplete TODORECORDS
  • Using Document Link
Customer
  • Creating a New Customer Record
  • Editing an Existing Customer Record
  • Deleting an Existing Customer Record
  • a Customer Memo
  • Posting a Batch Sales Invoice
  • Posting a Batch Sales Credit Note
  • Posting a Sales Payment
  • Creating A New Price List Record
  • Creating A Customer Price List Price
  • Creating a Customer Delivery Address
  • Posting a Foreign Currency Sales Invoice
  • Posting a Foreign Currency Sales Credit Note
  • Posting Sales Credit Note and Allocating it to Outstanding Invoices
  • Posting a Sales Payment and Allocating to a Sales Payment On Account
  • Allocating an existing Sales Credit Note to an existing Sales Invoice
  • Generating a Customer Best Price
  • View Customer Aged Balances
  • View Customer Aged Periods
  • View Reading sales delivery records
  • Posting a Sales Invoice and Receipt - VAT Cash Accounting

Supplier
  • Creating a New Supplier Record
  • Editing an Existing Supplier Record
  • Deleting an Existing Supplier Record
  • Accessing a Supplier Memo
  • Posting a Batch Purchase Invoice
  • Posting a Batch Purchase Credit Note
  • Posting a Purchase Receipt
  • Creating a Supplier Delivery Address
  • Posting a Foreign Currency Purchase Invoice
  • Posting a Foreign Currency Purchase Credit Note
  • Posting Purchase Credit Note and Allocating it to Outstanding Invoices
  • Allocating an existing Purchase Credit Note to an existing Purchase Invoice
  • Generating a Supplier Best Price
  • View Supplier Aged Balances
  • View Supplier Aged Periods
  • Looping through supplier delivery addresses
Project Costing
  • Creating a new Project Record
  • Amend a Project Record
  • Deleting a Project Record
  • Creating a new Project Cost Code
  • Amending a Project Cost Code
  • Deleting a Project Cost Code
  • Creating a new Project Resource
  • Amending a Project Resource
  • Deleting a Project Resource
  • Creating a new Project Status
  • Amending a Project Status
  • Deleting a Project Status
  • Posting a Project Charge
  • Posting a Project Credit
  • Posting a Project Stock Issue
  • Posting a Project Stock Return
  • Posting a Project Supplier Invoice
  • Posting a Project Supplier Credit
  • Posting a Project Bank Payment
  • Posting a Project Product Invoice
  • Posting a Project Service Invoice
  • Posting a Project Sales Order
  • Marking a Project as Complete
  • View a Projects Transactions
  • Display Project Details In A Combobox
  • Display Project Statuses In A Combobox

Addresses
  • Create New company Address
  • Create a new Customer Address
  • Create a new Supplier Address
  • Edit a Customer Address
  • View Company Address properties
  • View Customer Address properties for all Customers
  • View Customer Addresses collection
  • Find Customer Address using GetEnumerator
  • View Supllier Address properties for all Suppliers
  • View Supplier Addresses collection
  • Find Supplier Address using GetEnumerator
  • View Customer Addresses Properties Using Item Method
Diary Event
  • Creating a New Diary Event
  • View DiaryEventLabels Properties using Item Method
  • View DiaryRecurrencePatterns Properties using Item Method
Document Addresses
  • Using Document Addresses in Visual Basic .NET
  • View DocumentType LoadType properties
Contact Histroy
  • Add a Contact History Item
  • Edit a Contact History Item
  • Delete a Contact History Item
  • View Contact History Properties
Invoicing
  • Posting a Product Invoice
  • Posting a Product Invoice and Receipt
  • Posting a Product Invoice with Negative Item Lines
  • Posting a Product Credit Note
  • Posting a Service Invoice
  • Posting a Service Invoice with Negative Item Lines
  • Posting a Service Credit Note
  • Posting a 'Mix and Match' Invoice
  • Posting a 'Mix and Match' Credit Note
  • Adding an Item Line to an Existing Invoice
  • Reading the Item Lines of an Existing Invoice
  • Posting a Foreign Currency Product Invoice
  • Manual Invoice Discount
  • Update Invoice to Ledgers
Sales Order Processing
  • Posting a Sales Order
  • Adding an Item Line to an Existing Order
  • Reading the Item Lines of an Existing Order
  • Posting a Foreign Currency Sales Order
Purchase Order Processing
  • Posting a Purchase Order
  • Adding an Item Line to an Existing Order
  • Reading the Item Lines of an Existing Order
  • Posting a Foreign Currency Purchase Order
Fixed Assets
  • Creating a new Fixed Asset Record
Bank
  • Creating a New Bank Account
  • Accessing a Bank Account Memo
  • Posting a Bank Payment
  • Posting a Bank Receipt
  • Posting and Allocating a Sales Invoice, Discount and Receipt
  • Posting a Purchase Payment
  • Posting a Bank Transfer
  • Creating a New Recurring Entry
  • Posting a BACS Purchase Payment
  • Posting a Sales Receipt Against an Existing Invoice
  • Posting a Purchase Payment Against an Existing Invoice
  • Posting a Purchase Payment and Cheque
  • Posting a Sales Receipt on Account (SA)
  • Posting a Purchase Payment on Account (PA)
  • Posting a Purchase Payment and Remittance
  • Posting a Sales Receipt Against an Invoice with Multiple Splits
  • Posting a Foreign Currency Sales Receipt
  • Posting a Foreign Currency Purchase Payment
  • Posting a Foreign Currency Bank Receipt
  • Posting a Foreign Currency Bank Payment
  • Find 'Bank' reconciled transactions
  • Posting a Purchase Payment And Remittance
  • Finding a SplitRecord through HeaderData Unique_Ref field
Nominal
  • Creating a New Nominal Account
  • Reading Nominal Codes
  • Accessing a Nominal Account Memo
  • Posting Journal Entries
  • Creating a New Accrual Record
  • Creating a New Prepayment Record
  • Reading the Chart of Accounts
  • Reading from Different Charts of Account
  • Creating a New Charity Fund
  • Reading Nominal Budgets
  • Reading Financial Budgets
Products
  • Creating a New Product Record
  • Posting an Adjustment In
  • Posting an Adjustment Out
  • Posting a Damages In
  • Posting a Damages Out
  • Posting a Write Off
  • Accessing a Product Record's Transactions
  • Creating a New Special Price
  • Allocate Stock
  • Issue Stock Allocation
  • Amend Stock Allocation
  • Display Stock Categories

Transactions (Financials)
  • Editing a Transaction Split
  • Flag Disputed Transactions
  • Finding Invoice Payments
Foreign Currency Transactions
  • Posting a Foreign Currency Sales Invoice
  • Posting a Foreign Currency Sales Credit Note
  • Posting a Foreign Currency Sales Receipt
  • Posting a Foreign Currency Purchase Invoice
  • Posting a Foreign Currency Purchase Credit Note
  • Posting a Foreign Currency Purchase Payment
  • Posting a Foreign Currency Bank Receipt
  • Posting a Foreign Currency Bank Payment
Construction Industry Scheme (CIS)
  • Amending CIS and ESubmission Settings
  • Creating a New Subcontractor Record
  • Creating a Subcontractor Record from an existing Supplier Record
  • Posting a Subcontractor Invoice
  • Posting a Subcontractor Payment
  • How to use CIS Collection Objects
  • Edit CIS Details
© Sage (UK) Ltd
  • Click here to send feedback on this article.


Changes to the SDO for Sage 50 Accounts 2009

With each new release enhancements are made to the SDO to improve functionality and expose new fields.

New Items

Object | Name | Length | Required | Type | Change
SDOEngine | ProgramTypes.sdoProgramStartUp |  |  | System.Enum | New Enum Value
SDOEngine | ErrorCode.sdoCannotCreateMultipleRegisteredAddresses |  |  | System.Enum | New Enum Value
SDOEngine | ErrorCode.sdoAttemptedToCreateCalendarEventLabel |  |  | System.Enum | New Enum Value
SDOEngine | ErrorCode.sdoAttemptedToEditReadOnlyCalendarEventLabel |  |  | System.Enum | New Enum Value
SDOEngine | New Enum AddressTypes |  |  | System.Enum | New Enumeration
SDOEngine | New Enum DiaryEventOccurenceType |  |  | System.Enum | New Enumeration
SDOEngine | New Enum DiaryRecurrencePeriod |  |  | System.Enum | New Enumeration
SDOEngine | New Enum DiaryRecurrenceDay |  |  | System.Enum | New Enumeration
SDOEngine | New Enum DiaryRecurrenceDayOccurrence |  |  | System.Enum | New Enumeration
SDOEngine | New Enum DiaryRecurrenceEndType |  |  | System.Enum | New Enumeration
SDOEngine | New Enum TraderType |  |  | System.Enum | New Enumeration
SDOEngine | New Enum DocumentTypeValue |  |  | System.Enum | New Enumeration
SDOEngine | New Enum DiaryEventAccountType |  |  | System.Enum | New Enumeration
SUPPLIERADDRESS | AddressNumber |  |  | System.Int32 | New Property
SUPPLIERADDRESS | Supplier |  |  | System.Object | New Property
SUPPLIERADDRESS | Name |  |  | System.String | New Property
SUPPLIERADDRESS | AddressType |  |  | SageDataObject150.AddressTypes | New Property
SUPPLIERADDRESS | Description |  |  | System.String | New Property
SUPPLIERADDRESS | AddressLine1 |  |  | System.String | New Property
SUPPLIERADDRESS | AddressLine2 |  |  | System.String | New Property
SUPPLIERADDRESS | AddressLine3 |  |  | System.String | New Property
SUPPLIERADDRESS | AddressLine4 |  |  | System.String | New Property
SUPPLIERADDRESS | AddressLine5 |  |  | System.String | New Property
SUPPLIERADDRESS | Country |  |  | System.Object | New Property
SUPPLIERADDRESS | Telephone |  |  | System.String | New Property
SUPPLIERADDRESS | Telephone2 |  |  | System.String | New Property
SUPPLIERADDRESS | Fax |  |  | System.String | New Property
SUPPLIERADDRESS | EMail |  |  | System.String | New Property
SUPPLIERADDRESS | Contact |  |  | System.String | New Property
SUPPLIERADDRESS | TaxCode |  |  | System.Object | New Property
SUPPLIERADDRESS | VatNumber |  |  | System.String | New Property
SUPPLIERADDRESS | Role |  |  | System.String | New Property
SUPPLIERADDRESS | Notes |  |  | System.String | New Property
SUPPLIERADDRESS | Update |  |  | System.Boolean | New Method
SUPPLIERADDRESS | Delete |  |  | System.Boolean | New Method
SUPPLIERADDRESS | Load |  |  | System.Boolean | New Method
SALESDATA | ADDRESS_1 | 60 | Yes | StringType | Description changed from 'Account Address Line1' to 'Registered Address Line1'.
SALESDATA | ADDRESS_2 | 60 | Yes | StringType | Description changed from 'Account Address Line2' to 'Registered Address Line2'.
SALESDATA | ADDRESS_3 | 60 | Yes | StringType | Description changed from 'Account Address Line3' to 'Registered Address Line3'.
SALESDATA | ADDRESS_4 | 60 | Yes | StringType | Description changed from 'Account Address Line4' to 'Registered Address Line4'.
SALESDATA | ADDRESS_5 | 60 | Yes | StringType | Description changed from 'Account Address Line5' to 'Registered Address Line5'.
SALESDATA | DEL_ADDRESS_1 | 60 | Yes | StringType | Description changed from 'Delivery Address Line1' to 'Default Delivery Address Line1'.
SALESDATA | DEL_ADDRESS_2 | 60 | Yes | StringType | Description changed from 'Delivery Address Line2' to 'Default Delivery Address Line2'.
SALESDATA | DEL_ADDRESS_3 | 60 | Yes | StringType | Description changed from 'Delivery Address Line3' to 'Default Delivery Address Line3'.
SALESDATA | DEL_ADDRESS_4 | 60 | Yes | StringType | Description changed from 'Delivery Address Line4' to 'Default Delivery Address Line4'.
SALESDATA | DEL_ADDRESS_5 | 60 | Yes | StringType | Description changed from 'Delivery Address Line5' to 'Default Delivery Address Line5'.
SALESDATA | DEL_CONTACT_NAME | 30 | Yes | StringType | Description changed from 'Delivery Contact Name' to 'Default Delivery Contact Name'.
SALESDATA | DEL_FAX | 30 | Yes | StringType | Description changed from 'Delivery Fax Number' to 'Default Delivery Fax Number'.
SALESDATA | DEL_NAME | 60 | Yes | StringType | Description changed from 'Delivery Name' to 'Default Delivery Name'.
SALESDATA | DEL_TELEPHONE | 30 | Yes | StringType | Description changed from 'Delivery Telephone Number' to 'Default Delivery Telephone Number'.
SALESDATA | GIFT_AID_ENABLED | 2 | Yes | SmallIntegerType | New Field
SALESDATA | MEMBER_REMINDER_DATE | 2 | Yes | IntegerType | Description changed from 'Member Riminder Date' to 'Member Reminder Date'.
SALESDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
SALESDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
SALESDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
SALESDATA | SEND_LETTERS_ELECTRONICALLY | 2 | Yes | SmallIntegerType | New Field
SALESDATA | MoveFirst |  |  | System.Boolean | New Method
SALESDATA | MoveLast |  |  | System.Boolean | New Method
SALESDATA | MoveNext |  |  | System.Boolean | New Method
SALESDATA | MovePrev |  |  | System.Boolean | New Method
PURCHASERECORD | ADDRESS_1 | 60 | Yes | StringType | Description changed from 'Account Address Line1' to 'Registered Address Line1'.
PURCHASERECORD | ADDRESS_2 | 60 | Yes | StringType | Description changed from 'Account Address Line2' to 'Registered Address Line2'.
PURCHASERECORD | ADDRESS_3 | 60 | Yes | StringType | Description changed from 'Account Address Line3' to 'Registered Address Line3'.
PURCHASERECORD | ADDRESS_4 | 60 | Yes | StringType | Description changed from 'Account Address Line4' to 'Registered Address Line4'.
PURCHASERECORD | ADDRESS_5 | 60 | Yes | StringType | Description changed from 'Account Address Line5' to 'Registered Address Line5'.
PURCHASERECORD | DEL_ADDRESS_1 | 60 | Yes | StringType | Description changed from 'Delivery Address Line1' to 'Default Delivery Address Line1'.
PURCHASERECORD | DEL_ADDRESS_2 | 60 | Yes | StringType | Description changed from 'Delivery Address Line2' to 'Default Delivery Address Line2'.
PURCHASERECORD | DEL_ADDRESS_3 | 60 | Yes | StringType | Description changed from 'Delivery Address Line3' to 'Default Delivery Address Line3'.
PURCHASERECORD | DEL_ADDRESS_4 | 60 | Yes | StringType | Description changed from 'Delivery Address Line4' to 'Default Delivery Address Line4'.
PURCHASERECORD | DEL_ADDRESS_5 | 60 | Yes | StringType | Description changed from 'Delivery Address Line5' to 'Default Delivery Address Line5'.
PURCHASERECORD | DEL_CONTACT_NAME | 30 | Yes | StringType | Description changed from 'Delivery Contact Name' to 'Default Delivery Contact Name'.
PURCHASERECORD | DEL_FAX | 30 | Yes | StringType | Description changed from 'Delivery Fax Number' to 'Default Delivery Fax Number'.
PURCHASERECORD | DEL_NAME | 60 | Yes | StringType | Description changed from 'Delivery Name' to 'Default Delivery Name'.
PURCHASERECORD | DEL_TELEPHONE | 30 | Yes | StringType | Description changed from 'Delivery Telephone Number' to 'Default Delivery Telephone Number'.
PURCHASERECORD | GIFT_AID_ENABLED | 2 | Yes | SmallIntegerType | New Field
PURCHASERECORD | MEMBER_REMINDER_DATE | 2 | Yes | IntegerType | Description changed from 'Member Riminder Date' to 'Member Reminder Date'.
PURCHASERECORD | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
PURCHASERECORD | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
PURCHASERECORD | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
PURCHASERECORD | SEND_LETTERS_ELECTRONICALLY | 2 | Yes | SmallIntegerType | New Field
COUNTRYCODERECORD | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
COUNTRYCODERECORD | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
COUNTRYCODERECORD | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
BANKHEADERDATA | PRACTICE_SOLUTIONS_REFN | 60 | Yes | StringType | New Field
BANKHEADERDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
BANKHEADERDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
BANKHEADERDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
RECURRINGDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
RECURRINGDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
RECURRINGDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
RECURRINGDATA | MoveFirst |  |  | System.Boolean | New Method
RECURRINGDATA | MoveLast |  |  | System.Boolean | New Method
RECURRINGDATA | MoveNext |  |  | System.Boolean | New Method
RECURRINGDATA | MovePrev |  |  | System.Boolean | New Method
POPDATA | PRACTICE_SOLUTIONS_REFN | 60 | Yes | StringType | New Field
POPDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
POPDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
POPDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
POPDATA | MoveFirst |  |  | System.Boolean | New Method
POPDATA | MoveLast |  |  | System.Boolean | New Method
POPDATA | MoveNext |  |  | System.Boolean | New Method
POPDATA | MovePrev |  |  | System.Boolean | New Method
DEPARTMENTDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
DEPARTMENTDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
DEPARTMENTDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
DEPARTMENTDATA | MoveFirst |  |  | System.Boolean | New Method
DEPARTMENTDATA | MoveLast |  |  | System.Boolean | New Method
DEPARTMENTDATA | MoveNext |  |  | System.Boolean | New Method
DEPARTMENTDATA | MovePrev |  |  | System.Boolean | New Method
ACCRUALDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
ACCRUALDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
ACCRUALDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
ACCRUALDATA | MoveFirst |  |  | System.Boolean | New Method
ACCRUALDATA | MoveLast |  |  | System.Boolean | New Method
ACCRUALDATA | MoveNext |  |  | System.Boolean | New Method
ACCRUALDATA | MovePrev |  |  | System.Boolean | New Method
SALESDELIVERYDATA | ADDRESS_TYPE | 1 | TRUE | ByteType | New Field
SALESDELIVERYDATA | CONTACT_ROLE | 30 | Yes | StringType | New Field
SALESDELIVERYDATA | NOTES | 200 | Yes | StringType | New Field
SALESDELIVERYDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
SALESDELIVERYDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
SALESDELIVERYDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
SALESDELIVERYDATA | MoveFirst |  |  | System.Boolean | New Method
SALESDELIVERYDATA | MoveLast |  |  | System.Boolean | New Method
SALESDELIVERYDATA | MoveNext |  |  | System.Boolean | New Method
SALESDELIVERYDATA | MovePrev |  |  | System.Boolean | New Method
PRICERECORD | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
PRICERECORD | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
PRICERECORD | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
COMPANYDELIVERYDATA | ADDRESS_TYPE | 1 | TRUE | ByteType | New Field
COMPANYDELIVERYDATA | CONTACT_ROLE | 30 | Yes | StringType | New Field
COMPANYDELIVERYDATA | NOTES | 200 | Yes | StringType | New Field
COMPANYDELIVERYDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
COMPANYDELIVERYDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
COMPANYDELIVERYDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
COMPANYDELIVERYDATA | MoveFirst |  |  | System.Boolean | New Method
COMPANYDELIVERYDATA | MoveLast |  |  | System.Boolean | New Method
COMPANYDELIVERYDATA | MoveNext |  |  | System.Boolean | New Method
COMPANYDELIVERYDATA | MovePrev |  |  | System.Boolean | New Method
SUPPLIERADDRESSES | Count |  |  | System.Int32 | New Property
SUPPLIERADDRESSES | Item |  |  | SageDataObject150.SupplierAddress | New Method
SPLITDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
SPLITDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
SPLITDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
SOPDATA | LAST_NETVALUE_DISCOUNT | 8 | Yes | DoubleType | New Field
SOPDATA | PRACTICE_SOLUTIONS_REFN | 60 | Yes | StringType | New Field
SOPDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
SOPDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
SOPDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
SOPDATA | UNALLOCATED_NETVALUE_DISCOUNT | 8 | Yes | DoubleType | New Field
SOPDATA | MoveFirst |  |  | System.Boolean | New Method
SOPDATA | MoveLast |  |  | System.Boolean | New Method
SOPDATA | MoveNext |  |  | System.Boolean | New Method
SOPDATA | MovePrev |  |  | System.Boolean | New Method
COMPANYADDRESS | AddressNumber |  |  | System.Int32 | New Property
COMPANYADDRESS | Name |  |  | System.String | New Property
COMPANYADDRESS | AddressType |  |  | SageDataObject150.AddressTypes | New Property
COMPANYADDRESS | Description |  |  | System.String | New Property
COMPANYADDRESS | AddressLine1 |  |  | System.String | New Property
COMPANYADDRESS | AddressLine2 |  |  | System.String | New Property
COMPANYADDRESS | AddressLine3 |  |  | System.String | New Property
COMPANYADDRESS | AddressLine4 |  |  | System.String | New Property
COMPANYADDRESS | AddressLine5 |  |  | System.String | New Property
COMPANYADDRESS | Country |  |  | System.Object | New Property
COMPANYADDRESS | Telephone |  |  | System.String | New Property
COMPANYADDRESS | Telephone2 |  |  | System.String | New Property
COMPANYADDRESS | Fax |  |  | System.String | New Property
COMPANYADDRESS | EMail |  |  | System.String | New Property
COMPANYADDRESS | Contact |  |  | System.String | New Property
COMPANYADDRESS | Role |  |  | System.String | New Property
COMPANYADDRESS | Notes |  |  | System.String | New Property
COMPANYADDRESS | Update |  |  | System.Boolean | New Method
COMPANYADDRESS | Delete |  |  | System.Boolean | New Method
COMPANYADDRESS | Load |  |  | System.Boolean | New Method
COMPANYDELIVERYRECORD | ADDRESS_TYPE | 1 | TRUE | ByteType | New Field
COMPANYDELIVERYRECORD | CONTACT_ROLE | 30 | Yes | StringType | New Field
COMPANYDELIVERYRECORD | NOTES | 200 | Yes | StringType | New Field
COMPANYDELIVERYRECORD | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
COMPANYDELIVERYRECORD | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
COMPANYDELIVERYRECORD | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
TODORECORD | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
TODORECORD | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
TODORECORD | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
CUSTOMERADDRESSES | Count |  |  | System.Int32 | New Property
CUSTOMERADDRESSES | Item |  |  | SageDataObject150.CustomerAddress | New Method
BANKRECORD | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
BANKRECORD | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
BANKRECORD | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
DOCUMENTTYPE | UniqueID |  |  | System.Int32 | New Property
DOCUMENTTYPE | Type |  |  | SageDataObject150.DocumentTypeValue | New Property
DOCUMENTTYPE | Description |  |  | System.String | New Property
DOCUMENTTYPE | UsedForCustomers |  |  | System.Boolean | New Property
DOCUMENTTYPE | UsedForSuppliers |  |  | System.Boolean | New Property
DOCUMENTTYPE | Update |  |  | System.Boolean | New Method
DOCUMENTTYPE | Delete |  |  | System.Boolean | New Method
DOCUMENTTYPE | Load |  |  | System.Boolean | New Method
DOCUMENTTYPE | LoadType |  |  | System.Boolean | New Method
BILLDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
BILLDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
BILLDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
BILLDATA | MoveFirst |  |  | System.Boolean | New Method
BILLDATA | MoveLast |  |  | System.Boolean | New Method
BILLDATA | MoveNext |  |  | System.Boolean | New Method
BILLDATA | MovePrev |  |  | System.Boolean | New Method
POPRECORD | PRACTICE_SOLUTIONS_REFN | 60 | Yes | StringType | New Field
POPRECORD | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
POPRECORD | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
POPRECORD | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
CREDITCHARGEDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
CREDITCHARGEDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
CREDITCHARGEDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
CREDITCHARGEDATA | MoveFirst |  |  | System.Boolean | New Method
CREDITCHARGEDATA | MoveLast |  |  | System.Boolean | New Method
CREDITCHARGEDATA | MoveNext |  |  | System.Boolean | New Method
CREDITCHARGEDATA | MovePrev |  |  | System.Boolean | New Method
DIARYEVENTLABELS | Count |  |  | System.Int32 | New Property
DIARYEVENTLABELS | Item |  |  | SageDataObject150.DiaryEventLabel | New Method
BANKREMITTANCEDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
BANKREMITTANCEDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
BANKREMITTANCEDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
DOCUMENTADDRESSES | Count |  |  | System.Int32 | New Property
DOCUMENTADDRESSES | Item |  |  | SageDataObject150.DocumentType | New Method
DIARYEVENTLABEL | UniqueID |  |  | System.Int32 | New Property
DIARYEVENTLABEL | Name |  |  | System.String | New Property
DIARYEVENTLABEL | Color |  |  | System.Int32 | New Property
DIARYEVENTLABEL | ReadOnly |  |  | System.Boolean | New Property
DIARYEVENTLABEL | Update |  |  | System.Boolean | New Method
DIARYEVENTLABEL | Delete |  |  | System.Boolean | New Method
DIARYEVENTLABEL | Load |  |  | System.Boolean | New Method
REMITTANCERECORD | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
REMITTANCERECORD | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
REMITTANCERECORD | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
NOMINALRECORD | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
NOMINALRECORD | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
NOMINALRECORD | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
CUSTOMERADDRESS | AddressNumber |  |  | System.Int32 | New Property
CUSTOMERADDRESS | Customer |  |  | System.Object | New Property
CUSTOMERADDRESS | Name |  |  | System.String | New Property
CUSTOMERADDRESS | AddressType |  |  | SageDataObject150.AddressTypes | New Property
CUSTOMERADDRESS | Description |  |  | System.String | New Property
CUSTOMERADDRESS | AddressLine1 |  |  | System.String | New Property
CUSTOMERADDRESS | AddressLine2 |  |  | System.String | New Property
CUSTOMERADDRESS | AddressLine3 |  |  | System.String | New Property
CUSTOMERADDRESS | AddressLine4 |  |  | System.String | New Property
CUSTOMERADDRESS | AddressLine5 |  |  | System.String | New Property
CUSTOMERADDRESS | Country |  |  | System.Object | New Property
CUSTOMERADDRESS | Telephone |  |  | System.String | New Property
CUSTOMERADDRESS | Telephone2 |  |  | System.String | New Property
CUSTOMERADDRESS | Fax |  |  | System.String | New Property
CUSTOMERADDRESS | EMail |  |  | System.String | New Property
CUSTOMERADDRESS | Contact |  |  | System.String | New Property
CUSTOMERADDRESS | TaxCode |  |  | System.Object | New Property
CUSTOMERADDRESS | VatNumber |  |  | System.String | New Property
CUSTOMERADDRESS | Role |  |  | System.String | New Property
CUSTOMERADDRESS | Notes |  |  | System.String | New Property
CUSTOMERADDRESS | Update |  |  | System.Boolean | New Method
CUSTOMERADDRESS | Delete |  |  | System.Boolean | New Method
CUSTOMERADDRESS | Load |  |  | System.Boolean | New Method
CONTROLDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
CONTROLDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
CONTROLDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
ASSETDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
ASSETDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
ASSETDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
ASSETDATA | MoveFirst |  |  | System.Boolean | New Method
ASSETDATA | MoveLast |  |  | System.Boolean | New Method
ASSETDATA | MoveNext |  |  | System.Boolean | New Method
ASSETDATA | MovePrev |  |  | System.Boolean | New Method
STOCKTRAN | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
STOCKTRAN | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
STOCKTRAN | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
SALESDELIVERYRECORD | ADDRESS_TYPE | 1 | TRUE | ByteType | New Field
SALESDELIVERYRECORD | CONTACT_ROLE | 30 | Yes | StringType | New Field
SALESDELIVERYRECORD | NOTES | 200 | Yes | StringType | New Field
SALESDELIVERYRECORD | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
SALESDELIVERYRECORD | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
SALESDELIVERYRECORD | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
QUEUEDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
QUEUEDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
QUEUEDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
QUEUEDATA | MoveFirst |  |  | System.Boolean | New Method
QUEUEDATA | MoveLast |  |  | System.Boolean | New Method
QUEUEDATA | MoveNext |  |  | System.Boolean | New Method
QUEUEDATA | MovePrev |  |  | System.Boolean | New Method
PURCHASEDELIVERYRECORD | ADDRESS_TYPE | 1 | TRUE | ByteType | New Field
PURCHASEDELIVERYRECORD | CONTACT_ROLE | 30 | Yes | StringType | New Field
PURCHASEDELIVERYRECORD | NOTES | 200 | Yes | StringType | New Field
PURCHASEDELIVERYRECORD | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
PURCHASEDELIVERYRECORD | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
PURCHASEDELIVERYRECORD | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
DIARYEVENTS | Count |  |  | System.Int32 | New Property
DIARYEVENTS | Item |  |  | SageDataObject150.DiaryEvent | New Method
ACCOUNTSTATUSDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
ACCOUNTSTATUSDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
ACCOUNTSTATUSDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
ACCOUNTSTATUSDATA | MoveFirst |  |  | System.Boolean | New Method
ACCOUNTSTATUSDATA | MoveLast |  |  | System.Boolean | New Method
ACCOUNTSTATUSDATA | MoveNext |  |  | System.Boolean | New Method
ACCOUNTSTATUSDATA | MovePrev |  |  | System.Boolean | New Method
STOCKDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
STOCKDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
STOCKDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
STOCKDATA | MoveFirst |  |  | System.Boolean | New Method
STOCKDATA | MoveLast |  |  | System.Boolean | New Method
STOCKDATA | MoveNext |  |  | System.Boolean | New Method
STOCKDATA | MovePrev |  |  | System.Boolean | New Method
SOPITEM | NETVALUE_DISCOUNT_ALLOCATED | 8 | Yes | DoubleType | New Field
HEADERDATA | PRACTICE_SOLUTIONS_REFN | 60 | Yes | StringType | New Field
HEADERDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
HEADERDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
HEADERDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
GOODSNOTESDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
GOODSNOTESDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
GOODSNOTESDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
CURRENCYDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
CURRENCYDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
CURRENCYDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
CURRENCYDATA | MoveFirst |  |  | System.Boolean | New Method
CURRENCYDATA | MoveLast |  |  | System.Boolean | New Method
CURRENCYDATA | MoveNext |  |  | System.Boolean | New Method
CURRENCYDATA | MovePrev |  |  | System.Boolean | New Method
CREDITWWWDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
CREDITWWWDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
CREDITWWWDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
CREDITWWWDATA | MoveFirst |  |  | System.Boolean | New Method
CREDITWWWDATA | MoveLast |  |  | System.Boolean | New Method
CREDITWWWDATA | MoveNext |  |  | System.Boolean | New Method
CREDITWWWDATA | MovePrev |  |  | System.Boolean | New Method
CHARTDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
CHARTDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
CHARTDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
CHARTDATA | MoveFirst |  |  | System.Boolean | New Method
CHARTDATA | MoveLast |  |  | System.Boolean | New Method
CHARTDATA | MoveNext |  |  | System.Boolean | New Method
CHARTDATA | MovePrev |  |  | System.Boolean | New Method
CATEGORY | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
CATEGORY | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
CATEGORY | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
CATEGORY | MoveFirst |  |  | System.Boolean | New Method
CATEGORY | MoveLast |  |  | System.Boolean | New Method
CATEGORY | MoveNext |  |  | System.Boolean | New Method
CATEGORY | MovePrev |  |  | System.Boolean | New Method
ASSETRECORD | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
ASSETRECORD | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
ASSETRECORD | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
USAGEDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
USAGEDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
USAGEDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
TODODATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
TODODATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
TODODATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
TODODATA | MoveFirst |  |  | System.Boolean | New Method
TODODATA | MoveLast |  |  | System.Boolean | New Method
TODODATA | MoveNext |  |  | System.Boolean | New Method
TODODATA | MovePrev |  |  | System.Boolean | New Method
SETUPDATA | ALLOW_ON_HOLD_TRANS_ENTRY | 2 | Yes | SmallIntegerType | New Field
SETUPDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
SETUPDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
SETUPDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
SETUPDATA | VAT_REGISTERED_FLAG | 1 | Yes | ByteType | New Field
PURCHASEDELIVERYDATA | ADDRESS_TYPE | 1 | TRUE | ByteType | New Field
PURCHASEDELIVERYDATA | CONTACT_ROLE | 30 | Yes | StringType | New Field
PURCHASEDELIVERYDATA | NOTES | 200 | Yes | StringType | New Field
PURCHASEDELIVERYDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
PURCHASEDELIVERYDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
PURCHASEDELIVERYDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
PURCHASEDELIVERYDATA | MoveFirst |  |  | System.Boolean | New Method
PURCHASEDELIVERYDATA | MoveLast |  |  | System.Boolean | New Method
PURCHASEDELIVERYDATA | MoveNext |  |  | System.Boolean | New Method
PURCHASEDELIVERYDATA | MovePrev |  |  | System.Boolean | New Method
COUNTRYCODEDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
COUNTRYCODEDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
COUNTRYCODEDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
COUNTRYCODEDATA | MoveFirst |  |  | System.Boolean | New Method
COUNTRYCODEDATA | MoveLast |  |  | System.Boolean | New Method
COUNTRYCODEDATA | MoveNext |  |  | System.Boolean | New Method
COUNTRYCODEDATA | MovePrev |  |  | System.Boolean | New Method
CONTACTDATEIDXRECORD | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
CONTACTDATEIDXRECORD | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
CONTACTDATEIDXRECORD | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
DIARYRECURRENCEPATTERN | UniqueID |  |  | System.Int32 | New Property
DIARYRECURRENCEPATTERN | StartTime |  |  | System.DateTime | New Property
DIARYRECURRENCEPATTERN | DurationInMinutes |  |  | System.Int32 | New Property
DIARYRECURRENCEPATTERN | RecurrencePeriod |  |  | SageDataObject150.DiaryRecurrencePeriod | New Property
DIARYRECURRENCEPATTERN | DailyWeekdaysOnly |  |  | System.Boolean | New Property
DIARYRECURRENCEPATTERN | DailyIntervalInDays |  |  | System.Int32 | New Property
DIARYRECURRENCEPATTERN | WeeklyIntervalInWeeks |  |  | System.Int32 | New Property
DIARYRECURRENCEPATTERN | WeeklyDaysOfWeek |  |  | System.Int32 | New Property
DIARYRECURRENCEPATTERN | MonthlyIntervalInMonths |  |  | System.Int32 | New Property
DIARYRECURRENCEPATTERN | MonthlyDayOfMonth |  |  | System.Int32 | New Property
DIARYRECURRENCEPATTERN | MonthlyNthIntervalInMonths |  |  | System.Int32 | New Property
DIARYRECURRENCEPATTERN | MonthlyNthDayOccurrence |  |  | SageDataObject150.DiaryRecurrenceDayOccurrence | New Property
DIARYRECURRENCEPATTERN | MonthlyNthDayOfWeek |  |  | System.Int32 | New Property
DIARYRECURRENCEPATTERN | YearlyMonthOfYear |  |  | System.Int32 | New Property
DIARYRECURRENCEPATTERN | YearlyDayOfMonth |  |  | System.Int32 | New Property
DIARYRECURRENCEPATTERN | YearlyNthDayOccurrence |  |  | SageDataObject150.DiaryRecurrenceDayOccurrence | New Property
DIARYRECURRENCEPATTERN | YearlyNthDayOfWeek |  |  | System.Int32 | New Property
DIARYRECURRENCEPATTERN | YearlyNthMonthOfYear |  |  | System.Int32 | New Property
DIARYRECURRENCEPATTERN | StartDate |  |  | System.DateTime | New Property
DIARYRECURRENCEPATTERN | EndType |  |  | SageDataObject150.DiaryRecurrenceEndType | New Property
DIARYRECURRENCEPATTERN | EndDate |  |  | System.DateTime | New Property
DIARYRECURRENCEPATTERN | TotalOccurrences |  |  | System.Int32 | New Property
DIARYRECURRENCEPATTERN | Update |  |  | System.Boolean | New Method
DIARYRECURRENCEPATTERN | Delete |  |  | System.Boolean | New Method
DIARYRECURRENCEPATTERN | Load |  |  | System.Boolean | New Method
REMITTANCEDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
REMITTANCEDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
REMITTANCEDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
PURCHASEDATA | ADDRESS_1 | 60 | Yes | StringType | Description changed from 'Account Address Line1' to 'Registered Address Line1'.
PURCHASEDATA | ADDRESS_2 | 60 | Yes | StringType | Description changed from 'Account Address Line2' to 'Registered Address Line2'.
PURCHASEDATA | ADDRESS_3 | 60 | Yes | StringType | Description changed from 'Account Address Line3' to 'Registered Address Line3'.
PURCHASEDATA | ADDRESS_4 | 60 | Yes | StringType | Description changed from 'Account Address Line4' to 'Registered Address Line4'.
PURCHASEDATA | ADDRESS_5 | 60 | Yes | StringType | Description changed from 'Account Address Line5' to 'Registered Address Line5'.
PURCHASEDATA | DEL_ADDRESS_1 | 60 | Yes | StringType | Description changed from 'Delivery Address Line1' to 'Default Delivery Address Line1'.
PURCHASEDATA | DEL_ADDRESS_2 | 60 | Yes | StringType | Description changed from 'Delivery Address Line2' to 'Default Delivery Address Line2'.
PURCHASEDATA | DEL_ADDRESS_3 | 60 | Yes | StringType | Description changed from 'Delivery Address Line3' to 'Default Delivery Address Line3'.
PURCHASEDATA | DEL_ADDRESS_4 | 60 | Yes | StringType | Description changed from 'Delivery Address Line4' to 'Default Delivery Address Line4'.
PURCHASEDATA | DEL_ADDRESS_5 | 60 | Yes | StringType | Description changed from 'Delivery Address Line5' to 'Default Delivery Address Line5'.
PURCHASEDATA | DEL_CONTACT_NAME | 30 | Yes | StringType | Description changed from 'Delivery Contact Name' to 'Default Delivery Contact Name'.
PURCHASEDATA | DEL_FAX | 30 | Yes | StringType | Description changed from 'Delivery Fax Number' to 'Default Delivery Fax Number'.
PURCHASEDATA | DEL_NAME | 60 | Yes | StringType | Description changed from 'Delivery Name' to 'Default Delivery Name'.
PURCHASEDATA | DEL_TELEPHONE | 30 | Yes | StringType | Description changed from 'Delivery Telephone Number' to 'Default Delivery Telephone Number'.
PURCHASEDATA | GIFT_AID_ENABLED | 2 | Yes | SmallIntegerType | New Field
PURCHASEDATA | MEMBER_REMINDER_DATE | 2 | Yes | IntegerType | Description changed from 'Member Riminder Date' to 'Member Reminder Date'.
PURCHASEDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
PURCHASEDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
PURCHASEDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
PURCHASEDATA | SEND_LETTERS_ELECTRONICALLY | 2 | Yes | SmallIntegerType | New Field
PURCHASEDATA | MoveFirst |  |  | System.Boolean | New Method
PURCHASEDATA | MoveLast |  |  | System.Boolean | New Method
PURCHASEDATA | MoveNext |  |  | System.Boolean | New Method
PURCHASEDATA | MovePrev |  |  | System.Boolean | New Method
PRICELISTRECORD | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
PRICELISTRECORD | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
PRICELISTRECORD | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
STOCKRECORD | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
STOCKRECORD | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
STOCKRECORD | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
SOPRECORD | LAST_NETVALUE_DISCOUNT | 8 | Yes | DoubleType | New Field
SOPRECORD | PRACTICE_SOLUTIONS_REFN | 60 | Yes | StringType | New Field
SOPRECORD | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
SOPRECORD | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
SOPRECORD | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
SOPRECORD | UNALLOCATED_NETVALUE_DISCOUNT | 8 | Yes | DoubleType | New Field
MISCWWWDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
MISCWWWDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
MISCWWWDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
MISCWWWDATA | MoveFirst |  |  | System.Boolean | New Method
MISCWWWDATA | MoveLast |  |  | System.Boolean | New Method
MISCWWWDATA | MoveNext |  |  | System.Boolean | New Method
MISCWWWDATA | MovePrev |  |  | System.Boolean | New Method
INVOICERECORD | LAST_NETVALUE_DISCOUNT | 8 | Yes | DoubleType | New Field
INVOICERECORD | PRACTICE_SOLUTIONS_REFN | 60 | Yes | StringType | New Field
INVOICERECORD | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
INVOICERECORD | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
INVOICERECORD | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
INVOICERECORD | UNALLOCATED_NETVALUE_DISCOUNT | 8 | Yes | DoubleType | New Field
INVOICEDATA | LAST_NETVALUE_DISCOUNT | 8 | Yes | DoubleType | New Field
INVOICEDATA | PRACTICE_SOLUTIONS_REFN | 60 | Yes | StringType | New Field
INVOICEDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
INVOICEDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
INVOICEDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
INVOICEDATA | UNALLOCATED_NETVALUE_DISCOUNT | 8 | Yes | DoubleType | New Field
INVOICEDATA | MoveFirst |  |  | System.Boolean | New Method
INVOICEDATA | MoveLast |  |  | System.Boolean | New Method
INVOICEDATA | MoveNext |  |  | System.Boolean | New Method
INVOICEDATA | MovePrev |  |  | System.Boolean | New Method
DOCUMENTTYPES | Count |  |  | System.Int32 | New Property
DOCUMENTTYPES | Item |  |  | SageDataObject150.DocumentType | New Method
DOCUMENTADDRESS | AccountType |  |  | SageDataObject150.TraderType | New Property
DOCUMENTADDRESS | AccountRefn |  |  | System.String | New Property
DOCUMENTADDRESS | DocumentTypeID |  |  | System.Int32 | New Property
DOCUMENTADDRESS | AddressNumber |  |  | System.Int32 | New Property
DOCUMENTADDRESS | DocumentType |  |  | System.Object | New Property
DOCUMENTADDRESS | Customer |  |  | System.Object | New Property
DOCUMENTADDRESS | CustomerAddress |  |  | System.Object | New Property
DOCUMENTADDRESS | Supplier |  |  | System.Object | New Property
DOCUMENTADDRESS | SupplierAddress |  |  | System.Object | New Property
DOCUMENTADDRESS | Update |  |  | System.Boolean | New Method
DOCUMENTADDRESS | Delete |  |  | System.Boolean | New Method
DOCUMENTADDRESS | Load |  |  | System.Boolean | New Method
COMPANYADDRESSES | Count |  |  | System.Int32 | New Property
COMPANYADDRESSES | Item |  |  | SageDataObject150.CompanyAddress | New Method
BANKDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
BANKDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
BANKDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
BANKDATA | MoveFirst |  |  | System.Boolean | New Method
BANKDATA | MoveLast |  |  | System.Boolean | New Method
BANKDATA | MoveNext |  |  | System.Boolean | New Method
BANKDATA | MovePrev |  |  | System.Boolean | New Method
SALESRECORD | ADDRESS_1 | 60 | Yes | StringType | Description changed from 'Account Address Line1' to 'Registered Address Line1'.
SALESRECORD | ADDRESS_2 | 60 | Yes | StringType | Description changed from 'Account Address Line2' to 'Registered Address Line2'.
SALESRECORD | ADDRESS_3 | 60 | Yes | StringType | Description changed from 'Account Address Line3' to 'Registered Address Line3'.
SALESRECORD | ADDRESS_4 | 60 | Yes | StringType | Description changed from 'Account Address Line4' to 'Registered Address Line4'.
SALESRECORD | ADDRESS_5 | 60 | Yes | StringType | Description changed from 'Account Address Line5' to 'Registered Address Line5'.
SALESRECORD | DEL_ADDRESS_1 | 60 | Yes | StringType | Description changed from 'Delivery Address Line1' to 'Default Delivery Address Line1'.
SALESRECORD | DEL_ADDRESS_2 | 60 | Yes | StringType | Description changed from 'Delivery Address Line2' to 'Default Delivery Address Line2'.
SALESRECORD | DEL_ADDRESS_3 | 60 | Yes | StringType | Description changed from 'Delivery Address Line3' to 'Default Delivery Address Line3'.
SALESRECORD | DEL_ADDRESS_4 | 60 | Yes | StringType | Description changed from 'Delivery Address Line4' to 'Default Delivery Address Line4'.
SALESRECORD | DEL_ADDRESS_5 | 60 | Yes | StringType | Description changed from 'Delivery Address Line5' to 'Default Delivery Address Line5'.
SALESRECORD | DEL_CONTACT_NAME | 30 | Yes | StringType | Description changed from 'Delivery Contact Name' to 'Default Delivery Contact Name'.
SALESRECORD | DEL_FAX | 30 | Yes | StringType | Description changed from 'Delivery Fax Number' to 'Default Delivery Fax Number'.
SALESRECORD | DEL_NAME | 60 | Yes | StringType | Description changed from 'Delivery Name' to 'Default Delivery Name'.
SALESRECORD | DEL_TELEPHONE | 30 | Yes | StringType | Description changed from 'Delivery Telephone Number' to 'Default Delivery Telephone Number'.
SALESRECORD | GIFT_AID_ENABLED | 2 | Yes | SmallIntegerType | New Field
SALESRECORD | MEMBER_REMINDER_DATE | 2 | Yes | IntegerType | Description changed from 'Member Riminder Date' to 'Member Reminder Date'.
SALESRECORD | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
SALESRECORD | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
SALESRECORD | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
SALESRECORD | SEND_LETTERS_ELECTRONICALLY | 2 | Yes | SmallIntegerType | New Field
PRICELISTDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
PRICELISTDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
PRICELISTDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
PRICELISTDATA | MoveFirst |  |  | System.Boolean | New Method
PRICELISTDATA | MoveLast |  |  | System.Boolean | New Method
PRICELISTDATA | MoveNext |  |  | System.Boolean | New Method
PRICELISTDATA | MovePrev |  |  | System.Boolean | New Method
NOMINALDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
NOMINALDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
NOMINALDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
NOMINALDATA | MoveFirst |  |  | System.Boolean | New Method
NOMINALDATA | MoveLast |  |  | System.Boolean | New Method
NOMINALDATA | MoveNext |  |  | System.Boolean | New Method
NOMINALDATA | MovePrev |  |  | System.Boolean | New Method
COURIERWWWDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
COURIERWWWDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
COURIERWWWDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
COURIERWWWDATA | MoveFirst |  |  | System.Boolean | New Method
COURIERWWWDATA | MoveLast |  |  | System.Boolean | New Method
COURIERWWWDATA | MoveNext |  |  | System.Boolean | New Method
COURIERWWWDATA | MovePrev |  |  | System.Boolean | New Method
BANKWWWDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
BANKWWWDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
BANKWWWDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
BANKWWWDATA | MoveFirst |  |  | System.Boolean | New Method
BANKWWWDATA | MoveLast |  |  | System.Boolean | New Method
BANKWWWDATA | MoveNext |  |  | System.Boolean | New Method
BANKWWWDATA | MovePrev |  |  | System.Boolean | New Method
BANKREMITTANCERECORD | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
BANKREMITTANCERECORD | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
BANKREMITTANCERECORD | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
STOCKALLOCATION | ReadOnly |  |  | System.Int32 | New Property
STOCKCATEGORY | MoveFirst |  |  | System.Boolean | New Method
STOCKCATEGORY | MoveLast |  |  | System.Boolean | New Method
STOCKCATEGORY | MoveNext |  |  | System.Boolean | New Method
STOCKCATEGORY | MovePrev |  |  | System.Boolean | New Method
PRICEDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
PRICEDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
PRICEDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
PRICEDATA | MoveFirst |  |  | System.Boolean | New Method
PRICEDATA | MoveLast |  |  | System.Boolean | New Method
PRICEDATA | MoveNext |  |  | System.Boolean | New Method
PRICEDATA | MovePrev |  |  | System.Boolean | New Method
PREPAYDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
PREPAYDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
PREPAYDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
PREPAYDATA | MoveFirst |  |  | System.Boolean | New Method
PREPAYDATA | MoveLast |  |  | System.Boolean | New Method
PREPAYDATA | MoveNext |  |  | System.Boolean | New Method
PREPAYDATA | MovePrev |  |  | System.Boolean | New Method
DIARYEVENT | UniqueID |  |  | System.Int32 | New Property
DIARYEVENT | OccurrenceType |  |  | SageDataObject150.DiaryEventOccurenceType | New Property
DIARYEVENT | RecurrencePattern |  |  | System.Object | New Property
DIARYEVENT | IsDeletedOccurrence |  |  | System.Int32 | New Property
DIARYEVENT | OriginalStartTime |  |  | System.DateTime | New Property
DIARYEVENT | OriginalEndTime |  |  | System.DateTime | New Property
DIARYEVENT | IsAllDayEvent |  |  | System.Int32 | New Property
DIARYEVENT | HasReminder |  |  | System.Int32 | New Property
DIARYEVENT | ReminderMinutesBeforeStart |  |  | System.Int32 | New Property
DIARYEVENT | NextReminderTime |  |  | System.DateTime | New Property
DIARYEVENT | StartTime |  |  | System.DateTime | New Property
DIARYEVENT | EndTime |  |  | System.DateTime | New Property
DIARYEVENT | Label |  |  | System.Object | New Property
DIARYEVENT | Subject |  |  | System.String | New Property
DIARYEVENT | Location |  |  | System.String | New Property
DIARYEVENT | UserName |  |  | System.String | New Property
DIARYEVENT | AccountType |  |  | SageDataObject150.DiaryEventAccountType | New Property
DIARYEVENT | Customer |  |  | System.Object | New Property
DIARYEVENT | Supplier |  |  | System.Object | New Property
DIARYEVENT | AccountContact |  |  | System.String | New Property
DIARYEVENT | Update |  |  | System.Boolean | New Method
DIARYEVENT | Delete |  |  | System.Boolean | New Method
DIARYEVENT | Load |  |  | System.Boolean | New Method
CONTACTDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
CONTACTDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
CONTACTDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
CONTACTDATA | MoveFirst |  |  | System.Boolean | New Method
CONTACTDATA | MoveLast |  |  | System.Boolean | New Method
CONTACTDATA | MoveNext |  |  | System.Boolean | New Method
CONTACTDATA | MovePrev |  |  | System.Boolean | New Method
CONTACTACCOUNTIDXRECORD | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
CONTACTACCOUNTIDXRECORD | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
CONTACTACCOUNTIDXRECORD | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
DIARYRECURRENCEPATTERNS | Count |  |  | System.Int32 | New Property
DIARYRECURRENCEPATTERNS | Item |  |  | SageDataObject150.DiaryRecurrencePattern | New Method
ACCESSDATA | INV_TMAIL | 1 | Yes | ByteType | Description changed from 'Invoicing - Transaction e-Mail' to 'Invoicing - Transaction Email'.
ACCESSDATA | POP_TMAIL | 1 | Yes | ByteType | Description changed from 'POP - Transaction e-Mail' to 'POP - Transaction Email'.
ACCESSDATA | RECORD_CREATE_DATE | 8 | Yes | DateType2 | New Field
ACCESSDATA | RECORD_DELETED | 2 | Yes | SmallIntegerType | New Field
ACCESSDATA | RECORD_MODIFY_DATE | 8 | Yes | DateType2 | New Field
ACCESSDATA | SOP_TMAIL | 1 | Yes | ByteType | Description changed from 'SOP - Transaction e-Mail' to 'SOP - Transaction Email'.
ACCESSDATA | MoveFirst |  |  | System.Boolean | New Method
ACCESSDATA | MoveLast |  |  | System.Boolean | New Method
ACCESSDATA | MoveNext |  |  | System.Boolean | New Method
ACCESSDATA | MovePrev |  |  | System.Boolean | New Method
WORKSPACE | CreateCompanyAddress |  |  | System.Object | New Method
WORKSPACE | CreateCompanyAddresses |  |  | System.Object | New Method
WORKSPACE | CreateCustomerAddress |  |  | System.Object | New Method
WORKSPACE | CreateCustomerAddresses |  |  | System.Object | New Method
WORKSPACE | CreateSupplierAddress |  |  | System.Object | New Method
WORKSPACE | CreateSupplierAddresses |  |  | System.Object | New Method
WORKSPACE | CreateDiaryEvent |  |  | System.Object | New Method
WORKSPACE | CreateDiaryEvents |  |  | System.Object | New Method
WORKSPACE | CreateDiaryEventLabel |  |  | System.Object | New Method
WORKSPACE | CreateDiaryEventLabels |  |  | System.Object | New Method
WORKSPACE | CreateDiaryRecurrencePattern |  |  | System.Object | New Method
WORKSPACE | CreateDiaryRecurrencePatterns |  |  | System.Object | New Method
WORKSPACE | CreateDocumentType |  |  | System.Object | New Method
WORKSPACE | CreateDocumentTypes |  |  | System.Object | New Method
WORKSPACE | CreateDocumentAddress |  |  | System.Object | New Method
WORKSPACE | CreateDocumentAddresses |  |  | System.Object | New Method
WORKSPACE | GetCurrentServerTime |  |  | System.DateTime | New Method
WORKSPACE | CreateMetaData |  |  | System.Object | New Method


Changes to the SDO for Sage 50 Accounts 2010

With each new release enhancements are made to the SDO to improve functionality and expose new fields.

New Items

Object
Name
Length
 Required Type Change
SDOEngine ObjectType.sdoBusinessObject
System.Enum New Enum Value
BANKHEADERDATA DEPOSIT_DATE
2
 No DateType1 New Field
BANKHEADERDATA DEPOSIT_FLAG
1
 No ByteType New Field
BANKHEADERDATA PROTX_REFN
40
 No StringType Description changed from 'Sage Payment Solutions Refn' to 'Sage Pay Reference'.
SALESDELIVERYDATA TELEPHONE_2
30
 No StringType New Field
GOODSNOTESRECORD ACCOUNT_REF
8
 Yes StringType New Field
GOODSNOTESRECORD GOODS_NO
4
 Yes IntegerType New Field
GOODSNOTESRECORD GRN_NEXT
4
 Yes IntegerType New Field
GOODSNOTESRECORD GRN_PREV
4
 Yes IntegerType New Field
GOODSNOTESRECORD ITEM_NO
4
 Yes IntegerType New Field
GOODSNOTESRECORD ORDER_NO
4
 Yes IntegerType New Field
GOODSNOTESRECORD POP_ITEM_NO
2
 Yes SmallIntegerType New Field
GOODSNOTESRECORD POSTED_DATE
2
 Yes DateType1 New Field
GOODSNOTESRECORD QTY_AMOUNT
8
 Yes DoubleType New Field
GOODSNOTESRECORD QTY_BALANCE
8
 Yes DoubleType New Field
GOODSNOTESRECORD QTY_ORDERED
8
 Yes DoubleType New Field
GOODSNOTESRECORD QTY_RECEIVED
8
 Yes DoubleType New Field
GOODSNOTESRECORD QTY_TO_DELIVER
8
 Yes DoubleType New Field
GOODSNOTESRECORD RECORD_CREATE_DATE
8
 No DateType2 New Field
GOODSNOTESRECORD RECORD_DELETED
2
 No SmallIntegerType New Field
GOODSNOTESRECORD RECORD_MODIFY_DATE
8
 No DateType2 New Field
GOODSNOTESRECORD STOCK_CODE
30
 Yes StringType New Field
GOODSNOTESRECORD STOCK_DESC
60
 No StringType New Field
GOODSNOTESRECORD SUPPLIER_GRN
20
 Yes StringType New Field
GOODSNOTESRECORD Fields
SageDataObject160.Fields New Property
GOODSNOTESRECORD Count
System.Int32 New Property
GOODSNOTESRECORD Memo
System.String New Property
GOODSNOTESRECORD RecordNumber
System.Int32 New Method
GOODSNOTESRECORD MoveFirst
System.Boolean New Method
GOODSNOTESRECORD MoveLast
System.Boolean New Method
GOODSNOTESRECORD MoveNext
System.Boolean New Method
GOODSNOTESRECORD MovePrev
System.Boolean New Method
GOODSNOTESRECORD Update
System.Boolean New Method
GOODSNOTESRECORD AddNew
System.Boolean New Method
GOODSNOTESRECORD Find
System.Boolean New Method
GOODSNOTESRECORD Remove
System.Boolean New Method
GOODSNOTESRECORD Move
System.Boolean New Method
GOODSNOTESRECORD Edit
System.Boolean New Method
GOODSNOTESRECORD CancelUpdate
System.Boolean New Method
COMPANYDELIVERYDATA TELEPHONE_2
30
 No StringType New Field
SPLITDATA DEPOSIT_DATE
2
 No DateType1 New Field
SPLITDATA DEPOSIT_FLAG
1
 No ByteType New Field
COMPANYDELIVERYRECORD TELEPHONE_2
30
 No StringType New Field
INVOICE CustomerReference
System.String New Property
INVOICE CarriageNet
System.Double New Property
INVOICE CarriageTax
System.Double New Property
INVOICE CarriageGross
System.Double New Property
INVOICE CarriageTaxCode
System.Int16 New Property
INVOICE DiscountAmount
System.Double New Property
INVOICE DiscountPercent
System.Double New Property
INVOICE SettlementDiscountAmount
System.Double New Property
INVOICE SettlementDiscountPercent
System.Double New Property
INVOICE NetTotal
System.Double New Property
INVOICE DiscountTotal
System.Double New Property
INVOICE TaxTotal
System.Double New Property
INVOICE GrossTotal
System.Double New Property
INVOICE CostTotal
System.Double New Property
INVOICE ProfitTotal
System.Double New Property
INVOICE Recalculate
System.Double New Method
INVOICE AddItem
SageDataObject160.InvoiceLine New Method
BANKRECORD ACCOUNT_TYPE
60
 No StringType Description changed from 'Account type' to 'Bank Account Type'.
BANKRECORD ACCOUNT_TYPE
60
 No StringType Length changed from '1' to '60'.
BANKRECORD ACCOUNT_TYPE
60
 No StringType Type changed from 'ByteType' to 'StringType'.
BANKRECORD LAST_REC_BALANCE
8
 No DoubleType New Field
BANKRECORD LAST_REC_DATE
2
 No DateType1 New Field
INVOICES Count
System.Int32 New Property
INVOICES Item
SageDataObject160.Invoice New Method
INVOICELINE StockCode
System.String New Property
INVOICELINE ActualUnitPrice
System.Double New Property
INVOICELINE ChargesTotal
System.Double New Property
INVOICELINE CostTotal
System.Double New Property
INVOICELINE DiscountAmount
System.Double New Property
INVOICELINE DiscountPercent
System.Double New Property
INVOICELINE DiscountTotal
System.Double New Property
INVOICELINE GrossTotal
System.Double New Property
INVOICELINE ListUnitPrice
System.Double New Property
INVOICELINE NetTotal
System.Double New Property
INVOICELINE PriceTax
System.Double New Property
INVOICELINE ProfitTotal
System.Double New Property
INVOICELINE TaxTotal
System.Double New Property
SALESDELIVERYRECORD TELEPHONE_2
30
 No StringType New Field
PURCHASEDELIVERYRECORD TELEPHONE_2
30
 No StringType New Field
DISPUTEDREASON DisputeReasonID
System.Int32 New Property
DISPUTEDREASON Name
System.String New Property
DISPUTEDREASON Load
System.Boolean New Method
STOCKDATA PRODUCT_BARCODE
60
 No StringType New Field
STOCKDATA RecordNumber
System.Int32 New Method
HEADERDATA DEPOSIT_DATE
2
 No DateType1 New Field
HEADERDATA DEPOSIT_FLAG
1
 No ByteType New Field
HEADERDATA PROTX_REFN
40
 No StringType Description changed from 'Sage Payment Solutions Refn' to 'Sage Pay Reference'.
SETUPDATA CASH_REGISTER_BANK
8
 No StringType New Field
SETUPDATA CASH_REGISTER_DISCREPENCIES_NOM
8
 No StringType New Field
SETUPDATA CASH_REGISTER_SALES_NOM
8
 No StringType New Field
SETUPDATA CASH_REGISTER_TAX_INCLUSIVE_FLAG
1
 No ByteType New Field
SETUPDATA CASH_REGISTER_TAXCODE
2
 No SmallIntegerType New Field
SETUPDATA COMPANYID
36
 Yes StringType New Field
PURCHASEDELIVERYDATA TELEPHONE_2
30
 No StringType New Field
STOCKRECORD PRODUCT_BARCODE
60
 No StringType New Field
BANKDATA ACCOUNT_TYPE
60
 No StringType Description changed from 'Account type' to 'Bank Account Type'.
BANKDATA ACCOUNT_TYPE
60
 No StringType Length changed from '1' to '60'.
BANKDATA ACCOUNT_TYPE
60
 No StringType Type changed from 'ByteType' to 'StringType'.
BANKDATA LAST_REC_BALANCE
8
 No DoubleType New Field
BANKDATA LAST_REC_DATE
2
 No DateType1 New Field
PROJECT CommittedCost
System.Double New Property
ACCESSDATA BANK_CASHREGISTER
1
 No ByteType New Field
ACCESSDATA BANK_DEPOSITCASH
1
 No ByteType New Field
WORKSPACE CreateInvoices
System.Object New Method
WORKSPACE CreateInvoice
System.Object New Method
WORKSPACE CreateInvoiceLine
System.Object New Method


Changes to the SDO for Sage 50 Accounts 2011

With each new release enhancements are made to the SDO to improve functionality and expose new fields.

New Items

Object Name
Length
 Required Type Change
SDOEngine FileType.sdoGDNData
System.Enum New Enum Value
SDOEngine FileType.sdoGDNData
System.Enum New Enum Value
SDOEngine FileType.sdoGDNIndex
System.Enum New Enum Value
SALESDATA RecordNumber
System.Int32 New Method
RECURRINGDATA RecordNumber
System.Int32 New Method
POPDATA RecordNumber
System.Int32 New Method
DEPARTMENTDATA RecordNumber
System.Int32 New Method
ACCRUALDATA RecordNumber
System.Int32 New Method
SALESDELIVERYDATA RecordNumber
System.Int32 New Method
COMPANYDELIVERYDATA RecordNumber
System.Int32 New Method
SOPDATA RecordNumber
System.Int32 New Method
GDNRECORD ACCOUNT_REF
8
 Yes StringType New Field
GDNRECORD CUSTOMER_GDN
20
 Yes StringType New Field
GDNRECORD GOODS_NO
4
 Yes IntegerType New Field
GDNRECORD GRN_NEXT
4
 Yes IntegerType New Field
GDNRECORD GRN_PREV
4
 Yes IntegerType New Field
GDNRECORD ITEM_NO
4
 Yes IntegerType New Field
GDNRECORD ORDER_NO
4
 Yes IntegerType New Field
GDNRECORD POSTED_DATE
2
 Yes DateType1 New Field
GDNRECORD QTY_AMOUNT
8
 Yes DoubleType New Field
GDNRECORD QTY_BALANCE
8
 Yes DoubleType New Field
GDNRECORD QTY_ORDERED
8
 Yes DoubleType New Field
GDNRECORD QTY_RECEIVED
8
 Yes DoubleType New Field
GDNRECORD QTY_TO_DELIVER
8
 Yes DoubleType New Field
GDNRECORD RECORD_CREATE_DATE
8
 No DateType2 New Field
GDNRECORD RECORD_DELETED
2
 No SmallIntegerType New Field
GDNRECORD RECORD_MODIFY_DATE
8
 No DateType2 New Field
GDNRECORD SOP_ITEM_NO
2
 Yes SmallIntegerType New Field
GDNRECORD STOCK_CODE
30
 Yes StringType New Field
GDNRECORD STOCK_DESC
60
 No StringType New Field
GDNRECORD Fields
SageDataObject300.Fields New Property
GDNRECORD Count
System.Int32 New Property
GDNRECORD Memo
System.String New Property
GDNRECORD RecordNumber
System.Int32 New Method
GDNRECORD MoveFirst
System.Boolean New Method
GDNRECORD MoveLast
System.Boolean New Method
GDNRECORD MoveNext
System.Boolean New Method
GDNRECORD MovePrev
System.Boolean New Method
GDNRECORD Update
System.Boolean New Method
GDNRECORD AddNew
System.Boolean New Method
GDNRECORD Find
System.Boolean New Method
GDNRECORD Remove
System.Boolean New Method
GDNRECORD Move
System.Boolean New Method
GDNRECORD Edit
System.Boolean New Method
GDNRECORD CancelUpdate
System.Boolean New Method
INVOICE DiscountType
System.SByte New Property
GDNDATA ACCOUNT_REF
8
 Yes StringType New Field
GDNDATA CUSTOMER_GDN
20
 Yes StringType New Field
GDNDATA GOODS_NO
4
 Yes IntegerType New Field
GDNDATA GRN_NEXT
4
 Yes IntegerType New Field
GDNDATA GRN_PREV
4
 Yes IntegerType New Field
GDNDATA ITEM_NO
4
 Yes IntegerType New Field
GDNDATA ORDER_NO
4
 Yes IntegerType New Field
GDNDATA POSTED_DATE
2
 Yes DateType1 New Field
GDNDATA QTY_AMOUNT
8
 Yes DoubleType New Field
GDNDATA QTY_BALANCE
8
 Yes DoubleType New Field
GDNDATA QTY_ORDERED
8
 Yes DoubleType New Field
GDNDATA QTY_RECEIVED
8
 Yes DoubleType New Field
GDNDATA QTY_TO_DELIVER
8
 Yes DoubleType New Field
GDNDATA RECORD_CREATE_DATE
8
 No DateType2 New Field
GDNDATA RECORD_DELETED
2
 No SmallIntegerType New Field
GDNDATA RECORD_MODIFY_DATE
8
 No DateType2 New Field
GDNDATA SOP_ITEM_NO
2
 Yes SmallIntegerType New Field
GDNDATA STOCK_CODE
30
 Yes StringType New Field
GDNDATA STOCK_DESC
60
 No StringType New Field
GDNDATA FileType
SageDataObject300.FileType New Property
GDNDATA Fields
SageDataObject300.Fields New Property
GDNDATA Read
System.Boolean New Method
GDNDATA Write
System.Boolean New Method
GDNDATA Seek
System.Boolean New Method
GDNDATA Count
System.Int32 New Method
GDNDATA Lock
System.Boolean New Method
GDNDATA Unlock
System.Boolean New Method
GDNDATA Open
System.Boolean New Method
GDNDATA Close
System.Void New Method
GDNDATA FindFirst
System.Boolean New Method
GDNDATA FindNext
System.Boolean New Method
GDNDATA MoveFirst
System.Boolean New Method
GDNDATA MoveLast
System.Boolean New Method
GDNDATA MoveNext
System.Boolean New Method
GDNDATA MovePrev
System.Boolean New Method
GDNDATA RecordNumber
System.Int32 New Method
BANKRECORD ACCOUNT_TYPE
1
 No ByteType Description changed from 'Bank Account Type' to 'Account type'.
BANKRECORD ACCOUNT_TYPE
1
 No ByteType Length changed from '60' to '1'.
BANKRECORD ACCOUNT_TYPE
1
 No ByteType Type changed from 'StringType' to 'ByteType'.
BILLDATA RecordNumber
System.Int32 New Method
INVOICELINE StockDiscountPercent
System.Double New Property
CREDITCHARGEDATA RecordNumber
System.Int32 New Method
GDNINDEX RECORD_NUMBER
4
 Yes IntegerType New Field
GDNINDEX REFERENCE
23
 Yes StringType New Field
GDNINDEX Key
System.String New Property
GDNINDEX DataRecordNumber
System.Int32 New Property
GDNINDEX IndexRecordNumber
System.Int32 New Property
GDNINDEX FileType
SageDataObject300.FileType New Property
GDNINDEX Fields
SageDataObject300.Fields New Property
GDNINDEX Count
System.Int32 New Method
GDNINDEX Lock
System.Boolean New Method
GDNINDEX Unlock
System.Boolean New Method
GDNINDEX Open
System.Boolean New Method
GDNINDEX Close
System.Void New Method
GDNINDEX Add
System.Boolean New Method
GDNINDEX Remove
System.Boolean New Method
GDNINDEX Find
System.Boolean New Method
GDNINDEX MoveFirst
System.Boolean New Method
GDNINDEX MoveLast
System.Boolean New Method
GDNINDEX MoveNext
System.Boolean New Method
GDNINDEX MovePrev
System.Boolean New Method
GDNINDEX Move
System.Boolean New Method
GDNINDEX Read
System.Boolean New Method
GDNINDEX Write
System.Boolean New Method
GDNINDEX Seek
System.Boolean New Method
CONTROLDATA LAST_GDN
4
 Yes IntegerType New Field
ASSETDATA RecordNumber
System.Int32 New Method
QUEUEDATA RecordNumber
System.Int32 New Method
ACCOUNTSTATUSDATA RecordNumber
System.Int32 New Method
GOODSNOTESDATA FileType
SageDataObject300.FileType New Property
GOODSNOTESDATA Read
System.Boolean New Method
GOODSNOTESDATA Write
System.Boolean New Method
GOODSNOTESDATA Seek
System.Boolean New Method
GOODSNOTESDATA Count
System.Int32 New Method
GOODSNOTESDATA Lock
System.Boolean New Method
GOODSNOTESDATA Unlock
System.Boolean New Method
GOODSNOTESDATA Open
System.Boolean New Method
GOODSNOTESDATA Close
System.Void New Method
GOODSNOTESDATA FindFirst
System.Boolean New Method
GOODSNOTESDATA FindNext
System.Boolean New Method
CURRENCYDATA RecordNumber
System.Int32 New Method
CREDITWWWDATA RecordNumber
System.Int32 New Method
CHARTDATA RecordNumber
System.Int32 New Method
CATEGORY RecordNumber
System.Int32 New Method
TODODATA RecordNumber
System.Int32 New Method
SETUPDATA FLAT_RATE_VAT_PERCENT
8
 No DoubleType New Field
SETUPDATA VAT_SCHEME_FLAG
1
 No ByteType New Field
SETUPDATA FindFirst
System.Boolean New Method
SETUPDATA FindNext
System.Boolean New Method
SETUPDATA MoveFirst
System.Boolean New Method
SETUPDATA MoveLast
System.Boolean New Method
SETUPDATA MoveNext
System.Boolean New Method
SETUPDATA MovePrev
System.Boolean New Method
SETUPDATA RecordNumber
System.Int32 New Method
PURCHASEDELIVERYDATA RecordNumber
System.Int32 New Method
COUNTRYCODEDATA RecordNumber
System.Int32 New Method
PURCHASEDATA RecordNumber
System.Int32 New Method
MISCWWWDATA RecordNumber
System.Int32 New Method
INVOICEDATA RecordNumber
System.Int32 New Method
BANKDATA ACCOUNT_TYPE
1
 No ByteType Description changed from 'Bank Account Type' to 'Account type'.
BANKDATA ACCOUNT_TYPE
1
 No ByteType Length changed from '60' to '1'.
BANKDATA ACCOUNT_TYPE
1
 No ByteType Type changed from 'StringType' to 'ByteType'.
BANKDATA RecordNumber
System.Int32 New Method
PRICELISTDATA RecordNumber
System.Int32 New Method
COURIERWWWDATA RecordNumber
System.Int32 New Method
BANKWWWDATA RecordNumber
System.Int32 New Method
STOCKCATEGORY RecordNumber
System.Int32 New Method
PRICEDATA RecordNumber
System.Int32 New Method
PREPAYDATA RecordNumber
System.Int32 New Method
CONTACTDATA RecordNumber
System.Int32 New Method
ACCESSDATA RecordNumber
System.Int32 New Method


Changes to the SDO for Sage 50 Accounts 2011

What's New in Sage Data Objects for Sage 50 Accounts 2012?

Compatibility Update

This release of the SDK is a compatibility update for Sage 50 Accounts 2012.

As you'd expect, code examples are provided to demonstrate how to upgrade your current applications and take advantage of the SDK's functionality. Please let us know if you'd like to see more.

New\Changed Methods, Fields and Properties

Object | Name | Description | Type | Change
ACCESSDATA | SETT_LOCK_DATE | Settings Menu - Lock Date | Byte | Field Change
BANKHEADERDATA | ISP_REFERENCE | Inv/Sop/Pop Reference. Additional field | Integer | Field Change
BANKHEADERDATA | OVERRIDDEN_CLOSED_LEDGER_DATE | The closed ledger date that was overridden at the time of posting. Additional field | Date | Field Change
COUNTRYCODEDATA | VAT_FORMAT_2 | Field now removed | String | Field Change
COUNTRYCODEDATA | VAT_FORMAT_3 | Field now removed | String | Field Change
COUNTRYCODEDATA | VAT_FORMAT_4 | Field now removed | String | Field Change
COUNTRYCODEDATA | VAT_FORMAT_5 | Field now removed | String | Field Change
COUNTRYCODERECORD | VAT_FORMAT_1 | Field now removed | String | Field Change
COUNTRYCODERECORD | VAT_FORMAT_2 | Field now removed | String | Field Change
COUNTRYCODERECORD | VAT_FORMAT_3 | Field now removed | String | Field Change
COUNTRYCODERECORD | VAT_FORMAT_4 | Field now removed | String | Field Change
COUNTRYCODERECORD | VAT_FORMAT_5 | Field now removed | String | Field Change
HEADERDATA | ISP_REFERENCE | Inv/Sop/Pop Reference. Additional field | Integer | Field Change
HEADERDATA | OVERRIDDEN_CLOSED_LEDGER_DATE | The closed ledger date that was overridden at the time of posting. Additional field | Date | Field Change
INVOICEDATA | EMAILED | Email flag - Yes/No. Additional field | Byte | Field Change
INVOICERECORD | EMAILED | Email flag - Yes/No. Additional field | Byte | Field Change
INVOICEPOST | Update | Wraps business logic to add Net value discounts and deal with rounding. Method | Boolean | Method Changes
POPPOST | EMAILED | Emailed flag - Yes/No. Additional field | Byte | Field Change
POPDATA | EMAILED | Email flag - Yes/No. Additional field | Byte | Field Change
POPRECORD | EMAILED | Email flag - Yes/No. Additional field | Byte | Field Change
PURCHASEDATA | ACCOUNT_TYPE_CUSTOMER | Field now removed | Small Integer | Field Change
PURCHASEDATA | ACCOUNT_TYPE_DONOR | Field now removed | Small Integer | Field Change
PURCHASEDATA | ACCOUNT_TYPE_MEMBER | Field now removed | Small Integer | Field Change
PURCHASEDATA | PRIORITY_SUPPLIER | Field now removed | Small Integer | Field Change
PURCHASEDATA | PRIORITY_TRADER | Priority Supplier. Additional field | Small Integer | Field Change
PURCHASEDATA | RECEIPT_BF | Receipts brought forward. Additional field | Double | Field Change
PURCHASEDATA | RECEIPT_CF | Receipts carry forward. Additional field | Double | Field Change
PURCHASEDATA | RECEIPT_MTH1 | Receipts Month 1. Additional field | Double | Field Change
PURCHASEDATA | RECEIPT_MTH2 | Receipts Month 2. Additional field | Double | Field Change
PURCHASEDATA | RECEIPT_MTH3 | Receipts Month 3. Additional field | Double | Field Change
PURCHASEDATA | RECEIPT_MTH4 | Receipts Month 4. Additional field | Double | Field Change
PURCHASEDATA | RECEIPT_MTH5 | Receipts Month 5. Additional field | Double | Field Change
PURCHASEDATA | RECEIPT_MTH6 | Receipts Month 6. Additional field | Double | Field Change
PURCHASEDATA | RECEIPT_MTH7 | Receipts Month 7. Additional field | Double | Field Change
PURCHASEDATA | RECEIPT_MTH8 | Receipts Month 8. Additional field | Double | Field Change
PURCHASEDATA | RECEIPT_MTH9 | Receipts Month 9. Additional field | Double | Field Change
PURCHASEDATA | RECEIPT_MTH10 | Receipts Month 10. Additional field | Double | Field Change
PURCHASEDATA | RECEIPT_MTH11 | Receipts Month 11. Additional field | Double | Field Change
PURCHASEDATA | RECEIPT_MTH12 | Receipts Month 12. Additional field | Double | Field Change
PURCHASERECORD | ACCOUNT_TYPE_CUSTOMER | Field now removed | Small Integer | Field Change
PURCHASERECORD | ACCOUNT_TYPE_DONOR | Field now removed | Small Integer | Field Change
PURCHASERECORD | ACCOUNT_TYPE_MEMBER | Field now removed | Small Integer | Field Change
PURCHASERECORD | PRIORITY_SUPPLIER | Field now removed | Small Integer | Field Change
PURCHASERECORD | PRIORITY_TRADER | Priority Supplier | Small Integer | Field Change
PURCHASERECORD | RECEIPT_BF | Receipts brought forward. Additional field | Double | Field Change
PURCHASERECORD | RECEIPT_CF | Receipts carry forward. Additional field | Double | Field Change
PURCHASERECORD | RECEIPT_MTH1 | Receipts Month 1. Additional field | Double | Field Change
PURCHASERECORD | RECEIPT_MTH2 | Receipts Month 2. Additional field | Double | Field Change
PURCHASERECORD | RECEIPT_MTH3 | Receipts Month 3. Additional field | Double | Field Change
PURCHASERECORD | RECEIPT_MTH4 | Receipts Month 4. Additional field | Double | Field Change
PURCHASERECORD | RECEIPT_MTH5 | Receipts Month 5. Additional field | Double | Field Change
PURCHASERECORD | RECEIPT_MTH6 | Receipts Month 6. Additional field | Double | Field Change
PURCHASERECORD | RECEIPT_MTH7 | Receipts Month 7. Additional field | Double | Field Change
PURCHASERECORD | RECEIPT_MTH8 | Receipts Month 8. Additional field | Double | Field Change
PURCHASERECORD | RECEIPT_MTH9 | Receipts Month 9. Additional field | Double | Field Change
PURCHASERECORD | RECEIPT_MTH10 | Receipts Month 10. Additional field | Double | Field Change
PURCHASERECORD | RECEIPT_MTH11 | Receipts Month 11. Additional field | Double | Field Change
PURCHASERECORD | RECEIPT_MTH12 | Receipts Month 12. Additional field | Double | Field Change
PURCHASERECORD | EMAILED | Email flag - Yes/No. Additional field | Byte | Field Change
POPPOST | Update | Wraps business logic to add Net value discounts and deal with rounding. Method | Boolean | Method Changes
SETUPDATA | CLOSED_LEDGER_CHECK_DATE | The date which a transaction being posted is validated against. Field | Date | Field Change
SETUPDATA | CLOSED_LEDGER_DATE_CONTROL_ENABLED | Flag indicating if closed ledger control is currently enforced. Field | Byte | Field Change
SETUPDATA | IsDateValidForLockDate | Method that returns sdoLockDate type informing if the transaction will post successfully | Date | Additional Method
SALESDATA | ACCOUNT_TYPE_CUSTOMER | Field now removed | Small Integer | Field Change
SALESDATA | ACCOUNT_TYPE_DONOR | Field now removed | Small Integer | Field Change
SALESDATA | ACCOUNT_TYPE_MEMBER | Field now removed | Small Integer | Field Change
SALESDATA | PRIORITY_SUPPLIER | Field now removed | Small Integer | Field Change
SALESDATA | PRIORITY_TRADER | Priority Supplier. Additional Field | Small Integer | Field Change
SALESDATA | RECEIPT_BF | Receipts brought forward. Additional Field | Double | Field Change
SALESDATA | RECEIPT_CF | Receipts carry forward. Additional Field | Double | Field Change
SALESDATA | RECEIPT_MTH1 | Receipts Month 1. Additional Field | Double | Field Change
SALESDATA | RECEIPT_MTH2 | Receipts Month 2. Additional Field | Double | Field Change
SALESDATA | RECEIPT_MTH3 | Receipts Month 3. Additional Field | Double | Field Change
SALESDATA | RECEIPT_MTH4 | Receipts Month 4. Additional Field | Double | Field Change
SALESDATA | RECEIPT_MTH5 | Receipts Month 5. Additional Field | Double | Field Change
SALESDATA | RECEIPT_MTH6 | Receipts Month 6. Additional Field | Double | Field Change
SALESDATA | RECEIPT_MTH7 | Receipts Month 7. Additional Field | Double | Field Change
SALESDATA | RECEIPT_MTH8 | Receipts Month 8. Additional Field | Double | Field Change
SALESDATA | RECEIPT_MTH9 | Receipts Month 9. Additional Field | Double | Field Change
SALESDATA | RECEIPT_MTH10 | Receipts Month 10. Additional Field | Double | Field Change
SALESDATA | RECEIPT_MTH11 | Receipts Month 11. Additional Field | Double | Field Change
SALESDATA | RECEIPT_MTH12 | Receipts Month 12. Additional Field | Double | Field Change
SALESRECORD | ACCOUNT_TYPE_CUSTOMER | Field now removed | Small Integer | Field Change
SALESRECORD | ACCOUNT_TYPE_DONOR | Field now removed | Small Integer | Field Change
SALESRECORD | ACCOUNT_TYPE_MEMBER | Field now removed | Small Integer | Field Change
SALESRECORD | PRIORITY_SUPPLIER | Field now removed | Small Integer | Field Change
SALESRECORD | PRIORITY_TRADER | Priority Supplier. Additional Field | Small Integer | Field Change
SALESRECORD | RECEIPT_BF | Receipts brought forward. Additional Field | Double | Field Change
SALESRECORD | RECEIPT_CF | Receipts carry forward. Additional Field | Double | Field Change
SALESRECORD | RECEIPT_MTH1 | Receipts Month 1. Additional Field | Double | Field Change
SALESRECORD | RECEIPT_MTH2 | Receipts Month 2. Additional Field | Double | Field Change
SALESRECORD | RECEIPT_MTH3 | Receipts Month 3. Additional Field | Double | Field Change
SALESRECORD | RECEIPT_MTH4 | Receipts Month 4. Additional Field | Double | Field Change
SALESRECORD | RECEIPT_MTH5 | Receipts Month 5. Additional Field | Double | Field Change
SALESRECORD | RECEIPT_MTH6 | Receipts Month 6. Additional Field | Double | Field Change
SALESRECORD | RECEIPT_MTH7 | Receipts Month 7. Additional Field | Double | Field Change
SALESRECORD | RECEIPT_MTH8 | Receipts Month 8. Additional Field | Double | Field Change
SALESRECORD | RECEIPT_MTH9 | Receipts Month 9. Additional Field | Double | Field Change
SALESRECORD | RECEIPT_MTH10 | Receipts Month 10. Additional Field | Double | Field Change
SALESRECORD | RECEIPT_MTH11 | Receipts Month 11. Additional Field | Double | Field Change
SALESRECORD | RECEIPT_MTH12 | Receipts Month 12. Additional Field | Double | Field Change
SOPDATA | Emailed | Emailed flag - Yes/No. Additional Field | Byte | Field Change
SOPRECORD | Emailed | Emailed flag - Yes/No. Additional Field | Byte | Field Change
SOPPOST | Emailed | Emailed flag - Yes/No. Additional Field | Byte | Field Change
SOPPOST | Update | Wraps business logic to add Net value discounts and deal with rounding. Method | Boolean | Method Changes
SPLITDATA | INTERNAL_REF | Extra reference. Reduced length was 60 chars now 30 chars. | String | Field Change

Changes to existing Methods, Fields and Properties

The ISP Post objects Update method now wraps business logic to apportion the net value discount appropriately across the individual item lines. You now only need to set the relevant fields on the InvoicePost or SopPost Header, a more in depth overview of the changes and effects to the ISP Post Object can be found in the ISP Post Considerations page.

In addition the update method will throw an exception in the event update is called when the workspace is not connected.

Sage 50 Accounts now has the ability to Close Ledgers for periods, this now means that if a user does not have the appropriate access rights they will not be able to post a Transaction using the TransactionPost method if the period has been closed.

SetupData has two new methods that allow you to check if the date and user have permission to post the transaction.

TransactionPost.Update has additional validation that will not allow negative values to be posted to the ledgers or allow certain transaction types (SI for example) to be posted to a Bank account.

Resolved Issues

Last user added to company is used for all posting of sales invoices rather than current user.

  • The SDO now uses the current user when posting.

TransactionPost.Update() posts one-sided journal where Bank nominal code or major control account is supplied on an invoice.

  • The SDO TransactionPost.Update method will now return false if a Bank Account is selected.

SDO - StockAllocation.Issue method sets incorrect year on Date field.

  • StockAllocation.Issue method now sets the correct year on Date field.

Application object returns no values for POP and SOP dialogs.

  • Application object nowreturns values for POP and SOP dialogs.
Chart data SDO object GetChart method throws exception oChartdata.GetChart(1)
  • GetChart method no longer throws an exception.


Changes to the SDO for Sage 50 Accounts 2011

Changes to the SDO for Sage 50 Accounts 2013

Compatibility Update

This release of the SDK is a compatibility update for Sage 50 Accounts 2013.

As you'd expect, code examples are provided to demonstrate how to upgrade your current applications and take advantage of the SDK's functionality. Please let us know if you'd like to see more.

New\Changed Methods, Fields and Properties

Object | Name | Description | Type | Change
SALESDATA | DONOR_FORENAME |  | String | New Field
SALESDATA | DONOR_SURNAME |  | String | New Field
SALESDATA | DONOR_TITLE |  | String | New Field
SALESRECORD | DONOR_FORENAME |  | String | New Field
SALESRECORD | DONOR_SURNAME |  | String | New Field
SALESRECORD | DONOR_TITLE |  | String | New Field
SPLITDATA | GASDS_CLAIM_SUBMITTED |  | Small Integer | New Field
SPLITDATA | GIFT_AID |  | Small Integer | New Field
SPLITDATA | SMALL_DONATION |  | Small Integer | New Field

New\Changed Constants

Constant | Name | Description | Type | Change
STOCKPOST | StockTransArtefactType | New Constant Sets the value on a GO Stock Tran | Small Integer | Constant Change
STOCKTRAN | StockTransArtefactType | New Constant Sets the value on a GO Stock Tran | Small Integer | Constant Change

Changes to existing Methods, Fields and Properties

Changes to the core product Stock Transaction activity have necessitated a new hidden field to hold an Integer value for a Goods Out(GO) transaction. This field now determines where the stock transaction originates from being either an Invoice or a SOP. The initial release of the 2013 SDO (20.0.11.260) does not set a value and the StockPost.Update method will return false. Later builds of the SDO dll will set a default value of 1(Invoice) if the StockTransArtefactType field is not set. This means that if the Sage 50 Accounts user then tries to use the drill around functionality the program will automatically look the invoice number up with the corresponding value. A new code example has been created to show how the field can be set.

Resolved Issues

SDO ISP Post objects set the first item number to 1. Is set to 0 via the GUI.

  • The SDO ISP Post objects now set the first Item Number to 0 inline with the GUI.

GetCompanies method unable to enumerate collection.

  • The SDO now allows the company list to be iterated.

NominRecord\SalesRecord\PurchaseRecord objects update method allows the creation of a new Record without an ACCOUNT_REF.

  • The SDO will now return false if you try and create a Nominal\Sales\Purchase record without setting the ACCOUNT_REF.

SDO AccessData object no longer exposes CUST_RECEIPT.

  • AccessData now exposes the CUST_RECEIPT .


What's New in Sage Data Objects 2008

What's New in Sage Data Objects for Sage 50 Accounts 2014?

Compatibility Update

This release of the SDK is a compatibility update for Sage 50 Accounts 2014.

As you'd expect, code examples are provided to demonstrate how to upgrade your current applications and take advantage of the SDK's functionality. Please let us know if you'd like to see more.

New\Changed Methods, Fields and Properties

Object | Name | Description | Type | Change
ACCESSDATA | TOOLS_END_ARCHIVE | Tools->Period End Menu - Archive Company | Byte Type | New Field
BANKDATA | BANK_BICSWIFT | Bank BIC/Swift | String | New Field
BANKDATA | BANK_IBAN | Bank IBAN | String | New Field
BANKRECORD | BANK_BICSWIFT | Bank BIC/Swift | String | New Field
BANKRECORD | BANK_IBAN | Bank IBAN | String | New Field
INVOICEDATA | GDN_NUMBER | GDN Reference | Small Integer | New Field
INVOICERECORD | GDN_NUMBER | GDN Reference | Small Integer | New Field
POPRECORD | GDN_NUMBER | GDN Reference | Integer Type | New Field
POPRECORD | INTRASTAT_STATUS | Intrastat Reconciled Status | Byte Type | Description changed from Quantity IntraStat Confirmed to Quantity Intrastat Confirmed
POPITEM | QTY_INTRASTAT_CONFIRMED | Quantity Intrastat Confirmed | Double | Description changed from Quantity IntraStat Confirmed to Quantity Intrastat Confirmed
PURCHASEDATA | VAT_REG_NUMBER | VAT Registration Number | String | Field length change Was 30 now 20.
PURCHASERECORD | VAT_REG_NUMBER | VAT Registration Number | String | Field length change Was 30 now 20.
SALESDATA | DONOR_FORENAME | Donor Forename | String | New Field
SALESDATA | DONOR_SURNAME | Donor Surname | String | New Field
SALESDATA | DONOR_TITLE | Donor Title | String | New Field
SALESDATA | VAT_REG_NUMBER | VAT Registration Number | String | Field length change Was 30 now 20.
SALESRECORD | DONOR_FORENAME | Donor Forename | String | New Field
SALESRECORD | DONOR_SURNAME | Donor Surname | String | New Field
SALESRECORD | DONOR_TITLE | Donor Title | String | New Field
SALESRECORD | VAT_REG_NUMBER | VAT Registration Number | String | Field length change Was 30 now 20.
SETUPDATA | VAT_REG_NUMBER | VAT Registration Number | String | Field length change Was 30 now 20.
SPLITDATA | GASDS_CLAIM_SUBMITTED | GASDS Claim Submitted | Small Integer | New Field
SPLITDATA | GIFT_AID | Gift Aid status | Small Integer | New Field
SPLITDATA | SMALL_DONATION | Small Donations | Small Integer | New Field
STOCKTDATA | INTRASTAT_COMMODITY_CODE | Intrastat Import Duty code | String | New Field
STOCKTDATA | INTRASTAT_IMPORT_DUTY_CODE | Intrastat Import Duty code | String | New Field
STOCKTDATA | SUPP_UNIT_QTY | Supplementary Unit Quantity | Double | New Field
STOCKTRECORD | INTRASTAT_COMMODITY_CODE | Intrastat Import Duty code | String | New Field
STOCKTRECORD | INTRASTAT_IMPORT_DUTY_CODE | Intrastat Import Duty code | String | New Field
STOCKTRECORD | SUPP_UNIT_QTY | Supplementary Unit Quantity | Double | New Field
STOCKTRAN | GDN_NUMBER | GDN Reference | Integer | New Field
STOCKTRAN | GRN_NUMBER | GRN Reference | Integer | New Field

Resolved Issues

Fund Balance out by - Error if SDO Datapath is all in lower case when posting a transaction with a fund number.

  • TransactionPost can now be used to post a transaction with a fund number to a data path in lower case .

ISP Item.Text free text field shows the previous items's .Text free text if it is blank.

  • ISP Item.Text free text field no longer shows the previous items's .Text free text if it is blank.

IsDeleted() method of POPItem object does not return a boolean.

  • IsDeleted() method of POPItem object now returns a boolean.

Intrastat import duty field is not exposed to the SDO.

  • Intrastat import duty field is now exposed via the SDO.

SDO InvoicePost method causes memory leak when posting large batches of invoices

  • The memory leak has now been fixed and it is recommended that the objects are instantiated and destroyed as per this example. The SDO helper class has also been improved to include these changes.


What's New in Sage Data Objects 2008

What's New in Sage Data Objects for Sage 50 Accounts 2015?

Compatibility Update

This release of the SDK is a compatibility update for Sage 50 Accounts 2015.

As you'd expect, code examples are provided to demonstrate how to upgrade your current applications and take advantage of the SDK's functionality. Please let us know if you'd like to see more.

This release sees some exciting changes and improvements to the Sage 50 Accounts proposition:
Freedom with online data – The product has the technical capability now to hold data in the “cloud” rather than desktop based meaning access can be gained from outside the office. Read more...
Live Accountant access – With your client’s data online, accountants (using Sage 50 Client Manager) can access client data instantly via the cloud, which is a large change for accountants.
Completely new navigation and design - The product has been redesigned to makes it easier for you and your customers to find the functions you need in half the time.
Scheduled, automated back-up - The product now provides peace of mind by automatically creating secure data backups.
Scalable for larger businesses – As your business grows, Sage 50 Accounts will grow with you by allowing up to 20 users and 1,500,000 transactions.
New mobile apps – the new version of the software will entitle the customer to use a mobile app which allows them to track their businesses key performance metrics.

Sage 50 Accounts 2015 sees an introduction to the use of interfaces bringing added functionality in the shape of methods to allocate Sales Orders and update invoices. A new JournalPost object now allows journals to be posted by declaring and populating only a single header and adding as many splits as required, the journal posts if the debits balance with the credits.

Architectural changes to Sage 50 Accounts 2015 see the introduction of a data service which runs server side. Although this is quite a large architectual change it does not require changes to your SDO application and deployment.

New\Changed Objects, Methods, Fields and Properties

Object | Name | Description | Type | Change
ACCESSDATA | BANK_ACTIVITY | Bank Activity | Byte Type | New Field
ACCESSDATA | BANK_CUST_RECEIPT | BANK_CUST_RECEIPT | Byte Type | New Field
ACCESSDATA | BANK_CUST_REFUND | BANK_CUST_REFUND | Byte Type | New Field
ACCESSDATA | BANK_DOWNLOAD_RECEIPT | BANK_DOWNLOAD_RECEIPT | Byte Type | New Field
ACCESSDATA | BANK_REMITTANCE | BANK_REMITTANCE | Byte Type | New Field
ACCESSDATA | BANK_SUPP_PAYMENT | BANK_SUPP_PAYMENT | Byte Type | New Field
ACCESSDATA | BANK_SUPP_REFUND | BANK_SUPP_REFUND | Byte Type | New Field
ACCESSDATA | CUST_BANKDETAILS | CUST_BANKDETAILS | Byte Type | New Field
ACCESSDATA | CUST_CHASEDEBT | CUST_CHASEDEBT | Byte Type | New Field
ACCESSDATA | CUST_COMMUNICATIONS | CUST_COMMUNICATIONS | Byte Type | New Field
ACCESSDATA | CUST_CONTRA_ENTRIES | CUST_CONTRA_ENTRIES | Byte Type | New Field
ACCESSDATA | CUST_PDF | CUST_PDF | Byte Type | New Field
ACCESSDATA | CUST_REFUNDS | CUST_REFUNDS | Byte Type | New Field
ACCESSDATA | DEPARTMENTS | DEPARTMENTS | Byte Type | New Field
ACCESSDATA | DEPARTMENTS_ACTIVITY | DEPARTMENTS_ACTIVITY | Byte Type | New Field
ACCESSDATA | DEPARTMENTS_EDIT | DEPARTMENTS_EDIT | Byte Type | New Field
ACCESSDATA | DEPARTMENTS_REPORTS | DEPARTMENTS_REPORTS | Byte Type | New Field
ACCESSDATA | DIARY | DIARY | Byte Type | New Field
ACCESSDATA | DIARY_COMPLETE | DIARY_COMPLETE | Byte Type | New Field
ACCESSDATA | DIARY_IMP_EXP | DIARY_IMP_EXP | Byte Type | New Field
ACCESSDATA | DIARY_RECORD | DIARY_RECORD | Byte Type | New Field
ACCESSDATA | DIARY_VIEW_EVENTS | DIARY_VIEW_EVENTS | Byte Type | New Field
ACCESSDATA | FUNDS | FUNDS | Byte Type | New Field
ACCESSDATA | FUNDS_ACTIVITY | FUNDS_ACTIVITY | Byte Type | New Field
ACCESSDATA | FUNDS_GASDS | FUNDS_GASDS | Byte Type | New Field
ACCESSDATA | FUNDS_GIFD_AID | FUNDS_GIFD_AID | Byte Type | New Field
ACCESSDATA | BANK_ACTIVITY | Bank Activity | Byte Type | New Field
ACCESSDATA | BANK_CUST_RECEIPT | BANK_CUST_RECEIPT | Byte Type | New Field
ACCESSDATA | BANK_CUST_REFUND | BANK_CUST_REFUND | Byte Type | New Field
ACCESSDATA | BANK_DOWNLOAD_RECEIPT | BANK_DOWNLOAD_RECEIPT | Byte Type | New Field
ACCESSDATA | BANK_REMITTANCE | BANK_REMITTANCE | Byte Type | New Field
ACCESSDATA | BANK_SUPP_PAYMENT | BANK_SUPP_PAYMENT | Byte Type | New Field
ACCESSDATA | BANK_SUPP_REFUND | BANK_SUPP_REFUND | Byte Type | New Field
ACCESSDATA | CUST_BANKDETAILS | CUST_BANKDETAILS | Byte Type | New Field
ACCESSDATA | CUST_CHASEDEBT | CUST_CHASEDEBT | Byte Type | New Field
ACCESSDATA | CUST_COMMUNICATIONS | CUST_COMMUNICATIONS | Byte Type | New Field
ACCESSDATA | CUST_CONTRA_ENTRIES | CUST_CONTRA_ENTRIES | Byte Type | New Field
ACCESSDATA | CUST_PDF | CUST_PDF | Byte Type | New Field
ACCESSDATA | CUST_REFUNDS | CUST_REFUNDS | Byte Type | New Field
ACCESSDATA | DEPARTMENTS | DEPARTMENTS | Byte Type | New Field
ACCESSDATA | DEPARTMENTS_ACTIVITY | DEPARTMENTS_ACTIVITY | Byte Type | New Field
ACCESSDATA | DEPARTMENTS_EDIT | DEPARTMENTS_EDIT | Byte Type | New Field
ACCESSDATA | DEPARTMENTS_REPORTS | DEPARTMENTS_REPORTS | Byte Type | New Field
ACCESSDATA | DIARY | DIARY | Byte Type | New Field
ACCESSDATA | DIARY_COMPLETE | DIARY_COMPLETE | Byte Type | New Field
ACCESSDATA | DIARY_IMP_EXP | DIARY_IMP_EXP | Byte Type | New Field
ACCESSDATA | DIARY_RECORD | DIARY_RECORD | Byte Type | New Field
ACCESSDATA | DIARY_VIEW_EVENTS | DIARY_VIEW_EVENTS | Byte Type | New Field
ACCESSDATA | FUNDS | FUNDS | Byte Type | New Field
ACCESSDATA | FUNDS_ACTIVITY | FUNDS_ACTIVITY | Byte Type | New Field
ACCESSDATA | FUNDS_GASDS | FUNDS_GASDS | Byte Type | New Field
ACCESSDATA | FUNDS_GIFD_AID | FUNDS_GIFD_AID | Byte Type | New Field
ACCESSDATA | FUNDS_NOMCODES | FUNDS_NOMCODES | Byte Type | New Field
ACCESSDATA | FUNDS_RECORD | FUNDS_RECORD | Byte Type | New Field
ACCESSDATA | FUNDS_REPORTS | FUNDS_REPORTS | Byte Type | New Field
ACCESSDATA | FUNDS_TRANSFER | FUNDS_TRANSFER | Byte Type | New Field
ACCESSDATA | HELP | HELP | Byte Type | New Field
ACCESSDATA | HELP_CUSTOMIZE | HELP_CUSTOMIZE | Byte Type | New Field
ACCESSDATA | NOM_ACTIVITY | NOM_ACTIVITY | Byte Type | New Field
ACCESSDATA | NOM_BUDGET | NOM_BUDGET | Byte Type | New Field
ACCESSDATA | NOM_COA | NOM_COA | Byte Type | New Field
ACCESSDATA | NOM_JOURNAL | NOM_JOURNAL | Byte Type | New Field
ACCESSDATA | NOM_QUICKRATIO | NOM_QUICKRATIO | Byte Type | New Field
ACCESSDATA | POP_INTRASTAT | POP_INTRASTAT | Byte Type | New Field
ACCESSDATA | QUOTATIONS | QUOTATIONS | Byte Type | New Field
ACCESSDATA | QUOTE_ALLOC_STOCk | QUOTE_ALLOC_STOCk | Byte Type | New Field
ACCESSDATA | QUOTE_AMEND_ALLOC | QUOTE_AMEND_ALLOC | Byte Type | New Field
ACCESSDATA | QUOTE_LOST | QUOTE_LOST | Byte Type | New Field
ACCESSDATA | QUOTE_OPEN | QUOTE_OPEN | Byte Type | New Field
ACCESSDATA | QUOTE_PRINT/MAIL | QUOTE_PRINT/MAIL | Byte Type | New Field
ACCESSDATA | QUOTE_PROFIT | QUOTE_PROFIT | Byte Type | New Field
ACCESSDATA | QUOTE_RECORD | QUOTE_RECORD | Byte Type | New Field
ACCESSDATA | DIARY_RECORD | DIARY_RECORD | Byte Type | New Field
ACCESSDATA | QUOTE_WON | QUOTE_WON | Byte Type | New Field
ACCESSDATA | SETT_COUNTRIES | SETT_COUNTRIES | Byte Type | New Field
ACCESSDATA | SETT_EMAIL_DEF | SETT_EMAIL_DEF | Byte Type | New Field
ACCESSDATA | SOP_INTRASTAT | SOP_INTRASTAT | Byte Type | New Field
ACCESSDATA | FUNDS_GIFD_AID | FUNDS_GIFD_AID | Byte Type | New Field
ACCESSDATA | SUPP_BANK_DETAILS | SUPP_BANK_DETAILS | Byte Type | New Field
ACCESSDATA | SUPP_CIS_LETTERS | SUPP_CIS_LETTERS | Byte Type | New Field
ACCESSDATA | SUPP_CIS_REPORTS | SUPP_CIS_REPORTS | Byte Type | New Field
ACCESSDATA | SUPP_CIS_RETURN | SUPP_CIS_RETURN | Byte Type | New Field
ACCESSDATA | SUPP_CIS_STATEMENTS | SUPP_CIS_STATEMENTS | Byte Type | New Field
ACCESSDATA | SUPP_CIS_VERIFY | SUPP_CIS_VERIFY | Byte Type | New Field
ACCESSDATA | SUPP_COMMUNICATIONS | SUPP_COMMUNICATIONS | Byte Type | New Field
ACCESSDATA | SUPP_CONTRA_ENTRIES | SUPP_CONTRA_ENTRIES | Byte Type | New Field
ACCESSDATA | SUPP_MANAGE_PAYMENT | SUPP_MANAGE_PAYMENT | Byte Type | New Field
ACCESSDATA | SUPP_PDF | SUPP_PDF | Byte Type | New Field
ACCESSDATA | SUPP_REFUND | SUPP_REFUND | Byte Type | New Field
ACCESSDATA | SUPP_SUBCONTRACTORS | SUPP_SUBCONTRACTORS | Byte Type | New Field
ACCESSDATA | VAT_RTD | VAT_RTD | Byte Type | New Field
ACCESSDATA | VAT_TAX_QUERIES | VAT_TAX_QUERIES | Byte Type | New Field
ACCESSDATA | VAT_VALUES | VAT_VALUES | Byte Type | New Field
ACCESSDATA | VAT_VERIF_REPORT | VAT_VERIF_REPORT | Byte Type | New Field
BANKDATA | BACS_REFERENCE | Bacs reference. | String Type | New Field
BANKRECORD | BACS_REFERENCE | Bacs reference. | String Type | New Field
ISopAllocate | ISopAllocate | New object for allocating stock to Sop Orders | SDORecord Object | New Object
ISopAllocate | AllocateAll | New method for allocating stock to Sop Orders | Returns a OrderStatusType | New Method
IUpdateLedgers | IUpdateLedgers | New object for updating Invoice Records to the ledgers | SDOPosting Object | New Object
IUpdateLedgers | Post | New method for updating Invoice Records to the ledgers | Returns a Boolean | New Method
JOURNALPOST | JOURNALPOST | New object for posting journal transactions | SDOPosting Object | New Object
JOURNALPOST | ACCOUNT_REF | Sales/Purchase/Bank Account Reference | String | New Field
JOURNALPOST | AMOUNT_PAID | Total amount paid | Double | New Field
JOURNALPOST | BANK_CODE | Bank Account Reference | String | New Field
JOURNALPOST | BANK_FLAG | Bank Reconciled Flag | Byte Type | New Field
JOURNALPOST | CURRENCY | Currency For Transaction | Byte Type | New Field
JOURNALPOST | CURRENCY_USED | Currency Used | Byte Type | New Field
JOURNALPOST | DATE | Transaction Date | Date Type | New Field
JOURNALPOST | DATE_DUE | Date Invoice Is Due For Payment | Date Type | Description changed from Quantity IntraStat Confirmed to Quantity Intrastat Confirmed
JOURNALPOST | DATE_FORECAST | Forecast Date | Date Type | Description changed from Quantity IntraStat Confirmed to Quantity Intrastat Confirmed
JOURNALPOST | DATE_LAST_CHARGE | Date Interest Last Charged | Date Type | Field length change Was 30 now 20.
JOURNALPOST | DELETED_FLAG | Transaction deleted flag | SmallIntegerType | Field length change Was 30 now 20.
JOURNALPOST | DEPOSIT_DATE | Bank deposited date | Date Type | New Field
JOURNALPOST | DEPOSIT_FLAG | Bank deposited flag | SmallIntegerType | New Field
JOURNALPOST | DETAILS | Details | String Type | New Field
JOURNALPOST | ELEC_TRANS | Electronic Transaction Flag | SmallIntegerType | Field length change Was 30 now 20.
JOURNALPOST | EURO_GROSS | euro Gross Amount | DoubleType | New Field
JOURNALPOST | EURO_RATE | euro Rate | DoubleType | New Field
JOURNALPOST | FINANCE_CHARGE | Finance Charge Flag | ByteType | New Field
JOURNALPOST | FIRST_SPLIT | Item Number | IntegerType | Field length change Was 30 now 20.
JOURNALPOST | FORECAST_INCLUDE | Included in Forecast | DateType | Field length change Was 30 now 20.
JOURNALPOST | FOREIGN_AMOUNT_PAID | Foreign Total amount paid | DoubleType | New Field
JOURNALPOST | FOREIGN_GROSS | Foreign Gross Amount | DoubleType | New Field
JOURNALPOST | FOREIGN_NET_AMOUNT | Foreign Net Amount | DoubleType | New Field
JOURNALPOST | FOREIGN_GROSS | Foreign Gross Amount | DoubleType | New Field
JOURNALPOST | FOREIGN_NET_AMOUNT | Foreign Net Amount | DoubleType | New Field
JOURNALPOST | FOREIGN_RATE | Foreign Rate for euro currency | DoubleType | New Field
JOURNALPOST | FOREIGN_TAX_AMOUNT | Foreign Tax Amount | DoubleType | New Field
JOURNALPOST | INTERST_RATE | Interest Rate To Charge | DoubleType | New Field
JOURNALPOST | SUPP_UNIT_QTY | Supplementary Unit Quantity | DoubleType | New Field
JOURNALPOST | INV_REF | Invoice Reference Number | StringType | New Field
JOURNALPOST | ISP_REFERENCE | Inv/SOP/POP Reference | StringType | New Field
JOURNALPOST | JOB_REFERENCE | Job Costing Reference | StringType | New Field
JOURNALPOST | LAST_SPLIT | Item Number | IntegerType | New Field
JOURNALPOST | NET_AMOUNT | Net Amount | DoubleType | New Field
JOURNALPOST | NEXT_ACCOUNT | Item Number | IntegerType | New Field
JOURNALPOST | NEXT_BANK | Item Number | IntegerType | New Field
JOURNALPOST | NO_DISPUTED | Number of Disputed Splits | SmallIntegerType | New Field
JOURNALPOST | NO_OF_SPLIT | Item Number | IntegerType | New Field
JOURNALPOST | SUPP_UNIT_QTY | Supplementary Unit Quantity | DoubleType | New Field
JOURNALPOST | OPENING_BALANCE_TRANS | Is Transaction an Opening Balance | SmallIntegerType | New Field
JOURNALPOST | OVERRIDDEN_CLOSED_LEDGER_DATE | The closed ledger date that was overridden at the time of posting | DateType | New Field
JOURNALPOST | PAID_FLAG | Transaction paid flag - y/n | ByteType | New Field
JOURNALPOST | POSTED_DATE | posting date | DateType | New Field
JOURNALPOST | POSTING_LOCATION | Location transaction Posted From | SmallIntegerType | New Field
JOURNALPOST | PRACTICE_SOLUTIONS_REFN | Sage Practice Solutions Reference | StringType | New Field
JOURNALPOST | PREV_ACCOUNT | Item Number | IntegerType | New Field
JOURNALPOST | PREV_BANK | Item Number | IntegerType | New Field
JOURNALPOST | PRINTED_FLAG | Printed Flag | ByteType | New Field
JOURNALPOST | PROTX_REFN | Sage Pay Reference | StringType | New Field
JOURNALPOST | RECON_DATE | Bank reconciled date | DateType | New Field
JOURNALPOST | RECORD_CREATE_DATE | Date and time when the record was created | DateType2 | New Field
JOURNALPOST | RECORD_DELETED | Flag denoting if the record has been deleted or not. | SmallIntegerType | New Field
JOURNALPOST | RECORD_MODIFY_DATE | Date and time when the record was modified | DateType2 | New Field
JOURNALPOST | REVALUATION_TRANS | Is transaction a Revaluation Transaction | SmallIntegerType | New Field
JOURNALPOST | SETT_DISCOUNT_RATE | Settlement Discount Rate | DoubleType | New Field
JOURNALPOST | TAX_AMOUNT | Tax amount | DoubleType | New Field
JOURNALPOST | TYPE | Transaction type | ByteType | New Field
JOURNALPOST | UNIQUE_REF | Header Number | IntegerType | New Field
JOURNALPOST | USER_NAME | User name | StringType | New Field
JOURNALPOST | VAT_FLAG | VAT Flag | ByteType | New Field
PURCHASEDATA | INACTIVE | Inactive Flag - Yes/No | ByteType | Field removed
PURCHASEDATA | INACTIVE_FLAG | Inactive Flag - Yes/No | ByteType | New Field
PURCHASEDATA | PAYMENT_TYPE | Payment Type | IntegerType | New Field
PURCHASEACTIVEINDEX | PURCHASEACTIVEINDEX | New object | SDOINDEXFILE Object | New Object
PURCHASEACTIVEINDEX | ACCOUNT_REF | Account Reference | StringType | New Field
PURCHASEACTIVEINDEX | INACTIVE_FLAG | Inactive Flag - Yes/No | ByteType | New Field
PURCHASERECORD | INACTIVE | Inactive Flag - Yes/No | ByteType | Field removed
PURCHASERECORD | INACTIVE_FLAG | Inactive Flag - Yes/No | ByteType | New Field
PURCHASERECORD | PAYMENT_TYPE | Payment Type | IntegerType | New Field
SALESACTIVEINDEX | SALESACTIVEINDEX | New Object | SDOINDEXFILE Object | New Object
SALESACTIVEINDEX | ACCOUNT_REF | Account Reference | StringType | New Field
SALESACTIVEINDEX | RECORD_NUMBER | Record number in data file | IntegerType | New Field
SALESDATA | INACTIVE | Inactive Flag - Yes/No | ByteType | Field removed
SALESDATA | INACTIVE_FLAG | Inactive Flag - Yes/No | ByteType | New Field
SALESDATA | PAYMENT_TYPE | Payment Type | IntegerType | New Field
SALESRECORD | INACTIVE | Inactive Flag - Yes/No | ByteType | Field removed
SALESRECORD | INACTIVE_FLAG | Inactive Flag - Yes/No | ByteType | New Field
SALESRECORD | PAYMENT_TYPE | Payment Type | IntegerType | New Field
SETUPDATA | PRODUCT_DESCRIPTION_DISCOUNT_A | Product description discount A | StringType | New Field
SETUPDATA | PRODUCT_DESCRIPTION_DISCOUNT_B | Product description discount B | StringType | New Field
SETUPDATA | PRODUCT_DESCRIPTION_DISCOUNT_C | Product description discount C | StringType | New Field
SETUPDATA | PRODUCT_DESCRIPTION_DISCOUNT_D | Product description discount D | StringType | New Field
SETUPDATA | PRODUCT_DESCRIPTION_DISCOUNT_E | Product description discount E | StringType | New Field
SETUPDATA | ECSALES_BRANCH_POSTCODE | EC Sales branch postcode. Available on only UK datasets. | StringType | New Field
SETUPDATA | STOCKACTIVEINDEX | New Object | SDOINDEXFILE Object | New Object
SETUPDATA | RECORD_NUMBER | Record number in data file | IntegerType | New Field
SETUPDATA | STOCK_CODE | Stock Code | StringType | New Field
STOCKDATA | COUNTRY_CODE_OF_ORIGIN | Country code of origin. Irish data sets only | SmallIntegerType | New Field
STOCKPOST | INACTIVE_FLAG | Inactive Flag - Yes/No | ByteType | New Field
STOCKRECORD | INACTIVE_FLAG | Inactive Flag - Yes/No | ByteType | New Field
STOCKRECORD | COUNTRY_CODE_OF_ORIGIN | Country code of origin. Irish data sets only | SmallIntegerType | New Field
VERBRESULTINDEX | VERBRESULTINDEX | New Object | SDOINDEXFILE Object | New Object
VERBRESULTINDEX | ORIGINATOR | Originator's reference | StringType | New Field
VERBRESULTRECORD | VERBRESULTRECORD | New Object | SDORECORD Object | New Object
VERBRESULTRECORD | COMMENT | Any comments about the result | StringType | New Field
VERBRESULTRECORD | ORIGINATOR | Originator's reference | StringType | New Field
VERBRESULTRECORD | RESULT | Result of the verb | SmallIntegerType | New Field
VERBRESULTDATA | VERBRESULTDATA | New Object | SDOFILE Object | New Object
VERBRESULTDATA | COMMENT | Any comments about the result | StringType | New Field
VERBRESULTDATA | ORIGINATOR | Originator's reference | StringType | New Field
VERBRESULTDATA | RESULT | Result of the verb | SmallIntegerType | New Field


What's New in Sage Data Objects 2008

What's New in Sage Data Objects for Sage 50 Accounts 2016?

Compatibility Update

This release of the SDK is a compatibility update for Sage 50 Accounts 2016.

As you'd expect, code examples are provided to demonstrate how to upgrade your current applications and take advantage of the SDK's functionality. Please let us know if you'd like to see more.

New\Changed Objects, Methods, Fields and Properties

Object | Name | Description | Type | Change
BANKHEADERDATA USER_NAME_AMENDED User name
String
New Field
BANKHEADERDATA | DATE_AMENDED | Date Transaction Amended | String | New Field
HEADERDATA
USER_NAME_AMENDED User Name
String
New Field
HEADERDATA
DATE_AMENDED Date Transaction Amended String New Field
INVOICEDATA | ANALYSIS_1 | Analysis 1 | String | New Field
INVOICEDATA | ANALYSIS_2 | Analysis 2 | String | New Field
INVOICEDATA | ANALYSIS_3 | Analysis 3 | String | New Field
INVOICEDATA | COUNTRY_CODE | Customer Country Code | String | New Field
INVOICEDATA | INVOICE_FOREIGN_BALANCE | Foreign Balance | Double | New Field
INVOICERECORD
ANALYSIS_1 Analysis 1 String New Field
INVOICERECORD
ANALYSIS_2 Analysis 2 String New Field
INVOICERECORD
ANALYSIS_3 Analysis 3 String New Field
INVOICERECORD
INVOICE_FOREIGN_BALANCE Foreign Balance Double New Field
POPDATA
ANALYSIS_1 Analysis 1 String New Field
POPDATA
ANALYSIS_2 Analysis 2 String New Field
POPDATA
ANALYSIS_3 Analysis 3 String New Field
POPDATA | COUNTRY_CODE | Supplier Country Code | String | New Field
POPDATA
INVOICE_FOREIGN_BALANCE Foreign Balance Double New Field
POPRECORD
ANALYSIS_1 Analysis 1 String New Field
POPRECORD
ANALYSIS_2 Analysis 2 String New Field
POPRECORD
ANALYSIS_3 Analysis 3 String New Field
POPRECORD
INVOICE_FOREIGN_BALANCE Foreign Balance Double New Field
PURCHASEDATA
DISPUTED Disputed Integer New Field
PURCHASERECORD
DISPUTED Disputed Integer New Field
SALESDATA
DISPUTED Disputed Integer New Field
SALESRECORD
DISPUTED Disputed Integer New Field
SETUPDATA
CUST_UPDATE_TRAN_EX_REF_FROM Source used to fill the extra reference field Integer New Field
SETUPDATA
CUST_UPDATE_TRAN_REF_FROM Source used to fill the reference field Integer New Field
SETUPDATA
SIPS_BANKREFN The reference for the SIPS bank account StringType New Field
SETUPDATA
SIPS_REF The GUID of the associated SIPS Account IntegerType New Field
SETUPDATA
SUPP_UPDATE_TRAN_EX_REF_FROM Source used to fill the extra reference field DoubleType New Field
SETUPDATA
SUPP_UPDATE_TRAN_REF_FROM Source used to fill the reference field IntegerType New Field
SOPDATA
ANALYSIS_1 Analysis 1 String New Field
SOPDATA
ANALYSIS_2 Analysis 2 String New Field
SOPDATA
ANALYSIS_3 Analysis 3 String New Field
SOPDATA | COUNTRY_CODE | Customer Country Code | String | New Field
SOPDATA
INVOICE_FOREIGN_BALANCE Foreign Balance Double New Field
SOPRECORD
ANALYSIS_1 Analysis 1 String New Field
SOPRECORD
ANALYSIS_2 Analysis 2 String New Field
SOPRECORD
ANALYSIS_3 Analysis 3 String New Field
SOPRECORD | INVOICE_FOREIGN_BALANCE | Foreign Balance | Double | New Field
SPLITDATA
PROJECT_ID Project ID SmallIntegerType New Field


What's New in Sage Data Objects 2008

What's New in Sage Data Objects for Sage 50 Accounts 2017?

Compatibility Update

This release of the SDK is a compatibility update for Sage 50 Accounts 2017.
As you'd expect, code examples are provided to demonstrate how to upgrade your current applications and take advantage of the SDK's functionality. Please let us know if you'd like to see more.

Sage 50c (23.1)

Sage 50c (23.1) is an update to the current Sage 50 v23.0 program, the update will be available for all v23 users. The SDO keys have not changed for v23.1, the SDO keys for v23.0 work for v23.1.
The 23.1 update can be downloaded from Sage Accounts software updates.

The Sage 50c (23.1) release has implemented new Objects, Fields and Properties, as well as improvements to the SDO's validation.
Sage Developer Services has created a forum post to document the topics that are being generated by 23.1, the forum will be continually updated.
Please see Sage(UK) Forum - Sage 50c (23.1) SDO Validation for more information on topics such as:

Non-Sterling transactions, Assigning projects to transactions, Customer records with invalid characters and Tax codes on customer/suppliers transactions.

New\Changed Objects, Methods, Fields and Properties for 23.1

Object Change
IDOCUMENTLINK
New Object

Object Name Description Type Change
IDOCUMENTLINK
DOCUMENTLINK Path to the File String New Field
IDOCUMENTLINK
TRANSACTIONID Transaction Number Integer New Field
IDOCUMENTLINK
Update Boolean New Method
IDOCUMENTLINK
Delete Boolean New Method
IDOCUMENTLINK
Load Boolean New Method
SALESEDATA
PAYMENT_DUE_FROM Payment Due From Int16 New Field
PURCHASEDATA
PAYMENT_DUE_FROM Payment Due From Int16 New Field
SALESRECORD
PAYMENT_DUE_FROM Payment Due From Int16 New Field
PURCHASERECORD
PAYMENT_DUE_FROM Payment Due From Int16 New Field
CUSTOMERADDRESS
ModifyDate Read-Only Property for the Modify Date Date New Property
SUPPLIERADDRESS
ModifyDate Read-Only Property for the Modify Date Date New Property
SDOEngine
FileType.sdoDocumentLinkData File Type System.Enum New Enum Value
SDOEngine
FileType.sdoDocumentLinkIndex File Type System.Enum New Enum Value
SPLIDATA
HAS_EXTERNAL_LINK Sets whether the transaction has an external link Int16 New Field

New\Changed Objects, Methods, Fields and Properties in the release version of 23

Object Change
CONTACTHISTORY
New Object
CONTACTHISTORYS
New Object

Object Name Description Type Change
PURCHASEDATA
TRADER_FOREIGN_BALANCE Foreign Balance Double New Field
INVOICEDATA
PAYMENT_DUE_DATE Invoice Payment Due Date
 Date New Field
CONTACTHISTORY
UniqueID Int32 New Property
CONTACTHISTORY
CustomerSupplier SageDataObject300.ContactType New Property
CONTACTHISTORY
AccountRef String New Property
CONTACTHISTORY
MajorContactType SageDataObject300.ContactHistoryMajorContactType New Property
CONTACTHISTORY
SubContactType SageDataObject300.ContactHistorySubContactType New Property
CONTACTHISTORY
ContactDate DateTime New Property
CONTACTHISTORY
ContactName String New Property
CONTACTHISTORY
Telephone String New Property
CONTACTHISTORY
Style Int16 New Property
CONTACTHISTORY
Location Int16 New Property
CONTACTHISTORY
OurContactUserName String New Property
CONTACTHISTORY
Outcome SageDataObject300.ContactHistoryOutcome New Property
CONTACTHISTORY
PromisedPayment Double New Property
CONTACTHISTORY
PromisedDate DateTime New Property
CONTACTHISTORY
FollowUpDate DateTime New Property
CONTACTHISTORY
Offset Int32 New Property
CONTACTHISTORY
Balance Double New Property
CONTACTHISTORY
Start Int32 New Property
CONTACTHISTORY
End Int32 New Property
CONTACTHISTORY
Duration Int32 New Property
CONTACTHISTORY
FollowUpEventID Int32 New Property
CONTACTHISTORY
Subject String New Property
CONTACTHISTORY
AddressLine1 String New Property
CONTACTHISTORY
AddressLine2 String New Property
CONTACTHISTORY
AddressLine3 String New Property
CONTACTHISTORY
AddressLine4 String New Property
CONTACTHISTORY
AddressLine5 String New Property
CONTACTHISTORY
FollowUpTime DateTime New Property
CONTACTHISTORY
Note1 String New Property
CONTACTHISTORY
Note2 String New Property
CONTACTHISTORY
Note3 String New Property
CONTACTHISTORY
Invoiced Int16 New Property
CONTACTHISTORY
Update Boolean New Method
CONTACTHISTORY
Delete Boolean New Method
CONTACTHISTORY
Load Boolean New Method
CONTACTHISTORYS
Count Int32 New Property
CONTACTHISTORYS
Item SageDataObject300.ContactHistory New Method
SALESRECORD
TRADER_FOREIGN_BALANCE Foreign Balance Double New Field
PURCHASERECORD
TRADER_FOREIGN_BALANCE Foreign Balance Double New Field
SALESDATA
TRADER_FOREIGN_BALANCE Foreign Balance Double New Field
INVOICERECORD
PAYMENT_DUE_DATE Invoice Payment Due Date
 Date New Field
WORKSPACE
CreateContactHistory System.Object New Method
WORKSPACE
CreateContactHistorys System.Object New Method


What's New in Sage Data Objects 2008

What's New in Sage Data Objects for Sage 50 Accounts Version 24 (v24.0, v24.1 and v24.2)

Compatibility Update

This release of the SDK is a compatibility update for Sage 50 Accounts version 24.
As you'd expect, code examples are provided to demonstrate how to upgrade your current applications and take advantage of the SDK's functionality. Please let us know if you'd like to see more.

New Sage 50 Accounts Report Designer

Sage 50 Accounts version 24 includes a new version of the Report Design program that Sage 50 Accounts uses for its reporting, as a result there is a new Sage.Reporting.Engine.integration.dll file. This is located:
C:\Program Files (x86)\Common Files\Sage\Assemblies\Report Designer v4 and is installed as part of the update to Sage Accounts version 24.
Sage 50 Accounts Report Designer API

Whats New in v24.2 update

In v24.2 the customer/supplier modules have included a selection of social media fields, these new fields have been added to the following objects.

Object Name Description Length Type Change
SALESRECORD
TWITTER Twitter Address 35 String New Field
SALESRECORD
LINKEDIN LinkedIn Address 64 String New Field
SALESRECORD
FACEBOOK Facebook Address 75 String New Field
SALESDATA
TWITTER Twitter Address 35 String New Field
SALESDATA
LINKEDIN LinkedIn Address 64 String New Field
SALESDATA
FACEBOOK Facebook Address 75 String New Field
PURCHASERECORD
TWITTER Twitter Address 35 String New Field
PURCHASERECORD
LINKEDIN LinkedIn Address 64 String New Field
PURCHASERECORD
FACEBOOK Facebook Address 75 String New Field
PURCHASEDATA
TWITTER Twitter Address 35 String New Field
PURCHASEDATA
LINKEDIN LinkedIn Address 64 String New Field
PURCHASEDATA
FACEBOOK Facebook Address 75 String New Field

The following objects have new fields for the bank charges feature, these fields are read only.

Object Name Description Length Type Change
BANKDATA
BANK_CHARGES_DEFAULT_BANK_REF The default bank account for bank charges (Read Only) 8 String New Field
BANKDATA
BANK_CHARGES_DEFAULT_NOMINAL_CODE The default nominal code for bank charges (Read Only) 8 String New Field
BANKDATA
BANK_CHARGES_DEFAULT_DEPARTMENT The default department for bank charges (Read Only) 2 Small Integer New Field
BANKDATA
BANK_CHARGES_DEFAULT_TAX_CODE The default tax code for bank charges (Read Only) 2 Small Integer New Field
BANKRECORD
BANK_CHARGES_DEFAULT_BANK_REF The default bank account for bank charges (Read Only) 8 String New Field
BANKRECORD
BANK_CHARGES_DEFAULT_NOMINAL_CODE The default nominal code for bank charges (Read Only) 8 String New Field
BANKRECORD
BANK_CHARGES_DEFAULT_DEPARTMENT The default department for bank charges (Read Only) 2 Small Integer New Field
BANKRECORD
BANK_CHARGES_DEFAULT_TAX_CODE The default tax code for bank charges (Read Only) 2 Small Integer New Field
HEADERDATA
BANK_CHARGE_ACCOUNT Bank Charge Customer/Supplier Ref (Read Only) 8 String New Field
HEADERDATA
BANK_CHARGE_IS_CUSTOMER Is Bank Charge Customer or Supplier (Read Only) 2 Small Integer New Field
BANKHEADERDATA
BANK_CHARGE_ACCOUNT Bank Charge Customer/Supplier Ref (Read Only) 8 String New Field
BANKHEADERDATA
BANK_CHARGE_IS_CUSTOMER Is Bank Charge Customer or Supplier (Read Only) 2 Small Integer New Field

Whats New in v24.1 update

Negative item line

It is now possible to mark certain types of item lines as negative on Product Invoices and Service Invoices when posted through the SDO. Product invoices follow the program logic so only special product codes ( S1, S2 and S3 ) can be marked as negative. To mark an item line as negative you would need to add a line similar to the example code below to the relevant item line posting:

VB.Net

oInvoiceItem.Fields.Item("IS_NEGATIVE_LINE").Value = 1)

C#.Net

SDOHelper.Write(oInvoiceItem, "IS_NEGATIVE_LINE", 1);

The SDO also follows the program logic for the total value of the invoice. If the negative line value(s) exceed the positive value(s) the invoice will not be created.

User Management

There have been improvements made to the way the main Sage 50 program handles users that are locked in caused by, for example, program / SDO application crashes.
If the Sage 50 program or SDO is closed unintentionally, the user that was logged in is removed from the Queue.dta file. This changes should mean you will see a reduction in the ‘Username in Use‘ error messages as a user cannot be logged in twice, as the user is no longer left open in the Queue.dta file.

SDO Activation

It is now no longer necessary to activate the SDO through the main Sage 50 program or programmatically through the SDO.
It is already activated and does not require the SDO serial number and activation key to be entered.

New\Changed Objects, Methods, Fields and Properties for v24

Object Change
BANKFEEDPOSTING
Sage Internal Use - Do Not Use New Object

Object Name Description Length Type Change
BANKDATA
BANK_FEEDS_ACCESS_TO_ACCOUNTANT_GRANTED Access To Accountant Granted 2 Byte New Field
BANKDATA
INACTIVE_FLAG Inactive Flag - Yes/No 4 Integer New Field
BANKRECORD
BANK_FEEDS_ACCESS_TO_ACCOUNTANT_GRANTED Access To Accountant Granted 2 Byte New Field
BANKRECORD
INACTIVE_FLAG Inactive Flag - Yes/No 4 Integer New Field
CONTACTHISTORY
HasExternalLink Sets whether has external link (0 = No, 1 = Yes) 2 Int16 New Property
NOMINALDATA
INACTIVE_FLAG Inactive Flag - Yes/No 4 Integer New Field
NOMINALRECORD
INACTIVE_FLAG Inactive Flag - Yes/No 4 Integer New Field
SDOEngine
ErrorCode.sdoInvoiceTotalNegative Enum New Enum Value
SDOEngine
ErrorCode.sdoIncorrectStockCodeType Enum New Enum Value
STOCKDATA
WEB_DESCRIPTION Web Description 255 String Length changed from '60' to '255'
STOCKRECORD
WEB_DESCRIPTION Web Description 255 String Length changed from '60' to '255'
TAXCODE
Rate Double New Property


What's New in Sage Data Objects 2008

What's New in Sage Data Objects for Sage 50 Accounts v25 and v25.1

Compatibility Update

This release of the SDK is a compatibility update for Sage 50 Accounts v25 and v25.1.
As you'd expect, code examples are provided to demonstrate how to upgrade your current applications and take advantage of the SDK's functionality. Please let us know if you'd like to see more.

What is Sage 50 Accounts?

Sage 50 Accounts is the new branding of Sage 50 Accounts, it is the same program from an installation, data storage and processing point of view. Sage 50 Accounts includes cloud features powered by Microsoft 365, these features are not exposed to the SDO.

Whats New in v25.1 update

These new fields have been added to the following objects.

Object Name Description Length Type Change
SetupData
PROGRAM_MAJOR_VERSION Program Major Version 2 Small Integer New Field
SetupData
PROGRAM_MINOR_VERSION Program Major Version 2 Small Integer New Field
SetupData
PROGRAM_BUILD_VERSION Program Major Version 2 Small Integer New Field
SetupData
PROGRAM_BUGFIX_VERSION Program Major Version 2 Small Integer New Field
TransactionPost
BANK_RECONCILIATION_ID Bank reconciliation ID that this transaciton is part of 4 Integer New Field
AccessData
HELP_UPDATESETTINGS Help - Software Update Settings 1 Byte New Field


What's New in Sage Data Objects 2008

What's New in Sage Data Objects for Sage 50 Accounts v26

Compatibility Update

This release of the SDK is a compatibility update for Sage 50 Accounts v26.
As you'd expect, code examples are provided to demonstrate how to upgrade your current applications and take advantage of the SDK's functionality. Please let us know if you'd like to see more.

What is Sage 50 Accounts?

Sage 50 Accounts is the new branding of Sage 50 Accounts, it is the same program from an installation, data storage and processing point of view. Sage 50 Accounts includes cloud features powered by Microsoft 365, these features are not exposed to the SDO.

Whats New in v26 update

These new fields have been added to the following objects.

Object Name Description Length Type Change
ControlData
TX_REVERSE_CHARGE Tax Code reverse charge setting - X refers to 0-99 tax code e.g. T99_REVERSE_CHARGE 2 Small Integer New Field
ISalesRecord
PaymentDueFromOption PaymentDueFrom Option 0 Property New Property
IPurchaseRecord
PaymentDueFromOption PaymentDueFrom Option 0 Property New Property
ICustomer
PaymentDueFromOption PaymentDueFrom Option 0 Property New Property
ISupplier
PaymentDueFromOption PaymentDueFrom Option 0 Property New Property
ICustomer
MANDATEREF Mandate reference 26 String New Field
ISupplier
MANDATEREF Mandate reference 26 String New Field
SDOEngine
PaymentDueFromOption Enum New Enum Value


What's New in Sage Data Objects 2020

What's New in Sage Data Objects for Sage 50 Accounts v28

Compatibility Update

This release of the SDK is a compatibility update for Sage 50 Accounts v28.
As you'd expect, code examples are provided to demonstrate how to upgrade your current applications and take advantage of the SDK's functionality. Please let us know if you'd like to see more.

What is Sage 50 Accounts?

Sage 50 Accounts is the new branding of Sage 50 Accounts, it is the same program from an installation, data storage and processing point of view. Sage 50 Accounts includes cloud features powered by Microsoft 365, these features are not exposed to the SDO.

Whats New in v28 update

The install location for the SDO dependencies has changed to C:\Program Files (x86)\Sage\Accounts\SDO\2022 from System32/SysWow64. The SDO dependencies will always be installed there regardless of where the program is installed.
This was done so potentially there is less of a permissions problem installing to the local directory compared to installing in the system directory.

There has been changes made in the documentation to the report designer API which we would recommend you review. New detail can be found on the following help file pages:

ReportDesignerAPI

Implementing the new ReportDesignerResolver class

There has also been some new descriptions added for RDA specific exceptions/error codes aswell as some new guidance for how to handle these exceptions. More information can be found at the following help file pages:

Exceptions/Error Codes

RDA Events


What's New in Sage Data Objects 2020

What's New in Sage Data Objects for Sage 50 Accounts v29

Compatibility Update

This release of the SDK is a compatibility update for Sage 50 Accounts v29.
As you'd expect, code examples are provided to demonstrate how to upgrade your current applications and take advantage of the SDK's functionality. Please let us know if you'd like to see more.

Whats New in v29 update

SDO Files Names

The SdoENDxxx.tlb and sg50SdoEnginexxx.dll files in v29 no longer contains the version number as these files are held in a versioned SDO folder, it is no longer required for them to contain the version.
For v29 these files are held in C:\Program Files (x86)\Sage\Accounts\SDO\2024 and are named as followed:

  • SdoENG.tlb
  • sg50SdoEngine.dll

SDO Object, Properties and Field changes

  • The customer and supplier records have 3 additional analysis and email fields, allowing 6 analysis and emails per record.

  • The number of characters available in a Product record for the description and Part Number have been increased to 120 and 60.

  • Added EORI number to customer and supplier delivery addresses.
    EROI number is required for users dealing with cross border trade � they must be able to store an EORI number on customer and supplier delivery addresses.

  • New Company Registration Number field has been added to the Customer, Supplier and SetupData data objects.

Sage 50 Accounts v29.0.286.0 Update

  • Known Issue Fix - We have resolved an issue with the UniqueRegID property on the Company object returning nothing. This has been addressed and UniqueRegID now returns the UniqueRegID to the selected company.

List of all updated fields

The table below contains all the changes to the SDO in v29

Object | Name | Description | Length | Type | Change
STOCKDATA | DESCRIPTION | Description | 120 | StringType | Length changed from '60' to '120'.
STOCKDATA | SUPPLIER_PART_NUMBER | Supplier's part number | 60 | StringType | Length changed from '16' to '60'.
POPITEM | DESCRIPTION | Description | 120 | StringType | Length changed from '60' to '120'.
POPITEM | SERVICE_FILE | Redundant - Do not use | 120 | StringType | Length changed from '60' to '120'.
POPITEM | TEXT | Service invoice/credit text | 120 | StringType | Length changed from '60' to '120'.
GDNDATA | STOCK_DESC | Stock Description | 120 | StringType | Length changed from '60' to '120'.
GOODSNOTESDATA | STOCK_DESC | Stock Description | 120 | StringType | Length changed from '60' to '120'.
PURCHASEDATA | ANALYSIS_4 | Analysis 4 | 30 | StringType | New Field
PURCHASEDATA | ANALYSIS_5 | Analysis 5 | 30 | StringType | New Field
PURCHASEDATA | ANALYSIS_6 | Analysis 6 | 30 | StringType | New Field
PURCHASEDATA | COMPANY_REGISTRATION_NUMBER | Company Reg. Number | 16 | StringType | New Field
PURCHASEDATA | E_MAIL4 | E-Mail Address (4) | 255 | StringType | New Field
PURCHASEDATA | E_MAIL5 | E-Mail Address (5) | 255 | StringType | New Field
PURCHASEDATA | E_MAIL6 | E-Mail Address (6) | 255 | StringType | New Field
POPDATA | EORI_NUMBER | Delivery address EORI Number | 17 | StringType | New Field
POPRECORD | EORI_NUMBER | Delivery address EORI Number | 17 | StringType | New Field
ACCESSDATA | SETT_INV_PAY | Settings Menu - Invoice Payments | 1 | ByteType | New Field
ACCESSDATA | SETT_ONEDRIVE_DOC | Settings Menu - OneDrive Document Settings | 1 | ByteType | New Field
ACCESSDATA | SOFTWAREUPDATES | Software Updates | 1 | ByteType | New Field
ACCESSDATA | SOFTWAREUPDATES_UPDATESETTINGS | Software Updates - Software Update Settings | 1 | ByteType | New Field
ACCESSDATA | TOOLS_CUSTOMIZE | Tools Manu - Customise your company | 1 | ByteType | New Field
INVOICEDATA | EORI_NUMBER | Delivery address EORI Number | 17 | StringType | New Field
SALESRECORD | ANALYSIS_4 | Analysis 4 | 30 | StringType | New Field
SALESRECORD | ANALYSIS_5 | Analysis 5 | 30 | StringType | New Field
SALESRECORD | ANALYSIS_6 | Analysis 6 | 30 | StringType | New Field
SALESRECORD | COMPANY_REGISTRATION_NUMBER | Company Reg. Number | 16 | StringType | New Field
SALESRECORD | E_MAIL4 | E-Mail Address (4) | 255 | StringType | New Field
SALESRECORD | E_MAIL5 | E-Mail Address (5) | 255 | StringType | New Field
SALESRECORD | E_MAIL6 | E-Mail Address (6) | 255 | StringType | New Field
GOODSNOTESRECORD | STOCK_DESC | Stock Description | 120 | StringType | Length changed from '60' to '120'.
PURCHASERECORD | ANALYSIS_4 | Analysis 4 | 30 | StringType | New Field
PURCHASERECORD | ANALYSIS_5 | Analysis 5 | 30 | StringType | New Field
PURCHASERECORD | ANALYSIS_6 | Analysis 6 | 30 | StringType | New Field
PURCHASERECORD | COMPANY_REGISTRATION_NUMBER | Company Reg. Number | 16 | StringType | New Field
PURCHASERECORD | E_MAIL4 | E-Mail Address (4) | 255 | StringType | New Field
PURCHASERECORD | E_MAIL5 | E-Mail Address (5) | 255 | StringType | New Field
PURCHASERECORD | E_MAIL6 | E-Mail Address (6) | 255 | StringType | New Field
SALESDATA | ANALYSIS_4 | Analysis 4 | 30 | StringType | New Field
SALESDATA | ANALYSIS_5 | Analysis 5 | 30 | StringType | New Field
SALESDATA | ANALYSIS_6 | Analysis 6 | 30 | StringType | New Field
SALESDATA | COMPANY_REGISTRATION_NUMBER | Company Reg. Number | 16 | StringType | New Field
SALESDATA | E_MAIL4 | E-Mail Address (4) | 255 | StringType | New Field
SALESDATA | E_MAIL5 | E-Mail Address (5) | 255 | StringType | New Field
SALESDATA | E_MAIL6 | E-Mail Address (6) | 255 | StringType | New Field
INVOICEITEM | DESCRIPTION | Description | 120 | StringType | Length changed from '60' to '120'.
INVOICEITEM | SERVICE_FILE | Redundant - Do not use | 120 | StringType | Length changed from '60' to '120'.
INVOICEITEM | TEXT | Service invoice/credit text | 120 | StringType | Length changed from '60' to '120'.
GDNRECORD | STOCK_DESC | Stock Description | 120 | StringType | Length changed from '60' to '120'.
STOCKRECORD | DESCRIPTION | Description | 120 | StringType | Length changed from '60' to '120'.
STOCKRECORD | SUPPLIER_PART_NUMBER | Supplier's part number | 60 | StringType | Length changed from '16' to '60'.
SOPRECORD | EORI_NUMBER | Delivery address EORI Number | 17 | StringType | New Field
SOPITEM | DESCRIPTION | Description | 120 | StringType | Length changed from '60' to '120'.
SOPITEM | SERVICE_FILE | Redundant - Do not use | 120 | StringType | Length changed from '60' to '120'.
SOPITEM | TEXT | Service invoice/credit text | 120 | StringType | Length changed from '60' to '120'.
SETUPDATA | BUSINESS_TYPE | Business Type | 1 | ByteType | New Field
SETUPDATA | COMPANY_REGISTRATION_NUMBER | Company Reg. Number | 16 | StringType | New Field
SETUPDATA | PURCHASE_ANALYSIS_4 | Purchase analysis 4 | 10 | StringType | New Field
SETUPDATA | PURCHASE_ANALYSIS_5 | Purchase analysis 5 | 10 | StringType | New Field
SETUPDATA | PURCHASE_ANALYSIS_6 | Purchase analysis 6 | 10 | StringType | New Field
SETUPDATA | SALES_ANALYSIS_4 | Sales Analysis 4 | 10 | StringType | New Field
SETUPDATA | SALES_ANALYSIS_5 | Sales Analysis 5 | 10 | StringType | New Field
SETUPDATA | SALES_ANALYSIS_6 | Sales Analysis 6 | 10 | StringType | New Field
CUSTOMERADDRESS | EORINumber | Delivery address EORI Number | 17 | System.String | New Property
SUPPLIERADDRESS | EORINumber | Delivery address EORI Number | 17 | System.String | New Property
SOPDATA | EORI_NUMBER | Delivery address EORI Number | 17 | StringType | New Field
INVOICERECORD | EORI_NUMBER | Delivery address EORI Number | 17 | StringType | New Field


Sage 50 Accounts - Example - RDA Events

Example - How to handle RDA events

To make your customers aware in the event of an issue with an RDA connection, you must ensure all requests are made as part of a try catch block. This will enable you to catch the exception, and read the associated error code, then take action. In most cases, you will want to notify the user that they must stop processing immediately and proceed to the Sage 50 Accounts desktop application as soon as possible. Upon logging in (if the user has the appropriate access rights) they will receive a message explaining the issue and provide options to resolve. Once completed, they may return to processing as normal in the application, or via a third-party. At present the only way to get the error code, is within the catch block:

Essentially using oSDO.LastError.Code (oSDO being an instance of SageDataObject300.SDOEngine) will provide you with the code caught. Here you can find a list of potential error codes returned.

C#.NET [image] Copy C# Code

try

{

// The Desired request

}

catch (Exception ex)

{

String lastError = oSDO.LastError.Code.ToString();

Console.WriteLine(lastError);

//take desired action/notify the user

}


Understanding Audit Trail Transactions

Introduction

The TransactionPost object makes it easy to post and allocate audit trail transactions into Sage 50 Accounts as it handles the updating of all the necessary data files without the developer having to know where the information ends up. There are circumstances, particularly if you are reading transactions, when it is important to know how audit trail transactions are made up.

Multi-Level Transactions

Audit trail transactions in Sage 50 Accounts are held at three levels, each of which represents greater detailed analysis of the makeup of a transaction. Within SDO, these levels are represented by the HeaderData, SplitData and UsageData objects. The three levels are best represented by looking at a Customer Activity screen from Sage 50 Accounts:

  • Headers

The screenshot below shows the Customer Activity screen within Sage 50 Accounts

:

The transaction details shown highlighted in red come from the Header section of the transaction and can be accessed via the HeaderData object. At this level, you have access to summary information for the transaction such as the customer account the transaction was posted to and the total amounts for Net and VAT for the transactions.

  • Splits

The screenshot below shows the same activity, but has highlighed the next 'level'of the transaction:

The transaction details that are now available come from one or more 'splits' for the transaction and can be accessed via the SplitData object. At this level, you have access to the individual items that make up the transaction so you can see, for example, which nominal code(s) the transaction lines were posted to. The split level information is what you see when you go into the Financials screen in Sage 50 Accounts.

Here, you can see that that there are two splits, transaction numbers 1 and 2, for the single Header transaction above. Note that the number on the left hand side of the Header list is always the first split transaction number.

  • Usages

If a transaction is partly or fully paid, it will have an allocation, or Usage. On each transaction split within the bottom list box of the activity screen a "plus" icon will appear if an allocation exists. This gives us the ability to "drill down" from the split to the usage transaction:

The transaction details within the lower list box are now expanded to show the usage(s) for each split. These usage transactions can be accessed via the UsageData object. At this level, you have access to the allocation information such as the split numbers and paid amounts.

Here, Header transaction 3 is highlighted in the top list, which gives you a breakdown of Split number 3 (with 2 usages) and Split number 4 (with 1 usage).

Bear in mind that when transactions are allocated (i.e. SI and SR transactions) both the SI and the SR have a usage. In the screenshot, the usages for the SI transactions are shown, but the SR and SD transactions would also have corresponding usages (which you would see by selecting the appropriate headers/splits).

Replicating this functionality with the SDO

Using the objects, methods and properties available to you via the SDO, it is possible to recreate this multi-level drill-down on transactions as demonstrated in the following VB.NET code sample:

  'Error Handler
  On Error GoTo Error_Handler

  'Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oSalesRecord As SageDataObject300.SalesRecord
  Dim oHeaderData As SageDataObject300.HeaderData
  Dim oSplitData As SageDataObject300.SplitData
  Dim oUsageData As SageDataObject300.UsageData

  'Declare Variables
  Dim szDataPath As String

  'Create the SDOEngine Object
  oSDO = New SageDataObject300.SDOEngine

  'Create the Workspace
  oWS = oSDO.Workspaces.Add("Example")

  'Select Company. The SelectCompany method takes the program install
  'folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  'A U.I. for company selection is presented to the user. If a company is selected,
  'the path will be passed to the szDataPath variable.
  'If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then

    '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")

      'Move to the First Customer Account
      oSalesRecord.MoveFirst

      'Use the Link Method to get the Headers for the Customer Account
      oHeaderData = oSalesRecord.Link

      'Move to the First Header - This gives access to the transaction information
      'as per the first screenshot above
      oHeaderData.MoveFirst

      'Use the Link method to get the Splits for the Header
      oSplitData = oHeaderData.Link

      'Now loop through the Splits as there may be more than one
      oSplitData.MoveFirst

      Do

        'At the Split level we now have access to the transaction information
        'as per the second screenshot above

        'Use the Link method again to get the Usages for the Split
        oUsageData = oSplitData.Link

        'Now Loop through the Usages as there may be more than one
        oUsageData.MoveFirst

        Do

          'At the Usage level we now have access to the transaction information
          'as per the third screenshot above

        Loop Until Not oUsageData.MoveNext

      Loop Until Not oSplitData.MoveNext

      'Disconnect
      oWS.Disconnect()

    End If

  End If

  'Destroy Objects
  oSalesRecord = Nothing
  oHeaderData = Nothing
  oSplitData = Nothing
  oUsageData = Nothing
  oWS = Nothing
  oSDO = Nothing

  Exit Sub

'Error Handling Code
Error_Handler:

MsgBox("The SDO generated the following error: " & oSDO.LastError.Text)


Posting Foreign Currency Transactions

Introduction

Essentially, posting foreign currency transactions is the same as posting base currency transactions as you still use the TransactionPost object. The only difference is that you populate the fields that relate to foreign currency instead of the base currency fields.

In order to post foreign currency transactions using SDO, you must ensure the following:

  1. The Foreign Trader Setup Wizard has been run in Sage 50 Accounts.
  2. The currency field for the account you are writing the foreign value to should be set to something other than the base currency.

Populating Fields

The following fields need to be populated:

Name | Description
FOREIGN_RATE | The exchange rate, set by the user or from the Sales/Purchase/Bank account.
CURRENCY | The currency read from the Sales/Purchase/Bank account.
FOREIGN_NET_AMOUNT | Set instead of NET_AMOUNT
FOREIGN_TAX_AMOUNT | Set instead of TAX_AMOUNT
FOREIGN_AMOUNT_PAID | Set instead of AMOUNT_PAID

Error Messages

The following exceptions may be generated by the Update method of the TransactionPost object when posting foreign currency transactions:

Constant | Value | Reason
sdoForTraNotEnabled | 33 | This will be reported when you have not run the Foreign Trader Wizard in Sage 50 Accounts; Because Accountst and Accounts Plus do not have the Foreign Trader Wizard, you will not be able to post foreign trader transactions. In practice, this particular exception is unlikely to be thrown as the two exceptions below are tested for first.
sdoCurrencyDoesNotMatch | 34 | This will be reported when the currency type assigned to the account does not match the currency type assigned to the transaction. For example, if you have dollar ($) account, you cannot post euros into it.
sdoForeignRateSetOnBase | 35 | This will be reported when you are trying to post a standard transaction to a BASE currency account but you have set the FOREIGN_RATE field in the transaction to something other than 0 or 1.

Examples

Posting a Foreign Currency Sales Invoice
Posting a Foreign Currency Sales Credit Note
Posting a Foreign Currency Sales Receipt
Posting a Foreign Currency Purchase Invoice
Posting a Foreign Currency Purchase Credit Note
Posting a Foreign Currency Purchase Payment
Posting a Foreign Currency Bank Receipt
Posting a Foreign Currency Bank Payment


Linking Invoices Entered in the Invoicing Module to Audit Trail Transactions

Introduction

It is sometimes useful to be able to read an invoice and then find the audit trail transactions that were created when the invoice was updated. Sage 50 Accounts uses the 'Quick Link' option to achieve this functionality and it can be duplicated with the SDO.

Considerations

In order for this functionality to work correctly, there are some considerations you should be aware of:

  • You need to identify if the option to 'Update Using Order No' is switched on in Sage 50 Accounts.
  • The INV_REF field on the Header must be unique. If a batch invoice has been entered with the same number as an invoice in the invoicing module or a transaction has been edited in File Maintenance, this may cause the function to fail.

Example

The code sample below, written in VB.NET, demonstrates how to duplicate this functionality with the SDO. Note that we loop through the transactions for the selected customer rather than using the FindFirst method to find the invoice/order number on the HeaderData object - this is down to personal preference but going directly to the customer's transaction can be a great deal faster than using FindFirst.

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oInvoiceRecord As SageDataObject300.InvoiceRecord
  Dim oHeaderData As SageDataObject300.HeaderData
  Dim oSplitData As SageDataObject300.SplitData
  Dim oSalesRecord As SageDataObject300.SalesRecord
  Dim oSetupData As SageDataObject300.SetupData

  ' Declare Variables
  Dim szDataPath As String
  Dim szInvoiceToFind As String

  ' Create the SDOEngine Object
  oSDO = New SageDataObject300.SDOEngine()

  ' Create the Workspace
  oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then

    ' Try to Connect - Will Throw an Exception if it Fails
    If oWS.Connect(szDataPath, "", "", "Example") Then

      ' Create an Instance of the InvoiceRecord Object
      oInvoiceRecord = oWS.CreateObject("InvoiceRecord")

      ' Find the Invoice Record
      oInvoiceRecord.Fields.Item("INVOICE_NUMBER").Value = CInt(64)
      If oInvoiceRecord.Find(False) Then

        ' Create an Instance of the SetupData object and Read the Record
        oSetupData = oWS.CreateObject("SetupData")
        oSetupData.Read(1)

        ' Are we Updating by Invoice or Order Number
        If Convert.ToByte(oSetupData.Fields.Item("INVOICE_UPD_ORDERNO").Value) = 1 Then

          ' Update is by Order Number
          szInvoiceToFind = oInvoiceRecord.Fields.Item("ORDER_NUMBER").Value

        Else

          ' Update is by Invoice Number
          szInvoiceToFind = CStr(oInvoiceRecord.Fields.Item("INVOICE_NUMBER").Value)

        End If

        ' Get the SalesRecord for the Customer on the Invoice
        oSalesRecord = oWS.CreateObject("SalesRecord")
        oSalesRecord.Fields.Item("ACCOUNT_REF").Value = CStr(oInvoiceRecord.Fields.Item("ACCOUNT_REF").Value)

        If oSalesRecord.Find(False) Then

          ' Now Loop Through the transactions for the Customer as this is probably faster
          ' than using the FindFirst method
          oHeaderData = oSalesRecord.Link

          oHeaderData.MoveFirst()

          Do

            ' Does the Reference match the Invoice/Order Number
            If oHeaderData.Fields.Item("INV_REF").Value = szInvoiceToFind Then

              ' It matches so loop through the splits
              oSplitData = oHeaderData.Link
              oSplitData.MoveFirst()

              Do

                ' Display the Details for the Split
                MsgBox(oSplitData.Fields.Item("DETAILS").Value)

              Loop Until Not oSplitData.MoveNext

              oHeaderData.MoveLast()

            End If

          Loop Until Not oHeaderData.MoveNext

        End If

      End If

      ' Disconnect
      oWS.Disconnect()

    End If

  End If

  ' Destroy Objects
  oSetupData = Nothing
  oSalesRecord = Nothing
  oHeaderData = Nothing
  oSplitData = Nothing
  oWS = Nothing
  oSDO = Nothing

  Exit Sub

' Error Handling Code
Error_Handler:

  MsgBox("The SDO generated the following error: " & oSDO.LastError.Text)


Invoice\SOP\POP Post Considerations

The introduction of mobile integration with Sage 50 Accounts 2012 required some changes to the way Invoices\SOPs\POPs post to the program via SDO. The update method of the ISP Posting objects now wraps business logic to deal with rounding and calculations for net, tax and discount values, meaning you can post an invoice item with only the net amount, Tax_Rate, Qty_Order and Unit_Price set on the item line of a product invoice and Net_Amount, Unit_Price and Tax_Rate set for a service invoice.

There may be times when it is necessary to calculate the net and tax from a gross figure that is being passed from an external source, this was an initial oversight in the 2012 SDO release Sg50SDOEngine180.DLL version 18.0.10.208 that may result in rounding issues with the net and vat amounts not agreeing to the gross. The problem was fixed with Sg50SDOEngine180.DLL version 18.0.10.209.

In order to preserve the values you must now set the TAX_FLAG on the item line to (1), this will override the new business logic allowing the values set to remain. The example values below show values that would not round exactly and require the set values to be preserved.

Gross value = 159.99

Net Value = 133.33 (rounded to 2 decimal places using mid point rounding away from zero.

Tax value = Gross - Net (26.66)

Setting the TAX_FLAG to 1 does not prevent the values from being re calculated if for example a Net Value Discount is set on the ISP header as the Tax_Amount would need to be re calculated.

Setting a Net Value Discount

Setting a Net Value Discount prior to 2012 required lines of code, the business logic wrapped in the update method of 2012 now allows you to efficiently set a Net Value Discount by setting only one field on the header, two if you would like a description. The code example Posting a Product Invoice with Net Value Discount goes in to further detail.

Setting Item Line Discounts

Setting an Item Line Discount is made simpler with the added business logic, we no longer have to set the Discount_Rate field as this is set if a Customer\Supplier record has an associated discount. We still need to set the Full_Net_Amount and The Net_Amount in order for the business logic to calculate the monetary value of the discount applied. The code example Posting a Product Invoice with an Item Line Discount further explains the code.

Examples Using this Object

Posting a Product Invoice
Posting a Product Invoice and Receipt
Posting a Product Credit Note
Posting a Service Invoice
Posting a Service Credit Note
Posting a 'Mix and Match' Invoice
Posting a 'Mix and Match' Credit Note
Adding an Item Line to an Invoice
Posting a Product Invoice with an Item Line Discount
Posting a Product Invoice with Item Vat amendable
Posting a Product Invoice with Net Value Discount
Posting a Purchase Order
Posting a Purchase Order with Item Vat amendable
Adding an Item Line to a Purchase Order
Posting a Sales Order
Adding an Item to a Sales Order
Posting a Sales Order with Net Value Discount
Posting a Sales Order with Item Vat amendable


Sage 50 Accounts - Example - Accessing a Bank Account Memo

Improving memory usage

Introduction

Recently there has been a noticeable shift in the type of SDO applications being written to integrate with Sage 50 Accounts. With more applications being written as services, memory problems with the SDO or its use with .Net are quickly highlighted.

In order to create more memory efficient and reliable applications we have found the use of the System.RunTime.InteropServices Namespace to be of significant benefit in allowing the SDO objects to be marshalled and collected more efficiently.

We also found when using the posting objects Header property to set each field, it created an object for each value being set which wasn’t being destroyed and collected by the .Net Garbage collector as expected.

In light of these findings changes to the SDO Helper class have been made and the following example shows changes to object instantiation and use.
C#.NET [image] Copy C# Code

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using System.Diagnostics;

using System.IO;

using System.Xml;

using System.Runtime.InteropServices;

namespace MemoryUsage

{

            //Declare objects and Instantiate WorkSpace

            SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

            SageDataObject300.Workspaces workspaces = oSDO.Workspaces;

            SageDataObject300.WorkSpace oWS = workspaces.Add("myWorkSpace") as SageDataObject300.WorkSpace;

            //Declare Variables

            String szDataPath;

            //Show select company dialog

            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails

            try

            {

                //Leaving the username and password blank generates a login dialog

                oWS.Connect(szDataPath, "", "", "myWorkSpace");

                //Instantiate objects

                SageDataObject300.SalesRecord oSalesRecord = oWS.CreateObject("SalesRecord") as SageDataObject300.SalesRecord;

                SageDataObject300.InvoicePost oInvoicePost = oWS.CreateObject("InvoicePost") as SageDataObject300.InvoicePost;

                SageDataObject300.StockRecord oStockRecord = oWS.CreateObject("StockRecord") as SageDataObject300.StockRecord;

                /*Create an object for the InvoicePost Header Values, this prevents an object being

                 created for each InvoicePost.Header value */

                SageDataObject300.SDOFile oHeader = oInvoicePost.Header as SageDataObject300.SDOFile;

                //Read the first customer record and use to populate the invoice fields

                oSalesRecord.MoveFirst();

                //Read the First Stock Code & populate fields from Stock Code

                oStockRecord.MoveFirst();

                //Set the invoice type

                oInvoicePost.Type = (SageDataObject300.InvoiceType)SageDataObject300.LedgerType.sdoLedgerInvoice;

                SDOHelper.Write(oHeader, "ACCOUNT_REF", (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));

                SDOHelper.Write(oHeader, "NAME", (String)SDOHelper.Read(oSalesRecord, "NAME"));

                SDOHelper.Write(oHeader, "ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_1"));

                SDOHelper.Write(oHeader, "ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_2"));

                SDOHelper.Write(oHeader, "ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_3"));

                SDOHelper.Write(oHeader, "ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_4"));

                SDOHelper.Write(oHeader, "ADDRESS_5", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_5"));

                SDOHelper.Write(oHeader, "DEL_ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_1"));

                SDOHelper.Write(oHeader, "DEL_ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_2"));

                SDOHelper.Write(oHeader, "DEL_ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_3"));

                SDOHelper.Write(oHeader, "DEL_ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_4"));

                SDOHelper.Write(oHeader, "DEL_ADDRESS_5", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_5"));

                SDOHelper.Write(oHeader, "CUST_TEL_NUMBER", (String)SDOHelper.Read(oSalesRecord, "TELEPHONE"));

                SDOHelper.Write(oHeader, "CONTACT_NAME", (String)SDOHelper.Read(oSalesRecord, "CONTACT_NAME"));

                SDOHelper.Write(oHeader, "GLOBAL_TAX_CODE", (Int16)SDOHelper.Read(oSalesRecord, "DEF_TAX_CODE"));

                //Populate other invoice header information

                SDOHelper.Write(oHeader, "INVOICE_DATE", DateTime.Today);

                SDOHelper.Write(oHeader, "NOTES_1", "Notes 1");

                SDOHelper.Write(oHeader, "NOTES_2", "Notes 2");

                SDOHelper.Write(oHeader, "NOTES_3", "Notes 3");

                SDOHelper.Write(oHeader, "TAKEN_BY", "Chris Reed");

                SDOHelper.Write(oHeader, "ORDER_NUMBER", "");

                SDOHelper.Write(oHeader, "CUST_ORDER_NUMBER", "");

                SDOHelper.Write(oHeader, "PAYMENT_REF", "");

                // If anything is entered in the GLOBAL_NOM_CODE, all of the updated invoice’s splits will have this nominal code and

                // also this willforce anything entered in the GLOBAL_DETAILS field into the all the splits details field.

                SDOHelper.Write(oHeader, "GLOBAL_NOM_CODE", "");

                SDOHelper.Write(oHeader, "GLOBAL_DETAILS", "");

                SDOHelper.Write(oHeader, "INVOICE_TYPE_CODE", (Byte)SageDataObject300.InvoiceType.sdoProductInvoice);

                //Create and invoice item

                //Need to invoke the Add method

                SageDataObject300.SDOCollection items = oInvoicePost.Items as SageDataObject300.SDOCollection;

                SageDataObject300.InvoiceItem oInvoiceItem = SDOHelper.Add(items) as SageDataObject300.InvoiceItem;

                SDOHelper.Write(oInvoiceItem, "STOCK_CODE", SDOHelper.Read(oStockRecord, "STOCK_CODE"));

                SDOHelper.Write(oInvoiceItem, "DESCRIPTION", SDOHelper.Read(oStockRecord, "DESCRIPTION"));

                SDOHelper.Write(oInvoiceItem, "NOMINAL_CODE", SDOHelper.Read(oStockRecord, "NOMINAL_CODE"));

                SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)SDOHelper.Read(oStockRecord, "TAX_CODE"));

                //Populate other invoice item fields

                SDOHelper.Write(oInvoiceItem, "QTY_ORDER", 1);

                SDOHelper.Write(oInvoiceItem, "UNIT_PRICE", 200);

                SDOHelper.Write(oInvoiceItem, "NET_AMOUNT", 200);

                SDOHelper.Write(oInvoiceItem, "TAX_AMOUNT", 0);

                SDOHelper.Write(oInvoiceItem, "COMMENT_1", "Comment 1");

                SDOHelper.Write(oInvoiceItem, "COMMENT_2", "Comment 2");

                SDOHelper.Write(oInvoiceItem, "UNIT_OF_SALE", "");

                SDOHelper.Write(oInvoiceItem, "FULL_NET_AMOUNT", 200);

                SDOHelper.Write(oInvoiceItem, "TAX_RATE", 0);

                //Update the invoice

                bool success = oInvoicePost.Update();

                /* The GC is not aware of the unmanaged resources wrapped by the

                managed resource. We need to call the FinalReleaseComObject from

                the Marshal class in the System.Runtime.InteropServices Namespace*/

                Marshal.FinalReleaseComObject(oInvoiceItem);

                oInvoiceItem = null;

                Marshal.FinalReleaseComObject(items);

                items = null;

                Marshal.FinalReleaseComObject(oHeader);

                oHeader = null;

                Marshal.FinalReleaseComObject(oInvoicePost);

                oInvoicePost = null;

                Marshal.FinalReleaseComObject(oStockRecord);

                oStockRecord = null;

                Marshal.FinalReleaseComObject(oSalesRecord);

                oSalesRecord = null;

                //Disconnect

                oWS.Disconnect();

                Marshal.FinalReleaseComObject(oWS);

                oWS = null;

                Marshal.FinalReleaseComObject(workspaces);

                workspaces = null;

                Marshal.FinalReleaseComObject(oSDO);

                oSDO = null;

                GC.WaitForPendingFinalizers();

                GC.Collect();

                MessageBox.Show(string.Format("invoice posted"));

            }

            catch (Exception ex)

            {

                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message,"Error!");

            }

}// namespace


Sage 50 Accounts - Example - Accessing a Bank Account Memo

Sage Drive Data

Introduction

Sage 50 Accounts with Sage Drive* - an innovative new way to access your data via the cloud. The simple infographic below explains how Sage 50 Accounts and Sage Drive* will work seamlessly together.

On the left is Sage 50 Accounts. All the functionality you know and love with the option to add extra users or companies and industry specific apps. On the right is Sage Drive*. The added freedom of cloud working, be it with your accountant or home workers. Sage Drive* enables access to your accounts via mobile and tablet apps* or connected devices.

SDO and Sage Drive

At the time of writing, access to Sage Drive Data is granted only to Sage Mobile Devices and the desktop application itself. Data access via the SDO has not changed in its implementation. You are still required to create an SDO connection with the data held on a file server or client PC. The new data service will then do all of the work in terms of committing the data to Sage Drive if configured and licenced. The Data Service also checks for changes made by mobile devices and updates the local data with any recognised changes.


Access Type Constants

Access Types

Enumeration name

AccessType

Values

The following table lists the constants for Access Types:

Constant | Value | Description
sdoAccessNone | 1 | No Access to option.
sdoAccessPart | 2 | Part Access to option.
sdoAccessFull | 4 | Full Access to option.

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.AccessTypes

Applies To

These constants are used in conjunction with the following objects:

Object | Fields
AccessData | All fields except NAME and PASSWORD.


Ledger Constants

Address Types

Enumeration name

AddressType

Values

The following table lists the constants for the Address Types:

Constant | Value | Description
sdoDeliveryAddress | 0 | Delivery Address
sdoContactAddress | 1 | Contact Address
sdoRegisteredAddress | 2 | Registered Address

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.AddressTypes

Remarks

These constants are used to return the type of Address.

Applies To

These constants are used in conjunction with the following objects:

Object | Property
CompanyAddress | Type
CustomerAddress | Type
SupplierAddress | Type

Examples Using this Object

Create a new Customer Address
Create a new Supplier Address


Ageing Type Constants

Ageing Types

Enumeration name

TransactionAgeingType

Values

The following table lists the constants for Ageing Types:

Constant | Value | Description
sdoAgeByPeriod | 0 | Age Transactions by Period
sdoAgeByCalendarMonth | 1 | Age Transactions by Calendar Month
sdoAgeByDay | 2 | Age Transactions by Days

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.TransactionAgeingType

Applies To

These constants are used in conjunction with the following objects:

Object | Field
SetupData | SALES_CAL_MTH_AGED
SetupData | PURCHASE_CAL_MTH_AGED

These constants are also used in conjunction with the following object:
Object | Method
AgedBalances | SetAgedMode(TransactionAgeingType)


Bank Account Type Constants

Bank Account Types

Enumeration name

BankType

Values

The following table lists the constants for the Bank Account Types:

Constant | Value | Description
sdoTypeCheque | 1 | Cheque Account
sdoTypeCash | 2 | Cash Account
sdoTypeCredit | 4 | Credit Card Account

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.BankType

Applies To

These constants are used in conjunction with the following objects:

Object | Field
BankData | ACCOUNT_TYPE
BankRecord | ACCOUNT_TYPE


Bank Reconciliation Type Constants

Bank Reconciliation Types

Enumeration name

BankReconType

Values

The following table lists the constants for the Bank Reconciliation Types:

From Sage 50 Accounts v12 new constant values were introduced along with the updated Bank Reconciliation feature. In Sage 50 Accounts 2007 constant values 0 and 1 were not used. These values may be seen in data sets from Sage 50 Accounts 2007, if the data has been updated from a previous version.

Constant | Value | Appears in Sage 50 Accounts as | Description
sdoBankNotApplicable 0 '-' Not Applicable
sdoBankReconciled | 1 | 'R' | Reconciled
sdoBankUnreconciled | 0 | 'N' | Not Reconciled
sdoBankAdjustment | 65 | 'A' | Adjustment
sdoBankCleared | 67 | 'C' | Cleared
sdoBankEreconciled | 69 | 'E' | E Reconciled
sdoBankUnreconciled | 78 | 'N' | Not Reconciled
sdoBankNotApplicable 78 '-' Not Applicable
sdoBankReconciled | 82 | 'Y' | Reconciled

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.BankReconType

Remarks

Note: The Not Applicable and Not Reconciled flags depend on a combination of the value and transaction type. For example, a Sales Invoice would be flagged as Not Applicable.

Applies To

These constants are used in conjunction with the following objects:

Object | Field
BankHeaderData | BANK_FLAG
HeaderData | BANK_FLAG
SplitData | BANK_FLAG


Business Type Constants

Business Types

Enumeration name

BusinessType

Values

The following table lists the constants for the Business Types:

Constant | Value
btAgriculture | 0
btMining | 1
btConstruction | 2
btManufacturingFoodTobaccoAlchoholAndRelatedProducts | 3
btManufacturingOtherNonDurableGoodsClothing | 4
btManufacturingDurableGoodsCars | 5
btTransport | 6
btCommunicationsElectricGasSanitary | 7
btWholesaleDurableGoods | 8
btWholesaleNonDurableGoods | 9
btRetail | 10
btAccounts | 11
btFinanceInsuranceRealEstate | 12
btBusinessSevices | 13
btGovernmentLegalAndEducaton | 14
btLeisureAndPersonalServices | 15
btMembershipNonCommercial | 16
btOther | 17

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.BusinessType

Applies To

These constants are used in conjunction with the following objects:

Object | Method
SDOEngine | Register


Ledger Constants

Contact History Major Contact Types

Enumeration name

ContactHistoryMajorContactType

Values

The following table lists the constants for the Contact History Major Contact Types:

Constant | Value | Description
sdoLetterFaxEmail | 0 | Letter Fax or Email
sdoMeeting | 1 | Meeting
sdoTelephone | 2 | Telephone

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.ContactHistoryMajorContactType

Remarks

These constants are used to return the type of ContactHistoryMajorContactType.

Applies To

These constants are used in conjunction with the following objects:

Object | Property
ContactHistory | Type
ContacyHistorys | Type

Examples Using this Object

View Contact History Properties
Edit a Contact History Item
Create New Contact History Item


Ledger Constants

Contact History Outcome

Enumeration name

ContactHistoryOutcome

Values

The following table lists the constants for the Contact history Outcome:

Constant | Value | Description
sdoNoContact | 0 | No Contact
sdoMeeting | 1 | Meeting
sdoContactMade | 2 | Contact made
sdoCallThemBack | 3 | Call them back
sdoTheyWillCallBack | 4 | They will call back
sdoSendReminder | 5 | Send Reminder
sdoSendWarning | 6 | Send warning
sdoSendLegal | 7 | Send legal
sdoSendOther | 8 | Send other
sdoReminderReceived | 9 | Reminder received
sdoWarningReceived | 10 | Warning received
sdoLegalReceived | 11 | Legal received
sdoOtherReceived | 12 | Other received
sdoSendLetter | 13 | Send letter
sdoPaymentPromised | 14 | Payment promised
sdoDispute | 15 | Dispute
sdoSent | 16 | Sent
sdoReceived | 17 | Received
sdoProduced | 18 | Produced

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.ContactHistoryOutcome

Remarks

These constants are used to return the type of ContactHistoryOutcome.

Applies To

These constants are used in conjunction with the following objects:

Object | Property
ContactHistory | Type
ContacyHistorys | Type

Examples Using this Object

View Contact History Properties
Edit a Contact History Item
Create New Contact History Item


Ledger Constants

Contact History SubContact Type

Enumeration name

ContactHistorySubContactType

Values

The following table lists the constants for the Address Contact history SubContact Types:

Constant | Value | Description
sdoTelephoneMade | 0 | No Contact
sdoTelephoneReceived | 1 | Meeting
sdoLetterReceived | 2 | Contact made
sdoFaxReceived | 3 | Call them back
sdoEmailReceived | 4 | They will call back
sdoLetterSent | 5 | Send Reminder
sdoFaxSent | 6 | Send warning
sdoEmailSent | 7 | Send legal
sdoMeetingPlaced | 8 | Send other

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.ContactHistorySubContactType

Remarks

These constants are used to return the type of ContactHistorySubContactType.

Applies To

These constants are used in conjunction with the following objects:

Object | Property
ContactHistory | Type
ContacyHistorys | Type

Examples Using this Object

View Contact History Properties
Edit a Contact History Item
Create New Contact History Item


Ledger Constants

Contact Types

Enumeration name

ContactType

Values

The following table lists the constants for the Contact Types:

Constant | Value | Description
sdoCustomerContact | 67 | Customer contact
sdoSupplierContact | 83 | Supplier contact

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.ContactType

Remarks

These constants are used to return the type of ContactType.

Applies To

These constants are used in conjunction with the following objects:

Object | Property
ContactHistory | Type
ContacyHistorys | Type

Examples Using this Object

View Contact History Properties
Edit a Contact History Item
Create New Contact History Item


Control Account Type Constants

Control Account Types

Enumeration name

ControlTypes

Values

The following table lists the constants for the Control Types:

Constant | Value | Description
sdoNtNormal | 0 | Nominal Account
sdoNtBank | 1 | Bank Account
sdoNtDebtors | 2 | Debtors Control Account
sdoNtCreditors | 3 | Creditors Control Account
sdoNtDefaultBank | 4 | Default Bank Account
sdoNtSalesTax | 5 | Sales Tax Control Account
sdoNtPurchaseTax | 6 | Purchase Tax Control Account
sdoNtSalesDiscount | 7 | Sales Discount
sdoNtPurchaseDiscount | 8 | Purchase Discount
sdoNtRetainedEarnings | 9 | Retained Earnings
sdoNtDefaultSales | 10 | Default Sales Account
sdoNtAccruals | 11 | Accruals Account
sdoNtPrepayments | 12 | Prepayments Account
sdoNtBadDebts | 13 | Bad Debts Account
sdoNtMispostings | 14 | Mispostings Account
sdoNtSuspense | 15 | Suspense Account
sdoNtDefFinance | 16 | Credit Charge

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.ControlTypes

Applies To

These constants are used in conjunction with the following objects:

Object | Method/Property
NominalRecord | ControlType property
NominalRecord | FindControlAccount method


DiaryEventAccountType

Enumeration name

DiaryEventAccountType

Values

The following table lists the constants for the DiaryEventAccount Types:

Constant | Value | Description
sdoCustomerAccount | 0 | Customer Account
sdoNoLinkedAccount | 1 | No Linked Account
sdoSupplierAccount | 2 | Supplier Account

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.DiaryEventAccountType.

Remarks

These constants are used to return the type of DiaryEventAccountType

Applies To

These constants are used in conjunction with the following objects:

Object | Property
DiaryEvent | Type

Examples Using this Object

Creating a new Diary Event
Reading the last Diary Event


DiaryEventOccurenceTypes

Enumeration name

DiaryEventOccurence

Values

The following table lists the constants for the DiaryEventOccurence Types:

Constant | Value | Description
sdoNotRecurring | 0 | Not Recurring
sdoRecurrenceException | 1 | Recurring Exception
sdoRecurrenceMaster | 2 | Recurrence Master
sdoRecurrenceOccurrence | 3 | Recurrence Occurence

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.DiaryEventOccurenceType.

Remarks

These constants are used to return the type of diary event occurance.

Applies To

These constants are used in conjunction with the following objects:

Object | Property
DiaryEventRecurrence | Type

Examples Using this Object

Creating a new Diary Event
Reading the last Diary Event


DiaryRecurrenceDayOccurrenceTypes

Enumeration name

DiaryRecurrenceEndTypes

Values

The following table lists the constants for the DiaryRecurrenceEndTypes:

Constant | Value | Description
sdoFirst | 0 | Indicates a recurrence on the first instance of a certain day in a month.
sdoSecond | 1 | Indicates a recurrence on the second instance of a certain day in a month.
sdoThird | 2 | Indicates a recurrence on the third instance of a certain day in a month.
sdoFourth | 3 | Indicates a recurrence on the fourth instance of a certain day in a month.
sdoNoEndDate | 4 | Indicates a recurrence on the last instance of a certain day in a month.

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.DiaryRecurrenceDayOccurence

Remarks

These constants are used to return the type of DiaryRecurrenceDayOccurance. For instance, if you want the recurrence to occur on the third Monday of every month, then assign sdoThird to the MonthlyNthDayOccurrence of the DiaryrecurrencePattern object.

Applies To

This constant is used in conjunction with the following objects:

Object | Property
DiaryRecurrencePattern | Type


DiaryRecurrenceDay

Enumeration name

DiaryRecurrenceDay

Values

The following table lists the constants for the DiaryRecurrenceDayTypes:

Constant | Value | Description
sdoSunday | 0 | Sunday
sdoMonday | 1 | Monday
sdoTuesday | 2 | Tuesday
sdoWednesday | 3 | Wednesday
sdoThursday | 4 | Thursday
sdoFriday | 5 | Friday
sdoSaturday | 6 | Saturday

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.DiaryRecurrenceDay

Remarks

These constants are used to return or set the reccurence day. For example if you are wanting a recurrence on the first Monday of every month, this constant is used to represent the 'Monday' part of the recurrence entry.

Applies To

These constants are used in conjunction with the following objects:

Object | Property
DiaryRecurrencePattern | Type


DiaryRecurrenceEndTypes

Enumeration name

DiaryRecurrenceEndTypes

Values

The following table lists the constants for the DiaryRecurrenceEndTypes:

Constant | Value | Description
sdoEndAfterOccurences | 0 | End After Occurrences
sdoEndDate | 1 | End Date
sdoNoEndDate | 2 | No End Date

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.DiaryRecurrenceEndTypes

Remarks

These constants are used to return the type of DiaryRecurrenceEndTypes.

Applies To

These constants are used in conjunction with the following objects:

Object | Property
DiaryRecurrencePattern | Type

Examples Using this Object

Creating a new Diary Event
Reading the last Diary Event


Ledger Constants

DocumentTypeValue

Enumeration name

DocumentTypeValue

Values

The following table lists the constants for the DocumentTypes:

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.DocumentTypeValue.

Constant | Value | Description
sdoReminder | 1 | Reminder
sdoWarning | 2 | Warning
sdoLegalThreat | 3 | Legal Threat
sdoStatements | 4 | Statements
sdoOrdersAndQuotes | 5 | Orders And Quotes
sdoInvoicesAndCredits | 6 | Invoices And Credits
sdoGoodsNotes | 7 | GDN\GRN
sdoRemittances | 8 | Remittances
sdoDefaultLetter | 9 | Default Letter

Remarks

These constants are used to return the type of DocumentTypeValue.

Applies To

These constants are used in conjunction with the following objects:

Object | Property
DocumentType | Type


ESubmission Sender Type Constants

CIS Type

Enumeration name

ESubmissionSenderType

Values

The following table lists the constants for ESubmission Sender Types:

Constant | Value | Description
sdoCompany | 0 | Company
sdoIndividual | 1 | Individual
sdoAgent | 2 | Agent
sdoBureau | 3 | Bureau
sdoPartnership | 4 | Partnership
sdoGovernment | 5 | Government
sdoOther | 6 | Other
sdoTrust | 7 | Trust

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.ESubmissionSenderType

Applies To

These constants are used in conjunction with the following objects:

Object | Property
ESubmissionSetting | CISType


Exception/Error Code Constants

Exceptions/Error Codes

Enumeration name

ErrorCode

Description

As well as returning True or False, a number of methods will throw an exception if the method cannot be completed successfully. You should have an error handler within your code to deal with any exceptions thrown by the SDO.

Values

The following table lists the constants for Exceptions:

Constant | Value | Description
sdoNone | 0 | No Description
sdoInvalidArg | 1 | No Description
sdoArchiveException | 2 | No Description
sdoException | 3 | No Description
sdoDaoException | 4 | No Description
sdoDBException | 5 | No Description
sdoFileException | 6 | No Description
sdoMemoryException | 7 | No Description
sdoNotSupportedException | 8 | No Description
sdoOleException | 9 | No Description
sdoOleDispatchException | 10 | No Description
sdoResourceException | 11 | No Description
sdoUserException | 12 | No Description
sdoUnknownException | 13 | No Description
sdoInvalidOpenMode | 14 | The mode specified for the Open method is invalid.
sdoInvalidName | 15 | The Object Name you are specifying is invalid.
sdoNotConnected | 16 | You are trying to create an object without a valid connection to the Sage 50 Accounts data.
sdoInvalidKey | 17 | No Description
sdoInvalidValue | 18 | No Description
sdoInvalidUse | 19 | No Description
sdoInvalidType | 20 | No Description
sdoLogonFail | 21 | No Description
sdoLogonPassword | 22 | The Password used in the connection is invalid.
sdoLogonNameInUse | 23 | The Logon Name used in the connection is invalid.
sdoLogonExclusive | 24 | Sage 50 Accounts is in exclusive mode. This would occur, for example, if Disk Doctor is in use.
sdoBadDataPath | 25 | The data path used in the connection is invalid.
sdoWrongVersion | 26 | The Sage 50 Accounts data is a different version to the SDO.
sdoBadUpdateMode | 27 | The Update method has been called without previously having called the AddNew or Edit methods.
sdoDeleteFailedHasTrans | 28 | The record cannot be deleted as the account has transactions associated with it.
sdoDeleteFailed | 29 | The record cannot be deleted for a reason other than having transactions associated i.e. there is a balance on the account.
sdoLogonUserCountExceeded | 30 | The connection would cause the user count to be exceeded.
sdoNotRegistered | 31 | The SDO has not been registered on this machine.
sdoReadOnlyAccess | 32 | The object you are trying to update is read only - this applies to the AccessData object.
sdoForTraNotEnabled | 33 | The Foreign Trader Wizard has not yet been completed - please run Sage 50 Accounts and complete the Foreign Trader Wizard.
sdoCurrencyDoesNotMatch | 34 | The Foreign Currency on the account does not match the Foreign Currency on the transaction.
sdoForeignRateSetOnBase | 35 | You are trying to post a BASE transaction with a Foreign Currency Rate - please clear the Foreign Currency Rate.
sdoInvalidSave | 36 | Attempting to save an existing object having failed to Load.
sdoInvalidProjectStatus | 37 | Project status set to not allow postings.
sdoInvalidProject | 38 | Invalid Project.
sdoMaxCostCodes | 39 | Maximum number of project cost codes is 100.
sdoInvalidAllocation | 40 | No Description.
sdoInvalidIssue | 41 | No Description
sdoInvalidFund | 42 | Invalid Fund Type.
sdoInvalidBudget | 43 | Invalid Financial Budget.
sdoZeroValueTransaction | 44 | The transaction must have a value greater than zero.
sdoCannotCreateMultipleRegisteredAddresses | 45 | Only one registered address per customer or supplier.
sdoAttemptedToCreateCalendarEventLabel | 46 | Error creating the diary event label.
sdoAttemptedToEditReadOnlyCalendarEventLabel | 47 | Read Only event label selected for editing.
sdoFileLockedAccountsBusy | 48 | File is locked or busy
sdoClosedLedgerDateControlError | 49 | Date specified is before the closed ledger date
sdoEmptyKey | 50 | No Description
sdoContactHistoryMajorContactTypeNotFound | 51 | Major contact type not found
sdoContactHistorySubContactTypeNotFound | 52 | Sub contact type not found
sdoContactHistoryContactOutcomeNotFound | 53 | Contact outcome not found
sdoContactHistoryInvalidContactTypePassed | 54 | Invalid contact type
sdoContactHistorySubjectNotSpecified | 55 | Subject not specified
sdoContactHistoryDateNotSpecified | 56 | Contact date not specified
sdoContactHistoryPromisedPaymentIsZero | 57 | Promised payment is zero
sdoContactHistoryFollowUpDatePriorToContactDate | 58 | Follow up date prior to contact date
sdoContactHistoryUserNameIsEmptyOrDoesNotExist | 59 | Contact user name is empty or does not exist
sdoContactHistoryMajorContactTypeDiffers | 60 | Major contact type differs
sdoContactHistoryInvalidSubContactTypeForMajorType | 61 | Invalid sub contact type for major type
sdoContactHistoryInvalidOutcomeForMajorType | 62 | Invalid outcome for major type
sdoEmptyAccountReference | 63 | Empty Account Ref
sdoDataHasBeenRestored | 64 | Data Raised if data has been restored from a backup whilst an active SDO connection was in place. Client code MUST disconnect, and attempt reconnect following completion of the restore.
sdoInvalidNominalCode | 65 | Invalid nominal code
sdoBankAccountNotAvailable | 66 | Bank account not available
sdoBankAccountIsControl | 67 | Bank account is control account
sdoBankIsNotBaseCurrency | 68 | Bank account is not base currency
sdoInvalidCostCode | 69 | Invalid cost code
sdoSalPurAccountIsOnHold | 70 | Sales or purchase account is on hold
sdoSalPurAccountIsInactive | 71 | Sales or purchase account is inactive
sdoSalPurAccountDeleted | 72 | Sales or purchase account has been deleted
sdoSalPurAccountTermsNotAgreed | 73 | Sales or purchase account has terms not agreed set
sdoSalPurAccountNotBaseCurrency | 74 | Sales or purchase account is not in base currency
sdoInvalidTransactionNumber | 75 | Invalid transaction number
sdoInvalidTaxCodeForPayment | 76 | Invalid tax code for payment
sdoSagePaymentsMismatch | 77 | Sage Payments mismatch
sdoZeroValueNet | 78 | Zero value net
sdoTransactionCannotHaveProject | 79 | Transaction cannot have project
sdoProjectSetButNotACostCode | 80 | Project set but not a cost code
sdoCostCodeSetButNotAProject | 81 | Cost code set but not a project
sdoAccountRefContainsSpaces | 82 | Account ref contains spaces
sdoAddressLinesTooLong | 83 | Address lines too long
sdoAccountRefAlreadyExists | 84 | Account ref already exists
sdoTransactionCannotHaveCostCode | 85 | Transaction cannot have cost code
sdoAccountRefContainsInvalidCharacters | 86 | Account ref contains invalid characters
sdoInvalidDate | 87 | Invalid date
sdoNominalAccountIsControl | 88 | Nominal account is a control account
sdoInvoiceTotalNegative | 89 | Total value on Invoice is negative
sdoIncorrectStockCodeType | 90 | Incorrect stock code/invoice type for negative line
sdoConnectionKickedOut | 91 | Raised if a client connected via SDO was actively disconnected e.g. admin forcibly disconnects the user. Client code MUST disconnect but may attempt reconnect following this.
sdoUnableConnectToDataService | 94 | No Description
sdoCannotChangeCurrencyWhenTransactionsExist | 95 | No Description
sdoCannotChangeCurrencyWhenForeignTraderNotEnabled | 96 | No Description
sdoCanNotUsePostponedAccountingTaxCode | 97 | No Description
sdoCanNotUseNonCUImportExportTaxCode | 98 | No Description
sdoCannotChangeCompanyDetailsRemoteSites | 99 | No Description
sdoOSSSettingsMismatch | 100 | No Description
sdoOnServiceAvailabilityException | 101 | Raised if connectivity to an external service (e.g. RDA, Sage ID, or even Internet connectivity itself) is lost whilst an active SDO connection was in place. Client code MUST disconnect, and attempt reconnect following this.
sdoOnTokenExpiredException | 102 | Raised if the authentication token used to sync with RDA has expired whilst an active SDO connection was in place. Client code MUST stop processing on this dataset, disconnect, and resolve the issue by logging on via the main Accounts UI.
sdoOnAuthTimedoutException | 103 | Raised if the authentication token used to sync with RDA has expired whilst an active SDO connection was in place and a subsequent attempt to authorise resulted in a timeout i.e. server did not respond within the timeout period. Client code MUST stop processing on this dataset, disconnect, and resolve the issue by logging on via the main Accounts UI.
sdoOnAccessToDatasetRevokedException | 104 | Raised if the dataset is set up to sync with RDA but access to RDA has been revoked e.g. admin removes user permissions. Client code should stop processing on this dataset as changes will be lost.
sdoOnAccessDeniedBySageIDException | 105 | Raised if the dataset is set up to sync with RDA but the SageID account used to set this up is unable to complete authentication e.g. account locked due to too many log on. Client code MUST disconnect and stop processing on this dataset until the issue is resolved.
sdoOnDataForkDetectedException | 106 | Raised if the dataset is set up to sync with RDA but a conflict is detected between data held in the cloud Vs the data held locally, and conflict resolution is required by the end user. Client code MUST stop processing on this dataset, disconnect, and resolve the issue by logging on via the main Accounts UI.
sdoOnServerNotCapableException | 107 | Raised if the data service holding the data is an older version Vs the client version (SDO being the client in this case) and the client has requested the server perform an action that it is not capable of i.e. function does not exist in the older server version. Client code should stop processing on this dataset, disconnect, and resolve the issue by upgrading the data service.
sdoOnConnectionClosedException | 108 | No Description
sdoOnDatasetLimitReachedException | 109 | Raised if the dataset is set up to sync with RDA but the volume of data being synchronised exceeds the daily limit. Client code MUST stop processing on this dataset until the limit is raised or the checking period rolls over i.e. the following day.
sdoOnTooManyRequestsException | 110 | Raised if the dataset is set up to sync with RDA but the total number requests being issued to RDA exceeds a configured limit. Client code MUST stop processing on this dataset and perform a back off until the cooldown period is passed.
sdoOnDatasetRemovedException | 111 | Raised if the dataset is set up to sync with RDA but that dataset has subsequently been removed from RDA e.g. admin turns off RDA . Client code should stop processing on this dataset as changes will be lost.
sdoOnInvalidClientException | 112 | Raised if the authentication token used to sync with RDA has expired whilst an active SDO connection was in place and a subsequent authentication attempt was made but the Sage ID used does not match the one RDA was originally set up with. Client code MUST stop processing on this dataset, disconnect, and resolve the issue by logging on via the main Accounts UI.
sdoOnSageIDTimeOutOfSyncException | 113 | Raised if the authentication token used to sync with RDA has expired whilst an active SDO connection was in place and a subsequent authentication attempt resulted in an error due to the local system time being invalid i.e. the system clock is set to the incorrect date/time. Client code MUST stop processing on this dataset, disconnect, and resolve the issue by logging on via the main Accounts UI.
sdoOnDataServiceMessageException | 114 | Raised if the data service encountered an error whilst running. Client code MUST stop processing on this dataset, disconnect, and resolve the issue by logging on via the main Accounts UI and confirming data service and the data itself are operating correctly.
sdoOnBadHandshakeException | 115 | Raised if the initial handshake attempt with the data service failed. Client code would be unable to connect to the data in any event if this occurred. Most likely this would be an installation issue so repair the install and confirm connectivity via the main Accounts UI.
sdoOnDataProviderErrorException | 116 | Raised if the dataset is set up to sync with RDA but the RDA service returned an error when processing the data. Client code MUST stop processing on this dataset, disconnect, and resolve the issue by logging on via the main Accounts UI.
sdoOnMainSiteDisconnectException | 117 | only for legacy support as from v28 onwards there is no longer a concept of main and remote sites. All sites are now equal so this will never occur in v28 onwards. For v27 and earlier this is raised if you are on a remote site and the main site has become unavailable for some reason. In the main Accounts UI this triggers the do you want to work offline prompt. Recommendation would be that client code stop processing as data loss could occur otherwise, the client can continue processing with the caveat/warning that data loss could occur.
sdoOnSageHardDriveLimitExceededException | 118 | Raised if the dataset is set up to sync with RDA and another site has made a significant data change e.g. restored a back-up meaning the local site must rebase. Client code MUST stop processing on this dataset, disconnect, and reconnect after the rebase has completed.
sdoOnInvalidSyncStateLoopDetectedException | 119 | Raised if the dataset is set up to sync with RDA but unreconcilable conflicts have been encountered with processing changes from other sites. Client code MUST stop processing on this dataset, disconnect, and resolve the issue by logging on via the main Accounts UI.
sdoOnLockDownException | 120 | Raised if the dataset is set up to sync with RDA, unreconcilable conflicts have been encountered with processing changes from other sites and another client is in the process of correcting the issue (performing a rebase). Client code MUST stop processing on this dataset, disconnect, and can reconnect once the issue is resolved
sdoOnDataServiceDisconnectedException | 121 | Raised if connectivity to the data service has been lost whilst there was an active SDO connection e.g. data service or the OS crashed or lost network connectivity. Client code would be unable to continue to process the data in any event if this occurred. Need to correct the issue and reconnect/retry later.
sdoOnFailedAuthAttemptException | 122 | Raised if the dataset is set up to sync with RDA but a general authentication error was encountered with the Sage ID being used. Client code should stop processing on this dataset as changes will be lost and resolve the issue by logging on via the main Accounts UI.
sdoOnConnectionClosed | 123 | Raised if a client connected via SDO was unexpectedly disconnected e.g. server crash or reboot. Client code MUST disconnect but may attempt reconnect following this.
sdoOnRestoreBaselineFailed | 124
sdoOnFailedToBackupLocalDataBeforeOverwritten | 125

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.ErrorCode

Applies To:

These constants are used in conjunction with the following objects:

Object | Property
SDOError | Code


Invoice Item Type Constants

Invoice Item Types

Enumeration name

InvoiceItemType

Values

The following table lists the constants for the Invoice Item Types:

Constant | Value | Description
sdoItemStock | 0 | Standard Stock Item Invoice
sdoItemService | 1 | Standard Service Invoice Without Access to the Memo Field Levels Set
sdoItemQtyService | 2 | Service Invoice with the Memo option Enabled to allow more extensive text

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.InvoiceItemType

Remarks

sdoItemQtyService must be used when creating stock/service invoices.

Applies To

These constants are used in conjunction with the following objects:

Object | Field
InvoiceItem | SERVICE_FLAG
SOPItem | SERVICE_FLAG


Invoice Type Constants

Invoice/Order Types

Enumeration name

InvoiceType

Values

The following table lists the constants for the Invoice/Order Item Types:

Constant | Value | Description
sdoProductInvoice | 0 | Sales Order or Product Invoice originating from Invoicing
sdoSopInvoice | 1 | Product Invoice originating from Sales Order Processing
sdoServiceInvoice | 2 | Service Invoice
sdoProductCredit | 3 | Product Credit Note
sdoServiceCredit | 4 | Service Credit Note
sdoProductProforma | 5 | Product Invoice Proforma
sdoProductQuotation | 6 | Product Invoice Quotation
sdoServiceProforma | 7 | Service Invoice Proforma
sdoServiceQuotation | 8 | Service Invoice Quotation
sdoSopQuote | 9 | Sales Order Quotation
sdoSopProforma | 11 | Sales Order Proforma

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.InvoiceType

Remarks

These constants apply only to Sales Invoices/Credit Notes and Sales Orders. Purchase Orders have only one type and do not need these constants.

Applies To

These constants are used in conjunction with the following objects:

Object | Field
InvoiceData | INVOICE_TYPE_CODE
InvoicePost | INVOICE_TYPE_CODE
InvoiceRecord | INVOICE_TYPE_CODE
SOPData | ORDER_TYPE
SOPPost | ORDER_TYPE
SOPRecord | ORDER_TYPE


Ledger Constants

Ledger Types (Invoice/SOP/POP Post)

Enumeration name

LedgerType

Values

The following table lists the constants for the Ledger Types:

Constant | Value | Description
sdoLedgerInvoice | 261 | Product Invoice
sdoLedgerService | 264 | Service Invoice
sdoLedgerCredit | 265 | Purchase Credit Note
sdoLedgerSop | 267 | Sales Order
sdoLedgerPop | 268 | Purchase Order
sdoLedgerServiceCredit | 279 | Service Credit Note

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.LedgerType

Remarks

These constants are used to enable the GetNextNumber method to return the correct Invoice/Order number.

Applies To

These constants are used in conjunction with the following objects:

Object | Property
InvoicePost | Type
SOPPost | Type
POPPost | Type


Lock Date Permission

LockDatePermission Types

Enumeration name

LockDatePermissionType

Values

The following table lists the constants for the LockDatePermission Types:

Constant | Value | Description
sdoLockDatePostingPermitted | 0 | Transaction date is valid and not affected by lock date functionality. Transactions posted with this date are unaffected by the lock date functionality
sdoLockDateUserCanOverride | 1 | Transaction date is within a locked period but the logged on user can override (i.e. user is manager or user has been assigned the appropriate access right). Transactions posted with this date will post but will be flagged as overriden by the user.
sdoLockDatePostingDenied | 2 | Transaction date is within a locked period and the logged on user does not have permission to override. Transactions posted with this date will cause TranPost::Update to throw an exception.

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.LockDatePermission

Remarks

These constants apply only to the SetupData object.

Applies To

These constants are used in conjunction with the following objects:

Object | Method
SetupData | IsDateValidForLockDate


Nominal Account Type Constants

Nominal Account Types

Enumeration name

NominalType

Values

The following table lists the constants for the Nominal Account Types:

Constant | Value | Description
sdoTypeNormal | 1 | Nominal Account
sdoTypeBank | 2 | Bank Account
sdoTypeControl | 4 | Control Account

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.NominalType

Applies To

These constants are used in conjunction with the following objects:

Object | Field
NominalData | ACCOUNT_TYPE
NominalRecord | ACCOUNT_TYPE


CIS Card Type Constants

Nominal Category Types

Enumeration name

NominalCategory

Values

The following table lists the constants for the various Nominal Category Types:

Constant | Value | Description
sdoSales | 1 | Sales
sdoPurchases | 2 | Purchases
sdoDirectExpenses | 3 | Direct Liabilities
sdoOverheads | 4 | Overheads
sdoFixedAssets | 5 | Fixed Assets
sdoCurrentAssets | 6 | Current Assets
sdoCurrentLiabilities | 7 | Current Liabilities
sdoLongTermLiabilities | 8 | Long Term Liabilities
sdoCapitalReserves | 9 | Capitals and Reserves

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.NominalCategory

Applies To

These constants are used in conjunction with the following object:

Object | Property
FinancialBudget | NomCategory


Quotation Status Constants

Object Type

Enumeration name

ObjectType

Values

The following table lists the constants for the Object Type:

Constant | Value | Description
sdoDataFile | 0 | This object refers to a Data File (e.g. SalesData)
sdoIndexFile | 1 | This object refers to an Index File (e.g. SalesIndex)
sdoRecord | 2 | This is a Record Object (e.g. SalesRecord)
sdoLinkedFile | 3 | This is a linked file object (e.g. InvoiceItem)
sdoRecordLinkedFile | 4 | This is a record linked file object (e.g. BankRecord)
sdoLinkedSubFile | 5 | This is a linked sub file object (e.g. BankHeaderData)
sdoPosting | 6 | This is a posting object (e.g. TransactionPost)
sdoBusinessObject | 7 | Theis is a business object (e.g. Project)
sdoUndefinedObject | -1 | This object is of an undefined type

Note: To use these constants in Visual Basic .NET or C#, prefix the constant name with SageDataObject300.ObjectType

Remarks

This enumeration describes the Type of a Workspace.DataObjects.Item. This is a collection of DataObjects that provides metadata on the Sage Data Objects.

Applies To

These constants are used in conjunction with the following objects:

Object | Property
Workspace.DataObjects.Item | Type


Open Mode Constants

Open Modes

Enumeration name

OpenMode

Values

The following table lists the constants for the file Open Modes:

Constant | Value
sdoRead | 0
sdoReadWrite | 1
sdoWrite | 2
sdoShareExclusive | 16
sdoShareDenyWrite | 32
sdoShareDenyRead | 48
sdoShareDenyNone | 64
sdoDelete | 512
sdoCreate | 4096
sdoExist | 16384

Applies To

These constants are used in conjunction with the following objects:

Object | Method
SDOFile | Open
SDOLinkedFile | Open
SDOLinkedSubFile | Open


Sales Order Status Constants

Sales Order Status

Enumeration name

OrderStatusType

Values

The following table lists the constants for the Sales Order Status:

Constant | Value | Allocated | Dispatched
sdoZeroAlloc | 0 | Blank | Blank
sdoPartAlloc | 1 | Part | Blank
sdoFullAlloc | 2 | Full | Blank
sdoCancelled | 3 | Cancelled | Blank
sdoPartZeroAlloc | 4 | Blank | Part
sdoPartPartAlloc | 5 | Part | Part
sdoPartFullAlloc | 6 | Full | Part
sdoPartCancelled | 7 | Cancel | Part
sdoComplete | 8 | Blank | Complete
sdoHeldPart | 9 | Held | Part
sdoHeld | 10 | Held | Blank

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.OrderStatusType

Remarks

The Allocated and Dispatched columns represent the same named columns in the Sage 50 Accounts Sales Order Processing screen. When nothing appears in a column it is assumed to be blank. E.g. A new Sales Order has no stock allocated or dispatched, therefore both columns are listed here as Blank. (See sdoZeroAlloc)

Applies To

These constants are used in conjunction with the following objects:

Object | Field
SOPData | STATUS
SopPost | STATUS
SOPRecord | STATUS


Program Type Constants

Program Types

Enumeration name

ProgramTypes

Values

The following table lists the constants for the Program Types:

Constant | Value | Description
sdoProgramFinCon | 1 | Accounts Professional
sdoProgramAccPlus | 2 | Accounts Plus

4 Standard (Accounts)
sdoProgramInstant | 16 | Instant Accounts
sdoProgramInstplus | 64 | Essentials (Instant Accounts Plus)
sdoProgramClientMgr | 128 | Accounts Client Manager
sdoProgramStartUp | 1024 | Start Up

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.ProgramTypes

Applies To

These constants are used in conjunction with the following objects:

Object | Field
SetupData | PROGRAM_TYPE
Workspace | ProgramType method


Ledger Constants

Request Types

Enumeration name

RequestType

Values

The following table lists the constants for the Request Types:

Constant | Value
sdoREQUEST_DOCTOR | 1
sdoBackup | 2
sdoRestore | 3
sdoLOGON | 4
sdoREQUEST_IMPORT | 5
sdoREQUEST_PREPAYMENTS | 6
sdoREQUEST_ACCRUALS | 7
sdoRECURRING | 8
sdoUPDATELEDGER | 9
sdoMONTHEND | 10
sdoYEAREND | 11
sdoCONTROLACC | 12
sdoINVDEL | 13
sdoSOPDEL | 14
sdoPOPDEL | 15
sdoBANKREC | 16
sdoINVACCESS | 17
sdoSOPACCESS | 18
sdoPOPACCESS | 19
sdoCOMPPREF | 20
sdoSALDEFAULTS | 21
sdoPURDEFAULTS | 22
sdoSTKDEFAULTS | 23
sdoACCESSRIGHTS | 24
sdoTAXCODES | 25
sdoCURRENCY | 26
sdoDEPARTMENTS | 27
sdoPRODCAT | 28
sdoCONSOL | 29
sdoLAYOUT | 30
sdoINVPRN | 31
sdoSOPPRN | 32
sdoPOPPRN | 33
sdoNEW_COMPANY | 34
sdoDELETE_COMPANY | 35
sdoGLOBAL_CHANGE | 36
sdoDELETE_RECORDS | 37
sdoCLEARSTOCK | 38
sdoCLEARAUDIT | 39
sdoWRITEOFF | 40
sdoCONTRA | 41
sdoUPGRADEPROGRAM | 42
sdoDEFINV | 43
sdoDEFASS | 44
sdoREPORTS | 45
sdoSAL_RECEIPTS | 46
sdoPUR_PAYMENTS | 47
sdoVATRETURN | 48
sdoEIS | 49
sdoRETURNOFTRADINGDETAILS | 50
sdoEDIT_CONTACT | 51
sdoEDIT_TODO | 52
sdoFINANCE_CHARGE | 53
sdoRATES | 54
sdoBATCHPAYMENT | 55
sdoSALDISPUTES | 56
sdoPURDISPUTES | 57
sdoSTARTUP | 58
sdoFINYEARCHANGE | 59
sdoMULTIADDRESS | 60
sdoPRICELIST | 61
sdoSOP2POP | 62
sdoASSETDISPOSAL | 63
sdoBANKEPAYMENT | 64
sdoBANKERECONCILE | 65
sdoSTK2POP | 66
sdoPOPGRN | 67
sdoNOMREVERSALS | 68
sdoREQUEST_ACCSTATUS | 69
sdoCHEQUEPRINTING | 70
sdoBANKDEFAULTS | 71
sdoARCHIVECOMPANY | 72
sdoRESTOREARCHIVE | 73
sdoFOREIGN_TRADER | 74
sdoNOMCHARTDEFAULT | 75
sdoCONFIGEDITOR | 76
sdoBANKTRANSFER | 77
sdoREQUEST_COUNTRYCODES | 78
sdoSOPINTRASTAT | 79
sdoPOPINTRASTAT | 80
sdoACCOUNTANTSLINK | 81
sdoVIEWCHANGES | 82
sdoVIEWCLIENTCHANGES | 83
sdoCONTACTHIST | 84
sdoREQUEST_PROJECT | 85
sdoEDITRECURRING | 86
sdoPROJECTSTRUCTURE | 87
sdoADVANCEDBUDGETS | 88
sdoAPPLYACCOUNTANTLINK | 89
sdoENABLECIS | 90
sdoACTIVATE_CIS | 91
sdoCISVERIFY | 92
sdoCISSUBMITRETURN | 93
sdoCORRECTIONS | 94
sdoEDIT_CALENDAR_EVENT | 95
sdoFINBUDGET_REBUILD | 96
sdoEDIT_CALENDAR_EVENT_LABELS | 97
sdoDEPOSIT_CASH | 98
sdoSAGEPAY_DOWNLOAD_WIZARD | 99
sdoEMAILDEFAULTS | 100
sdoCUSTOMISEYOURCOMPANY | 101
sdoCOMPANYARCHIVE | 102
sdoGASDS_SETTINGS | 103
sdoDATA_MANAGEMENT_DELETE_STOCK | 104
sdoACTIVATE_FT | 105
sdoENABLE_FT | 106
sdoOPENING_BALANCES | 107
sdoDELETE_FUND | 108
sdoSAGE_DRIVE_SETUP | 109
sdoECSALES | 110
sdoTOOLS_SAGE_DRIVE | 111
sdoSIPS_MISSING_PAYMENTS | 112
sdoBANK_FEEDS | 113
sdoRECURRING_INVOICES | 114
sdoRECURRING_SOP | 115
sdoRECURRING_POP | 116
sdoSAGE_DRIVE_RECONNECT | 117
sdoCASH_FLOW | 118
sdoSUGGEST_PAYMENT | 119
sdoUNALLOCATE_TRANSACTION | 120
sdoLOCK_DATE | 121
sdoREQUEST_CIS_NOMINALS | 122
sdoCONTRA_SAL | 123
sdoCONTRA_PUR | 124
sdoMANAGE_DD | 125
sdoDD_SETTLEMENTS | 126
sdoDD_PAYMENT | 127
sdoINVOICE_PAYMENT_SETTINGS | 128
sdoREVERSE_BANK_RECONCILIATION | 129
sdoBACKGROUND_BACKUP | 130
sdoBACKGROUND_CHECKDATA | 131
sdoLOCAL_CHECKDATA | 132
sdoUPDATING_DATAVERSION | 133
sdoSDI | 134
sdoCONCURRENT_VATRETURN | 135
sdoCORRUPTION_MANAGER | 136
sdoTAX_CODE_CREATION | 137
sdoMTD_SETTINGS | 138
sdoCUSTOM_ALERT | 139
sdoUSER_CREATE | 140
sdoUSER_DELETE | 141
sdoUSER_COPY | 142
sdoUSER_EDIT | 143
sdoUSER_MATCH_EMAIL | 144
sdoSAGEID_CONNECTION | 145
sdoCHANGE_PASSWORD | 146
sdoSAGEID_SETTINGS | 147
sdoOSSIOSS_ACTIVATION | 148
sdoBANK_FEEDS_APPROVAL | 149
sdoDATA_FIXING | 150
sdoDASHBOARD_ACCESS | 151
sdoACTION_END | 32768

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.RequestType

Remarks

These constants are used to return the type of Request.


Stock Item Type Constants

Stock Item Types

Enumeration name

StockItemType

Values

The following table lists the constants for the Stock Item Types:

Constant | Value | Description
sdoStockItem | 0 | Standard Stock Item
sdoNonStockItem | 1 | Stock Item with 'Ignore Stock Levels' Set
sdoServiceItem | 2 | Stock Item with 'Ignore Stock Levels' Set and the facility to use memos

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.StockItemType

Applies To

These constants are used in conjunction with the following objects:

Object | Field
StockData | ITEM_TYPE
StockPost | ITEM_TYPE
StockRecord | ITEM_TYPE


Stock Transaction Type Constants

Stock Transaction Artefact Type

Enumeration name

StockTransArtefactType

Values

The following table lists the constants for Artefact Types:

Constant | Value | Description
StockTransArtefactType | 1 | Stock Transaction originates from an Invoice
StockTransArtefactType | 2 | Stock Transaction originates from a SOP
StockTransArtefactType | 3 | Stock Transaction originates from a POP

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.StockTransType

Applies To

These constants are used in conjunction with the following objects:

Object | Field
StockPost | ARTEFACT_TYPE
StockTran | ARTEFACT_TYPE

Examples Using this constant

Posting a Goods Out


Stock Transaction Type Constants

Stock Transaction Types

Enumeration name

StockTransType

Values

The following table lists the constants for the Stock Transaction Types:

Constant | Value | Description
sdoAI | 1 | Adjustment In
sdoAO | 2 | Adjustment Out
sdoGI | 3 | Goods In
sdoGO | 4 | Goods Out
sdoMI | 5 | Movement In (From Stock Transfer)
sdoMO | 6 | Movement Out (From Stock Transfer)
sdoGR | 7 | Goods Returned
sdoDI | 8 | Damages In
sdoDO | 9 | Damages Out
sdoWO | 10 | Write Off

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.StockTransType

Applies To

These constants are used in conjunction with the following objects:

Object | Field
StockTran | TYPE


Transaction Type Constants

Transaction Types

Enumeration name

TransType

Values

The following table lists the constants for the Transaction Types:

Constant | Value | Description
sdoSI | 1 | Sales Invoice
sdoSC | 2 | Sales Credit
sdoSR | 3 | Sales Receipt
sdoSA | 4 | Sales Receipt on Account
sdoSD | 5 | Sales Discount
sdoPI | 6 | Purchase Invoice
sdoPC | 7 | Purchase Credit
sdoPP | 8 | Purchase Payment
sdoPA | 9 | Purchase Payment on Account
sdoPD | 10 | Purchase Discount
sdoBP | 11 | Bank Payment
sdoBR | 12 | Bank Receipt
sdoCP | 13 | Cash Payment
sdoCR | 14 | Cash Receipt
sdoJD | 15 | Journal Debit
sdoJC | 16 | Journal Credit
sdoVP | 17 | Visa Payment
sdoVR | 18 | Visa Receipt
sdoCC | 19 | Project Cost Credit
sdoCD | 20 | Project Cost Debit - Charge
sdoPAI | 21 | Project Adjustment In
sdoPAO | 22 | Project Adjustment Out
sdoCO | 23 | Project Committed Cost
sdoSP | 24 | Sales Payment
sdoPR | 25 | Purchase Receipt

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.TransType

Applies To

These constants are used in conjunction with the following objects:

Object | Field
BankHeaderData | TYPE
HeaderData | TYPE
SplitData | TYPE
TransactionPost | TYPE
UsageData | TYPE
ProjectTransaction | Type Property


Vat Reconciliation Type Constants

Vat Reconciliation Types

Enumeration name

VatType

Values

The following table lists the constants for the Vat Reconciliation Types:

Constant | Value | Appears in Sage 50 Accounts as | Description
sdoVatNotApplicable 0 '-' Not Applicable
sdoVatReconciled | 1 | 'R' | Reconciled
sdoVatUnreconciled | 0 | 'N' | Not Reconciled

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.VatType

Remarks

Note: The Not Applicable and Not Reconciled flags depend on a combination of the value and transaction type.

Applies To

These constants are used in conjunction with the following objects:

Object | Field
BankHeaderData | VAT_FLAG
HeaderData | VAT_FLAG
SplitData | VAT_FLAG


SDOEngine Object

Description

The SDOEngine object forms the basis for creating a connection to a Sage 50 Accounts data source. Creating a SDOEngine object initialises the object model.

Under normal circumstances, a single instance of the SDOEngine object in an application, declared either Public or Global, is all that is required.

Methods

The SDOEngine object has the following methods:

Method | Description
Register | Allows you to register the SDO on a machine within your own application.
SelectCompany | Displays a dialog box allowing the user to select a dataset.

Properties

The SDOEngine object has the following properties:

Property | Description
IsRegistered | Returns if the SDO is registered or not.
LastError | Returns the last error generated by the SDO.
Workspaces Collection | Returns a list of workspaces created.


Register Method

Description

The Register method allows you to register SDO on a machine within your own application. As SDO can be registered in Sage 50 Accounts, you would typically only use this method if your application is to be installed on a machine that has no installation of Sage 50 Accounts.

Note: In v24.1, it is now no longer necessary to register the SDO. The SDO is already activated and does not require the SDO serial number and activation key to be entered. oSDO.IsRegistered will always return true.

Syntax

The Register method has the following syntax:

object.Register Serial Number, Activation Key, Product, Company, Business Type

with the following parts:

Part | Description
Object | Applies to the SDOEngine object
Serial Number | The SDO Serial Number
Activation Key | The SDO Activation Key
Product | The Name of your application
Company | Your Company Name
Business Type | The Business Type - for a list of Business Type constants, click here.

Return Values

The Register method returns the following values:

Value | Description
True | The SDO was successfully registered.
False | The SDO could not be registered.

Remarks

For a list of possible reasons why the Register method may fail, see the Common Questions & Answers article.

Example

The following example demonstrates the use of the Register method in conjunction with the IsRegistered property:

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine

  ' Create the SDOEngine Object
  oSDO = New SageDataObject300.SDOEngine

  If oSDO.IsRegistered Then

    ' SDO is Registered

  Else

    ' SDO is not Registered so call the Register method

      If oSDO.Register("SD01234", "ABCDEFG", "My Add On", "My Company", btRetail) Then

        ' SDO was registered

      Else

        ' SDO could not be registered

      End If

  End If

  ' Destroy Objects
  oSDO = Nothing

Related Topics

Property | Description
IsRegistered | Determines if the SDO is registered.


SelectCompany Method

Description

The SelectCompany method allows you to present the user with a list of companies they can access. When the method is called, a dialog box appears listing the companies available within Sage 50 Accounts.

If there is only one company dataset in Sage 50 Accounts, the method will return the datapath without displaying a list of companies.

Syntax

The SelectCompany method has the following syntax:

object.SelectCompany Path

with the following parts:

Part | Description
Object | Applies to the SDOEngine object.
Path | Path to the Sage 50 Accounts program installation.

Return Value(s)

The SelectCompany method returns the following values:

Value | Description
DataPath | A string expression holding the data path for the selected company.

Remarks

The DataPath returned by the method can be passed directly to the Connect method of the Workspace object. If the user does not select a company from the dialog box or chooses Cancel, a blank data path is returned by the method - you should check for this in your code.

Example

The following example demonstrates the use of the SelectCompany method:

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace

' Declare Variables
Dim szDataPath As String

' Create the SDOEngine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024\")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

' Try to Connect - Will Throw an Exception if it Fails
If oWS.Connect(szDataPath, "", "", "Example") Then
MsgBox("Connection Established", MsgBoxStyle.OKOnly, "SDO Examples")

' The SelectCompany method has returned a valid data path so code can
' continue here...

 End If

End If

' Destroy the Objects
oWS = Nothing
oSDO = Nothing

Exit Sub

' Error Handling Code
Error_Handler:

Select Case oSDO.LastError.Code

' 3rd Party Integration NOT Enabled - Site Activation
Case Is = SageDataObject300.ErrorCode.sdoNotRegistered
MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OKOnly, "SDO Examples")

' Invalid Password
Case Is = SageDataObject300.ErrorCode.sdoLogonPassword
MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OKOnly, "SDO Examples")

' User is Already Logged On
Case Is = SageDataObject300.ErrorCode.sdoLogonNameInUse
MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OKOnly, "SDO Examples")

' Sage 50 Accounts is in Exclusive Mode i.e. File Maintenance
Case Is = SageDataObject300.ErrorCode.sdoLogonExclusive
MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OKOnly, "SDO Examples")

' Invalid Data Path on Connect
Case Is = SageDataObject300.ErrorCode.sdoBadDataPath
MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OKOnly, "SDO Examples")

' Sage 50 Accounts is not Same Version as SDO
Case Is = SageDataObject300.ErrorCode.sdoWrongVersion
MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OKOnly, "SDO Examples")

End Select
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  MessageBox.Show("Connected!");

  //The SelectCompany method has returned a valid data path so code can
  //continue here...

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}

Related Topics

Method | Description
Connect | Establishes a connection to the Sage 50 Accounts data files.
Disconnect | Terminates the connection to the Sage 50 Accounts data files.
IsValidUser | Allows you to check if a User Name is valid prior to connecting to the data.


IsRegistered Property

Description

The IsRegistered property returns a boolean value that represents if the SDO is registered.

Note: The SDOEngine will allow 30 connections before requiring registration. While it is in this phase the IsRegistered method will return True indicating that the SDO is registered. After 30 connections the method will return false unless the SDO has been registered.

One method of checking to see if the SDOEngine is registered is to look for the file that is created after successful registration. The file SDOEng.usr is located in the programs default settings location, C:\ProgramData\Sage\Accounts\2024

Note: In v24.1, it is now no longer necessary to register the SDO. The SDO is already activated and does not require the SDO serial number and activation key to be entered. oSDO.IsRegistered will always return true.

Syntax

The IsRegistered property has the following syntax:

object.IsRegistered

with the following parts:

Part | Description
Object | Applies to the SDOEngine object

Remarks

This property is Read Only.

Return Values

The IsRegistered property returns the following values:

Return Value | Description
True | The SDO has been registered on the machine. This value can also be returned if Sage 50 has been installed 'as new' on a PC that has never had a previous Sage 50 installation within the last 30 days.
False | The SDO is not registered.

Example

The following example demonstrates the use of the IsRegistered property:

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine

  ' Create the SDOEngine Object
  Set oSDO = New SageDataObject300.SDOEngine

  If oSDO.IsRegistered Then

    ' SDO is Registered

  Else

    ' SDO is not Registered

  End If

  ' Destroy Objects
  Set oSDO = Nothing

  Exit Sub

' Error Handling Code
Error_Handler:

  MsgBox "The SDO generated the following error: " & oSDO.LastError.Text


Last Error Property

Description

The LastError property holds details of the last error returned by the SDO.

Syntax

The LastError property has the following syntax:

object.LastError

with the following parts:

Part | Description
Object | Applies to the SDOEngine object

Remarks

This property is Read Only.

Example

The following example demonstrates the use of the LastError property in the error handling code to handle connection errors:

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace

  ' Declare Variables
  Dim szDataPath As String

  ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company.  The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then

    ' Try to Connect - Will Throw an Exception if it Fails
    If oWS.Connect szDataPath, "", "", "Example" Then

      ' Connection Successful
      MsgBox "Connection Successful", vbOKOnly, "SDO Examples"

      ' Disconnect
      oWS.Disconnect

    End If

  End If

  ' Destroy Objects
  Set oWS = Nothing
   Set oSDO = Nothing

  Exit Sub

' Error Handling Code
Error_Handler:

  Select Case oSDO.LastError.Code

    ' Invalid Password
    Case Is = sdoLogonNameInUse
        MsgBox "Logon Failed Due To: " & oSDO.LastError.Text

    ' User is Already Logged On
    Case Is = sdoLogonNameInUse
        MsgBox "Logon Failed Due To: " & oSDO.LastError.Text

    ' Sage 50 is in Exclusive Mode i.e. File Maintenance
    Case Is = sdoLogonExclusive
        MsgBox "Logon Failed Due To: " & oSDO.LastError.Text

    ' Invalid Data Path on Connect
    Case Is = sdoBadDataPath
        MsgBox = "Logon Failed Due To: " & oSDO.LastError.Text

    ' Sage 50 is not Same Version as SDO
    Case Is = sdoWrongVersion
        MsgBox = "Logon Failed Due To: " & oSDO.LastError.Text

  End Select

Related Topics

Methods and Properties | Description
Code | Returns the code relating to the error.
Text | Returns a description of the error.


Workspaces Property

Workspaces Collection

Description

The Workspaces collection holds the currently active workspaces. You may want to have more than one workspace in order to access two datasets at the same time within the same application.

Methods

The Workspaces collection has the following methods:

Method | Description
Add | Adds a workspace to the collection
Remove | Removes a workspace from the collection.

Properties

The Workspaces collection has the following properties:

Property | Description
Count | Returns the number of active workspaces.


SDOError Object

Description

The SDOError object provides information about errors that occur whilst the Sage Data Objects are being used. It is returned by the SDOEngine object in it's LastError property.

Methods

The SDOError object has no methods.

Properties

The SDOError object has the following properties:

Property | Description
Code | Code for the error as detailed in the Exceptions article.
Text | Text describing the error.


Code Property

Description

The Code property returns an integer that represents the last error generated by SDO.

Syntax

The Code property has the following syntax:

object.Code

with the following parts:

Part | Description
Object | Applies to the SDOError object

Remarks

This property is Read Only.

Return Value(s)

Constant | Value | Description
sdoNone | 0 | No Description
sdoInvalidArg | 1 | No Description
sdoArchiveException | 2 | No Description
sdoException | 3 | No Description
sdoDaoException | 4 | No Description
sdoDBException | 5 | No Description
sdoFileException | 6 | No Description
sdoMemoryException | 7 | No Description
sdoNotSupportedException | 8 | No Description
sdoOleException | 9 | No Description
sdoOleDispatchException | 10 | No Description
sdoResourceException | 11 | No Description
sdoUserException | 12 | No Description
sdoUnknownException | 13 | No Description
sdoInvalidOpenMode | 14 | The mode specified for the Open method is invalid.
sdoInvalidName | 15 | The Object Name you are specifying is invalid.
sdoNotConnected | 16 | You are trying to create an object without a valid connection to the Sage 50 Accounts data.
sdoInvalidKey | 17 | No Description
sdoInvalidValue | 18 | No Description
sdoInvalidUse | 19 | No Description
sdoInvalidType | 20 | No Description
sdoLogonFail | 21 | No Description
sdoLogonPassword | 22 | The Password used in the connection is invalid.
sdoLogonNameInUse | 23 | The Logon Name used in the connection is invalid.
sdoLogonExclusive | 24 | Sage 50 Accounts is in exclusive mode. This would occur, for example, if Disk Doctor is in use.
sdoBadDataPath | 25 | The data path used in the connection is invalid.
sdoWrongVersion | 26 | The Sage 50 Accounts data is a different version to the SDO.
sdoBadUpdateMode | 27 | The Update method has been called without previously having called the AddNew or Edit methods.
sdoDeleteFailedHasTrans | 28 | The record cannot be deleted as the account has transactions associated with it.
sdoDeleteFailed | 29 | The record cannot be deleted for a reason other than having transactions associated i.e. there is a balance on the account.
sdoLogonUserCountExceeded | 30 | The connection would cause the user count to be exceeded.
sdoNotRegistered | 31 | The SDO has not been registered on this machine.
sdoReadOnlyAccess | 32 | The object you are trying to update is read only - this applies to the AccessData object.
sdoForTraNotEnabled | 33 | The Foreign Trader Wizard has not yet been completed - please run Sage 50 Accounts and complete the Foreign Trader Wizard.
sdoCurrencyDoesNotMatch | 34 | The Foreign Currency on the account does not match the Foreign Currency on the transaction.
sdoForeignRateSetOnBase | 35 | You are trying to post a BASE transaction with a Foreign Currency Rate - please clear the Foreign Currency Rate.
sdoInvalidSave | 36 | Attempting to save an existing object having failed to Load.
sdoInvalidProjectStatus | 37 | Project status set to not allow postings.
sdoInvalidProject | 38 | Invalid Project.
sdoMaxCostCodes | 39 | Maximum number of project cost codes is 100.
sdoInvalidAllocation | 40 | No Description.
sdoInvalidIssue | 41 | No Description
sdoInvalidFund | 42 | Invalid Fund Type.
sdoInvalidBudget | 43 | Invalid Financial Budget.
sdoZeroValueTransaction | 44 | The transaction must have a value greater than zero.
sdoCannotCreateMultipleRegisteredAddresses | 45 | Only one registered address per customer or supplier.
sdoAttemptedToCreateCalendarEventLabel | 46 | Error creating the diary event label.
sdoAttemptedToEditReadOnlyCalendarEventLabel | 47 | Read Only event label selected for editing.
sdoFileLockedAccountsBusy | 48 | File is locked or busy
sdoClosedLedgerDateControlError | 49 | Date specified is before the closed ledger date
sdoEmptyKey | 50 | No Description
sdoContactHistoryMajorContactTypeNotFound | 51 | Major contact type not found
sdoContactHistorySubContactTypeNotFound | 52 | Sub contact type not found
sdoContactHistoryContactOutcomeNotFound | 53 | Contact outcome not found
sdoContactHistoryInvalidContactTypePassed | 54 | Invalid contact type
sdoContactHistorySubjectNotSpecified | 55 | Subject not specified
sdoContactHistoryDateNotSpecified | 56 | Contact date not specified
sdoContactHistoryPromisedPaymentIsZero | 57 | Promised payment is zero
sdoContactHistoryFollowUpDatePriorToContactDate | 58 | Follow up date prior to contact date
sdoContactHistoryUserNameIsEmptyOrDoesNotExist | 59 | Contact user name is empty or does not exist
sdoContactHistoryMajorContactTypeDiffers | 60 | Major contact type differs
sdoContactHistoryInvalidSubContactTypeForMajorType | 61 | Invalid sub contact type for major type
sdoContactHistoryInvalidOutcomeForMajorType | 62 | Invalid outcome for major type
sdoEmptyAccountReference | 63 | Empty Account Ref
sdoDataHasBeenRestored | 64 | Data has been restored
sdoInvalidNominalCode | 65 | Invalid nominal code
sdoBankAccountNotAvailable | 66 | Bank account not available
sdoBankAccountIsControl | 67 | Bank account is control account
sdoBankIsNotBaseCurrency | 68 | Bank account is not base currency
sdoInvalidCostCode | 69 | Invalid cost code
sdoSalPurAccountIsOnHold | 70 | Sales or purchase account is on hold
sdoSalPurAccountIsInactive | 71 | Sales or purchase account is inactive
sdoSalPurAccountDeleted | 72 | Sales or purchase account has been deleted
sdoSalPurAccountTermsNotAgreed | 73 | Sales or purchase account has terms not agreed set
sdoSalPurAccountNotBaseCurrency | 74 | Sales or purchase account is not in base currency
sdoInvalidTransactionNumber | 75 | Invalid transaction number
sdoInvalidTaxCodeForPayment | 76 | Invalid tax code for payment
sdoSagePaymentsMismatch | 77 | Sage Payments mismatch
sdoZeroValueNet | 78 | Zero value net
sdoTransactionCannotHaveProject | 79 | Transaction cannot have project
sdoProjectSetButNotACostCode | 80 | Project set but not a cost code
sdoCostCodeSetButNotAProject | 81 | Cost code set but not a project
sdoAccountRefContainsSpaces | 82 | Account ref contains spaces
sdoAddressLinesTooLong | 83 | Address lines too long
sdoAccountRefAlreadyExists | 84 | Account ref already exists
sdoTransactionCannotHaveCostCode | 85 | Transaction cannot have cost code
sdoAccountRefContainsInvalidCharacters | 86 | Account ref contains invalid characters
sdoInvalidDate | 87 | Invalid date
sdoNominalAccountIsControl | 88 | Nominal account is a control account
sdoInvoiceTotalNegative | 89 | Total value on Invoice is negative
sdoIncorrectStockCodeType | 90 | Incorrect stock code/invoice type for negative line
sdoIncorrectStockCodeType | 90 | Incorrect stock code/invoice type for negative line
sdoUnableConnectToDataService | 94 | No Description
sdoCannotChangeCurrencyWhenTransactionsExist | 95 | No Description
sdoCannotChangeCurrencyWhenForeignTraderNotEnabled | 96 | No Description
sdoCanNotUsePostponedAccountingTaxCode | 97 | No Description
sdoCanNotUseNonCUImportExportTaxCode | 98 | No Description
sdoCannotChangeCompanyDetailsRemoteSites | 99 | No Description
sdoOSSSettingsMismatch | 100 | No Description
sdoOnServiceAvailabilityException | 101 | No Description
sdoOnTokenExpiredException | 102 | No Description
sdoOnAuthTimedoutException | 103 | No Description
sdoOnAccessToDatasetRevokedException | 104 | No Description
sdoOnAccessDeniedBySageIDException | 105 | No Description
sdoOnDataForkDetectedException | 106 | No Description
sdoOnServerNotCapableException | 107 | No Description
sdoOnConnectionClosedException | 108 | No Description
sdoOnDatasetLimitReachedException | 109 | No Description
sdoOnTooManyRequestsException | 110 | No Description
sdoOnDatasetRemovedException | 111 | No Description
sdoOnInvalidClientException | 112 | No Description
sdoOnSageIDTimeOutOfSyncException | 113 | No Description
sdoOnDataServiceMessageException | 114 | No Description
sdoOnBadHandshakeException | 115 | No Description
sdoOnDataProviderErrorException | 116 | No Description
sdoOnMainSiteDisconnectException | 117 | No Description
sdoOnSageHardDriveLimitExceededException | 118 | No Description
sdoOnInvalidSyncStateLoopDetectedException | 119 | No Description
sdoOnLockDownException | 120 | No Description
sdoOnDataServiceDisconnectedException | 121 | No Description
sdoOnFailedAuthAttemptException | 122 | No Description
sdoOnConnectionClosed | 123 | No Description

Example

The following example demonstrates the use of the Code property in the error handling code:

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace

  ' Declare Variables
  Dim szDataPath As String
  ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company.  The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then

    ' Try to Connect - Will Throw an Exception if it Fails
    If oWS.Connect szDataPath, "", "", "Example" Then

      ' Connection Successful
      MsgBox "Connection Successful", vbOKOnly, "SDO Examples"

      ' Disconnect
      oWS.Disconnect

    End If

  End If

  ' Destroy Objects
  Set oWS = Nothing
  Set oSDO = Nothing

  Exit Sub
' Error Handling Code
Error_Handler:

  Select Case oSDO.LastError.Code

    ' Invalid Password
    Case Is = sdoLogonNameInUse
        MsgBox "Logon Failed Due To: " & oSDO.LastError.Text

    ' User is Already Logged On
    Case Is = sdoLogonNameInUse
        MsgBox "Logon Failed Due To: " & oSDO.LastError.Text

    ' Sage 50 is in Exclusive Mode i.e. File Maintenance
    Case Is = sdoLogonExclusive
        MsgBox "Logon Failed Due To: " & oSDO.LastError.Text

    ' Invalid Data Path on Connect
    Case Is = sdoBadDataPath
        MsgBox = "Logon Failed Due To: " & oSDO.LastError.Text

    ' Sage 50 is not Same Version as SDO
    Case Is = sdoWrongVersion
        MsgBox = "Logon Failed Due To: " & oSDO.LastError.Text

  End Select

Related Topics

Methods and Properties | Description
Text | Returns a description of the error.
LastError | Returns details of the last error generated by the SDO.


Text Property - SDOError Object

Description

The Text property returns an string expression that describes the last error generated by the SDO.

Syntax

The Text property has the following syntax:

object.Text

with the following parts:

Part | Description
Object | Applies to the SDOError object

Remarks

This property is Read Only.

Example

The following example demonstrates the use of the Text property:

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace

  ' Declare Variables
  Dim szDataPath As String

  ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company.  The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then

    ' Try to Connect - Will Throw an Exception if it Fails
    If oWS.Connect szDataPath, "", "", "Example" Then

      ' Connection Successful
      MsgBox "Connection Successful", vbOKOnly, "SDO Examples"

      ' Disconnect and Destroy the SDO Objects
      oWS.Disconnect

    End If

  End If

  ' Destroy Objects
  Set oWS = Nothing
   Set oSDO = Nothing

  Exit Sub

' Error Handling Code
Error_Handler:

  Select Case oSDO.LastError.Code

    ' Invalid Password
    Case Is = sdoLogonNameInUse
        MsgBox "Logon Failed Due To: " & oSDO.LastError.Text

    ' User is Already Logged On
    Case Is = sdoLogonNameInUse
        MsgBox "Logon Failed Due To: " & oSDO.LastError.Text

    ' Sage 50 is in Exclusive Mode i.e. File Maintenance
    Case Is = sdoLogonExclusive
        MsgBox "Logon Failed Due To: " & oSDO.LastError.Text

    ' Invalid Data Path on Connect
    Case Is = sdoBadDataPath
        MsgBox = "Logon Failed Due To: " & oSDO.LastError.Text

    ' Sage 50 is not Same Version as SDO
    Case Is = sdoWrongVersion
        MsgBox = "Logon Failed Due To: " & oSDO.LastError.Text

  End Select

Related Topics

Methods and Properties | Description
Code | Returns an integer that represents the last error generated by the SDO.
LastError | Returns details of the last error generated by the SDO.


Workspace Object

Description

The Workspace object is used to connect to a Sage 50 Accounts data source and forms the basis for all object creation. All other objects, with the exception of the new objects (shown below) are created from the Workspace object using the CreateObject method.

Methods

The Workspace object has the following methods:

Method | Description
Connect | Creates a connection to the Sage 50 Accounts data files.
CreateObject | Creates an SDO object of the specified type.
Disconnect | Terminates a connection to the Sage 50 Accounts data files.
IsValidUser | Allows you to check if a User Name is valid prior to connecting to the data.
CreateCompanyAddress | Returns the Sage 50 Accounts CompanyAddress object.
CreateCompanyAddresses | Returns the Sage 50 Accounts CompanyAddresses object.
CreateContactHistory | Returns the Sage 50 Accounts CustomerAddress object.
CreateContactHistorys | Returns the Sage 50 Accounts CustomerAddress object.
CreateCountry | Returns the Sage 50 Accounts Project Costing Country object.
CreateCustomerAddress | Returns the Sage 50 Accounts CustomerAddress object.
CreateCustomerAddresses | Returns the Sage 50 Accounts CustomerAddresses object.
CreateCustomer | Returns the Sage 50 Accounts Project Costing Customer object.
CreateDepartment | Returns the Sage 50 Accounts Project Costing Department object.
CreateDiaryEvent | Returns the Sage 50 Accounts Diary Event object.
CreateDiaryEvents | Returns the Sage 50 Accounts Diary Events object.
CreateDiaryEventLabel | Returns the Sage 50 Accounts Diary Event Label object.
CreateDiaryEventLabels | Returns the Sage 50 Accounts Diary Event Labels object.
CreateDiaryRecurrencePattern | Returns the Sage 50 Accounts Diary Event Recurrence Pattern object.
CreateDiaryRecurrencePatterns | Returns the Sage 50 Accounts Diary Event Recurrence Patterns object.
CreateDisputedReason | Returns the Sage 50 Accounts DisputedReason object.
CreateNominal | Returns the Sage 50 Accounts Project Costing Nominal object.
CreateProject | Returns the Sage 50 Accounts Project Costing Project object.
CreateProjectOnlyTransaction | Returns the Sage 50 Accounts Project Costing ProjectOnlyTransaction object.
CreateProjects | Returns the Sage 50 Accounts Project Costing Projects collection object.
CreateProjectCostCode | Returns the Sage 50 Accounts Project Costing ProjectCostCode object.
CreateProjectCostCodes | Returns the Sage 50 Accounts Project Costing ProjectCostCodes collection object.
CreateProjectResource | Returns the Sage 50 Accounts Project Costing ProjectResource object.
CreateProjectResources | Returns the Sage 50 Accounts Project Costing ProjectResources collection object.
CreateProjectStatus | Returns the Sage 50 Accounts Project Costing ProjectStatus object.
CreateProjectStatuses | Returns the Sage 50 Accounts Project Costing ProjectStatuses collection object.
CreateProjectTransaction | Returns the Sage 50 Accounts Project Costing ProjectTransaction object.
CreateProjectTransactions | Returns the Sage 50 Accounts Project Costing ProjectTransactions collection object.
CreateSupplier | Returns the Sage 50 Accounts Supplier object.
CreateSupplierAddress | Returns the Sage 50 Accounts Supplier Address object
CreateSupplierAddresses | Returns the Sage 50 Accounts Supplier Addresses object.
CreateTaxCode | Returns the Sage 50 Accounts Project Costing TaxCode object.
IsDriveSleepModeEnabled | Used to determine if Remote Data sleep mode is enabled
IsValidDataPath | Used to determine if the data path is valid

Properties

The Workspace object has the following properties:

Property | Description
ActiveCOA | Returns the COA that is currently active.
DataObjects | Returns properties and methods associated with the Data Objects.
Name | Holds the name of the workspace.
PartialData | Returns True or false .
Path | Returns the Sage 50 Accounts Data path.
ProgramType | Returns the Sage 50 Accounts program type i.e. Accounts Professional.
Version | Holds the version of Sage 50 Accounts.
UI | Allows the SDO's dialog boxes to be turned on and off.


Connect Method

Description

The Connect method creates a connection to the Sage 50 Accounts data files. You must have a valid connection in place before attempting to create instances of any of the data objects.

Syntax

The Connect method has the following syntax:

object.Connect DataPath, UserName, Password, UniqueID

with the following parts:

Part | Description
Object | Applies to the Workspace object.
DataPath | A string expression containing the path to the Sage 50 Accounts data files ACCDATA folder. i.e. C:\ProgramData\Sage\Accounts\2024\ accdata.
UserName | A string expression containing the name to use for the user you wish to connect. If the Sage 50 Accounts Access Rights option is switched on, this should be a valid user name, otherwise it should be 'MANAGER'.
Password | A string expression containing the password for the user specified in UserName. If the Sage 50 Accounts Access Rights option is switched on, this should be the password for the relevant user, otherwise it should be the password set up for 'MANAGER'.
UniqueID | A unique string expression to identify the connection to Sage 50 Accounts. In Sage 50 Accounts, we use the Computer Name as the unique identifier. In Visual Basic .NET this can be accessed easily by using SystemInformation.ComputerName

Return Values

The Connect method returns the following values:

Return Value | Description
True | A connection was successfully made to the Sage 50 Accounts data.
False | A connection could not be made - you should handle the exception to determine why the connection failed.

Remarks

Although the Connect method will return False if the connection fails, it will also throw an exception and you should handle this within your code as demonstrated in the example below. Click here for a list of the possible exceptions.

If the connect throws exception 31 (SDO Not Registered), the SDO has not been registered on the machine you are using. To ensure that SDO is registered, follow the instructions here.

Connecting to the Sage 50 Accounts data via SDO is the same as logging into Sage 50 Accounts as a user. If you are running Sage 50 Accounts and your SDO application at the same time, you cannot have more users in total that you have a license for in Sage 50 Accounts (except for Accounts Professional). For example, if you have the single user version of Sage 50 Accounts and someone is using Sage 50 Accounts, you cannot connect your SDO application at the same time.

Once you have established a valid connection, you must call the Disconnect method of the Workspace object in order to remove the user from the current user list.

There is a current issue that can cause the Disconnect method to fail to clear the active users from the user list. This is caused by the UniqueID string being more than 32 characters. In this situation the Connect and Disconnect will appear to succeed but the user will remain in the user list.

Example

The following example demonstrates the use of the Connect method:

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace

  ' Declare Variables
  Dim szDataPath As String
  ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company.  The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then

    ' Connect to Data Files - An exception will be thrown if this fails
    If oWS.Connect(szDataPath, "", "", "Example") Then

      ' Connection has been successful so your code goes here.....

      ' Disconnect
      oWS.Disconnect

    End If

  End If

  ' Destroy the SDO Objects
  Set oWS = Nothing
  Set oSDO = Nothing

  Exit Sub
' Error Handling Code
Error_Handler:

  Select Case oSDO.LastError.Code

    ' Invalid Password
    Case Is = sdoLogonNameInUse
        MsgBox "Logon Failed Due To: " & oSDO.LastError.Text

    ' User is Already Logged On
    Case Is = sdoLogonNameInUse
        MsgBox "Logon Failed Due To: " & oSDO.LastError.Text

    ' Sage 50 Accounts is in Exclusive Mode i.e. File Maintenance
    Case Is = sdoLogonExclusive
        MsgBox "Logon Failed Due To: " & oSDO.LastError.Text

    ' Invalid Data Path on Connect
    Case Is = sdoBadDataPath
        MsgBox "Logon Failed Due To: " & oSDO.LastError.Text

    ' Sage 50 Accounts is not Same Version as SDO
    Case Is = sdoWrongVersion
        MsgBox "Logon Failed Due To: " & oSDO.LastError.Text

    ' SDO is Not Registered on this Machine
    Case Is = sdoNotRegistered
        MsgBox "Logon Failed Due To: " & oSDO.LastError.Text

  End Select

Related Topics

Method | Description
Disconnect | Terminates the connection to the Sage 50 Accounts data files.
IsValidUser | Checks if the specified user name is valid in Sage 50 Accounts.
SelectCompany | Displays a dialog box allowing the user to select a company.


CreateObject Method

Description

The CreateObject method is used to create an object of the specified type. This is the primary method used to create objects that represent the Sage 50 Accounts data files and allow access to the data files.

Syntax

The CreateObject method has the following syntax:

object.CreateObject(ObjectName)

with the following parts:

Part | Description
Object | Applies to the Workspace object.
ObjectName | A string expression containing the name of the object you wish to create. For a list of creatable data objects, click here.

Return Values

The CreateObject method returns the following values:

Return Value | Description
True | The object was successfully created.
False | The object could not be created.

Remarks

The most common reason for the CreateObject method to fail is a misspelling of the object name. If the name is not spelt correctly, an exception (Error Code 15) will be thrown.

You should always destroy any objects you create by setting them to Nothing.

Example

The following example demonstrates the use of the CreateObject method by creating an instance of the SetupData object:

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oSetupData As SageDataObject300.SetupData

  ' Declare Variables
  Dim szDataPath As String

  ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
   If szDataPath <> "" Then

    ' Connect to Data Files - An exception will be thrown if this fails
    If oWS.Connect szDataPath, "", "", "Example" Then

      ' Create an Instance of the SetupData Object
      Set oSetupData = oWS.CreateObject("SetupData")

      ' Display the Company Name
      MsgBox oSetupData.FIelds.Item("NAME").Value

       ' Disconnect
      oWS.Disconnect

    End If

  End If

  ' Destroy Objects
  Set oSetupData = Nothing
  Set oWS = Nothing
   Set oSDO = Nothing

  Exit Sub

 ' Error Handling Code
Error_Handler:

  MsgBox "The SDO generated the following error: " & oSDO.LastError.Text


Disconnect Method

Description

The Disconnect method terminates the current connection to the Sage 50 Accounts data files.

Syntax

The Disconnect method has the following syntax:

object.Disconnect

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Value(s)

The Disconnect method returns the following values:

Return Value | Description
True | The disconnection was successful.
False | The disconnection could not be made.

Remarks

There is a current issue that can cause the Disconnect method to fail to clear the active users from the user list. This is caused by the UniqueID string being more than 32 characters. In this situation the Connect and Disconnect will appear to succeed but the user will remain in the user list.

Example

The following example demonstrates the use of the Disconnect method:

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace

  ' Declare Variables
  Dim szDataPath As String
  ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
   If szDataPath <> "" Then

    ' Connect to Data Files - An exception will be thrown if this fails
    If oWS.Connect(szDataPath, "", "", "Example") Then

      ' Disconnect
      oWS.Disconnect

    End If

  End If

  ' Destroy the SDO Objects
  Set oWS = Nothing
  Set oSDO = Nothing

  Exit Sub

' Error Handling Code
Error_Handler:

  Select Case oSDO.LastError.Code

    ' Invalid Password
    Case Is = sdoLogonNameInUse
        MsgBox "Logon Failed Due To: " & oSDO.LastError.Text

    ' User is Already Logged On
    Case Is = sdoLogonNameInUse
        MsgBox "Logon Failed Due To: " & oSDO.LastError.Text

    ' Sage 50 Accounts is in Exclusive Mode i.e. File Maintenance
    Case Is = sdoLogonExclusive
        MsgBox "Logon Failed Due To: " & oSDO.LastError.Text

    ' Invalid Data Path on Connect
    Case Is = sdoBadDataPath
        MsgBox "Logon Failed Due To: " & oSDO.LastError.Text

    ' Sage 50 Accounts is not Same Version as SDO
    Case Is = sdoWrongVersion
        MsgBox "Logon Failed Due To: " & oSDO.LastError.Text

  End Select

Related Topics

Method | Description
Connect | Establishes a connection to the Sage 50 Accounts data files.
IsValidUser | Allows you to check if a User Name is valid prior to connecting to the data.
SelectCompany | Displays a dialog box allowing the user to select a company.


IsValidUser Method

Description

The IsValidUser method is used to determine whether a specified user name is valid in Sage 50 Accounts

IsValidUser takes exactly the same parameters as the Connect method and generates the same exceptions although no connection is ever made to the Sage 50 Accounts data files.

Syntax

The IsValidUser method has the following syntax:

object.IsValidUser DataPath, UserName, Password, UniqueID

with the following parts:

Part | Description
Object | Applies to the Workspace object.
DataPath | A string expression containing the path to the Sage 50 Accounts data files ACCDATA folder. i.e. C:\ProgramData\Sage\Accounts\2024\ accdata.
UserName | A string expression containing the name to use for the user you wish to check. If the Sage 50 Accounts Access Rights option is switched on, this should be a valid user name, otherwise it should be 'MANAGER'.
Password | A string expression containing the password for the user specified in UserName. If the Sage 50 Accounts Access Rights option is switched on, this should be the password for the relevant user, otherwise it should be the password set up for 'MANAGER'.
UniqueID | A unique string expression to identify the connection to Sage 50. In Sage 50 Accounts, we use the Computer Name as the unique identifier.

Return Values

The IsValidUser method returns the following values:

Return Value | Description
True | The specified user name is valid.
False | The specified user name is invalid.

Remarks

Although the IsValidUser method will return False if the connection fails, it will also throw an exception and you should handle the exception within your code as demonstrated in the example below. Click here for a list of the possible exceptions.

Example

The following example demonstrates the use of the IsValidUser method:

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace

   ' Declare Variables
  Dim szDataPath As String
  ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
   If szDataPath <> "" Then

    ' Connect to Data Files - An exception will be thrown if this fails
    If oWS.IsValidUser(szDataPath, "", "", "Example") Then

      MsgBox "Specified User Name is valid."

    Else

      MsgBox "Specified User Name is invalid."

    End If

  End If

  ' Destroy the SDO Objects
  Set oWS = Nothing
  Set oSDO = Nothing

  Exit Sub

' Error Handling Code
Error_Handler:

  Select Case oSDO.LastError.Code

    ' Invalid Password
    Case Is = sdoLogonNameInUse
        MsgBox "Logon Failed Due To: " & oSDO.LastError.Text

    ' User is Already Logged On
    Case Is = sdoLogonNameInUse
        MsgBox "Logon Failed Due To: " & oSDO.LastError.Text

    ' Sage 50 Accounts is in Exclusive Mode i.e. File Maintenance
    Case Is = sdoLogonExclusive
        MsgBox "Logon Failed Due To: " & oSDO.LastError.Text

    ' Invalid Data Path on Connect
    Case Is = sdoBadDataPath
        MsgBox "Logon Failed Due To: " & oSDO.LastError.Text

    ' Sage 50 Accounts is not Same Version as SDO
    Case Is = sdoWrongVersion
        MsgBox "Logon Failed Due To: " & oSDO.LastError.Text

  End Select

Related Topics

Method | Description
Connect | Establishes a connection to the Sage 50 Accounts data files.


CreateCISSetting Method

Description

The CreateCISSetting method is used to create an object of type CISSetting. This is the method used to create a business object that represents the CIS Tab of Company Preferences.

Syntax

The CreateCISSetting method has the following syntax:

Object.CreateCISSetting

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Values

The CreateCISSetting method returns the following object:

Return Value | Description
CISSetting | An object of type CISSetting. The object is not positioned at a record until the .Load method is used.

Examples Using This Method

Example - Amending CIS Settings


CreateCISSubcontractor Method

Description

The CreateCISSubcontractor method is used to create an object of type CISSubcontractor. This is the method used to create a business object that represents the CIS tab of a Subcontractor Record.

Syntax

The CreateCISSubcontractor method has the following syntax:

Object.CreateCISSubcontractor

with the following parts:

Object.CreateCISSubcontractor

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Values

The CreateCISSubcontractor method returns the following object:

Examples Using This Method

Example - Creating a New Subcontractor Record


CreateCISSubcontractors Method

Description

The CreateCISSubcontractors method is used to create an object of type CISSubcontractors. This is the method used to create a business object that represents the CIS tab of a Subcontractor Record. This object is a collection of CISSubcontractor objects.

Syntax

The CreateCISSubcontractors method has the following syntax:

Object.CreateCISSubcontractors

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Values

The CreateCISSubcontractors method returns the following object:

Return Value | Description
CISSubcontractors | An object of type CISSubcontractors. This is a collection of CISSubcontractor objects.

Examples Using This Method

Example - Creating a New Subcontractor Record


CreateCISSubcontractorTaxHistory Method

Description

The CreateCISSubcontractorTaxHistory method is used to create an object of type CISSubcontractorTaxHistory. This is the method used to create a business object that represents the Tax History Information on a CIS Subcontractor Record.

Syntax

The CreateCISSubcontractorTaxHistory method has the following syntax:

Object.CreateCISSubcontractorTaxHistory

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Values

The CreateCISSubcontractorTaxHistory method returns the following object:

Return Value | Description
CISSubcontractorTaxHistory | An object of type CISSubcontractorTaxHistory . The object is not positioned at a record until the .Load method is used.

Examples Using This Object

Example - Creating a New Subcontractor Record
Example - Creating a Subcontractor Record From an Existing Supplier Record
Example - Posting a Subcontractor Invoice
Example - Creating a New Subcontractor Record
Example -Edit CIS details


CreateCISSubcontractorTaxHistorys Method

Description

The CreateCISSubcontractorTaxHistorys method is used to create an object of type CISSubcontractorTaxHistorys . This is the method used to create a business object that represents the Tax History Information on a CIS Subcontractor Record. This object is a collection of CISSubcontractorTaxHistory objects.

Syntax

The CreateCISSubcontractorTaxHistorys method has the following syntax:

Object.CreateCISSubcontractorTaxHistorys

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Values

The CreateCISSubcontractorTaxHistorys method returns the following object:

Return Value | Description
CISSubcontractorTaxHistorys | An object of type CISSubcontractorTaxHistorys.This is a collection of CISSubcontractorTaxHistory objects.

Examples Using This Method

Example - Creating a New Subcontractor Record


CreateCISSubcontractorLegacy Method

Description

The CreateCISSubcontractorLegacy method is used to create an object of type CISSubcontractorLegacy. This is the method used to create a business object that represents the Pre 2007 Information on a CIS Subcontractor Record.

Syntax

The CreateCISSubcontractorLegacy method has the following syntax:

Object.CreateCISSubcontractorLegacy

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Values

The CreateCISSubcontractorLegacy method returns the following object:

Return Value | Description
CISSubcontractorLegacy | An object of type Project. The object is not positioned at a record until the .Load method is used.

Examples Using This Object

Example - Creating a New Subcontractor Record
Example - Creating a Subcontractor Record From an Existing Supplier Record
Example - Posting a Subcontractor Invoice
Example - Creating a New Subcontractor Record
Example -Edit CIS details


CreateProject Method

CreateCISSubcontractorLegacys Method

Description

The CreateCISSubcontractorLegacys method is used to create an object of type CISSubcontractorLegacys. This is the method used to create an object that represents the Pre

Information on a CIS Record. This object is a collection of CISSubcontractorLegacy objects.

Syntax

The CreateCISSubcontractorLegacys method has the following syntax:

Object.CreateCISSubcontractorLegacys

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Values

The CISSubcontractorLegacys method returns the following object:

Return Value | Description
CISSubcontractorLegacys | An object of type Project. The object is not positioned at a record until the .Load method is used.

Examples Using This Object

Editing CIS details


CreateCompanyAddress Method

Description

The CreateCompanyAddress method is used to create an object of the type CompanyAddress.

Syntax

The CreateCompanyAddress method has the following syntax:

Object.CreateCompanyAddress

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Value

The CreateCompanyAddress method returns the following value:

Return Value | Description
CompanyAddress | An object of type SageDataObjectN.CompanyAddress (N denotes SDO version e.g. 180)

Remarks

You should always destroy any objects you create by setting them to Nothing.

Examples Using this Object

View Company Address Properties
Create New company Address


CreateCompanyAddresses Method

Description

The CreateCompanyAddresses method is used to create an object of the type CompanyAddresses.

Syntax

The CreateCompanyAddresses method has the following syntax:

Object.CreateCompanyAddresses

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Value

The CreateCompanyAddresses method returns the following value:

Return Value | Description
CompanyAddresses | An object of type SageDataObjectN.CompanyAddresses (N denotes SDO version e.g. 180)

Remarks

You should always destroy any objects you create by setting them to Nothing.

Examples Using this Object

View Company Address Properties
Create New company Address


CreateCountry Method

Description

The CreateCountry method is used to create an object of the type Country. This is the method used to create an object that represent the Sage 50 Accounts data Country Code on a Project Costing Project.

Syntax

The CreateCountry method has the following syntax:

Object.CreateCountry

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Value

The CreateCustomer method returns the following value:

Return Value | Description
Country | An object of type SageDataObjectN.Country (N denotes SDO version e.g. 180)

Remarks

You should always destroy any objects you create by setting them to Nothing.

Examples Using This Method

Create a new Project Record


CreateCustomer Method

Description

The CreateCustomer method is used to create an object of the type Customer. This is the method used to create an object that represent the Sage 50 Accounts data sales ledger account on a Project Costing Project and ProjectTransaction.

Syntax

The CreateCustomer method has the following syntax:

Object.CreateCustomer

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Value

The CreateCustomer method returns the following value:

Return Value | Description
Customer | An object of type SageDataObjectN.Customer (N denotes SDO version e.g. 180)

Remarks

You should always destroy any objects you create by setting them to Nothing.

Examples Using This Object

Create a new Project Record


CreateCustomerAddress Method

Description

The CreateCustomerAddress method is used to create an object of the type CustomerAddress.

Syntax

The CreateCustomerAddress method has the following syntax:

Object.CreateCustomerAddress

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Value

The CreateCustomerAddress method returns the following value:

Return Value | Description
CustomerAddress | An object of type SageDataObjectN.CustomerAddress (N denotes SDO version e.g. 180)

Remarks

You should always destroy any objects you create by setting them to Nothing.

Examples Using this Object

View Customer Address Properties
Edit a Customer Address
Create a new Customer Address


CreateCustomer Method

CreateCustomerAddresses Method

Description

The CreateCustomerAddresses method is used to create an object of the type CustomerAddresses.

Syntax

The CreateCustomerAddresses method has the following syntax:

Object.CreateCustomerAddresses

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Value

The CreateCustomerAddresses method returns the following value:

Return Value | Description
CustomerAddresses | An object of type SageDataObjectN.CustomerAddresses (N denotes SDO version e.g. 180)

Remarks

You should always destroy any objects you create by setting them to Nothing.

Examples Using this Object

View Customer Address Properties
Edit a Customer Address
Create a new Customer Address


CreateDepartment Method

Description

The CreateDepartment method is used to create an object of the type Department. This is the method used to create an object that represent the Sage 50 Accounts data department on a Project Costing ProjectTransaction.

Syntax

The CreateDepartment method has the following syntax:

Object.CreateDepartment

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Value

The CreateDepartment method returns the following value:

Return Value | Description
Department | An object of type SageDataObjectN.Department (N denotes SDO version e.g. 180)

Remarks

You should always destroy any objects you create by setting them to Nothing.

There are currently no examples that use this method.


CreateDiaryEvent Method

Description

The CreateDiaryEvent method is used to create an object of the type DiaryEvent.

Syntax

The CreateDiaryEvent method has the following syntax:

Object.CreateDiaryEvent

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Value

The CreateDiaryEvent method returns the following value:

Return Value | Description
DiaryEvent | An object of type SageDataObjectN.DiaryEvent (N denotes SDO version e.g. 180)

Remarks

You should always destroy any objects you create by setting them to Nothing.

Examples Using This Object

Creating a new Diary Event
Reading the last Diary Event


CreateDiaryEvents Method

Description

The CreateDiaryEvents method is used to create an object of the type DiaryEvents.

Syntax

The CreateDiaryEvents method has the following syntax:

Object.CreateDiaryEvents

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Value

The CreateCustomer method returns the following value:

Return Value | Description
CreateDiaryEvents | An object of type SageDataObjectN.DiaryEvents (N denotes SDO version e.g. 180)

Remarks

You should always destroy any objects you create by setting them to Nothing.

Examples Using This Object

There are currently no examples using this method.


CreateDiaryEventLabel Method

Description

The CreateDiaryEventLabel method is used to create an object of the type DiaryEventLabel.

Syntax

The CreateDiaryEventLabel method has the following syntax:

Object.CreateDiaryEventLabel

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Value

The CreateDiaryEventLabel method returns the following value:

Return Value | Description
DiaryEventLabel | An object of type SageDataObjectN.DiaryEventLabel (N denotes SDO version e.g. 180)

Remarks

You should always destroy any objects you create by setting them to Nothing.

Examples Using This Object

Creating a new Diary Event
Reading the last Diary Event


CreateCustomer Method

CreateDiaryEventLabels Method

Description

The CreateDiaryEventLabels method is used to create an object of the type DiaryEventLabels.

Syntax

The CreateDiaryEventLabels method has the following syntax:

Object.CreateDiaryEventLabels

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Value

The CreateDiaryEventLabels method returns the following value:

Return Value | Description
DiaryEventLabels | An object of type SageDataObjectN.DiaryEventLabels (N denotes SDO version e.g. 180)

Remarks

You should always destroy any objects you create by setting them to Nothing.

<

Examples Using This Object

View DiaryEventLabels Properties using Item Method


DiaryRecurrencePattern

Description

The DiaryRecurrencePattern object represents a Sage 50 Accounts Diary Recurrence within Diary.

Applies to

Sage 50 Accounts Standard and Professional.

Properties

Name | Description | Length | Input | Data Type
DailyIntervalInDays | Number of days between recurrences | 4 | Optional | Integer
DailyWeekdaysOnly | Set true to specify if only to use work days | 1 | Optional | Boolean
DurationInMinutes | Number of minutes appointment runs from the specified start time. | 4 | Optional | Integer
EndDate | The end date of the appointment | 2 | Optional | Date
EndType | Specifies how the occurence ends | 4 | Optional | Integer
MonthlyDayOfMonth | Day of month for recurrence | 4 | Optional | Integer
MonthlyIntervalInMonths | Can be used to specify every x number of months | 4 | Optional | Integer
MonthlyNthDayOccurrence | Day on which will occur every month: i.e. 1st Monday. | 4 | Optional | Integer
MonthlyNthDayOfWeek | Day of the week every month on which will occur. i.e. 1st Monday. | 4 | Optional | Integer
MonthlyNthIntervalInMonths | Can be used to specify every x number of months | 8 | Optional | Integer
RecurrencePeriod | How is recurrence defined? i.e. Monthly/Yearly. | 4 | Optional | Integer
StartDate | The Start Date of the recurrence | 2 | Optional | Date
StartTime | The Start Time of the recurrence | 2 | Optional | Date
TotalOccurrences | The total number of recurrences | 4 | Optional | Integer
UniqueID | The unique ID of the recurrence | 4 | Auto Generated | Integer
WeeklyDaysOfWeek | Represents the days of the week on which the entry will occur. | 4 | Optional | Integer
WeeklyIntervalInWeeks | Occurs every x weeks. | 4 | Optional | Integer
YearlyDayOfMonth | Date of month to occur yearly, i.e. 29th. | 4 | Optional | Integer
YearlyMonthOfYear | Month of year to occur yearly. | 4 | Optional | Integer
YearlyNthDayOccurrence | Day on which to occur yearly: i.e. 1st Monday of September. | 4 | Optional | Integer
YearlyNthDayOfWeek | Day on which to occur yearly: i.e. 1st Monday of September. | 4 | Optional | Integer
YearlyNthMonthOfYear | Month in which to occur yearly: i.e. 1st Monday of September. | 4 | Optional | Integer
Methods

Click here to view the methods.

Remarks

The DiaryRecurrencePattern object is used to represent how a diary entry repeats over time within the Diary Module. For instance, if we want a Diary Entry to repeat on the 1st of September every year, the DiaryrecurrencePattern object is used to specify this.

Examples Using This Object

Creating a new Diary Event
Reading the last Diary Event


CreateDiaryRecurrencePattern Method

CreateDiaryRecurrencePatterns Method

Description

The CreateDiaryRecurrencePatterns method is used to create an object of the type DiaryRecurrencePatterns.

Syntax

The CreateDiaryRecurrencePatterns method has the following syntax:

Object.Create DiaryRecurrencePatterns

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Value

The CreateCustomer method returns the following value:

Return Value | Description
DiaryRecurrencePatterns | An object of type SageDataObjectN.DiaryRecurrencePatterns (N denotes SDO version e.g. 180)

Remarks

You should always destroy any objects you create by setting them to Nothing.

Examples Using This Object

View DiaryRecurrencePatterns Properties using Item Method


CreateDisputedReason Method

Description

The CreateDisputedReason method is used to create an object of the type DisputedReason. This is the method used to create an object that represent the Sage 50 Accounts data Disputed Reason that is given when a supplier invoice is put into dispute.

Syntax

The CreateDisputedReason method has the following syntax:

Object.CreateDisputedReason

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Value

The CreateDisputedReason method returns the following value:

Return Value | Description
DisputedReason | An object of type SageDataObjectN.DisputedReason (N denotes SDO version e.g. 180)

Remarks

You should always destroy any objects you create by setting them to Nothing.

There are currently no examples that use this method.


CreateDocumentAddress Method

Description

The CreateDocumentAddress method is used to create an object of the type DocumentAddress.

Syntax

The CreateDocumentAddress method has the following syntax:

Object.CreateDocumentAddress

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Value

The CreateDocumentAddress method returns the following value:

Return Value | Description
DocumentAddress | An object of type SageDataObjectN.DocumentAddress (N denotes SDO version e.g. 180)

Remarks

You should always destroy any objects you create by setting them to Nothing.

Examples Using This Object

Using the Document Address Object


CreateDocumentAddresses Method

Description

The CreateDocumentAddresses method is used to create an object of the type DocumentAddresses.

Syntax

The CreateDocumentAddresses method has the following syntax:

Object.CreateDocumentAddresses

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Value

The CreateCustomer method returns the following value:

Return Value | Description
DocumentAddresses | An object of type SageDataObjectN.DocumentAddresses (N denotes SDO version e.g. 180)

Remarks

You should always destroy any objects you create by setting them to Nothing.

Examples Using This Object

Using the Document Address Object


CreateDocumentType Method

Description

The CreateDocumentType method is used to create an object of the type DocumentType.

Syntax

The CreateDocumentType method has the following syntax:

Object.CreateDocumentType

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Value

The CreateDocumentType method returns the following value:

Return Value | Description
DocumentType | An object of type SageDataObjectN.DocumentType (N denotes SDO version e.g. 180)

Remarks

You should always destroy any objects you create by setting them to Nothing.

Examples Using This Object

Using the Document Address Object


CreateDocumentTypes Method

Description

The CreateDocumentTypes method is used to create an object of the type DocumentTypes.

Syntax

The CreateDocumentTypes method has the following syntax:

Object.CreateDocumentTypes

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Value

The CreateCustomer method returns the following value:

Return Value | Description
DocumentTypes | An object of type SageDataObjectN.DocumentTypes (N denotes SDO version e.g. 180)

Remarks

You should always destroy any objects you create by setting them to Nothing.

Examples Using This Object

Using the Document Address Object


CreateESubmissionSetting Method

Description

The CreateESubmissionSetting method is used to create an object of type ESubmissionSetting . This is the method used to create a business object that represents the ESubmission settings of the CIS Tab of Company Preferences.

Syntax

The CreateESubmissionSetting method has the following syntax:

Object.CreateESubmissionSetting

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Values

The CreateESubmissionSetting method returns the following object:

Return Value | Description
ESubmissionSetting | An object of type ESubmissionSetting . The object is not positioned at a record until the .Load method is used.

Examples Using This Method

Example - Amending CIS Settings


CreateESubmissionSetting Method

CreateFinancialBudget Method

Description

The CreateFinancialBudget method is used to create an object of type FinancialBudget . This is the method used to create a business object that represents the Financial Budget information from the Budgets module of Sage 50 Accounts.

Syntax

The CreateFinancialBudget method has the following syntax:

Object.CreateFinancialBudget

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Values

The CreateESubmissionSetting method returns the following object:

Return Value | Description
FinancialBudget | An object of type FinancialBudget . The object is not positioned at a record until the .Load method is used.

Examples Using This Method

Example - Reading Financial Budgets


CreateESubmissionSetting Method

CreateFinancialBudgets Method

Description

The CreateFinancialBudgets method is used to create an object of type FinancialBudgets. This is the method used to create a business object that represents the Financial Budgets information from the Budgets module within Sage 50 Accounts. This object is a collection of FinancialBudget.

Syntax

The FinancialBudgets method has the following syntax:

Object.FinancialBudgets

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Values

The FinancialBudgets method returns the following object:

Return Value | Description
FinancialBudgets | An object of type FinancialBudgets. The object is not positioned at a record until the .Load method is used.

Examples Using This Method

Example - Reading Financial Budgets


CreateNominal Method

Description

The CreateNominal method is used to create an object of the type Nominal. This is the method used to create an object that represent the Sage 50 Accounts data nominal code on a Project Costing ProjectTransaction.

Syntax

The CreateNominal method has the following syntax:

Object.CreateNominal

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Value

The CreateNominal method returns the following value:

Return Value | Description
Nominal | An object of type SageDataObjectN.Nominal (N denotes SDO version e.g. 180)

Examples Using this Method

Creating a New Charity Fund


CreateProject Method

Description

The CreateProject method is used to create an object of the specified type. This is the primary method used to create a business object that represents the Sage 50 Accounts data Project Costing Project.

Syntax

The CreateProject method has the following syntax:

Object.CreateProject

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Values

The CreateProject method returns the following object:

Return Value | Description
Project | An object of type Project. The object is not positioned at a record until the .Load method is used.

Examples Using This Method

Create a new Project Record
Amend a Project Record
Delete a Project Record
Post a Project Charge
Post a Project Credit
Post a Project Stock Issue
Post a Project Stock Return
Post a Project Supplier Invoice
Post a Project Supplier Credit
Post a Project Bank Payment
Post a Project Product Invoice
Post a Project Service Invoice
Post a Project Sales Order
Marking a Project as Complete
View a Project Transactions
Display Project Details In A Combobox
Create a new project costcode
Create a new project resource
Reading the chart of accounts
Creating a New Prepayment Record
Creating a New Charity Fund


CreateProjects Method

Description

The CreateProjects method is used to create an object of the specified type. This is the primary method used to create a business object that represent the Sage 50 Accounts data Project Costing Records. This object is a collection of Project objects.

Syntax

The CreateProjects method has the following syntax:

Object.CreateProjects

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Values

The CreateProjects method returns the following object:

Return Value | Description
Projects | An object of type Projects. This is a collection of Project objects.

Examples Using This Object

Display Project Details In A Combobox


CreateProjectCostCode Method

Description

The CreateProjectCostCode method is used to create an object of the specified type. This is the primary method used to create a business object that represents the Sage 50 Accounts data Project Costing Cost Code.

Syntax

The CreateProjectCostCode method has the following syntax:

Object.CreateProjectCostCode

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Values

The CreateProjectCostCode method returns the following object:

Return Value | Description
ProjectCostCode | An object of type ProjectCostCode. The object is not positioned at a record until the .Load method is used.

Examples Using This Method

Create a new Project CostCode
Amend a Project CostCode
Delete a Project CostCode
Post a Project Charge
Post a Project Credit
Post a Project Stock Issue
Post a Project Stock Return
Post a Project Supplier Invoice
Post a Project Supplier Credit
Post a Project Bank Payment


CreateProjectCostCodes Method

Description

The CreateProjectCostCodes method is used to create an object of the specified type. This is the primary method used to create a business object that represent the Sage 50 Accounts data Project Costing Cost Codes. This object is a collection of ProjectCostCode objects.

Syntax

The CreateProjectCostCodes method has the following syntax:

Object.CreateProjectCostCodes

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Values

The CreateProjectCostCode method returns the following object:

Return Value | Description
ProjectCostCodes | An object of type ProjectCostCodes. This is a collection of ProjectCostCode objects.

There are currently no examples that use this method.


CreateProjectOnlyTransaction Method

Description

The CreateProjectTransaction method is used to create an object of the specified type. This is the primary method used to create a business object that represents a Project Costing Cost Only Transaction.

Syntax

The CreateProjectOnlyTransaction method has the following syntax:

Object.CreateProjectOnlyTransaction

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Values

The CreateProjectTransaction method returns the following object:

Return Value | Description
ProjectOnlyTransaction | An object of type ProjectOnlyTransaction. The object is not positioned at a record until the .Load method is used.

Remarks

Examples Using This Method

Post a Project Charge
Post a Project Credit
Create a new project record


CreateProjectResource Method

Description

The CreateProjectResource method is used to create an object of the specified type. This is the primary method used to create a business object that represents the Sage 50 Accounts data Project Costing Resource.

Syntax

The CreateProjectResource method has the following syntax:

Object.CreateProjectResource

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Values

The CreateObject method returns the following object:

Return Value | Description
ProjectResource | An object of type ProjectResource. The object is not positioned at a record until the .Load method is used.

Remarks

You should always destroy any objects you create by setting them to Nothing.

Examples Using This Method

Create a new Project Resource
Amend a Project Resource
Delete a Project Resource
Post a Project Charge
Post a Project Credit


CreateProjectResources Method

Description

The CreateProjectResources method is used to create an object of the specified type. This is the primary method used to create a business object that represent the Sage 50 Accounts data Project Costing Resources. This object is a collection of ProjectResource objects.

Syntax

The CreateProjectResources method has the following syntax:

Object.CreateProjectResources

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Values

The CreateProjectCostCode method returns the following object:

Return Value | Description
ProjectResources | An object of type ProjectResources. This is a collection of ProjectResouce objects.

There are currently no examples that use this method.


CreateProjectStatus Method

Description

The CreateProjectStatus method is used to create an object of the specified type. This is the primary method used to create a business object that represents the Sage 50 Accounts data Project Costing Resource.

Syntax

The CreateProjectStatus method has the following syntax:

Object.CreateProjectStatus

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Values

The CreateObject method returns the following object:

Return Value | Description
ProjectStatus | An object of type ProjectStatus. The object is not positioned at a record until the .Load method is used.

Examples Using This Method

Create a new Project Record
Create a new Project Status
Amend a Project Status
Delete a Project Status
Marking a Project as Complete


CreateProjectStatuses Method

Description

The CreateProjectStatuses method is used to create an object of the specified type. This is the primary method used to create a business object that represent the Sage 50 Accounts data Project Costing Statuses. This object is a collection of ProjectStatus objects.

Syntax

The CreateProjectStatuses method has the following syntax:

Object.CreateProjectStatuses

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Values

The CreateProjectCostCode method returns the following object:

Return Value | Description
ProjectStatuses | An object of type ProjectStatuses. This is a collection of ProjectStatus objects.

Examples Using This Object

Display Project Statuses In A Combobox


CreateProjectTransaction Method

Description

The CreateProjectTransaction method is used to create an object of the specified type. This is the primary method used to create a business object that represents the Sage 50 Accounts data Project Costing Transaction.

Syntax

The CreateProjectTransaction method has the following syntax:

Object.CreateProjectTransaction

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Values

The CreateProjectTransaction method returns the following object:

Return Value | Description
ProjectTransaction | An object of type ProjectTransaction. The object is not positioned at a record until the .Load method is used.

There are currently no examples that use this method.


CreateProjectTransactions Method

Description

The CreateProjectTransactions method is used to create an object of the specified type. This is the primary method used to create a business object that represent the Sage 50 Accounts data Project Costing Transactions. This object is a collection of ProjectTransaction objects.

Syntax

The CreateProjectTransactions method has the following syntax:

Object.CreateProjectTransactions

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Values

The CreateProjectCostCode method returns the following object:

Return Value | Description
ProjectTransactions | An object of type ProjectTransactions. This is a collection of ProjectTransaction objects.

Examples Using This Method

View a Project Transactions


CreateSupplier Method

Description

The CreateSupplier method is used to create an object of the type Supplier. This is the method used to create an object that represent the Sage 50 Accounts data supplier on a Project Costing Transaction and a CIS Subcontractor Record.

Syntax

The CreateSupplier method has the following syntax:

Object.CreateSupplier

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Value

The CreateSupplier method returns the following value:

Return Value | Description
Supplier | An object of type SageDataObjectN.Supplier (N denotes SDO version e.g. 120)

Remarks

You should always destroy any objects you create by setting them to Nothing.

Examples Using This Object

There are no examples using this object


CreateSupplierAddress Method

Description

The CreateSupplierAddress method is used to create an object of the type SupplierAddress.

Syntax

The CreateSupplierAddress method has the following syntax:

Object.CreateSupplierAddress

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Value

The CreateCustomer method returns the following value:

Return Value | Description
SupplierAddress | An object of type SageDataObjectN.SupplierAddress (N denotes SDO version e.g. 180)

Remarks

You should always destroy any objects you create by setting them to Nothing.

Examples Using this Object

View Supplier Address Properties
Create a new Supplier Address


CreateSupplierAddresses Method

Description

The CreateSupplierAddresses method is used to create an object of the type SupplierAddress.

Syntax

The CreateSupplierAddr esses method has the following syntax:

Object.CreateSupplierAdd resses

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Value

The CreateSupplierAddresses method returns the following value:

Return Value | Description
SupplierAddresses | An object of type SageDataObjectN.SupplierAddresses (N denotes SDO version e.g. 180)

Remarks

You should always destroy any objects you create by setting them to Nothing.

Examples Using this Object

View Supplier Address Properties
Create a new Supplier Address


CreateTaxCode Method

Description

The CreateTaxCode method is used to create an object of the type TaxCode. This is the method used to create an object that represent the Sage 50 Accounts data Tax Code on a Project Costing ProjectTransaction.

Syntax

The CreateTaxCode method has the following syntax:

Object.CreateTaxCode

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Value

The CreateCustomer method returns the following value:

Return Value | Description
TaxCode | An object of type SageDataObjectN.TaxCode (N denotes SDO version e.g. 120)

Remarks

You should always destroy any objects you create by setting them to Nothing.

Examples Using this Object

Create a new Customer Address
Create a new Supplier Address


Name Property

Description

The Name property returns the name of the object.

For a Workspace object this property returns the name specified when the Workspace object is created using the Workspaces collection Add method.

For a Field object this property returns the internal name for the field. This name can be used when referring to the field within the Fields collection.

Syntax

The Name property has the following syntax:

object.Name

with the following parts:

Part | Description
Object | Applies to a Workspace or SDOField object.

Values

Holds the name of the object as a string expression.

Remarks

This property is Read Only.

Example

The following example demonstrates the use of the Name property:

  ' Declare Objects
Dim oSDO As
  SageDataObject300.SDOEngine
Dim oWS As
  SageDataObject300.WorkSpace

' Create the SDO Engine Object
Set oSDO =  New
  SageDataObject300.SDOEngine

' Create the Workspace
Set oWS = oSDO.Workspaces.Add("Example")

' Show the Name of the Workspace
MsgBox oWS.Name

' Destroy the SDO Objects
Set oWS =  Nothing
Set oSDO =  Nothing


UI Property

Description

The UI property enables you to enable or disable the standard SDO dialog boxes.

Syntax

The UI property has the following syntax:

object.UI = Value

with the following parts:

Part | Description
Object | Applies to the Workspace object.
Value | A boolean expression, True or False.

Values

As a boolean expression, the UI property holds one of the following values:

Value | Description
True | Show the SDO dialog boxes.
False | Do not show the SDO dialog boxes.

Remarks

The default value for the property is True. To disable the standard SDO dialog boxes (Open Setup.dta, Logon, User Name Already In Use), set the UI property to False. To ensure no dialog boxes appear, you should set the value as soon as you have created the Workspace object.

Example

The following example demonstrates the use of the UI property:

  ' Declare Objects
Dim oSDO As
  SageDataObject300.SDOEngine
Dim oWS As
  SageDataObject300.WorkSpace

' Create the SDO Engine Object
Set oSDO =  New
  SageDataObject300.SDOEngine

' Create the Workspace
Set oWS = oSDO.Workspaces.Add("Example")

' Set the UI Property so we get no dialog boxes
oWS.UI = False

' Destroy the SDO Objects
Set oWS =  Nothing
Set oSDO =  Nothing


Version Property

Description

The Version property holds the version of Sage 50 Accounts the Workspace relates to.

Syntax

The Version property has the following syntax:

object.Version

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Values

Holds the version of Sage 50 as a string expression. The string is a concatenation of the MAJOR_VERSION, MINOR_VERSION and REVISION_NO fields from the SetupData object.

Remarks

Prior to checking the Version property, you must have a valid connection in place.

This property is Read Only.

Example

The following example demonstrates the use of the Version property:

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Variables
  Dim szDataPath As Boolean

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace

  ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then
    ' Connect to Data Files
    If oWS.Connect szDataPath, "", "", "Example" Then

      ' Show the Version Number
      MsgBox oWS.Version

      ' Disconnect
      oWS.Disconnect

    End If

  End If

  ' Destroy Objects
  Set oWS = Nothing
   Set oSDO = Nothing

 ' Error Handling Code
Error_Handler:

  MsgBox "The SDO generated the following error: " & oSDO.LastError.Text


Business Object

Business Objects

Description

Sage Data Objects (SDO) for Sage 50 Accounts continues improving how Sage 50 Accounts integrated applications are developed.

With this release of the SDK, we continue to roll-out new business objects in favour of the traditional data object.

Business objects will offer you several distinct advantages over data objects:

  1. No knowledge of the underlying database structure is required - enabling you to bypass the time it takes to investigate data object models and relationships.

  2. They do all of the hard work for you - To appreciate the power of business objects, let us consider the Sage 50 Accounts sales order entry process. Upon selecting a customer account, and required line items, we hit the ‘save’ button. Sage 50 Accounts will read user-configured settings to automate discount and VAT calculations, stock allocations, nominal code assignments and more. Business objects will eventually deliver the same benefits of process automation to Sage 50 Accounts developers; saving hours if not days spent researching and reviewing Sage 50 Accounts application logic. At present, SDO shies away from some of these more complex tasks.

  3. You have the confidence that data integrity is preserved at all times - incomplete or invalid data submissions will always be rejected.

Please note - Over time business objects will be developed to replace all existing data objects, BUT, there are no immediate plans to end of life Sage Data Objects for Sage 50 Accounts. Where there is a business object, however, we'd recommend using it, as this will ease the transition from data objects in the future.

Business objects are created by calling their individual class factories, for example to create an instance of the Project object, you would call workspace.CreateProject, rather than calling the workspace.CreateObject("ObjectName") method and passing a string parameter.

To see an example using the new factory classes, follow this link.


Address Objects

Description

The Address objects are a set of business objects designed to give access to the Sage 50 Accounts address data. These objects are read and write enabled.

Objects

Business

The following table lists all the Address Business Objects:

Object | Description | Object Type
CompanyAddress | Address Listed against the company record | Business
CustomerAddress | Address Listed against the customer records | Business
SupplierAddress | Address Listed against the supplier record | Business

Address Business Objects have the methods below.

Method | Description
Delete | Deletes the current record and will return false if the record cannot be removed.
Load | Load can be the record based on the Primary key (Integer), or the record based on a unique key field(String).
Update | The Update method commits changes to the data files. Depending on the object being used, the method will perform certain validation checks and will return False if the data in the object is invalid.

Collection

The following table lists all the Address Collection Objects:

Object | Description | Object Type
CompanyAddresses | Collection of Company Address Records | Collection
CustomerAddresses | Collection of Customer Address Records | Collection
SupplierAddresses | Collection of Supplier Address Records | Collection

Address Collection Business Objects have the method below. Note: These methods do not apply to the single objects.

Method | Description
GetEnumerator | Returns an enumerator for this object.
Item

Returns an instance of an item within a collection using an indexed field as the basis for the search.


CompanyAddress

Description

The CompanyAddress object gives access to the Company Address properties to read and write data.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

The object has no fields collection.

Methods
Method | Description
Delete | Delete
Load | Load
Update | Update

Properties

Property | Description | Length | Input | Data Type
AddressLine1 | Address Line 1 | 60 | Optional | String
AddressLine2 | Address Line 2 | 60 | Optional | String
AddressLine3 | Address Line 3 | 60 | Optional | String
AddressLine4 | Address Line 4 | 60 | Optional | String
AddressLine5 | Address Line 5 | 60 | Optional | String
AddressNumber | Index Number of The Address | 4 | Auto Generated | Integer
AddressType | Address Type | 1 | Required | Integer
Contact | Contact Name | 30 | Optional | String
Country | Country | 2 | Optional | String
Description | Description Of Address | 30 | Optional | String
EMail | Email Address | 255 | Optional | String
Fax | Fax Number | 30 | Optional | String
Name | Name | 60 | Optional | String
Notes | Notes | 200 | Optional | String
Role | Role | 30 | Optional | String
Telephone | Telephone | 30 | Optional | String
Telephone2 | Telephone 2 | 30 | Optional | String

Examples Using this Object

View Company Address Properties
Create New company Address


CompanyAddresses

Description

The CompanyAddresses object gives access to the collection of associated company addresses including delivery addresses.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

The object has no fields collection.

Methods

Method | Description
GetEnumerator | Returns an enumerator for this object
Item | Returns an object of the specified collection type based on a specified index value

Properties

Property | Description
Count | Returns the number of addresses in the current collection.

Examples Using this Object

View Company Address Properties
Create New company Address


CustomerAddress

Description

The CustomerAddress object gives access to the Customer Address (SALDA.DTA) table and the Customer Delivery Address Index (SALDAIDX.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

The object has no fields collection.

Methods
Method | Description
Delete | Deletes the current record and will return false if the record cannot be removed
Load | Load can be the record based on the Primary key (Integer), or the record based on a unique key field(String)
Update | The Update method commits changes to the data files. Depending on the object being used, the method will perform certain validation checks and will return False if the data in the object is invalid

Properties

Property | Description | Length | Input | Data Type
AddressLine1 | Address Line 1 | 60 | Optional | String
AddressLine2 | Address Line 2 | 60 | Optional | String
AddressLine3 | Address Line 3 | 60 | Optional | String
AddressLine4 | Address Line 4 | 60 | Optional | String
AddressLine5 | Address Line 5 | 60 | Optional | String
AddressNumber | Index Number of The Address | 4 | Auto Generated | Integer
AddressType | Address Type | 1 | Required | Integer
Contact | Contact Name | 30 | Optional | String
Country | Country | 2 | Optional | String
Customer | Customer Name | 255 | Optional | String
Description | Description Of Address | 30 | Optional | String
EMail | Email Address | 255 | Optional | String
EORINumber | Delivery address EORI Number | 17 | Optional | String
Fax | Fax Number | 30 | Optional | String
ModifyDate | Read-Only Property for the Modify Date | 2 | Optional | Date
Name | Name | 60 | Optional | String
Notes | Notes | 200 | Optional | String
Role | Role | 30 | Optional | String
TaxCode | Tax Code | 10 | Optional | Integer
Telephone | Telephone | 30 | Optional | String
Telephone2 | Telephone 2 | 30 | Optional | String
VatNumber | Vat Number | 20 | Optional | String

Examples Using this Object

View Customer Address Properties
Edit a Customer Address
Create a new Customer Address


CustomerAddresses

Description

The CustomerAddresses object gives access to the Customer Delivery Address collection (SALDA.DTA) table. and the Customer Delivery Address Index (SALDAIDX.DTA) table. As an SDOBusiness object, it encapsulates both the data and index files.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

The object has no fields collection.
Methods
Method | Description
GetEnumerator | Returns an enumerator for this object
Item | Returns an object of the specified collection type based on a specified index value

Properties

Property | Description
Count | Returns the number of items in the collection.

Examples Using this Object

View Customer Address Collection
Find Customer Address Using GetEnumerator
Create a new Customer Address


ChartData

SupplierAddress

Description

The SupplierAddress object gives access to the Supplier Address (PURDA.DTA) table and the Supplier Delivery Address Index (PURDAIDX.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

The object has no fields collection.

Methods
Method | Description
Delete | Delete
Load | Load
Update | Update

Properties

Property | Description | Length | Input | Data Type
AddressLine1 | Address Line 1 | 60 | Optional | String
AddressLine2 | Address Line 2 | 60 | Optional | String
AddressLine3 | Address Line 3 | 60 | Optional | String
AddressLine4 | Address Line 4 | 60 | Optional | String
AddressLine5 | Address Line 5 | 60 | Optional | String
AddressNumber | Index Number of The Address | 4 | Auto Generated | Integer
AddressType | Address Type | 1 | Required | Integer
Contact | Contact Name | 30 | Optional | String
Country | Country | 2 | Optional | String
Customer | Customer Name | 255 | Optional | String
Description | Description Of Address | 30 | Optional | String
EMail | Email Address | 255 | Optional | String
EORINumber | Delivery address EORI Number | 17 | Optional | String
Fax | Fax Number | 30 | Optional | String
ModifyDate | Read-Only Property for the Modify Date | 2 | Optional | Date
Name | Name | 60 | Optional | String
Notes | Notes | 200 | Optional | String
Role | Role | 30 | Optional | String
Supplier Supplier object - Optional Supplier
TaxCode | Tax Code | 10 | Optional | Integer
Telephone | Telephone | 30 | Optional | String
Telephone2 | Telephone 2 | 30 | Optional | String
VatNumber | Vat Number | 20 | Optional | String

Examples Using this Object

View Supplier Address Properties
Create a new Supplier Address


SupplierAddresses

Description

The SupplierAddresses object gives access to the Supplier Delivery Address collection(PURDA.DTA) table. and the Supplier Delivery Address Index (PURDAIDX.DTA) table. As an SDOBusiness object, it encapsulates both the data and index files.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

The object has no fields collection.

Methods

Method | Description
GetEnumerator | Gets Enumerator
Item | Item

Properties

Property | Description
Count | Counts The Number Of Addresses In The Collection.

Examples Using this Object

View Supplier Address Collection
Find Supplier Address Using GetEnumerator
Create a new Supplier Address


Delete Method

Description

The Delete method is used to delete a record. A boolean value is returned as to whether the delete has been successful or not.

Syntax

The Delete method has the following syntax:

Object.Delete

with the following parts:

Part | Description
Object | Applies to the following objects: Project, ProjectCostCode, ProjectResource ProjectStatus CompanyAddress, CustomerAddress, ContactHistory and SupplierAddress.

Return Value(s)

The method returns the following values:

Value | Description
True | The object has been deleted.
False | The object cannot be deleted.

Examples Using This Method

Delete a Project Record
Delete a Project Cost Code
Delete a Project Resource
Delete a Project Status
Delete a Contact History Item


Load Method

Description

The Load method is used to load a record using an integer or string as the basis for the search.

Syntax

The Load method has the following syntax:

Object.Load(Reference As Object)

with the following parts:

Part | Description
Object | Applies to one of the following types: CharityFund, CharityFundType, CISSetting, CISSubcontractor, CISSubcontractorLegacy, CISSubcontractorTaxHistory, Country, Customer, Department, DisputedReason, ESubmissionSetting, FinancialBudget, Nominal, Product, Project, ProjectCostCode, ProjectOnlyTransaction, ProjectResource, ProjectStatus, ProjectTransaction, StockAllocation, Supplier and TaxCode.
Reference | This is of type Object representing the Object primary key field. This is of type String or Integer depending on the type of the primary key field for the object.

Return Value(s)

The method returns the following values:

Value | Description
True | The object has been loaded.
False | The object cannot be loaded.

Examples Using This Method

Create a new Project Record
Amend a Project Record
Delete a Project Record
Amend a Project Cost Code
Delete a Project Cost Code
 Amend a Project Resource
Delete a Project Resource
 Amend a Project Status
Delete a Project Status
Post a Project Charge
Post a Project Credit
Post a Project Stock Issue
Post a Project Stock Return
Post a Project Supplier Invoice
Post a Project Supplier Credit
Post a Project Bank Payment
Post a Project Product Invoice
Post a Project Service Invoice
Post a Project Sales Order
Marking a Project as Complete
View a Project Transactions
Reading Disputed Reasons
Reading Nominal Budgets
Reading Financial Budgets
Amending CIS and ESubmission Settings
Creating a New Subcontractor Record
Creating a Subcontractor Record from an existing Supplier Record
Posting a Subcontractor Invoice
How to use CIS Collection Objects


Update Method

Description

The Update method commits changes to the data files. Depending on the object being used, the method will perform certain validation checks and will return False if the data in the fields collection of the object is invalid.

Syntax

The Update method has the following syntax:

object.Update

with the following parts:

Part | Description
Object | Applies to one of the following types: SDORecord, SDORecordLinked and SDOIspPost.

Return Values

The Update method returns the following values:

Return Value | Description
True | The record was successfully updated.
False | The record could not be updated as the fields collection contained one or more invalid values. The fields checked by the update method vary depending on the object being used.

Remarks

Prior to calling Update, you must have previously have called either AddNew or Edit.

Examples

This example uses the Update method in conjunction with AddNew to create a new Customer Account.

    ' Error Handler
On Error GoTo Error_Handler

' Declare Objects
Dim oSDO As
  SageDataObject300.SDOEngine
Dim oWS As
  SageDataObject300.WorkSpace
Dim oSalesRecord As
  SageDataObject300.SalesRecord

' Declare Variables
Dim szDataPath As
  String

' Create the SDO Engine Object
Set oSDO =  New
  SageDataObject300.SDOEngine

' Create the Workspace
Set oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user.  If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> ""  Then

' Connect to Data Files
oWS.Connect szDataPath, "", "",
  "Example"

' Create an Instance of the SalesRecord Object
Set oSalesRecord = oWS.CreateObject("SalesRecord")

' Add a New Record
if oSalesRecord.AddNew Then

' Populate Fields
oSalesRecord.Fields.Item("ACCOUNT_REF").Value = CStr("0123")
oSalesRecord.Fields.Item("NAME").Value = CStr("New SDO Account")
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 & Wear")
oSalesRecord.Fields.Item("ADDRESS_5").Value = CStr("NE13
  9AA")
oSalesRecord.Fields.Item("CONTACT_NAME").Value = CStr("Audrey Hepburn")
oSalesRecord.Fields.Item("TELEPHONE").Value = CStr("0845
  1117733")
oSalesRecord.Fields.Item("FAX").Value = CStr("0845
  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

' Update Successful
MsgBox ("Account " & oSalesRecord("ACCOUNT_REF")
  & " successfully created.")

Else

' Update Unsuccessful
MsgBox ("Failed to Create Record.")

End If

End If

' Disconnect
oWS.Disconnect

End If

' Destroy Objects
Set oSalesRecord =  Nothing
Set oWS =  Nothing
Set oSDO =  Nothing

Exit Sub

' Error Handling Code
Error_Handler:

MsgBox "The SDO generated the following error: " &
    oSDO.LastError.Text

Update Returning False

The table below details the most common reasons for the Update method returning False:

Object | Reason for Failure
NominalRecord | No or invalid value for ACCOUNT_REF.
SalesRecord | No or invalid value for ACCOUNT_REF.
PurchaseRecord | No or invalid value for ACCOUNT_REF.
TransactionPost No or invalid value for ACCOUNT_REF. (i.e. Account must exist in Sage 50 Accounts)
No or invalid value for NOMINAL_CODE. (i.e. Account must exist in Sage 50 Accounts)
Zero values for NET_AMOUNT and TAX_AMOUNT (i.e. You cannot post a zero value transaction using the SDO)

Related Topics

Properties and Methods | Description
AddNew | Clears a buffer so that a new entry can be added to the data files.
CancelUpdate | Cancels an AddNew or Edit.
Edit | Allows the editing of an existing record.


Item Method

Description

The Item method is used to return an instance of an item within a collection using an indexed field as the basis for the search.

Syntax

The Item method has the following syntax:

Object.Item(Index As Object)

with the following parts:

Part | Description
Object | Applies to one of the following types: Projects, ProjectCostCodes, ProjectResources, ProjectStatuses, ProjectTransactions, Stock Allocations, CompanyAddresses, CustomerAddresses and SupplierAddresses
Index | This can be of type Integer representing the Object position (0 based).

Return Value

The method returns the following value:

Value | Description
Object | Returns an object based on the type returned by the collection e.g. Projects.Item(0) returns an object of type Project positioned at the first record.

Examples Using this Object

View Customer Addresses Properties Using Item Method


Method GetEnumerator

GetEnumerator Method

Description

The GetEnumerator method is used to return the IEnumerator for the collection.

Syntax

The Item method has the following syntax:

Object.GetEnumerator()

with the following parts:

Part | Description
Object | Applies to one of the following types: CompanyAddresses, CustomerAddresses, SupplierAddresses,
Index | This can be of type Integer representing the Object position (1 based in VB, 0 based in C#, can be changed).

Return Value

The method returns the following value:

Value | Description
Object | Returns a IEnumerator for the object collection

Examples Using this Object

Find Customer Address using GetEnumerator
Find Supplier Address using GetEnumerator


Count Property

Description

The Count property returns the number of records in the collection. For SDOFile objects, this will include deleted records. For SDORecord objects, the deleted records are not included.

Syntax

The Count property has the following syntax:

object.Count

with the following parts:

Part | Description
Object | Applies to one of the following types: SDORecord, SDORecordLinked, SDOFile, SDOIndexFile, SDOLinkedFile and SDOLinkedSubFile.

Values

The Count property returns an integer value.

Remarks

The Count property is Read Only.

Example

The following example uses the Count property to return the number of Customer records:

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oSalesRecord As SageDataObject300.SalesRecord

  ' Declare Variables
  Dim szDataPath As String

   ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then
    ' Connect to Data Files
    oWS.Connect szDataPath, "", "", "Example"

    ' Create an Instance of the SalesRecord object
    Set oSalesRecord = oWS.CreateObject("SalesRecord")

    ' Display the Number of Records
    MsgBox oSalesRecord.Count

    ' Disconnect
    oWS.Disconnect

  End If

  ' Destroy Objects
  Set oSalesRecord = Nothing
   Set oWS = Nothing
  Set oSDO = Nothing

  Exit Sub

' Error Handling Code
 Error_Handler:
  MsgBox "The SDO generated the following error: " & oSDO.LastError.Text


Object Description

Charity Funds

Description

The Charity Fund objects are business objects designed to give access to the Sage 50 Accounts Charity Fund module. Values are set on each object by assigning a value to the object's properties, NOT by using a fields collection.

Objects

Business

The following table lists all the Charirty Fund business objects:

Object | Description | Object Type
CharityFund | CharityFund record | Business
CharityFundType | ChartiyFundType record (read-only) | Business

CharityFund Business objects have the methods below.

Method | Description
Load | Load can be the record based on the Primary key (Integer), or the record based on a unique key field (String).
Update | (CharityFund object only) The Update method commits changes to the data files. It will also perform certain validation checks and will return False if the data in the object is invalid.

Examples

Creating a New Charity Fund


CharityFund

Description

The CharityFund object gives access to the Funds (FUND.DTA and FUNDIDX.DTA) table.

The FundID property is read-only.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Properties

Name | Description | Length | Input | Data Type
CONTACT | Fund Contact | 30 | Optional | String
DESCRIPTION | Fund Name | 63 | Optional | String
FUNDID Fund ID Number - Optional Integer
FUNDTYPE CharityFundType Object - Optional Object (FundType)
HELDBY | Fund Institution | 62 | Optional | String
NOMINAL Fund Nominal Object - Optional Object (Nominal)
Methods

Click here for a list of Methods for this object.

Remarks

The primary key field for the CharityFund object is the property FundID. This is the value that a search will be performed on when the .Load method is used, i.e. FundID.Load(FundID as Integer).

Examples Using this Object

Creating a New Charity Fund


CharityFundType

Description

The CharityFundType object gives read-only access to the FundsType (FUNDTYPE.DTA and FUNDTIDX.DTA) table.

There are three fund types, 1] Unrestricted, 2] Restricted and 3] Endowment. These can be read by passing in either the number of the Fund Type (integer) or the fund type name (string) as a parameter to the Load method.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Properties

Name Description Length Input Data Type
DESCRIPTION Fund Type Description - Optional String
FUNDTYPEID Fund Type ID - Optional Integer
Methods

Click here for a list of Methods for this object.

Examples Using this Object

Creating a New Charity Fund


Update Method

Description

The Update method is used to update a record. A boolean value is returned as to whether the update has been successful or not.

Syntax

The Update method has the following syntax:

Object.Update

with the following parts:

Part | Description
Object | Applies to the following objects: CISSetting, CISSubcontractor, CISSubcontractorLegacy, CISSubcontractorTaxHistory, CharityFund, DisputedReason, ESubmissionSetting, Project, ProjectCostCode, ProjectResource, ProjectStatus and StockAllocation.

Return Value(s)

The method returns the following values:

Value | Description
True | The object has been updated.
False | The object cannot be updated.

Remarks

When creating a new Object if one already exists that has the same reference then an exception (sdoInvalidSave) is thrown. If editing an existing object then make sure that it is loaded using the .Load method prior to making any changes and updating.

Examples Using This Method

Create a new Project Record
Amend a Project Record
Create a new Project Cost Code
Amend a Project Cost Code
Create a new Project Resource
Amend a Project Resource
Create a new Project Status
Amend a Project Status
Marking a Project as Complete
Creating a Charity Fund
Amending CIS and ESubmission Settings
Creating a New Subcontractor Record
Creating a Subcontractor Record from an existing Supplier Record


CIS Subcontractor Objects

Description

The CIS Subcontractor objects are a set of business objects designed to give access to the Sage 50 Accounts CIS module. Values are set on each object by assigning a value to the object's properties, NOT by using a fields collection.

Objects

Business

The following table lists all the CIS Business objects:

Object | Description | Object Type
CISSetting | CIS Settings | Business
ESubmissionSetting | ESubmission Settings | Business
CISSubContractor | Subcontractor Record | Business
CISSubcontractorLegacy | CIS Subcontractor Legacy Details (Pre 2007 Information) | Business
CISSubcontractorTaxHistory | CIS Subcontractor Tax History Details | Business

CIS Business objects have the methods below.

Method | Description
Load | Load can be the record based on the Primary key (Integer), or the record based on a unique key field(String).
Update | The Update method commits changes to the data files. Depending on the object being used, the method will perform certain validation checks and will return False if the data in the object is invalid.

Collection

The following table lists all the CIS Collection objects:

Object | Description | Object Type
CISSubcontractors | Collection of CIS Subcontractor Records | Collection
CISSubcontractorLegacys | Collection of CIS Subcontractor Legacys (Pre 2007 Information) | Collection
CISSubcontractorTaxHistorys | Collection of CIS Subcontractor Tax Historys | Collection

CIS collection objects have the method below. Note: These methods do not apply to the single objects.

Method | Description
Item | Returns an object of the specified collection type based on a specified index value.


CISSetting

Description

The CISSetting object represents the CIS tab within Company Preferences.

Applies to

CIS Module.

Properties

Name | Description | Length | Input | Data Type
AccountsOfficeReference | Accounts Office Reference Number | 13 | Required | String
CISControlReference | CIS Tax Control Nominal Code | n/a | Required | Object
CISCITBLevyNominal | CIS CITB Nominal Code | n/a | Required | Object
CISLabourNominal | CIS Labour Nominal Code | n/a | Required | Object
CISMaterialsNominal | CIS Materials Nominal Code | n/a | Required | Object
CISOtherNonTaxableNominal | CIS Other Non-Taxable Nominal Code | n/a | Required | Object
CISOtherTaxableNominal | CIS Other Taxable Nominal Code | n/a | Required | Object
CISTaxLiabilityNominal | CIS Tax Liability Nominal Code | n/a | Required | Object
CompanyRegistrationNo | Company Registration Number | 13 | Required | String
EndOfNextPeriod | End of Next Period Date (Not visible in program) | 2 | Optional | Date
HigherRate | Higher CIS Tax Rate % | 5 | Required | Double
IsCISEnabled | Is CIS Enabled | 2 | Read Only | Boolean
IsContractor | Not visible in program | 2 | Optional | Boolean
IsInactive | Not visible in program | 2 | Optional | Boolean
IsSubcontractor | Not visible in program | 2 | Optional | Boolean
NationalInsuranceNo | Not visible in program | 2 | Required | String
StandardRate | Standard CIS Tax Rate % | 5 | Required | Double
UniqueTaxReference | Unique Tax Reference Number | 10 | Required | String
Methods
Method | Description | Parameters | Output
Load | The Load method is used to load the CIS Setting object | None | Boolean
Update | The Update method commits changes to the data files. It will perform certain validation checks and will return false if the data in the object is invalid. | None | Boolean
Remarks

In order to call the Update method the Load method must first be called.

Examples Using This Object

Example - Amending CIS and ESubmission Settings


CISSubcontractor

Description

The CISSubContractor object represents the CIS tab of a Subcontractor Record.

Applies to

CIS Module.

Properties

Name | Description | Length | Input | Data Type
CompanyRegistrationNumber | Company Registration Number | 8 | Required | String
CompanyType | Business Type | 1 | Required | Byte
FirstName | First Name or Initial | 35 | Required (if Trading Name not relevant) | String
LastName | Surname | 35 | Required (if Trading Name not relevant) | String
LastVerified | Last Verified Date | 8 | Optional | Date
LegalName | Legal Name | 56 | Optional | String
MiddleName | Middle Name or Initial | 35 | Required (if Trading Name not relevant) | String
NationalInsuranceNumber | National Insurance Number | 9 | Required (if Unique Tax Reference is not available) | String
PartnershipName | Partnership Name | 56 | Required (if Business Type = Partnership) | String
PartnershipUTR | Partnership Unique Tax Reference | 10 | Required (if Business Type = Partnership) | String
PaymentFrequency | Payment Frequency to HMRC (Fortnightly / Monthly) | 1 | Optional | Byte
PaymentToThirdParty | Agreement to Pay a Third Party | 2 | Optional | Boolean
SendStatementByEmail | Send Statement By Email | 2 | Optional | Boolean
CISSubcontractorLegacy | CISSubcontractorLegacy object | n/a | Optional | Object
Supplier | Supplier Object | n/a | Required | Object
TaxHistorys | Tax Historys Object | n/a | Optional | Object
ThirdPartySupplier | Third Party Supplier Object | n/a | Optional | Object
TradingName | Trading Name | 56 | Required (if First Name and Surname are not completed) | String
TrustCommunicationName | Trust Communication Name | Optional | String
UniqueTaxReference | Unique Tax Reference | 10 | Required (if Business Type = Partnership) | String
UseLegalNameInReports | Use legal name in reports | 2 | Optional | Boolean
VerificationReferenceNumber | Verification Number | 13 | Required | String
VerificationStatus | Verification Status | 1 | Optional | Byte
Methods
Method | Description | Parameters | Output
Load | The Load method is used to load the CISSubcontractor object | Reference As Object | Boolean
Update | The Update method commits changes to the data files. It will perform certain validation checks and will return false if the data in the object is invalid. | None | Boolean

Examples Using This Object

Example - Creating a New Subcontractor Record
Example - Creating a Subcontractor Record From an Existing Supplier Record
Example - Posting a Subcontractor Invoice
Example - Posting a Subcontractor Payment
Example -Edit CIS details


CISSubcontractors

Description

The CISSubcontractors object represents a collection of CISSubcontractor objects.

Applies to

CIS Module

Properties

Name | Description | Length | Input | Data Type
Count | Returns the count of the collection. | 4 | Read-Only | Integer
Methods

There is one method (.Item) on this object, click here to view details.

Examples Using This Object

Example - How To Use CIS Collection Objects


CISSubcontractorLegacy

Description

The CISSubcontractorLegacy object represents the represents the Pre-2010 CIS information on a Subcontractor Record.

Applies to

CIS Module.

Properties

Name | Description | Length | Input | Data Type
CardType | CIS Card Type | 1 | Optional | Byte
CISNumber | CIS Number | 13 | Optional | String
CISType | CIS Type | 1 | Optional | Byte
Supplier | Supplier Object | n/a | Optional | Object
ValidFrom | Valid From Date | 2 | Optional | Date
ValidTo | Valid To Date | 2 | Optional | Date
Methods
Method | Description | Parameters | Output
Load | The Load method is used to load the CIS Setting object | Reference As String | Boolean
Update | The Update method commits changes to the data files. It will perform certain validation checks and will return false if the data in the object is invalid. | None | Boolean

Examples Using This Object

Example - Creating a New Subcontractor Record
Example - Creating a Subcontractor Record From an Existing Supplier Record
Example - Posting a Subcontractor Invoice
Example - Creating a New Subcontractor Record
Example -Edit CIS details


CISSubcontractorLegacys

Description

The CISSubcontractorLegacys object represents a collection of CISSubcontractorLegacy objects.

Applies to

CIS Module.

Properties

Name | Description | Length | Input | Data Type
Count | Returns the count of the collection. | 4 | Read-Only | Integer
Methods

There is one method (.Item) on this object, click here to view details.

Examples Using This Object

There are currently no examples that use this object.


CISSubcontractorTaxHistory

Description

The CISSubcontractorTaxHistory object represents a Sage 50 Accounts Tax History within a Subcontractor Record.

Applies to

CIS Module.

Properties

Name | Description | Length | Input | Data Type
EndDate | End Date | 2 | Required | Date
StartDate | Start Date | 2 | Required | Date
Supplier | Supplier Object | n/a | Required | Object
TaxTreatment | Tax Treatment Type | 1 | Required | Byte

Methods

Method | Description | Parameters | Output
Load | The Load method is used to load the CIS Setting object | Reference As String | Boolean
Update | The Update method commits changes to the data files. It will perform certain validation checks and will return false if the data in the object is invalid. | None | Boolean
Delete | Deletes the current record and will return false if the record cannot be removed | None | Boolean

Examples Using This Object

Example - Creating a New Subcontractor Record
Example - Creating a Subcontractor Record From an Existing Supplier Record
Example - Posting a Subcontractor Invoice
Example - Posting a Subcontractor Payment
Example -Edit CIS details


Project

CISSubcontractorTaxHistorys

Description

The CISSubcontractorTaxHistorys object represents a collection of CISSubcontractorTaxHistory objects.

Applies to

CIS Module.

Properties

Name | Description | Length | Input | Data Type
Count | Returns the count of the collection. | 4 | Read-Only | Integer
Methods

There is one method (.Item) on this object, click here to view details.

Examples Using This Object

There are currently no examples that use this method.


ESubmissionSetting

Description

The ESubmissionSetting object represents the ESubmission Settings of the CIS tab within Company Preferences.

Applies to

CIS Module.

Properties

Name | Description | Length | Input | Data Type
EMail | EMail Address | 39 | Required | String
Fax | Fax Number (not visible in program) | 21 | Optional | String
Forenames | Contact Forename | 30 | Required | String
Password | ESubmissions Password | 21 | Required | String
Salutation | Contact Salutation (not visible in program) | Optional | String
SenderType | ESubmission Sender Type | 1 | Required | Byte
SubmitAsAgent | Submit as an Agent Checkbox | 2 | Optional | Boolean
Surname | Contact Surname | 30 | Required | String
TaxOfficeNumber | Tax Office Number | 3 | Required | String
TaxOfficeReference | Tax Office Reference | 10 | Required | String
Telephone | Contact Telephone Number | 20 | Required | String
UserID | ESubmissions UserID | 21 | Required | String
Methods
Method | Description | Parameters | Output
Load | The Load method is used to load the ESubmission Setting object | None | Boolean
Update | The Update method commits changes to the data files. It will perform certain validation checks and will return false if the data in the object is invalid. | None | Boolean
Remarks

In order to call the Update method the Load method must first be called.

Examples Using This Object

Example - Amending CIS and ESubmission Settings


Country Property

CISControlReference

Description

The CISControlReference property returns an object of type Nominal for CIS within Sage 50.

Syntax

The CISControlReference property has the following syntax:

Object.CISControlReference

with the following parts:

Part | Description
Object | Applies to the following object: CISSetting.
CISControlReference | Returns the Nominal object of the current record.

Examples Using This Method

Example - Amending CIS Settings


Country Property

CISLabourNominal

Description

The CISLabourNominal property returns an object of type Nominal for CIS within Sage 50.

Syntax

The CISLabourNominal property has the following syntax:

Object.CISLabourNominal

with the following parts:

Part | Description
Object | Applies to the following object: CISSetting.
CISLabourNominal | Returns the Nominal object of the current record.

Examples Using This Method

Example - Amending CIS Settings


CIS Materials Nominal Property

CISMaterialsNominal

Description

The CISMaterialsNominal property returns an object of type Nominal for CIS within Sage 50.

Syntax

The CISMaterialsNominal property has the following syntax:

Object.CISMaterialsNominal

with the following parts:

Part | Description
Object | Applies to the following object: CISSetting.
CISMaterialsNominal | Returns the Nominal object of the current record.

Examples Using This Method

Example - Amending CIS Settings


CISOtherNonTaxableNominal Property

CISOtherNonTaxableNominal

Description

The CISOtherNonTaxableNominal property returns an object of type Nominal for CIS within Sage 50.

Syntax

The CISOtherNonTaxableNominal property has the following syntax:

Object.CISOtherNonTaxableNominal

with the following parts:

Part | Description
Object | Applies to the following object: CISSetting.
CISOtherNonTaxableNominal | Returns the Nominal object of the current record.

Examples Using This Method

Example - Amending CIS Settings


CISOtherTaxableNominal Property

CISOtherTaxableNominal

Description

The CISOtherTaxableNominal property returns an object of type Nominal for CIS within Sage 50.

Syntax

The CISOtherTaxableNominal property has the following syntax:

Object.CISOtherTaxableNominal

with the following parts:

Part | Description
Object | Applies to the following object: CISSetting.
CISOtherTaxableNominal | Returns the Nominal object of the current record.

Examples Using This Method

Example - Amending CIS Settings


CISTaxLiabilityNominal Property

CISTaxLiabilityNominal

Description

The CISTaxLiabilityNominal property returns an object of type Nominal for CIS within Sage 50.

Syntax

The CISTaxLiabilityNominal property has the following syntax:

Object.CISTaxLiabilityNominal

with the following parts:

Part | Description
Object | Applies to the following object: CISSetting.
CISTaxLiabilityNominal | Returns the Nominal object of the current record.

Examples Using This Method

Example - Amending CIS Settings


SubcontrctorLegacy Property

Description

The SubcontrctorLegacy property returns an object of type CISSubcontrctorLegacy for use with CIS within Sage 50.

Syntax

The SubcontrctorLegacy property has the following syntax:

Object.SubcontrctorLegacy

with the following parts:

Part | Description
Object | Applies to the following object: CISSubcontractor.
CISSubcontrctorLegacy | Returns the CISSubcontrctorLegacy object of the current record.

Examples Using This Method

There are currently no examples that use this property.


Supplier Property

Description

The Supplier property returns an object of type Supplier for use with Project Costing within Sage 50 Accounts.

Syntax

The Supplier property has the following syntax:

Object.Supplier

with the following parts:

Part | Description
Object | Applies to the following object: ProjectTransaction; CISSubcontractor;
Supplier | Returns the Supplier object of the current record.

Examples Using This Object

Example - Creating a New Subcontractor Record
Example - Creating a Subcontractor Record From an Existing Supplier Record
Example -Edit CIS details


TaxHistorys Property

Description

The TaxHistorys property returns an object of type TaxHistorys for use with CIS within Sage 50.

Syntax

The Supplier property has the following syntax:

Object.TaxHistorys

with the following parts:

Part | Description
Object | Applies to the following object: CISSubcontractor.
CISSubcontractorTaxHistorys | Returns the Supplier object of the current record.

Examples Using This Method

Example - Creating a New Subcontractor Record


ThridPartySupplier Property

ThirdPartySupplier Property

Description

The ThirdPartySupplier property returns an object of type Supplier for use with CIS within Sage 50.

Syntax

The Supplier property has the following syntax:

Object.ThirdPartySupplier

with the following parts:

Part | Description
Object | Applies to the following object: CISSubcontractor.
Supplier | Returns the Supplier object of the current record.

Examples Using This Method

Example - Creating a New Subcontractor Record


CustomerAddress

ContactHistory

Description

The ContactHistory object represents a Sage 50 Accounts Contacy History entry in the Customers/Suppliers Record.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

The object has no fields collection.

Methods
Method | Description
Delete | Deletes the current record and will return false if the record cannot be removed
Load | The Load method is used to load a record
Update | The Update method commits changes to the data files. Depending on the object being used, the method will perform certain validation checks and will return False if the data in the object is invalid

Properties

Property | Description | Length | Input | Data Type
AccountRef | Customer/Supplier account Reference | 8 | Required | String
AddressLine1 | Address Line 1 | 60 | Optional | String
AddressLine2 | Address Line 2 | 60 | Optional | String
AddressLine3 | Address Line 3 | 60 | Optional | String
AddressLine4 | Address Line 4 | 60 | Optional | String
AddressLine5 | Address Line 5 | 60 | Optional | String
Balance | Balance | 8 | Optional | Double
ContactDate | Contact Date | 2 | Required | Date
ContactName | Contact Name | 17 | Optional | String
CustomerSupplier | Customer/Supplier | N/A | Required | SageDataObject300.ContactType
Duration | Duration in seconds | 8 | Optional | Int32
End | Telephone Timer End | 8 | Optional | Int32
FollowUpDate | Follow Up Date | 2 | Optional | Date
FollowUpEventID | Follow Up event ID | 2 | Optional | Int32
FollowUpTime | Follow Up time | 2 | Optional | Date
HasExternalLink | Sets whether has external link (0 = No, 1 = Yes) | 2 | Optional | Int16
Invoiced | Invoice Created? | 1 | Optional | Int16
Location | Location(only used on Meeting MajorContactType) | 1 | Optional | Int16
MajorContactType | Contact Type | N/A | Required | SageDataObject300.ContactHistoryMajorContactType
Note1 | Note1 | 60 | Optional | String
Note2 | Note2 | 60 | Optional | String
Note3 | Note3 | 60 | Optional | String
Offset | Offset | 8 | Optional | Int32
OurContactUserName | Existing User That Logged This Contact | 20 | Optional | String
Outcome | Outcome | N/A | Optional | SageDataObject300.ContactHistoryOutcome
Offset | Offset | 8 | Optional | Int32
PromisedDate | Promised Date | 2 | Optional | Date
PromisedPayment | Promised Payment | 8 | Optional | Double
Start | Telephone Timer Start | 8 | Optional | Int32
Style | Style | 1 | Optional | Int16
SubContactType | SubContactType | N/A | Optional | SageDataObject300.ContactHistorySubContactType
Subject | Subject | 255 | Required | String
Telephone | Telephone | 30 | Optional | String
UniqueID | UniqueID | 8 | Optional | Int32

Examples Using this Object

View Contact History Properties
Edit a Contact History Item
Create New Contact History Item


ContactHistorys

Description

The ContactHistorys object gives access to the Contact Historys collection. As an SDOBusiness object, it encapsulates both the data and index files.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

The object has no fields collection.
Methods
Method | Description
GetEnumerator | Returns an enumerator for this object
Item | Returns an object of the specified collection type based on a specified index value

Properties

Property | Description
Count | Returns the number of items in the collection.

Examples Using this Object

View Contact History Properties
Edit a Contact History Item
Create New Contact History Item


Diary Entry Objects

Description

The DiaryEntry objects are a set of business objects designed to give access to the Sage 50 Accounts Diary data. These objects are read-only.

Objects

Business

The following table lists all the Diary Entry Business Objects:

Object | Description | Object Type
DiaryEvent | DiaryEvent object | Business
DiaryEventLabel | DiaryEventLabel object | Business
DiaryRecurrencePattern | DiaryRecurrencePattern object | Business

DiaryEntry Business Objects have the methods below.

Method | Description
Delete | Deletes the current record and will return false if the record cannot be removed.
Load | Load can be the record based on the Primary key (Integer), or the record based on a unique key field(String).
Update | The Update method commits changes to the data files. Depending on the object being used, the method will perform certain validation checks and will return False if the data in the object is invalid.

Collection

The following table lists all the DiaryEntry Collection Objects:

Object | Description | Object Type
DiaryEvents | Collection of DiaryEvents | Collection
DiaryEventLabels | Collection of DiaryEventLabels | Collection
DiaryRecurrencePatterns | Collection of DiaryRecurrencePatterns | Collection

DiaryEntry Collection Business Objects have the method below. Note: These methods do not apply to the single objects.

Method | Description
GetEnumerator | Returns an enumerator for this object
Item | Returns an object of the specified collection type based on a specified index value.


DiaryEvent

Description

The DiaryEvent object represents a Sage 50 Accounts Diary Event within the Diary module.

Applies to

Sage 50 Accounts Standard and Professional.

Properties

Name | Description | Length | Input | Data Type
AccountContact | The contact for this DiaryEvent | 28 | Optional | String
AccountType | The type of Account | 4 | Optional | Integer
Customer | The Customer business object | Optional | Object
EndTime | The End Time Of The Event | 2 | Optional | DateTime
HasReminder | Has A Reminder Set For Event | 4 | Optional | Integer
IsAllDayEvent | Is An All Day Event | 4 | Optional | Integer
IsDeletedOccurrence | Is A Deleted Occurrence | 4 | Optional | Integer
Label | The label of the event, i.e. Phone Call | 4 | Optional | Object
Location | Location | 41 | Optional | String
NextReminderTime | Next Time A Reminder Is Set | 2 | Optional | DateTime
OccurrenceType | Type Of Occurrence | 4 | Optional | Object
OriginalEndTime | Originally Entered End Time | 2 | Optional | Date Time
OriginalStartTime | Originally Entered Start Time | 2 | Optional | Date Time
RecurrencePattern | Recurrence Pattern | 8 | Optional | Object
ReminderMinutesBeforeStart | Reminder Minutes Before Start | 4 | Optional | Integer
StartTime | Start Time | 2 | Optional | DateTime
Subject | Subject | 255 | Required | String
Supplier | The Supplier business object | Optional | Object
UniqueID | Unique ID | 4 | Auto Generated | Integer
UserName | User Name | 32 | Required | String
Methods
Method | Description
Delete | Deletes the current record and will return false if the record cannot be removed
Load | Load can be the record based on the Primary key (Integer), or the record based on a unique key field(String).
Update | The Update method commits changes to the data files. Depending on the object being used, the method will perform certain validation checks and will return False if the data in the object is invalid
Remarks

The primary key field for the diaryEvent object is the property UniqueID. This is the value that a search will be performed on when the .Load method is used i.e. DiaryEvent.Load(UniqueID as Integer).

To amend or delete an existing DiaryEvent you first have to load the DiaryEvent using the DiaryEvent load method.

Examples Using This Object

Creating a new Diary Event
Reading the last Diary Event


DiaryEvents

Description

The DiaryEvents object represents a collection of Sage 50 Accounts Diary Events within the Diary module.

Applies to

Sage 50 Accounts Standard and Professional.

Properties

Name | Description | Length | Input | Data Type
Count | Counts The Number Of Diary Events | 4 | Auto generated | Integer
Methods
Name | Description
GetEnumerator | Returns an enumerator for this object
Item | Returns an instance of the item within a collection using an indexed field as the basis for the search

Examples Using This Object

Reading the last Diary Event


DiaryEventLabel

Description

The DiaryEventLabels object represents a Sage 50 Accounts Diary Event Type within the Diary module.

Applies to

Sage 50 Accounts Standard and Professional.

Properties

Name | Description | Length | Input | Data Type
Color | Colour | 8 | Optional | Integer
Name | Name | 1 | Optional | String
ReadOnly | Read Only | 5 | Optional | Boolean
UniqueID | Unique ID | 5 | Auto generated | Integer
Methods
Method | Description
Delete | Deletes the current record and will return false if the record cannot be removed
Load | Load can be the record based on the Primary key (Integer), or the record based on a unique key field(String).
Update | The Update method commits changes to the data files. Depending on the object being used, the method will perform certain validation checks and will return False if the data in the object is invalid
Remarks

The primary key field for the DiaryEventLabel object is the property UniqueID. This is the value that a search will be performed on when the .Load method is used i.e. DiaryEventLabel.Load(UniqueID as Integer).

To amend or delete an existing DiaryEventLabel you first have to load the DiaryEventLabel using the DiaryEventLabel load method.

Examples Using This Object

Creating a new Diary Event
Reading the last Diary Event


DiaryEventLabels

Description

The DiaryEventLabels object represents a Sage 50 Accounts Diary Event Labels collection within the Diary module.

Applies to

Sage 50 Accounts Standard and Professional.

Properties

Name | Description | Length | Input | Data Type
Count | Count | 8 | Auto generated | Integer
Methods
Method | Description
GetEnumerator | Returns an enumerator for this object
Item | Returns an instance of the item within a collection using an indexed field as the basis for the search
Remarks

The DiaryEventLabels object is a collection of Diary Event Types as seen in the Diary Module of the UI.

Examples Using This Object

View DiaryEventLabels Properties using Item Method


DiaryRecurrencePatterns

Description

The DiaryRecurrencePatterns object represents a collection of Sage 50 Accounts Diary Recurrence Patterns within the Diary module.

Applies to

Sage 50 Accounts Standard and Professional.

Properties

Name | Description | Length | Input | Data Type
Count | Counts The Number Of Diary Events | 4 | Auto generated | Integer
Methods
Name | Description
GetEnumerator | Returns an enumerator for this object
Item | Returns an instance of the item within a collection using an indexed field as the basis for the search
Remarks

The DiaryRecurrencePatterns object represents a collection of Sage 50 Accounts Diary Recurrence Patterns within the Diary module.

Examples Using This Object

View DiaryRecurrencePatterns Properties using Item Method


Address Objects

DocumentAddresses Objects

Description

The DocumentAddress object represents Sage 50 Accounts Document Addresses, where different documents can be sent to different Customer or Supplier Addresses. The following screen shot shows where this is accessed via the programs UI.

Objects

Business

The following table lists all the DocumentAddress Business Objects:

Object | Description | Object Type
DocumentAddress | Documents Listed against the Customer or Supplier record | Business
DocumentType | Document Type Listed against the Customer or Supplier record | Business

DocumentAddress Business Objects have the methods below.

Method | Description
Delete | Deletes the current record and will return false if the record cannot be removed.
Load | Load can be the record based on the Primary key (Integer), or the record based on a unique key field(String).
Update | The Update method commits changes to the data files. Depending on the object being used, the method will perform certain validation checks and will return False if the data in the object is invalid.

Collection

The following table lists all the DocumentAddress Collection Objects:

Object | Description | Object Type
DocumentAddresses | Collection of Documents Listed against the Customer or Supplier record | Business
DocumentTypes | Collection of Document Type Listed against the Customer or Supplier record | Business

Document DocumentAddress Collection Business Objects have the method below. Note: These methods do not apply to the single objects.

Method | Description
Get Enumerator | Returns an enumerator for this object.
Item

Returns an instance of an item within a collection using an indexed field as the basis for the search.


DocumentAddress

Description

The DocumentAddress object represents Sage 50 Accounts Document Addresses, where different documents can be sent to different Customer or Supplier Addresses. The following screen shot shows where this is accessed via the programs UI.

Applies to

Sage 50 Accounts Standard and Professional.

Properties

Name | Description | Length | Input | Data Type
AccountRefn | Account Reference | 8 | String
AccountType | Account Type | 1 | TraderType
AddressNumber | Address Number | 4 | Integer
Customer | Customer Place Holder | 4 | Object
CustomerAddress | Customer Address | 4 | Object
DocumentType | Document Type | 4 | Object
DocumentTypeID | Document Type ID | 10 | String
Supplier | Supplier Place holder | 4 | Object
SupplierAddress | Supplier Address | 4 | Object
Methods
Method | Description
Delete | Deletes the current record and will return false if the record cannot be removed.
Load | Load can be the record based on the Primary key (Integer), or the record based on a unique key field(String)
Update | The Update method commits changes to the data files. Depending on the object being used, the method will perform certain validation checks and will return False if the data in the object is invalid.

Remarks

The primary key field for the Document address object is the property AddressNumber. This is the value that a search will be performed on when the .Load method is used i.e. DocumentAddress.Load(AddressNumber as Integer).

To amend or delete an existing Document Address you first have to load the Document Address using the Document Address load method.

Examples Using This Object

Using the Document Address Object


DocumentAddresses

Description

The DocumentAddresses object represents a collection of Sage 50 Accounts Document Addresses.

Applies to

Sage 50 Accounts Standard and Professional.

Properties

Name | Description | Length | Input | Data Type
Count | Returns the count of the collection. | 4 | Integer
Methods

Method | Description
GetEnumerator | Returns an enumerator for this object
Item | Returns an instance of the item within a collection using an indexed field as the basis for the search

Examples Using This Object

Using the Document Address Object


DocumentType

Description

The DocumentType object represents Sage 50 Accounts Document Types.

Applies to

Sage 50 Accounts Standard and Professional.

Properties

Name | Description | Length | Input | Data Type
Description | Description | 30 | Required | String
Type | Type | 1 | Optional | DocumentTypeValue
UniqueID | Unique ID | 4 | Auto generated | Integer
UsedForCustomers | Used For Customers | 1 | Optional | Boolean
UsedForSuppliers | Used For Suppliers | 1 | Optional | Boolean
Methods
Name | Description
Delete | Deletes the current record and will return false if the record cannot be removed
Load | Load can be the record based on the Primary key (Integer), or the record based on a unique key field(String)
LoadType | Loads the specified Document Type
Update | The Update method commits changes to the data files. Depending on the object being used, the method will perform certain validation checks and will return False if the data in the object is invalid

Remarks

The primary key field for the DocumentType object is the property UniqueID. This is the value that a search will be performed on when the DocumentType.Load method is used i.e. DocumentType.Load(UniqueID as Integer).

Examples Using This Object

Using the Document Address Object
View DocumentType LoadType properties


DocumentTypes

Description

The DocumentTypes object represents a collection of Sage 50 Accounts Document Types.

Applies to

Sage 50 Accounts Standard and Professional.

Properties

Name | Description | Length | Data Type
Count | Returns the count of the collection. | 4 | Integer
Methods
Name | Description
GetEnumerator | Returns an enumerator for this object
Item | Returns the DocumentType from the specified index position.

Remarks

The DocumentTypes object holds a collection of the Sage 50 Accounts Document Types.

Examples Using This Object

Using the Document Address Object


LoadType Method

Description

The LoadType method is used to load a DocumentType object using an integer.

Syntax

The Load method has the following syntax:

Object.LoadType(Reference As Object)

with the following parts:

Part | Description
Object | Applies to one of the following types: DocumentType
Reference | This is of type Object representing the Object primary key field. This is of Integer.

Return Value(s)

The method returns the following values:

Value | Description
True | The object has been loaded.
False | The object cannot be loaded.

Examples Using This Object

View DocumentType LoadType properties


DocumentLink

Description

The DocumentLink object allows developers to specify a file path against a transaction in the Transactions link.

This link can be accessed through the Sage 50 Accounts Transactions List, which contains a Ext. Link button and a Ext column. The Ext Link will only become available through the Sage 50 Accounts program if it has also been enabled on the SplitData object with the "HAS_EXTERNAL_LINK" property.

Applies to

All Sage 50 Accounts variants. This object is first introduced on Sage 50 Accounts version 23.1

Properties

Name | Description | Length | Input | Data Type
DocumentLink | Path to the file | n/a | Required | String
TransactionID | Transaction number | n/a | Required | Integer
Methods
Method | Description
Delete | Deleted the link that is being accessed
Load | Loads the specifed transaction. Takes the transaction number as its parameter
Update | Updates the link to commit the change

Examples Using This Object

Using the Document Link Object


Project Costing Objects

Financial Budget Objects

Description

The Financial Budget objects are a set of business objects designed to give access to the Sage 50 Accounts departmental budget data. These objects are read-only.

Objects

Business

The following table lists all the Financial Budget Business Objects:

Object | Description | Object Type
FinancialBudget | Financial Budget Record | Business

Financial Budget Business Objects have the methods below.

Method | Description
Load | Load can be the record based on the Primary key (Integer), or the record based on a unique key field(String).

Collection

The following table lists all the Financial Budget Collection Objects:

Object | Description | Object Type
FinancialBudgets | Collection of Financial Budget Records | Collection

Financial Collection Business Objects have the method below. Note: These methods do not apply to the single objects.

Method | Description
Item | Returns an object of the specified collection type based on a specified index value.


FinBudget

FinancialBudget

Description

The FinancialBudget object gives read only access to the departmental budgets within Sage 50 Accounts.

Applies to

Sage 50 Accounts Essentials, Standard and Professional

Properties

Name | Description | Length | Input | Data Type
Actual | Actual Expenditure | 5 | Read Only | Double
Budget | Budget Expenditure | 5 | Read Only | Double
Department | Department Object | n/a | Read Only | Object
DepartmentID | Department ID number | 4 | Read Only | Integer
NomCategory | Nominal Category | 1 | Read Only | Byte
Nominal | Nominal Object | n/a | Read Only | Object
NominalRefn | Nominal Reference | 8 | Read Only | String
Period | Period / Month | 4 | Read Only | Integer
Persisted Actual | Period / Month | 4 | Read Only | Integer
Persisted Budget | Period / Month | 4 | Read Only | Integer
Year | Year | 4 | Read Only | Integer
Methods
Method | Description | Parameters | Output
Load | The Load method is used to load the FinancialBudget object | Reference As Object | Boolean

Examples Using This Object

Example - Reading Financial Budgets


FinBudget

FinancialBudgets

Description

The FinancialBudgets object represents a collection of FinancialBudget objects in Sage 50 Accounts.

Applies to

Sage 50 Accounts Essentials, Standard and Professional

Properties

Name | Description | Length | Input | Data Type
Count | Returns the count of the collection. | 4 | Read-Only | Integer
Methods

There is one method (.Item) on this object, click here to view details.

Examples Using This Object

Example - Reading Financial Budgets


Business Object

Placeholders

Description

In future business objects will only interact with other business objects; therefore we have created what are essentially skeleton objects. These skeleton objects are used to retrieve data from tables which have no associated business object.

All skeleton objects will, over time be developed until such a time they become full business objects in their own right.

Placeholder Objects

The following table lists the Sage 50 Accounts Placeholder objects.

Object | Description | Object Type
Country | Country Code object | Placeholder
Customer | Sales Ledger object | Placeholder
Department | Department object | Placeholder
Nominal | Nominal Ledger object | Placeholder
Product | Product Ledger object | Placeholder
Supplier | Purchase Ledger object | Placeholder
TaxCode | Tax Code object | Placeholder

The Placeholder objects have the method below.

Method | Description
Load | Loads the record based on the object primary key field.


Country

Description

The Country object represents the Sage 50 Accounts data Country Code on a Project Costing Project.

Applies to

Sage 50 Accounts Standard and Professional.

Properties

Name | Description | Length | Data Type
Code | Two character country code | 2 | String
CombinedCode | Two character country code | 2 | String
ConvertedCode | Two character country code | 2 | String
EUMember | EUMember | 1 | Boolean
Name | Name of Country | 30 | String
Method

The Country object has one method (Load). Click here to view the method.

Remarks

The primary key field for the country object is the property Code. This is the value that a search will be performed on when the .Load method is used i.e. Country.Load(Code as String).

Examples Using This Object

Create a new Project Record


Customer

Description

The Customer object represents the Sage 50 Accounts data sales ledger account on a Project Costing Project and ProjectTransaction.

Applies to

Sage 50 Accounts Standard and Professional.

Properties

Name | Description | Length | Data Type
Reference | Account Reference | 8 | String
PaymentDueFromOption | Payment Due From Option | 8 | Int32
Method

The Customer object has one method (Load). Click here to view the method.

Remarks

The primary key field for the Customer object is the Reference property. This is the value that a search will be performed on when the .Load method is used i.e. Customer.Load(Reference as String).

Examples Using This Object

Create a new Project Record


Department

Description

The Department object represents the Sage 50 Accounts department on a Project Costing ProjectTransaction.

Applies to

Sage 50 Accounts Standard and Professional.

Properties

Name | Description | Length | Data Type
DepartmentID | Department unique identifier | 4 | Integer
Name | Department name | 50 | String
Reference | Department Reference | 8 | String
Method

The Department object has one method (Load). Click here to view the method.

Remarks

From Sage 50 Accounts 2007 onwards the reference property has been added to the Department object. The Reference is user defined and is the information shown in Financials and Activity screens. When populating budget information via SDO it is the Department_ID that needs to be passed

The primary key field for the Department object is the property Department_ID. This is the value that a search will be performed on when the .Load method is used i.e. Department.Load(Department_ID as Integer).

Examples Using this Object

Example - Reading and Editing Department Names


Nominal

Description

The Nominal object represents the Sage 50 Accounts nominal on a Project Costing ProjectTransaction.

Applies to

Sage 50 Accounts Standard and Professional.

Properties

Name | Description | Length | Data Type
REFERENCE | Nominal code reference | 8 | String
Method

The Nominal object has one method (Load). Click here to view the method.

Remarks

The primary key field for the Nominal object is the property Reference. This is the value that a search will be performed on when the .Load method is used i.e. Nominal.Load(Reference as String).

Examples Using this Object

Creating a New Charity Fund


Customer

Product

Description

The Product object represents a Sage 50 Accounts Product within Products.

Applies to

Sage 50 Accounts Standard and Professional.

Properties

Name | Description | Length | Data Type
Reference | Account Reference | 8 | String
Method

The Product object has one method (Load). Click here to view the method.

Remarks

The primary key field for the Product object is the Reference property. This is the value that a search will be performed on when the .Load method is used i.e. Product.Load(Reference as String).

Examples Using This Object

Allocate Stock


Supplier

Description

The Supplier object represents the Sage 50 Accounts supplier on a Project Costing ProjectTransaction.

Applies to

Sage 50 Accounts Standard and Professional.

Properties

Name | Description | Length | Data Type
Reference | Supplier reference | 8 | String
PaymentDueFromOption | Payment due from option | 8 | Int32
Method

The Supplier object has one method (Load). Click here to view the method.

Remarks

The primary key field for the Supplier object is the Reference property. This is the value that a search will be performed on when the .Load method is used i.e. Supplier.Load(Reference as String).

Examples Using this Object

Example - Edit CIS Details In Visual Basic .NET


TaxCode

Description

The TaxCode object represents the Sage 50 Accounts data tax code on a Project Costing ProjectTransaction.

Applies to

Sage 50 Accounts Standard and Professional.

Properties

Name | Description | Length | Data Type
TaxCodeID | Unique reference for the tax code | 4 | Integer
Rate | Tax rate | Double
Name | The Tax Code i.e. T1 | 3 | String
Method

The TaxCode object has one method (Load). Click here to view the method.

Remarks

The primary field for the TaxCode object is the property TaxCodeID. This is the value that a search will be performed on when the .Load method is used i.e. TaxCode.Load(TaxCodeID as Integer).

Examples Using this Object

View Supplier Address Properties
Create a new Supplier Address


Project Costing Objects

Description

The Project Costing objects are a set of business objects designed to give access to the Sage 50 Accounts Project Costing module. Values are set on each object by assigning a value to the object's properties, NOT by using a fields collection.

The SplitData, StockTran, SOPItem and InvoiceItem objects have new properties to allow them to be linked to a Project Costing Project. Click here to see the SplitData properties. Click here to see the SOPItem, InvoiceItem and StockTran properties.

Objects

Load

The following table lists the Project Costing Load object:

Object | Description | Object Type
ProjectTransaction | Project Costing Transaction | Load

Project Costing Load object has the method below.

Method | Description
Load | The Load method is used to load a record using an integer as the basis for the search on the primary key field.

Posting

The following table lists the Project Costing Post object:

Object | Description | Object Type
ProjectOnlyTransaction | Project Costing Cost Only Transaction | Posting

Project Costing Post object has the methods below.

Method | Description
Post | The Post method is used to post a new project cost only transaction to the database.

Business

The following table lists all the Project Costing Business objects:

Object | Description | Object Type
Project | Project Costing Record | Business
ProjectCostCode | Project Costing Cost Code | Business
ProjectResource | Project Costing Resource | Business
ProjectStatus | Project Costing Status | Business

Project Costing Business objects have the methods below.

Method | Description
Delete | Deletes the current record and will return false if the record cannot be removed.
Load | Load can be the record based on the Primary key (Integer), or the record based on a unique key field(String).
Update | The Update method commits changes to the data files. Depending on the object being used, the method will perform certain validation checks and will return False if the data in the object is invalid.

Collection

The following table lists all the Project Costing Collection objects:

Object | Description | Object Type
Projects | Collection of Project Costing Records | Collection
ProjectCostCodes | Collection of Project Costing Cost Codes | Collection
ProjectResources | Collection of Project Costing Resources | Collection
ProjectStatuses | Collection of Project Costing Statuses | Collection
ProjectTransactions | Collection of Project Costing Transactions | Collection

Project Costing collection objects have the method below. Note: These methods do not apply to the single objects.

Method | Description
Item | Returns an object of the specified collection type based on a specified index value.


Project

Description

The Project object represents a Sage 50 Accounts Project within Project Costing.

Applies to

Sage 50 Accounts Standard and Professional.

Properties

Name | Description | Length | Input | Data Type
Address1 | Site Address Line 1 | 60 | String
Address2 | Site Address Line 2 | 60 | Object
Address3 | Site Address Line 3 | 60 | Optional | String
Address4 | Site Address Line 4 | 60 | Optional | String
Address5 | Site Address Line 5 | 60 | Optional | String
Analysis1 | Project Analysis 1 | 30 | Optional | String
Analysis2 | Project Analysis 2 | 30 | Optional | String
Analysis3 | Project Analysis 3 | 30 | Optional | String
BilledNet | Billed Net | 8 | ReadOnly | Double
BilledVAT | Billed VAT | 8 | ReadOnly | Double
CommittedCost | Committed Cost | 8 | Optional | Double
Contact | Site Contact Name | 30 | Optional | String
Country | Country Object | Required | Object
Customer | Customer object | Optional | Object
Description | Project Description | 255 | Optional | String
EMail | Project email address | 255 | Optional | String
EndDate | Date the project ends | 2 | Required | Date
Fax | Fax Number | 30 | Optional | String
LastBilledDate | Last Billed Date | 2 | ReadOnly | Date
LastCostDate | Last Cost Date | 2 | ReadOnly | Date
Name | Project Name | 255 | Required | String
OrderNumber | Project Order Number | 30 | Optional | String
OutstandingToBill | Outstanding to Bill | 8 | ReadOnly | Double
PriceQuoted | Project Price Quoted | 8 | Optional | Double
ProfitToDate | Profit to Date | 8 | ReadOnly | Double
ProjectID | Unique identifier for the Project | 4 | AutoGenerated | Integer
Reference | Project Reference | 12 | Required | String
StartDate | Date the project starts | 2 | Required | Date
Status | ProjectStatus Object | Required | Object
Telehpone | Telephone Number (misspelling of Property name is correct) | 30 | Optional | String
TotalBilled | Total Billed | 8 | ReadOnly | Double
TotalBudget | Total Budget for the Project | 8 | Optional | Double
TotalCost | Total Cost for the Project | 8 | ReadOnly | Double
Transactions | Returns a ProjectTransactions object which is a collection of Transaction objects that belong to the Project. | ReadOnly | Object
Variance | The TotalBudget less the TotalCost | 8 | ReadOnly | Double
Methods

Click here to view the methods.

Remarks

The primary key field for the project object is the property ProjectID. This is the value that a search will be performed on when the .Load method is used i.e. Project.Load(ProjectID as Integer). Alternatively .Load of a Project record can be performed based on the unique field Reference i.e. Project.Load(Reference as String).

To amend or delete an existing project you first have to load the project using the project's load method.

Examples Using This Object

Create a new Project Record
Amend a Project Record
Delete a Project Record
Post a Project Charge
Post a Project Credit
Post a Project Stock Issue
Post a Project Stock Return
Post a Project Supplier Invoice
Post a Project Supplier Credit
Post a Project Bank Payment
Post a Project Product Invoice
Post a Project Service Invoice
Post a Project Sales Order
Marking a Project as Complete
View a Project Transactions
Display Project Details In A Combobox


Projects

Description

The Projects object represents a collection of Projects within Sage 50 Accounts Project Costing.

Applies to

Sage 50 Accounts Standard and Professional.

Properties

Name | Description | Length | Input | Data Type
Count | The number of projects in the collection | 4 | ReadOnly | Integer
Method

Click here to view the method.

Examples Using This Object

Display Project Details In A Combobox


ProjectOnlyTransaction

Description

The ProjectOnlyTransaction object represents a Sage 50 Accounts Project Costing Only Transaction within Project Costing. This can be either a Project Charge (sdoCD) or a Project Credit (sdoCC)

Project Only Transactions enable you to record costs incurred when work is carried out on a project. For example, you might post a Project Only Transaction for labour costs, using the number of hours’ work and the hourly rate shown on timesheets submitted by a contractor.

You can also use Project Only Transaction to enter costs that do not affect your accounts or stock, such as costs involving non-stock or service items. Alternatively, you can use Project Only Transactions to record adjustments or corrections to other costs for the project.

Note: If you attempt to Post a ProjectOnlyTransaction to a project that has a Status that is set to not allow postings then an error is thrown (sdoInvalidProjectStatus - Code 37).

Applies to

Sage 50 Accounts Standard and Professional.

Properties

Name | Description | Length | Input | Data Type
CostCode | ProjectCostCode Object | Required | Object
Date | Transaction Date | 2 | Required | Date
Details | Transaction Details | 60 | Optional | String
Project | Project Object | Required | Object
Quantity | Transaction Quantity | 8 | Required | Double
Rate | Transaction Rate | 8 | Required | Double
Reference | Transaction Reference | 8 | Optional | String
Resource | ProjectResource Object | Optional | Object
TransactionID | Unique Identifier for the Project Transaction | 4 | Autogenerated | Integer
Type | Transaction Type | 4 | Required | Integer
Methods

Click here to view the methods.

Examples Using This Object

Post a Project Charge
Create a new project record
Create a new project costcode
Create a new project resource
Reading the chart of accounts
Creating a New Prepayment Record
Creating a New Charity Fund
Display Project Details In A Combobox
Post a Project Credit


ProjectResource

Description

The ProjectResource object represents a Sage 50 Accounts Resource within Project Costing.

Applies to

Sage 50 Accounts Standard and Professional.

Properties

Name | Description | Length | Input | Data Type
CostCode | Resource CostCode | 4 | Optional | Integer
Name | Resource Name | 30 | Optional | String
Rate | Resource Charge Rate | 8 | Required | Double
Reference | Resource Reference | 8 | Required | String
ResourceID | Unique identifier for the Resource | 4 | AutoGenerated | Integer
Unit | Resource Unit of Measure | 30 | Optional | String
Methods

Click here to view the methods.

Remarks

The primary key field for the resource object is the property ResourceID. This is the value that a search will be performed on when the .Load method is used i.e. ProjectResource.Load(ResourceID as Integer). Alternatively .Load of a ProjectResource record can be performed based on the unique field Reference i.e. ProjectResource.Load(Reference as String).

To amend or delete an existing resource you first have to load the resource using the resource's load method.

Examples Using This Object

Create a new Project Resource
Amend a Project Resource
Delete a Project Resource
Post a Project Charge
Post a Project Credit
Create a new project record
Create a new project costcode
Reading the chart of accounts
Creating a New Prepayment Record
Creating a New Charity Fund
Display Project Details In A Combobox


ProjectResources

Description

The ProjectResources object represents a collection of Resource objects within Sage 50 Accounts Project Costing.

Applies to

Sage 50 Accounts Standard and Professional.

Properties

Name | Description | Length | Input | Data Type
Count | The number of resources in the collection | 4 | ReadOnly | Integer
Method

Click here to view the method.

Examples Using this Object

There are currently no examples that make use of this object.


ProjectResource

ProjectStatus

Description

The ProjectStatus object represents a Sage 50 Accounts Status within a Project Costing Project.

Applies to

Sage 50 Accounts Standard and Professional.

Properties

Name | Description | Length | Input | Data Type
Default | Is Default Flag | 2 | Optional - see Remarks | Boolean
Deletion | Allow Deletion Flag | 2 | Depends - see Remarks | Boolean
Name | Status Description | 30 | Optional | String
Postings | Allow Postings Flag | 2 | Depends - see Remarks | Boolean
Reference | Status Code | 15 | Required | String
StatusID | Unique identifier for the Status | 4 | AutoGenerated | Integer
Methods

Click here to view the methods.

Remarks

The primary key field for the status object is the property StatusID. This is the value that a search will be performed on when the .Load method is used i.e. ProjectStatus.Load(StatusID as Integer). Alternatively .Load of a ProjectStstus record can be performed based on the unique field Reference i.e. ProjectStatus.Load(Reference as String).

To amend or delete an existing status you first have to load the status using the status's load method.

The Deletion and Postings properties should not both be set, you cannot have a Status that allows for both Deletion and Postings. You can have either one set or none set.

If a new ProjectStatus is added and the Default property is set to True then the ProjectStatus that was previously set as Default will have to be set to False. You cannot have more than one ProjectStatus with the Default property set.

Examples Using This Object

Create a new Project Record
Create a new Project Status
Amend a Project Status
Delete a Project Status
Marking a Project as Complete
Display Project Statuses In A Combobox


ProjectStatuses

Description

The ProjectStatuses object represents a collection of Status objects within Sage 50 Accounts Project Costing.

Applies to

Sage 50 Accounts Standard and Professional.

Properties

Name | Description | Length | Input | Data Type
Count | The number of status objects in the collection | 4 | ReadOnly | Integer
Method

Click here to view the method.

Examples Using This Object

Marking a Project Record as Complete
Display Project Statuses In A Combobox


ProjectTransaction

Description

The ProjectTransaction object represents a Sage 50 Accounts Transaction within Project Costing. NOTE: This object is read-only.

Applies to

Sage 50 Accounts Standard and Professional.

Properties

Name | Description | Length | Data Type
Amount | Net Amount | 8 | Double
AuditTrailID | Audit Trail Split ID or RecordNumber | 4 | Integer
CostCode | ProjectCostCode Object | Object
Customer | Customer Object - only returned on sdoSI and sdoSC ProjectTransaction types | Object
Date | Transaction Date | 2 | Date
Department | Department Object - only returned on sdoSI, sdoSC, sdoPI, sdoPC and sdoBP ProjectTransaction types (will return null for department 0) | Object
Details | Transaction Details | 60 | String
ExtReference | Transaction Extra Reference | 30 | String
Nominal | Nominal Object - only returned on sdoSI, sdoSC, sdoPI, sdoPC and sdoBP ProjectTransaction types | Object
Project | Project Object | Object
Quantity | Transaction Quantity | 8 | Double
Rate | Transaction Rate | 8 | Double
Reference | Transaction Reference | 8 | String
Resource | ProjectResource Object only returned on sdoCC, sdoCD ProjectTransaction types if it was set | Object
Supplier | Supplier Object - only returned on sdoPI and sdoPC ProjectTransaction types | Object
Tax | Tax Amount | 8 | Double
TaxCode | TaxCode Object - only returned on sdoSI, sdoSC, sdoPI, sdoPC and sdoBP ProjectTransaction types | Object
TransactionID | Unique Identifier for the Project Transaction | 4 | Integer
Type | Transaction Type | 4 | Integer
Methods

The ProjectTransaction object has one method ( load ).

Remarks

The TransactionID is the primary key field that is used in the .Load method i.e. ProjectTransaction.Load(TransactionID as Integer).

Examples Using This Object

View a Projects Transactions


ProjectTransactions

Description

The ProjectTransactions object represents a collection of Transaction objects within Sage 50 Accounts Project Costing.

Applies to

Sage 50 Accounts Standard and Professional.

Properties

Name | Description | Length | Input | Data Type
Count | The number of transaction objects in the collection | 4 | ReadOnly | Integer
Method

Click here to view the method.

Examples Using This Object

View a Project Transactions


CostCode Property

Description

The CostCode property returns an object of type ProjectCostCode for use with Project Costing within Sage 50 Accounts.

Syntax

The CostCode property has the following syntax:

Object.CostCode

with the following parts:

Part | Description
Object | Applies to the following objects: ProjectOnlyTransaction, ProjectTransaction, SplitData, StockAllocation and StockTran.
CostCode | Returns the ProjectCostCode object of the current record.

Examples Using This Property

Create a new Project CostCode
Amend a Project CostCode
Delete a Project CostCode
Post a Project Charge
Post a Project Credit
Post a Project Stock Issue
Post a Project Stock Return
Post a Project Supplier Invoice
Post a Project Supplier Credit
Post a Project Bank Payment
View a Project Transactions


Country Property

Description

The Country property returns an object of type Country for use with Project Costing within Sage 50 Accounts.

Syntax

The Coutry property has the following syntax:

Object.Country

with the following parts:

Part | Description
Object | Applies to the following object: Project.
Country | Returns the Country object of the current record.

Examples Using This Method

Create a new Project Record


Customer Property

Description

The Customer property returns an object of type Customer for use with Project Costing within Sage 50 Accounts.

Syntax

The Project property has the following syntax:

Object.Customer

with the following parts:

Part | Description
Object | Applies to the following objects: Project and ProjectTransaction.
Customer | Returns the Customer object of the current record.

Examples Using This Object

Create a new Project Record


Department Property

Description

The Department property returns an object of type Department for use with Project Costing, CIS and Financial Forecasting within Sage 50 Accounts.

Syntax

The Department property has the following syntax:

Object.Department

with the following parts:

Part | Description
Object | Applies to the following object: ProjectTransaction.
Department | Returns the Department object of the current record.

There are currently no examples that use this property.


Nominal Property

Description

The Nominal property returns an object of type Nominal for use with various Sage 50 Accounts business objects.

Syntax

The Nominal property has the following syntax:

Object.Nominal

with the following parts:

Part | Description
Object | Applies to the following objects: ProjectTransaction, FinancialBudget
Nominal | Returns the Nominal object of the current record.

There are currently no examples that use this property.


Project Property

Description

The Project property returns an object of type Project for use with Project Costing within Sage 50 Accounts.

Syntax

The Project property has the following syntax:

Object.Project

with the following parts:

Part | Description
Object | Applies to the following objects: InvoiceItem, ProjectOnlyTransaction, ProjectTransaction, SOPItem, SplitData, StockAllocation and StockTran.
Project | Returns the Project object of the current record.

Examples Using This Method

Post a Project Charge
Post a Project Credit
Post a Project Stock Issue
Post a Project Stock Return
Post a Project Supplier Invoice
Post a Project Supplier Credit
Post a Project Bank Payment
Post a Project Product Invoice
Post a Project Service Invoice
Post a Project Sales Order
Marking a Project as Complete
Allocate Stock


Resource Property

Description

The Resource property returns an object of type ProjectResource for use with Project Costing within Sage 50 Accounts.

Syntax

The Resource property has the following syntax:

Object.Resource

with the following parts:

Part | Description
Object | Applies to the following objects: ProjectOnlyTransaction, ProjectTransaction.
Resource | Returns the ProjectResource object of the current record.

Examples Using This Method

Post a Project Charge
Post a Project Credit


Status Property

Description

The Status property returns an object of type ProjectStatus for use with Project Costing within Sage 50 Accounts.

Syntax

The Status property has the following syntax:

Object.Status

with the following parts:

Part | Description
Object | Applies to the following object: Project.
Status | Returns the ProjectStatus object of the current record.

Examples Using This Method

Create a new Project Record
Marking a Project as Complete


TaxCode Property

Description

The TaxCode property returns an object of type TaxCode for use with Project Costing within Sage 50 Accounts.

Syntax

The TaxCode property has the following syntax:

Object.TaxCode

with the following parts:

Part | Description
Object | Applies to the following object: ProjectTransaction.
TaxCode | Returns the TaxCode object of the current record.

There are currently no examples that use this property.


Transactions Property

Description

The Transactions property returns an object of type ProjectTransactions for use with Project Costing within Sage 50 Accounts.

Syntax

The Transactions property has the following syntax:

Object.Transactions

with the following parts:

Part | Description
Object | Applies to the following object: Project.
Transactions | Returns the ProjectTransactions object of the current record.

Examples Using This Property

View a Project Transactions


Post Method

Description

The Post method is used to post a new project cost only transaction to the database. A boolean value is returned as to whether the post has been successful or not.

Syntax

The Post method has the following syntax:

Object.Post

with the following parts:

Part | Description
Object | Applies to the following object: ProjectOnlyTransaction.

Return Value(s)

The method returns the following values:

Value | Description
True | The object has been saved.
False | The object cannot be saved.

Examples Using This Method

Post a Project Charge
Post a Project Credit


Object Description

Stock Objects

Description

The Stock objects are a set of business objects designed to give access to the Sage 50 Accounts Product Allocations module. Values are set on each object by assigning a value to the object's properties, NOT by using a fields collection.

Objects

Business

The following table lists all the Stock Business objects:

Object | Description | Object Type
StockAllocation | StockAllocation Record | Business

Stock Business objects have the methods below.

Method | Description
Issue | Issues the current record and todo.
Load | Load can be the record based on the Primary key (Integer), or the record based on a unique key field (String).
Update | The Update method commits changes to the data files. Depending on the object being used, the method will perform certain validation checks and will return False if the data in the object is invalid.

Collection

The following table lists all the Stock Collection objects:

Object | Description | Object Type
StockAllocations | Collection of Project Costing Records

Stock collection objects have the method below. Note: These methods do not apply to the single objects.

Method | Description
Item | Returns an object of the specified collection type based on a specified index value.


StockAllocation

Description

The StockAllocation object represents a Sage 50 Accounts Allocation within Products.

Applies to

Sage 50 Accounts Standard and Professional.

Properties

Name | Description | Length | Input | Data Type
AllocationID | Transaction Identifier | 4 | Required | Integer
CostCode | CostCode Object | Optional | Object
CostPrice | Cost Price | 8 | Optional | Double
Date | Transaction Date | 2 | Required | Date
Details | Transaction Details | 60 | Optional | String
Product | Product Object | Required | Object
Project | Project Object | Optional | Object
QtyAllocated | Quantity Allocated | 8 | Required | Double
QtyIssued | Quantity Issued | 8 | Required | Double
ReadOnly | Is Read Only | 4 | Optional | Integer
Reference | Transaction Reference | 30 | Optional | String
Methods

Click here to view the methods.

Remarks

The primary key field for the StockAllocation object is the property AllocationID. This is the value that a search will be performed on when the .Load method is used i.e. StockAllocation.Load(AllocationID as Integer). Alternatively .Load of a StockAllocation record can be performed based on the unique field Reference i.e. StockAllocation.Load(Reference as String).

To amend or remove an existing StockAllocation you first have to load the allocation using the StockAllocations's load method.

Examples Using This Object

Allocate Stock


StockAllocations

Description

The StockAllocations object represents a collection of Product Allocations within Sage 50 Accounts.

Applies to

Sage 50 Accounts Standard and Professional.

Properties

Name | Description | Length | Input | Data Type
Count | The number of Allocations in the collection | 4 | ReadOnly | Integer
Method

Click here to view the method.

Examples Using this Object

There are currently no examples that make use of this object.


CostCode Property

Product Property

Description

The Product property returns an object of type Product.

Syntax

The Product property has the following syntax:

Object.Product

with the following parts:

Part | Description
Object | Applies to the following objects: StockAllocation.
Product | Returns the Product object of the current record.

Examples Using This Property

Allocate Stock


CreateCountry Method

CreateProduct Method

Description

The CreateProduct method is used to create an object of the type Product. This is the method used to create an object that represents the Sage 50 Accounts Product.

Syntax

The CreateProduct method has the following syntax:

Object.CreateProduct

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Value

The CreateProduct method returns the following value:

Return Value | Description
Product | An object of type SageDataObjectN.Product (N denotes SDO version e.g. 180)

Remarks

You should always destroy any objects you create by setting them to Nothing.

Examples Using This Method

Allocate Stock


CreateCountry Method

CreateStockAllocation Method

Description

The CreateStockAllocation method is used to create an object of the type StockAllocation. This is the method used to create an object that represents the Sage 50 Accounts Product Allocation.

Syntax

The CreateStockAllocation method has the following syntax:

Object.CreateStockAllocation

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Value

The CreateStockAllocation method returns the following value:

Return Value | Description
StockAllocation | An object of type SageDataObjectN.StockAllocation (N denotes SDO version e.g. 120)

Remarks

You should always destroy any objects you create by setting them to Nothing.

Examples Using This Method

Allocate Stock


CreateProjects Method

CreateStockAllocations Method

Description

The CreateStockAllocations method is used to create an object of the specified type. This is the primary method used to create a business object that represent the Sage 50 Accounts Product Allocations. This object is a collection of StockAllocation objects.

Syntax

The CreateStockAllocations method has the following syntax:

Object.CreateStockAllocations

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Values

The CreateStockAllocations method returns the following object:

Return Value | Description
StockAllocations | An object of type StockAllocations. This is a collection of StockAllocation objects.

Examples Using This Method

Allocate Stock


Update Method

Issue Method

Description

The Issue method is used to issue the stock that has been allocated. A boolean value is returned as to whether the issue has been successful or not.

NOTE: When using the issue method on the StockAllocation object, you do NOT need to call Update as well.

Syntax

The Issue method has the following syntax:

Object.Issue(dfQtyToIssue As Double, dIssueDate as Date)

with the following parts:

Part | Description
Object | Applies to the following objects: StockAllocation.
dfQtyToIssue | This is the quantity that is to be issued from the allocated amount.
dIssueDate | This is the date to be used for the issued quantity.

Return Value(s)

The method returns the following values:

Value | Description
True | The stock has been issued.
False | The stock cannot be issued.

Examples Using This Method

Issue Allocation


DisputedReason

Description

The DisputedReason object represents a Sage 50 Accounts Disputed Reason.

Applies to

Accounts Plus and Professional.

Properties

Name | Description | Length | Input | Data Type
DisputeReasonID | Unique identifier for the DisputedReason | 4 | AutoGenerated | Integer
Name | Name of the Disputed Reason e.g. 'Goods not delivered' | 60 | Optional | String
Methods

The DisputedReason object has the methods below:

Name | Data Type
Load | Load can be the record based on the Primary key (Integer), or the record based on a unique key field(String).
Update | The Update method commits changes to the data files. Depending on the object being used, the method will perform certain validation checks and will return False if the data in the object is invalid.

Remarks

The primary key field for the DisputedReason object is the property DisputedReasonID. This is the value that a search will be performed on when the .Load method is used i.e. DisputedReason.Load(DisputedReasonID as Integer).

Examples Using this Object

There are currently no examples that make use of this object.

Reading Disputed Reasons


Objects by Type

Data Objects by Type

The table below lists the data object by type.

Note: Where both a business object and data object exist to access the same Sage 50 Accounts data, we strongly recommend using the business object. Over time, business objects will be developed to replace all existing data objects. Whilst there are no immediate plans to end of life Sage Data Objects for Sage 50, using business objects where possible will ease the transition from data objects in the future.

For a list of which objects relate to Sage 50 Accounts Essentials, Standard and Professional, click here.

SDOFile

 SDOIndexFile SDOIspPost SDOLinkedFile SDOLinkedSubFile SDOPosting SDORecord SDORecordLinked
AccessData AssetIndex InvoicePost InvoiceItem BankHeaderData StockPost AssetRecord BankRecord
AccountStatusData BankIndex POPPost POPItem HeaderData TransactionPost BankRemittanceRecord InvoiceRecord
AccrualData BankRemittanceIndex SOPPost SOPItem SplitData CompanyDeliveryRecord NominalRecord
AssetCategory CompanyDeliveryIndex StockTran ContactAccountIdxRecord POPRecord
AssetData ContactAccountIndex UsageData ContactDateIdxRecord PurchaseRecord
BankData ContactDateIndex CountryCodeRecord SalesRecord
BankRemittanceData CountryCodeIndex PriceRecord SOPRecord
BankWWWData InvoiceIndex PriceListRecord StockRecord
BillData NominalIndex PurchaseDeliveryRecord
Category POPIndex RemittanceRecord
ChartData PriceIndex SalesDeliveryRecord
CompanyDeliveryData PriceListIndex ToDoRecord
ContactData PurchaseDeliveryIndex
ControlData PurchaseIndex
CountryCodeData RemittanceIndex
CourierWWWData SalesDeliveryIndex
CreditChargeData SalesIndex
CreditWWWData SOPIndex
CurrencyData StockIndex
DepartmentData ToDoIndex
InvoiceData
MiscWWWData
NominalData
POPData
PrepayData
PriceData
PriceListData
PurchaseDeliveryData
PurchaseData
QueueData
RecurringData
RemittanceData
SalesDeliveryData
SalesData
SetupData
SOPData
StockCategory
StockData
ToDoData


Objects List

All Objects

The following table lists all the SDO objects. For a list of which objects relate to which version (Essentials, Standard and Professional) of Sage 50 Accounts, click here.

Object | Description | Core Object
AccessData | Access Rights Data - ACCESS.DTA | SDOFile
AccountStatusData | Account Status Data - ACCSTAT.DTA | SDOFile
AccrualData | Accruals Data - ACCRUAL.DTA | SDOFile
AgedBalances | Customer and Supplier aged balances calculator
AssetCategory | Fixed Assets Category Data - ASTCAT.DTA | SDOFile
AssetData | Fixed Assets Data - ASSETS.DTA | SDOFile
AssetIndex | Fixed Assets Index - ASTINDEX.DTA | SDOIndexFile
AssetRecord | Fixed Asset Register | SDORecord
BankData | Bank Data - BANK.DTA | SDOFile
BankHeaderData | Bank Data - BANK.DTA | SDOLinkedSubFile
BankIndex | Bank Index - BNKINDEX.DTA | SDOIndexFile
BankRecord | Bank Account Records | SDORecordLinked
BankRemittanceData | Remittance Line Data - BNKREMDA.DTA | SDOFile
BankRemittanceIndex | Remittance Line Index - BNKREMIX.DTA | SDOIndexFile
BankRemittanceRecord | Remittances | SDORecord
BankWWWData | Bank WWW Data - BANKWWW.DTA | SDOFile
BillData | Bills Data - BILLS.DTA | SDOFile
Category | Category Data - CATEGORY.DTA | SDOFile
ChartData | Chart of Accounts Data - x.COA | SDOFile
CharityFund | Charity Funds - FUND.DTA
CharityFundType | Charity Fund Types - FUNDTYPE.DTA
CISSetting | The CISSetting object represents the CIS tab within Company Preferences. | SDOBusinessObject
CISSubcontractor | The CISSubcontractor object represents the CIS tab of a Subcontractor Record. | SDOBusinessObject
CISSubcontractors | The CISSubcontractors object represents the CIS tab of a Subcontractor Record. | SDOBusinessObject
CISSubcontractorLegacy | CIS Subcontractor Legacy | SDOBusinessObject
CISSubcontractorLegacys | CIS Subcontractor Legacys | SDOBusinessObject
CISSubcontractorTaxHistory | CIS Subcontractor Tax History | SDOBusinessObject
CISSubcontractorTaxHistorys | CIS Subcontractor Tax Historys | SDOBusinessObject
COAS | Chart of Accounts | SDOBusinessObject
Companies | Collection of Company Data Sets
Company | Individual Data Set
CompanyAddress | Company Address | SDOBusinessObject
CompanyAddresses | Company Addresses | SDOBusinessObject
CompanyDeliveryData | Company Delivery Address Data - COMDA.DTA | SDOFile
CompanyDeliveryIndex | Company Delivery Address Index - COMDAIDX.DTA | SDOIndexFile
CompanyDeliveryRecord | Company Delivery Addresses | SDORecord
ContactAccountIdxRecord | Contact Records (by Account Index) | SDORecord
ContactAccountIndex | Contact Records Index - CONTINDA.DTA | SDOIndexFile
ContactData | ContactData - CONTACT.DTA | SDOFile
ContactDateIdxRecord | Contact Records (by Date Index) | SDORecord
ContactDateIndex | Contact Date Index - CONTINDD.DTA | SDOIndexFile
ContactHistory | Contact History - CNTHISDA.DTA | SDOBusinessObject
ContactHistorys | Contact Historys - CNTHISDA.DTA | SDOBusinessObject
ControlData | Control Data - ACCOUNT.DTA | SDOFile
Country | Country Code on a Project | SDOBusinessObject
CountryCodeData | Country Codes - COUNTRY.DTA | SDOFile
CountryCodeIndex | Country Codes Index - CTRYIDX.DAT | SDOIndexFile
CountryCodeRecord | Country Code Records | SDORecord
CourierWWWData | Courier Resources Data - COURWWW.DTA | SDOFile
CreditChargeData | Credit Charge Data - FINRATES.DTA | SDOFile
CreditWWWData | Credit Resources Data - CREDWWW.DTA | SDOFile
CurrencyData | Currency Data - CURRENCY.DTA | SDOFile
Customer | Project Costing Customer | SDOBusinessObject
CustomerAddress | Customer Address | SDOBusinessObject
CustomerAddresses | Customer Addresses | SDOBusinessObject
Department | Project Costing Transaction Department | SDOBusinessObject
DepartmentData | Department Data - DEPARTM.DTA | SDOFile
DiaryEvent | Diary Event | SDOBusinessObject
DiaryEvents | Diary Events | SDOBusinessObject
DiaryEventLabel | Diary Event Label | SDOBusinessObject
DiaryEventLabels | Diary Event Labels | SDOBusinessObject
DiaryRecurrencePattern | Diary Reccurence Pattern | SDOBusinessObject
DiaryRecurrencePatterns | Diary Recurrence Patterns | SDOBusinessObject
DisputedReason | Disputed Reason - DISPREAS.DTA | SDOBusinessObject
DocumentAddress | Document Address | SDOBusinessObject
DocumentAddresses | Document Addresses | SDOBusinessObject
DocumentLink | Document Link | SDOBusinessObject
DocumentType | Document Type | SDOBusinessObject
DocumentTypes | Document Types | SDOBusinessObject
ESubmissionSetting | ESubmission Settings of the CIS tab within Company Preferences | SDOBusinessObject
FinancialBudget | Financial Budget | SDOBusinessObject
FinancialBudgets | Financial Budgets | SDOBusinessObject
GDNData | Goods Delivery Notes Data- GDNDATA.DTA | SDOFile
GDNIndex | Goods Delivery Notes Index - GDNINDEX.DTA | SDOIndexFile
GDNRecord | GDN Records | SDORecordLinked
HeaderData | Transaction Headers - HEADER.DTA | SDOLinkedSubFile
InvoiceData | Invoice Headers Data - INVOICE.DTA | SDOFile
InvoiceIndex | Invoice Record Index - INVINDEX.DTA | SDOIndexFile
InvoiceItem | Invoice Item Lines - INVITEM.DTA | SDOLinkedFile
InvoicePost | Create Stock/Service Invoice | SDOIspPost
InvoiceRecord | Invoice Records | SDORecordLinked
MiscWWWData | Miscellaneous Resources Data - MISCWWW.DTA | SDOFile
Nominal | Project Costing Transaction Nominal | SDOBusinessObject
NominalData | Nominal Ledger Data - NOMINAL.DTA | SDOFile
NominalIndex | Nominal Ledger Index - NOMINDEX.DTA | SDOIndexFile
NominalRecord | Nominal Ledger Records | SDORecordLinked
POPData | Purchase Orders Header Data - PUORDER.DTA | SDOFile
POPIndex | Purchase Order Index - PUOINDEX.DTA | SDOIndexFile
POPItem | Purchase Order Line Items - PUOITEM.DTA | SDOLinkedFile
POPPost | Create Purchase Order | SDOIspPost
POPRecord | Purchase Order Records | SDORecordLinked
PrepayData | Prepayments Data - PREPAY.DTA | SDOFile
PriceData | Price Data - PRICE.DTA | SDOFile
PriceIndex | Price Index - PRICEIDX.DTA | SDOIndexFile
PriceRecord | Product Price List Records | SDORecord
PriceListData | Price List Data - PRLST.DTA | SDOFile
PriceListIndex | Price List Index - PRLSTIDX.DTA | SDOIndexFile
PriceListRecord | Customer Price List Records | SDORecord
Pricing | Pricing Calculator | SDOBusinessObject
Product | Used when loading a product for recording stock allocations | SDOBusinessObject
Project | Project | SDOBusinessObject
Projects | Projects | SDOBusinessObject
ProjectCostCode | Project Cost Code | SDOBusinessObject
ProjectCostCodes | Project Cost Codes | SDOBusinessObject
ProjectResource | Project Resource | SDOBusinessObject
ProjectResources | Project Resources | SDOBusinessObject
ProjectStatus | Project Status | SDOBusinessObject
ProjectStatuses | Project Statuses | SDOBusinessObject
ProjectTransaction | Project Transaction | SDOBusinessObject
ProjectTransactions | Project Transactions | SDOBusinessObject
PurchaseDeliveryData | Purchase Delivery Address Data - PURDA.DTA | SDOFile
PurchaseDeliveryIndex | Purchase Delivery Address Index - PURDAIDX.DTA | SDOIndexFile
PurchaseDeliveryRecord | Suppliers Delivery Addresses | SDORecord
PurchaseData | Suppliers Data - PURCHASE.DTA | SDOFile
PurchaseIndex | Suppliers Index - PURINDEX.DTA | SDOIndexFile
PurchaseRecord | Supplier Account Records | SDORecordLinked
QueueData | Current Users - QUEUE.DTA | SDOFile
RecurringData | Recurring Entries Data - RECUR.DTA | SDOFile
RemittanceData | Cheque Remittance Line Data - REMIT.DTA | SDOFile
RemittanceIndex | Cheque Remittance Line Index - REMITIDX.DTA | SDOIndexFile
RemittanceRecord | Cheque Remittances | SDORecord
SalesDeliveryData | Sales Delivery Data - SALDA.DTA | SDOFile
SalesDeliveryIndex | Sales Delivery Index - SALDAIDX.DTA | SDOIndexFile
SalesDeliveryRecord | Customers Delivery Addresses | SDORecord
SalesData | Customers Data - SALES.DTA | SDOFile
SalesIndex | Customers Index - SALINDEX.DTA | SDOIndexFile
SalesRecord | Customer Account Records | SDORecordLinked
SetupData | Setup Data - SETUP.DTA | SDOFile
SOPData | Sales Orders Header Data - SAORDER.DTA | SDOFile
SOPIndex | Sales Order Index - SAOINDEX.DTA | SDOIndexFile
SOPItem | Sales Order Line Items - SAOITEM.DTA | SDOLinkedFile
SOPPost | Create Sales Order | SDOIspPost
SOPRecord | Sales Order Records | SDORecordLinked
SplitData | Transaction Splits - SPLIT.DTA | SDOLinkedSubFile
StockAllocation | Stock Allocation | SDOBusinessObject
StockAllocations | Stock Allocations | SDOBusinessObject
StockCategory | Stock Category Data - STKCAT.DTA | SDOFile
StockData | Stock Data - STOCK.DTA | SDOFile
StockIndex | Stock Index - STKINDEX.DTA | SDOIndexFile
StockPost | Create Stock Transaction | SDOPosting
StockRecord | Stock Records | SDORecordLinked
StockTran | Stock Transactions - STKTRANS.DTA | SDOLinkedFile
Supplier | Project Costing Transaction Supplier | SDOBusinessObject
SupplierAddress | Supplier Delivery Address | SDOBusinessObject
SupplierAddresses | Supplier Delivery Addresses | SDOBusinessObject
TaxCode | Tax Code | SDOBusinessObject
ToDoData | Task Manager Data - TODO.DTA | SDOFile
ToDoIndex | Task Manager Index - TODOIDX.DTA | SDOIndexFile
ToDoRecord | Task Manager | SDORecord
TransactionPost | Create Audit Trail Transaction | SDOPosting
UsageData | Transaction Usages - USAGE.DTA | SDOLinkedFile


AccessData

Description

The AccessData object gives access to the Access Rights (ACCESS.DTA) table.

This object holds the information that you see in Sage 50 Accounts when you go into the Settings | Access Rights... menu option in Sage 50 Accounts. Using this object enables you to allow access to modules in your application in the same way as Sage 50 Accounts does.

Note: The object is read only, you cannot create or amend a user's details using it. If you attempt to call the Update method of the object an exception, sdoReadOnlyAccess, will be thrown.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
BANK | Bank | 1 | Optional | Byte
BANK_ACTIVITY | Bank - Activity | 1 | Optional | Byte
BANK_BALANCE | Bank - Balances | 1 | Optional | Byte
BANK_BATCH | Bank - Batch | 1 | Optional | Byte
BANK_CASHFLOW | Bank - Cashflow | 1 | Optional | Byte
BANK_CASHREGISTER | Bank - Cash Register | 1 | Optional | Byte
BANK_CHEQUES | Bank - Cheques | 1 | Optional | Byte
BANK_CUST_RECEIPT | Bank - Customer Receipt | 1 | Optional | Byte
BANK_CUST_REFUND | Bank - Customer Refund | 1 | Optional | Byte
BANK_DEPOSITCASH | Bank - Deposit Cash | 1 | Optional | Byte
BANK_DONOTRECEIPT | Bank - Donor Receipt | 1 | Optional | Byte
BANK_DOWNLOAD_RECEIPT | Bank - Download Receipts | 1 | Optional | Byte
BANK_EPAY | Bank - ePayments | 1 | Optional | Byte
BANK_ERECONCILE | Bank - eReconcile | 1 | Optional | Byte
BANK_PAYMENT | Bank - Bank Payment | 1 | Optional | Byte
BANK_RECEIPT | Bank - Receipt | 1 | Optional | Byte
BANK_RECONCILE | Bank - Reconciliation | 1 | Optional | Byte
BANK_RECORD | Bank - Record | 1 | Optional | Byte
BANK_RECUR | Bank - Recurring Entries | 1 | Optional | Byte
BANK_REMITTANCE | Bank - Remittance | 1 | Optional | Byte
BANK_REPORT | Bank - Reports | 1 | Optional | Byte
BANK_REVALUATION | Bank - Revaluation | 1 | Optional | Byte
BANK_STATEMENT | Bank - Statements | 1 | Optional | Byte
BANK_SUPP_PAYMENT | Bank - Supplier Payment | 1 | Optional | Byte
BANK_SUPP_REFUND | Bank - Supplier Refund | 1 | Optional | Byte
BANK_TRANSFER | Bank - Transfer | 1 | Optional | Byte
CONNECTED_SERVICES | Connected Services | 1 | Optional | Byte
CONNECTED_SERVICES_INVOICE_PAYMENTS | Connected Services - Invoice Payments | 1 | Optional | Byte
CONNECTED_SERVICES_INVOICEFINANCE | Connected Services - Satago | 1 | Optional | Byte
CONNECTED_SERVICES_SAGE_NETWORK | Connected Services - Sage Network settings | 1 | Optional | Byte
COMPANY | Company | 1 | Optional | Byte
COMPANY_ACTIVITY | Company - Activity | 1 | Optional | Byte
COMPANY_COA | Company - Chart of Accounts | 1 | Optional | Byte
COMPANY_FINREPORTS | Company - Financial Reports | 1 | Optional | Byte
COMPANY_FUNDS | Company - Funds | 1 | Optional | Byte
COMPANY_INTRASTAT | Company - Prepare Intrastat Return | 1 | Optional | Byte
COMPANY_JOURNAL | Company - Journal | 1 | Optional | Byte
COMPANY_NOMREPORTS | Company - Nominal Reports | 1 | Optional | Byte
COMPANY_PREPAUDIT | Company - Prepare for Audit | 1 | Optional | Byte
COMPANY_QUICKRATIO | Company - QuickRatio | 1 | Optional | Byte
CUST_ACTIVITY | Customer - Activity | 1 | Optional | Byte
CUST_BANKDETAILS | Customer - Bank Details | 1 | Optional | Byte
CUST_AGED | Customer - Aged Balance | 1 | Optional | Byte
CUST_CHARGED | Customer - Charges | 1 | Optional | Byte
CUST_CHASEDEBT | Customer - Chase debt | 1 | Optional | Byte
CUST_COMMUNICATIONS | Customer - Communications | 1 | Optional | Byte
CUST_CONTRA_ENTRIES | Customer - Contra Entries | 1 | Optional | Byte
CUST_CREDIT | Customer - Batch Credits | 1 | Optional | Byte
CUST_DISPUTE | Customer - Batch Disputes | 1 | Optional | Byte
CUST_INVOICE | Customer - Batch Invoices | 1 | Optional | Byte
CUST_LABEL | Customer - Labels | 1 | Optional | Byte
CUST_LETTER | Customer - Letters | 1 | Optional | Byte
CUST_PAYMENT | Customer - Receive Payment | 1 | Optional | Byte
CUST_PDF | Customer - Secure PDF | 1 | Optional | Byte
CUST_POSTINVOICE | Customer - Post Invoice | 1 | Optional | Byte
CUST_PRICELIST | Customer - Price Lists | 1 | Optional | Byte
CUST_QUOTATIONS | Customer - Quotations | 1 | Optional | Byte
CUST_RECORD | Customer - Record | 1 | Optional | Byte
CUST_REFUNDS | Customer - Refunds | 1 | Optional | Byte
CUST_REPORT | Customer - Reports | 1 | Optional | Byte
CUST_STATEMENT | Customer - Statements | 1 | Optional | Byte
CUST_WRITEOFF | Customer - WriteOff/Refund | 1 | Optional | Byte
CUSTOMERS | Customers | 1 | Optional | Byte
DEPARTMENTS | Departments | 1 | Optional | Byte
DEPARTMENTS_ACTIVITY | Departments - Activity | 1 | Optional | Byte
DEPARTMENTS_EDIT | Departments - Edit | 1 | Optional | Byte
DEPARTMENTS_REPORTS | Departments - Reports | 1 | Optional | Byte
DEF_CALLRATE | Default Call Rate | 8 | Optional | Double
DIARY | Diary | 1 | Optional | Byte
DIARY_COMPLETE | Diary - Complete event | 1 | Optional | Byte
DIARY_IMP_EXP | Diary - Import/Export | 1 | Optional | Byte
DIARY_RECORD | Diary - Record | 1 | Optional | Byte
DIARY_VIEW_EVENTS | Diary - Only view and edit own events | 1 | Optional | Byte
EXCEL_INTEGRATION | Sage Integrated Reporting | 1 | Optional | Byte
EXCLUDE_DOCTOR | Exclude Deleted Transactions | 2 | Optional | Small Integer
FILE_BACKUP | File Menu - Backup | 1 | Optional | Byte
FILE_DEL_COMP | File Menu - Delete Company | 1 | Optional | Byte
FILE_IMPORT | File Menu - Import | 1 | Optional | Byte
FILE_MAIL | File Menu - Send Mail | 1 | Optional | Byte
FILE_MAINT | File Menu - Maintenance | 1 | Optional | Byte
FILE_MENU | File Menu | 1 | Optional | Byte
FILE_NEW_COMP | File Menu - New Company | 1 | Optional | Byte
FILE_NEW_REPORT | File Menu - New Report | 1 | Optional | Byte
FILE_OPEN_ARCHIVE | File Menu - Open Archive Data | 1 | Optional | Byte
FILE_OPEN_COMP | File Menu - Open Company | 1 | Optional | Byte
FILE_OPEN_DEMO | File Menu - Open Demo Data | 1 | Optional | Byte
FILE_OPEN_REPORT | File Menu - Open Report | 1 | Optional | Byte
FILE_RESTORE | File Menu - Restore | 1 | Optional | Byte
FILE_SENDTOEXCEL | File Menu - Send to Excel | 1 | Optional | Byte
FILE_SENDTOOUTLOOK | File Menu - Send to Outlook | 1 | Optional | Byte
FILE_SENDTOWORDNEW | File Menu - Send to Word (New) | 1 | Optional | Byte
FILE_SENDTOWORDOPEN | File Menu - Send to Word (Open) | 1 | Optional | Byte
FILE_SENDTOWORDRUN | File Menu - Send to Word (Run) | 1 | Optional | Byte
FIN_AUDIT | Financials - Audit Trail | 1 | Optional | Byte
FIN_BALANCE | Financials - Balance Sheet | 1 | Optional | Byte
FIN_BUDGET | Financials - Budget Analysis | 1 | Optional | Byte
FIN_PANDL | Financials - Profit and Loss | 1 | Optional | Byte
FIN_PRIOR | Financials - Prior Year Analysis | 1 | Optional | Byte
FIN_RATIO | Financials - Ratio | 1 | Optional | Byte
FIN_REPORT | Financials - Reports | 1 | Optional | Byte
FIN_TRIAL | Financials - Trial Balance | 1 | Optional | Byte
FIN_VAT | Financials - Vat Return | 1 | Optional | Byte
FIN_VERIFY | Financials Verify | 1 | Optional | Byte
FINANCIALS | Financials | 1 | Optional | Byte
FIX_DISPOSAL | Fixed Assets - Asset Valuation | 1 | Optional | Byte
FIX_RECORD | Fixed Assets - Record | 1 | Optional | Byte
FIX_REPORT | Fixed Assets - Reports | 1 | Optional | Byte
FIX_VAL | Fixed Assets - Asset Valuation | 1 | Optional | Byte
FIXED_ASSETS | Fixed Assets | 1 | Optional | Byte
FUNDS | Charitable funds | 1 | Optional | Byte
FUNDS_ACTIVITY | Charitable funds - Activity | 1 | Optional | Byte
FUNDS_GASDS | Charitable funds - GASDS Settings | 1 | Optional | Byte
FUNDS_GIFD_AID | Charitable funds - Gift aid declaration | 1 | Optional | Byte
FUNDS_NOMCODES | Charitable funds - Assign nominal codes | 1 | Optional | Byte
FUNDS_RECORD | Charitable funds - Record | 1 | Optional | Byte
FUNDS_REPORTS | Charitable funds - Reports | 1 | Optional | Byte
FUNDS_TRANSFER | Charitable funds - Fund Transfer | 1 | Optional | Byte
GROUP_HISTORY | Group History | 2 | Optional | Small Integer
HELP | Help | 1 | Optional | Byte
HELP_CUSTOMIZE | Help - Customise your company | 1 | Optional | Byte
HELP_UPDATESETTINGS | Help - Software Update Settings | 1 | Optional | Byte
INTERNET | Internet | 1 | Optional | Byte
INV_EDIT | Invoicing - Edit | 1 | Optional | Byte
INV_INVOICELIST | Invoicing - Invoice Order List | 1 | Optional | Byte
INV_LABELS | Invoicing - Print Labels | 1 | Optional | Byte
INV_PRINT | Invoicing - Print Invoices | 1 | Optional | Byte
INV_PROD_CRD | Invoicing - Product Credit Note | 1 | Optional | Byte
INV_PROD_INV | Invoicing - Product Invoice | 1 | Optional | Byte
INV_PROFIT | Invoicing - Profit | 1 | Optional | Byte
INV_QUOTATIONS | Invoicing - Quotations | 1 | Optional | Byte
INV_RECURRING | Invoicing - Recurring | 1 | Optional | Byte
INV_REPORT | Invoicing - Reports | 1 | Optional | Byte
INV_SERV_CRD | Invoicing - Service Credit Note | 1 | Optional | Byte
INV_SERV_INV | Invoicing - Service Invoice | 1 | Optional | Byte
INV_TMAIL | Invoicing - Transaction e-mail | 1 | Optional | Byte
INV_UPDATE | Invoicing - Update Ledgers | 1 | Optional | Byte
INVOICING | Product Invoice | 1 | Optional | Byte
NAME | Logon Name | 32 | Required | String
NOM_ACCRUAL | Nominal - Accruals | 1 | Optional | Byte
NOM_ACTIVITY | Nominal - Activity | 1 | Optional | Byte
NOM_BUDGET | Nominal - Budgets | 1 | Optional | Byte
NOM_COA | Nominal - Chart of Accounts | 1 | Optional | Byte
NOM_JOURNAL | Nominal - New Journal | 1 | Optional | Byte
NOM_PREPAY | Nominal - Prepayments | 1 | Optional | Byte
NOM_QUICKRATIO | Nominal - Ratio | 1 | Optional | Byte
NOM_RECORD | Nominal - Record | 1 | Optional | Byte
NOM_REPORT | Nominal - Reports | 1 | Optional | Byte
NOM_REVERSAL | Nominal - Reversal | 1 | Optional | Byte
NOMINAL | Nominal | 1 | Optional | Byte
POP | Purchase Orders | 1 | Optional | Byte
POP_AMEND | POP - Amend Deliveries | 1 | Optional | Byte
POP_DELIVER | POP - Deliver | 1 | Optional | Byte
POP_ENTRY | POP - Purchase Order Entry | 1 | Optional | Byte
POP_GOODSREC | POP - Goods Received | 1 | Optional | Byte
POP_INTRASTAT | POP - Intrastat return | 1 | Optional | Byte
POP_LABELS | POP - Print Labels | 1 | Optional | Byte
POP_ORDER | POP - Order | 1 | Optional | Byte
POP_POPLIST | POP - Purchase Order List | 1 | Optional | Byte
POP_PRINT | POP - Print | 1 | Optional | Byte
POP_RECURRING | POP - Recurring | 1 | Optional | Byte
POP_REPORT | POP - Reports | 1 | Optional | Byte
POP_TMAIL | POP - Transaction Email | 1 | Optional | Byte
POP_UPDATE | POP - Update Ledgers | 1 | Optional | Byte
PROD_ACTIVITY | Products - Activity | 1 | Optional | Byte
PROD_ADJ_IN | Products - Adjustments In | 1 | Optional | Byte
PROD_ADJ_OUT | Products - Adjustments Out | 1 | Optional | Byte
PROD_ALLOCATIONS | Products - Allocations | 1 | Optional | Byte
PROD_CHECKBOM | Products - Check BOM | 1 | Optional | Byte
PROD_LABELS | Products - Labels | 1 | Optional | Byte
PROD_PRICELIST | Products - Price Lists | 1 | Optional | Byte
PROD_PRODUCTLIST | Products - Product List | 1 | Optional | Byte
PROD_RECORD | Products - Record | 1 | Optional | Byte
PROD_REPORT | Products - Reports | 1 | Optional | Byte
PROD_RETURNS | Products - Stock Returns | 1 | Optional | Byte
PROD_SHORTFALL | Products - Shortfall | 1 | Optional | Byte
PROD_STKTAKE | Products - Stock Take | 1 | Optional | Byte
PROD_TRANSFER | Products - Transfer | 1 | Optional | Byte
PRODUCTS | Stock Record | 1 | Optional | Byte
PROJECT_ACTIVITY | Project Costing - Activity | 1 | Optional | Byte
PROJECT_ANALYSIS | Project Costing - View Analysis | 1 | Optional | Byte
PROJECT_COSTING | Project Costing | 1 | Optional | Byte
PROJECT_COSTS | Project Costing - Costs | 1 | Optional | Byte
PROJECT_CREDITS | Project Costing - Credits | 1 | Optional | Byte
PROJECT_DEBITS | Project Costing - Charges | 1 | Optional | Byte
PROJECT_ENTERBUDGETS | Project Costing - Enter Budgets | 1 | Optional | Byte
PROJECT_PROJECTLIST | Project Costing - Project List | 1 | Optional | Byte
PROJECT_RECORD | Project Costing - Record | 1 | Optional | Byte
PROJECT_REPORTS | Project Costing - Reports | 1 | Optional | Byte
PROJECT_RESOURCES | Project Costing - Resources | 1 | Optional | Byte
QUOTATIONS | Quotations | 1 | Optional | Byte
QUOTE_ALLOC_STOCk | Quotations - Allocate stock | 1 | Optional | Byte
QUOTE_AMEND_ALLOC | Quotations - Amend allocations | 1 | Optional | Byte
QUOTE_LOST | Quotations - Mark as lost | 1 | Optional | Byte
QUOTE_OPEN | Quotations - Mark as open | 1 | Optional | Byte
QUOTE_PRINT/MAIL | Quotations - Print/Email | 1 | Optional | Byte
QUOTE_PROFIT | Quotations - View profit on quote | 1 | Optional | Byte
QUOTE_RECORD | Quotations - Record | 1 | Optional | Byte
QUOTE_WON | Quotations - Mark as won | 1 | Optional | Byte
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
REP_GEN | Report Generator | 1 | Optional | Byte
SETT_ACCOUNTSTATUS | Settings Menu - Accounts Status | 1 | Optional | Byte
SETT_ASSET_CAT | Settings Menu - Asset Categories | 1 | Optional | Byte
SETT_BANK_DEF | Settings Menu - Bank Defaults | 1 | Optional | Byte
SETT_COMP_PREF | Settings Menu - Company Preferences | 1 | Optional | Byte
SETT_CONFIG_EDIT | Settings Menu - Configuration Editor | 1 | Optional | Byte
SETT_CONTROL | Settings Menu - Control Accounts | 1 | Optional | Byte
SETT_COUNTRIES | Settings Menu - Countries | 1 | Optional | Byte
SETT_CURRENCY | Settings Menu - Currency | 1 | Optional | Byte
SETT_CUST_DEF | Settings Menu - Customer Defaults | 1 | Optional | Byte
SETT_DELIVERY | Settings Menu - Delivery Address | 1 | Optional | Byte
SETT_DEPARTMENTS | Settings Menu - Departments | 1 | Optional | Byte
SETT_EMAIL_DEF | Settings Menu - Email defaults | 1 | Optional | Byte
SETT_FIN_YEAR | Settings Menu - Financial Year | 1 | Optional | Byte
SETT_INV_DEF | Settings Menu - Invoice Defaults | 1 | Optional | Byte
SETT_INV_PAY | Settings Menu - Invoice Payments | 1 | Optional | Byte
SETT_LOCK_DATE | Settings Menu - Invoice Defaults | 1 | Optional | Byte
SETT_ONEDRIVE_DOC | Settings Menu - OneDrive Document Settings | 1 | Optional | Byte
SETT_PROD_DEF | Settings Menu - Product Defaults | 1 | Optional | Byte
SETT_PRODUCT_CAT | Settings Menu - Product Categories | 1 | Optional | Byte
SETT_PROG_DATE | Settings Menu - Change Program Date | 1 | Optional | Byte
SETT_PROJECT_DEF | Settings Menu - Project Defaults | 1 | Optional | Byte
SETT_REMOTE | Settings Menu - Remote Data Access Settings | 1 | Optional | Byte
SETT_SUPP_DEF | Settings Menu - Supplier Defaults | 1 | Optional | Byte
SETT_TAXCODES | Settings Menu - Tax Codes | 1 | Optional | Byte
SETT_WWW | Settings Menu - WWW Resources | 1 | Optional | Byte
SETTINGS_MENU | Settings Menu | 1 | Optional | Byte
SOFTWAREUPDATES | Software Updates | 1 | Optional | Byte
SOFTWAREUPDATES_UPDATESETTINGS | Software Updates - Software Update Settings | 1 | Optional | Byte
SOP | Sales Orders | 1 | Optional | Byte
SOP_ALLOCATE | SOP - Allocate | 1 | Optional | Byte
SOP_AMEND | SOP - Amend Despatches | 1 | Optional | Byte
SOP_DESPATCH | SOP - Despatch | 1 | Optional | Byte
SOP_ENTRY | SOP - Sales Order Entry | 1 | Optional | Byte
SOP_GDN | SOP - Goods Delivered | 1 | Optional | Byte
SOP_INTRASTAT | SOP - Intrastat return | 1 | Optional | Byte
SOP_LABELS | SOP - Print Labels | 1 | Optional | Byte
SOP_PRINT | SOP - Print | 1 | Optional | Byte
SOP_PROFIT | SOP - Profit | 1 | Optional | Byte
SOP_QUOTATIONS | SOP - Quotations | 1 | Optional | Byte
SOP_RECURRING | SOP - Recurring | 1 | Optional | Byte
SOP_REPORT | SOP - Reports | 1 | Optional | Byte
SOP_SHORTFALL | SOP - Shortfall | 1 | Optional | Byte
SOP_SOPLIST | SOP - Sales Order List | 1 | Optional | Byte
SOP_TMAIL | SOP - Transaction eMail | 1 | Optional | Byte
SUPP_ACTIVITY | Supplier - Activity | 1 | Optional | Byte
SUPP_AGED | Supplier - Aged Balance | 1 | Optional | Byte
SUPP_BANKREMIT | Supplier - Bank Remittance | 1 | Optional | Byte
SUPP_BANK_DETAILS | Supplier - Bank Details | 1 | Optional | Byte
SUPP_CHEQUELIST | Supplier - Cheque List | 1 | Optional | Byte
SUPP_CIS_LETTERS | Supplier - CIS letters | 1 | Optional | Byte
SUPP_CIS_REPORTS | Supplier - CIS reports | 1 | Optional | Byte
SUPP_CIS_RETURN | Supplier - CIS return | 1 | Optional | Byte
SUPP_CIS_STATEMENTS | Supplier - CIS statements | 1 | Optional | Byte
SUPP_CIS_VERIFY | Supplier - Verify Sub Contractors | 1 | Optional | Byte
SUPP_COMMUNICATIONS | Supplier - Communications | 1 | Optional | Byte
SUPP_CONTRA_ENTRIES | Supplier - Contra entries | 1 | Optional | Byte
SUPP_CREDIT | Supplier - Batch Credits | 1 | Optional | Byte
SUPP_DISPUTE | Supplier - Batch Disputes | 1 | Optional | Byte
SUPP_INVOICE | Supplier - Batch Invoices | 1 | Optional | Byte
SUPP_LABEL | Supplier - Labels | 1 | Optional | Byte
SUPP_LETTER | Supplier - Letters | 1 | Optional | Byte
SUPP_LETTER | Supplier - Letters | 1 | Optional | Byte
SUPP_MANAGE_PAYMENT | Supplier - Manage payment view | 1 | Optional | Byte
SUPP_PAYMENT | Supplier - Make Payment | 1 | Optional | Byte
SUPP_PDF | Supplier - Secure PDF | 1 | Optional | Byte
SUPP_PRICELIST | Supplier - Price Lists | 1 | Optional | Byte
SUPP_RECORD | Supplier - Record | 1 | Optional | Byte
SUPP_REFUND | Supplier - Refunds | 1 | Optional | Byte
SUPP_REPORT | Supplier - Reports | 1 | Optional | Byte
SUPP_SUBCONTRACTORS | Supplier - Subcontractors | 1 | Optional | Byte
SUPP_WRITEOFF | Supplier - WriteOff/Refund | 1 | Optional | Byte
SUPPLIERS | Suppliers | 1 | Optional | Byte
TOOLS_CUSTOMIZE | Tools Manu - Customise your company | 1 | Optional | Byte
TOOLS_CONTRA | Tools Menu - Contra Entries | 1 | Optional | Byte
TOOLS_EPAPER | Tools Menu -Transaction email | 1 | Optional | Byte
TOOLS_END_ARCHIVE | Tools -> Period end - Archive company | 1 | Optional | Byte
TOOLS_END_AUDIT | Tools -> Period End Menu - Clear Audit Trail | 1 | Optional | Byte
TOOLS_END_CONS | Tools -> Period End Menu - Consolidation | 1 | Optional | Byte
TOOLS_END_MENU | Tools End Menu | 1 | Optional | Byte
TOOLS_END_MONTH | Tools -> Period End Menu - Month End | 1 | Optional | Byte
TOOLS_END_STOCK | Tools -> Period End Menu - Clear Stock | 1 | Optional | Byte
TOOLS_END_YEAR | Tools -> Period End Menu - Year End | 1 | Optional | Byte
TOOLS_GLOBAL | Tools Menu - Global Changes | 1 | Optional | Byte
TOOLS_MENU | Tools Menu | 1 | Optional | Byte
TOOLS_NETWORK | Tools Menu - Network setup | 1 | Optional | Byte
TOOLS_OPENING_BAL | Tools Menu - Opening balances | 1 | Optional | Byte
TOOLS_OPTIONS | Tools Menu - Options | 1 | Optional | Byte
TOOLS_UPDATE | Tools Menu - Update Program | 1 | Optional | Byte
TRANS_CHECK_AUDIT | Transactions - Check for audit queries | 1 | Optional | Byte
TRANS_EDIT_DELETE | Transactions - Edit/Delete | 1 | Optional | Byte
TRANS_REPORTS | Transactions - Reports | 1 | Optional | Byte
TRANS_VERIF_REPORTS | Transactions - Verification Reports | 1 | Optional | Byte
TRANSACTIONS | Transactions | 1 | Optional | Byte
UPDATE_ACTIVITY_POSTING | Update Activities on Posting | 2 | Optional | Small Integer
UPDATE_AGED_MODIFY | Update Aged on Modify | 2 | Optional | Small Integer
UPDATE_AGED_POSTING | Update Aged on Posting | 2 | Optional | Small Integer
UPDATE_BALANCE_MODIFY | Update Balances on Modify | 2 | Optional | Small Integer
UPDATE_BALANCE_POSTING | Update Balances on Posting | 2 | Optional | Small Integer
UPDATE_LAZY_ADD | Update Lazy Lists on Add | 2 | Optional | Small Integer
UPDATE_LAZY_MODIFY | Update Lazy Lists on Modify | 2 | Optional | Small Integer
UPDATE_LAZY_POSTING | Update Lazy Lists on Posting | 2 | Optional | Small Integer
UPDATE_LEDGER_ADD | Update Ledgers on Add | 2 | Optional | Small Integer
UPDATE_LEDGER_MODIFY | Update Ledgers on Modify | 2 | Optional | Small Integer
UPDATE_LEDGER_POSTING | Update Ledgers on Posting | 2 | Optional | Small Integer
VAT | VAT | 1 | Not Required | Byte
VAT_ECSALES | VAT - EC Sales List | 1 | Not Required | Byte
VAT_MANUALADJUSTMENTS | VAT - Manual Adjustments | 1 | Not Required | Byte
VAT_PAYMENT | VAT - Payment | 1 | Not Required | Byte
VAT_REPORTS | VAT - Reports | 1 | Not Required | Byte
VAT_RETURN | VAT - VAT Return | 1 | Not Required | Byte
VAT_REVERSECHARGELIST | VAT - Reverse Charge List | 1 | Not Required | Byte
VAT_RTD | VAT - VAT RTD | 1 | Not Required | Byte
VAT_SCALECHARGE | VAT - Scale Charges | 1 | Not Required | Byte
VAT_SUBMISSIONS | VAT - Submissions | 1 | Not Required | Byte
VAT_TAX_QUERIES | VAT - Check for tax queries | 1 | Not Required | Byte
VAT_TRANSFER | VAT - Transfer | 1 | Not Required | Byte
VAT_VALUES | VAT - Check for VAT values | 1 | Not Required | Byte
VAT_VERIF_REPORT | VAT - Verification reports | 1 | Not Required | Byte
VAT_VIEW | VAT - View | 1 | Not Required | Byte
WALL_BITMAP | Wallpaper Bitmap | 259 | Optional | String
WALL_POS | Wallpaper Position | 1 | Optional | Byte
WALL_SHOW | Wallpaper Display | 1 | Optional | Byte
WIZARDS | Wizards | 1 | Optional | Byte

Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Reading a User's Access Rights
� Sage (UK) Ltd Click here to send feedback on this article.


AccountStatusData

Description

The AccountStatusData object gives access to the Account Status (ACCSTAT.DTA) table. This table is fixed at 100 records, 0-99, you cannot add new records, only amend existing ones.

This object holds the information you see when you go into the Settings | Configuration... menu and choose the Account Status tab.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ON_HOLD | Account On Hold | 1 | Optional | Byte
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
STATUS | Account Status | 60 | Optional | String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Reading Account Status Data


AccrualData

Description

The AccrualData object gives access to the Accruals (ACCRUAL.DTA) table.

This object holds the information you see when you choose the Accruals option within the Nominal module.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
AMOUNT | Value | 8 | Required | Double
DEPT_NUMBER | Department Number | 2 | Optional | Small Integer
LAST_POSTED | Date Last Posted | 2 | Optional | Date
MONTHS_POSTED | Months Posted | 2 | Optional | Small Integer
MONTHS_TO_POST | Months to Post | 2 | Optional | Small Integer
NAME | Name | 60 | Optional | String
NOMINAL_CODE_1 | Expense Account Nominal Code | 8 | Required | String
NOMINAL_CODE_2 | Control Account Nominal Code | 8 | Required | String
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Creating a New Accrual Record


AgedBalances

Description

The AgedBalances object provides a simple interface to determine the aged balance values (and periods) for a customer or supplier.

Applies To

Sage 50 Accounts Essentials, Standard and Professional

Fields Collection

The object has no fields collection.

Methods

The object has the following methods:

Methods | Description | Parameter
Calculate | Calculates the aged balances.
GetAgedPeriodStart | Returns the aged period start as an Integer e.g. oAgedBalances.GetPeriodStart(1) will return the first period start. | Integer
GetCurrentBalance | Returns the current period aged balance as a Double e.g. oAgedBalances.GetCurrentBalance will return the current period aged balance.
GetFutureBalance | Returns the future period aged balance as a Double e.g. oAgedBalances.GetFutureBalance will return the future period aged balance.
GetOlderAgedPeriod | Returns the aged older period start as an Integer e.g. oAgedBalances.GetOlderAgedPeriod will return the older period start.
GetOlderBalance | Returns the older period balance as a Double e.g. oAgedBalances.GetOlderBalance will return the older period balance.
GetTotalBalance | Returns the total balance as a Double e.g. oAgedBalances.GetCurrentBalance will return the total balance.
Item | Returns the period balance as a Double e.g. oAgedBalances.Item(1) will return the balance for period 1 | Integer
Reset | Resets any criteria set to calculate the aged balances
SetAgedBalanceDate | Set the date you wish to use to calculate the aged balances e.g. oAgedBalances.SetAgedBalanceDate(CDate(Now)) | Date
SetAgedMode | Set the ageing type. This can be: sdoAgeByCalendarMonth - Ages by Calendar Month, sdoAgeByPeriod - Aged By Periods, sdoAgeByDay - Aged By Periods and first day of the month following the transaction date. e.g. oAgedBalances.SetAgedMode(SageDataObject120.TransactionAgeingType.sdoAgeByPeriod) | TransactionAgeingType
SetAgedPeriodStart | Set the aged period start values e.g. oAgedBalances.SetAgedPeriodStart(1, 30) sets the aged period start for period 1 to 30 days | Integer, Integer
SetIncludeFuture | Set whether you want to include transactions that are dated after the aged balance date in the total balance. 0 - do not include, 1 - include e.g. oAgedBalances.SetIncludeFuture(1). | Integer
SetIncludePaymentDate | Set the date you wish to use to include payments up to. e.g. oAgedBalances.SetIncludePaymentDate(CDate(Now)) | Date
SetOlderAgedPeriod | Set the older aged period start value e.g. oAgedBalances.SetolderAgedPeriod(120) sets the older aged period to 120 days | Integer

Properties

The AgedBalances object has the following property:

Property | Description
Count | Returns the number of aged balance periods (not including older) e.g. 3.

Examples using this object:

View Customer Aged Balances
View Customer Aged Periods
View Supplier Aged Balances
View Supplier Aged Periods


AssetCategory

Description

The AssetCategory object gives access to the Fixed Asset Categories (ASTCAT.DTA) table. This table is fixed at 99 records, 1-99, you cannot add new records, only amend existing ones.

This object holds the information you see when you go into the Settings | Configuration... menu and choose the Fixed Assets tab.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
NAME | Category Name | 60 | Optional | String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Reading Asset Category Data


AssetData

Description

The AssetData object gives access to the Fixed Assets (ASSETS.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ASSET_CAT | Category Number | 2 | Optional | Small Integer
ASSET_REF | Fixed Asset Reference | 8 | Required | String
BAL_SHEET_NOM_CODE | Balance Sheet Nominal Code | 8 | Required | String
COST_PRICE | Cost Price | 8 | Optional | Double
DEP_LAST | Amount of Last Depreciation | 8 | Optional | Double
DEP_METHOD_CODE | Depreciation Method Code | 2 | Optional | Small Integer
DEP_RATE | Depreciation Rate | 8 | Optional | Double
DEP_TO_DATE | Amount Depreciated to Date | 8 | Optional | Double
DEPT_NUMBER | Department Number | 2 | Optional | Small Integer
DETAILS_1 | Details 1 | 60 | Optional | String
DETAILS_2 | Details 2 | 60 | Optional | String
DETAILS_3 | Details 3 | 60 | Optional | String
EMPLOYEE | Employee | 15 | Optional | String
NET_BOOK | Net Book Value | 8 | Optional | Double
NEXT_ASSET | 4 | Optional | Integer
POST_DATE | 2 | Optional | Date
PREV_ASSET | 4 | Optional | Integer
PROFIT_LOSS_NOM_CODE | Profit and Loss Nominal Code | 8 | Required | String
PURCHASE_DATE | Date of Purchase | 2 | Optional | Date
PURCHASE_REF | Purchase Reference Number | 8 | Optional | String
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
SERIAL_NUMBER | Serial Number | 60 | Optional | String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Calculate total Straight Line depreciation


AssetIndex

Description

The AssetIndex object gives access to the Fixed Assets index (ASTINDEX.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Asset Reference | 8 | Required | String
RECORD_NUMBER | Record Number | 4 | Required | Integer
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Creating a New Fixed Asset Record


AssetRecord

Description

The AssetRecord object gives access to the Fixed Assets (ASSETS.DTA) table and the Fixed Assets index (ASTINDEX.DTA) table. As an SDORecord object, it encapsulates both the data and index files.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ASSET_CAT | Category Number | 2 | Optional | Small Integer
ASSET_REF | Fixed Asset Reference | 8 | Required | String
BAL_SHEET_NOM_CODE | Balance Sheet Nominal Code | 8 | Required | String
COST_PRICE | Cost Price | 8 | Optional | Double
DEP_LAST | Amount of Last Depreciation | 8 | Optional | Double
DEP_METHOD_CODE | Depreciation Method Code | 2 | Optional | Small Integer
DEP_RATE | Depreciation Rate | 8 | Optional | Double
DEP_TO_DATE | Amount Depreciated to Date | 8 | Optional | Double
DEPT_NUMBER | Department Number | 2 | Optional | Small Integer
DETAILS_1 | Details 1 | 60 | Optional | String
DETAILS_2 | Details 2 | 60 | Optional | String
DETAILS_3 | Details 3 | 60 | Optional | String
EMPLOYEE | Employee | 15 | Optional | String
NET_BOOK | Net Book Value | 8 | Optional | Double
NEXT_ASSET | 4 | Optional | Integer
POST_DATE | 2 | Optional | Date
PREV_ASSET | 4 | Optional | Integer
PROFIT_LOSS_NOM_CODE | Profit and Loss Nominal Code | 8 | Required | String
PURCHASE_DATE | Date of Purchase | 2 | Optional | Date
PURCHASE_REF | Purchase Reference Number | 8 | Optional | String
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
SERIAL_NUMBER | Serial Number | 60 | Optional | String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Creating a New Fixed Asset Record


BankData

Description

The BankData object gives access to the Bank Account (BANK.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_NAME | Bank Account Name | 60 | Optional | String
ACCOUNT_NUMBER | Bank Account Number | 60 | Optional | String
ACCOUNT_REF | Account Reference | 8 | Required | String
ACCOUNT_TYPE | Account Type | 1 | Optional | Byte
ADDRESS_1 | Address Line 1 | 60 | Optional | String
ADDRESS_2 | Address Line 2 | 60 | Optional | String
ADDRESS_3 | Address Line 3 | 60 | Optional | String
ADDRESS_4 | Address Line 4 | 60 | Optional | String
ADDRESS_5 | Address Line 5 | 60 | Optional | String
BACS_REFERENCE | BACS Reference | 60 | Optional | String
BANK_BICSWIFT | Bank BICSWIFT | 60 | Optional | String
BANK_FEEDS_ACCESS_TO_ACCOUNTANT_GRANTED | Access to Accountant Granted | 2 | Optional | Byte
BANK_FEEDS_ACCOUNT_ID | Bank Feeds Bank Account ID | 37 | Optional< | String
BANK_FEEDS_ENABLED | Bank Feeds Enabled | 4 | Optional< | Small Integer
BANK_FEEDS_HAS_FAILED_RULES | Bank Feed has had failed rules (remote site notification) | 2 | Optional< | Byte
BANK_FEEDS_LAST_TRAN_ID | Bank Last Transaction ID | 4 | Optional< | Integer
BANK_FEEDS_PROVIDER_TYPE | Bank Feeds Provider Type | 2 | Optional< | Small Integer
BANK_FEEDS_TRANSACTIONS_ARE_RECONCILED | Bank Transactions Are Posted Reconciled | 2 | Optional< | Byte
BANK_CHARGES_DEFAULT_BANK_REF | The default bank account for bank charges | 8 | Optional< | String
BANK_CHARGES_DEFAULT_DEPARTMENT | The default department for bank charges | 2 | Optional | Small Integer
BANK_CHARGES_DEFAULT_NOMINAL_CODE | The default nominal code for bank charges | 8 | Optional | String
BANK_CHARGES_DEFAULT_TAX_CODE | The default tax code for bank charges | 2 | Optional | Small Integer
BANK_IBAN | Bank IBAN | 60 | Optional | String
BANK_REF | Bank Reference Number | 2 | Optional | Small Integer
CONTACT_NAME | Bank Contact Name | 30 | Optional | String
CURRENCY | Currency Code | 1 | Optional | Byte
DELETED_FLAG | Is Deleted | 2 | Optional | Small Integer
E_MAIL | Bank EMail Address | 255 | Optional | String
ELEC_TRANS | Bank Accepts Electronic Payments | 2 | Optional | Small Integer
EXPIRY_DATE | Card Expiry Date | 2 | Optional | Date
EXTERNAL_USAGE | Number of External Usages | 4 | Optional | Integer
FAX | Bank Fax Number | 30 | Optional | String
FIRST_SPLIT | First Transaction | 4 | Optional | Integer
FOREIGN_BALANCE | Foreign Balance | 8 | Optional | Double
INACTIVE_FLAG | Inactive Flag - Yes/No | 4 | Optional | Integer
LAST_REC_BALANCE | Balance at last reconciliation | 8 | Optional | Double
LAST_REC_DATE | Date of last reconciliation | 2 | Optional | Date
LAST_SPLIT | Last Transaction | 4 | Optional | Integer
NAME | Name | 60 | Optional | String
NEXT_CHQ_NO | Next Cheque Number | 10 | Optional | String
NEXT_DEP_NO | Next Deposit Number | 6 | Optional | String
NEXT_WITHDRAWAL_NO | Next Withdrawal Number | 6 | Optional | String
NO_OF_SPLIT | Number of Splits | 4 | Optional | Integer
NO_OF_TRAN | Number of Transactions | 4 | Optional | Integer
NO_OF_UNRECONCILED_ITEMS | No of Unreconciled Items | 4 | Optional | Integer
NO_RECONCILIATION_FLAG | Ignore Reconciliation | 1 | Optional | Byte
OVERDRAFT_LIMIT | Overdraft Limit | 8 | Optional | Double
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
SORT_CODE | Bank Sort Code | 10 | Optional | String
TELEPHONE | Bank Telephone Number | 30 | Optional | String
WWW | Bank Web Site | 255 | Optional | String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Example - Find 'Bank' reconciled transactions


BankHeaderData

Description

The BankHeaderData object gives access to the Bank Transactions held in the HEADER.DTA table.

Note: You should only use this object to read the bank transactions. It should not, under any circumstances, be used to write transactions. To write bank transactions, you should use the TransactionPost object.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Sales/Purchase/Bank Account Reference | 8 | Required | String
AMOUNT_PAID | Total Amount Paid | 8 | Optional | Double
ATTACHMENT_ADDED | Flag whether the transaction has attachments on disk. | 2 | Optional | Small Integer
AUTO_POSTED_TRANSACTION_FLAG | Automatically posted transaction flag. | 2 | Optional | Small Integer
BANK_CHARGE_ACCOUNT | Bank Charge Customer/Supplier Ref (Read Only) | 8 | Optional | String
BANK_CHARGE_IS_CUSTOMER | Is Bank Charge Customer or Supplier (Read Only) | 2 | Optional | Small Integer
BANK_CODE | Bank Account Reference | 8 | Required | String
BANK_FEEDS_MATCHED | Bank Feeds Matched | 1 | Optional | Byte
BANK_FLAG | Bank Reconciled Flag | 1 | Optional | Byte or Character
BANK_RECONCILIATION_ID | Bank reconciliation ID that this transaciton is part of | 4 | Optional | Integer
CURRENCY | Currency for Transaction | 1 | Optional | Byte or Character
CURRENCY_USED | Currency Used | 1 | Optional | Byte or Character
DATE | Transaction Date | 2 | Required | Date
DATE_AMENDED | Date Transaction Amended | 32 | Optional | String
DATE_DUE | Date Invoice is Due for Payment | 2 | Optional | Date
DATE_FORECAST | Forecast Date | 2 | Optional | Date
DATE_LAST_CHARGE | Date Interest Last Charged | 2 | Optional | Date
DELETED_FLAG | Transaction Deleted Flag | 2 | Optional | Small Integer
DEPOSIT_DATE | Bank despoited date | 2 | Optional | Date
DEPOSIT_FLAG | Bank deposited flag | 1 | Optional | Byte
DETAILS | Details | 60 | Optional | String
ELEC_TRANS | Electronic Transaction Flag | 2 | Optional | Small Integer
EURO_GROSS | Euro Gross Amount | 8 | Required | Double
EURO_RATE | Euro Rate | 8 | Required | Double
FINANCE_CHARGE | Finance Charge Flag | 1 | Optional | Byte or Character
FIRST_SPLIT | Item Number | 4 | Optional | Integer
FORECAST_INCLUDE | Included in forecast | 2 | Optional | Date
FOREIGN_AMOUNT_PAID | Foreign Total Amount Paid | 8 | Optional | Double
FOREIGN_GROSS | Foreign Gross Amount | 8 | Required | Double
FOREIGN_NET_AMOUNT | Foreign Net Amount | 8 | Optional | Double
FOREIGN_RATE | Foreign Rate For Euro Currency | 8 | Required | Double
FOREIGN_TAX_AMOUNT | Foreign Tax Amount | 8 | Optional | Double
HAS_EXTERNAL_LINK | Has External Link | 2 | Optional | Small Integer
INTEREST_RATE | Interest Rate to Charge | 8 | Required | Double
INV_REF | 30 | Optional | String
ISP_REFERENCE | Inv/Sop/Pop Reference | 4 | Optional | Integer
JOB_REFERENCE | Job Costing Reference | 60 | Optional | String
LAST_SPLIT | Item Number | 4 | Optional | Integer
NET_AMOUNT | Net Amount | 8 | Required | Double
NEXT_ACCOUNT | Record Number for Next Account | 4 | Optional | Integer
NEXT_BANK | Record Number for Next Bank | 4 | Optional | Integer
NO_DISPUTED | Number of Disputed Splits | 2 | Optional | Small Integer
NO_OF_SPLIT | Number of Splits | 4 | Optional | Integer
OPENING_BALANCE_TRANS | Is Transaction an Opening Balance | 2 | Optional | Small Integer
ORIGINATOR_ID | Guid of the originating Overdrive transaction (For Internal Use Only) | 37 | Optional | String
OVERRIDDEN_CLOSED_LEDGER_DATE | The Closed ledger date that was overridden at the time of posting | 2 | Optional | Date
PAID_FLAG | Transaction Paid Flag | 1 | Optional | Byte or Character
POSTED_DATE | Posting Date | 2 | Optional | Date
POSTING_LOCATION | Location Transaction Posted From | 2 | Optional | Small Integer
PRACTICE_SOLUTIONS_REFN | Sage Practice Solutions Reference | 60 | Optional | String
PREV_ACCOUNT | Record Number for Previous Account | 4 | Optional | Integer
PREV_BANK | Record Number for Previous Bank | 4 | Optional | Integer
PRINTED_FLAG | Printed Flag | 1 | Optional | Byte or Character
PROTX_REFN | Sage Payment Solutions Refn | 63 | Optional | String
RECON_DATE | Date Transaction was Reconciled | 2 | Optional | Date
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
REVALUATION_TRANS | Is Transaction a Revaluation Transaction | 2 | Optional | Small Integer
SETT_DISCOUNT_RATE | Settlement Discount Rate | 8 | Optional | Double
TAX_AMOUNT | Tax Amount | 8 | Optional | Double
TYPE | Transaction Type | 1 | Required | Byte or Character
UNIQUE_REF | Header Number | 4 | Optional | Integer
USER_NAME | User Name | 32 | Optional | String
USER_NAME_AMENDED | Date this transaction was last amended | 2 | Optional | Date
VAT_FLAG | Vat Flag | 1 | Optional | Byte or Character

Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Example - Find 'Bank' reconciled transactions


BankIndex

Description

The BankIndex object gives access to the Bank Accounts Index (BNKINDEX.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Bank Account Reference | 8 | Required | String
RECORD_NUMBER | Record Number in Data File | 4 | Required | Integer
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Example - Find 'Bank' reconciled transactions


BankRecord

Description

The BankRecord object gives access to the Bank Account (BANK.DTA) table and the Bank Account index (BNKINDEX.DTA) table. As an SDORecord object, it encapsulates both the data and index files.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_NAME | Bank Account Name | 60 | Optional | String
ACCOUNT_NUMBER | Bank Account Number | 60 | Optional | String
ACCOUNT_REF | Account Reference | 8 | Required | String
ACCOUNT_TYPE | Account Type | 1 | Optional | Byte
ADDRESS_1 | Address Line 1 | 60 | Optional | String
ADDRESS_2 | Address Line 2 | 60 | Optional | String
ADDRESS_3 | Address Line 3 | 60 | Optional | String
ADDRESS_4 | Address Line 4 | 60 | Optional | String
ADDRESS_5 | Address Line 5 | 60 | Optional | String
BACS_REFERENCE | BACS Reference | 60 | Optional | String
BANK_BICSWIFT | Bank BICSWIFT | 60 | Optional | String
BANK_CHARGES_DEFAULT_BANK_REF | The default bank account for bank charges | 8 | Optional | String
BANK_CHARGES_DEFAULT_DEPARTMENT | The default department for bank charges | 2 | Optional | Small Integer
BANK_CHARGES_DEFAULT_NOMINAL_CODE | The default nominal code for bank charges | 8 | Optional | String
BANK_CHARGES_DEFAULT_TAX_CODE | The default tax code for bank charges | 2 | Optional | Small Integer
BANK_FEEDS_ACCESS_TO_ACCOUNTANT_GRANTED | Access to Accountant Granted | 2 | Optional | Byte
BANK_FEEDS_ACCOUNT_ID | Bank Feeds Bank Account ID | 37 | Optional | String
BANK_FEEDS_ENABLED | Bank Feeds Enabled | 4 | Optional | Small Integer
BANK_FEEDS_HAS_FAILED_RULES | Bank Feed has had failed rules (remote site notification) | 2 | Optional | Byte
BANK_FEEDS_LAST_TRAN_ID | Bank Last Transaction ID | 4 | Optional | Integer
BANK_FEEDS_PROVIDER_TYPE | Bank Feeds Provider Type | 2 | Optional | Small Integer
BANK_FEEDS_TRANSACTIONS_ARE_RECONCILED | Bank Transactions Are Posted Reconciled | 2 | Optional | Byte
BANK_IBAN | Bank IBAN | 60 | Optional | String
BANK_REF | Bank Reference Number | 2 | Optional | Small Integer
CONTACT_NAME | Bank Contact Name | 30 | Optional | String
CURRENCY | Currency Code | 1 | Optional | Byte
DELETED_FLAG | Is Deleted | 2 | Optional | Small Integer
E_MAIL | Bank EMail Address | 255 | Optional | String
ELEC_TRANS | Bank Accepts Electronic Payments | 2 | Optional | Small Integer
EXPIRY_DATE | Card Expiry Date | 2 | Optional | Date
EXTERNAL_USAGE | Number of External Usages | 4 | Optional | Integer
FAX | Bank Fax Number | 30 | Optional | String
FIRST_SPLIT | First Transaction | 4 | Optional | Integer
FOREIGN_BALANCE | Foreign Balance | 8 | Optional | Double
INACTIVE_FLAG | Inactive Flag - Yes/No | 4 | Optional | Integer
LAST_REC_BALANCE | Balance at last reconciliation | 8 | Optional | Double
LAST_REC_DATE | Date of last reconciliation | 2 | Optional | Date
LAST_SPLIT | Last Transaction | 4 | Optional | Integer
NAME | Name | 60 | Optional | String
NEXT_CHQ_NO | Next Cheque Number | 10 | Optional | String
NEXT_DEP_NO | Next Deposit Number | 6 | Optional | String
NEXT_WITHDRAWAL_NO | Next Withdrawal Number | 6 | Optional | String
NO_OF_SPLIT | Number of Splits | 4 | Optional | Integer
NO_OF_TRAN | Number of Transactions | 4 | Optional | Integer
NO_OF_UNRECONCILED_ITEMS | No of Unreconciled Items | 4 | Optional | Integer
NO_RECONCILIATION_FLAG | Ignore Reconciliation | 1 | Optional | Byte
OVERDRAFT_LIMIT | Overdraft Limit | 8 | Optional | Double
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
SORT_CODE | Bank Sort Code | 10 | Optional | String
TELEPHONE | Bank Telephone Number | 30 | Optional | String
WWW | Bank Web Site | 255 | Optional | String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Accessing a Bank Account Memo
Creating a New Bank Account
Posting a Bank Payment
Posting a Bank Receipt
Posting a Foreign Currency Bank Payment
Posting a Foreign Currency Bank Receipt


BankRemittanceData

Description

The BankemittanceData object gives access to the Supplier Remittances (BNKREMDA.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Supplier Account Reference | 8 | Required | String
ADDRESS_1 | Payee Address Line 1 | 60 | Optional | String
ADDRESS_2 | Payee Address Line 2 | 60 | Optional | String
ADDRESS_3 | Payee Address Line 3 | 60 | Optional | String
ADDRESS_4 | Payee Address Line 4 | 60 | Optional | String
ADDRESS_5 | Payee Address Line 5 | 60 | Optional | String
BANK | Bank Account Reference | 8 | Required | String
CHEQUE_NO | Cheque Number | 8 | Required | String
DATE | Date of Transactions | 2 | Required | Date
DETAILS | Details | 60 | Required | String
FAX | Payee Fax Number | 30 | Optional | String
FOREIGN_RATE | Foreign Exchange Rate | 8 | Required | Double
GROSS_AMOUNT | Transaction Gross Amount | 8 | Required | Double
INDEX | Unique Identifier for Remittance Line | 8 | Required | String
INV_REF | Invoice Reference | 30 | Required | String
LASTLINE_FLAG | Last Line Flag - True if this is the last line of the remittance | 2 | Required | Small Integer
NAME | Payee Name | 60 | Optional | String
NET_AMOUNT | Transaction Net Amount | 8 | Required | Double
PAYMENT_AMOUNT | Transaction Payment | 8 | Required | Double
PAYMENT_DATE | Date of Payment | 2 | Required | Date
PAYMENT_FLAG | Payment Flag | 2 | Required | Small Integer
PAYMENT_NO | Payment Header Transaction Record Number | 4 | Required | Integer
PRINTED_FLAG | Printed Flag | 2 | Required | Small Integer
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
TAX_CODE | Tax Code | 3 | Required | String
TELEPHONE | Payee Telephone Number | 30 | Optional | String
TRAN_TYPE | Transaction Type | 2 | Required | String
URN | Unique Identifier for this Remittance | 8 | Required | String
VAT_AMOUNT | Transaction Vat Amount | 8 | Required | Double

Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Posting a Purchase Payment and Remittance


BankRemittanceIndex

Description

The BankRemittanceIndex object gives access to the Supplier Remittances Index (BNKREMIX.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
RECORD_NUMBER | Record Number in Data File | 4 | Required | Integer
URN | Unique Identifier for the Remittance | 16 | Required | String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Posting a Purchase Payment and Remittance


BankRemittanceRecord

Description

The BankRemittanceRecord object gives access to the Supplier Remittances (BNKREMDA.DTA) table and the Supplier Remittances Index (BNKREMIX.DTA) table. As an SDORecord object, it encapsulates both the data and index files.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Supplier Account Reference | 8 | Required | String
ADDRESS_1 | Payee Address Line 1 | 60 | Optional | String
ADDRESS_2 | Payee Address Line 2 | 60 | Optional | String
ADDRESS_3 | Payee Address Line 3 | 60 | Optional | String
ADDRESS_4 | Payee Address Line 4 | 60 | Optional | String
ADDRESS_5 | Payee Address Line 5 | 60 | Optional | String
BANK | Bank Account Reference | 8 | Required | String
CHEQUE_NO | Cheque Number | 8 | Required | String
DATE | Date of Transactions | 2 | Required | Date
DETAILS | Details | 60 | Required | String
FAX | Payee Fax Number | 30 | Optional | String
FOREIGN_RATE | Foreign Exchange Rate | 8 | Required | Double
GROSS_AMOUNT | Transaction Gross Amount | 8 | Required | Double
INDEX | Unique Identifier for Remittance Line | 8 | Required | String
INV_REF | Invoice Reference | 30 | Required | String
LASTLINE_FLAG | Last Line Flag - True if this is the last line of the remittance | 2 | Required | Small Integer
NAME | Payee Name | 60 | Optional | String
NET_AMOUNT | Transaction Net Amount | 8 | Required | Double
PAYMENT_AMOUNT | Transaction Payment | 8 | Required | Double
PAYMENT_DATE | Date of Payment | 2 | Required | Date
PAYMENT_FLAG | Payment Flag | 2 | Required | Small Integer
PAYMENT_NO | Payment Header Transaction Record Number | 4 | Required | Integer
PRINTED_FLAG | Printed Flag | 2 | Required | Small Integer
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
TAX_CODE | Tax Code | 3 | Required | String
TELEPHONE | Payee Telephone Number | 30 | Optional | String
TRAN_TYPE | Transaction Type | 2 | Required | String
URN | Unique Identifier for this Remittance | 8 | Required | String
VAT_AMOUNT | Transaction Vat Amount | 8 | Required | Double

Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Posting a Purchase Payment and Remittance


BankWWWData

Description

The BankWWWData object gives access to the Bank Account Website Address (BANKWWW.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
NAME | Name | 60 | Optional | String
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
SEARCH | Search | 255 | Optional | String
WWW | World Wide Web Address | 255 | Optional | String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

There are currently no examples that make use of this object.


BillData

Description

The BillData object gives access to the Bill Data (BILLS.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Account Reference | 8 | Optional | String
BILL_DATE | Date of Bill | 2 | Optional | Date
DATE_PAID | Date Bill Paid | 2 | Optional | Date
DETAILS | Account Details | 60 | Optional | String
NET_AMOUNT | Net Amount | 8 | Optional | Double
NET_PAID | Net Amount Paid | 8 | Optional | Double
PAY_BY_DATE | Date Bill to be Paid By | 2 | Optional | Date
REFERENCE | Reference | 8 | Optional | String
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
TAX_AMOUNT | Tax Amount | 8 | Optional | Double
TAX_CODE | Tax Code | 2 | Optional | Small Integer
TAX_PAID | Tax Amount Paid | 8 | Optional | Double
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Example - Find unpaid bills


Category

Description

The Category object gives access to the Chart of Accounts Categories (CATEGORY.DTA) table.

Note: At the moment, the Category object only gives access to the categories for the first Chart of Accounts (1.COA)

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
HIGH | High Nominal Code | 8 | Optional | String
LOW | Low Nominal Code | 8 | Optional | String
NAME | Name | 60 | Optional | String
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Microsoft Excel 2000 Integration
Reading the Chart of Accounts


ChartData

Description

The ChartData object gives access to the Chart of Accounts headings.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
CHART_NAME | Chart Name | 60 | Optional | String
NAME_CAPITAL_RESERVES | Capital and Reserves Heading | 60 | Optional | String
NAME_CURRENT_ASSETS | Current Assets Heading | 60 | Optional | String
NAME_CURRENT_LIABILITIES | Current Liabilities Heading | 60 | Optional | String
NAME_EXPENSE | Expenses Heading | 60 | Optional | String
NAME_FIXED_ASSETS | Fixed Assets Heading | 60 | Optional | String
NAME_LONG_TERM_LIABILITIES | Long Term Liabilities Heading | 60 | Optional | String
NAME_OVERHEADS | Overheads Heading | 60 | Optional | String
NAME_PURCHASE | Purchase Heading | 60 | Optional | String
NAME_SALES | Sales Heading | 60 | Optional | String
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Microsoft Excel 2000 Integration
Reading the Chart of Accounts


Companies

Description

The Companies object gives access to the company dataset paths from the COMPANY file in the Sage 50 Accounts program directory.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

The object has no fields collection.

Methods

The Companies object has the following methods:

Method | Description
MoveFirst | Moves to the First company in the collection.
MoveNext | Moves to the Next company in the collection.

Properties

The Companies object has the following properties:

Property | Description
Count | Returns the number of companies in the collection.

Examples Using this Object

Example - List Company names in a ComboBox


ChartData

Company

Description

The Company object gives access to an individual company in the Companies collection.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

The object has no fields collection.

Methods

The object has no methods.

Properties

Property | Description
Path | Returns the path to the selected company.
Name | Returns the name to the selected company.
UniqueRegID | Returns the UniqueRegID to the selected company.

Examples Using this Object

Example - List Company names in a ComboBox


CompanyDeliveryData

Description

The CompanyDeliveryData object gives access to the Company Delivery Address (COMDA.DTA) table.

Applies to

Sage 50 Accounts Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Account Reference | 8 | Required | String
ADDRESS_1 | Delivery Address Line 1 | 60 | Optional | String
ADDRESS_2 | Delivery Address Line 2 | 60 | Optional | String
ADDRESS_3 | Delivery Address Line 3 | 60 | Optional | String
ADDRESS_4 | Delivery Address Line 4 | 60 | Optional | String
ADDRESS_5 | Delivery Address Line 5 | 60 | Optional | String
ADDRESS_REF | Address Reference Number | 2 | Required | Small Integer
ADDRESS_TYPE | Address Type | 1 | Required | Byte
CONTACT_NAME | Contact Name | 30 | Optional | String
CONTACT_ROLE | Contact Role | 30 | Optional | String
COUNTRY_CODE | Country Code | 2 | Required | String
DEFAULT_REF | Default Indicator | 2 | Required | Small Integer
DESCRIPTION | Description | 60 | Required | String
EMAIL | EMail | 255 | Optional | String
FAX | Fax | 30 | Optional | String
NAME | Name | 60 | Required | String
NOTES | Notes | 200 | Optional | String
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
REFERENCE | Delivery Address Reference | 12 | Required | String
TAX_CODE | Tax Code | 2 | Required | Small Integer
TELEPHONE | Telephone | 30 | Optional | String
TELEPHONE_2 | Telephone2 | 30 | Optional | String
VAT_NUMBER | Vat Registration Number | 20 | Optional | String

Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Creating a Company Delivery Address


CompanyDeliveryIndex

Description

The CompanyDeliveryIndex object gives access to the Company Delivery Address index (COMDAIDX.DTA) table.

Applies to

Sage 50 Accounts Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
RECORD_NUMBER | Record Number in Data File | 4 | Required | Integer
REFERENCE | Delivery Address Reference | 12 | Required | String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Creating a Company Delivery Address


CompanyDeliveryRecord

Description

The CompanyDeliveryRecord object gives access to the Company Delivery Address (COMDA.DTA) table and the Company Delivery Address index (COMDAIDX.DTA) table. As an SDORecord object, it encapsulates both the data and index files.

Applies to

Sage 50 Accounts Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Account Reference | 8 | Required | String
ADDRESS_1 | Delivery Address Line 1 | 60 | Optional | String
ADDRESS_2 | Delivery Address Line 2 | 60 | Optional | String
ADDRESS_3 | Delivery Address Line 3 | 60 | Optional | String
ADDRESS_4 | Delivery Address Line 4 | 60 | Optional | String
ADDRESS_5 | Delivery Address Line 5 | 60 | Optional | String
ADDRESS_REF | Address Reference Number | 2 | Required | Small Integer
ADDRESS_TYPE | Address Type | 1 | Required | Byte
CONTACT_NAME | Contact Name | 30 | Optional | String
CONTACT_ROLE | Contact Role | 30 | Optional | String
COUNTRY_CODE | Country Code | 2 | Required | String
DEFAULT_REF | Default Indicator | 2 | Required | Small Integer
DESCRIPTION | Description | 60 | Required | String
EMAIL | EMail | 255 | Optional | String
FAX | Fax | 30 | Optional | String
NAME | Name | 60 | Required | String
NOTES | Notes | 200 | Optional | String
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
REFERENCE | Delivery Address Reference | 12 | Required | String
TAX_CODE | Tax Code | 2 | Required | Small Integer
TELEPHONE | Telephone | 30 | Optional | String
TELEPHONE_2 | Telephone2 | 30 | Optional | String
VAT_NUMBER | Vat Registration Number | 20 | Optional | String

Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Creating a Company Delivery Address


ContactAccountIdxRecord

Description

The ContactAccountIdxRecord object gives access to the contacts (CONTACT.DTA) table sorted by ACCOUNT_REF. As an SDORecord object, it encapsulates both the data and index files.

NOTE: A new property 'Details' has been added to allow the details of the contact to be entered.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Account Reference | 8 | Required | String
BILL_POSTED | Posted Flag for Invoice Created | 2 | Optional | Small Integer
CALL_DATE | Call Date | 2 | Optional | Date
CALL_DURATION | Call Duration | 4 | Optional | Integer
CALL_END | Call End | 4 | Optional | Integer
CALL_START | Call Start | 4 | Optional | Integer
CONTACT | Contact Name | 30 | Optional | String
DELEFATED_TO | User Delegated To | 32 | Optional | String
FOLLOW_UP_DATE | Follow Up Date | 2 | Optional | Date
OFFSET | Memo Offset in Bytes | 4 | Optional | Integer
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
TELEPHONE | Telephone Number | 30 | Optional | String
TYPE | Contact Record Type | 1 | Required | Byte
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

There are currently no examples that make use of this object.


ContactAccountIndex

Description

The ContactAccountIndex object gives access to the Contacts Index (CONTINDA.DTA) sorted by ACCOUNT_REF.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Contact Account Reference | 8 | Required | String
RECORD_NUMBER | Record Number in Data File | 4 | Required | Integer
TYPE | Contact Type | 1 | Required | Byte
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

There are currently no examples that make use of this object.


ContactData

Description

The ContactData object gives access to the Contacts (CONTACT.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Account Reference | 8 | Required | String
BILL_POSTED | Bill Posted Flag | 2 | Optional | Small Integer
CALL_DATE | Call Date | 2 | Optional | Date
CALL_DURATION | Call Duration | 4 | Optional | Integer
CALL_END | Call End | 4 | Optional | Integer
CALL_START | Call Start | 4 | Optional | Integer
CONTACT | Contact Name | 30 | Optional | String
DELEFATED_TO | User Delegated To | 32 | Optional | String
FOLLOW_UP_DATE | Follow Up Date | 2 | Optional | Date
OFFSET | Memo Offset in Bytes | 4 | Optional | Integer
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED Flag denoting if the record has been deleted
2 Optional Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
TELEPHONE | Telephone Number | 30 | Optional | String
TYPE | Contact Record Type | 1 | Required | Byte
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

There are currently no examples that make use of this object.


ContactDateIdxRecord

Description

The ContactDateIdxRecord object gives access to the contacts (CONTACT.DTA) table sorted by CALL_DATE. As an SDORecord object, it encapsulates both the data and index files.

NOTE: A new property 'Details' has been added to allow the details of the contact to be entered.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Account Reference | 8 | Required | String
BILL_POSTED | Posted Flag for Invoice Created | 2 | Optional | Small Integer
CALL_DATE | Call Date | 2 | Optional | Date
CALL_DURATION | Call Duration | 4 | Optional | Integer
CALL_END | Call End | 4 | Optional | Integer
CALL_START | Call Start | 4 | Optional | Integer
CONTACT | Contact Name | 30 | Optional | String
DELEFATED_TO | User Delegated To | 32 | Optional | String
FOLLOW_UP_DATE | Follow Up Date | 2 | Optional | Date
OFFSET | Memo Offset in Bytes | 4 | Optional | Integer
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
TELEPHONE | Telephone Number | 30 | Optional | String
TYPE | Contact Record Type | 1 | Required | Byte
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

There are currently no examples that make use of this object.


ContactDateIndex

Description

The ContactDateIndex object gives access to the Contacts Index (CONTINDD.DTA) sorted by CALL_DATE.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Contact Account Reference | 8 | Required | String
DATE | Contact Date | 7 | Required | String
RECORD_NUMBER | Record Number in Data File | 4 | Required | Integer
TYPE | Contact Type | 1 | Required | Byte
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

There are currently no examples that make use of this object.


ControlData

Description

The ControlData object gives access to the Account (ACCOUNT.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCRUALS_NO | Accruals Record Number | 4 | Required | Integer
BADDEBTS_NO | Bad Debts Record Number | 4 | Required | Integer
CREDITORS_NO | Creditors Record Number | 4 | Required | Integer
DEBTORS_NO | Debtors Record Number | 4 | Required | Integer
DEFBANK_NO | Default Bank Record Number | 4 | Required | Integer
DEFFINANCE_NO | Default Finance Charges Record Number | 4 | Required | Integer
DEFREVALUE_NO | Default Revaluation Record Number | 4 | Required | Integer
DEFSALES_NO | Default Sales Record Number | 4 | Required | Integer
IOSS_NO | IOSS Tax Control Account record number | 4 | Required | Integer
LAST_CREDIT | Last Credit | 4 | Required | Integer
LAST_GDN | Last GDN | 4 | Required | Integer
LAST_GRN | Last GRN | 4 | Required | Integer
LAST_INVOICE | Last Invoice | 4 | Required | Integer
LAST_POP | Last POP | 4 | Required | Integer
LAST_SOP | Last SOP | 4 | Required | Integer
MANUALADJUSTMENTS_NO | Manual Adjustments record number | 4 | Required | Integer
MISPOSTINGS_NO | Mispostings Record Number | 4 | Required | Integer
NO_OF_ASSETS | Number of Asset Records | 4 | Required | Integer
NO_OF_BANK | Number of Bank Records | 4 | Required | Integer
NO_OF_CONTACTS | Number of Contact Records | 4 | Required | Integer
NO_OF_HEADERS | Number of Header Records | 4 | Required | Integer
NO_OF_INVOICE | Number of Invoice Records | 4 | Required | Integer
NO_OF_NOMINAL | Number of Nominal Records | 4 | Required | Integer
NO_OF_POP | Number of POP records | 4 | Required | Integer
NO_OF_PURCHASE | Number of Purchase Records | 4 | Required | Integer
NO_OF_SALES | Number of Sales Records | 4 | Required | Integer
NO_OF_SOP | Number of SOP Records | 4 | Required | Integer
NO_OF_SPLITS | Number of Split Records | 4 | Required | Integer
NO_OF_STOCK | Number of Stock Records | 4 | Required | Integer
NO_OF_USAGE | Number of Usage Records | 4 | Required | Integer
NONUNIONOSS_NO | Non-union OSS Tax Control Account record number | 4 | Required | Integer
PDISCOUNT_NO | Purchase Discount Record Number | 4 | Required | Integer
PLYEARAC_NO | P&L Record Number | 4 | Required | Integer
PREPAYMENTS_NO | Prepayments Record Number | 4 | Required | Integer
PROTECT_NO | Protect - Not Used | 4 | Required | Integer
PTAX_NO | Purchase Tax Record Number | 4 | Required | Integer
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
SDISCOUNT_NO | Sales Discount Record Number | 4 | Required | Integer
STAX_NO | Sales Tax Record Number | 4 | Required | Integer
SUSPENSE_NO | Suspense Record Number | 4 | Required | Integer
T0_DESCRIPTION | T0 Description | 60 | Optional | String
T0_EUROPURCHASE | T0 Euro Purchase | 1 | Optional | Byte
T0_EUROSALE | T0 Euro Sale | 1 | Optional | Byte
T0_INUSE | T0 In Use | 1 | Optional | Byte
T0_OVERRIDE_LINKED | T0 Override Linked Rate | 2 | Optional | Small Integer
T0_POSTPONED | T0 Postponed Accounting | 2 | Optional | Small Integer
T0_RATE | T0 Rate | 8 | Optional | Double
T0_RELATED | T0 Euro Purchase Related | 1 | Optional | Byte
T0_REVERSE_CHARGE | T0 Reverse Charge | 2 | Optional | Small Integer
T10_DESCRIPTION | T10 Description | 60 | Optional | String
T10_EUROPURCHASE | T10 Euro Purchase | 1 | Optional | Byte
T10_EUROSALE | T10 Euro Sale | 1 | Optional | Byte
T10_INUSE | T10 In Use | 1 | Optional | Byte
T10_OVERRIDE_LINKED | T10 Override Linked Rate | 2 | Optional | Small Integer
T10_POSTPONED | T10 Postponed Accounting | 2 | Optional | Small Integer
T10_RATE | T10 Rate | 8 | Optional | Double
T10_RELATED | T10 Euro Purchase Related | 1 | Optional | Byte
T10_REVERSE_CHARGE | T10 Reverse Charge | 2 | Optional | Small Integer
T11_DESCRIPTION | T11 Description | 60 | Optional | String
T11_EUROPURCHASE | T11 Euro Purchase | 1 | Optional | Byte
T11_EUROSALE | T11 Euro Sale | 1 | Optional | Byte
T11_INUSE | T11 In Use | 1 | Optional | Byte
T1_OVERRIDE_LINKED | T1 Override Linked Rate | 2 | Optional | Small Integer
T1_POSTPONED | T1 Postponed Accounting | 2 | Optional | Small Integer
T11_RATE | T11 Rate | 8 | Optional | Double
T11_RELATED | T11 Euro Purchase Related | 1 | Optional | Byte
T11_REVERSE_CHARGE | T11 Reverse Charge | 2 | Optional | Small Integer
T12_DESCRIPTION | T12 Description | 60 | Optional | String
T12_EUROPURCHASE | T12 Euro Purchase | 1 | Optional | Byte
T12_EUROSALE | T12 Euro Sale | 1 | Optional | Byte
T12_INUSE | T12 In Use | 1 | Optional | Byte
T12_OVERRIDE_LINKED | T12 Override Linked Rate | 2 | Optional | Small Integer
T12_POSTPONED | T12 Postponed Accounting | 2 | Optional | Small Integer
T12_RATE | T12 Rate | 8 | Optional | Double
T12_RELATED | T12 Euro Purchase Related | 1 | Optional | Byte
T12_REVERSE_CHARGE | T12 Reverse Charge | 2 | Optional | Small Integer
T13_DESCRIPTION | T13 Description | 60 | Optional | String
T13_EUROPURCHASE | T13 Euro Purchase | 1 | Optional | Byte
T13_EUROSALE | T13 Euro Sale | 1 | Optional | Byte
T13_INUSE | T13 In Use | 1 | Optional | Byte
T13_OVERRIDE_LINKED | T13 Override Linked Rate | 2 | Optional | Small Integer
T13_POSTPONED | T13 Postponed Accounting | 2 | Optional | Small Integer
T13_RATE | T13 Rate | 8 | Optional | Double
T13_RELATED | T13 Euro Purchase Related | 1 | Optional | Byte
T13_REVERSE_CHARGE | T13 Reverse Charge | 2 | Optional | Small Integer
T14_DESCRIPTION | T14 Description | 60 | Optional | String
T14_EUROPURCHASE | T14 Euro Purchase | 1 | Optional | Byte
T14_EUROSALE | T14 Euro Sale | 1 | Optional | Byte
T14_INUSE | T14 In Use | 1 | Optional | Byte
T14_OVERRIDE_LINKED | T14 Override Linked Rate | 2 | Optional | Small Integer
T14_POSTPONED | T14 Postponed Accounting | 2 | Optional | Small Integer
T14_RATE | T14 Rate | 8 | Optional | Double
T14_RELATED | T14 Euro Purchase Related | 1 | Optional | Byte
T14_REVERSE_CHARGE | T14 Reverse Charge | 2 | Optional | Small Integer
T15_DESCRIPTION | T15 Description | 60 | Optional | String
T15_EUROPURCHASE | T15 Euro Purchase | 1 | Optional | Byte
T15_EUROSALE | T15 Euro Sale | 1 | Optional | Byte
T15_INUSE | T15 In Use | 1 | Optional | Byte
T15_OVERRIDE_LINKED | T15 Override Linked Rate | 2 | Optional | Small Integer
T15_POSTPONED | T15 Postponed Accounting | 2 | Optional | Small Integer
T15_RATE | T15 Rate | 8 | Optional | Double
T15_RELATED | T15 Euro Purchase Related | 1 | Optional | Byte
T15_REVERSE_CHARGE | T15 Reverse Charge | 2 | Optional | Small Integer
T16_DESCRIPTION | T16 Description | 60 | Optional | String
T16_EUROPURCHASE | T16 Euro Purchase | 1 | Optional | Byte
T16_EUROSALE | T16 Euro Sale | 1 | Optional | Byte
T16_INUSE | T16 In Use | 1 | Optional | Byte
T16_OVERRIDE_LINKED | T16 Override Linked Rate | 2 | Optional | Small Integer
T16_POSTPONED | T16 Postponed Accounting | 2 | Optional | Small Integer
T16_RATE | T16 Rate | 8 | Optional | Double
T16_RELATED | T16 Euro Purchase Related | 1 | Optional | Byte
T16_REVERSE_CHARGE | T16 Reverse Charge | 2 | Optional | Small Integer
T17_DESCRIPTION | T17 Description | 60 | Optional | String
T17_EUROPURCHASE | T17 Euro Purchase | 1 | Optional | Byte
T17_EUROSALE | T17 Euro Sale | 1 | Optional | Byte
T17_INUSE | T17 In Use | 1 | Optional | Byte
T17_OVERRIDE_LINKED | T17 Override Linked Rate | 2 | Optional | Small Integer
T17_POSTPONED | T17 Postponed Accounting | 2 | Optional | Small Integer
T17_RATE | T17 Rate | 8 | Optional | Double
T17_RELATED | T17 Euro Purchase Related | 1 | Optional | Byte
T17_REVERSE_CHARGE | T17 Reverse Charge | 2 | Optional | Small Integer
T18_DESCRIPTION | T18 Description | 60 | Optional | String
T18_EUROPURCHASE | T18 Euro Purchase | 1 | Optional | Byte
T18_EUROSALE | T18 Euro Sale | 1 | Optional | Byte
T18_INUSE | T18 In Use | 1 | Optional | Byte
T18_OVERRIDE_LINKED | T18 Override Linked Rate | 2 | Optional | Small Integer
T18_POSTPONED | T18 Postponed Accounting | 2 | Optional | Small Integer
T18_RATE | T18 Rate | 8 | Optional | Double
T18_RELATED | T18 Euro Purchase Related | 1 | Optional | Byte
T18_REVERSE_CHARGE | T18 Reverse Charge | 2 | Optional | Small Integer
T19_DESCRIPTION | T19 Description | 60 | Optional | String
T19_EUROPURCHASE | T19 Euro Purchase | 1 | Optional | Byte
T19_EUROSALE | T19 Euro Sale | 1 | Optional | Byte
T19_INUSE | T19 In Use | 1 | Optional | Byte
T19_OVERRIDE_LINKED | T19 Override Linked Rate | 2 | Optional | Small Integer
T19_POSTPONED | T19 Postponed Accounting | 2 | Optional | Small Integer
T19_RATE | T19 Rate | 8 | Optional | Double
T19_RELATED | T19 Euro Purchase Related | 1 | Optional | Byte
T19_REVERSE_CHARGE | T19 Reverse Charge | 2 | Optional | Small Integer
T1_DESCRIPTION | T1 Description | 60 | Optional | String
T1_EUROPURCHASE | T1 Euro Purchase | 1 | Optional | Byte
T1_EUROSALE | T1 Euro Sale | 1 | Optional | Byte
T1_INUSE | T1 In Use | 1 | Optional | Byte
T1_OVERRIDE_LINKED | T1 Override Linked Rate | 2 | Optional | Small Integer
T1_POSTPONED | T1 Postponed Accounting | 2 | Optional | Small Integer
T1_RATE | T1 Rate | 8 | Optional | Double
T1_RELATED | T1 Euro Purchase Related | 1 | Optional | Byte
T1_REVERSE_CHARGE | T1 Reverse Charge | 2 | Optional | Small Integer
T20_DESCRIPTION | T20 Description | 60 | Optional | String
T20_EUROPURCHASE | T20 Euro Purchase | 1 | Optional | Byte
T20_EUROSALE | T20 Euro Sale | 1 | Optional | Byte
T20_INUSE | T20 In Use | 1 | Optional | Byte
T20_OVERRIDE_LINKED | T20 Override Linked Rate | 2 | Optional | Small Integer
T20_POSTPONED | T20 Postponed Accounting | 2 | Optional | Small Integer
T20_RATE | T20 Rate | 8 | Optional | Double
T20_RELATED | T20 Euro Purchase Related | 1 | Optional | Byte
T20_REVERSE_CHARGE | T20 Reverse Charge | 2 | Optional | Small Integer
T21_DESCRIPTION | T21 Description | 60 | Optional | String
T21_EUROPURCHASE | T21 Euro Purchase | 1 | Optional | Byte
T21_EUROSALE | T21 Euro Sale | 1 | Optional | Byte
T21_INUSE | T21 In Use | 1 | Optional | Byte
T21_OVERRIDE_LINKED | T21 Override Linked Rate | 2 | Optional | Small Integer
T21_POSTPONED | T21 Postponed Accounting | 2 | Optional | Small Integer
T21_RATE | T21 Rate | 8 | Optional | Double
T21_RELATED | T21 Euro Purchase Related | 1 | Optional | Byte
T21_REVERSE_CHARGE | T21 Reverse Charge | 2 | Optional | Small Integer
T22_DESCRIPTION | T22 Description | 60 | Optional | String
T22_EUROPURCHASE | T22 Euro Purchase | 1 | Optional | Byte
T22_EUROSALE | T22 Euro Sale | 1 | Optional | Byte
T22_INUSE | T22 In Use | 1 | Optional | Byte
T22_OVERRIDE_LINKED | T22 Override Linked Rate | 2 | Optional | Small Integer
T22_POSTPONED | T22 Postponed Accounting | 2 | Optional | Small Integer
T22_RATE | T22 Rate | 8 | Optional | Double
T22_RELATED | T22 Euro Purchase Related | 1 | Optional | Byte
T22_REVERSE_CHARGE | T22 Reverse Charge | 2 | Optional | Small Integer
T23_DESCRIPTION | T23 Description | 60 | Optional | String
T23_EUROPURCHASE | T23 Euro Purchase | 1 | Optional | Byte
T23_EUROSALE | T23 Euro Sale | 1 | Optional | Byte
T23_INUSE | T23 In Use | 1 | Optional | Byte
T23_OVERRIDE_LINKED | T23 Override Linked Rate | 2 | Optional | Small Integer
T23_POSTPONED | T23 Postponed Accounting | 2 | Optional | Small Integer
T23_RATE | T23 Rate | 8 | Optional | Double
T23_RELATED | T23 Euro Purchase Related | 1 | Optional | Byte
T23_REVERSE_CHARGE | T23 Reverse Charge | 2 | Optional | Small Integer
T24_DESCRIPTION | T24 Description | 60 | Optional | String
T24_EUROPURCHASE | T24 Euro Purchase | 1 | Optional | Byte
T24_EUROSALE | T24 Euro Sale | 1 | Optional | Byte
T24_INUSE | T24 In Use | 1 | Optional | Byte
T24_OVERRIDE_LINKED | T24 Override Linked Rate | 2 | Optional | Small Integer
T24_POSTPONED | T24 Postponed Accounting | 2 | Optional | Small Integer
T24_RATE | T24 Rate | 8 | Optional | Double
T24_RELATED | T24 Euro Purchase Related | 1 | Optional | Byte
T24_REVERSE_CHARGE | T24 Reverse Charge | 2 | Optional | Small Integer
T25_DESCRIPTION | T25 Description | 60 | Optional | String
T25_EUROPURCHASE | T25 Euro Purchase | 1 | Optional | Byte
T25_EUROSALE | T25 Euro Sale | 1 | Optional | Byte
T25_INUSE | T25 In Use | 1 | Optional | Byte
T25_OVERRIDE_LINKED | T25 Override Linked Rate | 2 | Optional | Small Integer
T25_POSTPONED | T25 Postponed Accounting | 2 | Optional | Small Integer
T25_RATE | T25 Rate | 8 | Optional | Double
T25_RELATED | T25 Euro Purchase Related | 1 | Optional | Byte
T25_REVERSE_CHARGE | T25 Reverse Charge | 2 | Optional | Small Integer
T26_DESCRIPTION | T26 Description | 60 | Optional | String
T26_EUROPURCHASE | T26 Euro Purchase | 1 | Optional | Byte
T26_EUROSALE | T26 Euro Sale | 1 | Optional | Byte
T26_INUSE | T26 In Use | 1 | Optional | Byte
T26_OVERRIDE_LINKED | T26 Override Linked Rate | 2 | Optional | Small Integer
T26_POSTPONED | T26 Postponed Accounting | 2 | Optional | Small Integer
T26_RATE | T26 Rate | 8 | Optional | Double
T26_RELATED | T26 Euro Purchase Related | 1 | Optional | Byte
T26_REVERSE_CHARGE | T26 Reverse Charge | 2 | Optional | Small Integer
T27_DESCRIPTION | T27 Description | 60 | Optional | String
T27_EUROPURCHASE | T27 Euro Purchase | 1 | Optional | Byte
T27_EUROSALE | T27 Euro Sale | 1 | Optional | Byte
T27_INUSE | T27 In Use | 1 | Optional | Byte
T27_OVERRIDE_LINKED | T27 Override Linked Rate | 2 | Optional | Small Integer
T27_POSTPONED | T27 Postponed Accounting | 2 | Optional | Small Integer
T27_RATE | T27 Rate | 8 | Optional | Double
T27_RELATED | T27 Euro Purchase Related | 1 | Optional | Byte
T27_REVERSE_CHARGE | T27 Reverse Charge | 2 | Optional | Small Integer
T28_DESCRIPTION | T28 Description | 60 | Optional | String
T28_EUROPURCHASE | T28 Euro Purchase | 1 | Optional | Byte
T28_EUROSALE | T28 Euro Sale | 1 | Optional | Byte
T28_INUSE | T28 In Use | 1 | Optional | Byte
T28_OVERRIDE_LINKED | T28 Override Linked Rate | 2 | Optional | Small Integer
T28_POSTPONED | T28 Postponed Accounting | 2 | Optional | Small Integer
T28_RATE | T28 Rate | 8 | Optional | Double
T28_RELATED | T28 Euro Purchase Related | 1 | Optional | Byte
T28_REVERSE_CHARGE | T28 Reverse Charge | 2 | Optional | Small Integer
T29_DESCRIPTION | T29 Description | 60 | Optional | String
T29_EUROPURCHASE | T29 Euro Purchase | 1 | Optional | Byte
T29_EUROSALE | T29 Euro Sale | 1 | Optional | Byte
T29_INUSE | T29 In Use | 1 | Optional | Byte
T29_OVERRIDE_LINKED | T29 Override Linked Rate | 2 | Optional | Small Integer
T29_POSTPONED | T29 Postponed Accounting | 2 | Optional | Small Integer
T29_RATE | T29 Rate | 8 | Optional | Double
T29_RELATED | T29 Euro Purchase Related | 1 | Optional | Byte
T29_REVERSE_CHARGE | T29 Reverse Charge | 2 | Optional | Small Integer
T2_DESCRIPTION | T2 Description | 60 | Optional | String
T2_EUROPURCHASE | T2 Euro Purchase | 1 | Optional | Byte
T2_EUROSALE | T2 Euro Sale | 1 | Optional | Byte
T2_INUSE | T2 In Use | 1 | Optional | Byte
T2_OVERRIDE_LINKED | T2 Override Linked Rate | 2 | Optional | Small Integer
T2_POSTPONED | T2 Postponed Accounting | 2 | Optional | Small Integer
T2_RATE | T2 Rate | 8 | Optional | Double
T2_RELATED | T2 Euro Purchase Related | 1 | Optional | Byte
T2_REVERSE_CHARGE | T2 Reverse Charge | 2 | Optional | Small Integer
T30_DESCRIPTION | T30 Description | 60 | Optional | String
T30_EUROPURCHASE | T30 Euro Purchase | 1 | Optional | Byte
T30_EUROSALE | T30 Euro Sale | 1 | Optional | Byte
T30_INUSE | T30 In Use | 1 | Optional | Byte
T30_OVERRIDE_LINKED | T30 Override Linked Rate | 2 | Optional | Small Integer
T30_POSTPONED | T30 Postponed Accounting | 2 | Optional | Small Integer
T30_RATE | T30 Rate | 8 | Optional | Double
T30_RELATED | T30 Euro Purchase Related | 1 | Optional | Byte
T30_REVERSE_CHARGE | T30 Reverse Charge | 2 | Optional | Small Integer
T31_DESCRIPTION | T31 Description | 60 | Optional | String
T31_EUROPURCHASE | T31 Euro Purchase | 1 | Optional | Byte
T31_EUROSALE | T31 Euro Sale | 1 | Optional | Byte
T31_INUSE | T31 In Use | 1 | Optional | Byte
T31_OVERRIDE_LINKED | T31 Override Linked Rate | 2 | Optional | Small Integer
T31_POSTPONED | T31 Postponed Accounting | 2 | Optional | Small Integer
T31_RATE | T31 Rate | 8 | Optional | Double
T31_RELATED | T31 Euro Purchase Related | 1 | Optional | Byte
T31_REVERSE_CHARGE | T31 Reverse Charge | 2 | Optional | Small Integer
T32_DESCRIPTION | T32 Description | 60 | Optional | String
T32_EUROPURCHASE | T32 Euro Purchase | 1 | Optional | Byte
T32_EUROSALE | T32 Euro Sale | 1 | Optional | Byte
T32_INUSE | T32 In Use | 1 | Optional | Byte
T32_OVERRIDE_LINKED | T32 Override Linked Rate | 2 | Optional | Small Integer
T32_POSTPONED | T32 Postponed Accounting | 2 | Optional | Small Integer
T32_RATE | T32 Rate | 8 | Optional | Double
T32_RELATED | T32 Euro Purchase Related | 1 | Optional | Byte
T32_REVERSE_CHARGE | T32 Reverse Charge | 2 | Optional | Small Integer
T33_DESCRIPTION | T33 Description | 60 | Optional | String
T33_EUROPURCHASE | T33 Euro Purchase | 1 | Optional | Byte
T33_EUROSALE | T33 Euro Sale | 1 | Optional | Byte
T33_INUSE | T33 In Use | 1 | Optional | Byte
T33_OVERRIDE_LINKED | T33 Override Linked Rate | 2 | Optional | Small Integer
T33_POSTPONED | T33 Postponed Accounting | 2 | Optional | Small Integer
T33_RATE | T33 Rate | 8 | Optional | Double
T33_RELATED | T33 Euro Purchase Related | 1 | Optional | Byte
T33_REVERSE_CHARGE | T33 Reverse Charge | 2 | Optional | Small Integer
T34_DESCRIPTION | T34 Description | 60 | Optional | String
T34_EUROPURCHASE | T34 Euro Purchase | 1 | Optional | Byte
T34_EUROSALE | T34 Euro Sale | 1 | Optional | Byte
T34_INUSE | T34 In Use | 1 | Optional | Byte
T34_OVERRIDE_LINKED | T34 Override Linked Rate | 2 | Optional | Small Integer
T34_POSTPONED | T34 Postponed Accounting | 2 | Optional | Small Integer
T34_RATE | T34 Rate | 8 | Optional | Double
T34_RELATED | T34 Euro Purchase Related | 1 | Optional | Byte
T34_REVERSE_CHARGE | T34 Reverse Charge | 2 | Optional | Small Integer
T35_DESCRIPTION | T35 Description | 60 | Optional | String
T35_EUROPURCHASE | T35 Euro Purchase | 1 | Optional | Byte
T35_EUROSALE | T35 Euro Sale | 1 | Optional | Byte
T35_INUSE | T35 In Use | 1 | Optional | Byte
T35_OVERRIDE_LINKED | T35 Override Linked Rate | 2 | Optional | Small Integer
T35_POSTPONED | T35 Postponed Accounting | 2 | Optional | Small Integer
T35_RATE | T35 Rate | 8 | Optional | Double
T35_RELATED | T35 Euro Purchase Related | 1 | Optional | Byte
T35_REVERSE_CHARGE | T35 Reverse Charge | 2 | Optional | Small Integer
T36_DESCRIPTION | T36 Description | 60 | Optional | String
T36_EUROPURCHASE | T36 Euro Purchase | 1 | Optional | Byte
T36_EUROSALE | T36 Euro Sale | 1 | Optional | Byte
T36_INUSE | T36 In Use | 1 | Optional | Byte
T36_OVERRIDE_LINKED | T36 Override Linked Rate | 2 | Optional | Small Integer
T36_POSTPONED | T36 Postponed Accounting | 2 | Optional | Small Integer
T36_RATE | T36 Rate | 8 | Optional | Double
T36_RELATED | T36 Euro Purchase Related | 1 | Optional | Byte
T36_REVERSE_CHARGE | T36 Reverse Charge | 2 | Optional | Small Integer
T37_DESCRIPTION | T37 Description | 60 | Optional | String
T37_EUROPURCHASE | T37 Euro Purchase | 1 | Optional | Byte
T37_EUROSALE | T37 Euro Sale | 1 | Optional | Byte
T37_INUSE | T37 In Use | 1 | Optional | Byte
T37_OVERRIDE_LINKED | T37 Override Linked Rate | 2 | Optional | Small Integer
T37_POSTPONED | T37 Postponed Accounting | 2 | Optional | Small Integer
T37_RATE | T37 Rate | 8 | Optional | Double
T37_RELATED | T37 Euro Purchase Related | 1 | Optional | Byte
T37_REVERSE_CHARGE | T37 Reverse Charge | 2 | Optional | Small Integer
T38_DESCRIPTION | T38 Description | 60 | Optional | String
T38_EUROPURCHASE | T38 Euro Purchase | 1 | Optional | Byte
T38_EUROSALE | T38 Euro Sale | 1 | Optional | Byte
T38_INUSE | T38 In Use | 1 | Optional | Byte
T38_OVERRIDE_LINKED | T38 Override Linked Rate | 2 | Optional | Small Integer
T38_POSTPONED | T38 Postponed Accounting | 2 | Optional | Small Integer
T38_RATE | T38 Rate | 8 | Optional | Double
T38_RELATED | T38 Euro Purchase Related | 1 | Optional | Byte
T38_REVERSE_CHARGE | T38 Reverse Charge | 2 | Optional | Small Integer
T39_DESCRIPTION | T39 Description | 60 | Optional | String
T39_EUROPURCHASE | T39 Euro Purchase | 1 | Optional | Byte
T39_EUROSALE | T39 Euro Sale | 1 | Optional | Byte
T39_INUSE | T39 In Use | 1 | Optional | Byte
T39_OVERRIDE_LINKED | T39 Override Linked Rate | 2 | Optional | Small Integer
T39_POSTPONED | T39 Postponed Accounting | 2 | Optional | Small Integer
T39_RATE | T39 Rate | 8 | Optional | Double
T39_RELATED | T39 Euro Purchase Related | 1 | Optional | Byte
T39_REVERSE_CHARGE | T39 Reverse Charge | 2 | Optional | Small Integer
T3_DESCRIPTION | T3 Description | 60 | Optional | String
T3_EUROPURCHASE | T3 Euro Purchase | 1 | Optional | Byte
T3_EUROSALE | T3 Euro Sale | 1 | Optional | Byte
T3_INUSE | T3 In Use | 1 | Optional | Byte
T3_OVERRIDE_LINKED | T3 Override Linked Rate | 2 | Optional | Small Integer
T3_POSTPONED | T3 Postponed Accounting | 2 | Optional | Small Integer
T3_RATE | T3 Rate | 8 | Optional | Double
T3_RELATED | T3 Euro Purchase Related | 1 | Optional | Byte
T3_REVERSE_CHARGE | T3 Reverse Charge | 2 | Optional | Small Integer
T40_DESCRIPTION | T40 Description | 60 | Optional | String
T40_EUROPURCHASE | T40 Euro Purchase | 1 | Optional | Byte
T40_EUROSALE | T40 Euro Sale | 1 | Optional | Byte
T40_INUSE | T40 In Use | 1 | Optional | Byte
T40_OVERRIDE_LINKED | T40 Override Linked Rate | 2 | Optional | Small Integer
T40_POSTPONED | T40 Postponed Accounting | 2 | Optional | Small Integer
T40_RATE | T40 Rate | 8 | Optional | Double
T40_RELATED | T40 Euro Purchase Related | 1 | Optional | Byte
T40_REVERSE_CHARGE | T0 Reverse Charge | 2 | Optional | Small Integer
T41_DESCRIPTION | T41 Description | 60 | Optional | String
T41_EUROPURCHASE | T41 Euro Purchase | 1 | Optional | Byte
T41_EUROSALE | T41 Euro Sale | 1 | Optional | Byte
T41_INUSE | T41 In Use | 1 | Optional | Byte
T41_OVERRIDE_LINKED | T41 Override Linked Rate | 2 | Optional | Small Integer
T41_POSTPONED | T41 Postponed Accounting | 2 | Optional | Small Integer
T41_RATE | T41 Rate | 8 | Optional | Double
T41_RELATED | T41 Euro Purchase Related | 1 | Optional | Byte
T41_REVERSE_CHARGE | T41 Reverse Charge | 2 | Optional | Small Integer
T42_DESCRIPTION | T42 Description | 60 | Optional | String
T42_EUROPURCHASE | T42 Euro Purchase | 1 | Optional | Byte
T42_EUROSALE | T42 Euro Sale | 1 | Optional | Byte
T42_INUSE | T42 In Use | 1 | Optional | Byte
T42_OVERRIDE_LINKED | T42 Override Linked Rate | 2 | Optional | Small Integer
T42_POSTPONED | T42 Postponed Accounting | 2 | Optional | Small Integer
T42_RATE | T42 Rate | 8 | Optional | Double
T42_RELATED | T42 Euro Purchase Related | 1 | Optional | Byte
T42_REVERSE_CHARGE | T42 Reverse Charge | 2 | Optional | Small Integer
T43_DESCRIPTION | T43 Description | 60 | Optional | String
T43_EUROPURCHASE | T43 Euro Purchase | 1 | Optional | Byte
T43_EUROSALE | T43 Euro Sale | 1 | Optional | Byte
T43_INUSE | T43 In Use | 1 | Optional | Byte
T43_OVERRIDE_LINKED | T43 Override Linked Rate | 2 | Optional | Small Integer
T43_POSTPONED | T43 Postponed Accounting | 2 | Optional | Small Integer
T43_RATE | T43 Rate | 8 | Optional | Double
T43_RELATED | T43 Euro Purchase Related | 1 | Optional | Byte
T43_REVERSE_CHARGE | T43 Reverse Charge | 2 | Optional | Small Integer
T44_DESCRIPTION | T44 Description | 60 | Optional | String
T44_EUROPURCHASE | T44 Euro Purchase | 1 | Optional | Byte
T44_EUROSALE | T44 Euro Sale | 1 | Optional | Byte
T44_INUSE | T44 In Use | 1 | Optional | Byte
T44_OVERRIDE_LINKED | T44 Override Linked Rate | 2 | Optional | Small Integer
T44_POSTPONED | T44 Postponed Accounting | 2 | Optional | Small Integer
T44_RATE | T44 Rate | 8 | Optional | Double
T44_RELATED | T44 Euro Purchase Related | 1 | Optional | Byte
T44_REVERSE_CHARGE | T44 Reverse Charge | 2 | Optional | Small Integer
T45_DESCRIPTION | T45 Description | 60 | Optional | String
T45_EUROPURCHASE | T45 Euro Purchase | 1 | Optional | Byte
T45_EUROSALE | T45 Euro Sale | 1 | Optional | Byte
T45_INUSE | T45 In Use | 1 | Optional | Byte
T45_OVERRIDE_LINKED | T45 Override Linked Rate | 2 | Optional | Small Integer
T45_POSTPONED | T45 Postponed Accounting | 2 | Optional | Small Integer
T45_RATE | T45 Rate | 8 | Optional | Double
T45_RELATED | T45 Euro Purchase Related | 1 | Optional | Byte
T45_REVERSE_CHARGE | T45 Reverse Charge | 2 | Optional | Small Integer
T46_DESCRIPTION | T46 Description | 60 | Optional | String
T46_EUROPURCHASE | T46 Euro Purchase | 1 | Optional | Byte
T46_EUROSALE | T46 Euro Sale | 1 | Optional | Byte
T46_INUSE | T46 In Use | 1 | Optional | Byte
T46_OVERRIDE_LINKED | T46 Override Linked Rate | 2 | Optional | Small Integer
T46_POSTPONED | T46 Postponed Accounting | 2 | Optional | Small Integer
T46_RATE | T46 Rate | 8 | Optional | Double
T46_RELATED | T46 Euro Purchase Related | 1 | Optional | Byte
T46_REVERSE_CHARGE | T46 Reverse Charge | 2 | Optional | Small Integer
T47_DESCRIPTION | T47 Description | 60 | Optional | String
T47_EUROPURCHASE | T47 Euro Purchase | 1 | Optional | Byte
T47_EUROSALE | T47 Euro Sale | 1 | Optional | Byte
T47_INUSE | T47 In Use | 1 | Optional | Byte
T47_OVERRIDE_LINKED | T47 Override Linked Rate | 2 | Optional | Small Integer
T47_POSTPONED | T47 Postponed Accounting | 2 | Optional | Small Integer
T47_RATE | T47 Rate | 8 | Optional | Double
T47_RELATED | T47 Euro Purchase Related | 1 | Optional | Byte
T47_REVERSE_CHARGE | T47 Reverse Charge | 2 | Optional | Small Integer
T48_DESCRIPTION | T48 Description | 60 | Optional | String
T48_EUROPURCHASE | T48 Euro Purchase | 1 | Optional | Byte
T48_EUROSALE | T48 Euro Sale | 1 | Optional | Byte
T48_INUSE | T48 In Use | 1 | Optional | Byte
T48_OVERRIDE_LINKED | T48 Override Linked Rate | 2 | Optional | Small Integer
T48_POSTPONED | T48 Postponed Accounting | 2 | Optional | Small Integer
T48_RATE | T48 Rate | 8 | Optional | Double
T48_RELATED | T48 Euro Purchase Related | 1 | Optional | Byte
T48_REVERSE_CHARGE | T48 Reverse Charge | 2 | Optional | Small Integer
T49_DESCRIPTION | T49 Description | 60 | Optional | String
T49_EUROPURCHASE | T49 Euro Purchase | 1 | Optional | Byte
T49_EUROSALE | T49 Euro Sale | 1 | Optional | Byte
T49_INUSE | T49 In Use | 1 | Optional | Byte
T49_OVERRIDE_LINKED | T49 Override Linked Rate | 2 | Optional | Small Integer
T49_POSTPONED | T49 Postponed Accounting | 2 | Optional | Small Integer
T49_RATE | T49 Rate | 8 | Optional | Double
T49_RELATED | T49 Euro Purchase Related | 1 | Optional | Byte
T49_REVERSE_CHARGE | T49 Reverse Charge | 2 | Optional | Small Integer
T4_DESCRIPTION | T4 Description | 60 | Optional | String
T4_EUROPURCHASE | T4 Euro Purchase | 1 | Optional | Byte
T4_EUROSALE | T4 Euro Sale | 1 | Optional | Byte
T4_INUSE | T4 In Use | 1 | Optional | Byte
T4_OVERRIDE_LINKED | T4 Override Linked Rate | 2 | Optional | Small Integer
T4_POSTPONED | T4 Postponed Accounting | 2 | Optional | Small Integer
T4_RATE | T4 Rate | 8 | Optional | Double
T4_RELATED | T4 Euro Purchase Related | 1 | Optional | Byte
T4_REVERSE_CHARGE | T4 Reverse Charge | 2 | Optional | Small Integer
T50_DESCRIPTION | T50 Description | 60 | Optional | String
T50_EUROPURCHASE | T50 Euro Purchase | 1 | Optional | Byte
T50_EUROSALE | T50 Euro Sale | 1 | Optional | Byte
T50_INUSE | T50 In Use | 1 | Optional | Byte
T50_OVERRIDE_LINKED | T50 Override Linked Rate | 2 | Optional | Small Integer
T50_POSTPONED | T50 Postponed Accounting | 2 | Optional | Small Integer
T50_RATE | T50 Rate | 8 | Optional | Double
T50_RELATED | T50 Euro Purchase Related | 1 | Optional | Byte
T50_REVERSE_CHARGE | T50 Reverse Charge | 2 | Optional | Small Integer
T51_DESCRIPTION | T51 Description | 60 | Optional | String
T51_EUROPURCHASE | T51 Euro Purchase | 1 | Optional | Byte
T51_EUROSALE | T51 Euro Sale | 1 | Optional | Byte
T51_INUSE | T51 In Use | 1 | Optional | Byte
T51_OVERRIDE_LINKED | T51 Override Linked Rate | 2 | Optional | Small Integer
T51_POSTPONED | T51 Postponed Accounting | 2 | Optional | Small Integer
T51_RATE | T51 Rate | 8 | Optional | Double
T51_RELATED | T51 Euro Purchase Related | 1 | Optional | Byte
T51_REVERSE_CHARGE | T51 Reverse Charge | 2 | Optional | Small Integer
T52_DESCRIPTION | T52 Description | 60 | Optional | String
T52_EUROPURCHASE | T52 Euro Purchase | 1 | Optional | Byte
T52_EUROSALE | T52 Euro Sale | 1 | Optional | Byte
T52_INUSE | T52 In Use | 1 | Optional | Byte
T52_OVERRIDE_LINKED | T52 Override Linked Rate | 2 | Optional | Small Integer
T52_POSTPONED | T52 Postponed Accounting | 2 | Optional | Small Integer
T52_RATE | T52 Rate | 8 | Optional | Double
T52_RELATED | T52 Euro Purchase Related | 1 | Optional | Byte
T52_REVERSE_CHARGE | T52 Reverse Charge | 2 | Optional | Small Integer
T53_DESCRIPTION | T53 Description | 60 | Optional | String
T53_EUROPURCHASE | T53 Euro Purchase | 1 | Optional | Byte
T53_EUROSALE | T53 Euro Sale | 1 | Optional | Byte
T53_INUSE | T53 In Use | 1 | Optional | Byte
T53_OVERRIDE_LINKED | T53 Override Linked Rate | 2 | Optional | Small Integer
T53_POSTPONED | T53 Postponed Accounting | 2 | Optional | Small Integer
T53_RATE | T53 Rate | 8 | Optional | Double
T53_RELATED | T53 Euro Purchase Related | 1 | Optional | Byte
T53_REVERSE_CHARGE | T53 Reverse Charge | 2 | Optional | Small Integer
T54_DESCRIPTION | T54 Description | 60 | Optional | String
T54_EUROPURCHASE | T54 Euro Purchase | 1 | Optional | Byte
T54_EUROSALE | T54 Euro Sale | 1 | Optional | Byte
T54_INUSE | T54 In Use | 1 | Optional | Byte
T54_OVERRIDE_LINKED | T54 Override Linked Rate | 2 | Optional | Small Integer
T54_POSTPONED | T54 Postponed Accounting | 2 | Optional | Small Integer
T54_RATE | T54 Rate | 8 | Optional | Double
T54_RELATED | T54 Euro Purchase Related | 1 | Optional | Byte
T54_REVERSE_CHARGE | T54 Reverse Charge | 2 | Optional | Small Integer
T55_DESCRIPTION | T55 Description | 60 | Optional | String
T55_EUROPURCHASE | T55 Euro Purchase | 1 | Optional | Byte
T55_EUROSALE | T55 Euro Sale | 1 | Optional | Byte
T55_INUSE | T55 In Use | 1 | Optional | Byte
T55_OVERRIDE_LINKED | T55 Override Linked Rate | 2 | Optional | Small Integer
T55_POSTPONED | T55 Postponed Accounting | 2 | Optional | Small Integer
T55_RATE | T55 Rate | 8 | Optional | Double
T55_RELATED | T55 Euro Purchase Related | 1 | Optional | Byte
T55_REVERSE_CHARGE | T55 Reverse Charge | 2 | Optional | Small Integer
T56_DESCRIPTION | T56 Description | 60 | Optional | String
T56_EUROPURCHASE | T56 Euro Purchase | 1 | Optional | Byte
T56_EUROSALE | T56 Euro Sale | 1 | Optional | Byte
T56_INUSE | T56 In Use | 1 | Optional | Byte
T56_OVERRIDE_LINKED | T56 Override Linked Rate | 2 | Optional | Small Integer
T56_POSTPONED | T56 Postponed Accounting | 2 | Optional | Small Integer
T56_RATE | T56 Rate | 8 | Optional | Double
T56_RELATED | T56 Euro Purchase Related | 1 | Optional | Byte
T56_REVERSE_CHARGE | T56 Reverse Charge | 2 | Optional | Small Integer
T57_DESCRIPTION | T57 Description | 60 | Optional | String
T57_EUROPURCHASE | T57 Euro Purchase | 1 | Optional | Byte
T57_EUROSALE | T57 Euro Sale | 1 | Optional | Byte
T57_INUSE | T57 In Use | 1 | Optional | Byte
T57_OVERRIDE_LINKED | T57 Override Linked Rate | 2 | Optional | Small Integer
T57_POSTPONED | T57 Postponed Accounting | 2 | Optional | Small Integer
T57_RATE | T57 Rate | 8 | Optional | Double
T57_RELATED | T57 Euro Purchase Related | 1 | Optional | Byte
T57_REVERSE_CHARGE | T57 Reverse Charge | 2 | Optional | Small Integer
T58_DESCRIPTION | T58 Description | 60 | Optional | String
T58_EUROPURCHASE | T58 Euro Purchase | 1 | Optional | Byte
T58_EUROSALE | T58 Euro Sale | 1 | Optional | Byte
T58_INUSE | T58 In Use | 1 | Optional | Byte
T58_OVERRIDE_LINKED | T58 Override Linked Rate | 2 | Optional | Small Integer
T58_POSTPONED | T58 Postponed Accounting | 2 | Optional | Small Integer
T58_RATE | T58 Rate | 8 | Optional | Double
T58_RELATED | T58 Euro Purchase Related | 1 | Optional | Byte
T58_REVERSE_CHARGE | T58 Reverse Charge | 2 | Optional | Small Integer
T59_DESCRIPTION | T59 Description | 60 | Optional | String
T59_EUROPURCHASE | T59 Euro Purchase | 1 | Optional | Byte
T59_EUROSALE | T59 Euro Sale | 1 | Optional | Byte
T59_INUSE | T59 In Use | 1 | Optional | Byte
T59_OVERRIDE_LINKED | T59 Override Linked Rate | 2 | Optional | Small Integer
T59_POSTPONED | T59 Postponed Accounting | 2 | Optional | Small Integer
T59_RATE | T59 Rate | 8 | Optional | Double
T59_RELATED | T59 Euro Purchase Related | 1 | Optional | Byte
T59_REVERSE_CHARGE | T59 Reverse Charge | 2 | Optional | Small Integer
T5_DESCRIPTION | T5 Description | 60 | Optional | String
T5_EUROPURCHASE | T5 Euro Purchase | 1 | Optional | Byte
T5_EUROSALE | T5 Euro Sale | 1 | Optional | Byte
T5_INUSE | T5 In Use | 1 | Optional | Byte
T5_OVERRIDE_LINKED | T5 Override Linked Rate | 2 | Optional | Small Integer
T5_POSTPONED | T5 Postponed Accounting | 2 | Optional | Small Integer
T5_RATE | T5 Rate | 8 | Optional | Double
T5_RELATED | T5 Euro Purchase Related | 1 | Optional | Byte
T5_REVERSE_CHARGE | T5 Reverse Charge | 2 | Optional | Small Integer
T60_DESCRIPTION | T60 Description | 60 | Optional | String
T60_EUROPURCHASE | T60 Euro Purchase | 1 | Optional | Byte
T60_EUROSALE | T60 Euro Sale | 1 | Optional | Byte
T60_INUSE | T60 In Use | 1 | Optional | Byte
T60_OVERRIDE_LINKED | T60 Override Linked Rate | 2 | Optional | Small Integer
T60_POSTPONED | T60 Postponed Accounting | 2 | Optional | Small Integer
T60_RATE | T60 Rate | 8 | Optional | Double
T60_RELATED | T60 Euro Purchase Related | 1 | Optional | Byte
T60_REVERSE_CHARGE | T60 Reverse Charge | 2 | Optional | Small Integer
T61_DESCRIPTION | T61 Description | 60 | Optional | String
T61_EUROPURCHASE | T61 Euro Purchase | 1 | Optional | Byte
T61_EUROSALE | T61 Euro Sale | 1 | Optional | Byte
T61_INUSE | T61 In Use | 1 | Optional | Byte
T61_OVERRIDE_LINKED | T61 Override Linked Rate | 2 | Optional | Small Integer
T61_POSTPONED | T61 Postponed Accounting | 2 | Optional | Small Integer
T61_RATE | T61 Rate | 8 | Optional | Double
T61_RELATED | T61 Euro Purchase Related | 1 | Optional | Byte
T61_REVERSE_CHARGE | T61 Reverse Charge | 2 | Optional | Small Integer
T62_DESCRIPTION | T62 Description | 60 | Optional | String
T62_EUROPURCHASE | T62 Euro Purchase | 1 | Optional | Byte
T62_EUROSALE | T62 Euro Sale | 1 | Optional | Byte
T62_INUSE | T62 In Use | 1 | Optional | Byte
T62_OVERRIDE_LINKED | T62 Override Linked Rate | 2 | Optional | Small Integer
T62_POSTPONED | T62 Postponed Accounting | 2 | Optional | Small Integer
T62_RATE | T62 Rate | 8 | Optional | Double
T62_RELATED | T62 Euro Purchase Related | 1 | Optional | Byte
T62_REVERSE_CHARGE | T62 Reverse Charge | 2 | Optional | Small Integer
T63_DESCRIPTION | T63 Description | 60 | Optional | String
T63_EUROPURCHASE | T63 Euro Purchase | 1 | Optional | Byte
T63_EUROSALE | T63 Euro Sale | 1 | Optional | Byte
T63_INUSE | T63 In Use | 1 | Optional | Byte
T63_OVERRIDE_LINKED | T63 Override Linked Rate | 2 | Optional | Small Integer
T63_POSTPONED | T63 Postponed Accounting | 2 | Optional | Small Integer
T63_RATE | T63 Rate | 8 | Optional | Double
T63_RELATED | T63 Euro Purchase Related | 1 | Optional | Byte
T63_REVERSE_CHARGE | T63 Reverse Charge | 2 | Optional | Small Integer
T64_DESCRIPTION | T64 Description | 60 | Optional | String
T64_EUROPURCHASE | T64 Euro Purchase | 1 | Optional | Byte
T64_EUROSALE | T64 Euro Sale | 1 | Optional | Byte
T64_INUSE | T64 In Use | 1 | Optional | Byte
T64_OVERRIDE_LINKED | T64 Override Linked Rate | 2 | Optional | Small Integer
T64_POSTPONED | T64 Postponed Accounting | 2 | Optional | Small Integer
T64_RATE | T64 Rate | 8 | Optional | Double
T64_RELATED | T64 Euro Purchase Related | 1 | Optional | Byte
T64_REVERSE_CHARGE | T64 Reverse Charge | 2 | Optional | Small Integer
T65_DESCRIPTION | T65 Description | 60 | Optional | String
T65_EUROPURCHASE | T65 Euro Purchase | 1 | Optional | Byte
T65_EUROSALE | T65 Euro Sale | 1 | Optional | Byte
T65_INUSE | T65 In Use | 1 | Optional | Byte
T64_OVERRIDE_LINKED | T64 Override Linked Rate | 2 | Optional | Small Integer
T64_POSTPONED | T64 Postponed Accounting | 2 | Optional | Small Integer
T65_RATE | T65 Rate | 8 | Optional | Double
T65_RELATED | T65 Euro Purchase Related | 1 | Optional | Byte
T65_REVERSE_CHARGE | T65 Reverse Charge | 2 | Optional | Small Integer
T66_DESCRIPTION | T66 Description | 60 | Optional | String
T66_EUROPURCHASE | T66 Euro Purchase | 1 | Optional | Byte
T66_EUROSALE | T66 Euro Sale | 1 | Optional | Byte
T66_INUSE | T66 In Use | 1 | Optional | Byte
T65_OVERRIDE_LINKED | T65 Override Linked Rate | 2 | Optional | Small Integer
T65_POSTPONED | T65 Postponed Accounting | 2 | Optional | Small Integer
T66_RATE | T66 Rate | 8 | Optional | Double
T66_RELATED | T66 Euro Purchase Related | 1 | Optional | Byte
T66_REVERSE_CHARGE | T66 Reverse Charge | 2 | Optional | Small Integer
T67_DESCRIPTION | T67 Description | 60 | Optional | String
T67_EUROPURCHASE | T67 Euro Purchase | 1 | Optional | Byte
T67_EUROSALE | T67 Euro Sale | 1 | Optional | Byte
T67_INUSE | T67 In Use | 1 | Optional | Byte
T67_OVERRIDE_LINKED | T67 Override Linked Rate | 2 | Optional | Small Integer
T67_POSTPONED | T67 Postponed Accounting | 2 | Optional | Small Integer
T67_RATE | T67 Rate | 8 | Optional | Double
T67_RELATED | T67 Euro Purchase Related | 1 | Optional | Byte
T67_REVERSE_CHARGE | T67 Reverse Charge | 2 | Optional | Small Integer
T68_DESCRIPTION | T0 Description | 60 | Optional | String
T68_EUROPURCHASE | T68 Euro Purchase | 1 | Optional | Byte
T68_EUROSALE | T68 Euro Sale | 1 | Optional | Byte
T68_INUSE | T68 In Use | 1 | Optional | Byte
T68_OVERRIDE_LINKED | T68 Override Linked Rate | 2 | Optional | Small Integer
T68_POSTPONED | T68 Postponed Accounting | 2 | Optional | Small Integer
T68_RATE | T68 Rate | 8 | Optional | Double
T68_RELATED | T68 Euro Purchase Related | 1 | Optional | Byte
T68_REVERSE_CHARGE | T68 Reverse Charge | 2 | Optional | Small Integer
T69_DESCRIPTION | T69 Description | 60 | Optional | String
T69_EUROPURCHASE | T69 Euro Purchase | 1 | Optional | Byte
T69_EUROSALE | T69 Euro Sale | 1 | Optional | Byte
T69_INUSE | T69 In Use | 1 | Optional | Byte
T69_OVERRIDE_LINKED | T69 Override Linked Rate | 2 | Optional | Small Integer
T69_POSTPONED | T69 Postponed Accounting | 2 | Optional | Small Integer
T69_RATE | T69 Rate | 8 | Optional | Double
T69_RELATED | T69 Euro Purchase Related | 1 | Optional | Byte
T69_REVERSE_CHARGE | T69 Reverse Charge | 2 | Optional | Small Integer
T6_DESCRIPTION | T6 Description | 60 | Optional | String
T6_EUROPURCHASE | T6 Euro Purchase | 1 | Optional | Byte
T6_EUROSALE | T6 Euro Sale | 1 | Optional | Byte
T6_INUSE | T6 In Use | 1 | Optional | Byte
T6_OVERRIDE_LINKED | T6 Override Linked Rate | 2 | Optional | Small Integer
T6_POSTPONED | T6 Postponed Accounting | 2 | Optional | Small Integer
T6_RATE | T6 Rate | 8 | Optional | Double
T6_RELATED | T6 Euro Purchase Related | 1 | Optional | Byte
T6_REVERSE_CHARGE | T6 Reverse Charge | 2 | Optional | Small Integer
T70_DESCRIPTION | T70 Description | 60 | Optional | String
T70_EUROPURCHASE | T70 Euro Purchase | 1 | Optional | Byte
T70_EUROSALE | T70 Euro Sale | 1 | Optional | Byte
T70_INUSE | T70 In Use | 1 | Optional | Byte
T70_OVERRIDE_LINKED | T70 Override Linked Rate | 2 | Optional | Small Integer
T70_POSTPONED | T70 Postponed Accounting | 2 | Optional | Small Integer
T70_RATE | T70 Rate | 8 | Optional | Double
T70_RELATED | T70 Euro Purchase Related | 1 | Optional | Byte
T70_REVERSE_CHARGE | T70 Reverse Charge | 2 | Optional | Small Integer
T71_DESCRIPTION | T71 Description | 60 | Optional | String
T71_EUROPURCHASE | T71 Euro Purchase | 1 | Optional | Byte
T71_EUROSALE | T71 Euro Sale | 1 | Optional | Byte
T71_INUSE | T71 In Use | 1 | Optional | Byte
T71_OVERRIDE_LINKED | T71 Override Linked Rate | 2 | Optional | Small Integer
T71_POSTPONED | T71 Postponed Accounting | 2 | Optional | Small Integer
T71_RATE | T71 Rate | 8 | Optional | Double
T71_RELATED | T71 Euro Purchase Related | 1 | Optional | Byte
T71_REVERSE_CHARGE | T71 Reverse Charge | 2 | Optional | Small Integer
T72_DESCRIPTION | T72 Description | 60 | Optional | String
T72_EUROPURCHASE | T72 Euro Purchase | 1 | Optional | Byte
T72_EUROSALE | T72 Euro Sale | 1 | Optional | Byte
T72_INUSE | T72 In Use | 1 | Optional | Byte
T72_OVERRIDE_LINKED | T72 Override Linked Rate | 2 | Optional | Small Integer
T72_POSTPONED | T72 Postponed Accounting | 2 | Optional | Small Integer
T72_RATE | T72 Rate | 8 | Optional | Double
T72_RELATED | T72 Euro Purchase Related | 1 | Optional | Byte
T72_REVERSE_CHARGE | T72 Reverse Charge | 2 | Optional | Small Integer
T73_DESCRIPTION | T73 Description | 60 | Optional | String
T73_EUROPURCHASE | T73 Euro Purchase | 1 | Optional | Byte
T73_EUROSALE | T73 Euro Sale | 1 | Optional | Byte
T73_INUSE | T73 In Use | 1 | Optional | Byte
T73_OVERRIDE_LINKED | T73 Override Linked Rate | 2 | Optional | Small Integer
T73_POSTPONED | T73 Postponed Accounting | 2 | Optional | Small Integer
T73_RATE | T73 Rate | 8 | Optional | Double
T73_RELATED | T73 Euro Purchase Related | 1 | Optional | Byte
T73_REVERSE_CHARGE | T73 Reverse Charge | 2 | Optional | Small Integer
T74_DESCRIPTION | T74 Description | 60 | Optional | String
T74_EUROPURCHASE | T74 Euro Purchase | 1 | Optional | Byte
T74_EUROSALE | T74 Euro Sale | 1 | Optional | Byte
T74_INUSE | T74 In Use | 1 | Optional | Byte
T74_OVERRIDE_LINKED | T74 Override Linked Rate | 2 | Optional | Small Integer
T74_POSTPONED | T74 Postponed Accounting | 2 | Optional | Small Integer
T74_RATE | T74 Rate | 8 | Optional | Double
T74_RELATED | T74 Euro Purchase Related | 1 | Optional | Byte
T74_REVERSE_CHARGE | T74 Reverse Charge | 2 | Optional | Small Integer
T75_DESCRIPTION | T75 Description | 60 | Optional | String
T75_EUROPURCHASE | T75 Euro Purchase | 1 | Optional | Byte
T75_EUROSALE | T75 Euro Sale | 1 | Optional | Byte
T75_INUSE | T75 In Use | 1 | Optional | Byte
T75_OVERRIDE_LINKED | T75 Override Linked Rate | 2 | Optional | Small Integer
T75_POSTPONED | T75 Postponed Accounting | 2 | Optional | Small Integer
T75_RATE | T75 Rate | 8 | Optional | Double
T75_RELATED | T75 Euro Purchase Related | 1 | Optional | Byte
T75_REVERSE_CHARGE | T75 Reverse Charge | 2 | Optional | Small Integer
T76_DESCRIPTION | T76 Description | 60 | Optional | String
T76_EUROPURCHASE | T76 Euro Purchase | 1 | Optional | Byte
T76_EUROSALE | T76 Euro Sale | 1 | Optional | Byte
T76_INUSE | T76 In Use | 1 | Optional | Byte
T76_OVERRIDE_LINKED | T76 Override Linked Rate | 2 | Optional | Small Integer
T76_POSTPONED | T76 Postponed Accounting | 2 | Optional | Small Integer
T76_RATE | T76 Rate | 8 | Optional | Double
T76_RELATED | T76 Euro Purchase Related | 1 | Optional | Byte
T76_REVERSE_CHARGE | T76 Reverse Charge | 2 | Optional | Small Integer
T77_DESCRIPTION | T77 Description | 60 | Optional | String
T77_EUROPURCHASE | T77 Euro Purchase | 1 | Optional | Byte
T77_EUROSALE | T77 Euro Sale | 1 | Optional | Byte
T77_INUSE | T77 In Use | 1 | Optional | Byte
T77_OVERRIDE_LINKED | T77 Override Linked Rate | 2 | Optional | Small Integer
T77_POSTPONED | T77 Postponed Accounting | 2 | Optional | Small Integer
T77_RATE | T77 Rate | 8 | Optional | Double
T77_RELATED | T77 Euro Purchase Related | 1 | Optional | Byte
T77_REVERSE_CHARGE | T77 Reverse Charge | 2 | Optional | Small Integer
T78_DESCRIPTION | T78 Description | 60 | Optional | String
T78_EUROPURCHASE | T78 Euro Purchase | 1 | Optional | Byte
T78_EUROSALE | T78 Euro Sale | 1 | Optional | Byte
T78_INUSE | T78 In Use | 1 | Optional | Byte
T78_OVERRIDE_LINKED | T78 Override Linked Rate | 2 | Optional | Small Integer
T78_POSTPONED | T78 Postponed Accounting | 2 | Optional | Small Integer
T78_RATE | T78 Rate | 8 | Optional | Double
T78_RELATED | T78 Euro Purchase Related | 1 | Optional | Byte
T78_REVERSE_CHARGE | T78 Reverse Charge | 2 | Optional | Small Integer
T79_DESCRIPTION | T79 Description | 60 | Optional | String
T79_EUROPURCHASE | T79 Euro Purchase | 1 | Optional | Byte
T79_EUROSALE | T79 Euro Sale | 1 | Optional | Byte
T79_INUSE | T79 In Use | 1 | Optional | Byte
T79_OVERRIDE_LINKED | T79 Override Linked Rate | 2 | Optional | Small Integer
T79_POSTPONED | T79 Postponed Accounting | 2 | Optional | Small Integer
T79_RATE | T79 Rate | 8 | Optional | Double
T79_RELATED | T79 Euro Purchase Related | 1 | Optional | Byte
T79_REVERSE_CHARGE | T79 Reverse Charge | 2 | Optional | Small Integer
T7_DESCRIPTION | T7 Description | 60 | Optional | String
T7_EUROPURCHASE | T7 Euro Purchase | 1 | Optional | Byte
T7_EUROSALE | T7 Euro Sale | 1 | Optional | Byte
T7_INUSE | T7 In Use | 1 | Optional | Byte
T7_OVERRIDE_LINKED | T7 Override Linked Rate | 2 | Optional | Small Integer
T7_POSTPONED | T7 Postponed Accounting | 2 | Optional | Small Integer
T7_RATE | T7 Rate | 8 | Optional | Double
T7_RELATED | T7 Euro Purchase Related | 1 | Optional | Byte
T7_REVERSE_CHARGE | T7 Reverse Charge | 2 | Optional | Small Integer
T80_DESCRIPTION | T80 Description | 60 | Optional | String
T80_EUROPURCHASE | T80 Euro Purchase | 1 | Optional | Byte
T80_EUROSALE | T80 Euro Sale | 1 | Optional | Byte
T80_INUSE | T80 In Use | 1 | Optional | Byte
T80_OVERRIDE_LINKED | T80 Override Linked Rate | 2 | Optional | Small Integer
T80_POSTPONED | T80 Postponed Accounting | 2 | Optional | Small Integer
T80_RATE | T80 Rate | 8 | Optional | Double
T80_RELATED | T80 Euro Purchase Related | 1 | Optional | Byte
T80_REVERSE_CHARGE | T80 Reverse Charge | 2 | Optional | Small Integer
T81_DESCRIPTION | T81 Description | 60 | Optional | String
T81_EUROPURCHASE | T81 Euro Purchase | 1 | Optional | Byte
T81_EUROSALE | T81 Euro Sale | 1 | Optional | Byte
T81_INUSE | T81 In Use | 1 | Optional | Byte
T81_OVERRIDE_LINKED | T81 Override Linked Rate | 2 | Optional | Small Integer
T81_POSTPONED | T81 Postponed Accounting | 2 | Optional | Small Integer
T81_RATE | T81 Rate | 8 | Optional | Double
T81_RELATED | T81 Euro Purchase Related | 1 | Optional | Byte
T81_REVERSE_CHARGE | T81 Reverse Charge | 2 | Optional | Small Integer
T82_DESCRIPTION | T82 Description | 60 | Optional | String
T82_EUROPURCHASE | T82 Euro Purchase | 1 | Optional | Byte
T82_EUROSALE | T82 Euro Sale | 1 | Optional | Byte
T82_INUSE | T82 In Use | 1 | Optional | Byte
T82_OVERRIDE_LINKED | T82 Override Linked Rate | 2 | Optional | Small Integer
T82_POSTPONED | T82 Postponed Accounting | 2 | Optional | Small Integer
T82_RATE | T82 Rate | 8 | Optional | Double
T82_RELATED | T82 Euro Purchase Related | 1 | Optional | Byte
T82_REVERSE_CHARGE | T82 Reverse Charge | 2 | Optional | Small Integer
T83_DESCRIPTION | T83 Description | 60 | Optional | String
T83_EUROPURCHASE | T83 Euro Purchase | 1 | Optional | Byte
T83_EUROSALE | T83 Euro Sale | 1 | Optional | Byte
T83_INUSE | T83 In Use | 1 | Optional | Byte
T83_OVERRIDE_LINKED | T83 Override Linked Rate | 2 | Optional | Small Integer
T83_POSTPONED | T83 Postponed Accounting | 2 | Optional | Small Integer
T83_RATE | T83 Rate | 8 | Optional | Double
T83_RELATED | T83 Euro Purchase Related | 1 | Optional | Byte
T83_REVERSE_CHARGE | T83 Reverse Charge | 2 | Optional | Small Integer
T84_DESCRIPTION | T84 Description | 60 | Optional | String
T84_EUROPURCHASE | T84 Euro Purchase | 1 | Optional | Byte
T84_EUROSALE | T84 Euro Sale | 1 | Optional | Byte
T84_INUSE | T84 In Use | 1 | Optional | Byte
T84_OVERRIDE_LINKED | T84 Override Linked Rate | 2 | Optional | Small Integer
T84_POSTPONED | T84 Postponed Accounting | 2 | Optional | Small Integer
T84_RATE | T84 Rate | 8 | Optional | Double
T84_RELATED | T84 Euro Purchase Related | 1 | Optional | Byte
T84_REVERSE_CHARGE | T84 Reverse Charge | 2 | Optional | Small Integer
T85_DESCRIPTION | T85 Description | 60 | Optional | String
T85_EUROPURCHASE | T85 Euro Purchase | 1 | Optional | Byte
T85_EUROSALE | T85 Euro Sale | 1 | Optional | Byte
T85_INUSE | T85 In Use | 1 | Optional | Byte
T85_OVERRIDE_LINKED | T85 Override Linked Rate | 2 | Optional | Small Integer
T85_POSTPONED | T85 Postponed Accounting | 2 | Optional | Small Integer
T85_RATE | T85 Rate | 8 | Optional | Double
T85_RELATED | T85 Euro Purchase Related | 1 | Optional | Byte
T85_REVERSE_CHARGE | T85 Reverse Charge | 2 | Optional | Small Integer
T86_DESCRIPTION | T86 Description | 60 | Optional | String
T86_EUROPURCHASE | T86 Euro Purchase | 1 | Optional | Byte
T86_EUROSALE | T86 Euro Sale | 1 | Optional | Byte
T86_INUSE | T86 In Use | 1 | Optional | Byte
T87_OVERRIDE_LINKED | T87 Override Linked Rate | 2 | Optional | Small Integer
T87_POSTPONED | T87 Postponed Accounting | 2 | Optional | Small Integer
T86_RATE | T86 Rate | 8 | Optional | Double
T86_RELATED | T86 Euro Purchase Related | 1 | Optional | Byte
T86_REVERSE_CHARGE | T86 Reverse Charge | 2 | Optional | Small Integer
T87_DESCRIPTION | T87 Description | 60 | Optional | String
T87_EUROPURCHASE | T87 Euro Purchase | 1 | Optional | Byte
T87_EUROSALE | T87 Euro Sale | 1 | Optional | Byte
T87_INUSE | T87 In Use | 1 | Optional | Byte
T87_OVERRIDE_LINKED | T87 Override Linked Rate | 2 | Optional | Small Integer
T87_POSTPONED | T87 Postponed Accounting | 2 | Optional | Small Integer
T87_RATE | T87 Rate | 8 | Optional | Double
T87_RELATED | T87 Euro Purchase Related | 1 | Optional | Byte
T87_REVERSE_CHARGE | T87 Reverse Charge | 2 | Optional | Small Integer
T88_DESCRIPTION | T88 Description | 60 | Optional | String
T88_EUROPURCHASE | T88 Euro Purchase | 1 | Optional | Byte
T88_EUROSALE | T88 Euro Sale | 1 | Optional | Byte
T88_INUSE | T88 In Use | 1 | Optional | Byte
T88_OVERRIDE_LINKED | T88 Override Linked Rate | 2 | Optional | Small Integer
T88_POSTPONED | T88 Postponed Accounting | 2 | Optional | Small Integer
T88_RATE | T88 Rate | 8 | Optional | Double
T88_RELATED | T88 Euro Purchase Related | 1 | Optional | Byte
T88_REVERSE_CHARGE | T88 Reverse Charge | 2 | Optional | Small Integer
T89_DESCRIPTION | T89 Description | 60 | Optional | String
T89_EUROPURCHASE | T89 Euro Purchase | 1 | Optional | Byte
T89_EUROSALE | T89 Euro Sale | 1 | Optional | Byte
T89_INUSE | T89 In Use | 1 | Optional | Byte
T89_OVERRIDE_LINKED | T89 Override Linked Rate | 2 | Optional | Small Integer
T89_POSTPONED | T89 Postponed Accounting | 2 | Optional | Small Integer
T89_RATE | T89 Rate | 8 | Optional | Double
T89_RELATED | T89 Euro Purchase Related | 1 | Optional | Byte
T89_REVERSE_CHARGE | T89 Reverse Charge | 2 | Optional | Small Integer
T8_DESCRIPTION | T8 Description | 60 | Optional | String
T8_EUROPURCHASE | T8 Euro Purchase | 1 | Optional | Byte
T8_EUROSALE | T8 Euro Sale | 1 | Optional | Byte
T8_INUSE | T8 In Use | 1 | Optional | Byte
T8_OVERRIDE_LINKED | T8 Override Linked Rate | 2 | Optional | Small Integer
T8_POSTPONED | T8 Postponed Accounting | 2 | Optional | Small Integer
T8_RATE | T8 Rate | 8 | Optional | Double
T8_RELATED | T8 Euro Purchase Related | 1 | Optional | Byte
T8_REVERSE_CHARGE | T8 Reverse Charge | 2 | Optional | Small Integer
T90_DESCRIPTION | T90 Description | 60 | Optional | String
T90_EUROPURCHASE | T90 Euro Purchase | 1 | Optional | Byte
T90_EUROSALE | T90 Euro Sale | 1 | Optional | Byte
T90_INUSE | T90 In Use | 1 | Optional | Byte
T90_OVERRIDE_LINKED | T90 Override Linked Rate | 2 | Optional | Small Integer
T90_POSTPONED | T90 Postponed Accounting | 2 | Optional | Small Integer
T90_RATE | T90 Rate | 8 | Optional | Double
T90_RELATED | T90 Euro Purchase Related | 1 | Optional | Byte
T90_REVERSE_CHARGE | T90 Reverse Charge | 2 | Optional | Small Integer
T91_DESCRIPTION | T91 Description | 60 | Optional | String
T91_EUROPURCHASE | T91 Euro Purchase | 1 | Optional | Byte
T91_EUROSALE | T91 Euro Sale | 1 | Optional | Byte
T91_INUSE | T91 In Use | 1 | Optional | Byte
T91_OVERRIDE_LINKED | T91 Override Linked Rate | 2 | Optional | Small Integer
T91_POSTPONED | T91 Postponed Accounting | 2 | Optional | Small Integer
T91_RATE | T91 Rate | 8 | Optional | Double
T91_RELATED | T91 Euro Purchase Related | 1 | Optional | Byte
T91_REVERSE_CHARGE | T91 Reverse Charge | 2 | Optional | Small Integer
T92_DESCRIPTION | T92 Description | 60 | Optional | String
T92_EUROPURCHASE | T92 Euro Purchase | 1 | Optional | Byte
T92_EUROSALE | T92 Euro Sale | 1 | Optional | Byte
T92_INUSE | T92 In Use | 1 | Optional | Byte
T92_OVERRIDE_LINKED | T92 Override Linked Rate | 2 | Optional | Small Integer
T92_POSTPONED | T92 Postponed Accounting | 2 | Optional | Small Integer
T92_RATE | T92 Rate | 8 | Optional | Double
T92_RELATED | T92 Euro Purchase Related | 1 | Optional | Byte
T92_REVERSE_CHARGE | T92 Reverse Charge | 2 | Optional | Small Integer
T93_DESCRIPTION | T93 Description | 60 | Optional | String
T93_EUROPURCHASE | T93 Euro Purchase | 1 | Optional | Byte
T93_EUROSALE | T93 Euro Sale | 1 | Optional | Byte
T93_INUSE | T93 In Use | 1 | Optional | Byte
T93_OVERRIDE_LINKED | T93 Override Linked Rate | 2 | Optional | Small Integer
T93_POSTPONED | T93 Postponed Accounting | 2 | Optional | Small Integer
T93_RATE | T93 Rate | 8 | Optional | Double
T93_RELATED | T93 Euro Purchase Related | 1 | Optional | Byte
T93_REVERSE_CHARGE | T93 Reverse Charge | 2 | Optional | Small Integer
T94_DESCRIPTION | T94 Description | 60 | Optional | String
T94_EUROPURCHASE | T94 Euro Purchase | 1 | Optional | Byte
T94_EUROSALE | T94 Euro Sale | 1 | Optional | Byte
T94_INUSE | T94 In Use | 1 | Optional | Byte
T94_OVERRIDE_LINKED | T94 Override Linked Rate | 2 | Optional | Small Integer
T94_POSTPONED | T94 Postponed Accounting | 2 | Optional | Small Integer
T94_RATE | T94 Rate | 8 | Optional | Double
T94_RELATED | T94 Euro Purchase Related | 1 | Optional | Byte
T94_REVERSE_CHARGE | T94 Reverse Charge | 2 | Optional | Small Integer
T95_DESCRIPTION | T95 Description | 60 | Optional | String
T95_EUROPURCHASE | T95 Euro Purchase | 1 | Optional | Byte
T95_EUROSALE | T95 Euro Sale | 1 | Optional | Byte
T95_INUSE | T95 In Use | 1 | Optional | Byte
T95_OVERRIDE_LINKED | T95 Override Linked Rate | 2 | Optional | Small Integer
T95_POSTPONED | T95 Postponed Accounting | 2 | Optional | Small Integer
T95_RATE | T95 Rate | 8 | Optional | Double
T95_RELATED | T95 Euro Purchase Related | 1 | Optional | Byte
T95_REVERSE_CHARGE | T95 Reverse Charge | 2 | Optional | Small Integer
T96_DESCRIPTION | T96 Description | 60 | Optional | String
T96_EUROPURCHASE | T96 Euro Purchase | 1 | Optional | Byte
T96_EUROSALE | T96 Euro Sale | 1 | Optional | Byte
T96_INUSE | T96 In Use | 1 | Optional | Byte
T96_OVERRIDE_LINKED | T96 Override Linked Rate | 2 | Optional | Small Integer
T96_POSTPONED | T96 Postponed Accounting | 2 | Optional | Small Integer
T96_RATE | T96 Rate | 8 | Optional | Double
T96_RELATED | T96 Euro Purchase Related | 1 | Optional | Byte
T96_REVERSE_CHARGE | T96 Reverse Charge | 2 | Optional | Small Integer
T97_DESCRIPTION | T97 Description | 60 | Optional | String
T97_EUROPURCHASE | T97 Euro Purchase | 1 | Optional | Byte
T97_EUROSALE | T97 Euro Sale | 1 | Optional | Byte
T97_INUSE | T97 In Use | 1 | Optional | Byte
T97_OVERRIDE_LINKED | T97 Override Linked Rate | 2 | Optional | Small Integer
T97_POSTPONED | T97 Postponed Accounting | 2 | Optional | Small Integer
T97_RATE | T97 Rate | 8 | Optional | Double
T97_RELATED | T97 Euro Purchase Related | 1 | Optional | Byte
T97_REVERSE_CHARGE | T97 Reverse Charge | 2 | Optional | Small Integer
T98_DESCRIPTION | T98 Description | 60 | Optional | String
T98_EUROPURCHASE | T98 Euro Purchase | 1 | Optional | Byte
T98_EUROSALE | T98 Euro Sale | 1 | Optional | Byte
T98_INUSE | T98 In Use | 1 | Optional | Byte
T98_OVERRIDE_LINKED | T98 Override Linked Rate | 2 | Optional | Small Integer
T98_POSTPONED | T98 Postponed Accounting | 2 | Optional | Small Integer
T98_RATE | T98 Rate | 8 | Optional | Double
T98_RELATED | T98 Euro Purchase Related | 1 | Optional | Byte
T98_REVERSE_CHARGE | T98 Reverse Charge | 2 | Optional | Small Integer
T99_DESCRIPTION | T99 Description | 60 | Optional | String
T99_EUROPURCHASE | T99 Euro Purchase | 1 | Optional | Byte
T99_EUROSALE | T99 Euro Sale | 1 | Optional | Byte
T99_INUSE | T99 In Use | 1 | Optional | Byte
T99_OVERRIDE_LINKED | T99 Override Linked Rate | 2 | Optional | Small Integer
T99_POSTPONED | T99 Postponed Accounting | 2 | Optional | Small Integer
T99_RATE | T99 Rate | 8 | Optional | Double
T99_RELATED | T99 Euro Purchase Related | 1 | Optional | Byte
T99_REVERSE_CHARGE | T99 Reverse Charge | 2 | Optional | Small Integer
T9_DESCRIPTION | T9 Description | 60 | Optional | String
T9_EUROPURCHASE | T9 Euro Purchase | 1 | Optional | Byte
T9_EUROSALE | T9 Euro Sale | 1 | Optional | Byte
T9_INUSE | T9 In Use | 1 | Optional | Byte
T9_OVERRIDE_LINKED | T9 Override Linked Rate | 2 | Optional | Small Integer
T9_POSTPONED | T9 Postponed Accounting | 2 | Optional | Small Integer
T9_RATE | T9 Rate | 8 | Optional | Double
T9_RELATED | T9 Euro Purchase Related | 1 | Optional | Byte
T9_REVERSE_CHARGE | T9 Reverse Charge | 2 | Optional | Small Integer
UNIONOSS_NO | Union OSS Tax Control Account record number | 4 | Required | Integer
UNIQUE_NO | Last Unique Reference | 4 | Required | Integer
VATLIABILITY_NO | VAT Liability record number | 4 | Required | Integer

Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Creating a New Accrual Record
Creating a New Prepayment Record
Posting a Purchase Payment
Posting a Sales Receipt
Posting a Foreign Currency Purchase Payment
Posting a Foreign Currency Sales Receipt
Reading Tax Codes


CountryCodeData

Description

The CountryCodeData object gives access to the Country Code (COUNTRY.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional

Fields Collection

Name | Description | Length | Input | Data Type
COUNTRY_CODE | Two character country code | 2 | Required | String
COUNTRY_NAME | Name of Country | 30 | Required | String
EU_MEMBER | EU Member | 2 | Required | Small Integer
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
VAT_FORMAT | Country Vat Format | 100 | Required | String

Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Example - Add a new country code


CountryCodeIndex

Description

The CountryCodeIndex object gives access to the Country Code Index (CTRYIDX.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
COUNTRY_CODE | Country Code | 2 | Required | String
RECNO | Record number in data file | 4 | Required | Integer

Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Example - Add a new country code


CountryCodeRecord

Description

The CountryCodeRecord object gives access to the Country Codes (COUNTRY.DTA) table and the Country Code Index (CTRYIDX.DTA) table. As an SDORecord object, it encapsulates both the data and index files.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
COUNTRY_CODE | Two character country code | 2 | Required | String
COUNTRY_NAME | Name of Country | 30 | Required | String
EU_MEMBER | EU Member | 2 | Required | Small Integer
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
VAT_FORMAT | Country Vat Format | 100 | Required | String

Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Example - Add a new country code


CourierWWWData

Description

The CourierWWWData object gives access to the Courier web address (COURWWW.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
NAME | Name | 60 | Optional | String
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
SEARCH | Search | 255 | Optional | String
WWW | World Wide Web Address | 255 | Optional | String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Example - Reading CourierWWWData


CreditChargeData

Description

The CreditChargeData object gives access to the Credit Charge (FINRATES.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ADDITIONAL_RATE | Additional Rate | 8 | Optional | Double
BASE_RATE | Base Rate | 8 | Optional | Double
DATE_FROM | Date From | 2 | Optional | Date
EMPTY | Empty | 2 | Optional | Small Integer
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Example - List Credit Charge Data


CreditWWWData

Description

The CreditChargeData object gives access to the Credit Charge (FINRATES.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
NAME | Name | 60 | Optional | String
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
SEARCH | Search | 255 | Optional | String
WWW | World Wide Web Address | 255 | Optional | String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

There are currently no examples that make use of this object.


CurrencyData

Description

The CurrencyData object gives access to the Currency (CURRENCY.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
CODE | Currency Code | 3 | Optional | String
EMU_MEMBER | EMU Member | 2 | Required | Small Integer
EXCHANGE_RATE | Exchange Rate | 8 | Optional | Double
LOCKED | Locked | 2 | Optional | Small Integer
MAJOR_UNIT | Major Currency Unit | 20 | Optional | String
MINOR_UNIT | Minor Currency Unit | 20 | Optional | String
NAME | Currency Name | 30 | Optional | String
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
SYMBOL | Currency Symbol | 3 | Optional | String

Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Posting a Foreign Currency Bank Payment
Posting a Foreign Currency Bank Receipt
Posting a Foreign Currency Purchase Credit Note
Posting a Foreign Currency Purchase Invoice
Posting a Foreign Currency Purchase Payment
Posting a Foreign Currency Sales Credit Note
Posting a Foreign Currency Sales Invoice
Posting a Foreign Currency Sales Receipt
Posting a Foreign Currency Purchase Credit Note
Posting a Foreign Currency Purchase Order
Posting a Foreign Currency Sales Order


DepartmentData

Description

The DepartmentData object gives access to the Department (DEPARTM.DTA) table.

NOTE: The DEPT_REF field is the new unique identifier for the DepartmentData object. Although there is no validation with SDO either to block the creation of departments with the same reference as an existing department, or to create departments without a reference, they should be avoided at all costs as this would cause corruption within the internal index of the DepartmentData object.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
DEPT_REF | Reference User Defined | 8 | Optional | String
NAME | Department Name | 60 | Optional | String
NUMBER | Unique ID Number | 2 | AutoGenerated | Small Integer
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Reading and Editing Department Names


StockData

GDNData

Description

The GDNData object gives access to the Goods Despatched Notes (GDNDATA.DTA) table.

Applies to

Sage 50 Accounts Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Customer Account Reference | 8 | Required | String
CUSTOMER_GDN | Customer Goods Despatched Note | 20 | Required | String
GOODS_NO | Despatched Number | 4 | Required | Integer
GRN_NEXT | Next GDN | 4 | Required | Integer
GRN_PREV Previous GDN 4 Required

Integer
ITEM_NO Item Number 4 Required

Integer
ORDER_NO Order Number 4 Required

Integer
POSTED_DATE Date of Payment 2 Required

Date
PRINTED_FLAG Printed Flag 1 Optional

Byte
QTY_AMOUNT Stock Quantity Posted 8 Required

Double
QTY_BALANCE Stock Quantity Balance 8 Required

Double
QTY_ORDERED Stock Quantity Ordered 8 Required

Double
QTY_RECEIVED Stock Quantity Despatched 8 Required

Double
QTY_TO_DELIVER Stock Quantity To Despatch 8 Required

Double
RECORD_CREATE_DATE Date and time when the record was created 8 Optional

Date
RECORD_DELETED Flag denoting if the record has been deleted or not. 2 Optional

Small Integer
RECORD_MODIFY_DATE Date and time when the record was modified 8 Optional

Date
SOP_ITEM_NO Sales Order Item Number 2 Required

Small Integer
STOCK_CODE Stock Code 30 Required

String
STOCK_DESC Stock Description 120 Optional

String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object


InvoiceIndex

GDNIndex

Description

The GDNIndex object gives access to the Goods Despatched Notes index (GDNINDEX.DTA) table.

Applies to

Sage 50 Accounts Professional.

Fields Collection

Name | Description | Length | Input | Data Type
RECORD_NUMBER | Record Number in Data File | 4 | Required | Integer
REFERENCE | Unique indentifier for this Goods Delivery Note | 23 | Required | String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object


InvoiceData

GDNRecord

Description

The GDNRecord object gives access to the Goods Despatched Records (GDNDATA.DTA) table and the GDN Index (GDNINDEX.DTA) table. As an SDORecord object, it encapsulates both the data and index files.

Applies to

Sage 50 Accounts Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Customer Account Reference | 8 | Required | String
CUSTOMER_GDN | Customer Goods Despatched Note | 20 | Required | String
GOODS_NO | Despatched Number | 4 | Required | Integer
GRN_NEXT | Next GDN | 4 | Required | Integer
GRN_PREV Previous GDN 4 Required

Integer
ITEM_NO Item Number 4 Required

Integer
ORDER_NO Order Number 4 Required

Integer
POSTED_DATE Date of Payment 2 Required

Date
PRINTED_FLAG Printed Flag 1 Optional

Byte
QTY_AMOUNT Stock Quantity Posted 8 Required

Double
QTY_BALANCE Stock Quantity Balance 8 Required

Double
QTY_ORDERED Stock Quantity Ordered 8 Required

Double
QTY_RECEIVED Stock Quantity Despatched 8 Required

Double
QTY_TO_DELIVER Stock Quantity To Despatch 8 Required

Double
RECORD_CREATE_DATE Date and time when the record was created 8 Optional

Date
RECORD_DELETED Flag denoting if the record has been deleted or not. 2 Optional

Small Integer
RECORD_MODIFY_DATE Date and time when the record was modified 8 Optional

Date
SOP_ITEM_NO Sales Order Item Number 2 Required

Small Integer
STOCK_CODE Stock Code 30 Required

String
STOCK_DESC Stock Description 120 Optional

String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Creating a Goods Despatched Note


InvoiceData

GoodsNotesData

Description

The GoodsNotesData object gives access to the Goods Received Notes (GN.DTA) table.

Applies to

Sage 50 Accounts Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Account Reference | 8 | Required | String
COST_CODE_ID | Cost code id | 4 | Optional | Integer
GOODS_NO | Goods Number | 4 | Required | Integer
GRN_NEXT | Next GRN | 4 | Required | Integer
GRN_PREV | Previous GRN | 4 | Required | Integer
ITEM_NO | Item Number | 4 | Required | Integer
ORDER_NO | Order Number | 4 | Required | Integer
POP_ITEM_NO | Purchase Order Item Number | 2 | Required | Small Integer
POSTED_DATE | Date of Payment | 2 | Required | Date
PROJECT_ID | Project id | 4 | Optional | Integer
QTY_AMOUNT | Stock Qty Posted | 8 | Required | Double
QTY_BALANCE | Stock Qty Balance | 8 | Required | Double
QTY_ORDERED | Stock Qty Ordered | 8 | Required | Double
QTY_RECEIVED | Stock Qty Received | 8 | Required | Double
QTY_TO_DELIVER | Stock Qty To Deliver | 8 | Required | Double
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
STOCK_CODE | Stock Code | 30 | Required | String
STOCK_DESC | Stock Description | 120 | Optional | String
SUPPLIER_GRN | Supplier Goods Received Note | 20 | Required | String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.


InvoiceIndex

GoodsNotesIndex

Description

The GoodsNotesIndex object gives access to the Goods Notes Index (GNINDEX.DTA) table.

Applies to

Sage 50 Accounts Professional.

Fields Collection

Name | Description | Length | Input | Data Type
RECORD_NUMBER | Record Number In Data File | 4 | Required | Integer
REFERENCE | Unique Identifier For This Goods Note | 23 | Required | String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object


InvoiceData

GoodsNotesRecord

Description

The GoodsNotesRecord object gives access to the Goods Notes Data (GNDATA.DTA) and Goods Notes Index (GNINDEX.DTA) tables.

Applies to

Sage 50 Accounts Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Account Reference | 8 | Required | String
COST_CODE_ID | Cost code id | 4 | Optional | Integer
GOODS_NO | Goods Number | 4 | Required | Integer
GRN_NEXT | Next GRN | 4 | Required | Integer
GRN_PREV | Previous GRN | 4 | Required | Integer
ITEM_NO | Item Number | 4 | Required | Integer
ORDER_NO | Order Number | 4 | Required | Integer
POP_ITEM_NO | Purchase Order Item Number | 2 | Required | Small Integer
POSTED_DATE | Date of Payment | 2 | Required | Date
PROJECT_ID | Project id | 4 | Optional | Integer
QTY_AMOUNT | Stock Qty Posted | 8 | Required | Double
QTY_BALANCE | Stock Qty Balance | 8 | Required | Double
QTY_ORDERED | Stock Qty Ordered | 8 | Required | Double
QTY_RECEIVED | Stock Qty Received | 8 | Required | Double
QTY_TO_DELIVER | Stock Qty To Deliver | 8 | Required | Double
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
STOCK_CODE | Stock Code | 30 | Required | String
STOCK_DESC | Stock Description | 120 | Optional | String
SUPPLIER_GRN | Supplier Goods Received Note | 20 | Required | String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.


HeaderData

Description

The HeaderData object gives access to the transaction Header (HEADER.DTA) table.

This object holds the 'top level' transaction information in Sage 50 Accounts - when you view a Customer or Supplier activity in Sage 50 Accounts, the initial list of transactions is built up from information available from this object. For further information on how the transaction files work go to the Understanding Audit Trail Transactions article.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Sales/Purchase/Bank Account Reference | 8 | Required | String
AMOUNT_PAID | Total Amount Paid | 8 | System Generated | Double
ATTACHMENT_ADDED | Flag whether the transaction has attachments on disk. | 2 | Optional | Small Integer
AUTO_POSTED_TRANSACTION_FLAG | Automatically posted transaction flag. | 2 | Optional | Small Integer
BANK_CHARGE_ACCOUNT | Bank Charge Customer/Supplier Ref (Read Only) | 8 | Optional | String
BANK_CHARGE_IS_CUSTOMER | Is Bank Charge Customer or Supplier (Read Only) | 2 | Optional | Small Integer
BANK_CODE | Bank Account Reference | 8 | Required | String
BANK_FEEDS_MATCHED | Bank Feeds Matched | 1 | Optional | Byte
BANK_FLAG | Bank Reconciled Flag | 1 | Optional | Byte
BANK_RECONCILIATION_ID | Bank reconciliation ID that this transaciton is part of | 4 | Optional | Integer
CURRENCY | Currency for Transaction | 1 | Optional | Byte
CURRENCY_USED | Currency Used | 1 | Optional | Byte
DATE | Transaction Date | 2 | Required | Date
DATE_AMENDED | Date Transaction Amended | 32 | Optional | String
DATE_DUE | Date Invoice is Due for Payment | 2 | System Generated | Date
DATE_FORECAST | Forecast Date | 2 | Optional | Date
DATE_LAST_CHARGE | Date Interest Last Charged | 2 | Optional | Date
DELETED_FLAG | Transaction Deleted Flag | 2 | Optional | Small Integer
DEPOSIT_DATE | Bank deposited date | 2 | Optional | Date
DEPOSIT_FLAG | Bank deposited flag | 1 | Optional | Byte
DETAILS | Details | 60 | Optional | String
ELEC_TRANS | Electronic Transaction Flag | 2 | Optional | Small Integer
EURO_GROSS | Euro Gross Amount | 8 | Required | Double
EURO_RATE | Euro Rate | 8 | Required | Double
FINANCE_CHARGE | Finance Charge Flag | 1 | Optional | Byte
FIRST_SPLIT | Record Number in the SplitData collection | 4 | System Generated | Integer
FORECAST_INCLUDE | Included in Forecast | 2 | Optional | Date
FOREIGN_AMOUNT_PAID | Foreign Total Amount Paid | 8 | Optional | Double
FOREIGN_GROSS | Foreign Gross Amount | 8 | Required | Double
FOREIGN_NET_AMOUNT | Foreign Net Amount | 8 | Optional | Double
FOREIGN_RATE | Foreign Rate For Euro Currency | 8 | Required | Double
FOREIGN_TAX_AMOUNT | Foreign Tax Amount | 8 | Optional | Double
HAS_EXTERNAL_LINK | Sets whether the transaction has an external link | 2 | Optional | Small Integer
INTEREST_RATE | Interest Rate to Charge | 8 | Required | Double
INV_REF | Invoice Reference Number | 30 | Optional | String
ISP_REFERENCE Inv\Sop\Pop Reference 4

System Generated

Integer
JOB_REFERENCE | Job Costing Reference | 60 | Optional | String
LAST_SPLIT | Record Number in the SplitData collection | 4 | System Generated | Integer
NET_AMOUNT | Net Amount | 8 | Required | Double
NEXT_ACCOUNT | Record Number for Next Account | 4 | System Generated | Integer
NEXT_BANK | Record Number for Next Bank | 4 | System Generated | Integer
NO_DISPUTED | Number of Disputed Splits | 2 | Optional | Small Integer
NO_OF_SPLIT | Number of Splits | 4 | System Generated | Integer
OPENING_BALANCE_TRANS | Flag To State Is An Opening Balance Transaction | 2 | Optional | Small Integer
ORIGINATOR_ID | Guid of the originating Overdrive transaction (For Internal Use Only) | 37 | Optional | String
OVERRIDDEN_CLOSED_LEDGER_DATE | The closed ledger date that was overridden at the time of posting | 2 | System Generated | Date
PAID_FLAG | Transaction Paid Flag | 1 | Optional | Byte
POSTED_DATE | Posting Date | 2 | Optional | Date
POSTING_LOCATION | Location Transaction Posted From | 2 | Optional | Small Integer
PRACTICE_SOLUTIONS_REFN | Sage Practice Solutions Reference | 60 | Optional | String
PREV_ACCOUNT | Record Number for Previous Account | 4 | System Generated | Integer
PREV_BANK | Record Number for Previous Bank | 4 | System Generated | Integer
PRINTED_FLAG | Printed Flag | 1 | Optional | Byte
PROTX_REFN | PROTX Reference | 63 | Optional | String
RECON_DATE | Bank Reconciled Date | 2 | Optional | Date
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
REVALUATION_TRANS | Flag To State Is a Revaluation Transaction | 2 | Optional | Small Integer
SETT_DISCOUNT_RATE | Settlement Discount Value on Header | 8 | Optional | Double
TAX_AMOUNT | Tax Amount | 8 | Optional | Double
TYPE | Transaction Type | 1 | Required | Byte
UNIQUE_REF | Unique Reference | 4 | System Generated | Integer
USER_NAME | User Name | 32 | Optional | String
USER_NAME_AMENDED | User Name | 2 | Optional | Date
VAT_FLAG | Vat Flag | 1 | Optional | Byte

Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Allocating a Receipt to an Invoice with Multiple Splits
Editing a Transaction Split
Posting a Foreign Currency Purchase Payment
Posting a Foreign Currency Sales Receipt
Posting a Purchase Payment Against an Existing Invoice
Posting a Purchase Payment
Posting a Purchase Payment on Account (PA)
Posting a Sales Receipt Against an Existing Invoice
Posting a Sales Receipt
Posting a Sales Receipt on Account (SA)
Flag Disputed Transactions


Sage 50 Accounts - Example - Allocate Sop Order

Example - Allocate Sop Order

The example code below demonstrates how to Allocate stock to a Sop Order using the SDO ISopAllocate interface introduced to the SDO in Sage 50 Accounts. The method allows stock items added to a Sop Order to be allocated, reducing free stock and increasing the allocated quantity.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code

' Declare Variables

Dim oSDO As SageDataObject300.SDOEngine = New SageDataObject300.SDOEngine

Dim oWS As SageDataObject300.WorkSpace

Dim sopRecord As SageDataObject300.SopRecord

Dim allocateSop As SageDataObject300.ISopAllocate

Dim szDataPath As String

' Create the Workspace

oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install

' folder as a parameter

szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,

' the path will be passed to the szDataPath variable.

' If not, or the Cancel button is selected, the variable will be left empty.

If szDataPath <> "" Then

Try

' Try to Connect - Will Throw an Exception if it Fails

oWS.Connect(szDataPath, "", "", "Example")

Console.WriteLine("Connected")

'Instantiate the Sop Record object

sopRecord = oWS.CreateObject("SOPRECORD")

'Set the SopOrder number on the SopRecord for the Find method

sopRecord.Fields.Item("Order_Number").Value = CStr("87")

'Find the sop record, false is a full match, true a partial match

If sopRecord.Find(False) Then

'Instantiate the SopAllocate object casting it as an SopReord

allocateSop = DirectCast(sopRecord, SageDataObject300.ISopAllocate)

'Ensure the object is not null

If Not allocateSop Is Nothing Then

Try

'Try and allocate, returns an OrderStatusType

allocateSop.AllocateAll()

Console.WriteLine("Invoice updated")

Console.ReadLine()

Catch ex As Exception

Console.WriteLine("Invoice failed to update " & ex.Message)

Console.ReadLine()

End Try

End If

Else

Console.WriteLine("Sop could not be located")

Console.ReadLine()

End If

'Disconnect

oWS.Disconnect()

Catch ex As Exception

Console.WriteLine(ex.Message)

End Try

End If

'Marshal objects to be released ensuring they are picked up by the GC

System.Runtime.InteropServices.Marshal.FinalReleaseComObject(oSDO)

oSDO = Nothing

System.Runtime.InteropServices.Marshal.FinalReleaseComObject(oWS)

oWS = Nothing

System.Runtime.InteropServices.Marshal.FinalReleaseComObject(sopRecord)

sopRecord = Nothing

System.Runtime.InteropServices.Marshal.FinalReleaseComObject(allocateSop)

allocateSop = Nothing
C#.NET [image] Copy C# Code

//Declare Variables

 SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

 SageDataObject300.WorkSpace oWS;

 SageDataObject300.SopRecord sopRecord;

 SageDataObject300.ISopAllocate allocate;

 String szDataPath;

 //Instantiate WorkSpace

 oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

 //Show select company dialog

 szDataPath = oSDO.SelectCompany(@"C:\ProgramData\Sage\Accounts\2024");

 //Try a connection, will throw an exception if it fails

 try

 {

    //Leaving the username and password blank generates a login dialog

    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

    //Instantiate the Sop Record object

    sopRecord = oWS.CreateObject("SOPRECORD") as SageDataObject300.SopRecord;

    //Set the Order Number on the Sop Record for the Find Method

    SDOHelper.Write(sopRecord, "ORDER_NUMBER", "89");

    //Find the Sop record, false is a fulll match, true a partial match

    if (sopRecord.Find(false))

    {

        //Instantiate the SopAllocate object

        allocate = sopRecord as SageDataObject300.ISopAllocate;

        //Ensure the object is not null

        if (allocate != null)

        {

            try

            {

                //Try and post, returns an OrderStatusType

                allocate.AllocateAll();

                Console.WriteLine("Sop allocated");

                Console.ReadLine();

            }

            catch (Exception ex)

            {

                Console.WriteLine("Sop failed to allocate " + ex.Message);

                Console.ReadLine();

            }

        }

    }

    //The SopOrder can't be found

    else

    {

        Console.WriteLine("Sop could not be located");

        Console.ReadLine();

    }

    //Disconnect

    oWS.Disconnect();

 }

 catch (Exception ex)

 {

    Console.WriteLine("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

    Console.ReadLine();

 }

 //Marshal objects to be released ensuring they are picked up by the GC

 System.Runtime.InteropServices.Marshal.FinalReleaseComObject(oSDO);

 oSDO = null;

 System.Runtime.InteropServices.Marshal.FinalReleaseComObject(oWS);

 oWS = null;

 System.Runtime.InteropServices.Marshal.FinalReleaseComObject(sopRecord);

 sopRecord = null;

 System.Runtime.InteropServices.Marshal.FinalReleaseComObject(allocate);

 allocate = null;


InvoiceData

Description

The InvoiceData object gives access to the Invoice (INVOICE.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Account Reference | 8 | Required | String
ADDRESS_1 | Customer Address 1 | 60 | Optional | String
ADDRESS_2 | Customer Address 2 | 60 | Optional | String
ADDRESS_3 | Customer Address 3 | 60 | Optional | String
ADDRESS_4 | Customer Address 4 | 60 | Optional | String
ADDRESS_5 | Customer Address 5 | 60 | Optional | String
AMOUNT_PREPAID | Amount Prepaid | 8 | Optional | Double
ANALYSIS_1 | Analysis 1 | 30 | Optional | String
ANALYSIS_2 | Analysis 2 | 30 | Optional | String
ANALYSIS_3 | Analysis 3 | 30 | Optional | String
BANK_CODE | Bank Posting Code | 8 | Optional | String
BASE_AMOUNT_PAID | Base Amount Prepaid | 8 | Optional | Double
BASE_CARR_NET | Base Carriage Net Amount | 8 | Optional | Double
BASE_CARR_TAX | Base Carriage Tax Amount | 8 | Optional | Double
BASE_NETVALUE_DISCOUNT | Net Value Discount Amount in Base Currency | 8 | Optional | Double
BASE_SETT_DISC_RATE | Base Settlement Discount % Rate | 8 | Optional | Double
BASE_TOT_NET | Base Net Amount(goods but not carriage) | 8 | Optional | Double
BASE_TOT_TAX | Base Tax Amount(goods but not carriage) | 8 | Optional | Double
CARR_DEPT_NUMBER | Carriage Department Number | 2 | Optional | Small Integer
CARR_NET | Carriage Net Amount | 8 | Optional | Double
CARR_NOM_CODE | Carriage Nominal Code | 8 | Optional | String
CARR_TAX | Carriage Tax Amount | 8 | Optional | Double
CARR_TAX_CODE | Carriage Tax Code | 2 | Optional | Small Integer
CONSIGNMENT_REF | Consignment Reference | 30 | Optional | String
CONTACT_NAME | Customer Contact Name | 30 | Optional | String
COURIER | Courier Number | 2 | Optional | Small Integer
CURRENCY | Currency | 1 | Optional | Byte
COUNTRY_CODE | Customer Country Code | 2 | Optional | String
CURRENCY_USED | Currency Used | 1 | Optional | Byte
CUST_DISC_RATE | Customer Discount | 8 | Optional | Double
CUST_ORDER_NUMBER | Customer's Order Number | 60 | Optional | String
CUST_TEL_NUMBER | Customer's Telephone Number | 30 | Optional | String
DEF_TAX_CODE | Default Tax Code | 2 | Optional | Small Integer
DEL_ADDRESS_1 | Delivery Address Line 1 | 60 | Optional | String
DEL_ADDRESS_2 | Delivery Address Line 2 | 60 | Optional | String
DEL_ADDRESS_3 | Delivery Address Line 3 | 60 | Optional | String
DEL_ADDRESS_4 | Delivery Address Line 4 | 60 | Optional | String
DEL_ADDRESS_5 | Delivery Address Line 5 | 60 | Optional | String
DELETED_FLAG | Is Deleted | 2 | Optional | Small Integer
DELIVERY_NAME | Delivery Address Name | 60 | Optional | String
DISCOUNT_COMMENT1 | Discount Comment 1 | 60 | Optional | String
DISCOUNT_COMMENT2 | Discount Comment 2 | 60 | Optional | String
DISCOUNT_TYPE | Discount Type | 1 | Optional | Byte
DUNS_NUMBER | Duns Number | 9 | Optional | String
EMAILED | Emailed flag - Yes/No | 1 | Optional | Byte
EORI_NUMBER | Delivery address EORI Number | 17 | Optional | String
EURO_GROSS | Euro Gross Amount | 8 | Optional | Double
EURO_RATE | Euro Rate | 8 | Optional | Double
EXTERNAL_USAGE | Number of External Usages | 4 | Optional | Integer
FIRST_ITEM | Record Number of First Invoice Item | 4 | Optional | Integer
FOREIGN_GROSS | Foreign Gross Amount | 8 | Optional | Double
FOREIGN_RATE | Foreign Rate for Euro Currency | 8 | Optional | Double
GDN_NUMBER | GDN Reference | 4 | Optional | Integer
GLOBAL_DEPT_NUMBER | Global Department Number | 2 | Optional | Small Integer
GLOBAL_DETAILS | Global Details | 60 | Optional | String
GLOBAL_NOM_CODE | Global Nominal Code | 8 | Optional | String
GLOBAL_TAX_CODE | Global Tax Code | 2 | Optional | Small Integer
HAS_EXTERNAL_LINK | Has External Link | 2 | Optional | Small Integer
INCOTERMS | Incoterms | 2 | Optional | Small Integer
INVOICE_DATE | Invoice Date | 2 | Required | Date
INVOICE_FOREIGN_BALANCE | Foreign Balance | 8 | Optional | Double
INVOICE_NUMBER | Invoice Number Limited to 7 digits | 4 | Required | Integer
INVOICE_PAYMENT_ID | Payment Cloud Identifier | 37 | Optional | String
INVOICE_TYPE_CODE | Invoice Type Code | 1 | Required | Byte
ITEMS_NET | Net Amount (Goods but not carriage) | 8 | Optional | Double
ITEMS_TAX | Tax Amount (Goods but not carriage) | 8 | Optional | Double
LAST_NETVALUE_DISCOUNT | Last Net Value Discount Amount | 8 | Optional | Double
LAST_UPDATED | Last Updated Date | 8 | Optional | Date
NAME | Customer Account Name | 60 | Optional | String
NETVALUE_DESCRIPTION | Net Value Discount Description | 60 | Optional | String
NETVALUE_DISCOUNT | Net Value Discount Amount | 8 | Optional | Double
NETVALUE_DISCOUNT_PERCENT | Net Value Discount Percentage | 8 | Optional | Double
NOTES_1 | Notes 1 | 60 | Optional | String
NOTES_2 | Notes 2 | 60 | Optional | String
NOTES_3 | Notes 3 | 60 | Optional | String
ORDER_NUMBER | Corresponding Order Number | 7 | Required | String
OSS_COUNTRY_OF_VAT | Country of VAT | 2 | Optional | String
OSS_REPORTING_TYPE | Report type | 2 | Optional | Small Integer
PAYMENT_DUE_DATE | Invoice Payment Due Date | 2 | Optional | Date
PAYMENT_OSS_COUNTRY_OF_VAT | Payment Country of VAT | 2 | Optional | String
PAYMENT_OSS_REPORTING_TYPE | Payment Report type | 2 | Optional | Small Integer
PAYMENT_REF | Payment Reference | 30 | Optional | String
PAYMENT_TAX_CODE | Payment tax code | 2 | Optional | Small Integer
PAYMENT_TYPE | Payment Type (sdoSR/sdoSA) | 1 | Optional | Byte
POSTED_CODE | Posted Flag - Yes/No | 1 | Optional | Byte
PRACTICE_SOLUTIONS_REFN | Sage Practice Solutions Reference | 60 | Optional | String
PRINTED_CODE | Printed Flag - Yes/No | 1 | Optional | Byte
QUOTE_EXPIRY | The expiry date of the quotation | 2 | Optional | Date
QUOTE_STATUS | The status of the quotation | 2 | Optional | Small Integer
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
RECURRING_REFERENCE | Recurring Reference | 11 | Optional | String
RESUBMIT_INVOICE_PAYMENT_REQUIRED | Payment Cloud Identifier | 0 | Optional | String
SEND_VIA_EMAIL | Sent via TMail - Yes/No | 1 | Optional | Byte
SETTLEMENT_DISC_RATE | Settlement Discount % Rate | 8 | Optional | Double
SETTLEMENT_DUE_DAYS | Settlement Days | 2 | Optional | Small Integer
STATUS | Order Status Code | 1 | Optional | Byte
TAKEN_BY | Order Taken By | 60 | Optional | String
TOTAL_BYTES | 4 | Optional | Integer
UNALLOCATED_NETVALUE_DISCOUNT | Unallocated Net Value Discount Value | 8 | Optional | Double
VAT_REG_NUMBER | VAT Number | 20 | Optional | String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Adding an Item Line to an Invoice
Reading the Item Lines of an Existing Invoice


InvoiceIndex

Description

The InvoiceIndex object gives access to the Invoice index (INVINDEX.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
INVOICE_NUMBER | Invoice Number Limited to 7 digits | 7 | Required | String
RECORD_NUMBER | Record Number in Data File | 4 | Required | Integer
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Adding an Item Line to an Invoice
Reading the Item Lines of an Existing Invoice


InvoiceItem

Description

The InvoiceItem object gives access to the Invoice Item (INVITEM.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ADD_DISC_RATE | Additional Discount Percentage Rate | 8 | Optional | Double
BASE_FULL_NET | Full Net Value in Base Currency | 8 | Optional | Double
BASE_NET | Net Value in Base Currency | 8 | Optional | Double
BASE_NETVALUE_DISCOUNT | Net Value Discount Amount in Base Currency | 8 | Optional | Double
BASE_TAX | Tax Value in Base Currency | 8 | Optional | Double
COMMENT_1 | Comment 1 | 60 | Optional | String
COMMENT_2 | Comment 2 | 60 | Optional | String
COST_CODE_ID | Project Cost Code ID | 4 | Optional | Integer
DELIVERY_DATE | Delivery Date | 2 | Optional | Date
DEPT_NUMBER | Department Number | 2 | Optional | Small Integer
DESCRIPTION | Description | 120 | Optional | String
DISCOUNT_AMOUNT | Total Discount Percent on line item | 8 | Optional | Double
DISCOUNT_RATE | Discount Rate set on Sales record | 8 | Optional | Double
EXT_ORDER_LINE_REF | External Line Reference for SOP to INV Link | 4 | Optional | Integer
EXT_ORDER_REF | External Reference for SOP to INV Link | 30 | Optional | String
FULL_NET_AMOUNT | Full Net Amount (Before Discount) | 8 | Optional | Double
FUND_NUMBER | Fund Number | 4 | Optional | Integer
INVOICE_NUMBER | Invoice Number | 4 | Optional | Integer
IS_NEGATIVE_LINE | Is item line negative (1 = negative 0 = positive) | 2 | Optional | Small Integer
ITEM_NUMBER | Item Number | 2 | Optional | Small Integer
ITEMID | Unique Identifier, Unaffected By File Maintenance Routines | 4 | System Created | Integer
JOB_REFERENCE | Job Reference (Line Information) | 60 | Optional | String
NET_AMOUNT | Net Amount (After Discount) | 8 | Optional | Double
NETVALUE_DISCOUNT | Net Discount Value | 8 | Optional | Double
NEXT_ITEM | Record Number of Next Item | 4 | Optional | Integer
NOMINAL_CODE | Nominal Code | 8 | Optional | String
OFFSET | Offset of Service Text | 4 | Optional | Integer
PREV_ITEM | Record Number of Previous Item | 4 | Optional | Integer
PROJECT_ID | Project ID | 4 | Optional | Integer
QTY_ALLOCATED | Quantity Allocated for this Order | 8 | Optional | Double
QTY_DELIVERED | Quantity Previously Delivered for this Order | 8 | Optional | Double
QTY_DESPATCH | Quantity left to Despatch | 8 | Optional | Double
QTY_INTRASTAT_CONFIRMED | Quantity Intrastat Confirmed | 8 | Optional | Double
QTY_ORDER | Quantity Ordered | 8 | Optional | Double
SERVICE_FILE | Redundant - Do Not Use | 120 | Optional | String
SERVICE_FILE_SIZE | Redundant - Do Not Use | 4 | Optional | Integer
SERVICE_FLAG

Service Item Flag

 1 Optional Byte
SERVICE_ITEM_LINES | Redundant - Do Not Use | 4 | Optional | Integer
STOCK_CODE | Stock Code | 30 | Required | String
TAX_AMOUNT | Tax Amount | 8 | Optional | Double
TAX_CODE | Tax Code | 2 | Optional | Small Integer
TAX_FLAG | Item VAT Ammended. | 1 | Optional | Byte
TAX_RATE | Tax Rate | 8 | Optional | Double
TEXT | Service Invoice/Credit Text | 120 | Optional | String
UNIT_OF_SALE | Unit of Sale | 8 | Optional | String
UNIT_PRICE | Unit Price | 8 | Optional | Double
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Posting a Product Invoice
Posting a Product Invoice and Receipt
Posting a Product Credit Note
Posting a Service Invoice
Posting a Service Credit Note
Posting a 'Mix and Match' Invoice
Posting a 'Mix and Match' Credit Note
Adding an Item Line to an Invoice
Reading the Item Lines of an Existing Invoice


InvoicePost

Description

The InvoicePost object enables Invoices to be posted with all the relevant tables being updated automatically.

NOTE: if an SA/SR payment is to be added to the invoice, the BANK_CODE field should also be populated.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Account Reference | 8 | Required | String
ADDRESS_1 | Customer Address 1 | 60 | Optional | String
ADDRESS_2 | Customer Address 2 | 60 | Optional | String
ADDRESS_3 | Customer Address 3 | 60 | Optional | String
ADDRESS_4 | Customer Address 4 | 60 | Optional | String
ADDRESS_5 | Customer Address 5 | 60 | Optional | String
AMOUNT_PREPAID | Amount Prepaid | 8 | Optional | Double
BANK_CODE | Bank Posting Code | 8 | Optional | String
BASE_TOT_NET | Base Net Amount (Goods but not carriage) | 8 | Optional | Double
BASE_TOT_TAX | Base Tax Amount (Goods but not carriage) | 8 | Optional | Double
BASE_CARR_NET | Base Carriage Net Amount | 8 | Optional | Double
BASE_CARR_TAX | Base Carriage Tax Amount | 8 | Optional | Double
BASE_NETVALUE_DISCOUNT | Net Value Discount Amount in Base Currency | 8 | Optional | Double
BASE_SETT_DISC_RATE | Base Settlement Discount % Rate | 8 | Optional | Double
BASE_AMOUNT_PAID | Base Amount Prepaid | 8 | Optional | Double
CARR_DEPT_NUMBER | Carriage Department Number | 2 | Optional | Small Integer
CARR_NET | Carriage Net Amount | 8 | Optional | Double
CARR_NOM_CODE | Carriage Nominal Code | 8 | Optional | String
CARR_TAX | Carriage Tax Amount | 8 | Optional | Double
CARR_TAX_CODE | Carriage Tax Code | 2 | Optional | Small Integer
CONSIGNMENT_REF | Consignment Reference | 30 | Optional | String
CONTACT_NAME | Customer Contact Name | 30 | Optional | String
COURIER | Courier Number | 2 | Optional | Small Integer
CURRENCY | Currency | 1 | Optional | Byte
CURRENCY_USED | Currency Used | 1 | Optional | Byte
CUST_DISC_RATE | Customer Discount | 8 | Optional | Double
CUST_ORDER_NUMBER | Customer's Order Number | 60 | Optional | String
CUST_TEL_NUMBER | Customer's Telephone Number | 30 | Optional | String
DEF_TAX_CODE | Default Tax Code | 2 | Optional | Small Integer
DEL_ADDRESS_1 | Delivery Address Line 1 | 60 | Optional | String
DEL_ADDRESS_2 | Delivery Address Line 2 | 60 | Optional | String
DEL_ADDRESS_3 | Delivery Address Line 3 | 60 | Optional | String
DEL_ADDRESS_4 | Delivery Address Line 4 | 60 | Optional | String
DEL_ADDRESS_5 | Delivery Address Line 5 | 60 | Optional | String
DELETED_FLAG | Is Deleted | 2 | Optional | Small Integer
DELIVERY_NAME | Delivery Address Name | 60 | Optional | String
DISCOUNT_COMMENT1 | Discount Comment 1 | 60 | Optional | String
DISCOUNT_COMMENT2 | Discount Comment 2 | 60 | Optional | String
DISCOUNT_TYPE | Discount Type | 1 | Optional | Byte
DUNS_NUMBER | DUNS credit reference number | 9 | Optional | String
EMAILED | Emailed flag - Yes/No | 1 | Optional | Byte
EURO_GROSS | Euro Gross Amount | 8 | Optional | Double
EURO_RATE | Euro Rate | 8 | Optional | Double
EXTERNAL_USAGE | Number of External Usages | 4 | Optional | Integer
FIRST_ITEM | Record Number of First Invoice Item | 4 | Optional | Integer
FOREIGN_GROSS | Foreign Gross Amount | 8 | Optional | Double
FOREIGN_RATE | Foreign Exchange Rate | 8 | Optional | Double
GLOBAL_DEPT_NUMBER | Global Department Number | 2 | Optional | Small Integer
GLOBAL_DETAILS | Global Details | 60 | Optional | String
GLOBAL_NOM_CODE | Global Nominal Code | 8 | Optional | String
GLOBAL_TAX_CODE | Global Tax Code | 2 | Optional | Small Integer
INVOICE_DATE | Invoice Date | 2 | Required | Date
INVOICE_NUMBER | Invoice Number Limited to 4 digits | 4 | Required | Integer
INVOICE_TYPE_CODE | Invoice Type Code | 1 | Required | Byte
ITEMS_NET | Net Amount (Goods but not carriage) | 8 | Optional | Double
ITEMS_TAX | Tax Amount (Goods but not carriage) | 8 | Optional | Double
LAST_NETVALUE_DISCOUNT | Last Net Value Discount Amount | 8 | Optional | Double
LAST_UPDATED | Date of last update | 8 | Optional | Date
NAME | Customer Account Name | 60 | Optional | String
NETVALUE_DESCRIPTION | Net Value Discount Description | 60 | Optional | String
NETVALUE_DISCOUNT | Net Value Discount Amount | 8 | Optional | Double
NETVALUE_DISCOUNT_PERCENT | Net Value Discount Percentage | 8 | Optional | Double
NOTES_1 | Notes 1 | 60 | Optional | String
NOTES_2 | Notes 2 | 60 | Optional | String
NOTES_3 | Notes 3 | 60 | Optional | String
ORDER_NUMBER | Corresponding Order Number | 7 | Required | String
OSS_COUNTRY_OF_VAT | Country of VAT | 2 | Optional | String
OSS_REPORTING_TYPE | Report type | 2 | Optional | Small Integer
PAYMENT_DUE_DATE | Invoice Payment Due Date | 2 | Optional | Date
PAYMENT_REF | Payment Reference | 30 | Optional | String
PAYMENT_TAX_CODE | Payment tax code | 2 | Optional | Small Integer
PAYMENT_TYPE | Payment Type (sdoSR/sdoSA) | 1 | Optional | Byte
PRACTICE_SOLUTIONS_REFN | Sage Practice Solutions Reference | 60 | Optional | String
POSTED_CODE | Posted Flag - Yes/No | 1 | Optional | Byte
PRINTED_CODE | Printed Flag - Yes/No | 1 | Optional | Byte
QUOTE_EXPIRY | The expiry date of the quotation | 2 | Optional | Date
QUOTE_STATUS | The status of the quotation | 2 | Optional | Small Integer
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
RECURRING_REFERENCE | Recurring Reference | 11 | Optional | String
SEND_VIA_EMAIL | Send via TMail - Yes/No | 1 | Optional | Byte
SETTLEMENT_DISC_RATE | Settlement Discount % Rate | 8 | Optional | Double
SETTLEMENT_DUE_DAYS | Settlement Days | 2 | Optional | Small Integer
STATUS | Order Status Code | 1 | Optional | Byte
TAKEN BY | Order Taken By | 60 | Optional | String
TOTAL_BYTES | 4 | Optional | Integer
UNALLOCATED_NETVALUE_DISCOUNT | Unallocated Net Value Discount Amount | 8 | Optional | Double
VAT_REG_NUMBER | VAT registration number | 20 | Optional | String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Posting a Product Invoice
Posting a Product Invoice and Receipt
Posting a Product Credit Note
Posting a Service Invoice
Posting a Service Credit Note
Posting a 'Mix and Match' Invoice
Posting a 'Mix and Match' Credit Note
Adding an Item Line to an Invoice


InvoiceRecord

Description

The InvoiceRecord object gives access to the Invoice (INVOICE.DTA) table and the Invoice index (INVINDEX.DTA) table. As an SDORecord object, it encapsulates both the data and index files.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Account Reference | 8 | Required | String
ADDRESS_1 | Customer Address 1 | 60 | Optional | String
ADDRESS_2 | Customer Address 2 | 60 | Optional | String
ADDRESS_3 | Customer Address 3 | 60 | Optional | String
ADDRESS_4 | Customer Address 4 | 60 | Optional | String
ADDRESS_5 | Customer Address 5 | 60 | Optional | String
AMOUNT_PREPAID | Amount Prepaid | 8 | Optional | Double
ANALYSIS_1 | Analysis 1 | 30 | Optional | String
ANALYSIS_2 | Analysis 2 | 30 | Optional | String
ANALYSIS_3 | Analysis 3 | 30 | Optional | String
BANK_CODE | Bank Posting Code | 8 | Optional | String
BASE_AMOUNT_PAID | Base Amount Prepaid | 8 | Optional | Double
BASE_CARR_NET | Base Carriage Net Amount | 8 | Optional | Double
BASE_CARR_TAX | Base Carriage Tax Amount | 8 | Optional | Double
BASE_NETVALUE_DISCOUNT | Net Value Discount Amount In base Currency | 8 | Optional | Double
BASE_SETT_DISC_RATE | Base Settlement Discount % Rate | 8 | Optional | Double
BASE_TOT_NET | Base Net Amount(goods no carriage) | 8 | Optional | Double
BASE_TOT_TAX | Base Tax Amount(goods no carriage) | 8 | Optional | Double
CARR_DEPT_NUMBER | Carriage Department Number | 2 | Optional | Small Integer
CARR_NET | Carriage Net Amount | 8 | Optional | Double
CARR_NOM_CODE | Carriage Nominal Code | 8 | Optional | String
CARR_TAX | Carriage Tax Amount | 8 | Optional | Double
CARR_TAX_CODE | Carriage Tax Code | 2 | Optional | Small Integer
CONSIGNMENT_REF | Consignment Reference | 30 | Optional | String
CONTACT_NAME | Customer Contact Name | 30 | Optional | String
COUNTRY_CODE | Customer Country code | 2 | Optional | String
COURIER | Courier Number | 2 | Optional | Small Integer
CURRENCY | Currency | 1 | Optional | Byte
CURRENCY_USED | Currency Used | 1 | Optional | Byte
CUST_DISC_RATE | Customer Discount | 8 | Optional | Double
CUST_ORDER_NUMBER | Customer's Order Number | 60 | Optional | String
CUST_TEL_NUMBER | Customer's Telephone Number | 30 | Optional | String
DEF_TAX_CODE | Default Tax Code | 2 | Optional | Small Integer
DEL_ADDRESS_1 | Delivery Address Line 1 | 60 | Optional | String
DEL_ADDRESS_2 | Delivery Address Line 2 | 60 | Optional | String
DEL_ADDRESS_3 | Delivery Address Line 3 | 60 | Optional | String
DEL_ADDRESS_4 | Delivery Address Line 4 | 60 | Optional | String
DEL_ADDRESS_5 | Delivery Address Line 5 | 60 | Optional | String
DELETED_FLAG | Is Deleted | 2 | Optional | Small Integer
DELIVERY_NAME | Delivery Address Name | 60 | Optional | String
DISCOUNT_COMMENT1 | Text For Discount Comment | 60 | Optional | String
DISCOUNT_COMMENT2 | Text For Discount Comment | 60 | Optional | String
DISCOUNT_TYPE | Discount Type | 1 | Optional | Byte
DUNS_NUMBER | Duns Number | 9 | Optional | String
EMAILED | Emailed flag - Yes/No | 1 | Optional | Byte
EORI_NUMBER | Delivery address EORI Number | 17 | Optional | String
EURO_GROSS | Euro Gross Amount | 8 | Optional | Double
EURO_RATE | Euro Rate | 8 | Optional | Double
EXTERNAL_USAGE | Number of External Usages | 4 | Optional | Integer
FIRST_ITEM | Record Number of First Invoice Item | 4 | Optional | Integer
FOREIGN_GROSS | Foreign Gross Amount | 8 | Optional | Double
FOREIGN_RATE | Foreign Exchange Rate | 8 | Optional | Double
GDN_NUMBER | GDN Reference | 4 | Optional | Integer
GLOBAL_DEPT_NUMBER | Global Department Number | 2 | Optional | Small Integer
GLOBAL_DETAILS | Global Details | 60 | Optional | String
GLOBAL_NOM_CODE | Global Nominal Code | 8 | Optional | String
GLOBAL_TAX_CODE | Global Tax Code | 2 | Optional | Small Integer
HAS_EXTERNAL_LINK | Has External Link | 2 | Optional | Small Integer
INCOTERMS | Incoterms | 2 | Optional | Small Integer
INVOICE_DATE | Invoice Date | 2 | Required | Date
INVOICE_FOREIGN_BALANCE | Foreign Balance | 8 | Optional | Double
INVOICE_NUMBER | Invoice Number Limited to 7 digits | 4 | Required | Integer
INVOICE_PAYMENT_ID | Payment Cloud Identifier | 37 | Optional | String
INVOICE_TYPE_CODE | Invoice Type Code | 1 | Required | Byte
ITEMS_NET | Net Amount (Goods but not carriage) | 8 | Optional | Double
ITEMS_TAX | Tax Amount (Goods but not carriage) | 8 | Optional | Double
LAST_NETVALUE_DISCOUNT | Last Value Discount Amount | 8 | Optional | Double
LAST_UPDATED | Last Updated Date | 8 | Optional | Date
NAME | Customer Account Name | 60 | Optional | String
NETVALUE_DESCRIPTION | Net Value Discount Description | 60 | Optional | String
NETVALUE_DISCOUNT | Net Value Discount Amount | 8 | Optional | Double
NETVALUE_DISCOUNT_PERCENT | Net Value Discount Percentage | 8 | Optional | Double
NOTES_1 | Notes 1 | 60 | Optional | String
NOTES_2 | Notes 2 | 60 | Optional | String
NOTES_3 | Notes 3 | 60 | Optional | String
ORDER_NUMBER | Corresponding Order Number | 7 | Required | String
OSS_COUNTRY_OF_VAT | Country of VAT | 2 | Optional | String
OSS_REPORTING_TYPE | Report type | 2 | Optional | Small Integer
PAYMENT_DUE_DATE | Invoice Payment Due Date | 2 | Optional | Date
PAYMENT_OSS_COUNTRY_OF_VAT | Payment Country of VAT | 2 | Optional | String
PAYMENT_OSS_REPORTING_TYPE | Payment Report type | 2 | Optional | Small Integer
PAYMENT_REF | Payment Reference | 30 | Optional | String
PAYMENT_TAX_CODE | Payment Reference | 2 | Optional | Small Integer
PAYMENT_TYPE | Payment Type (sdoSR/sdoSA) | 1 | Optional | Byte
POSTED_CODE | Posted Flag - Yes/No | 1 | Optional | Byte
PRACTICE_SOLUTIONS_REFN | Sage Practice Solutions Reference | 60 | Optional | String
PRINTED_CODE | Printed Flag - Yes/No | 1 | Optional | Byte
QUOTE_EXPIRY | The expiry date of the quotation | 2 | Optional | Date
QUOTE_STATUS | The status of the quotation | 2 | Optional | Small Integer
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
RECURRING_REFERENCE | Recurring Reference | 11 | Optional | String
RESUBMIT_INVOICE_PAYMENT_REQUIRED | Payment Cloud Identifier | 0 | Optional | String
SEND_VIA_EMAIL | Flag To Set Invoice Output To Email | 1 | Optional | Byte
SETTLEMENT_DISC_RATE | Settlement Discount % Rate | 8 | Optional | Double
SETTLEMENT_DUE_DAYS | Settlement Days | 2 | Optional | Small Integer
STATUS | Order Status Code | 1 | Optional | Byte
TAKEN_BY | Order Taken By | 60 | Optional | String
TOTAL_BYTES | 4 | Optional | Integer
UNALLOCATED_NETVALUE_DISCOUNT | Unallocated Net Value Discount amount | 8 | Optional | Double
VAT_REG_NUMBER | VAT registration number | 20 | Optional | String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Adding an Item Line to an Invoice
Reading the Item Lines of an Existing Invoice


Sage 50 Accounts - Example - Update Ledgers

Example - Update Ledgers

The example code below demonstrates how to update an un-posted Invoice Record using the SDO IUpdateLedgers interface introduced to the SDO in Sage 50 Accounts 2015. The method allows invoices created either from either a SOP record or the invoice module to be updated to the ledgers along with the relevant stock movements.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code

' Declare Variables

Dim oSDO As SageDataObject300.SDOEngine = New SageDataObject300.SDOEngine

Dim oWS As SageDataObject300.WorkSpace

Dim invoiceRecord As SageDataObject300.InvoiceRecord

Dim updateLedgers As SageDataObject300.IUpdateLedgers

Dim szDataPath As String

' Create the Workspace

oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install

' folder as a parameter

szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,

' the path will be passed to the szDataPath variable.

' If not, or the Cancel button is selected, the variable will be left empty.

If szDataPath <> "" Then

Try

' Try to Connect - Will Throw an Exception if it Fails

oWS.Connect(szDataPath, "", "", "Example")

Console.WriteLine("Connected")

'Instantiate the Invoice Record object

invoiceRecord = oWS.CreateObject("INVOICERECORD")

'Set the Invoice number on the Invoice Record for the Find meethod

invoiceRecord.Fields.Item("INVOICE_NUMBER").Value = CStr("89")

'Find the invoice record, false is a full match, true a partial match

If invoiceRecord.Find(False) Then

'Instantiate the UpdateLedgers object casting it as an InvoiceReord

updateLedgers = DirectCast(invoiceRecord, SageDataObject300.IUpdateLedgers)

'Ensure the object is not null

If Not updateLedgers Is Nothing Then

'Check to see if posted, returns a boolean

If updateLedgers.Post Then

Console.WriteLine("Invoice updated")

Console.ReadLine()

Else

Console.WriteLine("Invoice failed to update")

Console.ReadLine()

End If

End If

Else

Console.WriteLine("Invoice could not be located")

Console.ReadLine()

End If

'Disconnect

oWS.Disconnect()

Catch ex As Exception

Console.WriteLine(ex.Message)

End Try

End If

'Marshal objects to be released ensuring they are picked up by the GC

System.Runtime.InteropServices.Marshal.FinalReleaseComObject(oSDO)

oSDO = Nothing

System.Runtime.InteropServices.Marshal.FinalReleaseComObject(oWS)

oWS = Nothing

System.Runtime.InteropServices.Marshal.FinalReleaseComObject(invoiceRecord)

invoiceRecord = Nothing

System.Runtime.InteropServices.Marshal.FinalReleaseComObject(updateLedgers)

updateLedgers = Nothing
C#.NET [image] Copy C# Code

    //Declare Variables

    SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

    SageDataObject300.WorkSpace oWS;

    SageDataObject300.InvoiceRecord invoiceRecord;

    SageDataObject300.IUpdateLedgers updateLedgers;

    String szDataPath;

    //Instantiate WorkSpace

    oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

    //Show select company dialog

    szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

    //Try a connection, will throw an exception if it fails

    try

    {

        //Leaving the username and password blank generates a login dialog

        oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

        Console.WriteLine("Connected");

        //Instantiate the Invoice Record object

        invoiceRecord = oWS.CreateObject("INVOICERECORD") as SageDataObject300.InvoiceRecord;

        //Set the Invoice Number on the Invoice Record for the Find Method

        SDOHelper.Write(invoiceRecord, "INVOICE_NUMBER", "89");

        //Find the invoice record, false is a fulll match, true a partial match

        if (invoiceRecord.Find(false))

        {

            //Instantiate the UpdateLedgers object casting it as an InvoiceRecord

            updateLedgers = invoiceRecord as SageDataObject300.IUpdateLedgers;

            //Ensure the object is not null

            if (updateLedgers != null)

            {

                //Check to see if posted, returns a boolean

                if (updateLedgers.Post())

                {

                    Console.WriteLine("Invoice updated");

                    Console.ReadLine();

                }

                else

                {

                    Console.WriteLine("Invoice failed to update");

                    Console.ReadLine();

                }

            }

        }

            //The invoice can't be found

        else

        {

            Console.WriteLine("Invoice could not be located");

            Console.ReadLine();

        }

        //Disconnect

        oWS.Disconnect();

    }

    catch (Exception ex)

    {

        Console.WriteLine("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

        Console.ReadLine();

    }

    //Marshal objects to be released ensuring they are picked up by the GC

    System.Runtime.InteropServices.Marshal.FinalReleaseComObject(oSDO);

    oSDO = null;

    System.Runtime.InteropServices.Marshal.FinalReleaseComObject(oWS);

    oWS = null;

    System.Runtime.InteropServices.Marshal.FinalReleaseComObject(invoiceRecord);

    invoiceRecord = null;

    System.Runtime.InteropServices.Marshal.FinalReleaseComObject(updateLedgers);

    updateLedgers = null;

}


JournalPost

Description

The JournalPost object enables Audit Trail Journal transactions to be posted with all the relevant tables being updated automatically. The JournalPost.Update method may fail due to one of the reasons stated below:

  • The Account_Ref does not exist.
  • The Transaction Type does not match the account it is being posted to. e.g. Posting an SI Transaction to a Supplier Account
  • The Nominal code specified does not exists. Use the find method to ensure both the ACOUNT_REF and NOMINAL_CODE exist.
  • The Nominal code specified is of incorrect type. e.g. You cannot post a transaction of type SI to a control or bank account.
  • The currency specifyied does not match that of the Account_REF.
  • The Values set are negative. Ensure all values are unsigned.
  • The period the transaction is dated for is in a period which is locked.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Sales/Purchase/Bank Account Reference | 8 | Required | String
AMOUNT_PAID | Total Amount Paid | 8 | Optional | Double
BANK_CODE Bank Account Reference 8 Required for SA/SP/SR, PA/PP/PR
Not set for other transaction types 		String
BANK_FLAG | Bank Reconciled Flag | 1 | Optional | Byte
CURRENCY | Currency for Transaction | 1 | Optional | Byte
CURRENCY_USED | Currency Used | 1 | Optional | Byte
DATE | Transaction Date | 2 | Required | Date
DATE_DUE | Date Invoice is Due for Payment | 2 | Optional | Date
DATE_FORECAST | Forecast Date | 2 | Optional | Date
DATE_LAST_CHARGE | Date Interest Last Charged | 2 | Optional | Date
DELETED_FLAG | Transaction Deleted Flag | 2 | Optional | Small Integer
DEPOSIT_DATE | Bank Deposited Date | 2 | Optional | Date
DEPOSIT_FLAG | Bank Deposited Flag | 1 | Optional | Byte
DETAILS | Details | 60 | Optional | String
ELEC_TRANS | Electronic Transaction Flag | 2 | Optional | Small Integer
EURO_GROSS | Euro Gross Amount | 8 | Required | Double
EURO_RATE | Euro Rate | 8 | Required | Double
FINANCE_CHARGE | Finance Charge Flag | 1 | Optional | Byte
FIRST_SPLIT | Item Number | 4 | System Generated | Integer
FORECAST_INCLUDE | Included in Forecast | 2 | Optional | Date
FOREIGN_AMOUNT_PAID | Foreign Total Amount Paid | 8 | Optional | Double
FOREIGN_GROSS | Foreign Gross Amount | 8 | Required | Double
FOREIGN_NET_AMOUNT | Foreign Net Amount | 8 | Optional | Double
FOREIGN_RATE | Foreign Rate For Euro Currency | 8 | Required | Double
FOREIGN_TAX_AMOUNT | Foreign Tax Amount | 8 | Optional | Double
INTEREST_RATE | Interest Rate to Charge | 8 | Required | Double
INV_REF | Invoice Reference Number | 30 | Optional | String
ISP_REFERENCE Inv\Sop\Pop Reference 4

System Generated

Integer
JOB_REFERENCE | Job Costing Reference | 60 | Optional | String
LAST_SPLIT | Item Number | 4 | System Generated | Integer
NET_AMOUNT | Net Amount | 8 | Required | Double
NEXT_ACCOUNT | Record Number for Next Account | 4 | System Generated | Integer
NEXT_BANK | Record Number for Next Bank | 4 | System Generated | Integer
NO_DISPUTED | Number of Disputed Splits | 2 | Optional | Small Integer
NO_OF_SPLIT | Number of Splits | 4 | System Generated | Integer
OPENING_BALANCE_TRANS | Is Transaction an Opening Balance | 2 | Optional | Small Integer
OVERRIDDEN_CLOSED_LEDGER_DATE | The closed ledger date that was overridden at the time of posting | 2 | System Generated | Date
PAID_FLAG | Transaction Paid Flag | 1 | Optional | Byte
POSTED_DATE | Posting Date | 2 | Optional | Date
POSTING_LOCATION | Location Transaction Posted From | 2 | Optional | Small Integer
PRACTICE_SOLUTIONS_REFN | Sage Practice Solutions Reference | 60 | Optional | String
PREV_ACCOUNT | Record Number for Previous Account | 4 | System Generated | Integer
PREV_BANK | Record Number for Previous Bank | 4 | System Generated | Integer
PRINTED_FLAG | Printed Flag | 1 | Optional | Byte
PROTX_REFN | PROTX Reference | 63 | Optional | String
RECON_DATE | Date Transaction was Reconciled | 2 | Optional | Date
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted or not. | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
REVALUATION_TRANS | Is Transaction a Revaluation Transaction | 2 | Optional | Small Integer
SETT_DISCOUNT_RATE | Settlement Discount Rate | 8 | Optional | Double
TAX_AMOUNT | Tax Amount | 8 | Optional | Double
TYPE | Transaction Type | 1 | Required | Byte
UNIQUE_REF | Header Number | 4 | System Generated | Integer
USER_NAME | User Name | 32 | Optional | String
VAT_FLAG | Vat Flag | 1 | Optional | Byte

Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Posting a Journal Entry with JournalPost Object


MiscWWWData

Description

The MiscWWWData object gives access to the Miscellaneous Website Address (MISCWWW.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
NAME | Name | 60 | Optional | String
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
SEARCH | Search | 255 | Optional | String
WWW | World Wide Web Address | 255 | Optional | String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

There are currently no examples that make use of this object.


IsDateValidForLockDate Method

Description

The IsDateValidForLockDate method helps identify whether a transaction date is affected by a lock date.

Syntax

The IsDateValidForLockDate method has the following syntax:

object.IsDateValidForLockDate(DATE dTransactionDate)

with the following parts:

Part | Description
SetupData | Applies to only the SetupData object

Return Value(s)

The method returns the following values:

LockDatePermission is an enumerated type used to determine the LockDatePermission

Remarks

Sage 50 Accounts 2017 sees the introduction of Lock Dates which allow accounting periods to be closed. If the SDO is used to post a transaction that is dated before the lock date the TransactionPost.Update will return false and throw an exception if the user does not have the permission to post into closed periods. The LockDatePermission is an enumerator type that allows us to identify if the user has sufficient access to make the posting.

We recommend that SDO users are created without the ability to override closed periods. This is done through Settings>Access Rights>Menu Settings>Dialogs>Lock Date Settings as shown below.

Examples

Is Date Valid For Lock Date

Is Date User Valid For Lock Date

Related Topics


NominalData

Description

The NominalData object gives access to the Nominal (NOMINAL.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Account Code | 8 | Required | String
ACCOUNT_TYPE | Account Type Code | 1 | Optional | Byte
AUDIT_REF | Incomplete Records Reference | 20 | Optional | String
BALANCE | Balance | 8 | Optional | Double
BALANCE_BF | Balance Brought Forward | 8 | Optional | Double
BALANCE_FUTURE | Balance Future | 8 | Optional | Double
BALANCE_MTH1 | Balance Month 1 | 8 | Optional | Double
BALANCE_MTH2 | Balance Month 2 | 8 | Optional | Double
BALANCE_MTH3 | Balance Month 3 | 8 | Optional | Double
BALANCE_MTH4 | Balance Month 4 | 8 | Optional | Double
BALANCE_MTH5 | Balance Month 5 | 8 | Optional | Double
BALANCE_MTH6 | Balance Month 6 | 8 | Optional | Double
BALANCE_MTH7 | Balance Month 7 | 8 | Optional | Double
BALANCE_MTH8 | Balance Month 8 | 8 | Optional | Double
BALANCE_MTH9 | Balance Month 9 | 8 | Optional | Double
BALANCE_MTH10 | Balance Month 10 | 8 | Optional | Double
BALANCE_MTH11 | Balance Month 11 | 8 | Optional | Double
BALANCE_MTH12 | Balance Month 12 | 8 | Optional | Double
BUDGET_MTH1 | Budget Month 1 | 8 | Optional | Double
BUDGET_MTH2 | Budget Month 2 | 8 | Optional | Double
BUDGET_MTH3 | Budget Month 3 | 8 | Optional | Double
BUDGET_MTH4 | Budget Month 4 | 8 | Optional | Double
BUDGET_MTH5 | Budget Month 5 | 8 | Optional | Double
BUDGET_MTH6 | Budget Month 6 | 8 | Optional | Double
BUDGET_MTH7 | Budget Month 7 | 8 | Optional | Double
BUDGET_MTH8 | Budget Month 8 | 8 | Optional | Double
BUDGET_MTH9 | Budget Month 9 | 8 | Optional | Double
BUDGET_MTH10 | Budget Month 10 | 8 | Optional | Double
BUDGET_MTH11 | Budget Month 11 | 8 | Optional | Double
BUDGET_MTH12 | Budget Month 12 | 8 | Optional | Double
CREDIT_BF | Credit Brought Forward | 8 | Optional | Double
CREDIT_FUTURE | Credit for Future | 8 | Optional | Double
CREDIT_MTH1 | Credit Month 1 | 8 | Optional | Double
CREDIT_MTH2 | Credit Month 2 | 8 | Optional | Double
CREDIT_MTH3 | Credit Month 3 | 8 | Optional | Double
CREDIT_MTH4 | Credit Month 4 | 8 | Optional | Double
CREDIT_MTH5 | Credit Month 5 | 8 | Optional | Double
CREDIT_MTH6 | Credit Month 6 | 8 | Optional | Double
CREDIT_MTH7 | Credit Month 7 | 8 | Optional | Double
CREDIT_MTH8 | Credit Month 8 | 8 | Optional | Double
CREDIT_MTH9 | Credit Month 9 | 8 | Optional | Double
CREDIT_MTH10 | Credit Month 10 | 8 | Optional | Double
CREDIT_MTH11 | Credit Month 11 | 8 | Optional | Double
CREDIT_MTH12 | Credit Month 12 | 8 | Optional | Double
DEBIT_BF | Debit Brought Forward | 8 | Optional | Double
DEBIT_FUTURE | Debit for Future | 8 | Optional | Double
DEBIT_MTH1 | Debit Month 1 | 8 | Optional | Double
DEBIT_MTH2 | Debit Month 2 | 8 | Optional | Double
DEBIT_MTH3 | Debit Month 3 | 8 | Optional | Double
DEBIT_MTH4 | Debit Month 4 | 8 | Optional | Double
DEBIT_MTH5 | Debit Month 5 | 8 | Optional | Double
DEBIT_MTH6 | Debit Month 6 | 8 | Optional | Double
DEBIT_MTH7 | Debit Month 7 | 8 | Optional | Double
DEBIT_MTH8 | Debit Month 8 | 8 | Optional | Double
DEBIT_MTH9 | Debit Month 9 | 8 | Optional | Double
DEBIT_MTH10 | Debit Month 10 | 8 | Optional | Double
DEBIT_MTH11 | Debit Month 11 | 8 | Optional | Double
DEBIT_MTH12 | Debit Month 12 | 8 | Optional | Double
DELETED_FLAG | Is Deleted | 2 | Optional | Small Integer
EXTERNAL_USAGE | Number of External Usages | 4 | Optional | Integer
FIRST_SPLIT | Record Number of First Split | 4 | Optional | Integer
INACTIVE_FLAG | Inactive Flag - Yes/No | 4 | Optional | Integer
LAST_SPLIT | Record Number of Last Split | 4 | Optional | Integer
NAME | Name | 60 | Optional | String
NO_OF_SPLIT | Number of Splits | 4 | Optional | Integer
PRIOR_YR2_MTH1 | Prior Year 2 Month 1 | 8 | Optional | Double
PRIOR_YR2_MTH2 | Prior Year 2 Month 2 | 8 | Optional | Double
PRIOR_YR2_MTH3 | Prior Year 2 Month 3 | 8 | Optional | Double
PRIOR_YR2_MTH4 | Prior Year 2 Month 4 | 8 | Optional | Double
PRIOR_YR2_MTH5 | Prior Year 2 Month 5 | 8 | Optional | Double
PRIOR_YR2_MTH6 | Prior Year 2 Month 6 | 8 | Optional | Double
PRIOR_YR2_MTH7 | Prior Year 2 Month 7 | 8 | Optional | Double
PRIOR_YR2_MTH8 | Prior Year 2 Month 8 | 8 | Optional | Double
PRIOR_YR2_MTH9 | Prior Year 2 Month 9 | 8 | Optional | Double
PRIOR_YR2_MTH10 | Prior Year 2 Month 10 | 8 | Optional | Double
PRIOR_YR2_MTH11 | Prior Year 2 Month 11 | 8 | Optional | Double
PRIOR_YR2_MTH12 | Prior Year 2 Month 12 | 8 | Optional | Double
PRIOR_YR3_MTH1 | Prior Year 3 Month 1 | 8 | Optional | Double
PRIOR_YR3_MTH2 | Prior Year 3 Month 2 | 8 | Optional | Double
PRIOR_YR3_MTH3 | Prior Year 3 Month 3 | 8 | Optional | Double
PRIOR_YR3_MTH4 | Prior Year 3 Month 4 | 8 | Optional | Double
PRIOR_YR3_MTH5 | Prior Year 3 Month 5 | 8 | Optional | Double
PRIOR_YR3_MTH6 | Prior Year 3 Month 6 | 8 | Optional | Double
PRIOR_YR3_MTH7 | Prior Year 3 Month 7 | 8 | Optional | Double
PRIOR_YR3_MTH8 | Prior Year 3 Month 8 | 8 | Optional | Double
PRIOR_YR3_MTH9 | Prior Year 3 Month 9 | 8 | Optional | Double
PRIOR_YR3_MTH10 | Prior Year 3 Month 10 | 8 | Optional | Double
PRIOR_YR3_MTH11 | Prior Year 3 Month 11 | 8 | Optional | Double
PRIOR_YR3_MTH12 | Prior Year 3 Month 12 | 8 | Optional | Double
PRIOR_YR4_MTH1 | Prior Year 4 Month 1 | 8 | Optional | Double
PRIOR_YR4_MTH2 | Prior Year 4 Month 2 | 8 | Optional | Double
PRIOR_YR4_MTH3 | Prior Year 4 Month 3 | 8 | Optional | Double
PRIOR_YR4_MTH4 | Prior Year 4 Month 4 | 8 | Optional | Double
PRIOR_YR4_MTH5 | Prior Year 4 Month 5 | 8 | Optional | Double
PRIOR_YR4_MTH6 | Prior Year 4 Month 6 | 8 | Optional | Double
PRIOR_YR4_MTH7 | Prior Year 4 Month 7 | 8 | Optional | Double
PRIOR_YR4_MTH8 | Prior Year 4 Month 8 | 8 | Optional | Double
PRIOR_YR4_MTH9 | Prior Year 4 Month 9 | 8 | Optional | Double
PRIOR_YR4_MTH10 | Prior Year 4 Month 10 | 8 | Optional | Double
PRIOR_YR4_MTH11 | Prior Year 4 Month 11 | 8 | Optional | Double
PRIOR_YR4_MTH12 | Prior Year 4 Month 12 | 8 | Optional | Double
PRIOR_YR5_MTH1 | Prior Year 5 Month 1 | 8 | Optional | Double
PRIOR_YR5_MTH2 | Prior Year 5 Month 2 | 8 | Optional | Double
PRIOR_YR5_MTH3 | Prior Year 5 Month 3 | 8 | Optional | Double
PRIOR_YR5_MTH4 | Prior Year 5 Month 4 | 8 | Optional | Double
PRIOR_YR5_MTH5 | Prior Year 5 Month 5 | 8 | Optional | Double
PRIOR_YR5_MTH6 | Prior Year 5 Month 6 | 8 | Optional | Double
PRIOR_YR5_MTH7 | Prior Year 5 Month 7 | 8 | Optional | Double
PRIOR_YR5_MTH8 | Prior Year 5 Month 8 | 8 | Optional | Double
PRIOR_YR5_MTH9 | Prior Year 5 Month 9 | 8 | Optional | Double
PRIOR_YR5_MTH10 | Prior Year 5 Month 10 | 8 | Optional | Double
PRIOR_YR5_MTH11 | Prior Year 5 Month 11 | 8 | Optional | Double
PRIOR_YR5_MTH12 | Prior Year 5 Month 12 | 8 | Optional | Double
PRIOR_YR_MTH1 | Prior Year 1 Month 1 | 8 | Optional | Double
PRIOR_YR_MTH2 | Prior Year 1 Month 2 | 8 | Optional | Double
PRIOR_YR_MTH3 | Prior Year 1 Month 3 | 8 | Optional | Double
PRIOR_YR_MTH4 | Prior Year 1 Month 4 | 8 | Optional | Double
PRIOR_YR_MTH5 | Prior Year 1 Month 5 | 8 | Optional | Double
PRIOR_YR_MTH6 | Prior Year 1 Month 6 | 8 | Optional | Double
PRIOR_YR_MTH7 | Prior Year 1 Month 7 | 8 | Optional | Double
PRIOR_YR_MTH8 | Prior Year 1 Month 8 | 8 | Optional | Double
PRIOR_YR_MTH9 | Prior Year 1 Month 9 | 8 | Optional | Double
PRIOR_YR_MTH10 | Prior Year 1 Month 10 | 8 | Optional | Double
PRIOR_YR_MTH11 | Prior Year 1 Month 11 | 8 | Optional | Double
PRIOR_YR_MTH12 | Prior Year 1 Month 12 | 8 | Optional | Double
QUICK_RATIO_FLAG | Quick Ratio Account Flag | 1 | Optional | Byte
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date

Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Creating a New Accrual Record
Creating a New Prepayment Record
Posting a Foreign Currency Purchase Payment
Posting a Foreign Currency Sales Receipt
Posting a Purchase Payment
Posting a Sales Receipt
Creating a New Nominal Account


NominalIndex

Description

The NominalIndex object gives access to the Nominal index (NOMINDEX.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Account Reference | 8 | Required | String
RECORD_NUMBER | Record Number in Data File | 4 | Required | Integer
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Creating a New Nominal Account
Reading Nominal Budgets


NominalRecord

Description

The NominalRecord object gives access to the Nominal (NOMINAL.DTA) table and the Nominal index (NOMINDEX.DTA) table. As an SDORecord object, it encapsulates both the data and index files.

New GetBudget method

The new GetBudget method allows easy access to the budget figures for the nominal codes.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Account Code | 8 | Required | String
ACCOUNT_TYPE | Account Type Code | 1 | Optional | Byte
AUDIT_REF | Incomplete Records Reference | 20 | Optional | String
BALANCE | Balance | 8 | Optional | Double
BALANCE_BF | Balance Brought Forward | 8 | Optional | Double
BALANCE_FUTURE | Balance Future | 8 | Optional | Double
BALANCE_MTH1 | Balance Month 1 | 8 | Optional | Double
BALANCE_MTH10 | Balance Month 10 | 8 | Optional | Double
BALANCE_MTH11 | Balance Month 11 | 8 | Optional | Double
BALANCE_MTH12 | Balance Month 12 | 8 | Optional | Double
BALANCE_MTH2 | Balance Month 2 | 8 | Optional | Double
BALANCE_MTH3 | Balance Month 3 | 8 | Optional | Double
BALANCE_MTH4 | Balance Month 4 | 8 | Optional | Double
BALANCE_MTH5 | Balance Month 5 | 8 | Optional | Double
BALANCE_MTH6 | Balance Month 6 | 8 | Optional | Double
BALANCE_MTH7 | Balance Month 7 | 8 | Optional | Double
BALANCE_MTH8 | Balance Month 8 | 8 | Optional | Double
BALANCE_MTH9 | Balance Month 9 | 8 | Optional | Double
BUDGET_MTH1 | Budget Month 1 | 8 | Optional | Double
BUDGET_MTH10 | Budget Month 10 | 8 | Optional | Double
BUDGET_MTH11 | Budget Month 11 | 8 | Optional | Double
BUDGET_MTH12 | Budget Month 12 | 8 | Optional | Double
BUDGET_MTH2 | Budget Month 2 | 8 | Optional | Double
BUDGET_MTH3 | Budget Month 3 | 8 | Optional | Double
BUDGET_MTH4 | Budget Month 4 | 8 | Optional | Double
BUDGET_MTH5 | Budget Month 5 | 8 | Optional | Double
BUDGET_MTH6 | Budget Month 6 | 8 | Optional | Double
BUDGET_MTH7 | Budget Month 7 | 8 | Optional | Double
BUDGET_MTH8 | Budget Month 8 | 8 | Optional | Double
BUDGET_MTH9 | Budget Month 9 | 8 | Optional | Double
CREDIT_BF | Credit Brought Forward | 8 | Optional | Double
CREDIT_FUTURE | Credit for Future | 8 | Optional | Double
CREDIT_MTH1 | Credit Month 1 | 8 | Optional | Double
CREDIT_MTH10 | Credit Month 10 | 8 | Optional | Double
CREDIT_MTH11 | Credit Month 11 | 8 | Optional | Double
CREDIT_MTH12 | Credit Month 12 | 8 | Optional | Double
CREDIT_MTH2 | Credit Month 2 | 8 | Optional | Double
CREDIT_MTH3 | Credit Month 3 | 8 | Optional | Double
CREDIT_MTH4 | Credit Month 4 | 8 | Optional | Double
CREDIT_MTH5 | Credit Month 5 | 8 | Optional | Double
CREDIT_MTH6 | Credit Month 6 | 8 | Optional | Double
CREDIT_MTH7 | Credit Month 7 | 8 | Optional | Double
CREDIT_MTH8 | Credit Month 8 | 8 | Optional | Double
CREDIT_MTH9 | Credit Month 9 | 8 | Optional | Double
DEBIT_BF | Debit Brought Forward | 8 | Optional | Double
DEBIT_FUTURE | Debit for Future | 8 | Optional | Double
DEBIT_MTH1 | Debit Month 1 | 8 | Optional | Double
DEBIT_MTH10 | Debit Month 10 | 8 | Optional | Double
DEBIT_MTH11 | Debit Month 11 | 8 | Optional | Double
DEBIT_MTH12 | Debit Month 12 | 8 | Optional | Double
DEBIT_MTH2 | Debit Month 2 | 8 | Optional | Double
DEBIT_MTH3 | Debit Month 3 | 8 | Optional | Double
DEBIT_MTH4 | Debit Month 4 | 8 | Optional | Double
DEBIT_MTH5 | Debit Month 5 | 8 | Optional | Double
DEBIT_MTH6 | Debit Month 6 | 8 | Optional | Double
DEBIT_MTH7 | Debit Month 7 | 8 | Optional | Double
DEBIT_MTH8 | Debit Month 8 | 8 | Optional | Double
DEBIT_MTH9 | Debit Month 9 | 8 | Optional | Double
DELETED_FLAG | Is Deleted | 2 | Optional | Small Integer
EXTERNAL_USAGE | Number of External Usages | 4 | Optional | Integer
FIRST_SPLIT | Record Number of First Split | 4 | Optional | Integer
INACTIVE_FLAG | Inactive Flag - Yes/No | 4 | Optional | Integer
LAST_SPLIT | Record Number of Last Split | 4 | Optional | Integer
NAME | Name | 60 | Optional | String
NO_OF_SPLIT | Number of Splits | 4 | Optional | Integer
PRIOR_YR2_MTH1 | Prior Year 2 Month 1 | 8 | Optional | Double
PRIOR_YR2_MTH10 | Prior Year 2 Month 10 | 8 | Optional | Double
PRIOR_YR2_MTH11 | Prior Year 2 Month 11 | 8 | Optional | Double
PRIOR_YR2_MTH12 | Prior Year 2 Month 12 | 8 | Optional | Double
PRIOR_YR2_MTH2 | Prior Year 2 Month 2 | 8 | Optional | Double
PRIOR_YR2_MTH3 | Prior Year 2 Month 3 | 8 | Optional | Double
PRIOR_YR2_MTH4 | Prior Year 2 Month 4 | 8 | Optional | Double
PRIOR_YR2_MTH5 | Prior Year 2 Month 5 | 8 | Optional | Double
PRIOR_YR2_MTH6 | Prior Year 2 Month 6 | 8 | Optional | Double
PRIOR_YR2_MTH7 | Prior Year 2 Month 7 | 8 | Optional | Double
PRIOR_YR2_MTH8 | Prior Year 2 Month 8 | 8 | Optional | Double
PRIOR_YR2_MTH9 | Prior Year 2 Month 9 | 8 | Optional | Double
PRIOR_YR3_MTH1 | Prior Year 3 Month 1 | 8 | Optional | Double
PRIOR_YR3_MTH10 | Prior Year 3 Month 10 | 8 | Optional | Double
PRIOR_YR3_MTH11 | Prior Year 3 Month 11 | 8 | Optional | Double
PRIOR_YR3_MTH12 | Prior Year 3 Month 12 | 8 | Optional | Double
PRIOR_YR3_MTH2 | Prior Year 3 Month 2 | 8 | Optional | Double
PRIOR_YR3_MTH3 | Prior Year 3 Month 3 | 8 | Optional | Double
PRIOR_YR3_MTH4 | Prior Year 3 Month 4 | 8 | Optional | Double
PRIOR_YR3_MTH5 | Prior Year 3 Month 5 | 8 | Optional | Double
PRIOR_YR3_MTH6 | Prior Year 3 Month 6 | 8 | Optional | Double
PRIOR_YR3_MTH7 | Prior Year 3 Month 7 | 8 | Optional | Double
PRIOR_YR3_MTH8 | Prior Year 3 Month 8 | 8 | Optional | Double
PRIOR_YR3_MTH9 | Prior Year 3 Month 9 | 8 | Optional | Double
PRIOR_YR4_MTH1 | Prior Year 4 Month 1 | 8 | Optional | Double
PRIOR_YR4_MTH10 | Prior Year 4 Month 10 | 8 | Optional | Double
PRIOR_YR4_MTH11 | Prior Year 4 Month 11 | 8 | Optional | Double
PRIOR_YR4_MTH12 | Prior Year 4 Month 12 | 8 | Optional | Double
PRIOR_YR4_MTH2 | Prior Year 4 Month 2 | 8 | Optional | Double
PRIOR_YR4_MTH3 | Prior Year 4 Month 3 | 8 | Optional | Double
PRIOR_YR4_MTH4 | Prior Year 4 Month 4 | 8 | Optional | Double
PRIOR_YR4_MTH5 | Prior Year 4 Month 5 | 8 | Optional | Double
PRIOR_YR4_MTH6 | Prior Year 4 Month 6 | 8 | Optional | Double
PRIOR_YR4_MTH7 | Prior Year 4 Month 7 | 8 | Optional | Double
PRIOR_YR4_MTH8 | Prior Year 4 Month 8 | 8 | Optional | Double
PRIOR_YR4_MTH9 | Prior Year 4 Month 9 | 8 | Optional | Double
PRIOR_YR5_MTH1 | Prior Year 5 Month 1 | 8 | Optional | Double
PRIOR_YR5_MTH10 | Prior Year 5 Month 10 | 8 | Optional | Double
PRIOR_YR5_MTH11 | Prior Year 5 Month 11 | 8 | Optional | Double
PRIOR_YR5_MTH12 | Prior Year 5 Month 12 | 8 | Optional | Double
PRIOR_YR5_MTH2 | Prior Year 5 Month 2 | 8 | Optional | Double
PRIOR_YR5_MTH3 | Prior Year 5 Month 3 | 8 | Optional | Double
PRIOR_YR5_MTH4 | Prior Year 5 Month 4 | 8 | Optional | Double
PRIOR_YR5_MTH5 | Prior Year 5 Month 5 | 8 | Optional | Double
PRIOR_YR5_MTH6 | Prior Year 5 Month 6 | 8 | Optional | Double
PRIOR_YR5_MTH7 | Prior Year 5 Month 7 | 8 | Optional | Double
PRIOR_YR5_MTH8 | Prior Year 5 Month 8 | 8 | Optional | Double
PRIOR_YR5_MTH9 | Prior Year 5 Month 9 | 8 | Optional | Double
PRIOR_YR_MTH1 | Prior Year 1 Month 1 | 8 | Optional | Double
PRIOR_YR_MTH10 | Prior Year 1 Month 10 | 8 | Optional | Double
PRIOR_YR_MTH11 | Prior Year 1 Month 11 | 8 | Optional | Double
PRIOR_YR_MTH12 | Prior Year 1 Month 12 | 8 | Optional | Double
PRIOR_YR_MTH2 | Prior Year 1 Month 2 | 8 | Optional | Double
PRIOR_YR_MTH3 | Prior Year 1 Month 3 | 8 | Optional | Double
PRIOR_YR_MTH4 | Prior Year 1 Month 4 | 8 | Optional | Double
PRIOR_YR_MTH5 | Prior Year 1 Month 5 | 8 | Optional | Double
PRIOR_YR_MTH6 | Prior Year 1 Month 6 | 8 | Optional | Double
PRIOR_YR_MTH7 | Prior Year 1 Month 7 | 8 | Optional | Double
PRIOR_YR_MTH8 | Prior Year 1 Month 8 | 8 | Optional | Double
PRIOR_YR_MTH9 | Prior Year 1 Month 9 | 8 | Optional | Double
QUICK_RATIO_FLAG | Quick Ratio Account Flag | 1 | Optional | Byte
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date

Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Creating a New Nominal Account
Reading Nominal Budgets
Reading Nominal Codes


POPData

Description

The POPData object gives access to the Purchase Order (PUORDER.DTA) table.

Applies to

Sage 50 Accounts Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Account Reference | 8 | Required | String
ADDRESS_1 | Supplier Address 1 | 60 | Optional | String
ADDRESS_2 | Supplier Address 2 | 60 | Optional | String
ADDRESS_3 | Supplier Address 3 | 60 | Optional | String
ADDRESS_4 | Supplier Address 4 | 60 | Optional | String
ADDRESS_5 | Supplier Address 5 | 60 | Optional | String
AMOUNT_PREPAID | Amount Prepaid | 8 | Optional | Double
ANALYSIS_1 | Analysis 1 | 30 | Optional | String
ANALYSIS_2 | Analysis 2 | 30 | Optional | String
ANALYSIS_3 | Analysis 3 | 30 | Optional | String
BASE_AMOUNT_PAID | Base Amount Prepaid | 8 | Optional | Double
BASE_CARR_NET | Base Carriage Net Amount | 8 | Optional | Double
BASE_CARR_TAX | Base Carriage Tax Amount | 8 | Optional | Double
BASE_SETT_DISC_RATE | Base Settlement Discount % Rate | 8 | Optional | Double
BASE_TOT_NET | Base Net Amount (Goods but not Carriage) | 8 | Optional | Double
BASE_TOT_TAX | Base Tax Amount (Goods but not Carriage) | 8 | Optional | Double
CARR_DEPT_NUMBER | Carriage Department Number | 2 | Optional | Small Integer
CARR_NET | Carriage Net Amount | 8 | Optional | Double
CARR_NOM_CODE | Carriage Nominal Code | 8 | Optional | String
CARR_TAX | Carriage Tax Amount | 8 | Optional | Double
CARR_TAX_CODE | Carriage Tax Code | 2 | Optional | Small Integer
CONSIGNMENT_REF | Consignment Reference | 30 | Optional | String
CONTACT_NAME | Supplier Contact Name | 30 | Optional | String
COST_CODE_ID | Global Project Cost Code ID | 4 | Optional | Integer
COUNTRY_CODE | Supplier Country Code | 2 | Optional | String
COURIER | Courier Number | 2 | Optional | Small Integer
CURRENCY | Currency | 1 | Optional | Byte
CURRENCY_USED | Currency Used | 1 | Optional | Byte
DEL_ADDRESS_1 | Delivery Address Line 1 | 60 | Optional | String
DEL_ADDRESS_2 | Delivery Address Line 2 | 60 | Optional | String
DEL_ADDRESS_3 | Delivery Address Line 3 | 60 | Optional | String
DEL_ADDRESS_4 | Delivery Address Line 4 | 60 | Optional | String
DEL_ADDRESS_5 | Delivery Address Line 5 | 60 | Optional | String
DELETED_FLAG | Is Deleted | 2 | Optional | Small Integer
DELIVERY_DATE | Delivery Date | 2 | Optional | Date
DELIVERY_NAME | Delivery Address Name | 60 | Optional | String
DISCOUNT_TYPE | Discount Type | 1 | Optional | Byte
DUE_DATE | Due Date | 2 | Optional | Date
EMAILED | Emailed flag - Yes/No | 1 | Optional | Byte
EORI_NUMBER | Delivery address EORI Number | 17 | Optional | String
EURO_GROSS | Euro Gross Amount | 8 | Optional | Double
EURO_RATE | Euro Rate | 8 | Optional | Double
EXTERNAL_USAGE | Number of External Usages | 4 | Optional | Integer
FIRST_ITEM | Record Number of First POP Item | 4 | Optional | Integer
FOREIGN_GROSS | Foreign Gross Amount | 8 | Optional | Double
FOREIGN_RATE | Foreign Rate for Euro Currency | 8 | Optional | Double
GDN_NUMBER | GDN Reference | 4 | Optional | Integer
GLOBAL_DEPT_NUMBER | Global Department Number | 2 | Optional | Small Integer
HAS_EXTERNAL_LINK | Has External Link | 2 | Optional | Small Integer
INCOTERMS | Incoterms | 2 | Optional | Small Integer
INTRASTAT_STATUS | Intrastat Reconciled Status | 1 | Optional | Byte
INVOICE_FOREIGN_BALANCE | Foreign Balance | 8 | Optional | Double
INVOICE_NUMBER | Corresponding Invoice Number | 7 | Required | String
ITEMS_NET | Net Amount (Goods but not carriage) | 8 | Optional | Double
ITEMS_TAX | Tax Amount (Goods but not carriage) | 8 | Optional | Double
LAST_UPDATED | Last Updated Date | 8 | Optional | Date
NAME | Supplier Account Name | 60 | Optional | String
NOTES_1 | Notes 1 | 60 | Optional | String
NOTES_2 | Notes 2 | 60 | Optional | String
NOTES_3 | Notes 3 | 60 | Optional | String
ORDER_DATE | Order Date | 2 | Required | Date
ORDER_NUMBER | Corresponding Order Number Limited to 4 digits | 4 | Required | Integer
ORDER_TYPE | Order Type Code | 1 | Required | Byte
PAYMENT_REF | Payment Reference | 30 | Optional | String
PAYMENT_TYPE | Payment Type (SR/SA) | 1 | Optional | Byte
POSTED_CODE | Posted Flag - Yes/No | 1 | Optional | Byte
PRACTICE_SOLUTIONS_REFN | Sage Practice Solutions Reference | 60 | Optional | String
PRINTED_CODE | Printed Flag - Yes/No | 1 | Optional | Byte
PROJECT_ID | Global Project ID | 4 | Optional | Integer
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
RECURRING_REFERENCE | Recurring Reference | 11 | Optional | String
SETTLEMENT_DISC_RATE | Settlement Discount % Rate | 8 | Optional | Double
SETTLEMENT_DUE_DAYS | Settlement Days | 2 | Optional | Small Integer
STATUS | Order Status Code | 1 | Optional | Byte
SUPP_DISC_RATE | Supplier Discount | 8 | Optional | Double
SUPP_ORDER_NUMBER | Supplier's Order Number | 60 | Optional | String
SUPP_TEL_NUMBER | Supplier's Telephone Number | 30 | Optional | String
TAKEN_BY | Order Taken By | 60 | Optional | String
TOTAL_BYTES | 4 | Optional | Integer
VAT_REG_NUMBER | VAT Number | 20 | Optional | String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Reading the Item Lines of an Existing Purchase Order
Adding an Item Line to a Purchase Order


POPIndex

Description

The POPIndex object gives access to the Purchase Order index (PUOINDEX.DTA) table.

Applies to

Sage 50 Accounts Professional.

Fields Collection

Name | Description | Length | Input | Data Type
INVOICE_NUMBER | Purchase Order Number Limited to 7 digits | 7 | Required | String
RECORD_NUMBER | Record Number in Data File | 4 | Required | Integer
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Reading the Item Lines of an Existing Purchase Order
Adding an Item Line to a Purchase Order


POPItem

Description

The POPItem object gives access to the Purchase Order Item (PUOITEM.DTA) table.

Applies to

Sage 50 Accounts Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ADD_DISC_RATE | Additional Discount Percentage Rate | 8 | Optional | Double
BASE_FULL_NET Full Net Amount (no discount) 8 Optional

Double
BASE_NET Base Net Amount 8 Optional

Double
BASE_TAX Base Tax Amount 8 Optional

Double
COMMENT_1 | Comment 1 | 60 | Optional | String
COMMENT_2 | Comment 2 | 60 | Optional | String
COST_CODE_ID | Cost Code ID number | 4 | Optional | Integer
DELIVERY_DATE | Delivery Date | 2 | Optional | Date
DEPT_NUMBER | Department Number | 2 | Optional | Small Integer
DESCRIPTION | Description | 120 | Optional | String
DISCOUNT_AMOUNT | Discount Amount | 8 | Optional | Double
DISCOUNT_RATE | Discount Percentage Rate | 8 | Optional | Double
DUE_DATE | Due Date | 2 | Optional | Date
EXT_ORDER_LINE_REF | External Line Reference for SOP to INV Link | 4 | Optional | Integer
EXT_ORDER_REF | External Reference for SOP to INV Link | 30 | Optional | String
FULL_NET_AMOUNT | Full Net Amount (Before Discount) | 8 | Optional | Double
FUND_NUMBER | Fund Number | 4 | Optional | Integer
INVOICE_NUMBER | Invoice Number | 4 | Optional | Integer
ITEM_NUMBER | Item Number | 2 | Optional | Small Integer
ITEMID | Unique Identifier, Unaffected by file maintenance routines | 4 | System Produced | Integer
JOB_REFERENCE | Job Reference | 60 | Optional | String
NET_AMOUNT | Net Amount (After Discount) | 8 | Optional | Double
NEXT_ITEM | Record Number of Next Item | 4 | Optional | Integer
NOMINAL_CODE | Nominal Code | 8 | Optional | String
OFFSET | Offset of Service Text | 4 | Optional | Integer
PREV_ITEM | Record Number of Previous Item | 4 | Optional | Integer
PROJECT_ID | Project ID Number | 4 | Optional | Integer
QTY_ALLOCATED | Quantity Allocated for this Order | 8 | Optional | Double
QTY_ALLOCATED_TO_PROJECT | Quantity allocated to project | 8 | Optional | Double
QTY_DELIVERED | Quantity Previously Delivered for this Order | 8 | Optional | Double
QTY_DESPATCH | Quantity left to Despatch | 8 | Optional | Double
QTY_INTRASTAT_CONFIRMED | Quantity IntraStat Confirmed | 8 | Optional | Double
QTY_INVOICED | Quantity Invoiced | 8 | Optional | Double
QTY_ISSUED_TO_PROJECT | Quantity issued to project | 8 | Optional | Double
QTY_ORDER | Quantity Ordered | 8 | Optional | Double
SERVICE_FILE | Redundant - Do Not Use | 120 | Optional | String
SERVICE_FILE_SIZE | Redundant - Do Not Use | 4 | Optional | Integer
SERVICE_FLAG | Service Item Flag | 1 | Optional | Byte
SERVICE_ITEM_LINES | Redundant - Do Not Use | 4 | Optional | Integer
STOCK_CODE | Stock Code | 30 | Required | String
TAX_AMOUNT | Tax Amount | 8 | Optional | Double
TAX_CODE | Tax Code | 2 | Optional | Small Integer
TAX_FLAG | Item VAT Ammended. | 1 | Optional | Byte
TAX_RATE | Tax Rate | 8 | Optional | Double
TEXT | Service Invoice/Credit Text | 120 | Optional | String
UNIT_OF_SALE | Unit of Sale | 8 | Optional | String
UNIT_PRICE | Unit Price | 8 | Optional | Double

Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Reading the Item Lines of an Existing Purchase Order
Adding an Item Line to a Purchase Order


POPPost

Description

The POPPost object enables Purchase Orders to be posted with all the relevant tables being updated automatically.

Applies to

Sage 50 Accounts Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Account Reference | 8 | Required | String
ADDRESS_1 | Supplier Address 1 | 60 | Optional | String
ADDRESS_2 | Supplier Address 2 | 60 | Optional | String
ADDRESS_3 | Supplier Address 3 | 60 | Optional | String
ADDRESS_4 | Supplier Address 4 | 60 | Optional | String
ADDRESS_5 | Supplier Address 5 | 60 | Optional | String
AMOUNT_PREPAID | Amount Prepaid | 8 | Optional | Double
BASE_AMOUNT_PAID | Base Amount Prepaid | 8 | Optional | Double
BASE_CARR_NET | Base Carriage Net Amount | 8 | Optional | Double
BASE_CARR_TAX | Base Carriage Tax Amount | 8 | Optional | Double
BASE_SETT_DISC_RATE | Base Settlement Discount % Rate | 8 | Optional | Double
BASE_TOT_NET | Base Net Amount (Goods but not Carriage) | 8 | Optional | Double
BASE_TOT_TAX | Base Tax Amount (Goods but not Carriage) | 8 | Optional | Double
CARR_DEPT_NUMBER | Carriage Department Number | 2 | Optional | Small Integer
CARR_NET | Carriage Net Amount | 8 | Optional | Double
CARR_NOM_CODE | Carriage Nominal Code | 8 | Optional | String
CARR_TAX | Carriage Tax Amount | 8 | Optional | Double
CARR_TAX_CODE | Carriage Tax Code | 2 | Optional | Small Integer
CONSIGNMENT_REF | Consignment Reference | 30 | Optional | String
CONTACT_NAME | Supplier Contact Name | 30 | Optional | String
COST_CODE_ID | Cost Code ID Number | 4 | Optional | Integer
COURIER | Courier Number | 2 | Optional | Small Integer
CURRENCY | Currency | 1 | Optional | Byte
CURRENCY_USED | Currency Used (Not Used) | 1 | Optional | Byte
DEL_ADDRESS_1 | Delivery Address Line 1 | 60 | Optional | String
DEL_ADDRESS_2 | Delivery Address Line 2 | 60 | Optional | String
DEL_ADDRESS_3 | Delivery Address Line 3 | 60 | Optional | String
DEL_ADDRESS_4 | Delivery Address Line 4 | 60 | Optional | String
DEL_ADDRESS_5 | Delivery Address Line 5 | 60 | Optional | String
DELETED_FLAG | Is Deleted | 2 | Optional | Small Integer
DELIVERY_DATE | Delivery Date | 2 | Optional | Date
DELIVERY_NAME | Delivery Address Name | 60 | Optional | String
DISCOUNT_TYPE | Discount Type | 1 | Optional | Byte
DUE_DATE | Due Date | 2 | Optional | Date
EMAILED | Emailed flag - Yes/No | 1 | Optional | Byte
EURO_GROSS | Euro Gross Amount | 8 | Optional | Double
EURO_RATE | Euro Rate | 8 | Optional | Double
EXTERNAL_USAGE | Number of External Usages | 4 | Optional | Integer
FIRST_ITEM | Record Number of First POP Item | 4 | Optional | Integer
FOREIGN_GROSS | Foreign Gross Amount | 8 | Optional | Double
FOREIGN_RATE | Foreign Rate for Euro Currency | 8 | Optional | Double
GLOBAL_DEPT_NUMBER | Global Department Number | 2 | Optional | Small Integer
INTRASTAT_STATUS | Intrastat Reconciled Status | 1 | Optional | Byte
INVOICE_NUMBER | Corresponding Invoice Number | 7 | Required | String
ITEMS_NET | Net Amount (Goods but not carriage) | 8 | Optional | Double
ITEMS_TAX | Tax Amount (Goods but not carriage) | 8 | Optional | Double
LAST_UPDATED | Date of last update | 8 | Optional | Date
NAME | Supplier Account Name | 60 | Optional | String
NOTES_1 | Notes 1 | 60 | Optional | String
NOTES_2 | Notes 2 | 60 | Optional | String
NOTES_3 | Notes 3 | 60 | Optional | String
ORDER_DATE | Order Date | 2 | Required | Date
ORDER_NUMBER | Corresponding Order Number Limited to 4 digits | 4 | Required | Integer
ORDER_TYPE | Order Type Code | 1 | Required | Byte
PAYMENT_REF | Payment Reference | 30 | Optional | String
PAYMENT_TYPE | Payment Type (SR/SA) | 1 | Optional | Byte
POSTED_CODE | Posted Flag - Yes/No | 1 | Optional | Byte
PRACTICE_SOLUTIONS_REFN | Sage Practice Solutions Reference | 60 | Optional | String
PRINTED_CODE | Printed Flag - Yes/No | 1 | Optional | Byte
PROJECT_ID | Project ID Number | 4 | Optional | Integer
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
RECURRING_REFERENCE | Recurring Reference | 11 | Optional | String
SETTLEMENT_DISC_RATE | Settlement Discount % Rate | 8 | Optional | Double
SETTLEMENT_DUE_DAYS | Settlement Days | 2 | Optional | Small Integer
STATUS | Order Status Code | 1 | Optional | Byte
SUPP_DISC_RATE | Supplier Discount | 8 | Optional | Double
SUPP_ORDER_NUMBER | Supplier's Order Number | 60 | Optional | String
SUPP_TEL_NUMBER | Supplier's Telephone Number | 30 | Optional | String
TAKEN BY | Order Taken By | 60 | Optional | String
TOTAL_BYTES | 4 | Optional | Integer
VAT_REG_NUMBER | VAT registration number | 20 | Optional | String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Posting a Purchase Order
Adding an Item Line to a Purchase Order


POPRecord

Description

The POPRecord object gives access to the Purchase Order (PUORDER.DTA) table and the Purchase Order index (PUOINDEX.DTA) table. As an SDORecord object, it encapsulates both the data and index files.

Applies to

Sage 50 Accounts Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Account Reference | 8 | Required | String
ADDRESS_1 | Supplier Address 1 | 60 | Optional | String
ADDRESS_2 | Supplier Address 2 | 60 | Optional | String
ADDRESS_3 | Supplier Address 3 | 60 | Optional | String
ADDRESS_4 | Supplier Address 4 | 60 | Optional | String
ADDRESS_5 | Supplier Address 5 | 60 | Optional | String
AMOUNT_PREPAID | Amount Prepaid | 8 | Optional | Double
ANALYSIS_1 | Analysis 1 | 30 | Optional | String
ANALYSIS_2 | Analysis 2 | 30 | Optional | String
ANALYSIS_3 | Analysis 3 | 30 | Optional | String
BASE_AMOUNT_PAID | Base Amount Prepaid | 8 | Optional | Double
BASE_CARR_NET | Base Carriage Net Amount | 8 | Optional | Double
BASE_CARR_TAX | Base Carriage Tax Amount | 8 | Optional | Double
BASE_SETT_DISC_RATE | Base Settlement Discount % Rate | 8 | Optional | Double
BASE_TOT_NET | Base Net Amount (Goods but not Carriage) | 8 | Optional | Double
BASE_TOT_TAX | Base Tax Amount (Goods but not Carriage) | 8 | Optional | Double
CARR_DEPT_NUMBER | Carriage Department Number | 2 | Optional | Small Integer
CARR_NET | Carriage Net Amount | 8 | Optional | Double
CARR_NOM_CODE | Carriage Nominal Code | 8 | Optional | String
CARR_TAX | Carriage Tax Amount | 8 | Optional | Double
CARR_TAX_CODE | Carriage Tax Code | 2 | Optional | Small Integer
CONSIGNMENT_REF | Consignment Reference | 30 | Optional | String
CONTACT_NAME | Supplier Contact Name | 30 | Optional | String
COST_CODE_ID | Cost Code ID Number | 4 | Optional | Integer
COUNTRY_CODE | Supplier Country code | 2 | Optional | String
COURIER | Courier Number | 2 | Optional | Small Integer
CURRENCY | Currency | 1 | Optional | Byte
CURRENCY_USED | Currency Used | 1 | Optional | Byte
DEL_ADDRESS_1 | Delivery Address Line 1 | 60 | Optional | String
DEL_ADDRESS_2 | Delivery Address Line 2 | 60 | Optional | String
DEL_ADDRESS_3 | Delivery Address Line 3 | 60 | Optional | String
DEL_ADDRESS_4 | Delivery Address Line 4 | 60 | Optional | String
DEL_ADDRESS_5 | Delivery Address Line 5 | 60 | Optional | String
DELETED_FLAG | Is Deleted | 2 | Optional | Small Integer
DELIVERY_DATE | Delivery Date | 2 | Optional | Date
DELIVERY_NAME | Delivery Address Name | 60 | Optional | String
DISCOUNT_TYPE | Discount Type | 1 | Optional | Byte
DUE_DATE | Due Date | 2 | Optional | Date
EMAILED | Emailed flag - Yes/No | 1 | Optional | Byte
EORI_NUMBER | Delivery address EORI Number | 17 | Optional | String
EURO_GROSS | Euro Gross Amount | 8 | Optional | Double
EURO_RATE | Euro Rate | 8 | Optional | Double
EXTERNAL_USAGE | Number of External Usages | 4 | Optional | Integer
FIRST_ITEM | Record Number of First POP Item | 4 | Optional | Integer
FOREIGN_GROSS | Foreign Gross Amount | 8 | Optional | Double
FOREIGN_RATE | Foreign Rate for Euro Currency | 8 | Optional | Double
GDN_NUMBER | GDN Reference | 4 | Optional | Integer
GLOBAL_DEPT_NUMBER | Global Department Number | 2 | Optional | Small Integer
HAS_EXTERNAL_LINK | Has External Link | 2 | Optional | Small Integer
INCOTERMS | Incoterms | 2 | Optional | Small Integer
INTRASTAT_STATUS | Intrastat Reconciled Status | 1 | Optional | Byte
INVOICE_FOREIGN_BALANCE | Foreign Balance | 8 | Optional | Double
INVOICE_NUMBER | Corresponding Invoice Number | 7 | Required | String
ITEMS_NET | Net Amount (Goods but not carriage) | 8 | Optional | Double
ITEMS_TAX | Tax Amount (Goods but not carriage) | 8 | Optional | Double
LAST_UPDATED | Last Updated Date | 8 | Optional | Date
NAME | Supplier Account Name | 60 | Optional | String
NOTES_1 | Notes 1 | 60 | Optional | String
NOTES_2 | Notes 2 | 60 | Optional | String
NOTES_3 | Notes 3 | 60 | Optional | String
ORDER_DATE | Order Date | 2 | Required | Date
ORDER_NUMBER | Corresponding Order Number Limited to 7 digits | 4 | Required | Integer
ORDER_TYPE | Order Type Code | 1 | Required | Byte
PAYMENT_REF | Payment Reference | 30 | Optional | String
PAYMENT_TYPE | Payment Type (SR/SA) | 1 | Optional | Byte
POSTED_CODE | Posted Flag - Yes/No | 1 | Optional | Byte
PRACTICE_SOLUTIONS_REFN | Sage Practice Solutions Reference | 60 | Optional | String
PRINTED_CODE | Printed Flag - Yes/No | 1 | Optional | Byte
PROJECT_ID | Project ID Number | 4 | Optional | Integer
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
RECURRING_REFERENCE | Recurring Reference | 11 | Optional | String
SETTLEMENT_DISC_RATE | Settlement Discount % Rate | 8 | Optional | Double
SETTLEMENT_DUE_DAYS | Settlement Days | 2 | Optional | Small Integer
STATUS | Order Status Code | 1 | Optional | Byte
SUPP_DISC_RATE | Supplier Discount | 8 | Optional | Double
SUPP_ORDER_NUMBER | Supplier's Order Number | 60 | Optional | String
SUPP_TEL_NUMBER | Supplier's Telephone Number | 30 | Optional | String
TAKEN_BY | Order Taken By | 60 | Optional | String
TOTAL_BYTES | 4 | Optional | Integer
VAT_REG_NUMBER | VAT registration number | 20 | Optional | String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Reading the Item Lines of an Existing Purchase Order
Adding an Item Line to a Purchase Order


PrepayData

Description

The PrepayData object gives access to the Prepayments (PREPAY.DTA) table.

Applies to

Sage 50 Accounts Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
AMOUNT | Value | 8 | Required | Double
DEPT_NUMBER | Department Number | 2 | Optional | Small Integer
LAST_POSTED | Date Last Posted | 2 | Optional | Date
MONTHS_POSTED | Months Posted | 2 | Optional | Small Integer
MONTHS_TO_POST | Months to Post | 2 | Optional | Small Integer
NAME | Name | 60 | Optional | String
NOMINAL_CODE_1 | Expense Account Nominal Code | 8 | Required | String
NOMINAL_CODE_2 | Control Account Nominal Code | 8 | Required | String
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Creating a New Prepayment Record


PriceData

Description

The PriceData object gives access to the Price (PRICE.DTA) table.

Applies to

Sage 50 Accounts Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
DISCOUNT_TYPE | Price List Calculation Type | 1 | Required | Byte
EXT_REF | Price List External Reference (i.e. Price List Ref or Customer Ref) | 8 | Required | String
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
REFERENCE | Price List Reference | 39 | Required | String
ROUNDER_ADJUSTMENT | Rounding Adjustment | 8 | Optional | Double
ROUNDER_DIRECTION | Rounding Direction | 1 | Required | Byte
ROUNDER_METHOD | Rounding Method | 1 | Required | Byte
ROUNDER_MULTIPLE_OF | Rounding Multiple | 8 | Optional | Double
STOCK_CODE | Stock Code | 30 | Required | String
STORED_PRICE | Price stored for manually recalculated price lists | 8 | Optional | Double
TYPE | Price List Type | 1 | Required | Byte
VALUE | Value or Percentage - depending on discount type | 8 | Optional | Double
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Creating a Customer Price List Price


PriceIndex

Description

The PriceIndex object gives access to the Price index (PRICEIDX.DTA) table.

Applies to

Sage 50 Accounts Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
PRICE_REF | Price Item Reference | 39 | Required | String
RECORD_NUMBER | Record Number in Data File | 4 | Required | Integer
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Creating a Customer Price List Price


PriceRecord

Description

The PriceRecord object gives access to the Price (PRICE.DTA) table and the Price index (PRICEIDX.DTA) table. As an SDORecord object, it encapsulates both the data and index files.

Applies to

Sage 50 Accounts Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
DISCOUNT_TYPE | Price List Calculation Type | 1 | Required | Byte
EXT_REF | Price List External Reference (i.e. Price List Ref or Customer Ref) | 8 | Required | String
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
REFERENCE | Price List Reference | 39 | Required | String
ROUNDER_ADJUSTMENT | Rounding Adjustment | 8 | Optional | Double
ROUNDER_DIRECTION | Rounding Direction | 1 | Required | Byte
ROUNDER_METHOD | Rounding Method | 1 | Required | Byte
ROUNDER_MULTIPLE_OF | Rounding Multiple | 8 | Optional | Double
STOCK_CODE | Stock Code | 30 | Required | String
STORED_PRICE | Price stored for manually recalculated price lists | 8 | Optional | Double
TYPE | Price List Type | 1 | Required | Byte
VALUE | Value or Percentage - depending on discount type | 8 | Optional | Double
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Creating a Customer Price List Price


PriceListData

Description

The PriceListData object gives access to the Invoice (PRLST.DTA) table.

Applies to

Sage 50 Accounts Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
CURRENCY | Price List Currency | 1 | Required | Byte
HAS_STATIC_PRICES | Prices Remain Static | 1 | Required | Byte
IMPORT_FILE | Default Pathname for Import File | 259 | Optional | String
LAST_UPDATED | Date of Last Update | 2 | Required | Date
NAME | Price List Name | 60 | Required | String
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
REFERENCE | Price List Reference | 8 | Required | String
TYPE | Price List Type | 1 | Required | Byte
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Creating a New Price List Record
Creating a New Customer Price List Price


PriceListIndex

Description

The PriceListIndex object gives access to the Price List index (PRLSTIDX.DTA) table.

Applies to

Sage 50 Accounts Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
RECORD_NUMBER | Record Number in Data File | 4 | Required | Integer
REFERENCE | Price List Reference | 8 | Required | String
TYPE | Price List Type | 1 | Required | Byte
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Creating a New Price List Record
Creating a New Customer Price List Price


PriceListRecord

Description

The PriceListRecord object gives access to the Price List (PRLST.DTA) table and the Price List index (PRLSTIDX.DTA) table. As an SDORecord object, it encapsulates both the data and index files.

Applies to

Sage 50 Accounts Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
CURRENCY | Price List Currency | 1 | Required | Byte
HAS_STATIC_PRICES | Prices Remain Static | 1 | Required | Byte
IMPORT_FILE | Default Pathname for Import File | 259 | Optional | String
LAST_UPDATED | Date of Last Update | 2 | Required | Date
NAME | Price List Name | 60 | Required | String
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
REFERENCE | Price List Reference | 8 | Required | String
TYPE | Price List Type | 1 | Required | Byte
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Creating a New Price List Record
Creating a New Customer Price List Price


Pricing

Description

The Pricing object provides a simple interface to determine the price of a particular stock item for a single customer or supplier.

Applies To

Sage 50 Accounts Standard and Professional.

Fields Collection

The object has no fields collection.

Methods

The object has the following methods:

Methods | Description
CustomerUnitPrice | Calculates the price of a product for a given customer, taking into account any customer special prices or price list prices where applicable.
SupplierUnitPrice | Calculates the price of a product for a given supplier, taking into account any supplier price list prices where applicable.

Properties

The object has no properties.

Examples using this object:

Generating a Customer Best Price
Generating a Supplier Best Price


PurchaseIndex

PurchaseActiveIndex

Description

The PurchaseActiveIndex object gives access to the Purchase (PURCHASE_ACTIVE_INDEX.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Account Reference | 8 | Required | String
RECORD_NUMBER | Record Number in Data File | 4 | Required | Integer
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object


PurchaseData

Description

The PurchaseData object gives access to the Suppliers (PURCHASE.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_MANAGER | Name of Account Manager | 60 | Optional | String
ACCOUNT_ON_HOLD | Account On Hold | 1 | Optional | Byte
ACCOUNT_OPENED | Date Account Opened | 2 | Optional | Date
ACCOUNT_REF | Account Reference | 8 | Required | String
ACCOUNT_STATUS | Account Status | 2 | Optional | Small Integer
ACCOUNT_TYPE | Account Type | 2 | Optional | Small Integer
ADDRESS_1 | Account Address Line 1 | 60 | Optional | String
ADDRESS_2 | Account Address Line 2 | 60 | Optional | String
ADDRESS_3 | Account Address Line 3 | 60 | Optional | String
ADDRESS_4 | Account Address Line 4 | 60 | Optional | String
ADDRESS_5 | Account Address Line 5 | 60 | Optional | String
ANALYSIS_1 | Analysis 1 | 30 | Optional | String
ANALYSIS_2 | Analysis 2 | 30 | Optional | String
ANALYSIS_3 | Analysis 3 | 30 | Optional | String
ANALYSIS_4 | Analysis 4 | 30 | Optional | String
ANALYSIS_5 | Analysis 5 | 30 | Optional | String
ANALYSIS_6 | Analysis 6 | 30 | Optional | String
BACS | BACS Online Receipts Flag | 2 | Optional | Small Integer
BACS_REFERENCE | Reference for BACS Transfer | 60 | Optional | String
BALANCE | Balance | 8 | Optional | Double
BANK_ACCOUNT_NAME | Bank Account Name | 60 | Optional | String
BANK_ACCOUNT_NUMBER | Bank Account Number | 60 | Optional | String
BANK_ADDITIONAL_REF1 | Bank Additional Ref 1 | 60 | Optional | String
BANK_ADDITIONAL_REF2 | Bank Additional Ref 2 | 60 | Optional | String
BANK_ADDITIONAL_REF3 | Bank Additional Ref 3 | 60 | Optional | String
BANK_ADDRESS_1 | Bank Address 1 | 60 | Optional | String
BANK_ADDRESS_2 | Bank Address 2 | 60 | Optional | String
BANK_ADDRESS_3 | Bank Address 3 | 60 | Optional | String
BANK_ADDRESS_4 | Bank Address 4 | 60 | Optional | String
BANK_ADDRESS_5 | Bank Address 5 | 60 | Optional | String
BANK_BICSWIFT | Bank BIC/Swift | 60 | Optional | String
BANK_IBAN | Bank IBAN Number | 60 | Optional | String
BANK_NAME | Bank Name | 60 | Optional | String
BANK_ROLL_NUMBER | Bank Roll Number | 60 | Optional | String
BANK_SORT_CODE | Bank Sort Code | 10 | Optional | String
BUILD_SOCIETY_REF | Reference for Building Society Transfer | 60 | Optional | String
BUILDING_SOCIETY | Account uses Building Society | 2 | Optional | Small Integer
CAN_APPLY_CHARGES | Can Charge Credit | 2 | Optional | Small Integer
COMPANY_REGISTRATION_NUMBER | Company Reg. Number | 16 | Optional | String
CONTACT_NAME | Contact Name | 30 | Optional | String
COUNTRY_CODE | Country Code | 2 | Optional | String
CREDIT_APP_RECEIVED | True if Credit Application Received | 2 | Optional | Small Integer
CREDIT_APPLIED_FOR | Date Credit Applied For | 2 | Optional | Date
CREDIT_BF | Credits Brought Forward | 8 | Optional | Double
CREDIT_BUREAU | Credit Bureau Used | 2 | Optional | Small Integer
CREDIT_CARD_NO | Credit Card Number | 30 | Optional | String
CREDIT_CF | Credits Carried Forward | 8 | Optional | Double
CREDIT_LIMIT | Credit Limit | 8 | Optional | Double
CREDIT_MTH1 | Credit Month 1 | 8 | Optional | Double
CREDIT_MTH10 | Credit Month 10 | 8 | Optional | Double
CREDIT_MTH11 | Credit Month 11 | 8 | Optional | Double
CREDIT_MTH12 | Credit Month 12 | 8 | Optional | Double
CREDIT_MTH2 | Credit Month 2 | 8 | Optional | Double
CREDIT_MTH3 | Credit Month 3 | 8 | Optional | Double
CREDIT_MTH4 | Credit Month 4 | 8 | Optional | Double
CREDIT_MTH5 | Credit Month 5 | 8 | Optional | Double
CREDIT_MTH6 | Credit Month 6 | 8 | Optional | Double
CREDIT_MTH7 | Credit Month 7 | 8 | Optional | Double
CREDIT_MTH8 | Credit Month 8 | 8 | Optional | Double
CREDIT_MTH9 | Credit Month 9 | 8 | Optional | Double
CREDIT_POSITION | Credit Position | 2 | Optional | Small Integer
CREDIT_REFERENCE | Credit Bureau Reference | 60 | Optional | String
CURRENCY | Currency | 1 | Optional | Byte
DATE_CREDIT_APP_RECEIVED | Date Credit Application Received | 2 | Optional | Date
DECLARATION_VALID_FROM | Donor Declaration Valid From | 2 | Optional | Date
DEF_NOM_CODE | Default Nominal Code | 8 | Optional | String
DEF_TAX_CODE | Default Tax Code | 2 | Optional | Small Integer
DEL_ADDRESS_1 | Delivery Address Line 1 | 60 | Optional | String
DEL_ADDRESS_2 | Delivery Address Line 2 | 60 | Optional | String
DEL_ADDRESS_3 | Delivery Address Line 3 | 60 | Optional | String
DEL_ADDRESS_4 | Delivery Address Line 4 | 60 | Optional | String
DEL_ADDRESS_5 | Delivery Address Line 5 | 60 | Optional | String
DEL_CONTACT_NAME | Delivery Contact Name | 30 | Optional | String
DEL_FAX | Delivery Fax Number | 30 | Optional | String
DEL_NAME | Delivery Name | 60 | Optional | String
DEL_TELEPHONE | Delivery Telephone Number | 30 | Optional | String
DELETED_FLAG | Reserved for Future Use | 2 | Optional | Small Integer
DEPT_NUMBER | Department Number | 2 | Optional | Small Integer
DISCOUNT_RATE | Discount Rate | 8 | Optional | Double
DISCOUNT_TYPE | Discount Type | 1 | Optional | Byte
DISPUTED | Disputed | 4 | Optional | Integer
DONOR_FORENAME | Donor Forename | 35 | Optional | String
DONOR_SURNAME | Donor Surname | 35 | Optional | String
DONOR_TITLE | Donor Title | 4 | Optional | String
DUNS_NUMBER | DUNS_NUMBER | 9 | Optional | String
E_MAIL | EMail Address | 255 | Optional | String
E_MAIL2 | EMail Address 2 | 255 | Optional | String
E_MAIL3 | EMail Address 3 | 255 | Optional | String
E_MAIL4 | EMail Address 4 | 255 | Optional | String
E_MAIL5 | EMail Address 5 | 255 | Optional | String
E_MAIL6 | EMail Address 6 | 255 | Optional | String
EC_CODE | EC Member Code | 3 | Optional | String
EORI_NUMBER | EORI number | 17 | Optional | String
EXTERNAL_USAGE | Number of External Usages for this Record | 4 | Optional | Integer
FACEBOOK | Facebook Address | 75 | Optional | String
FAX | Fax Number | 30 | Optional | String
FIRST_HEADER | Record Number of First Transaction | 4 | Optional | Integer
FIRST_INVOICE | First Invoice Date | 2 | Optional | Date
GIFT_AID_ENABLED | Gift aid is enabled | 2 | Optional | Small Integer
HOLD_MAIL | Restrict Mail | 2 | Optional | Small Integer
INACTIVE_FLAG | Inactive Flag - yes/No | 1 | Optional | Byte
INCOTERMS | Incoterms | 2 | Optiona | Small Integer
INVOICE_BF | Invoices Brought Forward | 8 | Optional | Double
INVOICE_CF | Invoices Carry Forward | 8 | Optional | Double
INVOICE_MTH1 | Invoices Month 1 | 8 | Optional | Double
INVOICE_MTH10 | Invoices Month 10 | 8 | Optional | Double
INVOICE_MTH11 | Invoices Month 11 | 8 | Optional | Double
INVOICE_MTH12 | Invoices Month 12 | 8 | Optional | Double
INVOICE_MTH2 | Invoices Month 2 | 8 | Optional | Double
INVOICE_MTH3 | Invoices Month 3 | 8 | Optional | Double
INVOICE_MTH4 | Invoices Month 4 | 8 | Optional | Double
INVOICE_MTH5 | Invoices Month 5 | 8 | Optional | Double
INVOICE_MTH6 | Invoices Month 6 | 8 | Optional | Double
INVOICE_MTH7 | Invoices Month 7 | 8 | Optional | Double
INVOICE_MTH8 | Invoices Month 8 | 8 | Optional | Double
INVOICE_MTH9 | Invoices Month 9 | 8 | Optional | Double
LAST_CREDIT_REV | Date Last Credit Review | 2 | Optional | Date
LAST_HEADER | Record Number of Last Transaction | 4 | Optional | Integer
LAST_INV_DATE | Last Invoice Date | 2 | Optional | Date
LAST_PAY_DATE | Last Payment Date | 2 | Optional | Date
LAST_UPDATED | Last Updated Date | 8 | Optional | Date
LINKEDIN | LinkedIn Address | 64 | Optional | String
MANDATEREF | Direct Debit Mandate Ref | 25 | Optional | String
MEMBER_REMINDER_DATE | Member Reminder Date | 2 | Optional | Integer
MEMBER_RENEWAL_DATE | Member Renewal Date | 2 | Optional | Date
MEMBER_SINCE | Member Since | 2 | Optional | Date
MEMO_OFFSET | Offset in Credit Memo File | 4 | Optional | Integer
MEMO_SIZE | Size of Memo in bytes | 4 | Optional | Integer
MODIFY | Modified Count | 4 | Optional | Integer
NAME | Account Name | 60 | Optional | String
NEXT_CREDIT_REV | Date Next Credit Review | 2 | Optional | Date
NO_OF_HEADER | Number of Transactions | 4 | Optional | Integer
OVERRIDE_PRODUCT_NOMINAL | Override Product Nominal Code in Invoicing | 1 | Optional | Byte
OVERRIDE_PRODUCT_TAX | Override Product Tax Code in Invoicing | 1 | Optional | Byte
PAYMENT_BF | Payments Brought Forward | 8 | Optional | Double
PAYMENT_CF | Payments Carry Forward | 8 | Optional | Double
PAYMENT_DUE_DAYS | Payment Due Days | 2 | Optional | Small Integer
PAYMENT_DUE_FROM | Payment Due From | 2 | Optional | Small Integer
PAYMENT_MTH1 | Payments Month 1 | 8 | Optional | Double
PAYMENT_MTH10 | Payments Month 10 | 8 | Optional | Double
PAYMENT_MTH11 | Payments Month 11 | 8 | Optional | Double
PAYMENT_MTH12 | Payments Month 12 | 8 | Optional | Double
PAYMENT_MTH2 | Payments Month 2 | 8 | Optional | Double
PAYMENT_MTH3 | Payments Month 3 | 8 | Optional | Double
PAYMENT_MTH4 | Payments Month 4 | 8 | Optional | Double
PAYMENT_MTH5 | Payments Month 5 | 8 | Optional | Double
PAYMENT_MTH6 | Payments Month 6 | 8 | Optional | Double
PAYMENT_MTH7 | Payments Month 7 | 8 | Optional | Double
PAYMENT_MTH8 | Payments Month 8 | 8 | Optional | Double
PAYMENT_MTH9 | Payments Month 9 | 8 | Optional | Double
PAYMENT_TYPE | Payment Type | 4 | Optional | Integer
PRICE_LIST_REF | Price List Reference | 8 | Optional | String
PRIOR_YEAR | Prior YTD | 8 | Optional | Double
PRIORITY_TRADER | Priority Supplier | 2 | Optional | Small Integer
RECEIPT_BF | Receipts Brought Forward | 8 | Optional | Double
RECEIPT_CF | Receipts Carry Forward | 8 | Optional | Double
RECEIPT_MTH1 | Receipts Month 1 | 8 | Optional | Double
RECEIPT_MTH2 | Receipts Month 2 | 8 | Optional | Double
RECEIPT_MTH3 | Receipts Month 3 | 8 | Optional | Double
RECEIPT_MTH4 | Receipts Month 4 | 8 | Optional | Double
RECEIPT_MTH5 | Receipts Month 5 | 8 | Optional | Double
RECEIPT_MTH6 | Receipts Month 6 | 8 | Optional | Double
RECEIPT_MTH7 | Receipts Month 7 | 8 | Optional | Double
RECEIPT_MTH8 | Receipts Month 8 | 8 | Optional | Double
RECEIPT_MTH9 | Receipts Month 9 | 8 | Optional | Double
RECEIPT_MTH10 | Receipts Month 10 | 8 | Optional | Double
RECEIPT_MTH11 | Receipts Month 11 | 8 | Optional | Double
RECEIPT_MTH12 | Receipts Month 12 | 8 | Optional | Double
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
SALES_REP | Name of Sales Representative | 60 | Optional | String
SEND_INVOICES_ELECTRONICALLY | Send Invoices to this account via email | 2 | Optional | Small Integer
SEND_LETTERS_ELECTRONICALLY | Send Letters to this account via email | 2 | Optional | Small Integer
SETTLEMENT_DISC_RATE | Settlement Discount Rate | 8 | Optional | Double
SETTLEMENT_DUE_DAYS | Settlement Due Days | 2 | Optional | Small Integer
TELEPHONE | Telephone Number | 30 | Optional | String
TELEPHONE_2 | Second Telephone Number | 30 | Optional | String
TERMS | Terms | 30 | Optional | String
TERMS_AGREED_FLAG | Terms Agreed Flag | 2 | Optional | Small Integer
TRADER_FOREIGN_BALANCE | Foreign Balance | 8 | Optional | Double
TRADE_CONTACT | Name of Trade Contact | 30 | Optional | String
TURNOVER_MTD | Turnover Month To Date | 8 | Optional | Double
TURNOVER_YTD | Turnover Year Date | 8 | Optional | Double
TWITTER | Twitter Address | 35 | Optional | String
VAT_REG_NUMBER | VAT Registration Number | 20 | Optional | String
WWW | WWW Address | 255 | Optional | String

Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Creating a New Supplier Record
Editing an Existing Supplier Record
Deleting an Existing Supplier Record
Accessing a Supplier Memo
Creating a New Fixed Asset Record
Posting a Purchase Payment
Posting a Supplier Batch Purchase Credit Note
Posting a Supplier Batch Purchase Invoice
Creating a New Fixed Asset Record
Creating a Supplier Delivery Address
Posting a Foreign Currency Purchase Credit Note
Posting a Foreign Currency Purchase Invoice
Posting a Foreign Currency Purchase Payment
Posting a Purchase Payment
Posting a Foreign Currency Purchase Order


PurchaseDeliveryData

Description

The PurchaseDeliveryData object gives access to the Supplier Delivery Address (PURDA.DTA) table.

Applies to

Sage 50 Accounts Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Supplier Account Reference | 8 | Required | String
ADDRESS_1 | Delivery Address Line 1 | 60 | Optional | String
ADDRESS_2 | Delivery Address Line 2 | 60 | Optional | String
ADDRESS_3 | Delivery Address Line 3 | 60 | Optional | String
ADDRESS_4 | Delivery Address Line 4 | 60 | Optional | String
ADDRESS_5 | Delivery Address Line 5 | 60 | Optional | String
ADDRESS_REF | Address Reference Number | 2 | Required | Small Integer
ADDRESS_TYPE | Address Type | 1 | Required | Byte
CONTACT_NAME | Contact Name | 30 | Optional | String
CONTACT_ROLE | Contact Role | 30 | Optional | String
COUNTRY_CODE | Country Code | 2 | Required | String
DEFAULT_REF | Default Indicator | 2 | Required | Small Integer
DESCRIPTION | Description | 60 | Required | String
EMAIL | EMail Address | 255 | Optional | String
FAX | Fax Number | 30 | Optional | String
NAME | Name | 60 | Required | String
NOTES | Notes | 200 | Optional | String
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
REFERENCE | Delivery Address Reference | 12 | Required | String
TAX_CODE | Tax Code | 2 | Required | Small Integer
TELEPHONE | Telephone Number | 30 | Optional | String
TELEPHONE_2 | Telephone Number2 | 30 | Optional | String
VAT_NUMBER | Vat Registration Number | 20 | Optional | String

Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Creating a Supplier Delivery Address
Example - Looping through supplier delivery addresses


PurchaseDeliveryIndex

Description

The PurchaseDeliveryIndex object gives access to the Supplier Delivery Address Index (PURDAIDX.DTA) table.

Applies to

Sage 50 Accounts Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
RECORD_NUMBER | Record Number in Data File | 4 | Required | Integer
REFERENCE | Delivery Address Reference | 12 | Required | String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Creating a Supplier Delivery Address
Example - Looping through supplier delivery addresses


PurchaseDeliveryRecord

Description

The PurchaseDeliveryRecord object gives access to the Supplier Delivery Address (PURDA.DTA) table and the Supplier Delivery Address Index (PURDAIDX.DTA) table. As an SDORecord object, it encapsulates both the data and index files.

Applies to

Sage 50 Accounts Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Supplier Account Reference | 8 | Required | String
ADDRESS_1 | Delivery Address Line 1 | 60 | Optional | String
ADDRESS_2 | Delivery Address Line 2 | 60 | Optional | String
ADDRESS_3 | Delivery Address Line 3 | 60 | Optional | String
ADDRESS_4 | Delivery Address Line 4 | 60 | Optional | String
ADDRESS_5 | Delivery Address Line 5 | 60 | Optional | String
ADDRESS_REF | Address Reference Number | 2 | Required | Small Integer
ADDRESS_TYPE | Address Type | 1 | Required | Byte
CONTACT_NAME | Contact Name | 30 | Optional | String
CONTACT_ROLE | Contact Role | 30 | Optional | String
COUNTRY_CODE | Country Code | 2 | Required | String
DEFAULT_REF | Default Indicator | 2 | Required | Small Integer
DESCRIPTION | Description | 60 | Required | String
EMAIL | EMail Address | 255 | Optional | String
FAX | Fax Number | 30 | Optional | String
NAME | Name | 60 | Required | String
NOTES | Notes | 200 | Optional | String
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
REFERENCE | Delivery Address Reference | 12 | Required | String
TAX_CODE | Tax Code | 2 | Required | Small Integer
TELEPHONE | Telephone Number | 30 | Optional | String
TELEPHONE_2 | Telephone Number2 | 30 | Optional | String
VAT_NUMBER | Vat Registration Number | 20 | Optional | String

Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Creating a Supplier Delivery Address
Example - Looping through supplier delivery addresses


PurchaseIndex

Description

The PurchaseIndex object gives access to the Purchase (PURINDEX.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Account Reference | 8 | Required | String
RECORD_NUMBER | Record Number in Data File | 4 | Required | Integer
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Creating a New Supplier Record
Editing an Existing Supplier Record
Deleting an Existing Supplier Record
Accessing a Supplier Memo
Creating a New Fixed Asset Record
Creating a Supplier Delivery Address
Posting a Foreign Currency Purchase Credit Note
Posting a Foreign Currency Purchase Invoice
Posting a Foreign Currency Purchase Payment
Posting a Purchase Payment
Posting a Foreign Currency Purchase Order


PurchaseRecord

Description

The PurchaseRecord object gives access to the Purchase (PURCHASE.DTA) table and the Purchase index (PURINDEX.DTA) table. As an SDORecord object, it encapsulates both the data and index files.

New Method

The PurchaseRecord (and SalesRecord) objects have a new method (GetAgedBalances) to return an AgedBalances object.

Notes on address fields

The DEL_ADDRESS_x and ADDRESS_x fields have been superceded from version 2009 and above by the SupplierAddress Business Object. Previously entered addresses have not been removed and are available to read and write via these fields, however it is recommended that the Business Object is used instead.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_MANAGER | Name of Account Manager | 60 | Optional | String
ACCOUNT_ON_HOLD | Account On Hold | 1 | Optional | Byte
ACCOUNT_OPENED | Date Account Opened | 2 | Optional | Date
ACCOUNT_REF | Account Reference | 8 | Required | String
ACCOUNT_STATUS | Account Status | 2 | Optional | Small Integer
ACCOUNT_TYPE | Account Type | 2 | Optional | Small Integer
ADDRESS_1 | Registered Address Line1 | 60 | Optional | String
ADDRESS_2 | Registered Address Line2 | 60 | Optional | String
ADDRESS_3 | Registered Address Line3 | 60 | Optional | String
ADDRESS_4 | Registered Address Line4 | 60 | Optional | String
ADDRESS_5 | Registered Address Line5 | 60 | Optional | String
ANALYSIS_1 | Analysis 1 | 30 | Optional | String
ANALYSIS_2 | Analysis 2 | 30 | Optional | String
ANALYSIS_3 | Analysis 3 | 30 | Optional | String
ANALYSIS_4 | Analysis 4 | 30 | Optional | String
ANALYSIS_5 | Analysis 5 | 30 | Optional | String
ANALYSIS_6 | Analysis 6 | 30 | Optional | String
BACS | BACS Online Receipts Flag | 2 | Optional | Small Integer
BACS_REFERENCE | Reference for BACS Transfer | 60 | Optional | String
BALANCE | Balance | 8 | Optional | Double
BANK_ACCOUNT_NAME | Bank Account Name | 60 | Optional | String
BANK_ACCOUNT_NUMBER | Bank Account Number | 60 | Optional | String
BANK_ADDITIONAL_REF1 | Bank Additional Ref 1 | 60 | Optional | String
BANK_ADDITIONAL_REF2 | Bank Additional Ref 2 | 60 | Optional | String
BANK_ADDITIONAL_REF3 | Bank Additional Ref 3 | 60 | Optional | String
BANK_ADDRESS_1 | Bank Address 1 | 60 | Optional | String
BANK_ADDRESS_2 | Bank Address 2 | 60 | Optional | String
BANK_ADDRESS_3 | Bank Address 3 | 60 | Optional | String
BANK_ADDRESS_4 | Bank Address 4 | 60 | Optional | String
BANK_ADDRESS_5 | Bank Address 5 | 60 | Optional | String
BANK_BICSWIFT | Bank BIC/Swift | 60 | Optional | String
BANK_IBAN | Bank IBAN Number | 60 | Optional | String
BANK_NAME | Bank Name | 60 | Optional | String
BANK_ROLL_NUMBER | Bank Roll Number | 60 | Optional | String
BANK_SORT_CODE | Bank Sort Code | 10 | Optional | String
BUILD_SOCIETY_REF | Reference for Building Society Transfer | 60 | Optional | String
BUILDING_SOCIETY | Account uses Building Society | 2 | Optional | Small Integer
CAN_APPLY_CHARGES | Can Charge Credit | 2 | Optional | Small Integer
COMPANY_REGISTRATION_NUMBER | Company Reg. Number | 16 | Optional | String
CONTACT_NAME | Contact Name | 30 | Optional | String
COUNTRY_CODE | Country Code | 2 | Optional | String
CREDIT_APP_RECEIVED | True if Credit Application Received | 2 | Optional | Small Integer
CREDIT_APPLIED_FOR | Date Credit Applied For | 2 | Optional | Date
CREDIT_BF | Credits Brought Forward | 8 | Optional | Double
CREDIT_BUREAU | Credit Bureau Used | 2 | Optional | Small Integer
CREDIT_CARD_NO | Credit Card Number | 30 | Optional | String
CREDIT_CF | Credits Carried Forward | 8 | Optional | Double
CREDIT_LIMIT | Credit Limit | 8 | Optional | Double
CREDIT_MTH1 | Credit Month 1 | 8 | Optional | Double
CREDIT_MTH10 | Credit Month 10 | 8 | Optional | Double
CREDIT_MTH11 | Credit Month 11 | 8 | Optional | Double
CREDIT_MTH12 | Credit Month 12 | 8 | Optional | Double
CREDIT_MTH2 | Credit Month 2 | 8 | Optional | Double
CREDIT_MTH3 | Credit Month 3 | 8 | Optional | Double
CREDIT_MTH4 | Credit Month 4 | 8 | Optional | Double
CREDIT_MTH5 | Credit Month 5 | 8 | Optional | Double
CREDIT_MTH6 | Credit Month 6 | 8 | Optional | Double
CREDIT_MTH7 | Credit Month 7 | 8 | Optional | Double
CREDIT_MTH8 | Credit Month 8 | 8 | Optional | Double
CREDIT_MTH9 | Credit Month 9 | 8 | Optional | Double
CREDIT_POSITION | Credit Position | 2 | Optional | Small Integer
CREDIT_REFERENCE | Credit Bureau Reference | 60 | Optional | String
CURRENCY | Currency | 1 | Optional | Byte
DATE_CREDIT_APP_RECEIVED | Date Credit Application Received | 2 | Optional | Date
DECLARATION_VALID_FROM | Donor Declaration Valid From | 2 | Optional | Date
DEF_NOM_CODE | Default Nominal Code | 8 | Optional | String
DEF_TAX_CODE | Default Tax Code | 2 | Optional | Small Integer
DEL_ADDRESS_1 | Default Delivery Address Line1 | 60 | Optional | String
DEL_ADDRESS_2 | Default Delivery Address Line2 | 60 | Optional | String
DEL_ADDRESS_3 | Default Delivery Address Line3 | 60 | Optional | String
DEL_ADDRESS_4 | Default Delivery Address Line4 | 60 | Optional | String
DEL_ADDRESS_5 | Default Delivery Address Line5 | 60 | Optional | String
DEL_CONTACT_NAME | Default Delivery Contact Name | 30 | Optional | String
DEL_FAX | Default Delivery Fax Number | 30 | Optional | String
DEL_NAME | Default Delivery Name | 60 | Optional | String
DEL_TELEPHONE | Default Delivery Telephone Number | 30 | Optional | String
DELETED_FLAG | Reserved for Future Use | 2 | Optional | Small Integer
DEPT_NUMBER | Department Number | 2 | Optional | Small Integer
DISCOUNT_RATE | Discount Rate | 8 | Optional | Double
DISCOUNT_TYPE | Discount Type - Not Applicable to Supplier Records | 1 | Optional | Byte
DISPUTED | Disputed | 4 | Optional | Integer

DONOR_FORENAME

 Donor Forename 35 Optional String

DONOR_SURNAME

 Donor Surname 35 Optional String

DONOR_TITLE

 Donor Title 4 Optional String
DUNS_NUMBER | Duns Number | 9 | Optional | String
E_MAIL | EMail Address | 255 | Optional | String
E_MAIL2 | EMail Address 2 | 255 | Optional | String
E_MAIL3 | EMail Address 3 | 255 | Optional | String
E_MAIL4 | EMail Address 4 | 255 | Optional | String
E_MAIL5 | EMail Address 5 | 255 | Optional | String
E_MAIL6 | EMail Address 6 | 255 | Optional | String
EC_CODE | EC Member Code | 3 | Optional | String
EORI_NUMBER | EORI number | 17 | Optional | String
EXTERNAL_USAGE | Number of External Usages for this Record | 4 | Optional | Integer
FACEBOOK | Facebook Address | 75 | Optional | String
FAX | Fax Number | 30 | Optional | String
FIRST_HEADER | Record Number of First Transaction | 4 | Optional | Integer
FIRST_INVOICE | First Invoice Date | 2 | Optional | Date
GIFT_AID_ENABLED | Gift aid is enabled | 2 | Optional | Small Integer
HOLD_MAIL | Restrict Mail | 2 | Optional | Small Integer
INACTIVE_FLAG | Inactive Flag - yes/No | 1 | Optional | Byte
INCOTERMS | Incoterms | 2 | Optional | Small Integer
INVOICE_BF | Invoices Brought Forward | 8 | Optional | Double
INVOICE_CF | Invoices Carry Forward | 8 | Optional | Double
INVOICE_MTH1 | Invoices Month 1 | 8 | Optional | Double
INVOICE_MTH10 | Invoices Month 10 | 8 | Optional | Double
INVOICE_MTH11 | Invoices Month 11 | 8 | Optional | Double
INVOICE_MTH12 | Invoices Month 12 | 8 | Optional | Double
INVOICE_MTH2 | Invoices Month 2 | 8 | Optional | Double
INVOICE_MTH3 | Invoices Month 3 | 8 | Optional | Double
INVOICE_MTH4 | Invoices Month 4 | 8 | Optional | Double
INVOICE_MTH5 | Invoices Month 5 | 8 | Optional | Double
INVOICE_MTH6 | Invoices Month 6 | 8 | Optional | Double
INVOICE_MTH7 | Invoices Month 7 | 8 | Optional | Double
INVOICE_MTH8 | Invoices Month 8 | 8 | Optional | Double
INVOICE_MTH9 | Invoices Month 9 | 8 | Optional | Double
LAST_CREDIT_REV | Date Last Credit Review | 2 | Optional | Date
LAST_HEADER | Record Number of Last Transaction | 4 | Optional | Integer
LAST_INV_DATE | Last Invoice Date | 2 | Optional | Date
LAST_PAY_DATE | Last Payment Date | 2 | Optional | Date
LAST_UPDATED | Last Updated Date | 8 | Optional | Date
LINKEDIN | LinkedIn Address | 64 | Optional | String
MANDATEREF | Direct Debit Mandate Ref | 25 | Optional | String
MEMBER_REMINDER_DATE | Member Reminder Date | 2 | Optional | Integer
MEMBER_RENEWAL_DATE | Member Renewal Date | 2 | Optional | Date
MEMBER_SINCE | Member Since | 2 | Optional | Date
MEMO_OFFSET | Offset in Credit Memo File | 4 | Optional | Integer
MEMO_SIZE | Size of Memo in bytes | 4 | Optional | Integer
MODIFY | Modified Count | 4 | Optional | Integer
NAME | Account Name | 60 | Optional | String
NEXT_CREDIT_REV | Date Next Credit Review | 2 | Optional | Date
NO_OF_HEADER | Number of Transactions | 4 | Optional | Integer
OVERRIDE_PRODUCT_NOMINAL | Override Product Nominal Code in Invoicing | 1 | Optional | Byte
OVERRIDE_PRODUCT_TAX | Override Product Tax Code in Invoicing | 1 | Optional | Byte
PAYMENT_BF | Payments Brought Forward | 8 | Optional | Double
PAYMENT_CF | Payments Carry Forward | 8 | Optional | Double
PAYMENT_DUE_DAYS | Payment Due Days | 2 | Optional | Small Integer
PAYMENT_DUE_FROM | Payment Due From | 2 | Optional | Small Integer
PAYMENT_MTH1 | Payments Month 1 | 8 | Optional | Double
PAYMENT_MTH10 | Payments Month 10 | 8 | Optional | Double
PAYMENT_MTH11 | Payments Month 11 | 8 | Optional | Double
PAYMENT_MTH12 | Payments Month 12 | 8 | Optional | Double
PAYMENT_MTH2 | Payments Month 2 | 8 | Optional | Double
PAYMENT_MTH3 | Payments Month 3 | 8 | Optional | Double
PAYMENT_MTH4 | Payments Month 4 | 8 | Optional | Double
PAYMENT_MTH5 | Payments Month 5 | 8 | Optional | Double
PAYMENT_MTH6 | Payments Month 6 | 8 | Optional | Double
PAYMENT_MTH7 | Payments Month 7 | 8 | Optional | Double
PAYMENT_MTH8 | Payments Month 8 | 8 | Optional | Double
PAYMENT_MTH9 | Payments Month 9 | 8 | Optional | Double
PAYMENT_TYPE | Payment Type | 4 | Optional | Integer
PRICE_LIST_REF | Price List Reference | 8 | Optional | String
PRIOR_YEAR | Prior YTD | 8 | Optional | Double
PRIORITY_TRADER | Priority Supplier | 2 | Optional | Small Integer
RECEIPT_BF | Receipts Brought Forward | 8 | Optional | Double
RECEIPT_CF | Receipts Carry Forward | 8 | Optional | Double
RECEIPT_MTH1 | Receipts Month 1 | 8 | Optional | Double
RECEIPT_MTH2 | Receipts Month 2 | 8 | Optional | Double
RECEIPT_MTH3 | Receipts Month 3 | 8 | Optional | Double
RECEIPT_MTH4 | Receipts Month 4 | 8 | Optional | Double
RECEIPT_MTH5 | Receipts Month 5 | 8 | Optional | Double
RECEIPT_MTH6 | Receipts Month 6 | 8 | Optional | Double
RECEIPT_MTH7 | Receipts Month 7 | 8 | Optional | Double
RECEIPT_MTH8 | Receipts Month 8 | 8 | Optional | Double
RECEIPT_MTH9 | Receipts Month 9 | 8 | Optional | Double
RECEIPT_MTH10 | Receipts Month 10 | 8 | Optional | Double
RECEIPT_MTH11 | Receipts Month 11 | 8 | Optional | Double
RECEIPT_MTH12 | Receipts Month 12 | 8 | Optional | Double
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
SALES_REP | Name of Sales Representative | 60 | Optional | String
SEND_INVOICES_ELECTRONICALLY | Flag Set If Customer Is to Receive Invoice Via Email | 2 | Optional | Small Integer
SEND_LETTERS_ELECTRONICALLY | Flag Set If Customer Is to Receive Letters Via Email | 2 | Optional | Small Integer
SETTLEMENT_DISC_RATE | Settlement Discount Rate | 8 | Optional | Double
SETTLEMENT_DUE_DAYS | Settlement Due Days | 2 | Optional | Small Integer
TELEPHONE | Telephone Number | 30 | Optional | String
TELEPHONE_2 | Second Telephone Number | 30 | Optional | String
TERMS | Terms | 30 | Optional | String
TERMS_AGREED_FLAG | Terms Agreed Flag | 2 | Optional | Small Integer
TRADE_CONTACT | Name of Trade Contact | 30 | Optional | String
TRADER_FOREIGN_BALANCE | Foreign Balance | 8 | Optional | Double
TURNOVER_MTD | Turnover Month To Date | 8 | Optional | Double
TURNOVER_YTD | Turnover Year Date | 8 | Optional | Double
TWITTER | Twitter Address | 35 | Optional | String
VAT_REG_NUMBER | VAT Registration Number | 20 | Optional | String
WWW | WWW Address | 255 | Optional | String

Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Creating a New Supplier Record
Editing an Existing Supplier Record
Deleting an Existing Supplier Record
Accessing a Supplier Memo
Creating a New Fixed Asset Record
Creating a Supplier Delivery Address
Posting a Foreign Currency Purchase Credit Note
Posting a Foreign Currency Purchase Invoice
Posting a Foreign Currency Purchase Payment
Posting a Purchase Payment
Posting a Foreign Currency Purchase Order
� Sage (UK) Ltd Click here to send feedback on this article.


QueueData

Description

The QueueData object gives access to the Queue (QUEUE.DTA) table. This hold all the users who have connected to Sage 50 Accounts whether or not the connection is current and which option in Sage 50 Accounts they are currently using.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Account Reference | 8 | Optional | String
ACTION | Request Type | 2 | Required | Small Integer
DATE | Date of Request | 2 | Required | Date
EMPTY_FLAG | Empty Flag | 2 | Optional | Small Integer
LOGON_NAME | Logon Name | 32 | Required | String
MAX_USER | Maximum Number of Users | 2 | Optional | Small Integer
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
STATION_NAME | Station Name | 32 | Required | String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Example - Reading which users are logged on


RecurringData

Description

The RecurringData object gives access to the Recurring Entries (RECUR.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACTUAL_POSTINGS | Actual Postings to Date | 2 | Optional | Small Integer
BANK_CODE | Bank Account Reference | 8 | Required | String
CUSTOMER | Customer associated with this donation | 8 | Optional | String
DATE_NEXT_POSTING | Next Posting Date | 2 | Optional | Date
DAY_POSTED | Date of Postings | 2 | Optional | Small Integer
DEPARTMENT | Department Number | 2 | Optional | Small Integer
DETAILS | Details | 60 | Optional | String
FREQUENCY | Frequency of Payments | 2 | Optional | Small Integer
FREQUENCY_TYPE | Frequency Type | 2 | Optional | Small Integer
FUND | Fund to post against | 4 | Optional | Integer
NET_AMOUNT | Net Amount | 8 | Required | Double
NOMINAL_CODE | Nominal Code | 8 | Required | String
POSTED_THIS_MONTH | Posted This Month Flag | 1 | Optional | Byte
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
REFERENCE | Transaction Reference | 30 | Optional | String
REQUIRED_POSTINGS | Required Postings | 2 | Optional | Small Integer
START_DATE | Next Posting Date | 2 | Optional | Date
TAX_AMOUNT | Tax Amount | 8 | Optional | Double
TAX_CODE | Tax Code | 2 | Required | Small Integer
TYPE | Transaction Type | 1 | Required | Byte
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Creating a New Recurring Entry


RemittanceData

Description

The RemittanceData object gives access to the Supplier Remittances (REMIT.DTA) table. Despite its name the Remittance Record is used to create cheques that may be sent to a supplier or from the bank. It can be used in conjunction with the BankRemittanceData .

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Supplier Account Reference | 8 | Required | String
ADDRESS_1 | Payee Address Line 1 | 60 | Optional | String
ADDRESS_2 | Payee Address Line 2 | 60 | Optional | String
ADDRESS_3 | Payee Address Line 3 | 60 | Optional | String
ADDRESS_4 | Payee Address Line 4 | 60 | Optional | String
ADDRESS_5 | Payee Address Line 5 | 60 | Optional | String
BANK | Bank Account Reference | 8 | Required | String
CHEQUE_NO | Cheque Number | 8 | Required | String
DATE | Date of Transactions | 2 | Required | Date
DETAILS | Details | 60 | Required | String
FAX | Payee Fax Number | 30 | Optional | String
FOREIGN_RATE | Foreign Exchange Rate | 8 | Required | Double
GROSS_AMOUNT | Transaction Gross Amount | 8 | Required | Double
INDEX | Unique Identifier for Remittance Line | 8 | Required | String
INV_REF | Invoice Reference | 30 | Required | String
LASTLINE_FLAG | Last Line Flag - True if this is the last line of the remittance | 2 | Required | Small Integer
NAME | Payee Name | 60 | Optional | String
NET_AMOUNT | Transaction Net Amount | 8 | Required | Double
PAYMENT_AMOUNT | Transaction Payment | 8 | Required | Double
PAYMENT_DATE | Date of Payment | 2 | Required | Date
PAYMENT_FLAG | Payment Flag | 2 | Required | Small Integer
PAYMENT_NO | Payment Header Transaction Record Number | 4 | Required | Integer
PRINTED_FLAG | Printed Flag | 2 | Required | Small Integer
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
TAX_CODE | Tax Code | 3 | Required | String
TELEPHONE | Payee Telephone Number | 30 | Optional | String
TRAN_TYPE | Transaction Type | 2 | Required | String
URN | Unique Identifier for this Remittance | 8 | Required | String
VAT_AMOUNT | Transaction Vat Amount | 8 | Required | Double

Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Posting a Bank Payment and Cheque
Posting a Purchase Payment and Cheque


RemittanceIndex

Description

The RemittanceIndex object gives access to the Supplier Remittances Index (REMITIDX.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
RECORD_NUMBER | Record Number in Data File | 4 | Required | Integer
URN | Unique Identifier for the Remittance | 16 | Required | String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Posting a Purchase Payment and Cheque
Posting a Purchase Payment and Cheque


RemittanceRecord

Description

The RemittanceRecord object gives access to the Supplier Remittances (REMIT.DTA) table and the Supplier Remittances Index (REMITIDX.DTA) table. Despite its name the Remittance Record is used to create cheques that may be sent to a supplier or from the bank. It can be used in conjunction with the BankRemittanceRecord. As an SDORecord object, it encapsulates both the data and index files.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Supplier Account Reference | 8 | Required | String
ADDRESS_1 | Payee Address Line 1 | 60 | Optional | String
ADDRESS_2 | Payee Address Line 2 | 60 | Optional | String
ADDRESS_3 | Payee Address Line 3 | 60 | Optional | String
ADDRESS_4 | Payee Address Line 4 | 60 | Optional | String
ADDRESS_5 | Payee Address Line 5 | 60 | Optional | String
BANK | Bank Account Reference | 8 | Required | String
CHEQUE_NO | Cheque Number | 8 | Required | String
DATE | Date of Transactions | 2 | Required | Date
DETAILS | Details | 60 | Required | String
FAX | Payee Fax Number | 30 | Optional | String
FOREIGN_RATE | Foreign Exchange Rate | 8 | Required | Double
GROSS_AMOUNT | Transaction Gross Amount | 8 | Required | Double
INDEX | Unique Identifier for Remittance Line | 8 | Required | String
INV_REF | Invoice Reference | 30 | Required | String
LASTLINE_FLAG | Last Line Flag - True if this is the last line of the remittance | 2 | Required | Small Integer
NAME | Payee Name | 60 | Optional | String
NET_AMOUNT | Transaction Net Amount | 8 | Required | Double
PAYMENT_AMOUNT | Transaction Payment | 8 | Required | Double
PAYMENT_DATE | Date of Payment | 2 | Required | Date
PAYMENT_FLAG | Payment Flag | 2 | Required | Small Integer
PAYMENT_NO | Payment's Last Split Transaction Number | 4 | Required | Integer
PRINTED_FLAG | Printed Flag | 2 | Required | Small Integer
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was created | 8 | Optional | Date
TAX_CODE | Tax Code | 3 | Required | String
TELEPHONE | Payee Telephone Number | 30 | Optional | String
TRAN_TYPE | Transaction Type | 2 | Required | String
URN | Unique Identifier for this Remittance | 8 | Required | String
VAT_AMOUNT | Transaction Vat Amount | 8 | Required | Double

Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Posting a Bank Payment and Cheque
Posting a Purchase Payment and Cheque


PurchaseIndex

SalesActiveIndex

Description

The SalesActiveIndex object gives access to the Sales (SALES_ACTIVE_INDEX.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Account Reference | 8 | Required | String
RECORD_NUMBER | Record Number in Data File | 4 | Required | Integer
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object


SalesData

Description

The SalesData object gives access to the Customers (SALES.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_MANAGER | Name of Account Manager | 60 | Optional | String
ACCOUNT_ON_HOLD | Account On Hold | 1 | Optional | Byte
ACCOUNT_OPENED | Date Account Opened | 2 | Optional | Date
ACCOUNT_REF | Account Reference | 8 | Required | String
ACCOUNT_STATUS | Account Status | 2 | Optional | Small Integer
ACCOUNT_TYPE | Account Type | 2 | Optional | Small Integer
ACCOUNT_TYPE_CUSTOMER | Account Type Customer Flag | 2 | Optional | Small Integer
ACCOUNT_TYPE_DONOR | Account Type Donor Flag | 2 | Optional | Small Integer
ACCOUNT_TYPE_MEMBER | Account Type Member Flag | 2 | Optional | Small Integer
ADDRESS_1 | Account Address Line 1 | 60 | Optional | String
ADDRESS_2 | Account Address Line 2 | 60 | Optional | String
ADDRESS_3 | Account Address Line 3 | 60 | Optional | String
ADDRESS_4 | Account Address Line 4 | 60 | Optional | String
ADDRESS_5 | Account Address Line 5 | 60 | Optional | String
ANALYSIS_1 | Analysis 1 | 30 | Optional | String
ANALYSIS_2 | Analysis 2 | 30 | Optional | String
ANALYSIS_3 | Analysis 3 | 30 | Optional | String
ANALYSIS_4 | Analysis 4 | 30 | Optional | String
ANALYSIS_5 | Analysis 5 | 30 | Optional | String
ANALYSIS_6 | Analysis 6 | 30 | Optional | String
AVERAGE_PAY_DAYS | Average Time To Pay | 8 | Optional | Double
BACS | BACS Online Receipts Flag | 2 | Optional | Small Integer
BACS_REFERENCE | Reference for BACS Transfer | 60 | Optional | String
BALANCE | Balance | 8 | Optional | Double
BANK_ACCOUNT_NAME | Bank Account Name | 60 | Optional | String
BANK_ACCOUNT_NUMBER | Bank Account Number | 60 | Optional | String
BANK_ADDITIONAL_REF1 | Bank Additional Ref 1 | 60 | Optional | String
BANK_ADDITIONAL_REF2 | Bank Additional Ref 2 | 60 | Optional | String
BANK_ADDITIONAL_REF3 | Bank Additional Ref 3 | 60 | Optional | String
BANK_ADDRESS_1 | Bank Address Line 1 | 60 | Optional | String
BANK_ADDRESS_2 | Bank Address Line 2 | 60 | Optional | String
BANK_ADDRESS_3 | Bank Address Line 3 | 60 | Optional | String
BANK_ADDRESS_4 | Bank Address Line 4 | 60 | Optional | String
BANK_ADDRESS_5 | Bank Address Line 5 | 60 | Optional | String
BANK_BICSWIFT | Bank BIC/Swift | 60 | Optional | String
BANK_IBAN | Bank IBAN Number | 60 | Optional | String
BANK_NAME | Bank Name | 60 | Optional | String
BANK_ROLL_NUMBER | Bank Roll Number | 60 | Optional | String
BANK_SORT_CODE | Bank Sort Code | 10 | Optional | String
BUILD_SOCIETY_REF | Reference for Building Society Transfer | 60 | Optional | String
BUILDING_SOCIETY | Account uses Building Society | 2 | Optional | Small Integer
CAN_APPLY_CHARGES | Can Charge Credit | 2 | Optional | Small Integer
COMPANY_REGISTRATION_NUMBER | Company Reg. Number | 16 | Optional | String
CONTACT_NAME | Contact Name | 30 | Optional | String
COUNTRY_CODE | Country Code | 2 | Optional | String
CREDIT_APP_RECEIVED | True if Credit Application Received | 2 | Optional | Small Integer
CREDIT_APPLIED_FOR | Date Credit Applied For | 2 | Optional | Date
CREDIT_BF | Credits Brought Forward | 8 | Optional | Double
CREDIT_BUREAU | Credit Bureau Used | 2 | Optional | Small Integer
CREDIT_CARD_NO | Credit Card Number | 30 | Optional | String
CREDIT_CF | Credits Carried Forward | 8 | Optional | Double
CREDIT_LIMIT | Credit Limit | 8 | Optional | Double
CREDIT_MTH1 | Credit Month 1 | 8 | Optional | Double
CREDIT_MTH10 | Credit Month 10 | 8 | Optional | Double
CREDIT_MTH11 | Credit Month 11 | 8 | Optional | Double
CREDIT_MTH12 | Credit Month 12 | 8 | Optional | Double
CREDIT_MTH2 | Credit Month 2 | 8 | Optional | Double
CREDIT_MTH3 | Credit Month 3 | 8 | Optional | Double
CREDIT_MTH4 | Credit Month 4 | 8 | Optional | Double
CREDIT_MTH5 | Credit Month 5 | 8 | Optional | Double
CREDIT_MTH6 | Credit Month 6 | 8 | Optional | Double
CREDIT_MTH7 | Credit Month 7 | 8 | Optional | Double
CREDIT_MTH8 | Credit Month 8 | 8 | Optional | Double
CREDIT_MTH9 | Credit Month 9 | 8 | Optional | Double
CREDIT_POSITION | Credit Position | 2 | Optional | Small Integer
CREDIT_REFERENCE | Credit Bureau Reference | 60 | Optional | String
CURRENCY | Currency | 1 | Optional | Byte
DATE_CREDIT_APP_RECEIVED | Date Credit Application Recieved | 2 | Optional | Date
DECLARATION_VALID_FROM | Donor Declaration Valid From | 2 | Optional | Date
DEF_NOM_CODE | Default Nominal Code | 8 | Optional | String
DEF_TAX_CODE | Default Tax Code | 2 | Optional | Small Integer
DEL_ADDRESS_1 | Delivery Address Line 1 | 60 | Optional | String
DEL_ADDRESS_2 | Delivery Address Line 2 | 60 | Optional | String
DEL_ADDRESS_3 | Delivery Address Line 3 | 60 | Optional | String
DEL_ADDRESS_4 | Delivery Address Line 4 | 60 | Optional | String
DEL_ADDRESS_5 | Delivery Address Line 5 | 60 | Optional | String
DEL_CONTACT_NAME | Delivery Contact Name | 30 | Optional | String
DEL_FAX | Delivery Fax Number | 30 | Optional | String
DEL_NAME | Delivery Name | 60 | Optional | String
DEL_TELEPHONE | Delivery Telephone Number | 30 | Optional | String
DELETED_FLAG | Reserved for Future Use | 2 | Optional | Small Integer
DEPT_NUMBER | Department Number | 2 | Optional | Small Integer
DISCOUNT_RATE | Discount Rate | 8 | Optional | Double
DISCOUNT_TYPE | Discount Type | 1 | Optional | Byte
DISPUTED | Disputed | 4 | Optional | Integer

DONOR_FORENAME

 Donor Forename 35 Optional String

DONOR_SURNAME

 Donor Surname 35 Optional String

DONOR_TITLE

 Donor Title 4 Optional String
DUNS_NUMBER | Duns Number | 9 | Optional | String
E_MAIL | EMail Address | 255 | Optional | String
E_MAIL2 | EMail Address 2 | 255 | Optional | String
E_MAIL3 | EMail Address 3 | 255 | Optional | String
E_MAIL4 | EMail Address 4 | 255 | Optional | String
E_MAIL5 | EMail Address 5 | 255 | Optional | String
E_MAIL6 | EMail Address 6 | 255 | Optional | String
EC_CODE | EC Member Code | 3 | Optional | String
EORI_NUMBER | EORI number | 17 | Optional | String
EXTERNAL_USAGE | Number of External Usages for this Record | 4 | Optional | Integer
FACEBOOK | Facebook Address | 75 | Optional | String
FAX | Fax Number | 30 | Optional | String
FIRST_HEADER | Record Number of First Transaction | 4 | Optional | Integer
FIRST_INVOICE | First Invoice Date | 2 | Optional | Date
GIFT_AID_ENABLED | Gift aid is enabled | 2 | Optional | Small Integer
HOLD_MAIL | Restrict Mail | 2 | Optional | Small Integer
INACTIVE_FLAG | Inactive Flag - yes/No | 1 | Optional | Byte
INCOTERMS | Incoterms | 2 | Optional | Small Integer
INVOICE_BF | Invoices Brought Forward | 8 | Optional | Double
INVOICE_CF | Invoices Carry Forward | 8 | Optional | Double
INVOICE_MTH1 | Invoices Month 1 | 8 | Optional | Double
INVOICE_MTH10 | Invoices Month 10 | 8 | Optional | Double
INVOICE_MTH11 | Invoices Month 11 | 8 | Optional | Double
INVOICE_MTH12 | Invoices Month 12 | 8 | Optional | Double
INVOICE_MTH2 | Invoices Month 2 | 8 | Optional | Double
INVOICE_MTH3 | Invoices Month 3 | 8 | Optional | Double
INVOICE_MTH4 | Invoices Month 4 | 8 | Optional | Double
INVOICE_MTH5 | Invoices Month 5 | 8 | Optional | Double
INVOICE_MTH6 | Invoices Month 6 | 8 | Optional | Double
INVOICE_MTH7 | Invoices Month 7 | 8 | Optional | Double
INVOICE_MTH8 | Invoices Month 8 | 8 | Optional | Double
INVOICE_MTH9 | Invoices Month 9 | 8 | Optional | Double
LAST_CREDIT_REV | Date Last Credit Review | 2 | Optional | Date
LAST_HEADER | Record Number of Last Transaction | 4 | Optional | Integer
LAST_INV_DATE | Last Invoice Date | 2 | Optional | Date
LAST_PAY_DATE | Last Payment Date | 2 | Optional | Date
LAST_UPDATED | Date of last update | 8 | Optional | Date
LINKEDIN | LinkedIn Address | 64 | Optional | String
MANDATEREF | Direct Debit Mandate Ref | 25 | Optional | String
MEMBER_REMINDER_DATE | Member Reminder Date (days) | 2 | Optional | Integer
MEMBER_RENEWAL_DATE | Member Renewal Date | 2 | Optional | Date
MEMBER_SINCE | Member Since | 2 | Optional | Date
MEMO_OFFSET | Offset in Credit Memo File | 4 | Optional | Integer
MEMO_SIZE | Size of Memo in bytes | 4 | Optional | Integer
MODIFY | Modified Count | 4 | Optional | Integer
NAME | Account Name | 60 | Optional | String
NEXT_CREDIT_REV | Date Next Credit Review | 2 | Optional | Date
NO_OF_HEADER | Number of Transactions | 4 | Optional | Integer
OVERRIDE_PRODUCT_TAX | Override the products own Tax Code. | 1 | Optional | Byte
OVERRIDE_PRODUCT_NOMINAL | Override Product Nominal Code in Invoicing | 1 | Optional | Byte
PAYMENT_BF | Payments Brought Forward | 8 | Optional | Double
PAYMENT_CF | Payments Carry Forward | 8 | Optional | Double
PAYMENT_DUE_DAYS | Payment Due Days | 2 | Optional | Small Integer
PAYMENT_DUE_FROM | Payment Due From | 2 | Optional | Small Integer
PAYMENT_MTH1 | Payments Month 1 | 8 | Optional | Double
PAYMENT_MTH10 | Payments Month 10 | 8 | Optional | Double
PAYMENT_MTH11 | Payments Month 11 | 8 | Optional | Double
PAYMENT_MTH12 | Payments Month 12 | 8 | Optional | Double
PAYMENT_MTH2 | Payments Month 2 | 8 | Optional | Double
PAYMENT_MTH3 | Payments Month 3 | 8 | Optional | Double
PAYMENT_MTH4 | Payments Month 4 | 8 | Optional | Double
PAYMENT_MTH5 | Payments Month 5 | 8 | Optional | Double
PAYMENT_MTH6 | Payments Month 6 | 8 | Optional | Double
PAYMENT_MTH7 | Payments Month 7 | 8 | Optional | Double
PAYMENT_MTH8 | Payments Month 8 | 8 | Optional | Double
PAYMENT_MTH9 | Payments Month 9 | 8 | Optional | Double
PAYMENT_TYPE | Payment Type | 4 | Optional | Integer
PRICE_LIST_REF | Price List Reference | 8 | Optional | String
PRIOR_YEAR | Prior YTD | 8 | Optional | Double
PRIORITY_TRADER | Priority Supplier | 2 | Optional | Small Integer
RECEIPT_BF | Receipts Brought Forward | 8 | Optional | Double
RECEIPT_CF | Receipts Carry Forward | 8 | Optional | Double
RECEIPT_MTH1 | Receipt Month 1 | 8 | Optional | Double
RECEIPT_MTH2 | Receipt Month 2 | 8 | Optional | Double
RECEIPT_MTH3 | Receipt Month 3 | 8 | Optional | Double
RECEIPT_MTH4 | Receipt Month 4 | 8 | Optional | Double
RECEIPT_MTH5 | Receipt Month 5 | 8 | Optional | Double
RECEIPT_MTH6 | Receipt Month 6 | 8 | Optional | Double
RECEIPT_MTH7 | Receipt Month 7 | 8 | Optional | Double
RECEIPT_MTH8 | Receipt Month 8 | 8 | Optional | Double
RECEIPT_MTH9 | Receipt Month 9 | 8 | Optional | Double
RECEIPT_MTH10 | Receipt Month 10 | 8 | Optional | Double
RECEIPT_MTH11 | Receipt Month 11 | 8 | Optional | Double
RECEIPT_MTH12 | Receipt Month 12 | 8 | Optional | Double
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
SALES_REP | Name of Sales Representative | 60 | Optional | String
SEND_INVOICES_ELECTRONICALLY | Send Invoices to this account via Email | 2 | Optional | Small Integer
SEND_LETTERS_ELECTRONICALLY | Send Letters to this account via Email | 2 | Optional | Small Integer
SETTLEMENT_DISC_RATE | Settlement Discount Rate | 8 | Optional | Double
SETTLEMENT_DUE_DAYS | Settlement Due Days | 2 | Optional | Small Integer
TELEPHONE | Telephone Number | 30 | Optional | String
TELEPHONE_2 | Second Telephone Number | 30 | Optional | String
TERMS | Terms | 30 | Optional | String
TERMS_AGREED_FLAG | Terms Agreed Flag | 2 | Optional | Small Integer
TRADE_CONTACT | Name of Trade Contact | 30 | Optional | String
TRADER_FOREIGN_BALANCE | Foreign Balance | 8 | Optional | Double
TURNOVER_MTD | Turnover Month To Date | 8 | Optional | Double
TURNOVER_YTD | Turnover Year Date | 8 | Optional | Double
TWITTER | Twitter Address | 35 | Optional | String
VAT_REG_NUMBER | VAT Registration Number | 20 | Optional | String
WWW | WWW Address | 255 | Optional | String

Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Creating a New Customer Record


SalesDeliveryData

Description

The SalesDeliveryData object gives access to the Customer Delivery Address (PURDA.DTA) table.

NOTE - This object is obsolete as of version 2009. Please use the CustomerAddress object.

Applies to

Sage 50 Accounts Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Customer Account Reference | 8 | Required | String
ADDRESS_1 | Delivery Address Line 1 | 60 | Optional | String
ADDRESS_2 | Delivery Address Line 2 | 60 | Optional | String
ADDRESS_3 | Delivery Address Line 3 | 60 | Optional | String
ADDRESS_4 | Delivery Address Line 4 | 60 | Optional | String
ADDRESS_5 | Delivery Address Line 5 | 60 | Optional | String
ADDRESS_REF | Address Reference Number | 2 | Required | Small Integer
ADDRESS_TYPE | Address Type | 1 | Required | Byte
CONTACT_NAME | Contact Name | 30 | Optional | String
CONTACT_ROLE | Contact Role | 30 | Optional | String
COUNTRY_CODE | Country Code | 2 | Required | String
DEFAULT_REF | Default Indicator | 2 | Required | Small Integer
DESCRIPTION | Description | 60 | Required | String
EMAIL | EMail Address | 255 | Optional | String
FAX | Fax Number | 30 | Optional | String
NAME | Name | 60 | Required | String
NOTES | Notes | 200 | Optional | String
RECORD_CREATE_DATE | Date and time when record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when record was modified | 8 | Optional | Date
REFERENCE | Delivery Address Reference | 12 | Required | String
TAX_CODE | Tax Code | 2 | Required | Small Integer
TELEPHONE | Telephone Number | 30 | Optional | String
TELEPHONE_2 | Telephone Number2 | 30 | Optional | String
VAT_NUMBER | Vat Registration Number | 20 | Optional | String

Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Example - Reading sales delivery records


SalesDeliveryIndex

Description

The SalesDeliveryIndex object gives access to the Sales Delivery Address Index (SALDAIDX.DTA) table.

NOTE - This object is obsolete as of version 2009. Please use the CustomerAddress object.

Applies to

Sage 50 Accounts Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
RECORD_NUMBER | Record Number in Data File | 4 | Required | Integer
REFERENCE | Delivery Address Reference | 12 | Required | String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Example - Reading sales delivery records


SalesDeliveryRecord

Description

The SalesDeliveryRecord object gives access to the Customer Delivery Address (SALDA.DTA) table and the Customer Delivery Address Index (SALDAIDX.DTA) table. As an SDORecord object, it encapsulates both the data and index files.

NOTE - This object is obsolete as of version 2009. Please use the CustomerAddress object.

Applies to

Sage 50 Accounts Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Customer Account Reference | 8 | Required | String
ADDRESS_1 | Delivery Address Line 1 | 60 | Optional | String
ADDRESS_2 | Delivery Address Line 2 | 60 | Optional | String
ADDRESS_3 | Delivery Address Line 3 | 60 | Optional | String
ADDRESS_4 | Delivery Address Line 4 | 60 | Optional | String
ADDRESS_5 | Delivery Address Line 5 | 60 | Optional | String
ADDRESS_REF | Address Reference Number | 2 | Required | Small Integer
ADDRESS_TYPE | Address type | 1 | Required | Byte
CONTACT_NAME | Contact Name | 30 | Optional | String
CONTACT_ROLE | Contact Role | 30 | Optional | String
COUNTRY_CODE | Country Code | 2 | Required | String
DEFAULT_REF | Default Indicator | 2 | Required | Small Integer
DESCRIPTION | Description | 60 | Required | String
EMAIL | EMail Address | 255 | Optional | String
FAX | Fax Number | 30 | Optional | String
NAME | Name | 60 | Required | String
NOTES | Notes | 200 | Optional | String
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
REFERENCE | Delivery Address Reference | 12 | Required | String
TAX_CODE | Tax Code | 2 | Required | Small Integer
TELEPHONE | Telephone Number | 30 | Optional | String
TELEPHONE_2 | Telephone Number2 | 30 | Optional | String
VAT_NUMBER | Vat Registration Number | 20 | Optional | String

Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Example - Reading sales delivery records


SalesIndex

Description

The SalesIndex object gives access to the Customers Index (SALINDEX.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Account Reference | 8 | Required | String
RECORD_NUMBER | Record Number in Data File | 4 | Required | Integer
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Creating a New Customer Record


SalesRecord

Description

The SalesRecord object gives access to the Customers (SALES.DTA) table and the Customers Index (SALINDEX.DTA) table. As an SDORecord object, it encapsulates both the data and index files.

New Method

The SalesRecord (and PurchaseRecord) have a new method (GetAgedBalances) to return an AgedBalances object.

Notes on address fields

The DEL_ADDRESS_x and ADDRESS_x fields have been superceded from version 2009 and above by the CustomerAddress Business Object. Previously entered addresses have not been removed and are available to read and write via these fields, however it is recommended that the Business Object is used instead.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_MANAGER | Name of Account Manager | 60 | Optional | String
ACCOUNT_ON_HOLD | Account On Hold | 1 | Optional | Byte
ACCOUNT_OPENED | Date Account Opened | 2 | Optional | Date
ACCOUNT_REF | Account Reference | 8 | Required | String
ACCOUNT_STATUS | Account Status | 2 | Optional | Small Integer
ACCOUNT_TYPE | Account Type | 2 | Optional | Small Integer
ACCOUNT_TYPE_CUSTOMER | Account Type Customer Flag | 2 | Optional | Small Integer
ACCOUNT_TYPE_DONOR | Account Type Donor Flag | 2 | Optional | Small Integer
ACCOUNT_TYPE_MEMBER | Account Type Member Flag | 2 | Optional | Small Integer
ADDRESS_1 | Account Address Line 1 | 60 | Optional | String
ADDRESS_2 | Account Address Line 2 | 60 | Optional | String
ADDRESS_3 | Account Address Line 3 | 60 | Optional | String
ADDRESS_4 | Account Address Line 4 | 60 | Optional | String
ADDRESS_5 | Account Address Line 5 | 60 | Optional | String
ANALYSIS_1 | Analysis 1 | 30 | Optional | String
ANALYSIS_2 | Analysis 2 | 30 | Optional | String
ANALYSIS_3 | Analysis 3 | 30 | Optional | String
ANALYSIS_4 | Analysis 4 | 30 | Optional | String
ANALYSIS_5 | Analysis 5 | 30 | Optional | String
ANALYSIS_6 | Analysis 6 | 30 | Optional | String
AVERAGE_PAY_DAYS | Average Time To Pay | 8 | Optional | Double
BACS | BACS Online Receipts Flag | 2 | Optional | Small Integer
BACS_REFERENCE | Reference for BACS Transfer | 60 | Optional | String
BALANCE | Balance | 8 | Optional | Double
BANK_ACCOUNT_NAME | Bank Account Name | 60 | Optional | String
BANK_ACCOUNT_NUMBER | Bank Account Number | 60 | Optional | String
BANK_ADDITIONAL_REF1 | Bank Additional Ref 1 | 60 | Optional | String
BANK_ADDITIONAL_REF2 | Bank Additional Ref 2 | 60 | Optional | String
BANK_ADDITIONAL_REF3 | Bank Additional Ref 3 | 60 | Optional | String
BANK_ADDRESS_1 | Bank Address Line 1 | 60 | Optional | String
BANK_ADDRESS_2 | Bank Address Line 2 | 60 | Optional | String
BANK_ADDRESS_3 | Bank Address Line 3 | 60 | Optional | String
BANK_ADDRESS_4 | Bank Address Line 4 | 60 | Optional | String
BANK_ADDRESS_5 | Bank Address Line 5 | 60 | Optional | String
BANK_BICSWIFT | Bank BIC/Swift | 60 | Optional | String
BANK_IBAN | Bank IBAN Number | 60 | Optional | String
BANK_NAME | Bank Name | 60 | Optional | String
BANK_ROLL_NUMBER | Bank Roll Number | 60 | Optional | String
BANK_SORT_CODE | Bank Sort Code | 10 | Optional | String
BUILD_SOCIETY_REF | Reference for Building Society Transfer | 60 | Optional | String
BUILDING_SOCIETY | Account uses Building Society | 2 | Optional | Small Integer
CAN_APPLY_CHARGES | Can Charge Credit | 2 | Optional | Small Integer
COMPANY_REGISTRATION_NUMBER | Company Reg. Number | 16 | Optional | String
CONTACT_NAME | Contact Name | 30 | Optional | String
COUNTRY_CODE | Country Code | 2 | Optional | String
CREDIT_APP_RECEIVED | True if Credit Application Received | 2 | Optional | Small Integer
CREDIT_APPLIED_FOR | Date Credit Applied For | 2 | Optional | Date
CREDIT_BF | Credits Brought Forward | 8 | Optional | Double
CREDIT_BUREAU | Credit Bureau Used | 2 | Optional | Small Integer
CREDIT_CARD_NO | Credit Card Number | 30 | Optional | String
CREDIT_CF | Credits Carried Forward | 8 | Optional | Double
CREDIT_LIMIT | Credit Limit | 8 | Optional | Double
CREDIT_MTH1 | Credit Month 1 | 8 | Optional | Double
CREDIT_MTH10 | Credit Month 10 | 8 | Optional | Double
CREDIT_MTH11 | Credit Month 11 | 8 | Optional | Double
CREDIT_MTH12 | Credit Month 12 | 8 | Optional | Double
CREDIT_MTH2 | Credit Month 2 | 8 | Optional | Double
CREDIT_MTH3 | Credit Month 3 | 8 | Optional | Double
CREDIT_MTH4 | Credit Month 4 | 8 | Optional | Double
CREDIT_MTH5 | Credit Month 5 | 8 | Optional | Double
CREDIT_MTH6 | Credit Month 6 | 8 | Optional | Double
CREDIT_MTH7 | Credit Month 7 | 8 | Optional | Double
CREDIT_MTH8 | Credit Month 8 | 8 | Optional | Double
CREDIT_MTH9 | Credit Month 9 | 8 | Optional | Double
CREDIT_POSITION | Credit Position | 2 | Optional | Small Integer
CREDIT_REFERENCE | Credit Bureau Reference | 60 | Optional | String
CURRENCY | Currency | 1 | Optional | Byte
DATE_CREDIT_APP_RECEIVED | Date Credit Application Recieved | 2 | Optional | Date
DECLARATION_VALID_FROM | Donor Declaration Valid From | 2 | Optional | Date
DEF_NOM_CODE | Default Nominal Code | 8 | Optional | String
DEF_TAX_CODE | Default Tax Code | 2 | Optional | Small Integer
DEL_ADDRESS_1 | Delivery Address Line 1 | 60 | Optional | String
DEL_ADDRESS_2 | Delivery Address Line 2 | 60 | Optional | String
DEL_ADDRESS_3 | Delivery Address Line 3 | 60 | Optional | String
DEL_ADDRESS_4 | Delivery Address Line 4 | 60 | Optional | String
DEL_ADDRESS_5 | Delivery Address Line 5 | 60 | Optional | String
DEL_CONTACT_NAME | Delivery Contact Name | 30 | Optional | String
DEL_FAX | Delivery Fax Number | 30 | Optional | String
DEL_NAME | Delivery Name | 60 | Optional | String
DEL_TELEPHONE | Delivery Telephone Number | 30 | Optional | String
DELETED_FLAG | Reserved for Future Use | 2 | Optional | Small Integer
DEPT_NUMBER | Department Number | 2 | Optional | Small Integer
DISCOUNT_RATE | Discount Rate | 8 | Optional | Double
DISCOUNT_TYPE | Discount Type | 1 | Optional | Byte
DISPUTED | Disputed | 4 | Optional | Integer

DONOR_FORENAME

 Donor Forename 35 Optional String

DONOR_SURNAME

 Donor Surname 35 Optional String

DONOR_TITLE

 Donor Title 4 Optional String
DUNS_NUMBER | DUNS Number | 9 | Optional | String
E_MAIL | EMail Address | 255 | Optional | String
E_MAIL2 | EMail Address 2 | 255 | Optional | String
E_MAIL3 | EMail Address 3 | 255 | Optional | String
E_MAIL4 | EMail Address 4 | 255 | Optional | String
E_MAIL5 | EMail Address 5 | 255 | Optional | String
E_MAIL6 | EMail Address 6 | 255 | Optional | String
EC_CODE | EC Member Code | 3 | Optional | String
EORI_NUMBER | EORI number | 17 | Optional | String
EXTERNAL_USAGE | Number of External Usages for this Record | 4 | Optional | Integer
FACEBOOK | Facebook Address | 75 | Optional | String
FAX | Fax Number | 30 | Optional | String
FIRST_HEADER | Record Number of First Transaction | 4 | Optional | Integer
FIRST_INVOICE | First Invoice Date | 2 | Optional | Date
GIFT_AID_ENABLED | Gift Aid is enabled | 2 | Optional | Small Integer
HOLD_MAIL | Restrict Mail | 2 | Optional | Small Integer
INACTIVE_FLAG | Inactive Flag - yes/No | 1 | Optional | Byte
INCOTERMS | Incoterms | 2 | Optional | Small Integer
INVOICE_BF | Invoices Brought Forward | 8 | Optional | Double
INVOICE_CF | Invoices Carry Forward | 8 | Optional | Double
INVOICE_MTH1 | Invoices Month 1 | 8 | Optional | Double
INVOICE_MTH2 | Invoices Month 10 | 8 | Optional | Double
INVOICE_MTH3 | Invoices Month 11 | 8 | Optional | Double
INVOICE_MTH4 | Invoices Month 12 | 8 | Optional | Double
INVOICE_MTH5 | Invoices Month 2 | 8 | Optional | Double
INVOICE_MTH6 | Invoices Month 3 | 8 | Optional | Double
INVOICE_MTH7 | Invoices Month 4 | 8 | Optional | Double
INVOICE_MTH8 | Invoices Month 5 | 8 | Optional | Double
INVOICE_MTH9 | Invoices Month 6 | 8 | Optional | Double
INVOICE_MTH10 | Invoices Month 7 | 8 | Optional | Double
INVOICE_MTH11 | Invoices Month 8 | 8 | Optional | Double
INVOICE_MTH12 | Invoices Month 9 | 8 | Optional | Double
LAST_CREDIT_REV | Date Last Credit Review | 2 | Optional | Date
LAST_HEADER | Record Number of Last Transaction | 4 | Optional | Integer
LAST_INV_DATE | Last Invoice Date | 2 | Optional | Date
LAST_PAY_DATE | Last Payment Date | 2 | Optional | Date
LAST_UPDATED | Last Updated Date | 8 | Optional | Date
LINKEDIN | LinkedIn Address | 64 | Optional | String
MANDATEREF | Direct Debit Mandate Ref | 25 | Optional | String
MEMBER_REMINDER_DATE | Member Reminder Date (days) | 2 | Optional | Integer
MEMBER_RENEWAL_DATE | Member Renewal Date | 2 | Optional | Date
MEMBER_SINCE | Member Since | 2 | Optional | Date
MEMO_OFFSET | Offset in Credit Memo File | 4 | Optional | Integer
MEMO_SIZE | Size of Memo in bytes | 4 | Optional | Integer
MODIFY | Modified Count | 4 | Optional | Integer
NAME | Account Name | 60 | Optional | String
NEXT_CREDIT_REV | Date Next Credit Review | 2 | Optional | Date
NO_OF_HEADER | Number of Transactions | 4 | Optional | Integer
OVERRIDE_PRODUCT_TAX | Override the products own Tax Code. | 1 | Optional | Byte
OVERRIDE_PRODUCT_NOMINAL | Override Product Nominal Code in Invoicing | 1 | Optional | Byte
PAYMENT_BF | Payments Brought Forward | 8 | Optional | Double
PAYMENT_CF | Payments Carry Forward | 8 | Optional | Double
PAYMENT_DUE_DAYS | Payment Due Days | 2 | Optional | Small Integer
PAYMENT_DUE_FROM | Payment Due From | 2 | Optional | Small Integer
PAYMENT_MTH1 | Payments Month 1 | 8 | Optional | Double
PAYMENT_MTH2 | Payments Month 10 | 8 | Optional | Double
PAYMENT_MTH3 | Payments Month 11 | 8 | Optional | Double
PAYMENT_MTH4 | Payments Month 12 | 8 | Optional | Double
PAYMENT_MTH5 | Payments Month 2 | 8 | Optional | Double
PAYMENT_MTH6 | Payments Month 3 | 8 | Optional | Double
PAYMENT_MTH7 | Payments Month 4 | 8 | Optional | Double
PAYMENT_MTH8 | Payments Month 5 | 8 | Optional | Double
PAYMENT_MTH9 | Payments Month 6 | 8 | Optional | Double
PAYMENT_MTH10 | Payments Month 7 | 8 | Optional | Double
PAYMENT_MTH11 | Payments Month 8 | 8 | Optional | Double
PAYMENT_MTH12 | Payments Month 9 | 8 | Optional | Double
PAYMENT_TYPE | Payment Method | 4 | Optional | Integer
PRICE_LIST_REF | Price List Reference | 8 | Optional | String
PRIOR_YEAR | Prior YTD | 8 | Optional | Double
PRIORITY_TRADER | Priority Supplier | 2 | Optional | Small Integer
RECEIPT_BF | Receipts Brought Forward | 8 | Optional | Double
RECEIPT_CF | Receipts Carry Forward | 8 | Optional | Double
RECEIPT_MTH1 | Receipts Month 1 | 8 | Optional | Double
RECEIPT_MTH2 | Receipts Month 2 | 8 | Optional | Double
RECEIPT_MTH3 | Receipts Month 3 | 8 | Optional | Double
RECEIPT_MTH4 | Receipts Month 4 | 8 | Optional | Double
RECEIPT_MTH5 | Receipts Month 5 | 8 | Optional | Double
RECEIPT_MTH6 | Receipts Month 6 | 8 | Optional | Double
RECEIPT_MTH7 | Receipts Month 7 | 8 | Optional | Double
RECEIPT_MTH8 | Receipts Month 8 | 8 | Optional | Double
RECEIPT_MTH9 | Receipts Month 9 | 8 | Optional | Double
RECEIPT_MTH10 | Receipts Month 10 | 8 | Optional | Double
RECEIPT_MTH11 | Receipts Month 11 | 8 | Optional | Double
RECEIPT_MTH12 | Receipts Month 12 | 8 | Optional | Double
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
SALES_REP | Name of Sales Representative | 60 | Optional | String
SEND_INVOICES_ELECTRONICALLY | Send Invoices To This Account via Email | 2 | Optional | Small Integer
SEND_LETTERS_ELECTRONICALLY | Send Letters To This Account via Email | 2 | Optional | Small Integer
SETTLEMENT_DISC_RATE | Settlement Discount Rate | 8 | Optional | Double
SETTLEMENT_DUE_DAYS | Settlement Due Days | 2 | Optional | Small Integer
TELEPHONE | Telephone Number | 30 | Optional | String
TELEPHONE_2 | Second Telephone Number | 30 | Optional | String
TERMS | Terms | 30 | Optional | String
TERMS_AGREED_FLAG | Terms Agreed Flag | 2 | Optional | Small Integer
TRADE_CONTACT | Name of Trade Contact | 30 | Optional | String
TRADER_FOREIGN_BALANCE | Foreign Balance | 8 | Optional | Double
TURNOVER_MTD | Turnover Month To Date | 8 | Optional | Double
TURNOVER_YTD | Turnover Year Date | 8 | Optional | Double
TWITTER | Twitter Address | 35 | Optional | String
VAT_REG_NUMBER | VAT Registration Number | 20 | Optional | String
WWW | WWW Address | 255 | Optional | String

Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Creating a New Customer Record
Flag Disputed Transactions
Posting a Sales Invoice and Receipt - VAT Cash Accounting

� Sage (UK) Ltd Click here to send feedback on this article.


SetupData

Description

The SetupData object gives access to the Setup (SETUP.DTA) table. This table holds the company preferences and defaults such as the Company Name and Address.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACTIVE_SEARCH | Company Preferences - Parameters - Display ActiveSearch Popup | 1 | Optional | Byte
ADDRESS_1 | Company Address Line 1 | 60 | Optional | String
ADDRESS_2 | Company Address Line 2 | 60 | Optional | String
ADDRESS_3 | Company Address Line 3 | 60 | Optional | String
ADDRESS_4 | Company Address Line 4 | 60 | Optional | String
ADDRESS_5 | Company Address Line 5 | 60 | Optional | String
ADDRESS_ON_STAT | Print Name and Address on Stationery | 1 | Optional | Byte
ADDRESS_ON_STATIONERY | Address on Stationery Flag | 1 | Optional | Byte
ADDRESS_PROMPT_1 | Address Label 1 | 10 | Optional | String
ADDRESS_PROMPT_2 | Address Label 2 | 10 | Optional | String
ADDRESS_PROMPT_3 | Address Label 3 | 10 | Optional | String
ADDRESS_PROMPT_4 | Address Label 4 | 10 | Optional | String
ADDRESS_PROMPT_5 | Address Label 5 | 10 | Optional | String
AGE_DISPUTE_CURRENT | Age Disputed Items as Current | 2 | Optional | Small Integer
ALL_CUSTOMERS

Invoice/Order Defaults tab - Apply discounts to: 1 for All Customers, 0 for Customers who are NOT associated with a Price List.

NOTE If 0 then PRICE_LIST_PRICE must be set to 0.

 1 Optional Byte
ALLOW_NEGATIVE_STOCK | Allow Negative Stock Flag | 2 | Optional | Small Integer
ALLOW_ON_HOLD_TRANS_ENTRY | Allow Entering Transactions To An Account That Is On Hold | 2 | Optional | Small Integer
ALWAYS_CREATE_BATCH_EPAYMENT | Always create batch ePayments by default | 2 | Optional | Small Integer
AUTH_SERVICE_ADMIN_EMAIL | Auth Service Admin Email | 255 | Optional | String
AUTOENTRY_ENABLED_FLAG | Auto Entry Sync Enabled | 2 | Optional | Small Integer
AUTOENTRY_SYNC_PC_HOSTNAME | Auto Entry Sync PC Hostname | 15 | Optional | String
BANK_FEEDS_AUTOMATCH_IS_DISABLED | Disable Bank Feeds AutoMatch | 2 | Optional | SmallInteger
BANK_FEEDS_COMPANY_ID | Bank Cloud Company ID | 37 | Optional | String
BANK_FEEDS_ORGANISTION_ID | Bank Cloud Organisation ID | 37 | Optional | String
BANK_FEEDS_USER_EMAIL | Bank Cloud User Email | 99 | Optional | String
BANK_PAYMENT_DEFAULT_DEPARTMENT_CODE | User defined default department code for bank payments | 2 | Optional | SmallInteger
BANK_PAYMENT_DEFAULT_NOMINAL | User defined default nominal code for bank payments | 8 | Optional | String
BANK_PAYMENT_DEFAULT_TAX_CODE | User defined default tax code for bank payments | 2 | Optional | SmallInteger
BANK_RECEIPT_DEFAULT_DEPARTMENT_CODE | User defined default department code for bank receipts | 2 | Optional | SmallInteger
BANK_RECEIPT_DEFAULT_NOMINAL | User defined default nominal code for bank receipts | 8 | Optional | String
BANK_RECEIPT_DEFAULT_TAX_CODE | User defined default tax code for bank receipts | 2 | Optional | SmallInteger
BASE_CURRENCY | Base Currency | 2 | Optional | Small Integer
BUDGETING_TYPE | Budgeting Method | 2 | Optional | Small Integer
BUSINESS_TYPE | Business Type | 1 | Required | Byte
CASH_REGISTER_BANK | Cash register bank nominal | 8 | Optional | String
CASH_REGISTER_DISCREPENCIES_NOM | Cash register discrepencies nominal | 8 | Optional | String
CASH_REGISTER_SALES_NOM | Cash register sales nominal | 8 | Optional | String
CASH_REGISTER_TAX_INCLUSIVE_FLAG | Cash register tax inclusive flag | 1 | Optional | Byte
CASH_REGISTER_TAXCODE | Cash register tax code nominal | 2 | Optional | Small Integer
CASHSALES_ADD_MESSAGE | Cash Sales Adds a Message Line | 2 | Optional | Small Integer
CASHSALES_DEFAULT_BANK | Cash Sales Default Bank Account | 8 | Optional | String
CASHSALES_MESSAGE | Message Line Added To Invoice by Cash Sales | 60 | Optional | String
CASHSALES_PRINT_GDN | Cash Sales Prints GDN | 2 | Optional | Small Integer
CASHSALES_PRINT_INVOICE | Cash Sales Prints Invoice | 2 | Optional | Small Integer
CASHSALES_PRINT_SOP | Cash Sales Prints SOP | 2 | Optional | Small Integer
CASHSALES_USE_DEFAULT_BANK | Use Default Bank Without Prompting | 2 | Optional | Small Integer
CHARITY_ENABLED | Enable Charity/Non Profit Options | 1 | Optional | Byte
CHEQUE_LINES | Company Preferences - Reporting - Cheque lines per page | 2 | Optional | Small Integer
CLOSED_LEDGER_CHECK_DATE | The date which a transaction being posted is validated against | 2 | Optional | Date
CLOSED_LEDGER_DATE_CONTROL_ENABLED | Flag indicating if closed ledger control is currently enforced | 1 | Optional | Byte
COMPANY_REGISTRATION_NUMBER | Company Reg. Number | 16 | Optional | String
COMPANYID | Unique Company Id | 36 | Required | String
COUNTRY_CODE | The company default country code e.g. GB | 2 | Optional | String
CREDIT_CHARGE_DEP | Credit Charge Department | 2 | Optional | Small Integer
CREDIT_REF | Credit Reference Number | 60 | Optional | String
CUST_UPDATE_TRAN_EX_REF_FROM | Source used to fill the extra reference field | 2 | Optional | Small Integer
CUST_UPDATE_TRAN_REF_FROM | Source used to fill the reference field | 2 | Optional | Small Integer
CUSTOMER_COUNTRY_CODE | Default Customer Country Code | 2 | Optional | String
CUSTOMER_PAYMENT_DUE_IMMEDIATELY | Sets the Customer Payment due immediately flag | 2 | Optional | Small Integer
DATA_MANAGEMENT_DISABLED | Disable Data Management | 2 | Optional | Small Integer
DEF_COURIER | Default Courier | 2 | Optional | Small Integer
DEF_CREDIT_BUREAU | Default Credit Bureau | 2 | Optional | Small Integer
DEF_CUST_STATUS | Default Status for Customer Accounts | 2 | Optional | Small Integer
DEF_DELIVERY_TERMS | Default Delivery Terms | 8 | Optional | String
DEF_DELIVERY_TERMS_FOR_PURCHASES | Default Delivery Terms For Purchases [Intrastat] | 8 | Optional | String
DEF_DELIVERY_TERMS_FOR_SALES | Default Delivery Terms For Sales [Intrastat] | 8 | Optional | String
DEF_NOTC | Default Nature Of Transaction Code | 8 | Optional | String
DEF_NOTC_FOR_PURCHASES | Default Nature Of Transaction Code for Purchases [Intrastat] | 8 | Optional | String
DEF_NOTC_FOR_SALES | Default Nature Of Transaction Code for Sales [Intrastat] | 8 | Optional | String
DEF_PUR_ADDRESS | Default Purchase Order Address | 4 | Optional | Integer
DEF_SUPP_STATUS | Default Status for Supplier Accounts | 2 | Optional | Small Integer
DEFAULT_CHART | Default Chart of Accounts | 2 | Optional | Small Integer
DEPARTMENTS_LABEL | Departments Label | 10 | Optional | String
E_MAIL | Company EMail Address | 255 | Optional | String
ECSALES_BRANCH_POSTCODE | EC Sales Branch Postcode. Available on only UK datasets. | 8 | Optional | String
ENABLE_PROJECT_COSTING | Company Preferences - Parameters - Enable Project Costing | 1 | Optional | Byte
EURO_RATE | Euro Rate | 8 | Optional | Double
EXCLUDE_DISPUTED | Exclude Disputed Transactions | 2 | Optional | Small Integer
EXCLUDE_DOCTOR | Exclude Deleted Transactions | 2 | Optional | Small Integer
FAX | Fax Number | 30 | Optional | String
FINYEAR_MONTH | Financial Year Start Month | 1 | Optional | Byte
FINYEAR_YEAR | Financial Year | 2 | Optional | Small Integer
FIXEDASSETS_LABEL | Fixed Assets Label | 10 | Optional | String
FLAT_RATE_VAT_PERCENT | Flat Rate VAT Percent | 8 | Optional | Double
FOREIGN_TRADER_ENABLED | Foreign trader enabled flag | 1 | Read Only | Byte
GROUP_HISTORY | Group History | 2 | Optional | Small Integer
INV_SHOW_SPECIAL_CODES | Show Special Codes in Invoicing/SOP/POP | 1 | Optional | Byte
INVOICE_CARR_DEPT | Default Invoice Carriage Department | 2 | Optional | Small Integer
INVOICE_CARR_NET | Default Invoice Carriage Net | 8 | Optional | Double
INVOICE_CARR_NOMINAL | Default Invoice Carriage Nominal Code | 8 | Optional | String
INVOICE_DEF_ACC | Invoice Default to Account Ref | 1 | Optional | Byte
INVOICE_DEF_QTY | Invoice Item Default to Quantity | 1 | Optional | Byte
INVOICE_DEF_SRVTEXT | Default Service Text | 8 | Optional | String
INVOICE_DISC_UNITPRICE | Calculate Unit Price by Discount | 1 | Optional | Byte
ITEM_AMENDABLE | Vat Amendable on Items | 2 | Optional | Small Integer
LAST_AUDIT_CHECK | Last Audit Trail Check Date | 2 | Optional | Date
LAST_BACKUP | Last Backup Date | 2 | Optional | Date
LAST_BANK_CHECK | Last Bank Check Date | 2 | Optional | Date
LAST_CHEQUE | Last Cheque Index Number | 4 | Optional | Integer
LAST_CLEAR_AUDIT | Date Last Clear Audit Trail | 2 | Optional | Date
LAST_INVOICE_CHECK | Last Invoice Check Date | 2 | Optional | Date
LAST_MONTH_END | Last Month End | 2 | Optional | Date
LAST_NOMINAL_CHECK | Last Nominal Check Date | 2 | Optional | Date
LAST_POP_CHECK | Last POP Check Date | 2 | Optional | Date
LAST_PUCRHASE_CHECK | Last Purchase Check Date (fieldname is correct) | 2 | Optional | Date
LAST_REMITTANCE | Last System Generated Remittance Number | 4 | Optional | Integer
LAST_SALES_CHECK | Last Sales Check Date | 2 | Optional | Date
LAST_SOP_CHECK | Last SOP Check Date | 2 | Optional | Date
LAST_STOCK_CHECK | Last Stock Check Date | 2 | Optional | Date
MAJOR_VERSION | Major Version Number | 1 | Required | Byte
MINOR_VERSION | Minor Version Number | 1 | Required | Byte
NAME | Company Name | 60 | Optional | String
NO_RECUR_STARTUP | No Recurring Entries at Startup | 1 | Optional | Byte
NO_VAT_TAX_CODE | No Vat Tax Code | 2 | Optional | Small Integer
NO_WARN_VISA_RECEIPT | No Warnings on Visa Receipt | 1 | Optional | Byte
NON_VATABLE_TAX_CODE | Non Vatable Tax Code | 2 | Optional | Small Integer
OSSIOSS_ENABLED | OSSIOSS enabled flag | 2 | Optional | Small Integer
OVERRIDE_STOCK_DEP | Override Stock Department with Customer Department | 1 | Optional | Byte
POP_INTRASTAT_ENABLED | Intrastat reporting enabled for POP | 1 | Optional | Byte
PRICE_LIST_PRICES

Invoice/Order Defaults tab - Apply discounts to:

1 to include Price List Prices, 0 to exclude Price List Prices.

NOTE: Must be 0 if ALL_CUSTOMERS is 0.

 1 Optional Byte
PRINT_CHEQUE | Cheque Voucher | 1 | Optional | Byte
PRINT_LASER | Laser Format | 1 | Optional | Byte
PRINT_PAGE_THROW | Page Throw | 1 | Optional | Byte
PRINT_PLAIN | Plain Format | 1 | Optional | Byte
PRINT_PREFS | Print Preferences | 2 | Optional | Small Integer
PRINT_QUICK | Quick Format | 1 | Optional | Byte
PRODUCT_ANALYSIS_1 | 1st Product Customer Field | 10 | Optional | String
PRODUCT_ANALYSIS_2 | 2nd Product Customer Field | 10 | Optional | String
PRODUCT_ANALYSIS_3 | 3rd Product Customer Field | 10 | Optional | String
PROGRAM_MAJOR_VERSION | Program Major Version | 2 | Optional | Small Integer
PROGRAM_MINOR_VERSION | Program Major Version | 2 | Optional | Small Integer
PROGRAM_BUILD_VERSION | Program Major Version | 2 | Optional | Small Integer
PROGRAM_BUGFIX_VERSION | Program Major Version | 2 | Optional | Small Integer
PROGRAM_TYPE | Program Type Flag | 2 | Optional | Small Integer
PROJECT_CUSTOM_1 | Project Record Custom Field One Default | 30 | Optional | String
PROJECT_CUSTOM_2 | Project Record Custom Field Two Default | 30 | Optional | String
PROJECT_CUSTOM_3 | Project Record Custom Field Three Default | 30 | Optional | String
PRODUCT_DESCRIPTION_DISCOUNT_A | Product description discount A | 20 | Optional | String
PRODUCT_DESCRIPTION_DISCOUNT_B | Product description discount B | 20 | Optional | String
PRODUCT_DESCRIPTION_DISCOUNT_C | Product description discount C | 20 | Optional | String
PRODUCT_DESCRIPTION_DISCOUNT_D | Product description discount D | 20 | Optional | String
PRODUCT_DESCRIPTION_DISCOUNT_E | Product description discount E | 20 | Optional | String
PROJECT_CUSTOM_3 | Project Record Custom Field Three Default | 20 | Optional | String
PURCHASE_ACCOUNT_STATUS | Purchase Account Status | 2 | Optional | Small Integer
PURCHASE_AGED_PAYMENTS | Purchase Aged Payments | 2 | Optional | Small Integer
PURCHASE_AGREED_TERMS | Purchase Agreed Terms | 2 | Optional | Small Integer
PURCHASE_ANALYSIS_1 | Purchase Analysis 1 | 10 | Optional | String
PURCHASE_ANALYSIS_2 | Purchase Analysis 2 | 10 | Optional | String
PURCHASE_ANALYSIS_3 | Purchase Analysis 3 | 10 | Optional | String
PURCHASE_ANALYSIS_4 | Purchase Analysis 4 | 10 | Optional | String
PURCHASE_ANALYSIS_5 | Purchase Analysis 5 | 10 | Optional | String
PURCHASE_ANALYSIS_6 | Purchase Analysis 6 | 10 | Optional | String
PURCHASE_CAL_MTH_AGED | Purchase Transaction Ageing Method | 1 | Optional | Byte
PURCHASE_CARR_DEPT | Default Purchase Carriage Department | 2 | Optional | Small Integer
PURCHASE_CARR_NET | Default Purchase Carriage Net | 8 | Optional | Double
PURCHASE_CARR_NOMINAL | Default Purchase Carriage Nominal Code | 8 | Optional | String
PURCHASE_CREDIT_LIMIT | Purchase Default Credit Limit | 8 | Optional | Double
PURCHASE_CURRENCY | Purchase Default Currency | 1 | Optional | Byte
PURCHASE_DAYS_TO_AGE | Days to use for Purchase Transaction Ageing | 2 | Optional | Small Integer
PURCHASE_DEFAULT_INCOTERMS | Supplier Default Incoterms | 2 | Optional | Small Integer
PURCHASE_DEPARTMENT | Purchase Default Department | 2 | Optional | Small Integer
PURCHASE_DISC_TYPE | Purchase Discount Type | 1 | Optional | Byte
PURCHASE_DISCOUNT_VAL | Purchase Discount Value | 8 | Optional | Double
PURCHASE_DUEDAYS | Purchase Due Days | 2 | Optional | Small Integer
PURCHASE_FUTURE | Include Future Totals in Balance | 2 | Optional | Small Integer
PURCHASE_HOLD_MAIL | Purchase Hold Mail | 2 | Optional | Small Integer
PURCHASE_NOMINAL | Purchase Default Nominal Code | 8 | Optional | String
PURCHASE_PAY_DUE_DAYS | Purchase Payment Due Days | 2 | Optional | Small Integer
PURCHASE_PERIOD_1 | Purchase Aged Period 1 | 2 | Optional | Small Integer
PURCHASE_PERIOD_2 | Purchase Aged Period 2 | 2 | Optional | Small Integer
PURCHASE_PERIOD_3 | Purchase Aged Period 3 | 2 | Optional | Small Integer
PURCHASE_PERIOD_4 | Purchase Aged Period 4 | 2 | Optional | Small Integer
PURCHASE_SETT_DISCOUNT | Purchase Default Settlement Discount | 8 | Optional | Double
PURCHASE_TAXCODE | Purchase Default Tax Code | 2 | Optional | Small Integer
PURCHASE_TERMS | Purchase Default Terms | 30 | Optional | String
RECORD_CREATE_DATE | Date and time when record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when record was created | 8 | Optional | Date
REMITTANCE_LINES_PAGE | No of Remittance Lines per Page | 2 | Optional | Small Integer
REPORT_POSITION | Report Position | 1 | Optional | Byte
REPORTS_BANNER | Reports Include Banner | 2 | Optional | Small Integer
REPORTS_DISPLAY | Reports Display | 1 | Optional | Byte
REPORTS_EMAIL | Reports EMail | 1 | Optional | Byte
REPORTS_FILE | Reports File | 1 | Optional | Byte
REPORTS_PREVIEW | Reports Preview | 1 | Optional | Byte
REPORTS_PRINTER | Reports Printer | 1 | Optional | Byte
REVISION_NO | Revision Number | 1 | Required | Byte
SALES_ACCOUNT_STATUS | Sales Account Status | 2 | Optional | Small Integer
SALES_ADD_DISC_1 | Additional Discount Table 1 | 8 | Optional | Double
SALES_ADD_DISC_10 | Additional Discount Table 10 | 8 | Optional | Double
SALES_ADD_DISC_2 | Additional Discount Table 2 | 8 | Optional | Double
SALES_ADD_DISC_3 | Additional Discount Table 3 | 8 | Optional | Double
SALES_ADD_DISC_4 | Additional Discount Table 4 | 8 | Optional | Double
SALES_ADD_DISC_5 | Additional Discount Table 5 | 8 | Optional | Double
SALES_ADD_DISC_6 | Additional Discount Table 6 | 8 | Optional | Double
SALES_ADD_DISC_7 | Additional Discount Table 7 | 8 | Optional | Double
SALES_ADD_DISC_8 | Additional Discount Table 8 | 8 | Optional | Double
SALES_ADD_DISC_9 | Additional Discount Table 9 | 8 | Optional | Double
SALES_AGED_PAYMENTS | Sales Aged By Payments | 2 | Optional | Small Integer
SALES_AGREED_TERMS | Sales Agreed Credit Terms | 2 | Optional | Small Integer
SALES_AMOUNT_SOLD_1 | Sales Amount Sold 1 | 8 | Optional | Double
SALES_AMOUNT_SOLD_10 | Sales Amount Sold 10 | 8 | Optional | Double
SALES_AMOUNT_SOLD_2 | Sales Amount Sold 2 | 8 | Optional | Double
SALES_AMOUNT_SOLD_3 | Sales Amount Sold 3 | 8 | Optional | Double
SALES_AMOUNT_SOLD_4 | Sales Amount Sold 4 | 8 | Optional | Double
SALES_AMOUNT_SOLD_5 | Sales Amount Sold 5 | 8 | Optional | Double
SALES_AMOUNT_SOLD_6 | Sales Amount Sold 6 | 8 | Optional | Double
SALES_AMOUNT_SOLD_7 | Sales Amount Sold 7 | 8 | Optional | Double
SALES_AMOUNT_SOLD_8 | Sales Amount Sold 8 | 8 | Optional | Double
SALES_AMOUNT_SOLD_9 | Sales Amount Sold 9 | 8 | Optional | Double
SALES_ANALYSIS_1 | Sales Analysis 1 | 10 | Optional | String
SALES_ANALYSIS_2 | Sales Analysis 2 | 10 | Optional | String
SALES_ANALYSIS_3 | Sales Analysis 3 | 10 | Optional | String
SALES_ANALYSIS_4 | Sales Analysis 4 | 10 | Optional | String
SALES_ANALYSIS_5 | Sales Analysis 5 | 10 | Optional | String
SALES_ANALYSIS_6 | Sales Analysis 6 | 10 | Optional | String
SALES_CAL_MTH_AGED | Sales Transaction Ageing Method | 1 | Optional | Byte
SALES_CREDIT_LIMIT | Sales Credit Limit | 8 | Optional | Double
SALES_CURRENCY | Sales Default Currency | 1 | Optional | Byte
SALES_DAYS_TO_AGE | Days to use for Sales Transaction Ageing | 2 | Optional | Small Integer
SALES_DEFAULT_INCOTERMS | Customer Default Incoterms | 2 | Optional | Small Integer
SALES_DEF_CALLRATE | Sales Default Call Rate | 8 | Optional | Double
SALES_DEPARTMENT | Sales Default Department | 2 | Optional | Small Integer
SALES_DISC_TYPE | Sales Default Discount Type | 1 | Optional | Byte
SALES_DISCOUNT_VAL | Sales Discount Value | 8 | Optional | Double
SALES_DUEDAYS | Sales Default Due Days | 2 | Optional | Small Integer
SALES_FINANCE_RATE | Sales Finance Rate | 8 | Optional | Double
SALES_FUTURE | Include Future Totals in Balance | 2 | Optional | Small Integer
SALES_HOLD_MAIL | Sales Hold Mail | 2 | Optional | Small Integer
SALES_LAST_FIN_DATE | Sales Last Finance Date | 2 | Optional | Date
SALES_NOMINAL | Sales Default Nominal Code | 8 | Optional | String
SALES_PAY_DUE_DAYS | Sales Default Payment Due In | 2 | Optional | Small Integer
SALES_PERIOD_1 | Sales Aged Period 1 | 2 | Optional | Small Integer
SALES_PERIOD_2 | Sales Aged Period 2 | 2 | Optional | Small Integer
SALES_PERIOD_3 | Sales Aged Period 3 | 2 | Optional | Small Integer
SALES_PERIOD_4 | Sales Aged Period 4 | 2 | Optional | Small Integer
SALES_SETT_DISCOUNT | Sales Settlement Discount | 8 | Optional | Double
SALES_TAXCODE | Sales Default Tax Code | 2 | Optional | Small Integer
SALES_TERMS | Sales Default Terms | 30 | Optional | String
SHOW_REPORT_BITMAP | Show Report Bitmap | 1 | Optional | Byte
SINGLE_USER_FLAG | Single User Flag | 2 | Optional | Small Integer
SIPS_BANKREFN | The reference for the SIPS bank account | 8 | Optional | String
SIPS_REF | The GUID of the associated SIPS Account | 37 | Optional | String
SKELETON_JOURNALS | Copy Skeleton Journal Values | 2 | Optional | Small Integer
SOP_INTRASTAT_ENABLED | Intrastat reporting enabled for SOP | 1 | Optional | Byte
SPECIAL_PRICES | Invoice/Order Defaults tab - Apply discounts to: 1 to include Special Prices, 0 to exclude Special Prices | 1 | Optional | Byte
STOCKCATEGORY_LABEL | Product Categories Label | 10 | Optional | String
STOCK_CATEGORY | Stock Default Category | 2 | Optional | Small Integer
STOCK_DEPARTMENT | Stock Default Department | 2 | Optional | Small Integer
STOCK_NEGATIVE_COUNTER | Negative Stock Counter | 4 | Optional | Integer
STOCK_NOMINAL | Stock Default Nominal Code | 8 | Optional | String
STOCK_PURCHASE_NOMINAL | Stock Default Purchase Nominal Code | 8 | Optional | String
STOCK_QTYDP | Stock Quantity Decimal Precision | 2 | Optional | Small Integer
STOCK_TAXCODE | Stock Default Tax Code | 2 | Optional | Small Integer
STOCK_UNITDP | Stock Unit Decimal Precision | 2 | Optional | Small Integer
STOCK_UNITS | Stock Default Units | 8 | Optional | String
SUPP_UPDATE_TRAN_EX_REF_FROM | Source used to fill the extra reference field | 2 | Optional | Small Integer
SUPP_UPDATE_TRAN_REF_FROM | Source used to fill the reference field | 2 | Optional | Small Integer
SUPPLIER_COUNTRY_CODE | Default Supplier Country Code | 2 | Optional | String
SUPPLIER_PAYMENT_DUE_IMMEDIATELY | Sets the Supplier Payment due immediately flag | 2 | Optional | Small Integer
TELEPHONE | Telephone Number | 30 | Optional | String
TELEPHONE_2 | Second Telephone Number | 30 | Optional | String
TERMS_WARNING | Throw Warning on Terms | 2 | Optional | Small Integer
TIMESLIPS | Company Preferences - Parameters - Timeslips Link | 1 | Optional | Byte
TRANSFER_DEFAULTS | Transfer Company Details to New Company | 2 | Optional | Small Integer
UPDATE_ACTIVITY_POSTING | Update Activities on Posting | 2 | Optional | Small Integer
UPDATE_AGED_MODIFY | Update Aged on Modify | 2 | Optional | Small Integer
UPDATE_AGED_POSTING | Update Aged on Posting | 2 | Optional | Small Integer
UPDATE_BALANCE_MODIFY | Update Balances on Modify | 2 | Optional | Small Integer
UPDATE_BALANCE_POSTING | Update Balances on Posting | 2 | Optional | Small Integer
UPDATE_LAZY_ADD | Update Lazy Lists On Add | 2 | Optional | Small Integer
UPDATE_LAZY_MODIFY | Update Lazy Lists On Modify | 2 | Optional | Small Integer
UPDATE_LAZY_POSTING | Update Lazy Lists On Posting | 2 | Optional | Small Integer
UPDATE_LEDGER_ADD | Update Ledgers on Add | 2 | Optional | Small Integer
UPDATE_LEDGER_MODIFY | Update Ledgers on Modify | 2 | Optional | Small Integer
UPDATE_LEDGER_POSTING | Update Ledgers on Posting | 2 | Optional | Small Integer
UPDATE_SERVICE_TEXT | Update Service Default Text | 1 | Optional | Byte
VALIDATE_VAT_NO | Validate VAT Numbers | 1 | Optional | Byte
VALUE_DISCOUNTS | Invoice/Order Defaults tab - Always apply value discounts to special items (S1, S2 and S3) | 1 | Optional | Byte
VAT_CASH_FLAG | Vat Cash Accounting Flag | 1 | Optional | Byte
VAT_REG_NUMBER | Vat Registration Number | 20 | Optional | String
VAT_REGISTERED_FLAG | Vat Registration Number | 1 | Optional | Byte
VAT_SCHEME_FLAG | VAT scheme flag | 1 | Optional | Byte
WALL_BITMAP | Wallpaper Bitmap | 259 | Optional | String
WALL_POS | Wallpaper Position | 1 | Optional | Byte
WALL_SHOW | Wallpaper Display | 1 | Optional | Byte
WELCOME_SCREEN_FLAG | Hide Welcome Screen at Startup | 2 | Optional | Small Integer
WIZ_SCALE_CODE | Scale Charge Code | 8 | Optional | String
WIZ_SCALE_DATE | Last Scale Charges Posting Date | 2 | Optional | Date
WIZ_START_BILL | Call Bill Nominal | 8 | Optional | String
WIZ_START_GROUP_BANK | Group Items on Bank Reconciliation | 2 | Optional | Small Integer
WIZ_START_GROUP_PP | Group Invoices in Purchase Payments | 2 | Optional | Small Integer
WIZ_START_GROUP_SR | Group Invoices in Sales Receipts | 2 | Optional | Small Integer
WIZ_START_LAST_POS | Startup Wizard Last Position | 2 | Optional | Small Integer
WIZ_START_RUN | Startup Wizard Already Ran | 2 | Optional | Byte
WIZ_START_SPLITS | Payment by Splits | 2 | Optional | Small Integer
WIZ_STK_CLOSE_CODE | Stock Wizard Closing Stock Code | 8 | Optional | String
WIZ_STK_CLOSE_VAL | Previous Months Closing Stock Value | 8 | Optional | Double
WIZ_STK_CODE | Stock Wizard Stock Code | 8 | Optional | String
WIZ_STK_DATE | Last Stock Posting Date | 2 | Optional | Date
WIZ_VAT_AMOUNT | Vat Return Amount | 8 | Optional | Double
WIZ_VAT_CODE | Vat Code | 8 | Optional | String
WIZ_VAT_DATE | Last Vat Return Date | 2 | Optional | Date
WIZ_VAT_DATE_FROM | Last Vat Return Date From | 2 | Optional | Date
WIZ_VAT_DATE_TO | Last Vat Return Date To | 2 | Optional | Date
WIZ_VAT_PUR_AMOUNT | Vat Return Vat on Purchase Amount | 8 | Optional | Double
WIZ_VAT_SAL_AMOUNT | Vat Return Vat on Sales Amount | 8 | Optional | Double
WWW | Company WWW Address | 255 | Optional | String

Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Posting a Purchase Payment and Cheque
Posting a Purchase Payment and Remittance
Creating a Profit and Loss Report in Excel 2000
Creating an E-Mail in Microsoft Outlook 2000
Reading Nominal Budgets Using the GetBudget method
Determine the company VAT Scheme
Is Date Valid For Lock Date
Is Date User Valid For Lock Date
Check VAT Schemes


SOPData

Description

The SOPData object gives access to the Sales Order (SAORDER.DTA) table.

Applies to

Sage 50 Accounts Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Account Reference | 8 | Required | String
ADDRESS_1 | Customer Address 1 | 60 | Optional | String
ADDRESS_2 | Customer Address 2 | 60 | Optional | String
ADDRESS_3 | Customer Address 3 | 60 | Optional | String
ADDRESS_4 | Customer Address 4 | 60 | Optional | String
ADDRESS_5 | Customer Address 5 | 60 | Optional | String
ANALYSIS_1 | Analysis 1 | 30 | Optional | String
ANALYSIS_2 | Analysis 2 | 30 | Optional | String
ANALYSIS_3 | Analysis 3 | 30 | Optional | String
AMOUNT_PREPAID | Amount Prepaid | 8 | Optional | Double
BANK_CODE | Bank Posting Code | 8 | Optional | String
BASE_AMOUNT_PAID | Base Amount Prepaid | 8 | Optional | Double
BASE_CARR_NET | Base Carriage Net Amount | 8 | Optional | Double
BASE_CARR_TAX | Base Carriage Tax Amount | 8 | Optional | Double
BASE_NETVALUE_DISCOUNT | Net Value Discount Amount in Base Currency | 8 | Optional | Double
BASE_SETT_DISC_RATE | Base Settlement Discount % Rate | 8 | Optional | Double
BASE_TOT_NET | Base Net Amount (Goods but not carriage) | 8 | Optional | Double
BASE_TOT_TAX | Base Tax Amount (Goods but not carriage) | 8 | Optional | Double
CARR_DEPT_NUMBER | Carriage Department Number | 2 | Optional | Small Integer
CARR_NET | Carriage Net Amount | 8 | Optional | Double
CARR_NOM_CODE | Carriage Nominal Code | 8 | Optional | String
CARR_TAX | Carriage Tax Amount | 8 | Optional | Double
CARR_TAX_CODE | Carriage Tax Code | 2 | Optional | Small Integer
CONSIGNMENT_REF | Consignment Reference | 30 | Optional | String
CONTACT_NAME | Customer Contact Name | 30 | Optional | String
COUNTRY_CODE | Customer Country Code | 2 | Optional | String
COURIER | Courier Number | 2 | Optional | Small Integer
CURRENCY | Currency | 1 | Optional | Byte
CURRENCY_USED | Currency Used | 1 | Optional | Byte
CUST_DISC_RATE | Customer Discount | 8 | Optional | Double
CUST_ORDER_NUMBER | Customer's Order Number | 60 | Optional | String
CUST_TEL_NUMBER | Customer's Telephone Number | 30 | Optional | String
DEF_TAX_CODE | Default Tax Code | 2 | Optional | Small Integer
DEL_ADDRESS_1 | Delivery Address Line 1 | 60 | Optional | String
DEL_ADDRESS_2 | Delivery Address Line 2 | 60 | Optional | String
DEL_ADDRESS_3 | Delivery Address Line 3 | 60 | Optional | String
DEL_ADDRESS_4 | Delivery Address Line 4 | 60 | Optional | String
DEL_ADDRESS_5 | Delivery Address Line 5 | 60 | Optional | String
DELETED_FLAG | Is Deleted | 2 | Optional | Small Integer
DELIVERY_ADDRESS_REFN | Delivery address record number | 4 | Optional | Integer
DELIVERY_NAME | Delivery Address Name | 60 | Optional | String
DESPATCH_DATE | Despatch Date | 2 | Optional | Date
DISCOUNT_COMMENT1 | Text Field For Additional Comments | 60 | Optional | String
DISCOUNT_COMMENT2 | Text Field For Additional Comments | 60 | Optional | String
DISCOUNT_TYPE | Discount Type | 1 | Optional | Byte
DUNS_NUMBER | Duns credit Reference Number | 9 | Optional | String
EMAILED | Emailed flag - Yes/No | 1 | Optional | Byte
EORI_NUMBER | Delivery address EORI Number | 17 | Optional | String
EURO_GROSS | Euro Gross Amount | 8 | Optional | Double
EURO_RATE | Euro Rate | 8 | Optional | Double
EXTERNAL_USAGE | Number of External Usages | 4 | Optional | Integer
FIRST_ITEM | Record Number of First SOP Item | 4 | Optional | Integer
FOREIGN_GROSS | Foreign Gross Amount | 8 | Optional | Double
FOREIGN_RATE | Foreign Rate for Euro Currency | 8 | Optional | Double
GDN_NUMBER | GDN Reference | 4 | Optional | Integer
GLOBAL_DEPT_NUMBER | Global Department Number | 2 | Optional | Small Integer
GLOBAL_DETAILS | Global Details | 60 | Optional | String
GLOBAL_NOM_CODE | Global Nominal Code | 8 | Optional | String
GLOBAL_TAX_CODE | Global Tax Code | 2 | Optional | Small Integer
HAS_EXTERNAL_LINK | Has External Link | 2 | Optional | Small Integer
INCOTERMS | Incoterms | 2 | Optional | Small Integer
INTRASTAT_STATUS | Intrastat Reconciled Status | 1 | Optional | Byte
INVOICE_FOREIGN_BALANCE | Foreign Balance | 8 | Optional | Double
INVOICE_NUMBER | Invoice Number | 7 | Required | String
ITEMS_NET | Net Amount (Goods but not carriage) | 8 | Optional | Double
ITEMS_TAX | Tax Amount (Goods but not carriage) | 8 | Optional | Double
LAST_NETVALUE_DISCOUNT | Last Net Value Discount Amount | 8 | Optional | Double
LAST_UPDATED | Last Updated Date | 8 | Optional | Date
NAME | Customer Account Name | 60 | Optional | String
NETVALUE_DESCRIPTION | Net Value Discount description | 60 | Optional | String
NETVALUE_DISCOUNT | Discount Value To Be Deducted From Sop | 8 | Optional | Double
NETVALUE_DISCOUNT_PERCENT | Net Value Discount percentage | 8 | Optional | Double
NOTES_1 | Notes 1 | 60 | Optional | String
NOTES_2 | Notes 2 | 60 | Optional | String
NOTES_3 | Notes 3 | 60 | Optional | String
ORDER_DATE | Order Date | 2 | Required | Date
ORDER_NUMBER | Order Number | 4 | Required | Integer
ORDER_TYPE | Order Type Code | 1 | Required | Byte
OSS_COUNTRY_OF_VAT | Country of VAT | 2 | Optional | String
OSS_REPORTING_TYPE | Report type | 2 | Optional | Small Integer
PAYMENT_OSS_COUNTRY_OF_VAT | Payment Country of VAT | 2 | Optional | String
PAYMENT_OSS_REPORTING_TYPE | Payment Report type | 2 | Optional | Small Integer
PAYMENT_REF | Payment Reference | 30 | Optional | String
PAYMENT_TAX_CODE | Payment Tax Code | 2 | Optional | Small Integer
PAYMENT_TYPE | Payment Type (SR/SA) | 1 | Optional | Byte
PRACTICE_SOLUTIONS_REFN | Sage Practice Solutions Reference | 60 | Optional | String
PRINTED_CODE | Printed Flag - Yes/No | 1 | Optional | Byte
QUOTE_EXPIRY | The expiry date of the quotation | 2 | Optional | Date
QUOTE_STATUS | The status of the quotation | 2 | Optional | Small Integer
RECORD_CREATE_DATE | Time and date when record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Time and date when record was modified | 8 | Optional | Date
RECURRING_REFERENCE | Recurring Reference | 11 | Optional | String
SEND_VIA_EMAIL | Flag To Set Sop Output To Email | 1 | Optional | Byte
SETTLEMENT_DISC_RATE | Settlement Discount % Rate | 8 | Optional | Double
SETTLEMENT_DUE_DAYS | Settlement Days | 2 | Optional | Small Integer
STATUS | Order Status Code | 1 | Optional | Byte
TAKEN_BY | Order Taken By | 60 | Optional | String
TOTAL_BYTES | 4 | Optional | Integer
UNALLOCATED_NETVALUE_DISCOUNT | Unallocated Net Value Discount amount | 8 | Optional | Double
VAT_REG_NUMBER | VAT Number | 20 | Optional | String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Adding an item to a sales order


SOPIndex

Description

The SOPIndex object gives access to the Sales Order Index (SAOINDEX.DTA) table.

Applies to

Sage 50 Accounts Professional.

Fields Collection

Name | Description | Length | Input | Data Type
INVOICE_NUMBER | Sales Order Number | 7 | Required | String
RECORD_NUMBER | Record Number in Data File | 4 | Required | Integer
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Adding an item to a sales order


SOPItem

Description

The SOPItem object gives access to the Sales Order Items (SAOITEM.DTA) table.

Applies to

Sage 50 Accounts Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ADD_DISC_RATE Additional Discount Percentage Rate 8 Optional

Double
BASE_FULL_NET Full Net Amount (no discount) 8 Optional

Double
BASE_NET Base Net Amount 8 Optional

Double
BASE_NETVALUE_DISCOUNT Base Net Value Discount Amount 8 Optional

Double
BASE_TAX Base Tax Amount 8 Optional

Double
COMMENT_1 | Comment 1 | 60 | Optional | String
COMMENT_2 | Comment 2 | 60 | Optional | String
COST_CODE_ID | Project Cost Code ID | 4 | Optional | Integer
DELIVERY_DATE | Delivery Date | 2 | Optional | Date
DEPT_NUMBER | Department Number | 2 | Optional | Small Integer
DESCRIPTION | Description | 120 | Optional | String
DISCOUNT_AMOUNT | Total Discount Percent on line item | 8 | Optional | Double
DISCOUNT_RATE | Discount Rate set on Sales record | 8 | Optional | Double
DUE_DATE | Due Date | 2 | Optional | Date
EXT_ORDER_LINE_REF Extra Order Line Reference 4 Optional

Integer
EXT_ORDER_REF Extra Order Reference 30 Optional

String
FULL_NET_AMOUNT | Full Net Amount (Before Discount) | 8 | Optional | Double
FUND_NUMBER | Fund Number | 4 | Optional | Integer
INVOICE_NUMBER | Invoice Number | 4 | Optional | Integer
ITEM_NUMBER | Item Number | 2 | Optional | Small Integer
ITEMID | Unique Identifier, Unaffected By File Maintenance Routines | 4 | System Produced | Integer
JOB_REFERENCE | Job Reference (Line Information) | 60 | Optional | String
NET_AMOUNT | Net Amount (After Discount) | 8 | Optional | Double
NETVALUE_DISCOUNT | Net Value Discount amount | 8 | Optional | Double
NETVALUE_DISCOUNT_ALLOCATED | Negotiation Discount allocated | 8 | Optional | Double
NEXT_ITEM | Record Number of Next Item | 4 | Optional | Integer
NOMINAL_CODE | Nominal Code | 8 | Optional | String
OFFSET | Offset of Service Text | 4 | Optional | Integer
PREV_ITEM | Record Number of Previous Item | 4 | Optional | Integer
PROJECT_ID | Project ID | 4 | Optional | Integer
QTY_ALLOCATED | Quantity Allocated for this Order | 8 | Optional | Double
QTY_DELIVERED | Quantity Previously Delivered for this Order | 8 | Optional | Double
QTY_DESPATCH | Quantity left to Despatch | 8 | Optional | Double
QTY_INTRASTAT_CONFIRMED | Quantity IntraStat Confirmed | 8 | Optional | Double
QTY_ORDER | Quantity Ordered | 8 | Optional | Double
SERVICE_FILE | Redundant - Do Not Use | 120 | Optional | String
SERVICE_FILE_SIZE | Redundant - Do Not Use | 4 | Optional | Integer
SERVICE_FLAG | Service Item Flag | 1 | Optional | Byte
SERVICE_ITEM_LINES | Redundant - Do Not Use | 4 | Optional | Integer
STOCK_CODE | Stock Code | 30 | Required | String
TAX_AMOUNT | Tax Amount | 8 | Optional | Double
TAX_CODE | Tax Code | 2 | Optional | Small Integer
TAX_FLAG | Item VAT Ammended. | 1 | Optional | Byte
TAX_RATE | Tax Rate | 8 | Optional | Double
TEXT | Service Invoice/Credit Text | 120 | Optional | String
UNIT_OF_SALE | Unit of Sale | 8 | Optional | String
UNIT_PRICE | Unit Price | 8 | Optional | Double
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Posting a Sales Order
Adding an Item to a Sales Order


SOPPost

Description

The SOPPost object enables Sales Orders to be posted with all the relevant tables being updated automatically.

Applies to

Sage 50 Accounts Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Account Reference | 8 | Required | String
ADDRESS_1 | Customer Address 1 | 60 | Optional | String
ADDRESS_2 | Customer Address 2 | 60 | Optional | String
ADDRESS_3 | Customer Address 3 | 60 | Optional | String
ADDRESS_4 | Customer Address 4 | 60 | Optional | String
ADDRESS_5 | Customer Address 5 | 60 | Optional | String
AMOUNT_PREPAID | Amount Prepaid | 8 | Optional | Double
ANALYSIS_1 | Analysis 1 | 30 | Optional | String
ANALYSIS_2 | Analysis 2 | 30 | Optional | String
ANALYSIS_3 | Analysis 3 | 30 | Optional | String
BANK_CODE | Bank Posting Code | 8 | Optional | String
BASE_AMOUNT_PAID | Base Amount Prepaid | 8 | Optional | Double
BASE_CARR_NET | Base Carriage Net Amount | 8 | Optional | Double
BASE_CARR_TAX | Base Carriage Tax Amount | 8 | Optional | Double
BASE_NETVALUE_DISCOUNT | Base Net Value Discount Amount | 8 | Optional | Double
BASE_SETT_DISC_RATE | Base Settlement Discount % Rate | 8 | Optional | Double
BASE_TOT_NET | Base Net Amount (Goods but not carriage) | 8 | Optional | Double
BASE_TOT_TAX | Base Tax Amount (Goods but not carriage) | 8 | Optional | Double
CARR_DEPT_NUMBER | Carriage Department Number | 2 | Optional | Small Integer
CARR_NET | Carriage Net Amount | 8 | Optional | Double
CARR_NOM_CODE | Carriage Nominal Code | 8 | Optional | String
CARR_TAX | Carriage Tax Amount | 8 | Optional | Double
CARR_TAX_CODE | Carriage Tax Code | 2 | Optional | Small Integer
CONSIGNMENT_REF | Consignment Reference | 30 | Optional | String
CONTACT_NAME | Customer Contact Name | 30 | Optional | String
COURIER | Courier Number | 2 | Optional | Small Integer
CURRENCY | Currency | 1 | Optional | Byte
CURRENCY_USED | Currency Used | 1 | Optional | Byte
CUST_DISC_RATE | Customer Discount | 8 | Optional | Double
CUST_ORDER_NUMBER | Customer's Order Number | 60 | Optional | String
CUST_TEL_NUMBER | Customer's Telephone Number | 30 | Optional | String
DEF_TAX_CODE | Default Tax Code | 2 | Optional | Small Integer
DEL_ADDRESS_1 | Delivery Address Line 1 | 60 | Optional | String
DEL_ADDRESS_2 | Delivery Address Line 2 | 60 | Optional | String
DEL_ADDRESS_3 | Delivery Address Line 3 | 60 | Optional | String
DEL_ADDRESS_4 | Delivery Address Line 4 | 60 | Optional | String
DEL_ADDRESS_5 | Delivery Address Line 5 | 60 | Optional | String
DELETED_FLAG | Is Deleted | 2 | Optional | Small Integer
DELIVERY_NAME | Delivery Address Name | 60 | Optional | String
DESPATCH_DATE | Despatch Date | 2 | Optional | Date
DISCOUNT_COMMENT1 | Discount Comment 1 | 60 | Optional | String
DISCOUNT_COMMENT2 | Discount Comment 2 | 60 | Optional | String
DISCOUNT_TYPE | Discount Type | 1 | Optional | Byte
DUNS_NUMBER | Duns Credit Reference Number | 9 | Optional | String
EMAILED | Emailed flag - Yes/No | 1 | Optional | Byte
EURO_GROSS | Euro Gross Amount | 8 | Optional | Double
EURO_RATE | Euro Rate | 8 | Optional | Double
EXTERNAL_USAGE | Number of External Usages | 4 | Optional | Integer
FIRST_ITEM | Record Number of First SOP Item | 4 | Optional | Integer
FOREIGN_GROSS | Foreign Gross Amount | 8 | Optional | Double
FOREIGN_RATE | Foreign Rate for Euro Currency | 8 | Optional | Double
GLOBAL_DEPT_NUMBER | Global Department Number | 2 | Optional | Small Integer
GLOBAL_DETAILS | Global Details | 60 | Optional | String
GLOBAL_NOM_CODE | Global Nominal Code | 8 | Optional | String
GLOBAL_TAX_CODE | Global Tax Code | 2 | Optional | Small Integer
INTRASTAT_STATUS | Intrastat Reconciled Status | 1 | Optional | Byte
INVOICE_NUMBER | Invoice Number | 7 | Required | String
ITEMS_NET | Net Amount (Goods but not carriage) | 8 | Optional | Double
ITEMS_TAX | Tax Amount (Goods but not carriage) | 8 | Optional | Double
LAST_NETVALUE_DISCOUNT | Last Net Value Discount Amount | 8 | Optional | Double
LAST_UPDATED | Date Of Last Update | 8 | Optional | Date
NAME | Customer Account Name | 60 | Optional | String
NETVALUE_DESCRIPTION | Net Value Discount Description | 60 | Optional | String
NETVALUE_DISCOUNT | Net Value Discount Amount | 8 | Optional | Double
NETVALUE_DISCOUNT_PERCENT | Net Value Discount Amount | 8 | Optional | Double
NOTES_1 | Notes 1 | 60 | Optional | String
NOTES_2 | Notes 2 | 60 | Optional | String
NOTES_3 | Notes 3 | 60 | Optional | String
ORDER_DATE | Order Date | 2 | Required | Date
ORDER_NUMBER | Order Number | 4 | Required | Integer
OSS_COUNTRY_OF_VAT | Country of VAT | 2 | Optional | String
OSS_REPORTING_TYPE | Report type | 2 | Optional | Small Integer
ORDER_TYPE | Order Type Code | 1 | Required | Byte
PAYMENT_REF | Payment Reference | 30 | Optional | String
PAYMENT_TAX_CODE | Payment Tax Code | 2 | Optional | Small Integer
PAYMENT_TYPE | Payment Type (SR/SA) | 1 | Optional | Byte
PRACTICE_SOLUTIONS_REFN | Sage Practice Solutions Reference | 60 | Optional | String
PRINTED_CODE | Printed Flag - Yes/No | 1 | Optional | Byte
QUOTE_EXPIRY | The expiry date of the quotation | 2 | Optional | Date
QUOTE_STATUS | The status of the quotation | 2 | Optional | Small Integer
RECORD_CREATE_DATE | Date and time when record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when record was created | 8 | Optional | Date
RECURRING_REFERENCE | Recurring Reference | 11 | Optional | String
SEND_VIA_EMAIL | Sent Via Tmail - Yes/No | 1 | Optional | Byte
SETTLEMENT_DISC_RATE | Settlement Discount % Rate | 8 | Optional | Double
SETTLEMENT_DUE_DAYS | Settlement Days | 2 | Optional | Small Integer
STATUS | Order Status Code | 1 | Optional | Byte
TAKEN BY | Order Taken By | 60 | Optional | String
TOTAL_BYTES | 4 | Optional | Integer
UNALLOCATED_NETVALUE_DISCOUNT | Unallocated Net Value Discount Amount | 8 | Optional | Double
VAT_REG_NUMBER | VAT registration number | 20 | Optional | String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Posting a Sales Order
Adding an Item to a Sales Order


SOPRecord

Description

The SOPRecord object gives access to the Sales Order (SAORDER.DTA) table and the Sales Order Index (SAOINDEX.DTA) table. As an SDORecord object, it encapsulates both the data and index files.

Applies to

Sage 50 Accounts Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Account Reference | 8 | Required | String
ADDRESS_1 | Customer Address 1 | 60 | Optional | String
ADDRESS_2 | Customer Address 2 | 60 | Optional | String
ADDRESS_3 | Customer Address 3 | 60 | Optional | String
ADDRESS_4 | Customer Address 4 | 60 | Optional | String
ADDRESS_5 | Customer Address 5 | 60 | Optional | String
ANALYSIS_1 | Analysis 1 | 30 | Optional | String
ANALYSIS_2 | Analysis 2 | 30 | Optional | String
ANALYSIS_3 | Analysis 3 | 30 | Optional | String
AMOUNT_PREPAID | Amount Prepaid | 8 | Optional | Double
BANK_CODE | Bank Posting Code | 8 | Optional | String
BASE_AMOUNT_PAID | Base Amount Prepaid | 8 | Optional | Double
BASE_CARR_NET | Base Carriage Net Amount | 8 | Optional | Double
BASE_CARR_TAX | Base Carriage Tax Amount | 8 | Optional | Double
BASE_NETVALUE_DISCOUNT | Base Net Value Discount Amount | 8 | Optional | Double
BASE_SETT_DISC_RATE | Base Settlement Discount % Rate | 8 | Optional | Double
BASE_TOT_NET | Base Net Amount (Goods but not carriage) | 8 | Optional | Double
BASE_TOT_TAX | Base Tax Amount (Goods but not carriage) | 8 | Optional | Double
CARR_DEPT_NUMBER | Carriage Department Number | 2 | Optional | Small Integer
CARR_NET | Carriage Net Amount | 8 | Optional | Double
CARR_NOM_CODE | Carriage Nominal Code | 8 | Optional | String
CARR_TAX | Carriage Tax Amount | 8 | Optional | Double
CARR_TAX_CODE | Carriage Tax Code | 2 | Optional | Small Integer
CONSIGNMENT_REF | Consignment Reference | 30 | Optional | String
CONTACT_NAME | Customer Contact Name | 30 | Optional | String
COUNTRY_CODE | Customer Country code | 2 | Optional | String
COURIER | Courier Number | 2 | Optional | Small Integer
CURRENCY | Currency | 1 | Optional | Byte
CURRENCY_USED | Currency Used | 1 | Optional | Byte
CUST_DISC_RATE | Customer Discount | 8 | Optional | Double
CUST_ORDER_NUMBER | Customer's Order Number | 60 | Optional | String
CUST_TEL_NUMBER | Customer's Telephone Number | 30 | Optional | String
DEF_TAX_CODE | Default Tax Code | 2 | Optional | Small Integer
DEL_ADDRESS_1 | Delivery Address Line 1 | 60 | Optional | String
DEL_ADDRESS_2 | Delivery Address Line 2 | 60 | Optional | String
DEL_ADDRESS_3 | Delivery Address Line 3 | 60 | Optional | String
DEL_ADDRESS_4 | Delivery Address Line 4 | 60 | Optional | String
DEL_ADDRESS_5 | Delivery Address Line 5 | 60 | Optional | String
DELETED_FLAG | Is Deleted | 2 | Optional | Small Integer
DELIVERY_ADDRESS_REFN | Delivery address record number | 4 | Optional | Integer
DELIVERY_NAME | Delivery Address Name | 60 | Optional | String
DESPATCH_DATE | Despatch Date | 2 | Optional | Date
DISCOUNT_COMMENT1 | Text Field For Additional Comments | 60 | Optional | String
DISCOUNT_COMMENT2 | Text Field For Additional Comments | 60 | Optional | String
DISCOUNT_TYPE | Discount Type | 1 | Optional | Byte
DUNS_NUMBER | Duns Credit Reference Number | 9 | Optional | String
EMAILED | Emailed flag - Yes/No | 1 | Optional | Byte
EORI_NUMBER | Delivery address EORI Number | 17 | Optional | String
EURO_GROSS | Euro Gross Amount | 8 | Optional | Double
EURO_RATE | Euro Rate | 8 | Optional | Double
EXTERNAL_USAGE | Number of External Usages | 4 | Optional | Integer
FIRST_ITEM | Record Number of First SOP Item | 4 | Optional | Integer
FOREIGN_GROSS | Foreign Gross Amount | 8 | Optional | Double
FOREIGN_RATE | Foreign Rate for Euro Currency | 8 | Optional | Double
GDN_NUMBER | GDN Reference | 4 | Optional | Integer
GLOBAL_DEPT_NUMBER | Global Department Number | 2 | Optional | Small Integer
GLOBAL_DETAILS | Global Details | 60 | Optional | String
GLOBAL_NOM_CODE | Global Nominal Code | 8 | Optional | String
GLOBAL_TAX_CODE | Global Tax Code | 2 | Optional | Small Integer
HAS_EXTERNAL_LINK | Has External Link | 2 | Optional | Small Integer
INCOTERMS | Incoterms | 2 | Optional | Small Integer
INTRASTAT_STATUS | Intrastat Reconciled Status | 1 | Optional | Byte
INVOICE_FOREIGN_BALANCE | Foreign Balance | 8 | Optional | Double
INVOICE_NUMBER | Invoice Number | 7 | Required | String
ITEMS_NET | Net Amount (Goods but not carriage) | 8 | Optional | Double
LAST_NETVALUE_DISCOUNT | Last Net Value Discount amount | 8 | Optional | Double
ITEMS_TAX | Tax Amount (Goods but not carriage) | 8 | Optional | Double
LAST_UPDATED | Last Updated Date | 8 | Optional | Date
NAME | Customer Account Name | 60 | Optional | String
NETVALUE_DESCRIPTION | Net Value Discount Description | 60 | Optional | String
NETVALUE_DISCOUNT | Net Value Discount Amount | 8 | Optional | Double
NETVALUE_DISCOUNT_PERCENT | Net Value Discount Percentage | 8 | Optional | Double
NOTES_1 | Notes 1 | 60 | Optional | String
NOTES_2 | Notes 2 | 60 | Optional | String
NOTES_3 | Notes 3 | 60 | Optional | String
ORDER_DATE | Order Date | 2 | Required | Date
ORDER_NUMBER | Order Number | 4 | Required | Integer
ORDER_TYPE | Order Type Code | 1 | Required | Byte
OSS_COUNTRY_OF_VAT | Country of VAT | 2 | Optional | String
OSS_REPORTING_TYPE | Report type | 2 | Optional | Small Integer
PAYMENT_OSS_COUNTRY_OF_VAT | Payment Country of VAT | 2 | Optional | String
PAYMENT_OSS_REPORTING_TYPE | Payment Report type | 2 | Optional | Small Integer
PAYMENT_REF | Payment Reference | 30 | Optional | String
PAYMENT_TAX_CODE | Payment Tax Code | 2 | Optional | Small Integer
PAYMENT_TYPE | Payment Type (SR/SA) | 1 | Optional | Byte
PRACTICE_SOLUTIONS_REFN | Sage Practice Solutions Reference | 60 | Optional | String
PRINTED_CODE | Printed Flag - Yes/No | 1 | Optional | Byte
QUOTE_EXPIRY | The expiry date of the quotation | 2 | Optional | Date
QUOTE_STATUS | The status of the quotation | 2 | Optional | Small Integer
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
RECURRING_REFERENCE | Recurring Reference | 11 | Optional | String
SEND_VIA_EMAIL | Flag To Set Sop Output To Email | 1 | Optional | Byte
SETTLEMENT_DISC_RATE | Settlement Discount % Rate | 8 | Optional | Double
SETTLEMENT_DUE_DAYS | Settlement Days | 2 | Optional | Small Integer
STATUS | Order Status Code | 1 | Optional | Byte
TAKEN_BY | Order Taken By | 60 | Optional | String
TOTAL_BYTES | 4 | Optional | Integer
UNALLOCATED_NETVALUE_DISCOUNT | Unallocated Net Value Discount amount | 8 | Optional | Double
VAT_REG_NUMBER | VAT registration number | 20 | Optional | String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Adding an item to a sales order


SplitData

Description

The SplitData object gives access to the Splits (SPLIT.DTA) table.

This object holds the 'second level' transaction information in Sage 50 - when you go into the Financials option or drill down on a Customer or Supplier activity in Sage 50, the list of transactions is built up from information available from this object. For further information on how the transaction files work go to the Understanding Audit Trail Transactions article.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
AMOUNT_PAID | Total Amount Paid | 8 | Optional | Double
BANK_FLAG | Bank Reconciled Flag | 1 | Optional | Byte
DATE | Date | 2 | Required | Date
DELETED_FLAG | Transaction Deleted Flag | 2 | Optional | Small Integer
DEPOSIT_DATE | Bank deposited date | 2 | Optional | Date
DEPOSIT_FLAG | Bank deposited flag | 1 | Optional | Byte
DEPT_NUMBER | Department Number | 2 | Optional | Small Integer
DETAILS | Details | 60 | Optional | String
DISPUTE_TYPE | Dispute Type | 2 | Optional | Small Integer
DOCTOR_LINK | Pointer to Fix by Doctor | 4 | Optional | Integer
FIRST_USAGE | Record Number of First Usage | 4 | System Generated | Integer
FOREIGN_AMOUNT_PAID | Foreign Total Paid Amount | 8 | Optional | Double
FOREIGN_NET_AMOUNT | Foreign Net Amount | 8 | Optional | Double
FOREIGN_TAX_AMOUNT | Foreign Tax Amount | 8 | Optional | Double
FUND_NUMBER | Fund Number | 4 | Optional | Integer
GASDS_CLAIM_SUBMITTED | GASDS Claim Submitted | 2 | Optional | Small Integer
GIFT_AID | Gift Aid status | 2 | Optional | Small Integer
HAS_EXTERNAL_LINK | Sets whether the transaction has an external link (0 = No, 1 = Yes) | 2 | Optional | Small Integer
HEADER_NUMBER | Record Number of Header | 4 | System Generated | Integer
INTERNAL_REF | Extra Reference | 60 | Optional | String
LAST_USAGE | Record Number of Last Usage | 4 | System Generated | Integer
NET_AMOUNT | Net Amount | 8 | Optional | Double
NEXT_NOMINAL | Record Number of Next Split for this Nominal | 4 | System Generated | Integer
NEXT_SPLIT | Record Number of Next Split | 4 | System Generated | Integer
NO_OF_USAGE | Number of Usages | 4 | System Generated | Integer
NOMINAL_CODE | Nominal Code | 8 | Required | String
OSS_COUNTRY_OF_VAT | Country of VAT | 2 | Optional | String
OSS_REPORTING_TYPE | Report type | 2 | Optional | Small Integer
PAID_FLAG | Paid Flag | 1 | Optional | Byte
POSTED_DATE | Posting Date | 2 | Required | Date
PREV_NOMINAL | Record Number of Previous Split for this Nominal | 4 | System Generated | Integer
PREV_SPLIT | Record Number of Previous Split | 4 | System Generated | Integer
PROJECT_ID | Project ID | 2 | Optional | Small Integer
RECORD_CREATE_DATE | Date and time when the record was created | 8 | System Generated | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | System Generated | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was created | 8 | System Generated | Date
STATUS | Disputed Status Flag | 2 | Optional | Small Integer
SMALL_DONATION | Small Donations | 2 | Optional | Small Integer
TAX_AMOUNT | Tax Amount | 8 | Optional | Double
TAX_CODE | Tax Code | 2 | Required | Small Integer
TRAN_NUMBER | Unique Transaction Number as seen in the Customer\Supplier activity screen in the GUI. | 4 | System Generated | Integer
TYPE | Transaction Type | 1 | Required | Byte
UNIQUE_REF | Unique Reference | 4 | System Generated | Integer
USER_NAME | User Name | 32 | Optional | String
VAT_FLAG | Vat Reconciled Flag | 1 | Optional | Byte
VAT_RECONCILED_DATE | Date of VAT Reconciliation | 2 | Required | Date
VAT_RETURN_ID | Vat Return Identification Number | 4 | Optional | Integer

Methods

Click here for a list of Methods for this object.

Properties

The SplitData object has new properties to deal with Project Costing. Click here for a list of Properties for this object.

Examples Using this Object

Posting a Batch Sales Invoice
Posting a Batch Sales Credit Note
Posting a Batch Purchase Invoice
Posting a Batch Purchase Credit Note
Posting Journal Entries
Posting a Bank Payment
Posting a Bank Receipt
Posting a Sales Receipt
Posting a Purchase Payment
Posting a Bank Transfer
 Posting a Foreign Currency Sales Invoice
Posting a Foreign Currency Sales Credit Note
Posting a Foreign Currency Sales Receipt
Posting a Foreign Currency Purchase Invoice
Posting a Foreign Currency Purchase Credit Note
Posting a Foreign Currency Purchase Payment
Posting a Foreign Currency Bank Receipt
Posting a Foreign Currency Bank Payment
Flag Disputed Transactions


PurchaseIndex

StockActiveIndex

Description

The StockActiveIndex object gives access to the Stock (STOCK_ACTIVE_INDEX.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
STOCK_CODE | Stock Code | 30 | Required | String
RECORD_NUMBER | Record Number in Data File | 4 | Required | Integer
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object


StockCategory

Description

The StockCategory object gives access to the Stock Categories (STKCAT.DTA) table.

Applies to

Sage 50 Accounts Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
NAME | Category Name | 30 | Optional | String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Example - Display Stock Categories


StockData

Description

The StockData object gives access to the Stock (STOCK.DTA) table.

Applies to

Sage 50 Accounts Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ASSEMBLY_LEVEL | Assembly Level: the number of levels of components and sub-assemblies below the product assembly | 2 | Optional | Small Integer
AVERAGE_COST_PRICE | Average Cost Price | 8 | Optional | Double
BUDGET_QTY_SOLD_BF | Brought Forward Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_FUTURE | Future Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH1 | Month 1 Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH10 | Month 10 Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH11 | Month 11 Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH12 | Month 12 Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH2 | Month 2 Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH3 | Month 3 Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH4 | Month 4 Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH5 | Month 5 Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH6 | Month 6 Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH7 | Month 7 Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH8 | Month 8 Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH9 | Month 9 Budget Quantity Sold | 8 | Optional | Double
BUDGET_SALES_BF | Brought Forward Budget Sales | 8 | Optional | Double
BUDGET_SALES_FUTURE | Future Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH1 | Month 1 Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH10 | Month 10 Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH11 | Month 11 Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH12 | Month 12 Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH2 | Month 2 Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH3 | Month 3 Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH4 | Month 4 Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH5 | Month 5 Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH6 | Month 6 Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH7 | Month 7 Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH8 | Month 8 Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH9 | Month 9 Budget Sales | 8 | Optional | Double
COMMODITY_CODE | Commodity Code | 30 | Optional | String
COMPONENT_CODE_1 | Component Stock Code 1 | 30 | Optional | String
COMPONENT_CODE_2 | Component Stock Code 2 | 30 | Optional | String
COMPONENT_CODE_3 | Component Stock Code 3 | 30 | Optional | String
COMPONENT_CODE_4 | Component Stock Code 4 | 30 | Optional | String
COMPONENT_CODE_5 | Component Stock Code 5 | 30 | Optional | String
COMPONENT_CODE_6 | Component Stock Code 6 | 30 | Optional | String
COMPONENT_CODE_7 | Component Stock Code 7 | 30 | Optional | String
COMPONENT_CODE_8 | Component Stock Code 8 | 30 | Optional | String
COMPONENT_CODE_9 | Component Stock Code 9 | 30 | Optional | String
COMPONENT_CODE_10 | Component Stock Code 10 | 30 | Optional | String
COMPONENT_Code_11 | Component Stock Code 11 | 30 | Optional | String
COMPONENT_Code_12 | Component Stock Code 12 | 30 | Optional | String
COMPONENT_Code_13 | Component Stock Code 13 | 30 | Optional | String
COMPONENT_Code_14 | Component Stock Code 14 | 30 | Optional | String
COMPONENT_Code_15 | Component Stock Code 15 | 30 | Optional | String
COMPONENT_Code_16 | Component Stock Code 16 | 30 | Optional | String
COMPONENT_Code_17 | Component Stock Code 17 | 30 | Optional | String
COMPONENT_Code_18 | Component Stock Code 18 | 30 | Optional | String
COMPONENT_Code_19 | Component Stock Code 19 | 30 | Optional | String
COMPONENT_CODE_20 | Component Stock Code 20 | 30 | Optional | String
COMPONENT_Code_21 | Component Stock Code 21 | 30 | Optional | String
COMPONENT_Code_22 | Component Stock Code 22 | 30 | Optional | String
COMPONENT_Code_23 | Component Stock Code 23 | 30 | Optional | String
COMPONENT_Code_24 | Component Stock Code 24 | 30 | Optional | String
COMPONENT_Code_25 | Component Stock Code 25 | 30 | Optional | String
COMPONENT_Code_26 | Component Stock Code 26 | 30 | Optional | String
COMPONENT_Code_27 | Component Stock Code 27 | 30 | Optional | String
COMPONENT_Code_28 | Component Stock Code 28 | 30 | Optional | String
COMPONENT_Code_29 | Component Stock Code 29 | 30 | Optional | String
COMPONENT_CODE_30 | Component Stock Code 30 | 30 | Optional | String
COMPONENT_Code_31 | Component Stock Code 31 | 30 | Optional | String
COMPONENT_Code_32 | Component Stock Code 32 | 30 | Optional | String
COMPONENT_Code_33 | Component Stock Code 33 | 30 | Optional | String
COMPONENT_Code_34 | Component Stock Code 34 | 30 | Optional | String
COMPONENT_Code_35 | Component Stock Code 35 | 30 | Optional | String
COMPONENT_Code_36 | Component Stock Code 36 | 30 | Optional | String
COMPONENT_Code_37 | Component Stock Code 37 | 30 | Optional | String
COMPONENT_Code_38 | Component Stock Code 38 | 30 | Optional | String
COMPONENT_Code_39 | Component Stock Code 39 | 30 | Optional | String
COMPONENT_CODE_40 | Component Stock Code 40 | 30 | Optional | String
COMPONENT_Code_41 | Component Stock Code 41 | 30 | Optional | String
COMPONENT_Code_42 | Component Stock Code 42 | 30 | Optional | String
COMPONENT_Code_43 | Component Stock Code 43 | 30 | Optional | String
COMPONENT_Code_44 | Component Stock Code 44 | 30 | Optional | String
COMPONENT_Code_45 | Component Stock Code 45 | 30 | Optional | String
COMPONENT_Code_46 | Component Stock Code 46 | 30 | Optional | String
COMPONENT_Code_47 | Component Stock Code 47 | 30 | Optional | String
COMPONENT_Code_48 | Component Stock Code 48 | 30 | Optional | String
COMPONENT_Code_49 | Component Stock Code 49 | 30 | Optional | String
COMPONENT_Code_50 | Component Stock Code 50 | 30 | Optional | String
COMPONENT_QTY_1 | Component 1 Quantity | 8 | Optional | Double
COMPONENT_QTY_2 | Component 2 Quantity | 8 | Optional | Double
COMPONENT_QTY_3 | Component 3 Quantity | 8 | Optional | Double
COMPONENT_QTY_4 | Component 4 Quantity | 8 | Optional | Double
COMPONENT_QTY_5 | Component 5 Quantity | 8 | Optional | Double
COMPONENT_QTY_6 | Component 6 Quantity | 8 | Optional | Double
COMPONENT_QTY_7 | Component 7 Quantity | 8 | Optional | Double
COMPONENT_QTY_8 | Component 8 Quantity | 8 | Optional | Double
COMPONENT_QTY_9 | Component 9 Quantity | 8 | Optional | Double
COMPONENT_QTY_10 | Component 10 Quantity | 8 | Optional | Double
COMPONENT_QTY_11 | Component 11 Quantity | 8 | Optional | Double
COMPONENT_QTY_12 | Component 12 Quantity | 8 | Optional | Double
COMPONENT_QTY_13 | Component 13 Quantity | 8 | Optional | Double
COMPONENT_QTY_14 | Component 14 Quantity | 8 | Optional | Double
COMPONENT_QTY_15 | Component 15 Quantity | 8 | Optional | Double
COMPONENT_QTY_16 | Component 16 Quantity | 8 | Optional | Double
COMPONENT_QTY_17 | Component 17 Quantity | 8 | Optional | Double
COMPONENT_QTY_18 | Component 18 Quantity | 8 | Optional | Double
COMPONENT_QTY_19 | Component 19 Quantity | 8 | Optional | Double
COMPONENT_QTY_20 | Component 20 Quantity | 8 | Optional | Double
COMPONENT_QTY_21 | Component 21 Quantity | 8 | Optional | Double
COMPONENT_QTY_22 | Component 22 Quantity | 8 | Optional | Double
COMPONENT_QTY_23 | Component 23 Quantity | 8 | Optional | Double
COMPONENT_QTY_24 | Component 24 Quantity | 8 | Optional | Double
COMPONENT_QTY_25 | Component 25 Quantity | 8 | Optional | Double
COMPONENT_QTY_26 | Component 26 Quantity | 8 | Optional | Double
COMPONENT_QTY_27 | Component 27 Quantity | 8 | Optional | Double
COMPONENT_QTY_28 | Component 28 Quantity | 8 | Optional | Double
COMPONENT_QTY_29 | Component 29 Quantity | 8 | Optional | Double
COMPONENT_QTY_30 | Component 30 Quantity | 8 | Optional | Double
COMPONENT_QTY_31 | Component 31 Quantity | 8 | Optional | Double
COMPONENT_QTY_32 | Component 32 Quantity | 8 | Optional | Double
COMPONENT_QTY_33 | Component 33 Quantity | 8 | Optional | Double
COMPONENT_QTY_34 | Component 34 Quantity | 8 | Optional | Double
COMPONENT_QTY_35 | Component 35 Quantity | 8 | Optional | Double
COMPONENT_QTY_36 | Component 36 Quantity | 8 | Optional | Double
COMPONENT_QTY_37 | Component 37 Quantity | 8 | Optional | Double
COMPONENT_QTY_38 | Component 38 Quantity | 8 | Optional | Double
COMPONENT_QTY_39 | Component 39 Quantity | 8 | Optional | Double
COMPONENT_QTY_40 | Component 40 Quantity | 8 | Optional | Double
COMPONENT_QTY_41 | Component 41 Quantity | 8 | Optional | Double
COMPONENT_QTY_42 | Component 42 Quantity | 8 | Optional | Double
COMPONENT_QTY_43 | Component 43 Quantity | 8 | Optional | Double
COMPONENT_QTY_44 | Component 44 Quantity | 8 | Optional | Double
COMPONENT_QTY_45 | Component 45 Quantity | 8 | Optional | Double
COMPONENT_QTY_46 | Component 46 Quantity | 8 | Optional | Double
COMPONENT_QTY_47 | Component 47 Quantity | 8 | Optional | Double
COMPONENT_QTY_48 | Component 48 Quantity | 8 | Optional | Double
COMPONENT_QTY_49 | Component 49 Quantity | 8 | Optional | Double
COMPONENT_QTY_50 | Component 50 Quantity | 8 | Optional | Double
COST_BF | Brought Forward Costs | 8 | Optional | Double
COST_FUTURE | Future Costs | 8 | Optional | Double
COST_MTH1 | Month 1 Costs | 8 | Optional | Double
COST_MTH10 | Month 10 Costs | 8 | Optional | Double
COST_MTH11 | Month 11 Costs | 8 | Optional | Double
COST_MTH12 | Month 12 Costs | 8 | Optional | Double
COST_MTH2 | Month 2 Costs | 8 | Optional | Double
COST_MTH3 | Month 3 Costs | 8 | Optional | Double
COST_MTH4 | Month 4 Costs | 8 | Optional | Double
COST_MTH5 | Month 5 Costs | 8 | Optional | Double
COST_MTH6 | Month 6 Costs | 8 | Optional | Double
COST_MTH7 | Month 7 Costs | 8 | Optional | Double
COST_MTH8 | Month 8 Costs | 8 | Optional | Double
COST_MTH9 | Month 9 Costs | 8 | Optional | Double
COUNTRY_CODE_OF_ORIGIN | Country code of origin. Irish data sets only. | 2 | Optional | String
CUSTOM_1 | Custom Field 1 | 60 | Optional | String
CUSTOM_2 | Custom Field 2 | 60 | Optional | String
CUSTOM_3 | Custom Field 3 | 60 | Optional | String
DELETED_FLAG | Reserved for Future Use | 2 | Optional | Small Integer
DEPT_NUMBER | Department Number | 2 | Optional | Small Integer
DESCRIPTION | Description | 120 | Optional | String
DISC_A_LEVEL_10_QTY | Discount Table A, Break Level 10, Quantity | 8 | Optional | Double
DISC_A_LEVEL_10_RATE | Discount Table A, Break Level 10, Rate | 8 | Optional | Double
DISC_A_LEVEL_1_QTY | Discount Table A, Break Level 1, Quantity | 8 | Optional | Double
DISC_A_LEVEL_1_RATE | Discount Table A, Break Level 1, Rate | 8 | Optional | Double
DISC_A_LEVEL_2_QTY | Discount Table A, Break Level 2, Quantity | 8 | Optional | Double
DISC_A_LEVEL_2_RATE | Discount Table A, Break Level 2, Rate | 8 | Optional | Double
DISC_A_LEVEL_3_QTY | Discount Table A, Break Level 3, Quantity | 8 | Optional | Double
DISC_A_LEVEL_3_RATE | Discount Table A, Break Level 3, Rate | 8 | Optional | Double
DISC_A_LEVEL_4_QTY | Discount Table A, Break Level 4, Quantity | 8 | Optional | Double
DISC_A_LEVEL_4_RATE | Discount Table A, Break Level 4, Rate | 8 | Optional | Double
DISC_A_LEVEL_5_QTY | Discount Table A, Break Level 5, Quantity | 8 | Optional | Double
DISC_A_LEVEL_5_RATE | Discount Table A, Break Level 5, Rate | 8 | Optional | Double
DISC_A_LEVEL_6_QTY | Discount Table A, Break Level 6, Quantity | 8 | Optional | Double
DISC_A_LEVEL_6_RATE | Discount Table A, Break Level 6, Rate | 8 | Optional | Double
DISC_A_LEVEL_7_QTY | Discount Table A, Break Level 7, Quantity | 8 | Optional | Double
DISC_A_LEVEL_7_RATE | Discount Table A, Break Level 7, Rate | 8 | Optional | Double
DISC_A_LEVEL_8_QTY | Discount Table A, Break Level 8, Quantity | 8 | Optional | Double
DISC_A_LEVEL_8_RATE | Discount Table A, Break Level 8, Rate | 8 | Optional | Double
DISC_A_LEVEL_9_QTY | Discount Table A, Break Level 9, Quantity | 8 | Optional | Double
DISC_A_LEVEL_9_RATE | Discount Table A, Break Level 9, Rate | 8 | Optional | Double
DISC_B_LEVEL_10_QTY | Discount Table B, Break Level 10, Quantity | 8 | Optional | Double
DISC_B_LEVEL_10_RATE | Discount Table B, Break Level 10, Rate | 8 | Optional | Double
DISC_B_LEVEL_1_QTY | Discount Table B, Break Level 1, Quantity | 8 | Optional | Double
DISC_B_LEVEL_1_RATE | Discount Table B, Break Level 1, Rate | 8 | Optional | Double
DISC_B_LEVEL_2_QTY | Discount Table B, Break Level 2, Quantity | 8 | Optional | Double
DISC_B_LEVEL_2_RATE | Discount Table B, Break Level 2, Rate | 8 | Optional | Double
DISC_B_LEVEL_3_QTY | Discount Table B, Break Level 3, Quantity | 8 | Optional | Double
DISC_B_LEVEL_3_RATE | Discount Table B, Break Level 3, Rate | 8 | Optional | Double
DISC_B_LEVEL_4_QTY | Discount Table B, Break Level 4, Quantity | 8 | Optional | Double
DISC_B_LEVEL_4_RATE | Discount Table B, Break Level 4, Rate | 8 | Optional | Double
DISC_B_LEVEL_5_QTY | Discount Table B, Break Level 5, Quantity | 8 | Optional | Double
DISC_B_LEVEL_5_RATE | Discount Table B, Break Level 5, Rate | 8 | Optional | Double
DISC_B_LEVEL_6_QTY | Discount Table B, Break Level 6, Quantity | 8 | Optional | Double
DISC_B_LEVEL_6_RATE | Discount Table B, Break Level 6, Rate | 8 | Optional | Double
DISC_B_LEVEL_7_QTY | Discount Table B, Break Level 7, Quantity | 8 | Optional | Double
DISC_B_LEVEL_7_RATE | Discount Table B, Break Level 7, Rate | 8 | Optional | Double
DISC_B_LEVEL_8_QTY | Discount Table B, Break Level 8, Quantity | 8 | Optional | Double
DISC_B_LEVEL_8_RATE | Discount Table B, Break Level 8, Rate | 8 | Optional | Double
DISC_B_LEVEL_9_QTY | Discount Table B, Break Level 9, Quantity | 8 | Optional | Double
DISC_B_LEVEL_9_RATE | Discount Table B, Break Level 9, Rate | 8 | Optional | Double
DISC_C_LEVEL_10_QTY | Discount Table C, Break Level 10, Quantity | 8 | Optional | Double
DISC_C_LEVEL_10_RATE | Discount Table C, Break Level 10, Rate | 8 | Optional | Double
DISC_C_LEVEL_1_QTY | Discount Table C, Break Level 1, Quantity | 8 | Optional | Double
DISC_C_LEVEL_1_RATE | Discount Table C, Break Level 1, Rate | 8 | Optional | Double
DISC_C_LEVEL_2_QTY | Discount Table C, Break Level 2, Quantity | 8 | Optional | Double
DISC_C_LEVEL_2_RATE | Discount Table C, Break Level 2, Rate | 8 | Optional | Double
DISC_C_LEVEL_3_QTY | Discount Table C, Break Level 3, Quantity | 8 | Optional | Double
DISC_C_LEVEL_3_RATE | Discount Table C, Break Level 3, Rate | 8 | Optional | Double
DISC_C_LEVEL_4_QTY | Discount Table C, Break Level 4, Quantity | 8 | Optional | Double
DISC_C_LEVEL_4_RATE | Discount Table C, Break Level 4, Rate | 8 | Optional | Double
DISC_C_LEVEL_5_QTY | Discount Table C, Break Level 5, Quantity | 8 | Optional | Double
DISC_C_LEVEL_5_RATE | Discount Table C, Break Level 5, Rate | 8 | Optional | Double
DISC_C_LEVEL_6_QTY | Discount Table C, Break Level 6, Quantity | 8 | Optional | Double
DISC_C_LEVEL_6_RATE | Discount Table C, Break Level 6, Rate | 8 | Optional | Double
DISC_C_LEVEL_7_QTY | Discount Table C, Break Level 7, Quantity | 8 | Optional | Double
DISC_C_LEVEL_7_RATE | Discount Table C, Break Level 7, Rate | 8 | Optional | Double
DISC_C_LEVEL_8_QTY | Discount Table C, Break Level 8, Quantity | 8 | Optional | Double
DISC_C_LEVEL_8_RATE | Discount Table C, Break Level 8, Rate | 8 | Optional | Double
DISC_C_LEVEL_9_QTY | Discount Table C, Break Level 9, Quantity | 8 | Optional | Double
DISC_C_LEVEL_9_RATE | Discount Table C, Break Level 9, Rate | 8 | Optional | Double
DISC_D_LEVEL_10_QTY | Discount Table D, Break Level 10, Quantity | 8 | Optional | Double
DISC_D_LEVEL_10_RATE | Discount Table D, Break Level 10, Rate | 8 | Optional | Double
DISC_D_LEVEL_1_QTY | Discount Table D, Break Level 1, Quantity | 8 | Optional | Double
DISC_D_LEVEL_1_RATE | Discount Table D, Break Level 1, Rate | 8 | Optional | Double
DISC_D_LEVEL_2_QTY | Discount Table D, Break Level 2, Quantity | 8 | Optional | Double
DISC_D_LEVEL_2_RATE | Discount Table D, Break Level 2, Rate | 8 | Optional | Double
DISC_D_LEVEL_3_QTY | Discount Table D, Break Level 3, Quantity | 8 | Optional | Double
DISC_D_LEVEL_3_RATE | Discount Table D, Break Level 3, Rate | 8 | Optional | Double
DISC_D_LEVEL_4_QTY | Discount Table D, Break Level 4, Quantity | 8 | Optional | Double
DISC_D_LEVEL_4_RATE | Discount Table D, Break Level 4, Rate | 8 | Optional | Double
DISC_D_LEVEL_5_QTY | Discount Table D, Break Level 5, Quantity | 8 | Optional | Double
DISC_D_LEVEL_5_RATE | Discount Table D, Break Level 5, Rate | 8 | Optional | Double
DISC_D_LEVEL_6_QTY | Discount Table D, Break Level 6, Quantity | 8 | Optional | Double
DISC_D_LEVEL_6_RATE | Discount Table D, Break Level 6, Rate | 8 | Optional | Double
DISC_D_LEVEL_7_QTY | Discount Table D, Break Level 7, Quantity | 8 | Optional | Double
DISC_D_LEVEL_7_RATE | Discount Table D, Break Level 7, Rate | 8 | Optional | Double
DISC_D_LEVEL_8_QTY | Discount Table D, Break Level 8, Quantity | 8 | Optional | Double
DISC_D_LEVEL_8_RATE | Discount Table D, Break Level 8, Rate | 8 | Optional | Double
DISC_D_LEVEL_9_QTY | Discount Table D, Break Level 9, Quantity | 8 | Optional | Double
DISC_D_LEVEL_9_RATE | Discount Table D, Break Level 9, Rate | 8 | Optional | Double
DISC_E_LEVEL_10_QTY | Discount Table E, Break Level 10, Quantity | 8 | Optional | Double
DISC_E_LEVEL_10_RATE | Discount Table E, Break Level 10, Rate | 8 | Optional | Double
DISC_E_LEVEL_1_QTY | Discount Table E, Break Level 1, Quantity | 8 | Optional | Double
DISC_E_LEVEL_1_RATE | Discount Table E, Break Level 1, Rate | 8 | Optional | Double
DISC_E_LEVEL_2_QTY | Discount Table E, Break Level 2, Quantity | 8 | Optional | Double
DISC_E_LEVEL_2_RATE | Discount Table E, Break Level 2, Rate | 8 | Optional | Double
DISC_E_LEVEL_3_QTY | Discount Table E, Break Level 3, Quantity | 8 | Optional | Double
DISC_E_LEVEL_3_RATE | Discount Table E, Break Level 3, Rate | 8 | Optional | Double
DISC_E_LEVEL_4_QTY | Discount Table E, Break Level 4, Quantity | 8 | Optional | Double
DISC_E_LEVEL_4_RATE | Discount Table E, Break Level 4, Rate | 8 | Optional | Double
DISC_E_LEVEL_5_QTY | Discount Table E, Break Level 5, Quantity | 8 | Optional | Double
DISC_E_LEVEL_5_RATE | Discount Table E, Break Level 5, Rate | 8 | Optional | Double
DISC_E_LEVEL_6_QTY | Discount Table E, Break Level 6, Quantity | 8 | Optional | Double
DISC_E_LEVEL_6_RATE | Discount Table E, Break Level 6, Rate | 8 | Optional | Double
DISC_E_LEVEL_7_QTY | Discount Table E, Break Level 7, Quantity | 8 | Optional | Double
DISC_E_LEVEL_7_RATE | Discount Table E, Break Level 7, Rate | 8 | Optional | Double
DISC_E_LEVEL_8_QTY | Discount Table E, Break Level 8, Quantity | 8 | Optional | Double
DISC_E_LEVEL_8_RATE | Discount Table E, Break Level 8, Rate | 8 | Optional | Double
DISC_E_LEVEL_9_QTY | Discount Table E, Break Level 9, Quantity | 8 | Optional | Double
DISC_E_LEVEL_9_RATE | Discount Table E, Break Level 9, Rate | 8 | Optional | Double
EXTERNAL_USAGE | Number of External Usages | 4 | Optional | Integer
FIRST_TRAN | Record Number of First Transaction | 4 | Optional | Integer
IGNORE_STK_LVL_FLAG | Ignore Stock Levels Flag | 1 | Optional | Byte
INACTIVE_FLAG | Inactive Flag - yes/No | 1 | Optional | Byte
INTRASTAT_COMMODITY_CODE | Intrastat Commodity Code | 8 | Optional | String
INTRASTAT_IMPORT_DUTY_CODE | Intrastat Import Duty code | 2 | Optional | String
ITEM_TYPE | Item Type | 1 | Optional | Byte
LAST_COST_DISCOUNT | Last Cost Discounted | 8 | Optional | Double
LAST_ORDER_QUANTITY | Last Order Quantity | 8 | Optional | Double
LAST_PURCHASE_DATE | Last Purchase Date | 2 | Optional | Date
LAST_PURCHASE_PRICE | Last Purchase Price | 8 | Optional | Double
LAST_SALE_DATE | Last Sales Date | 2 | Optional | Date
LAST_TRAN | Record Number of Last Transaction | 4 | Optional | Integer
LAST_UPDATED | Last Updated Date | 8 | Optional | Date
LINK_LEVEL | Link Level: the number of BOM assemblies or sub-assemblies this stock record is part of | 2 | Optional | Small Integer
LOCATION | Location | 16 | Optional | String
NO_OF_TRAN | Number of Transactions | 4 | Optional | Integer
NOMINAL_CODE | Nominal Code | 8 | Optional | String
PRIOR_YR_COST_BF | Prior Year Brought Forward Costs | 8 | Optional | Double
PRIOR_YR_COST_FUTURE | Prior Year Future Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH1 | Prior Year Month 1 Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH10 | Prior Year Month 10 Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH11 | Prior Year Month 11 Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH12 | Prior Year Month 12 Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH2 | Prior Year Month 2 Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH3 | Prior Year Month 3 Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH4 | Prior Year Month 4 Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH5 | Prior Year Month 5 Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH6 | Prior Year Month 6 Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH7 | Prior Year Month 7 Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH8 | Prior Year Month 8 Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH9 | Prior Year Month 9 Costs | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_BF | Prior Year Brought Forward Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_FUTURE | Prior Year Future Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH1 | Prior Year Month 1 Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH10 | Prior Year Month 10 Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH11 | Prior Year Month 11 Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH12 | Prior Year Month 12 Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH2 | Prior Year Month 2 Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH3 | Prior Year Month 3 Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH4 | Prior Year Month 4 Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH5 | Prior Year Month 5 Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH6 | Prior Year Month 6 Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH7 | Prior Year Month 7 Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH8 | Prior Year Month 8 Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH9 | Prior Year Month 9 Quantity Sold | 8 | Optional | Double
PRIOR_YR_SALES_BF | Prior Year Brought Forward Sales | 8 | Optional | Double
PRIOR_YR_SALES_FUTURE | Prior Year Future Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH1 | Prior Year Month 1 Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH10 | Prior Year Month 10 Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH11 | Prior Year Month 11 Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH12 | Prior Year Month 12 Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH2 | Prior Year Month 2 Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH3 | Prior Year Month 3 Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH4 | Prior Year Month 4 Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH5 | Prior Year Month 5 Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH6 | Prior Year Month 6 Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH7 | Prior Year Month 7 Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH8 | Prior Year Month 8 Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH9 | Prior Year Month 9 Sales | 8 | Optional | Double
PRODUCT_BARCODE | BarCode | 60 | Optional | String
PURCHASE_NOMINAL_CODE | Purchase Nominal Code | 8 | Optional | String
PURCHASE_REF | Supplier's Account Reference | 8 | Optional | String
QTY_ALLOCATED | Quantity Allocated | 8 | Optional | Double
QTY_IN_STOCK | Quantity In Stock | 8 | Optional | Double
QTY_LAST_ORDER | Last Order Quantity | 8 | Optional | Double
QTY_LAST_STOCK_TAKE | Last Stock Take Quantity | 8 | Optional | Double
QTY_ON_ORDER | Quantity On Order | 8 | Optional | Double
QTY_REORDER | Reorder Quantity | 8 | Optional | Double
QTY_REORDER_LEVEL | Reorder Level | 8 | Optional | Double
QTY_SOLD_BF | Brought Forward Quantity Sold | 8 | Optional | Double
QTY_SOLD_FUTURE | Future Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH1 | Month 1 Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH10 | Month 10 Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH11 | Month 11 Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH12 | Month 12 Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH2 | Month 2 Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH3 | Month 3 Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH4 | Month 4 Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH5 | Month 5 Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH6 | Month 6 Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH7 | Month 7 Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH8 | Month 8 Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH9 | Month 9 Quantity Sold | 8 | Optional | Double
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was created | 8 | Optional | Date
SALES_BF | Brought Forward Sales | 8 | Optional | Double
SALES_FUTURE | Future Sales | 8 | Optional | Double
SALES_MTH1 | Month 1 Sales | 8 | Optional | Double
SALES_MTH10 | Month 10 Sales | 8 | Optional | Double
SALES_MTH11 | Month 11 Sales | 8 | Optional | Double
SALES_MTH12 | Month 12 Sales | 8 | Optional | Double
SALES_MTH2 | Month 2 Sales | 8 | Optional | Double
SALES_MTH3 | Month 3 Sales | 8 | Optional | Double
SALES_MTH4 | Month 4 Sales | 8 | Optional | Double
SALES_MTH5 | Month 5 Sales | 8 | Optional | Double
SALES_MTH6 | Month 6 Sales | 8 | Optional | Double
SALES_MTH7 | Month 7 Sales | 8 | Optional | Double
SALES_MTH8 | Month 8 Sales | 8 | Optional | Double
SALES_MTH9 | Month 9 Sales | 8 | Optional | Double
SALES_PRICE | Sale Price | 8 | Optional | Double
STOCK_CAT | Stock Category Number | 2 | Optional | Small Integer
STOCK_CODE | Stock Code | 30 | Required | String
STOCK_TAKE_DATE | Stock Take Date | 2 | Optional | Date
SUPP_UNIT_QTY | Supplementary Unit Quantity | 8 | Optional | Double
SUPPLIER_PART_NUMBER | Supplier's Part Number | 60 | Optional | String
TAX_CODE | Tax Code | 2 | Optional | Small Integer
UNIT_OF_SALE | Unit of Sale | 8 | Optional | String
UNIT_WEIGHT | Unit of Weight | 8 | Optional | Double
WEB_DESCRIPTION | Web Description | 255 | Optional | String
WEB_IMAGE | Web Image Filename | 60 | Optional | String
WEB_LONGDESCRIPTION | Web Long Description | 1023 | Optional | String
WEB_PUBLISH | Web Publish Flag | 2 | Optional | Small Integer
WEB_SPECIAL_OFFER | Web Special Offer | 2 | Optional | Small Integer
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Example - Creating a New Product Record


StockIndex

Description

The StockIndex object gives access to the Stock index (STKINDEX.DTA) table.

Applies to

Sage 50 Accounts Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
RECORD_NUMBER | Record Number in Data File | 4 | Required | Integer
STOCK_CODE | Stock Code | 30 | Required | String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Example - Creating a New Product Record


StockPost

Description

The StockPost object enables a Stock transaction to be created with all the relevant tables being updated automatically.

Note

From 2013(v19) when posting a Goods Out(GO) Stock Transaction if you do not set the Artefact_Type value this will automatically be set to 1. The Atrfact_Type determines where the stock transaction originates, this can be either an Invoice(1) or a SOP(2). In order for the drill around functionality in the GUI to funcion for stocktransactions you must set the Artefact_Type and ISP_Reference fields correctly.

Applies to

Sage 50 Accounts Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ARTEFACT_TYPE | Determines where the stock tran originates from Invoice or SOP | 1 | Optional | Small Integer
ASSEMBLY_LEVEL | Assembly Level: the number of levels of components and sub-assemblies below the product assembly | 2 | Optional | Small Integer
AVERAGE_COST_PRICE | Average Cost Price | 8 | Optional | Double
BUDGET_QTY_SOLD_BF | Brought Forward Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_FUTURE | Future Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH1 | Month 1 Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH10 | Month 10 Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH11 | Month 11 Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH12 | Month 12 Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH2 | Month 2 Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH3 | Month 3 Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH4 | Month 4 Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH5 | Month 5 Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH6 | Month 6 Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH7 | Month 7 Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH8 | Month 8 Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH9 | Month 9 Budget Quantity Sold | 8 | Optional | Double
BUDGET_SALES_BF | Brought Forward Budget Sales | 8 | Optional | Double
BUDGET_SALES_FUTURE | Future Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH1 | Month 1 Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH10 | Month 10 Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH11 | Month 11 Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH12 | Month 12 Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH2 | Month 2 Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH3 | Month 3 Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH4 | Month 4 Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH5 | Month 5 Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH6 | Month 6 Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH7 | Month 7 Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH8 | Month 8 Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH9 | Month 9 Budget Sales | 8 | Optional | Double
COMMODITY_CODE | Commodity Code | 30 | Optional | String
COMPONENT_CODE_1 | Component Stock Code 1 | 30 | Optional | String
COMPONENT_CODE_2 | Component Stock Code 2 | 30 | Optional | String
COMPONENT_CODE_3 | Component Stock Code 3 | 30 | Optional | String
COMPONENT_CODE_4 | Component Stock Code 4 | 30 | Optional | String
COMPONENT_CODE_5 | Component Stock Code 5 | 30 | Optional | String
COMPONENT_CODE_6 | Component Stock Code 6 | 30 | Optional | String
COMPONENT_CODE_7 | Component Stock Code 7 | 30 | Optional | String
COMPONENT_CODE_8 | Component Stock Code 8 | 30 | Optional | String
COMPONENT_CODE_9 | Component Stock Code 9 | 30 | Optional | String
COMPONENT_CODE_10 | Component Stock Code 10 | 30 | Optional | String
COMPONENT_Code_11 | Component Stock Code 11 | 30 | Optional | String
COMPONENT_Code_12 | Component Stock Code 12 | 30 | Optional | String
COMPONENT_Code_13 | Component Stock Code 13 | 30 | Optional | String
COMPONENT_Code_14 | Component Stock Code 14 | 30 | Optional | String
COMPONENT_Code_15 | Component Stock Code 15 | 30 | Optional | String
COMPONENT_Code_16 | Component Stock Code 16 | 30 | Optional | String
COMPONENT_Code_17 | Component Stock Code 17 | 30 | Optional | String
COMPONENT_Code_18 | Component Stock Code 18 | 30 | Optional | String
COMPONENT_Code_19 | Component Stock Code 19 | 30 | Optional | String
COMPONENT_CODE_20 | Component Stock Code 20 | 30 | Optional | String
COMPONENT_Code_21 | Component Stock Code 21 | 30 | Optional | String
COMPONENT_Code_22 | Component Stock Code 22 | 30 | Optional | String
COMPONENT_Code_23 | Component Stock Code 23 | 30 | Optional | String
COMPONENT_Code_24 | Component Stock Code 24 | 30 | Optional | String
COMPONENT_Code_25 | Component Stock Code 25 | 30 | Optional | String
COMPONENT_Code_26 | Component Stock Code 26 | 30 | Optional | String
COMPONENT_Code_27 | Component Stock Code 27 | 30 | Optional | String
COMPONENT_Code_28 | Component Stock Code 28 | 30 | Optional | String
COMPONENT_Code_29 | Component Stock Code 29 | 30 | Optional | String
COMPONENT_CODE_30 | Component Stock Code 30 | 30 | Optional | String
COMPONENT_Code_31 | Component Stock Code 31 | 30 | Optional | String
COMPONENT_Code_32 | Component Stock Code 32 | 30 | Optional | String
COMPONENT_Code_33 | Component Stock Code 33 | 30 | Optional | String
COMPONENT_Code_34 | Component Stock Code 34 | 30 | Optional | String
COMPONENT_Code_35 | Component Stock Code 35 | 30 | Optional | String
COMPONENT_Code_36 | Component Stock Code 36 | 30 | Optional | String
COMPONENT_Code_37 | Component Stock Code 37 | 30 | Optional | String
COMPONENT_Code_38 | Component Stock Code 38 | 30 | Optional | String
COMPONENT_Code_39 | Component Stock Code 39 | 30 | Optional | String
COMPONENT_CODE_40 | Component Stock Code 40 | 30 | Optional | String
COMPONENT_Code_41 | Component Stock Code 41 | 30 | Optional | String
COMPONENT_Code_42 | Component Stock Code 42 | 30 | Optional | String
COMPONENT_Code_43 | Component Stock Code 43 | 30 | Optional | String
COMPONENT_Code_44 | Component Stock Code 44 | 30 | Optional | String
COMPONENT_Code_45 | Component Stock Code 45 | 30 | Optional | String
COMPONENT_Code_46 | Component Stock Code 46 | 30 | Optional | String
COMPONENT_Code_47 | Component Stock Code 47 | 30 | Optional | String
COMPONENT_Code_48 | Component Stock Code 48 | 30 | Optional | String
COMPONENT_Code_49 | Component Stock Code 49 | 30 | Optional | String
COMPONENT_Code_50 | Component Stock Code 50 | 30 | Optional | String
COMPONENT_QTY_1 | Component 1 Quantity | 8 | Optional | Double
COMPONENT_QTY_2 | Component 2 Quantity | 8 | Optional | Double
COMPONENT_QTY_3 | Component 3 Quantity | 8 | Optional | Double
COMPONENT_QTY_4 | Component 4 Quantity | 8 | Optional | Double
COMPONENT_QTY_5 | Component 5 Quantity | 8 | Optional | Double
COMPONENT_QTY_6 | Component 6 Quantity | 8 | Optional | Double
COMPONENT_QTY_7 | Component 7 Quantity | 8 | Optional | Double
COMPONENT_QTY_8 | Component 8 Quantity | 8 | Optional | Double
COMPONENT_QTY_9 | Component 9 Quantity | 8 | Optional | Double
COMPONENT_QTY_10 | Component 10 Quantity | 8 | Optional | Double
COMPONENT_QTY_11 | Component 11 Quantity | 8 | Optional | Double
COMPONENT_QTY_12 | Component 12 Quantity | 8 | Optional | Double
COMPONENT_QTY_13 | Component 13 Quantity | 8 | Optional | Double
COMPONENT_QTY_14 | Component 14 Quantity | 8 | Optional | Double
COMPONENT_QTY_15 | Component 15 Quantity | 8 | Optional | Double
COMPONENT_QTY_16 | Component 16 Quantity | 8 | Optional | Double
COMPONENT_QTY_17 | Component 17 Quantity | 8 | Optional | Double
COMPONENT_QTY_18 | Component 18 Quantity | 8 | Optional | Double
COMPONENT_QTY_19 | Component 19 Quantity | 8 | Optional | Double
COMPONENT_QTY_20 | Component 20 Quantity | 8 | Optional | Double
COMPONENT_QTY_21 | Component 21 Quantity | 8 | Optional | Double
COMPONENT_QTY_22 | Component 22 Quantity | 8 | Optional | Double
COMPONENT_QTY_23 | Component 23 Quantity | 8 | Optional | Double
COMPONENT_QTY_24 | Component 24 Quantity | 8 | Optional | Double
COMPONENT_QTY_25 | Component 25 Quantity | 8 | Optional | Double
COMPONENT_QTY_26 | Component 26 Quantity | 8 | Optional | Double
COMPONENT_QTY_27 | Component 27 Quantity | 8 | Optional | Double
COMPONENT_QTY_28 | Component 28 Quantity | 8 | Optional | Double
COMPONENT_QTY_29 | Component 29 Quantity | 8 | Optional | Double
COMPONENT_QTY_30 | Component 30 Quantity | 8 | Optional | Double
COMPONENT_QTY_31 | Component 31 Quantity | 8 | Optional | Double
COMPONENT_QTY_32 | Component 32 Quantity | 8 | Optional | Double
COMPONENT_QTY_33 | Component 33 Quantity | 8 | Optional | Double
COMPONENT_QTY_34 | Component 34 Quantity | 8 | Optional | Double
COMPONENT_QTY_35 | Component 35 Quantity | 8 | Optional | Double
COMPONENT_QTY_36 | Component 36 Quantity | 8 | Optional | Double
COMPONENT_QTY_37 | Component 37 Quantity | 8 | Optional | Double
COMPONENT_QTY_38 | Component 38 Quantity | 8 | Optional | Double
COMPONENT_QTY_39 | Component 39 Quantity | 8 | Optional | Double
COMPONENT_QTY_40 | Component 40 Quantity | 8 | Optional | Double
COMPONENT_QTY_41 | Component 41 Quantity | 8 | Optional | Double
COMPONENT_QTY_42 | Component 42 Quantity | 8 | Optional | Double
COMPONENT_QTY_43 | Component 43 Quantity | 8 | Optional | Double
COMPONENT_QTY_44 | Component 44 Quantity | 8 | Optional | Double
COMPONENT_QTY_45 | Component 45 Quantity | 8 | Optional | Double
COMPONENT_QTY_46 | Component 46 Quantity | 8 | Optional | Double
COMPONENT_QTY_47 | Component 47 Quantity | 8 | Optional | Double
COMPONENT_QTY_48 | Component 48 Quantity | 8 | Optional | Double
COMPONENT_QTY_49 | Component 49 Quantity | 8 | Optional | Double
COMPONENT_QTY_50 | Component 50 Quantity | 8 | Optional | Double
COST_BF | Brought Forward Costs | 8 | Optional | Double
COST_FUTURE | Future Costs | 8 | Optional | Double
COST_MTH1 | Month 1 Costs | 8 | Optional | Double
COST_MTH10 | Month 10 Costs | 8 | Optional | Double
COST_MTH11 | Month 11 Costs | 8 | Optional | Double
COST_MTH12 | Month 12 Costs | 8 | Optional | Double
COST_MTH2 | Month 2 Costs | 8 | Optional | Double
COST_MTH3 | Month 3 Costs | 8 | Optional | Double
COST_MTH4 | Month 4 Costs | 8 | Optional | Double
COST_MTH5 | Month 5 Costs | 8 | Optional | Double
COST_MTH6 | Month 6 Costs | 8 | Optional | Double
COST_MTH7 | Month 7 Costs | 8 | Optional | Double
COST_MTH8 | Month 8 Costs | 8 | Optional | Double
COST_MTH9 | Month 9 Costs | 8 | Optional | Double
COST_PRICE | Cost Price | 8 | Optional | Double
CUSTOM_1 | Custom Field 1 | 60 | Optional | String
CUSTOM_2 | Custom Field 2 | 60 | Optional | String
CUSTOM_3 | Custom Field 3 | 60 | Optional | String
DATE | Transaction Date | 2 | Required | Date
DELETED_FLAG | Reserved for Future Use | 2 | Optional | Small Integer
DEPT_NUMBER | Department Number | 2 | Optional | Small Integer
DESCRIPTION | Description | 60 | Optional | String
DETAILS | Details | 60 | Optional | String
DISC_A_LEVEL_10_QTY | Discount Table A, Break Level 10, Quantity | 8 | Optional | Double
DISC_A_LEVEL_10_RATE | Discount Table A, Break Level 10, Rate | 8 | Optional | Double
DISC_A_LEVEL_1_QTY | Discount Table A, Break Level 1, Quantity | 8 | Optional | Double
DISC_A_LEVEL_1_RATE | Discount Table A, Break Level 1, Rate | 8 | Optional | Double
DISC_A_LEVEL_2_QTY | Discount Table A, Break Level 2, Quantity | 8 | Optional | Double
DISC_A_LEVEL_2_RATE | Discount Table A, Break Level 2, Rate | 8 | Optional | Double
DISC_A_LEVEL_3_QTY | Discount Table A, Break Level 3, Quantity | 8 | Optional | Double
DISC_A_LEVEL_3_RATE | Discount Table A, Break Level 3, Rate | 8 | Optional | Double
DISC_A_LEVEL_4_QTY | Discount Table A, Break Level 4, Quantity | 8 | Optional | Double
DISC_A_LEVEL_4_RATE | Discount Table A, Break Level 4, Rate | 8 | Optional | Double
DISC_A_LEVEL_5_QTY | Discount Table A, Break Level 5, Quantity | 8 | Optional | Double
DISC_A_LEVEL_5_RATE | Discount Table A, Break Level 5, Rate | 8 | Optional | Double
DISC_A_LEVEL_6_QTY | Discount Table A, Break Level 6, Quantity | 8 | Optional | Double
DISC_A_LEVEL_6_RATE | Discount Table A, Break Level 6, Rate | 8 | Optional | Double
DISC_A_LEVEL_7_QTY | Discount Table A, Break Level 7, Quantity | 8 | Optional | Double
DISC_A_LEVEL_7_RATE | Discount Table A, Break Level 7, Rate | 8 | Optional | Double
DISC_A_LEVEL_8_QTY | Discount Table A, Break Level 8, Quantity | 8 | Optional | Double
DISC_A_LEVEL_8_RATE | Discount Table A, Break Level 8, Rate | 8 | Optional | Double
DISC_A_LEVEL_9_QTY | Discount Table A, Break Level 9, Quantity | 8 | Optional | Double
DISC_A_LEVEL_9_RATE | Discount Table A, Break Level 9, Rate | 8 | Optional | Double
DISC_B_LEVEL_10_QTY | Discount Table B, Break Level 10, Quantity | 8 | Optional | Double
DISC_B_LEVEL_10_RATE | Discount Table B, Break Level 10, Rate | 8 | Optional | Double
DISC_B_LEVEL_1_QTY | Discount Table B, Break Level 1, Quantity | 8 | Optional | Double
DISC_B_LEVEL_1_RATE | Discount Table B, Break Level 1, Rate | 8 | Optional | Double
DISC_B_LEVEL_2_QTY | Discount Table B, Break Level 2, Quantity | 8 | Optional | Double
DISC_B_LEVEL_2_RATE | Discount Table B, Break Level 2, Rate | 8 | Optional | Double
DISC_B_LEVEL_3_QTY | Discount Table B, Break Level 3, Quantity | 8 | Optional | Double
DISC_B_LEVEL_3_RATE | Discount Table B, Break Level 3, Rate | 8 | Optional | Double
DISC_B_LEVEL_4_QTY | Discount Table B, Break Level 4, Quantity | 8 | Optional | Double
DISC_B_LEVEL_4_RATE | Discount Table B, Break Level 4, Rate | 8 | Optional | Double
DISC_B_LEVEL_5_QTY | Discount Table B, Break Level 5, Quantity | 8 | Optional | Double
DISC_B_LEVEL_5_RATE | Discount Table B, Break Level 5, Rate | 8 | Optional | Double
DISC_B_LEVEL_6_QTY | Discount Table B, Break Level 6, Quantity | 8 | Optional | Double
DISC_B_LEVEL_6_RATE | Discount Table B, Break Level 6, Rate | 8 | Optional | Double
DISC_B_LEVEL_7_QTY | Discount Table B, Break Level 7, Quantity | 8 | Optional | Double
DISC_B_LEVEL_7_RATE | Discount Table B, Break Level 7, Rate | 8 | Optional | Double
DISC_B_LEVEL_8_QTY | Discount Table B, Break Level 8, Quantity | 8 | Optional | Double
DISC_B_LEVEL_8_RATE | Discount Table B, Break Level 8, Rate | 8 | Optional | Double
DISC_B_LEVEL_9_QTY | Discount Table B, Break Level 9, Quantity | 8 | Optional | Double
DISC_B_LEVEL_9_RATE | Discount Table B, Break Level 9, Rate | 8 | Optional | Double
DISC_C_LEVEL_10_QTY | Discount Table C, Break Level 10, Quantity | 8 | Optional | Double
DISC_C_LEVEL_10_RATE | Discount Table C, Break Level 10, Rate | 8 | Optional | Double
DISC_C_LEVEL_1_QTY | Discount Table C, Break Level 1, Quantity | 8 | Optional | Double
DISC_C_LEVEL_1_RATE | Discount Table C, Break Level 1, Rate | 8 | Optional | Double
DISC_C_LEVEL_2_QTY | Discount Table C, Break Level 2, Quantity | 8 | Optional | Double
DISC_C_LEVEL_2_RATE | Discount Table C, Break Level 2, Rate | 8 | Optional | Double
DISC_C_LEVEL_3_QTY | Discount Table C, Break Level 3, Quantity | 8 | Optional | Double
DISC_C_LEVEL_3_RATE | Discount Table C, Break Level 3, Rate | 8 | Optional | Double
DISC_C_LEVEL_4_QTY | Discount Table C, Break Level 4, Quantity | 8 | Optional | Double
DISC_C_LEVEL_4_RATE | Discount Table C, Break Level 4, Rate | 8 | Optional | Double
DISC_C_LEVEL_5_QTY | Discount Table C, Break Level 5, Quantity | 8 | Optional | Double
DISC_C_LEVEL_5_RATE | Discount Table C, Break Level 5, Rate | 8 | Optional | Double
DISC_C_LEVEL_6_QTY | Discount Table C, Break Level 6, Quantity | 8 | Optional | Double
DISC_C_LEVEL_6_RATE | Discount Table C, Break Level 6, Rate | 8 | Optional | Double
DISC_C_LEVEL_7_QTY | Discount Table C, Break Level 7, Quantity | 8 | Optional | Double
DISC_C_LEVEL_7_RATE | Discount Table C, Break Level 7, Rate | 8 | Optional | Double
DISC_C_LEVEL_8_QTY | Discount Table C, Break Level 8, Quantity | 8 | Optional | Double
DISC_C_LEVEL_8_RATE | Discount Table C, Break Level 8, Rate | 8 | Optional | Double
DISC_C_LEVEL_9_QTY | Discount Table C, Break Level 9, Quantity | 8 | Optional | Double
DISC_C_LEVEL_9_RATE | Discount Table C, Break Level 9, Rate | 8 | Optional | Double
DISC_D_LEVEL_10_QTY | Discount Table D, Break Level 10, Quantity | 8 | Optional | Double
DISC_D_LEVEL_10_RATE | Discount Table D, Break Level 10, Rate | 8 | Optional | Double
DISC_D_LEVEL_1_QTY | Discount Table D, Break Level 1, Quantity | 8 | Optional | Double
DISC_D_LEVEL_1_RATE | Discount Table D, Break Level 1, Rate | 8 | Optional | Double
DISC_D_LEVEL_2_QTY | Discount Table D, Break Level 2, Quantity | 8 | Optional | Double
DISC_D_LEVEL_2_RATE | Discount Table D, Break Level 2, Rate | 8 | Optional | Double
DISC_D_LEVEL_3_QTY | Discount Table D, Break Level 3, Quantity | 8 | Optional | Double
DISC_D_LEVEL_3_RATE | Discount Table D, Break Level 3, Rate | 8 | Optional | Double
DISC_D_LEVEL_4_QTY | Discount Table D, Break Level 4, Quantity | 8 | Optional | Double
DISC_D_LEVEL_4_RATE | Discount Table D, Break Level 4, Rate | 8 | Optional | Double
DISC_D_LEVEL_5_QTY | Discount Table D, Break Level 5, Quantity | 8 | Optional | Double
DISC_D_LEVEL_5_RATE | Discount Table D, Break Level 5, Rate | 8 | Optional | Double
DISC_D_LEVEL_6_QTY | Discount Table D, Break Level 6, Quantity | 8 | Optional | Double
DISC_D_LEVEL_6_RATE | Discount Table D, Break Level 6, Rate | 8 | Optional | Double
DISC_D_LEVEL_7_QTY | Discount Table D, Break Level 7, Quantity | 8 | Optional | Double
DISC_D_LEVEL_7_RATE | Discount Table D, Break Level 7, Rate | 8 | Optional | Double
DISC_D_LEVEL_8_QTY | Discount Table D, Break Level 8, Quantity | 8 | Optional | Double
DISC_D_LEVEL_8_RATE | Discount Table D, Break Level 8, Rate | 8 | Optional | Double
DISC_D_LEVEL_9_QTY | Discount Table D, Break Level 9, Quantity | 8 | Optional | Double
DISC_D_LEVEL_9_RATE | Discount Table D, Break Level 9, Rate | 8 | Optional | Double
DISC_E_LEVEL_10_QTY | Discount Table E, Break Level 10, Quantity | 8 | Optional | Double
DISC_E_LEVEL_10_RATE | Discount Table E, Break Level 10, Rate | 8 | Optional | Double
DISC_E_LEVEL_1_QTY | Discount Table E, Break Level 1, Quantity | 8 | Optional | Double
DISC_E_LEVEL_1_RATE | Discount Table E, Break Level 1, Rate | 8 | Optional | Double
DISC_E_LEVEL_2_QTY | Discount Table E, Break Level 2, Quantity | 8 | Optional | Double
DISC_E_LEVEL_2_RATE | Discount Table E, Break Level 2, Rate | 8 | Optional | Double
DISC_E_LEVEL_3_QTY | Discount Table E, Break Level 3, Quantity | 8 | Optional | Double
DISC_E_LEVEL_3_RATE | Discount Table E, Break Level 3, Rate | 8 | Optional | Double
DISC_E_LEVEL_4_QTY | Discount Table E, Break Level 4, Quantity | 8 | Optional | Double
DISC_E_LEVEL_4_RATE | Discount Table E, Break Level 4, Rate | 8 | Optional | Double
DISC_E_LEVEL_5_QTY | Discount Table E, Break Level 5, Quantity | 8 | Optional | Double
DISC_E_LEVEL_5_RATE | Discount Table E, Break Level 5, Rate | 8 | Optional | Double
DISC_E_LEVEL_6_QTY | Discount Table E, Break Level 6, Quantity | 8 | Optional | Double
DISC_E_LEVEL_6_RATE | Discount Table E, Break Level 6, Rate | 8 | Optional | Double
DISC_E_LEVEL_7_QTY | Discount Table E, Break Level 7, Quantity | 8 | Optional | Double
DISC_E_LEVEL_7_RATE | Discount Table E, Break Level 7, Rate | 8 | Optional | Double
DISC_E_LEVEL_8_QTY | Discount Table E, Break Level 8, Quantity | 8 | Optional | Double
DISC_E_LEVEL_8_RATE | Discount Table E, Break Level 8, Rate | 8 | Optional | Double
DISC_E_LEVEL_9_QTY | Discount Table E, Break Level 9, Quantity | 8 | Optional | Double
DISC_E_LEVEL_9_RATE | Discount Table E, Break Level 9, Rate | 8 | Optional | Double
EXTERNAL_USAGE | Number of External Usages | 4 | Optional | Integer
FIRST_TRAN | Record Number of First Transaction | 4 | Optional | Integer
IGNORE_STK_LVL_FLAG | Ignore Stock Levels Flag | 1 | Optional | Byte
INACTIVE_FLAG | Inactive Flag - yes/No | 8 | Optional | Byte
INTRASTAT_COMMODITY_CODE | Intrastat Commodity Code | 8 | Optional | String
ISP_REFERENCE | Inv/Sop/Pop Reference | 4 | Optional | Integer
ITEM_TYPE | Item Type | 1 | Optional | Byte
LAST_COST_DISCOUNT | Last Cost Discounted | 8 | Optional | Double
LAST_ORDER_QUANTITY | Last Order Quantity | 8 | Optional | Double
LAST_PURCHASE_DATE | Last Purchase Date | 2 | Optional | Date
LAST_PURCHASE_PRICE | Last Purchase Price | 8 | Optional | Double
LAST_SALE_DATE | Last Sales Date | 2 | Optional | Date
LAST_TRAN | Record Number of Last Transaction | 4 | Optional | Integer
LAST_UPDATED | Last Updated Date | 8 | Optional | Date
LINK_LEVEL | Link Level: the number of BOM assemblies or sub-assemblies this stock record is part of | 2 | Optional | Small Integer
LOCATION | Location | 16 | Optional | String
NEXT_ITEM | Previous Tran | 4 | Optional | Integer
NO_OF_TRAN | Number of Transactions | 4 | Optional | Integer
NOMINAL_CODE | Nominal Code | 8 | Optional | String
PREV_ITEM | Next Tran | 4 | Optional | Integer
PRIOR_YR_COST_BF | Prior Year Brought Forward Costs | 8 | Optional | Double
PRIOR_YR_COST_FUTURE | Prior Year Future Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH1 | Prior Year Month 1 Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH10 | Prior Year Month 10 Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH11 | Prior Year Month 11 Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH12 | Prior Year Month 12 Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH2 | Prior Year Month 2 Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH3 | Prior Year Month 3 Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH4 | Prior Year Month 4 Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH5 | Prior Year Month 5 Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH6 | Prior Year Month 6 Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH7 | Prior Year Month 7 Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH8 | Prior Year Month 8 Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH9 | Prior Year Month 9 Costs | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_BF | Prior Year Brought Forward Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_FUTURE | Prior Year Future Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH1 | Prior Year Month 1 Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH10 | Prior Year Month 10 Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH11 | Prior Year Month 11 Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH12 | Prior Year Month 12 Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH2 | Prior Year Month 2 Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH3 | Prior Year Month 3 Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH4 | Prior Year Month 4 Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH5 | Prior Year Month 5 Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH6 | Prior Year Month 6 Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH7 | Prior Year Month 7 Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH8 | Prior Year Month 8 Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH9 | Prior Year Month 9 Quantity Sold | 8 | Optional | Double
PRIOR_YR_SALES_BF | Prior Year Brought Forward Sales | 8 | Optional | Double
PRIOR_YR_SALES_FUTURE | Prior Year Future Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH1 | Prior Year Month 1 Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH10 | Prior Year Month 10 Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH11 | Prior Year Month 11 Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH12 | Prior Year Month 12 Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH2 | Prior Year Month 2 Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH3 | Prior Year Month 3 Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH4 | Prior Year Month 4 Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH5 | Prior Year Month 5 Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH6 | Prior Year Month 6 Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH7 | Prior Year Month 7 Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH8 | Prior Year Month 8 Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH9 | Prior Year Month 9 Sales | 8 | Optional | Double
PRODUCT_BARCODE | BarCode | 60 | Optional | String
PURCHASE_NOMINAL_CODE | Purchase Nominal Code | 8 | Optional | String
PURCHASE_REF | Supplier's Account Reference | 8 | Optional | String
QTY_ALLOCATED | Quantity Allocated | 8 | Optional | Double
QTY_IN_STOCK | Quantity In Stock | 8 | Optional | Double
QTY_LAST_ORDER | Last Order Quantity | 8 | Optional | Double
QTY_LAST_STOCK_TAKE | Last Stock Take Quantity | 8 | Optional | Double
QTY_ON_ORDER | Quantity On Order | 8 | Optional | Double
QTY_REORDER | Reorder Quantity | 8 | Optional | Double
QTY_REORDER_LEVEL | Reorder Level | 8 | Optional | Double
QTY_SOLD_BF | Brought Forward Quantity Sold | 8 | Optional | Double
QTY_SOLD_FUTURE | Future Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH1 | Month 1 Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH10 | Month 10 Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH11 | Month 11 Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH12 | Month 12 Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH2 | Month 2 Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH3 | Month 3 Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH4 | Month 4 Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH5 | Month 5 Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH6 | Month 6 Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH7 | Month 7 Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH8 | Month 8 Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH9 | Month 9 Quantity Sold | 8 | Optional | Double
QTY_USED | Quantity Used | 8 | Optional | Double
QUANTITY | Quantity | 8 | Required | Double
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
REFERENCE | Transaction Reference | 8 | Optional | String
RESERVED | Reserved | 1 | Optional | Byte
SALES_BF | Brought Forward Sales | 8 | Optional | Double
SALES_FUTURE | Future Sales | 8 | Optional | Double
SALES_MTH1 | Month 1 Sales | 8 | Optional | Double
SALES_MTH10 | Month 10 Sales | 8 | Optional | Double
SALES_MTH11 | Month 11 Sales | 8 | Optional | Double
SALES_MTH12 | Month 12 Sales | 8 | Optional | Double
SALES_MTH2 | Month 2 Sales | 8 | Optional | Double
SALES_MTH3 | Month 3 Sales | 8 | Optional | Double
SALES_MTH4 | Month 4 Sales | 8 | Optional | Double
SALES_MTH5 | Month 5 Sales | 8 | Optional | Double
SALES_MTH6 | Month 6 Sales | 8 | Optional | Double
SALES_MTH7 | Month 7 Sales | 8 | Optional | Double
SALES_MTH8 | Month 8 Sales | 8 | Optional | Double
SALES_MTH9 | Month 9 Sales | 8 | Optional | Double
SALES_PRICE | Sales Price | 8 | Optional | Double
STOCK_CAT | Stock Category Number | 2 | Optional | Small Integer
STOCK_CODE | Stock Code | 30 | Required | String
STOCK_TAKE_DATE | Stock Take Date | 2 | Optional | Date
SUPPLIER_PART_NUMBER | Supplier's Part Number | 16 | Optional | String
TAX_CODE | Tax Code (0 to 99) | 2 | Optional | Small Integer
UNIT_OF_SALE | Unit of Sale | 8 | Optional | String
UNIT_WEIGHT | Unit of Weight | 8 | Optional | Double
WEB_DESCRIPTION | Web Description | 60 | Optional | String
WEB_IMAGE | Web Image Filename | 60 | Optional | String
WEB_LONGDESCRIPTION | Web Long Description | 1023 | Optional | String
WEB_PUBLISH | Web Publish Flag | 2 | Optional | Small Integer
WEB_SPECIAL_OFFER | Web Special Offer | 2 | Optional | Small Integer
TYPE | Transaction Type | 1 | Required | Byte
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Posting an Adjustment In
Posting an Adjustment Out
Posting a Goods Out


StockRecord

Description

The StockRecord object gives access to the Stock (STOCK.DTA) table and the Stock index (STKINDEX.DTA) table. As an SDORecord object, it encapsulates both the data and index files.

Applies to

Sage 50 Accounts Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ASSEMBLY_LEVEL | Assembly Level: the number of levels of components and sub-assemblies below the product assembly | 2 | Optional | Small Integer
AVERAGE_COST_PRICE | Average Cost Price | 8 | Optional | Double
BUDGET_QTY_SOLD_BF | Brought Forward Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_FUTURE | Future Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH1 | Month 1 Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH10 | Month 10 Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH11 | Month 11 Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH12 | Month 12 Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH2 | Month 2 Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH3 | Month 3 Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH4 | Month 4 Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH5 | Month 5 Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH6 | Month 6 Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH7 | Month 7 Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH8 | Month 8 Budget Quantity Sold | 8 | Optional | Double
BUDGET_QTY_SOLD_MTH9 | Month 9 Budget Quantity Sold | 8 | Optional | Double
BUDGET_SALES_BF | Brought Forward Budget Sales | 8 | Optional | Double
BUDGET_SALES_FUTURE | Future Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH1 | Month 1 Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH10 | Month 10 Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH11 | Month 11 Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH12 | Month 12 Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH2 | Month 2 Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH3 | Month 3 Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH4 | Month 4 Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH5 | Month 5 Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH6 | Month 6 Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH7 | Month 7 Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH8 | Month 8 Budget Sales | 8 | Optional | Double
BUDGET_SALES_MTH9 | Month 9 Budget Sales | 8 | Optional | Double
COMMODITY_CODE | Commodity Code | 30 | Optional | String
COMPONENT_CODE_1 | Component Stock Code 1 | 30 | Optional | String
COMPONENT_CODE_2 | Component Stock Code 2 | 30 | Optional | String
COMPONENT_CODE_3 | Component Stock Code 3 | 30 | Optional | String
COMPONENT_CODE_4 | Component Stock Code 4 | 30 | Optional | String
COMPONENT_CODE_5 | Component Stock Code 5 | 30 | Optional | String
COMPONENT_CODE_6 | Component Stock Code 6 | 30 | Optional | String
COMPONENT_CODE_7 | Component Stock Code 7 | 30 | Optional | String
COMPONENT_CODE_8 | Component Stock Code 8 | 30 | Optional | String
COMPONENT_CODE_9 | Component Stock Code 9 | 30 | Optional | String
COMPONENT_CODE_10 | Component Stock Code 10 | 30 | Optional | String
COMPONENT_Code_11 | Component Stock Code 11 | 30 | Optional | String
COMPONENT_Code_12 | Component Stock Code 12 | 30 | Optional | String
COMPONENT_Code_13 | Component Stock Code 13 | 30 | Optional | String
COMPONENT_Code_14 | Component Stock Code 14 | 30 | Optional | String
COMPONENT_Code_15 | Component Stock Code 15 | 30 | Optional | String
COMPONENT_Code_16 | Component Stock Code 16 | 30 | Optional | String
COMPONENT_Code_17 | Component Stock Code 17 | 30 | Optional | String
COMPONENT_Code_18 | Component Stock Code 18 | 30 | Optional | String
COMPONENT_Code_19 | Component Stock Code 19 | 30 | Optional | String
COMPONENT_CODE_20 | Component Stock Code 20 | 30 | Optional | String
COMPONENT_Code_21 | Component Stock Code 21 | 30 | Optional | String
COMPONENT_Code_22 | Component Stock Code 22 | 30 | Optional | String
COMPONENT_Code_23 | Component Stock Code 23 | 30 | Optional | String
COMPONENT_Code_24 | Component Stock Code 24 | 30 | Optional | String
COMPONENT_Code_25 | Component Stock Code 25 | 30 | Optional | String
COMPONENT_Code_26 | Component Stock Code 26 | 30 | Optional | String
COMPONENT_Code_27 | Component Stock Code 27 | 30 | Optional | String
COMPONENT_Code_28 | Component Stock Code 28 | 30 | Optional | String
COMPONENT_Code_29 | Component Stock Code 29 | 30 | Optional | String
COMPONENT_CODE_30 | Component Stock Code 30 | 30 | Optional | String
COMPONENT_Code_31 | Component Stock Code 31 | 30 | Optional | String
COMPONENT_Code_32 | Component Stock Code 32 | 30 | Optional | String
COMPONENT_Code_33 | Component Stock Code 33 | 30 | Optional | String
COMPONENT_Code_34 | Component Stock Code 34 | 30 | Optional | String
COMPONENT_Code_35 | Component Stock Code 35 | 30 | Optional | String
COMPONENT_Code_36 | Component Stock Code 36 | 30 | Optional | String
COMPONENT_Code_37 | Component Stock Code 37 | 30 | Optional | String
COMPONENT_Code_38 | Component Stock Code 38 | 30 | Optional | String
COMPONENT_Code_39 | Component Stock Code 39 | 30 | Optional | String
COMPONENT_CODE_40 | Component Stock Code 40 | 30 | Optional | String
COMPONENT_Code_41 | Component Stock Code 41 | 30 | Optional | String
COMPONENT_Code_42 | Component Stock Code 42 | 30 | Optional | String
COMPONENT_Code_43 | Component Stock Code 43 | 30 | Optional | String
COMPONENT_Code_44 | Component Stock Code 44 | 30 | Optional | String
COMPONENT_Code_45 | Component Stock Code 45 | 30 | Optional | String
COMPONENT_Code_46 | Component Stock Code 46 | 30 | Optional | String
COMPONENT_Code_47 | Component Stock Code 47 | 30 | Optional | String
COMPONENT_Code_48 | Component Stock Code 48 | 30 | Optional | String
COMPONENT_Code_49 | Component Stock Code 49 | 30 | Optional | String
COMPONENT_Code_50 | Component Stock Code 50 | 30 | Optional | String
COMPONENT_QTY_1 | Component 1 Quantity | 8 | Optional | Double
COMPONENT_QTY_2 | Component 2 Quantity | 8 | Optional | Double
COMPONENT_QTY_3 | Component 3 Quantity | 8 | Optional | Double
COMPONENT_QTY_4 | Component 4 Quantity | 8 | Optional | Double
COMPONENT_QTY_5 | Component 5 Quantity | 8 | Optional | Double
COMPONENT_QTY_6 | Component 6 Quantity | 8 | Optional | Double
COMPONENT_QTY_7 | Component 7 Quantity | 8 | Optional | Double
COMPONENT_QTY_8 | Component 8 Quantity | 8 | Optional | Double
COMPONENT_QTY_9 | Component 9 Quantity | 8 | Optional | Double
COMPONENT_QTY_10 | Component 10 Quantity | 8 | Optional | Double
COMPONENT_QTY_11 | Component 11 Quantity | 8 | Optional | Double
COMPONENT_QTY_12 | Component 12 Quantity | 8 | Optional | Double
COMPONENT_QTY_13 | Component 13 Quantity | 8 | Optional | Double
COMPONENT_QTY_14 | Component 14 Quantity | 8 | Optional | Double
COMPONENT_QTY_15 | Component 15 Quantity | 8 | Optional | Double
COMPONENT_QTY_16 | Component 16 Quantity | 8 | Optional | Double
COMPONENT_QTY_17 | Component 17 Quantity | 8 | Optional | Double
COMPONENT_QTY_18 | Component 18 Quantity | 8 | Optional | Double
COMPONENT_QTY_19 | Component 19 Quantity | 8 | Optional | Double
COMPONENT_QTY_20 | Component 20 Quantity | 8 | Optional | Double
COMPONENT_QTY_21 | Component 21 Quantity | 8 | Optional | Double
COMPONENT_QTY_22 | Component 22 Quantity | 8 | Optional | Double
COMPONENT_QTY_23 | Component 23 Quantity | 8 | Optional | Double
COMPONENT_QTY_24 | Component 24 Quantity | 8 | Optional | Double
COMPONENT_QTY_25 | Component 25 Quantity | 8 | Optional | Double
COMPONENT_QTY_26 | Component 26 Quantity | 8 | Optional | Double
COMPONENT_QTY_27 | Component 27 Quantity | 8 | Optional | Double
COMPONENT_QTY_28 | Component 28 Quantity | 8 | Optional | Double
COMPONENT_QTY_29 | Component 29 Quantity | 8 | Optional | Double
COMPONENT_QTY_30 | Component 30 Quantity | 8 | Optional | Double
COMPONENT_QTY_31 | Component 31 Quantity | 8 | Optional | Double
COMPONENT_QTY_32 | Component 32 Quantity | 8 | Optional | Double
COMPONENT_QTY_33 | Component 33 Quantity | 8 | Optional | Double
COMPONENT_QTY_34 | Component 34 Quantity | 8 | Optional | Double
COMPONENT_QTY_35 | Component 35 Quantity | 8 | Optional | Double
COMPONENT_QTY_36 | Component 36 Quantity | 8 | Optional | Double
COMPONENT_QTY_37 | Component 37 Quantity | 8 | Optional | Double
COMPONENT_QTY_38 | Component 38 Quantity | 8 | Optional | Double
COMPONENT_QTY_39 | Component 39 Quantity | 8 | Optional | Double
COMPONENT_QTY_40 | Component 40 Quantity | 8 | Optional | Double
COMPONENT_QTY_41 | Component 41 Quantity | 8 | Optional | Double
COMPONENT_QTY_42 | Component 42 Quantity | 8 | Optional | Double
COMPONENT_QTY_43 | Component 43 Quantity | 8 | Optional | Double
COMPONENT_QTY_44 | Component 44 Quantity | 8 | Optional | Double
COMPONENT_QTY_45 | Component 45 Quantity | 8 | Optional | Double
COMPONENT_QTY_46 | Component 46 Quantity | 8 | Optional | Double
COMPONENT_QTY_47 | Component 47 Quantity | 8 | Optional | Double
COMPONENT_QTY_48 | Component 48 Quantity | 8 | Optional | Double
COMPONENT_QTY_49 | Component 49 Quantity | 8 | Optional | Double
COMPONENT_QTY_50 | Component 50 Quantity | 8 | Optional | Double
COST_BF | Brought Forward Costs | 8 | Optional | Double
COST_FUTURE | Future Costs | 8 | Optional | Double
COST_MTH1 | Month 1 Costs | 8 | Optional | Double
COST_MTH10 | Month 10 Costs | 8 | Optional | Double
COST_MTH11 | Month 11 Costs | 8 | Optional | Double
COST_MTH12 | Month 12 Costs | 8 | Optional | Double
COST_MTH2 | Month 2 Costs | 8 | Optional | Double
COST_MTH3 | Month 3 Costs | 8 | Optional | Double
COST_MTH4 | Month 4 Costs | 8 | Optional | Double
COST_MTH5 | Month 5 Costs | 8 | Optional | Double
COST_MTH6 | Month 6 Costs | 8 | Optional | Double
COST_MTH7 | Month 7 Costs | 8 | Optional | Double
COST_MTH8 | Month 8 Costs | 8 | Optional | Double
COST_MTH9 | Month 9 Costs | 8 | Optional | Double
COUNTRY_CODE_OF_ORIGIN | Country code of origin. Irish data sets only. | 2 | Optional | String
CUSTOM_1 | Custom Field 1 | 60 | Optional | String
CUSTOM_2 | Custom Field 2 | 60 | Optional | String
CUSTOM_3 | Custom Field 3 | 60 | Optional | String
DELETED_FLAG | Reserved for Future Use | 2 | Optional | Small Integer
DEPT_NUMBER | Department Number | 2 | Optional | Small Integer
DESCRIPTION | Description | 120 | Optional | String
DISC_A_LEVEL_10_QTY | Discount Table A, Break Level 10, Quantity | 8 | Optional | Double
DISC_A_LEVEL_10_RATE | Discount Table A, Break Level 10, Rate | 8 | Optional | Double
DISC_A_LEVEL_1_QTY | Discount Table A, Break Level 1, Quantity | 8 | Optional | Double
DISC_A_LEVEL_1_RATE | Discount Table A, Break Level 1, Rate | 8 | Optional | Double
DISC_A_LEVEL_2_QTY | Discount Table A, Break Level 2, Quantity | 8 | Optional | Double
DISC_A_LEVEL_2_RATE | Discount Table A, Break Level 2, Rate | 8 | Optional | Double
DISC_A_LEVEL_3_QTY | Discount Table A, Break Level 3, Quantity | 8 | Optional | Double
DISC_A_LEVEL_3_RATE | Discount Table A, Break Level 3, Rate | 8 | Optional | Double
DISC_A_LEVEL_4_QTY | Discount Table A, Break Level 4, Quantity | 8 | Optional | Double
DISC_A_LEVEL_4_RATE | Discount Table A, Break Level 4, Rate | 8 | Optional | Double
DISC_A_LEVEL_5_QTY | Discount Table A, Break Level 5, Quantity | 8 | Optional | Double
DISC_A_LEVEL_5_RATE | Discount Table A, Break Level 5, Rate | 8 | Optional | Double
DISC_A_LEVEL_6_QTY | Discount Table A, Break Level 6, Quantity | 8 | Optional | Double
DISC_A_LEVEL_6_RATE | Discount Table A, Break Level 6, Rate | 8 | Optional | Double
DISC_A_LEVEL_7_QTY | Discount Table A, Break Level 7, Quantity | 8 | Optional | Double
DISC_A_LEVEL_7_RATE | Discount Table A, Break Level 7, Rate | 8 | Optional | Double
DISC_A_LEVEL_8_QTY | Discount Table A, Break Level 8, Quantity | 8 | Optional | Double
DISC_A_LEVEL_8_RATE | Discount Table A, Break Level 8, Rate | 8 | Optional | Double
DISC_A_LEVEL_9_QTY | Discount Table A, Break Level 9, Quantity | 8 | Optional | Double
DISC_A_LEVEL_9_RATE | Discount Table A, Break Level 9, Rate | 8 | Optional | Double
DISC_B_LEVEL_10_QTY | Discount Table B, Break Level 10, Quantity | 8 | Optional | Double
DISC_B_LEVEL_10_RATE | Discount Table B, Break Level 10, Rate | 8 | Optional | Double
DISC_B_LEVEL_1_QTY | Discount Table B, Break Level 1, Quantity | 8 | Optional | Double
DISC_B_LEVEL_1_RATE | Discount Table B, Break Level 1, Rate | 8 | Optional | Double
DISC_B_LEVEL_2_QTY | Discount Table B, Break Level 2, Quantity | 8 | Optional | Double
DISC_B_LEVEL_2_RATE | Discount Table B, Break Level 2, Rate | 8 | Optional | Double
DISC_B_LEVEL_3_QTY | Discount Table B, Break Level 3, Quantity | 8 | Optional | Double
DISC_B_LEVEL_3_RATE | Discount Table B, Break Level 3, Rate | 8 | Optional | Double
DISC_B_LEVEL_4_QTY | Discount Table B, Break Level 4, Quantity | 8 | Optional | Double
DISC_B_LEVEL_4_RATE | Discount Table B, Break Level 4, Rate | 8 | Optional | Double
DISC_B_LEVEL_5_QTY | Discount Table B, Break Level 5, Quantity | 8 | Optional | Double
DISC_B_LEVEL_5_RATE | Discount Table B, Break Level 5, Rate | 8 | Optional | Double
DISC_B_LEVEL_6_QTY | Discount Table B, Break Level 6, Quantity | 8 | Optional | Double
DISC_B_LEVEL_6_RATE | Discount Table B, Break Level 6, Rate | 8 | Optional | Double
DISC_B_LEVEL_7_QTY | Discount Table B, Break Level 7, Quantity | 8 | Optional | Double
DISC_B_LEVEL_7_RATE | Discount Table B, Break Level 7, Rate | 8 | Optional | Double
DISC_B_LEVEL_8_QTY | Discount Table B, Break Level 8, Quantity | 8 | Optional | Double
DISC_B_LEVEL_8_RATE | Discount Table B, Break Level 8, Rate | 8 | Optional | Double
DISC_B_LEVEL_9_QTY | Discount Table B, Break Level 9, Quantity | 8 | Optional | Double
DISC_B_LEVEL_9_RATE | Discount Table B, Break Level 9, Rate | 8 | Optional | Double
DISC_C_LEVEL_10_QTY | Discount Table C, Break Level 10, Quantity | 8 | Optional | Double
DISC_C_LEVEL_10_RATE | Discount Table C, Break Level 10, Rate | 8 | Optional | Double
DISC_C_LEVEL_1_QTY | Discount Table C, Break Level 1, Quantity | 8 | Optional | Double
DISC_C_LEVEL_1_RATE | Discount Table C, Break Level 1, Rate | 8 | Optional | Double
DISC_C_LEVEL_2_QTY | Discount Table C, Break Level 2, Quantity | 8 | Optional | Double
DISC_C_LEVEL_2_RATE | Discount Table C, Break Level 2, Rate | 8 | Optional | Double
DISC_C_LEVEL_3_QTY | Discount Table C, Break Level 3, Quantity | 8 | Optional | Double
DISC_C_LEVEL_3_RATE | Discount Table C, Break Level 3, Rate | 8 | Optional | Double
DISC_C_LEVEL_4_QTY | Discount Table C, Break Level 4, Quantity | 8 | Optional | Double
DISC_C_LEVEL_4_RATE | Discount Table C, Break Level 4, Rate | 8 | Optional | Double
DISC_C_LEVEL_5_QTY | Discount Table C, Break Level 5, Quantity | 8 | Optional | Double
DISC_C_LEVEL_5_RATE | Discount Table C, Break Level 5, Rate | 8 | Optional | Double
DISC_C_LEVEL_6_QTY | Discount Table C, Break Level 6, Quantity | 8 | Optional | Double
DISC_C_LEVEL_6_RATE | Discount Table C, Break Level 6, Rate | 8 | Optional | Double
DISC_C_LEVEL_7_QTY | Discount Table C, Break Level 7, Quantity | 8 | Optional | Double
DISC_C_LEVEL_7_RATE | Discount Table C, Break Level 7, Rate | 8 | Optional | Double
DISC_C_LEVEL_8_QTY | Discount Table C, Break Level 8, Quantity | 8 | Optional | Double
DISC_C_LEVEL_8_RATE | Discount Table C, Break Level 8, Rate | 8 | Optional | Double
DISC_C_LEVEL_9_QTY | Discount Table C, Break Level 9, Quantity | 8 | Optional | Double
DISC_C_LEVEL_9_RATE | Discount Table C, Break Level 9, Rate | 8 | Optional | Double
DISC_D_LEVEL_10_QTY | Discount Table D, Break Level 10, Quantity | 8 | Optional | Double
DISC_D_LEVEL_10_RATE | Discount Table D, Break Level 10, Rate | 8 | Optional | Double
DISC_D_LEVEL_1_QTY | Discount Table D, Break Level 1, Quantity | 8 | Optional | Double
DISC_D_LEVEL_1_RATE | Discount Table D, Break Level 1, Rate | 8 | Optional | Double
DISC_D_LEVEL_2_QTY | Discount Table D, Break Level 2, Quantity | 8 | Optional | Double
DISC_D_LEVEL_2_RATE | Discount Table D, Break Level 2, Rate | 8 | Optional | Double
DISC_D_LEVEL_3_QTY | Discount Table D, Break Level 3, Quantity | 8 | Optional | Double
DISC_D_LEVEL_3_RATE | Discount Table D, Break Level 3, Rate | 8 | Optional | Double
DISC_D_LEVEL_4_QTY | Discount Table D, Break Level 4, Quantity | 8 | Optional | Double
DISC_D_LEVEL_4_RATE | Discount Table D, Break Level 4, Rate | 8 | Optional | Double
DISC_D_LEVEL_5_QTY | Discount Table D, Break Level 5, Quantity | 8 | Optional | Double
DISC_D_LEVEL_5_RATE | Discount Table D, Break Level 5, Rate | 8 | Optional | Double
DISC_D_LEVEL_6_QTY | Discount Table D, Break Level 6, Quantity | 8 | Optional | Double
DISC_D_LEVEL_6_RATE | Discount Table D, Break Level 6, Rate | 8 | Optional | Double
DISC_D_LEVEL_7_QTY | Discount Table D, Break Level 7, Quantity | 8 | Optional | Double
DISC_D_LEVEL_7_RATE | Discount Table D, Break Level 7, Rate | 8 | Optional | Double
DISC_D_LEVEL_8_QTY | Discount Table D, Break Level 8, Quantity | 8 | Optional | Double
DISC_D_LEVEL_8_RATE | Discount Table D, Break Level 8, Rate | 8 | Optional | Double
DISC_D_LEVEL_9_QTY | Discount Table D, Break Level 9, Quantity | 8 | Optional | Double
DISC_D_LEVEL_9_RATE | Discount Table D, Break Level 9, Rate | 8 | Optional | Double
DISC_E_LEVEL_10_QTY | Discount Table E, Break Level 10, Quantity | 8 | Optional | Double
DISC_E_LEVEL_10_RATE | Discount Table E, Break Level 10, Rate | 8 | Optional | Double
DISC_E_LEVEL_1_QTY | Discount Table E, Break Level 1, Quantity | 8 | Optional | Double
DISC_E_LEVEL_1_RATE | Discount Table E, Break Level 1, Rate | 8 | Optional | Double
DISC_E_LEVEL_2_QTY | Discount Table E, Break Level 2, Quantity | 8 | Optional | Double
DISC_E_LEVEL_2_RATE | Discount Table E, Break Level 2, Rate | 8 | Optional | Double
DISC_E_LEVEL_3_QTY | Discount Table E, Break Level 3, Quantity | 8 | Optional | Double
DISC_E_LEVEL_3_RATE | Discount Table E, Break Level 3, Rate | 8 | Optional | Double
DISC_E_LEVEL_4_QTY | Discount Table E, Break Level 4, Quantity | 8 | Optional | Double
DISC_E_LEVEL_4_RATE | Discount Table E, Break Level 4, Rate | 8 | Optional | Double
DISC_E_LEVEL_5_QTY | Discount Table E, Break Level 5, Quantity | 8 | Optional | Double
DISC_E_LEVEL_5_RATE | Discount Table E, Break Level 5, Rate | 8 | Optional | Double
DISC_E_LEVEL_6_QTY | Discount Table E, Break Level 6, Quantity | 8 | Optional | Double
DISC_E_LEVEL_6_RATE | Discount Table E, Break Level 6, Rate | 8 | Optional | Double
DISC_E_LEVEL_7_QTY | Discount Table E, Break Level 7, Quantity | 8 | Optional | Double
DISC_E_LEVEL_7_RATE | Discount Table E, Break Level 7, Rate | 8 | Optional | Double
DISC_E_LEVEL_8_QTY | Discount Table E, Break Level 8, Quantity | 8 | Optional | Double
DISC_E_LEVEL_8_RATE | Discount Table E, Break Level 8, Rate | 8 | Optional | Double
DISC_E_LEVEL_9_QTY | Discount Table E, Break Level 9, Quantity | 8 | Optional | Double
DISC_E_LEVEL_9_RATE | Discount Table E, Break Level 9, Rate | 8 | Optional | Double
EXTERNAL_USAGE | Number of External Usages | 4 | Optional | Integer
FIRST_TRAN | Record Number of First Transaction | 4 | Optional | Integer
IGNORE_STK_LVL_FLAG | Ignore Stock Levels Flag | 1 | Optional | Byte
INACTIVE_FLAG | Inactive Flag - yes/No | 1 | Optional | Byte
INTRASTAT_COMMODITY_CODE | Intrastat Commodity Code | 8 | Optional | String
INTRASTAT_IMPORT_DUTY_CODE | Intrastat Import Duty code | 2 | Optional | String
ITEM_TYPE | Item Type | 1 | Optional | Byte
LAST_COST_DISCOUNT | Last Cost Discounted | 8 | Optional | Double
LAST_ORDER_QUANTITY | Last Order Quantity | 8 | Optional | Double
LAST_PURCHASE_DATE | Last Purchase Date | 2 | Optional | Date
LAST_PURCHASE_PRICE | Last Purchase Price | 8 | Optional | Double
LAST_SALE_DATE | Last Sales Date | 2 | Optional | Date
LAST_TRAN | Record Number of Last Transaction | 4 | Optional | Integer
LAST_UPDATED | Last Updated Date | 8 | Optional | Date
LINK_LEVEL | Link Level: the number of BOM assemblies or sub-assemblies this stock record is part of | 2 | Optional | Small Integer
LOCATION | Location | 16 | Optional | String
NO_OF_TRAN | Number of Transactions | 4 | Optional | Integer
NOMINAL_CODE | Nominal Code | 8 | Optional | String
PRIOR_YR_COST_BF | Prior Year Brought Forward Costs | 8 | Optional | Double
PRIOR_YR_COST_FUTURE | Prior Year Future Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH1 | Prior Year Month 1 Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH10 | Prior Year Month 10 Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH11 | Prior Year Month 11 Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH12 | Prior Year Month 12 Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH2 | Prior Year Month 2 Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH3 | Prior Year Month 3 Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH4 | Prior Year Month 4 Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH5 | Prior Year Month 5 Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH6 | Prior Year Month 6 Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH7 | Prior Year Month 7 Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH8 | Prior Year Month 8 Costs | 8 | Optional | Double
PRIOR_YR_COST_MTH9 | Prior Year Month 9 Costs | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_BF | Prior Year Brought Forward Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_FUTURE | Prior Year Future Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH1 | Prior Year Month 1 Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH10 | Prior Year Month 10 Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH11 | Prior Year Month 11 Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH12 | Prior Year Month 12 Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH2 | Prior Year Month 2 Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH3 | Prior Year Month 3 Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH4 | Prior Year Month 4 Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH5 | Prior Year Month 5 Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH6 | Prior Year Month 6 Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH7 | Prior Year Month 7 Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH8 | Prior Year Month 8 Quantity Sold | 8 | Optional | Double
PRIOR_YR_QTY_SOLD_MTH9 | Prior Year Month 9 Quantity Sold | 8 | Optional | Double
PRIOR_YR_SALES_BF | Prior Year Brought Forward Sales | 8 | Optional | Double
PRIOR_YR_SALES_FUTURE | Prior Year Future Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH1 | Prior Year Month 1 Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH10 | Prior Year Month 10 Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH11 | Prior Year Month 11 Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH12 | Prior Year Month 12 Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH2 | Prior Year Month 2 Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH3 | Prior Year Month 3 Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH4 | Prior Year Month 4 Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH5 | Prior Year Month 5 Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH6 | Prior Year Month 6 Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH7 | Prior Year Month 7 Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH8 | Prior Year Month 8 Sales | 8 | Optional | Double
PRIOR_YR_SALES_MTH9 | Prior Year Month 9 Sales | 8 | Optional | Double
PRODUCT_BARCODE | BarCode | 60 | Optional | String
PURCHASE_NOMINAL_CODE | Purchase Nominal Code | 8 | Optional | String
PURCHASE_REF | Supplier's Account Reference | 8 | Optional | String
QTY_ALLOCATED | Quantity Allocated | 8 | Optional | Double
QTY_IN_STOCK | Quantity In Stock | 8 | Optional | Double
QTY_LAST_ORDER | Last Order Quantity | 8 | Optional | Double
QTY_LAST_STOCK_TAKE | Last Stock Take Quantity | 8 | Optional | Double
QTY_ON_ORDER | Quantity On Order | 8 | Optional | Double
QTY_REORDER | Reorder Quantity | 8 | Optional | Double
QTY_REORDER_LEVEL | Reorder Level | 8 | Optional | Double
QTY_SOLD_BF | Brought Forward Quantity Sold | 8 | Optional | Double
QTY_SOLD_FUTURE | Future Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH1 | Month 1 Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH10 | Month 10 Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH11 | Month 11 Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH12 | Month 12 Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH2 | Month 2 Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH3 | Month 3 Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH4 | Month 4 Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH5 | Month 5 Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH6 | Month 6 Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH7 | Month 7 Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH8 | Month 8 Quantity Sold | 8 | Optional | Double
QTY_SOLD_MTH9 | Month 9 Quantity Sold | 8 | Optional | Double
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
SALES_BF | Brought Forward Sales | 8 | Optional | Double
SALES_FUTURE | Future Sales | 8 | Optional | Double
SALES_MTH1 | Month 1 Sales | 8 | Optional | Double
SALES_MTH10 | Month 10 Sales | 8 | Optional | Double
SALES_MTH11 | Month 11 Sales | 8 | Optional | Double
SALES_MTH12 | Month 12 Sales | 8 | Optional | Double
SALES_MTH2 | Month 2 Sales | 8 | Optional | Double
SALES_MTH3 | Month 3 Sales | 8 | Optional | Double
SALES_MTH4 | Month 4 Sales | 8 | Optional | Double
SALES_MTH5 | Month 5 Sales | 8 | Optional | Double
SALES_MTH6 | Month 6 Sales | 8 | Optional | Double
SALES_MTH7 | Month 7 Sales | 8 | Optional | Double
SALES_MTH8 | Month 8 Sales | 8 | Optional | Double
SALES_MTH9 | Month 9 Sales | 8 | Optional | Double
SALES_PRICE | Sale Price | 8 | Optional | Double
STOCK_CAT | Stock Category Number | 2 | Optional | Small Integer
STOCK_CODE | Stock Code | 30 | Required | String
STOCK_TAKE_DATE | Stock Take Date | 2 | Optional | Date
SUPP_UNIT_QTY | Supplementary Unit Quantity | 8 | Optional | Double
SUPPLIER_PART_NUMBER | Supplier's Part Number | 60 | Optional | String
TAX_CODE | Tax Code (0 to 99) | 2 | Optional | Small Integer
UNIT_OF_SALE | Unit of Sale | 8 | Optional | String
UNIT_WEIGHT | Unit of Weight | 8 | Optional | Double
WEB_DESCRIPTION | Web Description | 255 | Optional | String
WEB_IMAGE | Web Image Filename | 60 | Optional | String
WEB_LONGDESCRIPTION | Web Long Description | 1023 | Optional | String
WEB_PUBLISH | Web Publish Flag | 2 | Optional | Small Integer
WEB_SPECIAL_OFFER | Web Special Offer | 2 | Optional | Small Integer
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Example - Creating a New Product Record


StockTran

Description

The StockTran object enables you to access the stock transactions (STKTRANS.DTA) table.

Applies to

Sage 50 Accounts Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ARTEFACT_TYPE | Determines where the stock tran originates from Invoice or SOP | 1 | Optional | Byte
COST_PRICE | Cost Price | 8 | Optional | Double
DATE | Transaction Date | 2 | Required | Date
DETAILS | Details | 60 | Optional | String
DISCOUNT_COST_PRICE | Discount Cost Price | 8 | Optional | Double
GDN_NUMBER | GDN Reference | 4 | Optional | Integer
GRN_NUMBER | GRN Reference | 4 | Optional | Integer
ISP_REFERENCE | Inv/Sop/Pop Reference | 4 | Optional | Integer
NEXT_ITEM | Previous Tran | 4 | Optional | Integer
PREV_ITEM | Next Tran | 4 | Optional | Integer
QTY_USED | Quantity Used | 8 | Optional | Double
QUANTITY | Quantity | 8 | Required | Double
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
REFERENCE | Transaction Reference | 30 | Optional | String
RESERVED | Reserved | 1 | Optional | Byte
SALES_PRICE | Sales Price | 8 | Optional | Double
SDO_DESCRIPTION | SDO Description | 60 | Optional | String
STOCK_CODE | Stock Code | 30 | Required | String
TYPE | Transaction Type | 1 | Required | Byte
Methods

Click here for a list of Methods for this object.

Properties

The StockTran object has new properties to deal with Project Costing. Click here for a list of Properties for this object.

Examples Using this Object

Accessing Product Transactions
Posting an Adjustment In
Posting an Adjustment Out
Posting a Damages In
Posting a Damages Out
Posting a Goods Out
Posting a Write Off
Editing a Stock Transaction


ToDoData

Description

The ToDoData object gives access to the To Do (TODO.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
CODE | Code | 30 | Optional | String
COMPLETED | Completed | 2 | Optional | Small Integer
DATE | Date | 2 | Optional | Date
DELEGATED_TO | Delegated To | 32 | Optional | String
DETAILS | Details | 60 | Optional | String
LEDGER | Ledger | 2 | Optional | Small Integer
OFFSET | Offset of Memo | 4 | Optional | Integer
PROJECT | Project | 60 | Optional | String
RECORD_CREATE_DATE | Date and time when record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when record was modified | 8 | Optional | Date
TIME | Time | 4 | Optional | Integer
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Example - View incomplete TODORECORDS


ToDoIndex

Description

The ToDoIndex object gives access to the To Do index (TODOIDX.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
KEY | Delegated To + Date | 40 | Required | String
RECORD_NUMBER | Record Number in Data File | 4 | Required | Integer
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Example - View incomplete TODORECORDS


ToDoRecord

Description

The ToDoRecord object gives access to the To Do (TODO.DTA) table and the To Do index (TODOIDX.DTA) table. As an SDORecord object, it encapsulates both the data and index files.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
CODE | Code | 30 | Optional | String
COMPLETED | Completed | 2 | Optional | Small Integer
DATE | Date | 2 | Optional | Date
DELEGATED_TO | Delegated To | 32 | Optional | String
DETAILS | Details | 60 | Optional | String
LEDGER | Ledger | 2 | Optional | Small Integer
OFFSET | Offset of Memo | 4 | Optional | Integer
PROJECT | Project | 60 | Optional | String
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
TIME | Time | 4 | Optional | Integer
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Example - View incomplete TODORECORDS


TransactionPost

Description

The TransactionPost object enables Audit Trail transactions to be posted with all the relevant tables being updated automatically. The TransactionPost.Update method may fail due to one of the reasons stated below:

  • The Account_Ref does not exist.
  • The Transaction Type does not match the account it is being posted to. e.g. Posting an SI Transaction to a Supplier Account
  • The Nominal code specified does not exists. Use the find method to ensure both the ACOUNT_REF and NOMINAL_CODE exist.
  • The Nominal code specified is of incorrect type. e.g. You cannot post a transaction of type SI to a control or bank account.
  • The currency specifyied does not match that of the Account_REF.
  • The Values set are negative. Ensure all values are unsigned.
  • The period the transaction is dated for is in a period which is locked.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ACCOUNT_REF | Sales/Purchase/Bank Account Reference | 8 | Required | String
AMOUNT_PAID | Total Amount Paid | 8 | Optional | Double
BANK_CODE Bank Account Reference 8 Required for SA/SP/SR, PA/PP/PR
Not set for other transaction types 		String
BANK_FLAG | Bank Reconciled Flag | 1 | Optional | Byte
BANK_RECONCILIATION_ID | Bank reconciliation ID that this transaciton is part of | 4 | Optional | Integer
CURRENCY | Currency for Transaction | 1 | Optional | Byte
CURRENCY_USED | Currency Used | 1 | Optional | Byte
DATE | Transaction Date | 2 | Required | Date
DATE_DUE | Date Invoice is Due for Payment | 2 | Optional | Date
DATE_FORECAST | Forecast Date | 2 | Optional | Date
DATE_LAST_CHARGE | Date Interest Last Charged | 2 | Optional | Date
DELETED_FLAG | Transaction Deleted Flag | 2 | Optional | Small Integer
DEPOSIT_DATE | Bank Deposited Date | 2 | Optional | Date
DEPOSIT_FLAG | Bank Deposited Flag | 1 | Optional | Byte
DETAILS | Details | 60 | Optional | String
ELEC_TRANS | Electronic Transaction Flag | 2 | Optional | Small Integer
EURO_GROSS | Euro Gross Amount | 8 | Required | Double
EURO_RATE | Euro Rate | 8 | Required | Double
FINANCE_CHARGE | Finance Charge Flag | 1 | Optional | Byte
FIRST_SPLIT | Item Number | 4 | System Generated | Integer
FORECAST_INCLUDE | Included in Forecast | 2 | Optional | Date
FOREIGN_AMOUNT_PAID | Foreign Total Amount Paid | 8 | Optional | Double
FOREIGN_GROSS | Foreign Gross Amount | 8 | Required | Double
FOREIGN_NET_AMOUNT | Foreign Net Amount | 8 | Optional | Double
FOREIGN_RATE | Foreign Rate For Euro Currency | 8 | Required | Double
FOREIGN_TAX_AMOUNT | Foreign Tax Amount | 8 | Optional | Double
INTEREST_RATE | Interest Rate to Charge | 8 | Required | Double
INV_REF | Invoice Reference Number | 30 | Optional | String
ISP_REFERENCE Inv\Sop\Pop Reference 4

System Generated

Integer
JOB_REFERENCE | Job Costing Reference | 60 | Optional | String
LAST_SPLIT | Item Number | 4 | System Generated | Integer
NET_AMOUNT | Net Amount | 8 | Required | Double
NEXT_ACCOUNT | Record Number for Next Account | 4 | System Generated | Integer
NEXT_BANK | Record Number for Next Bank | 4 | System Generated | Integer
NO_DISPUTED | Number of Disputed Splits | 2 | Optional | Small Integer
NO_OF_SPLIT | Number of Splits | 4 | System Generated | Integer
OPENING_BALANCE_TRANS | Is Transaction an Opening Balance | 2 | Optional | Small Integer
OVERRIDDEN_CLOSED_LEDGER_DATE | The closed ledger date that was overridden at the time of posting | 2 | System Generated | Date
PAID_FLAG | Transaction Paid Flag | 1 | Optional | Byte
POSTED_DATE | Posting Date | 2 | Optional | Date
POSTING_LOCATION | Location Transaction Posted From | 2 | Optional | Small Integer
PRACTICE_SOLUTIONS_REFN | Sage Practice Solutions Reference | 60 | Optional | String
PREV_ACCOUNT | Record Number for Previous Account | 4 | System Generated | Integer
PREV_BANK | Record Number for Previous Bank | 4 | System Generated | Integer
PRINTED_FLAG | Printed Flag | 1 | Optional | Byte
PROTX_REFN | PROTX Reference | 63 | Optional | String
RECON_DATE | Date Transaction was Reconciled | 2 | Optional | Date
RECORD_CREATE_DATE | Date and time when the record was created | 8 | Optional | Date
RECORD_DELETED | Flag denoting if the record has been deleted or not. | 2 | Optional | Small Integer
RECORD_MODIFY_DATE | Date and time when the record was modified | 8 | Optional | Date
REVALUATION_TRANS | Is Transaction a Revaluation Transaction | 2 | Optional | Small Integer
SETT_DISCOUNT_RATE | Settlement Discount Rate | 8 | Optional | Double
TAX_AMOUNT | Tax Amount | 8 | Optional | Double
TYPE | Transaction Type | 1 | Required | Byte
UNIQUE_REF | Header Number | 4 | System Generated | Integer
USER_NAME | User Name | 32 | Optional | String
VAT_FLAG | Vat Flag | 1 | Optional | Byte

Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Posting a Batch Sales Invoice
Posting a Batch Sales Credit Note
Posting a Sales Payment
Posting a Purchase Receipt
Posting a Batch Purchase Invoice
Posting a Batch Purchase Credit Note
Posting Journal Entries
Posting a Bank Payment
Posting a Bank Receipt
Posting a Sales Receipt
Posting a Purchase Payment
Posting a Bank Transfer
 Posting a Foreign Currency Sales Invoice
Posting a Foreign Currency Sales Credit Note
Posting a Foreign Currency Sales Receipt
Posting a Foreign Currency Purchase Invoice
Posting a Foreign Currency Purchase Credit Note
Posting a Foreign Currency Purchase Payment
Posting a Foreign Currency Bank Receipt
Posting a Foreign Currency Bank Payment
Finding a SplitRecord through HeaderData Unique_Ref field


UsageData

Description

The UsageData object gives access to the usages (USAGE.DTA) table.

This object holds the 'third level' transaction information in Sage 50 Accounts - when you view a Customer or Supplier activity in Sage 50 Accounts, and drill all the way down, the list of transactions is built up from information available from this object. For further information on how the transaction files work go to the Understanding Audit Trail Transactions article.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
AMOUNT | Amount | 8 | Required | Double
DATE | Date | 2 | Required | Date
DELETED_FLAG | Transaction Deleted Flag | 2 | Optional | Small Integer
DETAILS | Details | 60 | Optional | String
DOCTOR_LINK | Pointer to Fix By Doctor | 4 | System Generated | Integer
FOREIGN_AMOUNT_PAID | Foreign Amount | 8 | Required | Double
LINK_USAGE | Record Number of Link Usage | 4 | System Generated | Integer
NEXT_USAGE | Record Number of Next Usage | 4 | System Generated | Integer
PREV_USAGE | Record Number of Previous Usage | 4 | System Generated | Integer
RECORD_CREATE_DATE | Date and time the record was created | 8 | System Generated | Date
RECORD_DELETED | Flag denoting if the record has been deleted | 2 | System Generated | Small Integer
RECORD_MODIFY_DATE | Date and time the record was modified | 8 | System Generated | Date
REFERENCE | Payment Reference | 30 | Optional | String
SPLIT_CROSSREF | Cross Reference Split Record Number | 4 | System Generated | Integer
SPLIT_NUMBER | Split Record Number | 4 | System Generated | Integer
TYPE | Transaction Type | 1 | Required | Byte
UNIQUE_REF | Unique Reference | 4 | System Generated | Integer
USER_NAME | User Name | 32 | Optional | String

Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object

Click here Understanding Transactions


AssetRecord

VerbResultData

Description

The VerbResultData object gives access to the Verb Result(VERBRESULT.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
COMMENT | Any comments about the result | 60 | Optional | String
ORIGINATOR | Originator's reference | 32 | Required | String
REASON | Verb failure reason | 4 | Optional | Integer
RESULT | Result of the verb | 2 | Optional | Small Integer
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object


PurchaseIndex

VerbResultIndex

Description

The VerbResultIndex object gives access to the Stock (VERBRESULT_INDEX.DTA) table.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
ORIGINATOR | Originator's reference | 32 | Required | String
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object


AssetRecord

VerbResultRecord

Description

The VerbResultRecord object gives access to the Verb Result(VERBRESULT.DTA) table and the Verb Result index (VERBRESULT_INDEX.DTA) table. As an SDORecord object, it encapsulates both the data and index files.

Applies to

Sage 50 Accounts Essentials, Standard and Professional.

Fields Collection

Name | Description | Length | Input | Data Type
COMMENT | Any comments about the result | 60 | Optional | String
ORIGINATOR | Originator's reference | 32 | Required | String
REASON | Verb failure reason | 4 | Optional | Integer
RESULT | Result of the verb | 2 | Optional | Small Integer
Methods

Click here for a list of Methods for this object.

Properties

Click here for a list of Properties for this object.

Examples Using this Object


SDOFile Object

SDOFile Objects

Description

The SDOFile objects represents the lowest level of access to the Sage 50 Accounts data files. These objects allow direct read/write access to the data files and, typically, should only be used where an equivalent SDORecord or SDORecordLinked object does not exist.

Note: If you use the SDOFile objects, you should be aware that the record collections they return will include deleted records. For example, if you delete a Customer account in Sage 50 Accounts, it will still be returned by the SalesData object whereas the SalesRecord object will ignore the deleted records. In order to get the SalesData object to ignore deleted records it is necessary to run the Compress option in File Maintenance within Sage 50 Accounts as this is the only way to remove deleted records from the data files.

Objects

The following table lists all the SDOFile objects:

Object | Description
AccessData | Access Rights Data - ACCESS.DTA
AccountStatusData | Account Status Data - ACCSTAT.DTA
AccrualData | Accruals Data - ACCRUAL.DTA
AssetCategory | Fixed Assets Category Data - ASTCAT.DTA
AssetData | Fixed Assets Data - ASSETS.DTA
BankData | Bank Data - BANK.DTA
BankRemittanceData | Remittance Line Data - BNKREMDA.DTA
BankWWWData | Bank WWW Data - BANKWWW.DTA
BillData | Bills Data - BILLS.DTA
Category | Category Data - CATEGOTY.DTA
ChartData | Chart of Accounts Data - 1.COA
CompanyDeliveryData | Company Delivery Address Data - COMDA.DTA
ContactData | ContactData - CONTACT.DTA
ControlData | Control Data - ACCOUNT.DTA
CountryCodeData | Country Codes - COUNTRY.DTA
CourierWWWData | Courier Resources Data - COURWWW.DTA
CreditChargeData | Credit Charge Data - FINRATES.DTA
CreditWWWData | Credit Resources Data - CREDWWW.DTA
CurrencyData | Currency Data - CURRENCY.DTA
DepartmentData | Department Data - DEPARTM.DTA
InvoiceData | Invoice Headers Data - INVOICE.DTA
MiscWWWData | Miscellaneous Resources Data - MISCWWW.DTA
NominalData | Nominal Ledger Data - NOMINAL.DTA
POPData | Purchase Orders Header Data - PUORDER.DTA
PrepayData | Prepayments Data - PREPAY.DTA
PriceData | Price Data - PRICE.DTA
PriceListData | Price List Data - PRLST.DTA
PurchaseDeliveryData | Purchase Delivery Address Data - PURDA.DTA
PurchaseData | Suppliers Data - PURCHASE.DTA
QueueData | Current Users - QUEUE.DTA
RecurringData | Recurring Entries Data - RECUR.DTA
RemittanceData | Cheque Remittance Line Data - REMIT.DTA
SalesDeliveryData | Sales Delivery Data - SALDA.DTA
SalesData | Customers Data - SALES.DTA
SetupData | Setup Data - SETUP.DTA
SOPData | Sales Orders Header Data - SAORDER.DTA
StockCategory | Stock Category Data - STKCAT.DTA
StockData | Stock Data - STOCK.DTA
ToDoData | Task Manager Data - TODO.DTA

Methods

The SDOFile objects have the following methods:

Method | Description
Close | Closes a previously opened data file or index.
FindFirst | Finds the first instance of a specified value in a specified field. Allows a sequential search to be carried out on non-indexed fields.
FindNext | Used after a FindFirst, finds the next match for the search criteria.
IsDateUserValidForLockDate | Only available on Setupdata. Identifies whether a transaction date and user are affected by lock date.
IsDateValidForLockDate | Only available on Setupdata. Identifies whether a transaction date is affected by lock date.
MoveFirst | Moves to the first record in the collection.
MoveLast | Moves to the last record in the collection.
MoveNext | Moves to the next record in the collection.
MovePrev | Moves to the previous record in the collection.
Lock | Locks a record specified by the record number parameter in a data file or index.
Open | Opens a data file or index in the mode specified by the open mode parameter.
Read | Reads a record specified by the record number parameter.
RecordNumber | Returns the record number of the currently selected record.
Unlock | Unlocks a previously locked record specified by the record number parameter.
Write | Writes a record to the data file specified by the record number parameter.

Properties

The SDOFile objects have the following properties:

Property | Description
Count | Returns the number of records in the current collection.
Fields | Returns a list of Fields.
FileType | Returns the type of the file. i.e. SDOFile


Close Method

Description

The Close method is used to close a file that has previously been opened using the Open method.

Syntax

The Close method has the following syntax:

object.Close

with the following parts:

Part | Description
Object | Applies to one of the following types: SDOFile, SDOIndexFile, SDOLinkedFile and SDOLinkedSubFile.

Return Value(s)

The method returns no values.

Remarks

Prior to calling Close, you must previously have called Open.

Examples

This example uses the Close method in conjunction with Open to access SetupData.

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oSetupData As SageDataObject300.SetupData

  ' Declare Variables
  Dim szDataPath As String

  ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then

    ' Connect to Data Files
    If oWS.Connect szDataPath, "", "", "Example" Then

      ' Create an Instance of the SetupData Object
      Set oSetupData = oWS.CreateObject("SetupData")

      ' Open the File for Read Only Access
      oSetupData.Open sdoRead

      ' Read Record 1
      oSetupData.Read 1

      ' Display the Company Name
      MsgBox oSetupData.Fields.Item("NAME").Value

      ' Close the File
      oSetupData.Close

      ' Disconnect
      oWS.Disconnect

    End If

  End If

  ' Destroy Objects
  Set oSetupData = Nothing
  Set oWS = Nothing
   Set oSDO = Nothing

  Exit Sub

 ' Error Handling Code
Error_Handler:

  MsgBox "The SDO generated the following error: " & oSDO.LastError.Text

Related Topics

Properties and Methods | Description
Open | Allows a file to be opened in a specified mode.


FindFirst Method

Description

The FindFirst method is used to find a record using a non-indexed field as the basis for the search.

Syntax

The FindFirst method has the following syntax:

object.FindFirst

with the following parts:

Part | Description
Object | Applies to one of the following types: SDOFile, SDOLinkedFile and SDOLinkedSubFile.

Return Value(s)

The method returns the following values:

Value | Description
True | A match was found for the search criteria.
False | No match was found for the search criteria.

Remarks

As it does not use an index, FindFirst is a sequential search. As a result of this, the FindFirst method may take some time to return a result on a large dataset. Following a FindFirst, you can find subsequent matches for the search criteria by calling FindNext. Wildcard searches will only work with the wildcard character at the end of the string i.e. INV*, you cannot run a wildcard search with the wildcard at the beginning i.e. *INV.

Examples

This example uses the FindFirst method as well as the FindNext method. The code demonstrates the following:
  • Using FindFirst on the HeaderData object to see if an invoice number exists.
  • Using FindFirst and FindNext to find all invoices for a particular customer account.

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oHeaderData As SageDataObject300.HeaderData
  Dim oSalesRecord As SageDataObject300.SalesRecord
  Dim oInvoiceData As SageDataObject300.InvoiceData

   ' Declare Variables
  Dim bFlag As Boolean
  Dim szAccount As String
  Dim szDataPath As String

  ' Create the SDO Engine Object
  Set oSDO = New SageDataObject80.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then
    ' Connect to Data Files
    oWS.Connect(szDataPath, "", "", "Example")

    ' *****************************************************
    ' Example 1
    ' This example detects whether a specific invoice is in the audit trail

    ' Create the HeaderData object
    Set oHeaderData = oWS.CreateObject("HeaderData")

    ' Attempt to find an Invoice
    ' If it's a string you are attempting to find then
    ' To get an exact match you will need to pad the field with spaces to the correct length
    ' e.g. in this case the INV_REF is 30 chars, so I am attempting to find INV001
    ' followed by 24 spaces.  To get a partial match use the wildcard e.g. INV*
    ' (you need not pad this with spaces)
    bFlag = oHeaderData.FindFirst("INV_REF", "INV001".PadRight(30, " "))

    If (bFlag) Then
MsgBox "The Find was Successfull" & Chr(10) & Chr(10) & "The details are " & _
        oHeaderData.Fields.Item("DETAILS")>Value, vbOKOnly Or vbInformation, "SDO"

    Else

      MsgBox "No Match Found", vbOKOnly Or vbInformation, "SDO"

    End If

    ' ***************************************************
    ' Example 2
    ' This example locates all Invoices for a particular customer

    ' Create the Objects
    Set oSalesRecord = oWS.CreateObject("SalesRecord")
    Set oInvoiceData = oWS.CreateObject("InvoiceData")

    ' Move to First Customer
    oSalesRecord.MoveFirst

    ' Extract Customer and pad to required length
    szAccount = oSalesRecord.Fields.Item("ACCOUNT_REF").Value
    szAccount = szAccount & String(8 - Len(szAccount), 32)

    ' Attempt to find the Customer in InvoiceData
    bFlag = oInvoiceData.FindFirst("ACCOUNT_REF", szAccount)

    If (bFlag) Then ' we have a match so loop until there are no more

      Do

        ' Display Invoice Number
        MsgBox "Customer " & szAccount & Chr(10) & Chr(10) & "Invoice Number " & _
          oInvoiceData.Fields.Item("INVOICE_NUMBER").Value, vbOKOnly Or vbInformation, "SDO"
        bFlag = oInvoiceData.FindNext("ACCOUNT_REF", strAccount)

      Loop While bFlag

    Else

      MsgBox "No Match Found", vbOKOnly Or vbInformation, "SDO"

    End If

    ' Disconnect
    oWS.Disconnect

  End If

  ' Destroy Objects
  Set oHeaderData = Nothing
  Set oSalesData = Nothing
  Set oInvoiceData = Nothing
   Set oWS = Nothing
  Set oSDO = Nothing

  Exit Sub

' Error Handling Code
 Error_Handler:
  MsgBox "The SDO generated the following error: " & oSDO.LastError.Text

Related Topics

Method | Description
FindNext | Finds the next instance of the specified criteria.


FindNext Method

Description

The FindNext method is used to find a record using a non-indexed field as the basis for the search.

Syntax

The FindNext method has the following syntax:

object.FindNext

with the following parts:

Part | Description
Object | Applies to one of the following types: SDOFile, SDOLinkedFile and SDOLinkedSubFile.

Return Value(s)

The method returns the following values:

Value | Description
True | A match was found for the search criteria
False | No match was found for the search criteria

Remarks

FindNext can only be used following a call to the FindFirst method.

As it does not use an index, FindNext is a sequential search. As a result of this, the FindNext method may take some time to return a result on a large dataset. Wildcard searches will only work with the wildcard character at the end of the string i.e. INV*, you cannot run a wildcard search with the wildcard at the beginning i.e. *INV.

Examples

This example uses the FindNext method as well as the FindFirst method.

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oSalesRecord As SageDataObject300.SalesRecord
  Dim oInvoiceData As SageDataObject300.InvoiceData

   ' Declare Variables
  Dim bFlag As Boolean
  Dim szAccount As String
  Dim szDataPath As String

  ' Create the SDO Engine Object
  Set oSDO = New SageDataObject80.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then
    ' Connect to Data Files
    oWS.Connect(szDataPath, "", "", "Example")

    ' This example locates all Invoices for a particular customer

    ' Create the Objects
    Set oSalesRecord = oWS.CreateObject("SalesRecord")
    Set oInvoiceData = oWS.CreateObject("InvoiceData")

    ' Move to First Customer
    oSalesRecord.MoveFirst

    ' Extract Customer and pad to required length
    szAccount = oSalesRecord.Fields.Item("ACCOUNT_REF") .Value
    szAccount = szAccount.PadRight(8, " ")

     ' Attempt to find the Customer in InvoiceData
    bFlag = oInvoiceData.FindFirst("ACCOUNT_REF", szAccount)

    If (bFlag) Then ' we have a match so loop until there are no more

      Do

        ' Display Invoice Number
        MsgBox "Customer " & szAccount & Chr(10) & Chr(10) & "Invoice Number " & _
          oInvoiceData.Fields.Item("INVOICE_NUMBER").Value, vbOKOnly Or vbInformation, "SDO"
        bFlag = oInvoiceData.FindNext("ACCOUNT_REF", szAccount)

      Loop While bFlag

    Else

      MsgBox "No Match Found", vbOKOnly Or vbInformation, "SDO"

    End If

    ' Disconnect
    oWS.Disconnect

  End If

  ' Destroy Objects
  Set oSalesData = Nothing
  Set oInvoiceData = Nothing
  Set oWS = Nothing
  Set oSDO = Nothing

  Exit Sub

' Error Handling Code
Error_Handler:
  MsgBox "The SDO generated the following error: " & oSDO.LastError.Text

Related Topics

Method | Description
FindFirst | Finds the first instance of the specified criteria.


Lock Method

Description

The Lock method allows you to lock a specified record so it cannot be accessed by anyone else.

Syntax

The Lock method has the following syntax:

object.Lock DataRecordNumber

with the following parts:

Part | Description
Object | Applies to one of the following types: SDOFile, SDOIndexFile, SDOLinkedFile and SDOLinkedSubFile.
DataRecordNumber | The record number of the record in the data file you wish to lock.

Return Value(s)

The Lock method returns the following values:

Return Value | Description
True | The record has been locked.
False | The record could not be locked.

Remarks

Having locked a record using the Lock method, you must ensure that you subsequently call the Unlock method.

Example

This example uses the Lock method to lock a record in SetupData.

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oSetupData As SageDataObject300.SetupData

  ' Declare Variables
  Dim szDataPath As String

  ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then
    ' Connect to Data Files - Will throw an exception if it fails
    If oWS.Connect szDataPath, "", "", "Example" Then

      ' Create an Instance of the SetupData object
      Set oSetupData = oWS.CreateObject("SetupData")

      ' Read and Lock the Record
      oSetupData.Read 1
      oSetupData.Lock 1

      ' Change the Company Name
      oSetupData.Fields.Item("NAME").Value = CStr("New Company Name")

      ' Write and Unlock the Record
      oSetupData.Write 1
      oSetupData.Unlock 1

      ' Disconnect
      oWS.Disconnect

    End If

  End If

  ' Destroy Objects
  Set oSetupData = Nothing
  Set oWS = Nothing
   Set oSDO = Nothing

  Exit Sub

' Error Handling Code
 Error_Handler:

  MsgBox "The SDO generated the following error: " & oSDO.LastError.Text

Related Topics

Properties and Methods | Description
Unlock | Unlocks a previously locked record.


IsDateUserValidForLockDate Method

Description

The IsDateUserValidForLockDate method helps identify whether a transaction date is affected by a lock date and if the user has permission to post in to that period.

Syntax

The IsDateUserValidForLockDate method has the following syntax:

object.IsDateUserValidForLockDate(DATE dTransactionDate, String User)

with the following parts:

Part | Description
SetupData | Applies to only the SetupData object

Return Value(s)

The method returns the following values:

LockDatePermission is an enumerated type used to determine the LockDatePermission

Remarks

Sage 50 Accounts 2017 sees the introduction of Lock Dates which allow accounting periods to be closed. If the SDO is used to post a transaction that is dated before the lock date the TransactionPost.Update will return false and throw an exception if the user does not have the permission to post into closed periods. The LockDatePermission is an enumerator type that allows us to identify if the user has sufficient access to make the posting.

We recommend that SDO users are created without the ability to override closed periods. This is done through Settings>Access Rights>Menu Settings>Dialogs>Lock Date Settings as shown below.

Examples

Is Date User Valid For Lock Date

Related Topics


MoveFirst Method

Description

The MoveFirst method moves to the first record in an object and makes that record the current record.

Syntax

The MoveFirst method has the following syntax:

object.MoveFirst

with the following parts:

Part | Description
Object | Applies to one of the following types: SDORecord, SDORecordLinked and SDOIndexFile.

Return Values

The MoveFirst method returns the following values:

Return Value | Description
True | The method was able to move to the first record in the collection.
False | The method was not able to move to the first record, there are no records in the collection.

Example

This example uses the MoveFirst method to position the Sales Record object to the first record.

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oSalesRecord As SageDataObject300.SalesRecord

  ' Declare Variables
  Dim szDataPath As String

   ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then

    ' Connect to Data Files
    oWS.Connect szDataPath, "", "", "Example"

    ' Create an Instance of the SalesRecord object
    Set oSalesRecord = oWS.CreateObject("SalesRecord")

    ' Move to the First Record
    oSalesRecord.MoveFirst

    MsgBox oSalesRecord("NAME")

    ' Disconnect
    oWS.Disconnect

  End If

  ' Destroy Objects
  Set oSalesRecord = Nothing
  Set oWS = Nothing
  Set oSDO = Nothing

  Exit Sub

' Error Handling Code
 Error_Handler:
  MsgBox "The SDO generated the following error: " & oSDO.LastError.Text

Related Topics

Properties and Methods | Description
Move | Moves to a specified record.
MoveLast | Moves to the last record in the collection.
MovePrev | Moves to the previous record in the collection.
MoveNext | Moves to the next record in the collection.


MoveLast Method

Description

The MoveLast method moves to the last record in an object and makes that record the current record.

Syntax

The MoveLast method has the following syntax:

object.MoveLast

with the following parts:

Part | Description
Object | Applies to one of the following types: SDORecord, SDORecordLinked and SDOIndexFile.

Return Values

The MoveLast method returns the following values:

Return Value | Description
True | The method was able to move to the last record in the collection.
False | The method was not able to move to the last record, there are no records in the collection.

Example

This example uses the MoveLast method to position the Sales Record object to the last record.

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oSalesRecord As SageDataObject300.SalesRecord

  ' Declare Variables
  Dim szDataPath As String

   ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then
    ' Connect to Data Files
    oWS.Connect szDataPath, "", "", "Example"

    ' Create an Instance of the SalesRecord object
    Set oSalesRecord = oWS.CreateObject("SalesRecord")

    ' Move to the Last Record
    oSalesRecord.MoveLast

    MsgBox oSalesRecord("NAME")

    ' Disconnect
    oWS.Disconnect

  End If

  ' Destroy Objects
  Set oSalesRecord = Nothing
  Set oWS = Nothing
   Set oSDO = Nothing

  Exit Sub

' Error Handling Code
 Error_Handler:
  MsgBox "The SDO generated the following error: " & oSDO.LastError.Text

Related Topics

Properties and Methods | Description
Move | Moves to a specified record.
MoveFirst | Moves to the first record in the collection.
MovePrev | Moves to the previous record in the collection.
MoveNext | Moves to the next record in the collection.


MoveNext Method

Description

The MoveNext method allows you to loop through records in a collection reading the index ascending.

Syntax

The MoveNext method has the following syntax:

object.MoveNext

with the following parts:

Part | Description
Object | Applies to one of the following types: SDORecord, SDORecordLinked and SDOIndexFile.

Return Values

The MoveNext method returns the following values:

Return Value | Description
True | The method was able to move to the next record in the collection.
False | The method was not able to move to the next record, the end of the file has been reached.

Example

This example uses the MoveNext method to loop through Customer records.

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oSalesRecord As SageDataObject300.SalesRecord

  ' Declare Variables
  Dim szDataPath As String
   ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then
    ' Connect to Data Files
    oWS.Connect szDataPath, "", "", "Example"

    ' Create an Instance of the SalesRecord object
    Set oSalesRecord = oWS.CreateObject("SalesRecord")

    ' Move to the First Record
    oSalesRecord.MoveFirst

    ' Loop through the Records
    Do

      MsgBox oSalesRecord("NAME")

    Loop Until Not oSalesRecord.MoveNext

    ' Disconnect
    oWS.Disconnect

  End If

  ' Destroy Objects
  Set oSalesRecord = Nothing
  Set oWS = Nothing
  Set oSDO = Nothing

' Error Handling Code
 Error_Handler:
  MsgBox "The SDO generated the following error: " & oSDO.LastError.Text

Related Topics

Properties and Methods | Description
Move | Moves to a specified record.
MoveFirst | Moves to the first record in the collection.
MoveLast | Moves to the last record in the collection.
MovePrev | Moves to the previous record in the collection.


MovePrev Method

Description

The MovePrev method allows you to loop through records in a collection reading the index descending.

Syntax

The MovePrev method has the following syntax:

object.MovePrev

with the following parts:

Part | Description
Object | Applies to one of the following types: SDORecord, SDORecordLinked and SDOIndexFile.

Return Values

The MovePrev method returns the following values:

Return Value | Description
True | The method was able to move to the previous record in the collection.
False | The method was not able to move to the previous record, the beginning of the file has been reached.

Example

This example uses the MovePrev and MoveLast methods to loop through Customer records.

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oSalesRecord As SageDataObject300.SalesRecord

  ' Declare Variables
  Dim szDataPath As String

   ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then
    ' Connect to Data Files
    oWS.Connect szDataPath, "", "", "Example"

    ' Create an Instance of the SalesRecord object
    Set oSalesRecord = oWS.CreateObject("SalesRecord")

    ' Move to the Last Record
    oSalesRecord.MoveLast

    ' Loop through the Records
    Do

      MsgBox oSalesRecord("NAME")

    Loop Until Not oSalesRecord.MovePrev

    ' Disconnect
    oWS.Disconnect

  End If

  ' Destroy Objects
  Set oSalesRecord = Nothing
  Set oWS = Nothing
   Set oSDO = Nothing

  Exit Sub

' Error Handling Code
 Error_Handler:
  MsgBox "The SDO generated the following error: " & oSDO.LastError.Text

Related Topics

Properties and Methods | Description
Move | Moves to a specified record.
MoveFirst | Moves to the first record in the collection.
MoveLast | Moves to the last record in the collection.
MoveNext | Moves to the next record in the collection.


Open Method

Description

The Open method allows a file to be opened in specified mode.

Syntax

The Open method has the following syntax:

object.Open OpenMode

with the following parts:

Part | Description
Object | Applies to one of the following types: SDOFile, SDOIndexFile, SDOLinkedFile and SDOLinkedSubFile.
OpenMode | The mode to open the file in. Allowable values are listed in the Open Mode Constants article.

Return Value(s)

The Open method returns the following values:

Value | Description
True | The file was opened in the specified mode.
False | The file could not be opened in the specified mode.

Example

This example uses the Open method in conjunction with Close to access SetupData.

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oSetupData As SageDataObject300.SetupData

  ' Declare Variables
  Dim szDataPath As String

  ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Connect to Data Files
  oWS.Connect szDataPath, "", "", "Example"

  ' Create an Instance of the SetupData Object
  Set oSetupData = oWS.CreateObject("SetupData")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then

     ' Connect to Data Files - Will throw an exception if it fails
    If oWS.Connect szDataPath, "", "", "Example" Then
      ' Open the File for Read Only Access
      oSetupData.Open sdoRead

      ' Read Record 1
      oSetupData.Read 1

      ' Display the Company Name
      MsgBox oSetupData.Fields.Item("NAME").Value

      ' Close the File
      oSetupData.Close

      ' Disconnect
      oWS.Disconnect

    End If

  End If

  ' Destroy Objects
  Set oSetupData = Nothing
  Set oWS = Nothing
   Set oSDO = Nothing

  Exit Sub

 ' Error Handling Code
Error_Handler:

  MsgBox "The SDO generated the following error: " & oSDO.LastError.Text

Related Topics

Methods and Properties | Description
Close | Closes a previously opened file.


Read Method

Description

The Read method allows you to read a specified record in a data file.

Syntax

The Read method has the following syntax:

object.Read DataRecordNumber

with the following parts:

Part | Description
Object | Applies to one of the following types: SDOFile, SDOIndexFile, SDOLinkedFile and SDOLinkedSubFile.
DataRecordNumber | The record number of the record in the data file you wish to read.

Return Value(s)

The Read method returns the following values:

Return Value | Description
True | The record has been read.
False | The record could not be read.

Example

This example uses the Read method to read a record in SetupData.

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oSetupData As SageDataObject300.SetupData

  ' Declare Variables
  Dim szDataPath As String

   ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then

    ' Connect to Data Files
    If oWS.Connect szDataPath, "", "", "Example" Then

      ' Create an Instance of the SetupData object
      Set oSetupData = oWS.CreateObject("SetupData")

      ' Read the Record
      oSetupData.Read 1

      ' Change the Company Name
      oSetupData.Fields.Item("NAME").Value = CStr("New Company Name")

      ' Write the Record
      oSetupData.Write 1

      ' Disconnect
      oWS.Disconnect

    End If

  End If

  ' Destroy Objects
  Set oSetupData = Nothing
  Set oSDO = Nothing
  Set oWS = Nothing

  Exit Sub

' Error Handling Code
 Error_Handler:

  MsgBox "The SDO generated the following error: " & oSDO.LastError.Text

Related Topics

Properties and Methods | Description
Lock | Locks the specified record.
Unlock | Unlocks the specified record.
Write | Writes changes to an object to the underlying data file.


RecordNumber Property

RecordNumber Method

Description

The DataRecordNumber method returns a record number of a record in a data file.

Syntax

The RecordNumber method has the following syntax:

object.RecordNumber

with the following parts:

Part | Description
Object | Applies to an SDOFile object

Values

The RecordNumber method returns an integer value.

Remarks

There are no parameters for this method.

Example

The following example uses the RecordNumber method to return the data record number of the second record in the SalesIndex object :

' Declare Sage Data Objects
Dim oSDO As New SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oSalesData As SageDataObject300.SalesData

' Declare variables
Dim szDataPath As String = "C:\ProgramData\Sage\Accounts\2024\"

' Create the workspace
oWS = oSDO.Workspaces.Add("Example")

Try
    ' Select the Company from the user-interface list of available companies
    szDataPath = oSDO.SelectCompany(szDataPath)

    If szDataPath <> "" Then

        ' Connect to data files
        If oWS.Connect(szDataPath, "", "", "Example") Then

        ' Instantiate the Sales Data object
         oSalesData = oWS.CreateObject("SalesData")

        ' Move to the last SalesData record
        oSalesData.MoveLast()

        ' Read and display the RecordNumber
        MessageBox.Show("Last RecordNumber is " & oSalesData.RecordNumber())

    End If
End If

Catch
    MessageBox.Show(oSDO.LastError.Text)
Finally
    ' Disconnect from the data files
    oWS.Disconnect()
End Try


Unlock Method

Description

The Unlock method allows you to unlock a record previously locked using the Lock method.

Syntax

The Unlock method has the following syntax:

object.Unlock DataRecordNumber

with the following parts:

Part | Description
Object | Applies to one of the following types: SDOFile, SDOIndexFile, SDOLinkedFile and SDOLinkedSubFile.
DataRecordNumber | The record number of the record in the data file you wish to unlock.

Return Value(s)

The Lock method returns the following values:

Return Value | Description
True | The record has been unlocked.
False | The record could not be unlocked.

Remarks

The Unlock method should only be used if the record has previously locked using the Lock method.

Example

This example uses the Unlock method to unlock a record in SetupData that had previously been locked using the Lock method.

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oSetupData As SageDataObject300.SetupData

  ' Declare Variables
  Dim szDataPath As String

   ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Connect to Data Files
  oWS.Connect szDataPath, "", "", "Example"

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then
    ' Connect to Data Files - Will throw an exception if it fails
    If oWS.Connect szDataPath, "", "", "Example" Then

     ' Create an Instance of the SetupData object
      Set oSetupData = oWS.CreateObject("SetupData")

      ' Read and Lock the Record
      oSetupData.Read 1
      oSetupData.Lock 1

      ' Change the Company Name
      oSetupData.Fields.Item("NAME").Value = CStr("New Company Name")

      ' Write and Unlock the Record
      oSetupData.Write 1
      oSetupData.Unlock 1

      ' Disconnect
      oWS.Disconnect

    End If

  End If

  ' Destroy Objects
  Set oSetupData = Nothing
  Set oWS = Nothing
   Set oSDO = Nothing

  Exit Sub

' Error Handling Code
 Error_Handler:

  MsgBox "The SDO generated the following error: " & oSDO.LastError.Text

Related Topics

Properties and Methods | Description
Lock | Locks a specified record.


Write Method

Description

The Write method commits changes made to the fields collection of an object to the underlying data file.

Syntax

The Write method has the following syntax:

object.Write DataRecordNumber

with the following parts:

Part | Description
Object | Applies to one of the following types: SDOFile, SDOIndexFile, SDOLinkedFile and SDOLinkedSubFile.
DataRecordNumber | The record number of the record in the data file you wish to write.

Return Value(s)

The Write method returns the following values:

Return Value | Description
True | The record has been written.
False | The record could not be written.

Remarks

The Write method can also be used, where appropriate, to write a new record to a data file. This can be done by passing the record count plus one as the DataRecordNumber parameter. Note that some data files, for example Department, have a fixed number of records so you never try to add a new one.

  oRecurringData.Write (oRecurringData.Count + 1)

Wherever possible however, you should use the AddNew method of the appropriate SDORecord object to add new records as this ensures that the relevant index is updated.

Example

This example uses the Write method to write changes to a record in SetupData.

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oSetupData As SageDataObject300.SetupData

  ' Declare Variables
  Dim szDataPath As String
   ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then
    ' Connect to Data Files
    If oWS.Connect(szDataPath, "", "", "Example") Then

      ' Create an Instance of the SetupData object
      Set oSetupData = oWS.CreateObject("SetupData")

      ' Read the Record
      oSetupData.Read 1

      ' Change the Company Name
      oSetupData.Fields.Item("NAME").Value = CStr("New Company Name")

      ' Write the Record
      oSetupData.Write 1

      ' Disconnect
      oWS.Disconnect

    End If

  End If

  ' Destroy Objects
  Set oSetupData = Nothing
  Set oWS = Nothing
  Set oSDO = Nothing

  Exit Sub

 ' Error Handling Code
Error_Handler:

  MsgBox "The SDO generated the following error: " & oSDO.LastError.Text

Related Topics

Properties and Methods | Description
AddNew | Adds a new record to an SDORecord object.
Read | Reads the specified record.


Fields Property

Description

The Fields property is a collection holding all the fields associated with a particular object. Fields are typically accessed using their name although their ordinal number within the collection can be used instead.

Syntax

The Fields property has the following syntax:

object.Fields(Field)

with the following parts:

Part | Description
Object | Applies to one of the following types: SDORecord, SDORecordLinked, SDOFile, SDOIndexFile, SDOLinkedFile, SDOLinkedSubFile, SDOIspPost and SDOPosting.
Field | Either a string expression containing the name of the field or an integer value representing the fields position in the collection.

Remarks

Individual fields within the collection are held in the Items collection of the Fields property. The Fields collection is Read Only, you cannot add your own fields to it.

Examples

The following examples shows how to access the Fields collection of the SalesRecord object using both field names and ordinal numbers.

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oSalesRecord As SageDataObject300.SalesRecord

  ' Declare Variables
  Dim iLoopcount As Integer
  Dim szDataPath As String

   ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then

    ' Connect to Data Files
    oWS.Connect szDataPath, "", "", "Example"

    ' Create an Instance of the SalesRecord object
    Set oSalesRecord = oWS.CreateObject("SalesRecord")

    ' Display the Customer Name
    MsgBox oSalesRecord.Fields.Item("NAME").Value

    ' Display all the Field Names
    For iLoopcount = 1 To oSalesRecord.Fields.Count

      MsgBox oSalesRecord.Fields(iLoopcount).Name

    Next

    ' Disconnect
    oWS.Disconnect

  End If

  ' Destroy Objects
  Set oSalesRecord = Nothing
  Set oWS = Nothing
   Set oSDO = Nothing

  Exit Sub

' Error Handling Code
 Error_Handler:
  MsgBox "The SDO generated the following error: " & oSDO.LastError.Text

Related Topics

Object | Description
Field | A single piece of data within a single record of an SDO object.


SDOIndexFile Objects

Description

The SDOIndexFile objects give direct read/write access to Sage 50 Accounts's index files. Typically, you would use the equivalent SDORecord or SDORecordLinked objects rather than accessing the index files directly.

Objects

The following table lists all the SDOIndexFile objects:

Object | Description
AssetIndex | Fixed Assets Index - ASTINDEX.DTA
BankIndex | Bank Index - BNKINDEX.DTA
BankRemittanceIndex | Remittance Line Index - BNKREMIX.DTA
CompanyDeliveryIndex | Company Delivery Address Index - COMDAIDX.DTA
ContactAccountIndex | Contact Records Index - CONTINDA.DTA
ContactDateIndex | Contact Date Index - CONTINDD.DTA
CountryCodeIndex | Country Code Index - CTRYINX.DTA
InvoiceIndex | Invoice Record Index - INVINDEX.DTA
NominalIndex | Nominal Ledger Index - NOMINDEX.DTA
POPIndex | Purchase Order Index - PUOINDEX.DTA
PriceIndex | Price Index - PRICEIDX.DTA
PriceListIndex | Price List Index - PRLSTIDX.DTA
PurchaseDeliveryIndex | Purchase Delivery Address Index - PURDAIDX.DTA
PurchaseIndex | Suppliers Index - PURINDEX.DTA
RemittanceIndex | Cheque Remittance Line Index - REMITIDX.DTA
SalesDeliveryIndex | Sales Delivery Index - SALDAIDX.DTA
SalesIndex | Customers Index - SALINDEX.DTA
SOPIndex | Sales Order Index - SAOINDEX.DTA
StockIndex | Stock Index - STKINDEX.DTA
ToDoIndex | Task Manager Index - TODOIDX.DTA

Methods

The SDOIndexFile objects have the following methods:

Methods | Description
Add
Close | Closes a previously opened data file or index.
Find | Enables a search to take place on the indexed field for a record that matches the specified criteria. The find can be exact or partial.
Lock | Locks a record specified by the record number parameter in a data file or index.
Move | Moves to a specified record in the collection.
MoveFirst | Moves to the first record in the collection.
MoveLast | Moves to the last record in the collection.
MoveNext | Moves to the next record in the collection.
MovePrev | Moves to the previous record in the collection.
Open | Opens a data file or index in the mode specified by the open mode parameter.
Read | Reads a record specified by the record number parameter.
Remove | Removes the current record and will throw an exception if the record cannot be removed.
Unlock | Unlocks a previously locked record specified by the record number parameter.
Write | Writes a record to the data file specified by the record number parameter.

Properties

The SDOIndexFile objects have the following properties:

Properties | Description
Count | Returns the number of records in the current collection.
DataRecordNumber | Returns the record number of record in the data file.
Fields | Returns a list of Fields.
FileType | Returns the type of the file. i.e. SDOFile
IndexRecordNumber | Returns the record number of the record in the index file.
Key | Returns the value of the Key field for the index. For example, on the SalesIndex object, the key field is ACCOUNT_REF.


Find Method

Description

The Find method is used to find a record using an indexed field as the basis for the search.

Syntax

The Find method has the following syntax:

object.Find(Boolean)

with the following parts:

Part | Description
Object | Applies to one of the following types: SDOFile, SDOLinkedFile and SDOLinkedSubFile.
Boolean | A boolean value that indicates whether the key stored in the relevant object is partial or complete. If a partial key is specified the first instance will be returned.

Return Value(s)

The method returns the following values:

Value | Description
True | A match was found for the search criteria.
False | No match was found for the search criteria.

Remarks

As Find is using an index a binary chop search is performed. As a result of this, the Find method is the quickest method of searching for a record in the Sage data objects. Following a Find, you can find subsequent matches for the search criteria by calling MoveNext.

When using the Find on a SDOIndexFile object you would need to populate the Key property. Further information on how to do this can be found by reviewing the documentation of the Key property.

Examples

This example uses the Find method to search for records matching criteria specified. The code demonstrates the following:
  • Using Find on the SalesRecord object to see if an exact match of a customer exists.
  • Using Find on the PurchaseRecord to find a supplier record beginning with S

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oSalesRecord As SageDataObject300.SalesRecord
  Dim oPurchaseRecord As SageDataObject300.PurchaseRecord

  ' Declare Variables
  Dim bFlag As Boolean
  Dim szDataPath As String

  ' Create the SDO Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then
    ' Connect to Data Files
    oWS.Connect szDataPath, "", "", "Example"

    ' ************** Complete Match on Sales Record object **********************

    ' Create Sales Record Object
    Set oSalesRecord = oWS.CreateObject("SalesRecord")

    ' Populate index field with value to search for
    oSalesRecord.Fields.Item("ACCOUNT_REF").Value = CStr("CASH001")

    ' Perform Exact match find
    bFlag = oSalesRecord.Find(False)

    If bFlag Then
      MsgBox "The find has been successful, the object is positioned to " & _
        oSalesRecord.Fields.Item("NAME").Value, vbOKOnly Or vbInformation, "SDO"

    Else
      MsgBox "The find has not found a match to your criteria", vbOKOnly Or vbInformation, "SDO"

    End If

    ' ************** Partial Match on Purchase Record object *******************
    ' Create the Purchase Record Object
    Set oPurchaseRecord = oWS.CreateObject("PurchaseRecord")

    ' Populate index field with value to search for
    oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value = CStr("S")

    ' Perform partial match find
    bFlag = oPurchaseRecord.Find(True)

    If bFlag Then
      MsgBox "The find has been successful, the object is positioned to " & _
        oPurchaseRecord.Fields.Item("NAME").Value, vbOKOnly Or vbInformation, "SDO"

    Else
      MsgBox "The find has not found a match to your criteria.", vbOKOnly Or vbInformation, "SDO"

    End If

    ' Disconnect & Destroy Objects
    oWS.Disconnect

  End If

  ' Destroy Objects
  Set oSalesRecord = Nothing
  Set oPurchaseRecord = Nothing
  Set oWS = Nothing
  Set oSDO = Nothing

  Exit Sub

' Error Handling Code
Error_Handler:

  MsgBox "The SDO generated the following error: " & oSDO.LastError.Text

Related Topics

Properties | Description
Key | Used in conjunction with the Find method on an Index object
Method | Description
MoveNext | Finds the next instance of the specified criteria.


Move Method

Description

The Move method changes the current record to the record in the index file specified by the record number parameter.

Note : The record position in the index file does not always correspond to the same record position in the data file.

Syntax

The Move method has the following syntax:

object.Move RecordNumber

with the following parts:

Part | Description
Object | Applies to one of the following types: SDORecord, SDORecordLinked and SDOIndexFile.

Return Values

The Move method returns the following values:

Return Value | Description
True | The method was able to move to the record specified in the parameter.
False | The method was not able to move to the record specified in the parameter.

Example

This example uses the Move method to position the Sales Record object at a specific position.

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oSalesRecord As SageDataObject300.SalesRecord

  ' Declare Variables
  Dim szDataPath As String
   ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then

    ' Connect to Data Files
    oWS.Connect szDataPath, "", "", "Example"

    ' Create an Instance of the SalesRecord object
    Set oSalesRecord = oWS.CreateObject("SalesRecord")

    ' Move to the tenth Record
    if oSalesRecord.Move(10) then
      MsgBox "The move has been successful and the object is positioned at account " & _
      oSalesRecord.Fields.Item("NAME").Value

    End If

    ' Disconnect
    oWS.Disconnect

  End if

  ' Destroy Objects
  Set oSalesRecord = Nothing
  Set oWS = Nothing
   Set oSDO = Nothing

  Exit Sub

' Error Handling Code
 Error_Handler:
  MsgBox "The SDO generated the following error: " & oSDO.LastError.Text

Related Topics

Methods | Description
MoveFirst | Moves to the first record in the collection.
MoveNext | Moves to the next record in the collection.
MoveLast | Moves to the last record in the collection.
MovePrev | Moves to the previous record in the collection.


Remove Method

Description

The Remove method attempts to physically delete the current record of an object from the data files.

Syntax

The Remove method has the following syntax:

object.Remove

with the following parts:

Part | Description
Object | Applies to one of the following types: SDOFile, SDOIndexFile, SDOLinkedFile and SDOLinkedSubFile.

Return Value(s)

The Remove method returns the following values:

Return Value | Description
True | The record could be removed.
False | The record could not be removed.

Remarks

The Remove method can be used to delete records in the same way as the Sage 50 Accounts product. If a record cannot be deleted, the Remove, method will throw an exception.

Deletion of records will fail for the same reasons as in Sage 50 Accounts. For example, you cannot delete a customer account if there is an outstanding balance or the account has transactions in the audit trail.

Example

This example uses the Remove method to attempt to delete the first record in the Sales Record object. If the Remove method fails an exception will be thrown and using an error trap the reason why the delete has failed will be presented to the user in a message box.

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oSalesRecord As SageDataObject300.SalesRecord

  ' Declare Variables
  Dim bFlag As Boolean
  Dim szDataPath As String
   ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then
    ' Connect to Data Files
    oWS.Connect szDataPath, "", "", "Example"

    ' Create an Instance of the SetupData object
    Set oSalesRecord = oWS.CreateObject("SalesRecord")

    ' Move to the first customer
    oSalesRecord.Movefirst

    Try to Delete the Record
    oSalesRecord.Remove

    ' Disconnect
    oWS.Disconnect

  End If

  ' Destroy Objects
  Set oSetupData = Nothing
  Set oWS = Nothing
  Set oSDO = Nothing

  Exit Sub

' Error Handling Code
Error_Handler:

  Select Case oSdo.LastError.Code

    ' Record has transactions
    Case Is = sdoDeleteFailedHasTrans
      Msgbox "Delete Failed due to: " & oSdo.LastError.Text

    ' Deletion Failed
    Case Is = sdoDeleteFailed
      Msgbox "Delete Failed due to: " & oSdo.LastError.Text

  End Select


DataRecordNumber Property

Description

The DataRecordNumber property sets or returns a record number of a record in a data file that relates to an index entry.

Syntax

The DataRecordNumber property has the following syntax:

object.DataRecordNumber

with the following parts:

Part | Description
Object | Applies to the SDOIndexFile objects only.

Values

The DataRecordNumber property returns an integer value.

Remarks

The DataRecordNumber property is Read Only.

Example

The following example uses the DataRecordNumber property to return the data record number of the second record in the SalesIndex object :

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oSalesIndex As SageDataObject300.SalesIndex

  ' Declare Variables
  Dim szDataPath As String

   ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is
  ' selected,' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left
  ' empty.
  If szDataPath <> "" Then
    ' Connect to Data Files
    oWS.Connect szDataPath, "", "", "Example"

    ' Create an Instance of the SalesRecord object
    Set oSalesIndex = oWS.CreateObject("SalesIndex")

    ' Move to the First Record in the collection
    oSalesIndex.MoveFirst

    ' Move to the next record
    oSalesIndex.MoveNext

    ' Display the data record number of the record we are positioned on
    MsgBox oSalesIndex.DataRecordNumber

    ' Disconnect
    oWS.Disconnect

  End If

  ' Destroy Objects
  Set oSalesIndex = Nothing
  Set oWS = Nothing
  Set oSDO = Nothing

  Exit Sub

' Error Handling Code
 Error_Handler:
  MsgBox "The SDO generated the following error: " & oSDO.LastError.Text


IndexRecordNumber Property

Description

The IndexRecordNumber property returns the record number of an entry in an index.

Syntax

The IndexRecordNumber property has the following syntax:

object.IndexRecordNumber

with the following parts:

Part | Description
Object | Applies to the SDOIndexFile objects only.

Values

The IndexRecordNumber property returns an integer value.

Remarks

The IndexRecordNumber property is Read Only.

Example

The following example uses the IndexRecordNumber property to return the index record number of the second record in the SalesIndex object:

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oSalesIndex As SageDataObject300.SalesIndex

  ' Declare Variables
  Dim szDataPath As String
   ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is
  ' selected,' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left
  ' empty.
  If szDataPath <> "" Then

    ' Connect to Data Files
    oWS.Connect szDataPath, "", "", "Example"

    ' Create an Instance of the SalesRecord object
    Set oSalesIndex = oWS.CreateObject("SalesIndex")

    ' Move to the First Record in the collection
    oSalesIndex.MoveFirst

    ' Move to the next record
    oSalesIndex.MoveNext

    ' Display the index record number of the record we are positioned on
    MsgBox oSalesIndex.IndexRecordNumber

    ' Disconnect
    oWS.Disconnect

  End If

  ' Destroy Objects
  Set oSalesIndex = Nothing
  Set oWS = Nothing
   Set oSDO = Nothing

  Exit Sub

' Error Handling Code
 Error_Handler:
  MsgBox "The SDO generated the following error: " & oSDO.LastError.Text


Key Property

Description

The Key property sets or returns the Key value of an Index.

Syntax

The Key property has the following syntax:

object.Key Value

with the following parts:

Part | Description
Object | Applies to a SDOIndexFile object.
Value | The value you want to find.

Remarks

When using the Find on an SDOIndexFile object you need to populate the Key property.

Examples

This example uses the Find method on the SalesIndex object to search for records matching criteria specified by using the Key property. The DataRecordNumber is used to position the SalesRecord object to the match that has been found.

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oSalesRecord As SageDataObject300.SalesRecord
  Dim oSalesIndex As SageDataObject300.SalesIndex

  ' Declare Variables
  Dim szDataPath As String

  ' Create the SDO Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then

    ' Connect to Data Files
    oWS.Connect szDataPath, "", "", "Example"

    ' Create Objects
    Set oSalesIndex = oWS.CreateObject("SalesIndex")
    Set oSalesRecord = oWS.CreateObject("SalesRecord")

    ' Populate key property with value to search for
    oSalesIndex.Key = CStr("ABC")

    ' Perform Find for an partial match
    If oSalesIndex.Find(True) Then

      'Position Sales Record object at found record
      oSalesRecord.Move oSalesIndex.DataRecordNumber
      MsgBox "The Find was Successfull " & Chr(10) & Chr(10) & "We are positioned on account " & _
        oSalesRecord("ACCOUNT_REF"), vbOKOnly Or vbInformation, "SDO"

    End If

    ' Disconnect
    oWS.Disconnect

  End If

  ' Destroy Objects
  Set oSalesIndex = Nothing
  Set oWS = Nothing
  Set oSDO = Nothing

  Exit Sub

' Error Handling Code
 Error_Handler:
  MsgBox "The SDO generated the following error: " & oSDO.LastError.Text

Related Topics

Method | Description
MoveNext | Finds the next instance of the specified criteria.


SDOIspPost Objects

Description

The SDOIspPost object (Invoice, Sop and Pop) represents Invoices, Sales Orders and Purchase Orders that can be posted to the data files. It is derived from the SDOPosting object but adds extra functionality required by Invoices and Orders.

Access the fields of a SDOIspPost object via the Header property. Use the Items property of this object to access any sub items such as Invoice Items. You can get the next available invoice or order number by using the GetNextNumber method and you can add a new entry to the data files by using the Update method once the fields have been filled in.

Objects

The following table lists all the SDOIspPost objects:

Object | Description
InvoicePost | Create Stock/Service Invoice
POPPost | Create Purchase Order
SOPPost | Create Sales Order

Methods

The SDOIspPost objects have the following methods:

Method | Description
GetNextNumber | Returns the next available invoice/order number. As in Sage 50 Accounts, the method returns the next available number after the last invoice/order that was saved so it may not necessarily be the next number after the current highest numbered invoice/order.
Type | Sets the Type of the invoice/order.
Update | Updates the invoice/order to the Sage 50 Accounts data files.

Properties

The SDOIspPost objects have the following properties:

Property | Description
Header | Sets the header items for the invoice/order.
Items | Sets the item lines for the invoice/order.


GetNextNumber Method

Description

The GetNextNumber method returns the next available Invoice/Sales Order/Purchase Order Number. The value is returned as a Long Integer (4 byte).

Note: As in Sage 50 Accounts, the method returns the next available number after the last invoice/order that was saved so it may not necessarily be the next number after the current highest numbered invoice/order. Since Sage 50 Accounts 2011 it is no longer essential to set the Invoice_Number. If the Invoice number is not set the update method will automatically set it with the next available number.

Parameters

The GetNextNumber method has the following syntax:

object.GetNextNumber

with the following parts:

Part | Description
Object | Applies to one of the following types : SDORecord and SDORecordLinked

Examples Using this Method

Posting a Product Invoice
 Posting a Product Invoice and Receipt
Posting a Product Credit Note
Posting a Service Invoice
Posting a Service Credit Note
Posting a 'Mix and Match' Invoice
Posting a 'Mix and Match' Credit Note
Adding an Item Line to an Invoice


Type Method

Description

The Type property sets an invoice that is being created so that the invoice will know what kind of invoice it is.

Syntax

The Type property has the following syntax:

object.Type [ = Sdo constant value ]

with the following parts:

Part | Description
Object | Applies to SDOIspPost.

Examples

This example simply sets the Invoice being added as a product invoice.

  ' Create an instance of the Objects
  Set oInvoicePost = oWS.CreateObject("InvoicePost")

  ' Set the type of invoice for the next available number
  oInvoicePost.Type = sdoLedgerInvoice


Header Property

Description

The Header property is a collection holding all the fields associated with a particular object. Fields are typically accessed using their name although their ordinal number within the collection can be used instead.

Syntax

The Fields property has the following syntax:

object.Header(Field)

with the following parts:

Part | Description
Object | Applies to one of the following types: SDOIspPost and SDOPosting.
Header | Either a string expression containing the name of the field or an integer value representing the fields position in the collection.

Remarks

Individual fields within the collection are held in the Items collection of the Header property. The collection is Read Only, you cannot add your own fields to it.

Examples

The following examples shows how to access the Header collection of the InvoicePost object using field names.

  ' Error Handler
On Error GoTo Error_Handler

' Declare Objects
Dim oSDO As
  SageDataObject300.SDOEngine
Dim oWS As
  SageDataObject300.WorkSpace
Dim oSalesRecord As
  SageDataObject300.SalesRecord

' Declare Variables
Dim bFlag As
  Boolean
Dim szDataPath As
  String

' Create the SDO Engine Object
Set oSDO = New
  SageDataObject300.SDOEngine

' Create the Workspace
Set oWS =
  oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes
  the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to
  the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left
  empty.
If szDataPath <> "" Then

' Connect to Data Files
oWS.Connect szDataPath, "", "",
  "Example"

' Create an instance of InvoicePost & Record object's
Set oSalesRecord = oWS.CreateObject("SalesRecord")
Set oInvoicePost =
  oWS.CreateObject("InvoicePost")

' Set the type of invoice so we can find the next available number
oInvoicePost.Type = sdoLedgerService

' Use the GetNextNumber Method to generate the next available number
oInvoicePost.Header("Invoice_Number") = CLng(oInvoicePost.GetNextNumber)

' Loop for Number of Items on the Invoice
For iCtr = 1 To 5
Set oInvoiceItem = oInvoicePost.Items.Add()

' This is the text for the line
oInvoiceItem.Text = CStr("This is the text for line number " &
  iCtr)
oInvoiceItem("Text") = CStr("Posting
  Text")
oInvoiceItem("Service_Item_Lines") = CLng(1)
oInvoiceItem("Net_Amount") = CDbl(100)
oInvoiceItem("Full_Net_Amount") = CDbl(100)
oInvoiceItem("Tax_Amount") = CDbl(17.5)
oInvoiceItem("Nominal_Code") = CStr(oSalesRecord("Def_Nom_Code"))
oInvoiceItem("Tax_Code") = CInt(oSalesRecord("Def_Tax_Code"))
oInvoiceItem("Tax_Rate") = CDbl(17.5)
Next iCtr

' Populate Invoice Header Information
oInvoicePost.Header("Invoice_Date") = CDate(Date)
oInvoicePost.Header("Notes_1") = CStr("")
oInvoicePost.Header("Notes_2") = CStr("")
oInvoicePost.Header("Notes_3") = CStr("")
oInvoicePost.Header("Taken_By") = CStr("")
oInvoicePost.Header("Order_Number") = CStr("")
oInvoicePost.Header("Cust_Order_Number") = CStr("")
oInvoicePost.Header("Payment_Ref") = CStr("")
oInvoicePost.Header("Global_Nom_Code") = CStr("")
oInvoicePost.Header("Global_Details") = CStr("")
oInvoicePost.Header("Invoice_Type_Code") = CByte(sdoServiceInvoice)
oInvoicePost.Header("Items_Net") = CDbl(500)
oInvoicePost.Header("Items_Tax") = CDbl(87.5)

' Read the first customer
oSalesRecord.MoveFirst
oInvoicePost.Header("Account_Ref") = CStr(oSalesRecord("Account_Ref"))
oInvoicePost.Header("Name") = CStr(oSalesRecord("Name"))
oInvoicePost.Header("Address_1") = CStr(oSalesRecord("Address_1"))
oInvoicePost.Header("Address_2") = CStr(oSalesRecord("Address_2"))
oInvoicePost.Header("Address_3") = CStr(oSalesRecord("Address_3"))
oInvoicePost.Header("Address_4") = CStr(oSalesRecord("Address_4"))
oInvoicePost.Header("Address_5") =
  CStr(oSalesRecord("Address_5"))
oInvoicePost.Header("Del_Address_1") = CStr(oSalesRecord("Del_Address_1"))
oInvoicePost.Header("Del_Address_2") = CStr(oSalesRecord("Del_Address_2"))
oInvoicePost.Header("Del_Address_3") = CStr(oSalesRecord("Del_Address_3"))
oInvoicePost.Header("Del_Address_4") = CStr(oSalesRecord("Del_Address_4"))
oInvoicePost.Header("Del_Address_5") = CStr(oSalesRecord("Del_Address_5"))
oInvoicePost.Header("Cust_Tel_Number") = CStr(oSalesRecord("Telephone"))
oInvoicePost.Header("Contact_Name") =
  CStr(oSalesRecord("Contact_Name"))
oInvoicePost.Header("Global_Tax_Code") = CInt(oSalesRecord("Def_Tax_Code"))

' Update the Invoice
bFlag = oInvoicePost.Update
If  bFlag  Then
MsgBox "Invoice Created Successfully"
Else
MsgBox "Invoice Not Created"
End If
' Disconnect & Destroy Objects
oWS.Disconnect

End If

' Destroy Objects
Set oSDO = Nothing
Set oWS = Nothing
Set oSalesRecord = Nothing
Set oInvoicePost = Nothing
Set oInvoiceItem = Nothing

Exit Sub

' Error Handling Code
Error_Handler:
MsgBox "The SDO generated the following error: " & oSDO.LastError.Text
End Sub

Related Topics

Object | Description
Field | A single piece of data within a single record of an SDO object.


Items Property

Items.Add Method

Description

The Items property is a collection holding all of the added items for a particular item object. You are able to Add items to this collection using the Add method.

Syntax

The Fields property has the following syntax:

object.Items.Add

with the following parts:

Part | Description
Object | Applies to one of the following types: SDOIspPost and SDOPosting.
Items.Add | Either a string expression containing the name of the field or an integer value representing the fields position in the collection.

Remarks

Individual

Examples

The following examples shows how to use the Items.Add method to add multiple Invoice Items to an invoice that is being created.

  ' Declare Objects
Dim oSDO  As
  SageDataObject300.SDOEngine
Dim oWS  As
  SageDataObject300.WorkSpace
Dim oInvoicePost  As
  SageDataObject300.InvoicePost
Dim oInvoiceItem  As
  SageDataObject300.InvoiceItem
Dim oSalesRecord  As
  SageDataObject300.SalesRecord

' Declare Variables
Dim  strDataPath As String
Dim bFlag As Boolean
Dim  iCtr As Integer

' Create the SDO Engine Object
Set oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
Set oWS = oSDO.Workspaces.Add("Example")

' Select company the select company method takes the program install
' directory as a parameter
strDataPath = oSDO.SelectCompany("C:\Line50v9")

' Connect to Data Files
oWS.Connect strDataPath, "", "", "Example"

' Create an instance of InvoicePost & Record object's
Set oSalesRecord = oWS.CreateObject("SalesRecord")
Set oInvoicePost = oWS.CreateObject("InvoicePost")

' Set the type of invoice so we can find the next available number
oInvoicePost.Type = sdoLedgerService

' Use the GetNextNumber Method to generate the next available number
oInvoicePost.Header("Invoice_Number") = CLng(oInvoicePost.GetNextNumber)

' Loop for Number of Items on the Invoice
For iCtr = 1 To 5
Set oInvoiceItem = oInvoicePost.Items.Add()

' This is the text for the line
oInvoiceItem.Text = CStr("This is the text for line number " &
  iCtr)
oInvoiceItem("Text") = CStr("Posting
  Text")
oInvoiceItem("Service_Item_Lines") = CLng(1)
oInvoiceItem("Net_Amount") = CDbl(100)
oInvoiceItem("Full_Net_Amount") = CDbl(100)
oInvoiceItem("Tax_Amount") = CDbl(17.5)
oInvoiceItem("Nominal_Code") = CStr(oSalesRecord("Def_Nom_Code"))
oInvoiceItem("Tax_Code") = CInt(oSalesRecord("Def_Tax_Code"))
oInvoiceItem("Tax_Rate") = CDbl(17.5)
Next iCtr

' Populate Invoice Header Information
oInvoicePost.Header("Invoice_Date") = CDate(Date)
oInvoicePost.Header("Notes_1") = CStr("")
oInvoicePost.Header("Notes_2") = CStr("")
oInvoicePost.Header("Notes_3") = CStr("")
oInvoicePost.Header("Taken_By") = CStr("")
oInvoicePost.Header("Order_Number") = CStr("")
oInvoicePost.Header("Cust_Order_Number") = CStr("")
oInvoicePost.Header("Payment_Ref") = CStr("")
oInvoicePost.Header("Global_Nom_Code") = CStr("")
oInvoicePost.Header("Global_Details") = CStr("")
oInvoicePost.Header("Invoice_Type_Code") = CByte(sdoServiceInvoice)
oInvoicePost.Header("Items_Net") = CDbl(500)
oInvoicePost.Header("Items_Tax") = CDbl(87.5)

' Read the first customer
oSalesRecord.MoveFirst
oInvoicePost.Header("Account_Ref") = CStr(oSalesRecord("Account_Ref"))
oInvoicePost.Header("Name") = CStr(oSalesRecord("Name"))
oInvoicePost.Header("Address_1") = CStr(oSalesRecord("Address_1"))
oInvoicePost.Header("Address_2") = CStr(oSalesRecord("Address_2"))
oInvoicePost.Header("Address_3") = CStr(oSalesRecord("Address_3"))
oInvoicePost.Header("Address_4") =
  CStr(oSalesRecord("Address_4"))
oInvoicePost.Header("Address_5") = CStr(oSalesRecord("Address_5"))
oInvoicePost.Header("Del_Address_1") = CStr(oSalesRecord("Del_Address_1"))
oInvoicePost.Header("Del_Address_2") = CStr(oSalesRecord("Del_Address_2"))
oInvoicePost.Header("Del_Address_3") = CStr(oSalesRecord("Del_Address_3"))
oInvoicePost.Header("Del_Address_4") = CStr(oSalesRecord("Del_Address_4"))
oInvoicePost.Header("Del_Address_5") = CStr(oSalesRecord("Del_Address_5"))
oInvoicePost.Header("Cust_Tel_Number") = CStr(oSalesRecord("Telephone"))
oInvoicePost.Header("Contact_Name") = CStr(oSalesRecord("Contact_Name"))
oInvoicePost.Header("Global_Tax_Code") = CInt(oSalesRecord("Def_Tax_Code"))

' Update the Invoice
bFlag = oInvoicePost.Update
If bFlag  Then
MsgBox "Invoice Created Successfully"
Else
MsgBox "Invoice Not Created"
End If

' Disconnect and Destroy Objects
oWS.Disconnect
Set oSDO =  Nothing
Set oWS =  Nothing
Set oSalesRecord =  Nothing
Set oInvoicePost =  Nothing
Set oInvoiceItem =  Nothing

Related Topics

Object | Description
Field | A single piece of data within a single record of an SDO object.


SDOLinkedFile Objects

Description

The SDOLinkedFile object represents linked list files such as INVITEM.DTA and STKTRANS.DTA. It is derived from SDOFile and inherits all of its properties and methods.

When a SDOLinkedFile object is opened directly it is immediately positioned to the first record in the file. The Fields collection of the file will then return the data of this current record. You can then use the MoveNext, MoveLast, MovePrev and MoveFirst methods to navigate the whole file.

If a SDOLinkedFile object is returned as a result of another objects Items property or Link method then the MoveNext, MoveLast, MovePrev and MoveFirst methods will navigate the originating object's items.

For example, the Items property of the InvoiceRecord object returns a SDOLinkedFile object representing the invoice's line items, using the MoveNext, MoveLast, MovePrev and MoveFirst methods on this link would navigate through the specific items for the invoice that related to InvoiceRecord's current record.

A method exists IsDeleted that returns a boolean value indicating whether or not the item is deleted. This method only applies to InvoiceItem, SOPItem and POPItem objects.

Objects

The following table lists all the SDOLinkedFile objects:

Object | Description
InvoiceItem | Invoice Item Lines - INVITEM.DTA
POPItem | Purchase Order Line Items - PUOITEM.DTA
SOPItem | Sales Order Line Items - SAOITEM.DTA
StockTran | Stock Transactions - STKTRANS.DTA
UsageData | Transaction Usages - USAGE.DTA

Methods

SDOLinkedFile objects have the following methods:

Methods | Description
Close | Closes a previously opened data file or index.
FindFirst | Finds the first instance of a specified value in a specified field. Allows a sequential search to be carried out on non-indexed fields.
FindNext | Used after a FindFirst, finds the next match for the search criteria.
IsDeleted | Returns True if the record has been deleted, otherwise False. Note: Only applies to InvoiceItem, SOPItem and POPItem objects.
Link | Links the 'transactions' relating to the header. For example, on a Sales\Purchase Record, this will return a collection holding the transactions for the current Nominal Code. Note this does not work for Nominal Records.
Lock | Locks a record specified by the record number parameter in a data file or index.
MoveFirst | Moves to the first record in the collection.
MoveLast | Moves to the last record in the collection.
MoveNext | Moves to the next record in the collection.
MovePrev | Moves to the previous record in the collection.
Open | Opens a data file or index in the mode specified by the open mode parameter.
Read | Reads a record specified by the record number parameter.
Unlock | Unlocks a previously locked record specified by the record number parameter.
Write | Writes a record to the data file specified by the record number parameter.

Properties

SDOLinkedFile objects have the following properties:

Properties | Description
CostCode

Returns the CostCode object of the current record. Note: Only applies to StockTran.
Count | Returns the number of records in the collection.
Fields | Returns the fields collection for the object.
FileType | Returns the type of the file, for example, SDORecord.
Project

Returns the Project object of the current record. Note: Only applies to InvoiceItem, SOPItem and StockTran.
RecordNumber | Returns the RecordNumber of the current record.
Text | For Invoice and Sales Orders, returns the free text for an item line.


IsDeleted Method

Description

The IsDeleted property returns a boolean value that represents if the SDO is registered.

Syntax

The IsDeleted property has the following syntax:

object.IsDeleted

with the following parts:

Part | Description
Object | Applies to the InvoiceItem, SOPItem and POPItem objects.

Remarks

This property is Read Only.

Return Values

The IsDeleted method returns the following values:

Return Value | Description
True | The item has been deleted.
False | The item has not been deleted.

Example

The following example demonstrates the use of the IsDeleted property:

 ' Error Handler
 On Error GoTo Error_Handler

 ' Declare Objects
 Dim oSDO As SageDataObject300.SDOEngine
 Dim oWS As SageDataObject300.WorkSpace
 Dim oSOPItem As SageDataObject300.SopItem

 ' Declare Variables
 Dim szDataPath As String
 Dim bFlag As Boolean

 ' Create the SDO Engine object
 Set oSDO = New SageDataObject300.SDOEngine

 ' Create the workspace
 Set oWS = oSDO.Workspaces.Add("Example")

 ' Select Company. The SelectCompany method takes the program install
 ' folder as a parameter
 szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

 ' A U.I. for company selection is presented to the user. If a company is selected,
 ' the path will be passed to the szDataPath variable.
 ' If not, or the Cancel button is selected, the variable will be left empty.
 If szDataPath <> "" Then

   ' Try to Connect - Will throw an exception if it fails
   If oWS.Connect(szDataPath, "", "", "Example") Then

     ' Create instance of SOPItem object
     Set oSOPItem = oWS.CreateObject("SOPItem")

     oSOPItem.MoveFirst

     Do

       MsgBox "SOPItem record number " & CStr(oSOPItem.RecordNumber) & " IsDeleted = " & CStr(oSOPItem.IsDeleted), vbOKOnly, "SDO Examples"

     Loop Until Not oSOPItem.MoveNext

     ' Disconnect
     oWS.Disconnect

   End If

 End If

 ' Destroy Objects
 Set oSOPItem = Nothing
 Set oWS = Nothing
 Set oSDO = Nothing

 Exit Sub

 ' Error Handling Code
 Error_Handler:

 MsgBox "The SDO generated the following error: " & oSDO.LastError.Text, vbOKOnly, "SDO Examples"


Link Method

Description

The Link method returns a reference to a SDOLinkedFile object or a SDOLinkedSubFile Object. Note the Link method will not work for Nominal Records. If you wish to return the transactions belonging to a Nominal Record you will need to use code as in the Nominal Activity code example.

Syntax

The Link method has the following syntax:

object.Link

with the following parts:

Part | Description
Object | An expression that evaluates to a SDORecordLinked, SDOLinkedFile and SDOLinkedSubFile object.

Return Value(s)

The method returns the following values:

Description
Returns a reference to a SDOLinkedFile object or a SDOLinkedSubFile Object.

Remarks

You would use the Link method to access any items that relate to a specific object. For example, if you have a SalesRecord object that represents your Customer records and you wish to access a specific customer's transactions you would use the Link method.

Examples

This example uses the Link method to give the user a list of transactions for the first customer account. The example also uses the Count, MoveFirst, MoveNext and RecordNumber methods / properties.

  ' Declare Objects
  Dim oSDO As New SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oHeaderData As SageDataObject300.HeaderData
  Dim oSplitData As SageDataObject300.SplitData

  ' Declare Variables
  Dim lRecordNum As Long
  Dim szMessage As String
  Dim szDataPath As String

  ' Create the SDO Object
  oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' Connect to Data Files
  oWS.Connect szDataPath, "", "", "Example"

  ' Create an Instance of HeaderData
  oHeaderData = oWS.CreateObject("HeaderData")

  ' Read First Header
  oHeaderData.MoveFirst
  lRecordNum = 1

  ' Loop through the Header's until it is the EOF
  ' or you have chosen not to see the Next Header
  Do
    ' Use the Link Method to return the Splits for this Header
    oSplitData = oHeaderData.Link

    ' Create standard message
    szMessage = "Header Number " & oHeaderData.RecordNumber & " has " & oSplitData.Count & " Split(s)"
    If oSplitData.Count > 1 Then szMessage = szMessage + "s"
    szMessage = szMessage & Chr(10)

 If oSplitData.Count >0 Then

    ' Move to the First Split of the Originating Object
    ' In this case, the First Split of the Header
    oSplitData.MoveFirst

    ' We can use the Count Method to determine how many Split's
    ' the Header has
    Do
      ' Add a transaction detail to the message
      szMessage = szMessage & Chr(10) & "Transaction Number " & oSplitData.RecordNumber

      ' Move to the Next Split of the Header
    Loop Until Not oSplitData.MoveNext

    End If

    ' Complete the Message
    szMessage = szMessage & Chr(10) & Chr(10) & Chr(10) & "Do you want " & "to see the next Header Transaction ?"

    ' Move to the next Header & increment lRecordNum
    oHeaderData.MoveNext
    lRecordNum = lRecordNum + 1

  Loop Until MsgBox(szMessage, vbYesNo) = vbNo Or lRecordNum > oHeaderData.Count

  ' Disconnect and Destroy the Objects
  oWS.Disconnect
  oSplitData = Nothing
  oHeaderData = Nothing
  oWS = Nothing
  oSDO = Nothing


RecordNumber Property

Description

The DataRecordNumber property returns a record number of a record in a data file.

Syntax

The RecordNumber property has the following syntax:

object.RecordNumber

with the following parts:

Part | Description
Object | Applies to a SDORecord and SDOLinkedFile object

Values

The RecordNumber property returns an integer value.

Remarks

The RecordNumber property is Read Only.

Example

The following example uses the RecordNumber property to return the data record number of the second record in the SalesIndex object :

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oHeaderData As SageDataObject300.HeaderData

  ' Declare Variables
  Dim szDataPath As String

   ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is
  ' selected,' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left
  ' empty.
  If szDataPath <> "" Then

    ' Connect to Data Files
    oWS.Connect szDataPath, "", "", "Example"

    ' Create an Instance of the SalesRecord object
    Set oHeaderData = oWS.CreateObject("HeaderData")

    ' Move to the First Record in the collection
    oHeaderData.MoveFirst

    ' Display the record number of the record we are positioned on
    MsgBox oHeaderData.RecordNumber

    ' Disconnect
    oWS.Disconnect

  End If

  ' Destroy Objects
  Set oHeaderData = Nothing
  Set oWS = Nothing
   Set oSDO = Nothing

  Exit Sub

' Error Handling Code
 Error_Handler:
  MsgBox "The SDO generated the following error: " & oSDO.LastError.Text


Text Property

Description

The Text property returns the free text of an Invoice or Order line.

Syntax

The Text property has the following syntax:

object.Text

with the following parts:

Part | Description
Object | Applies to an SDOIspPost object

Values

The Text property returns a string value.

Example

Examples of using this property are included in the main examples list for the posting of Service Invoices and Credit Notes.


SDOLinkedSubFile Objects

Description

The SDOLinkedSubFile object represents the linked list files that themselves contain linked lists such as HEADER.DTA and SPLITS.DTA. It is derived from SDOLinkedFile and inherits all of its properties and methods including those that SDOLinkedFile itself inherits from SDOFile.

When a SDOLinkedSubFile object is opened directly it is immediately positioned to the first record in the file. The Fields collection of the file will then return the data of this current record. You can then use the MoveNext, MoveLast, MovePrev and MoveFirst methods to navigate the whole file.

If a SDOLinkedSubFile object is returned as a result of another objects Items property or Link method then the MoveNext, MoveLast, MovePrev and MoveFirst methods will navigate the originating object's items.

For example, the Items property of the HeaderData object returns a SDOLinkedSubFile object representing the splits for that header record, using the MoveNext, MoveLast, MovePrev and MoveFirst methods on this link would navigate through the specific splits for that header.

Objects

The following table lists all the SDOLinkedSubFile objects:

Object | Description
BankHeaderData | Bank Data - BANK.DTA
HeaderData | Transaction Headers - HEADER.DTA
SplitData | Transaction Splits - SPLIT.DTA

Methods

SDOLinkedSubFile objects has the following methods:

Method | Description
Close | Closes a previously opened data file or index.
FindFirst | Finds the first instance of a specified value in a specified field. Allows a sequential search to be carried out on non-indexed fields.
FindNext | Used after a FindFirst, finds the next match for the search criteria.
Link | Links the 'transactions' relating to the header. For example, on a NominalRecord, this will return a collection holding the transactions for the current Nominal Code.
Lock | Locks a record specified by the record number parameter in a data file or index.
MoveFirst | Moves to the first record in the collection.
MoveLast | Moves to the last record in the collection.
MoveNext | Moves to the next record in the collection.
MovePrev | Moves to the previous record in the collection.
Open | Opens a data file or index in the mode specified by the open mode parameter.
Read | Reads a record specified by the record number parameter.
Unlock | Unlocks a previously locked record specified by the record number parameter.
Write | Writes a record to the data file specified by the record number parameter.

Properties

SDOLinkedSubFile objects has the following properties:

Property | Description
Count | Returns the number of records in the current collection.
Fields | Returns the fields collection for the object.
FileType | Returns the type of the file, for example, SDORecord.
RecordNumber | Returns the RecordNumber of the current record.
CostCode | Returns the CostCode object of the current record. Note: Only applies to SplitData.
Project | Returns the Project object of the current record. Note: Only applies to SplitData.


SDOPosting Objects

Description

The SDOPosting object represents audit trail and stock transactions that can be posted to the data files.

Access the fields of a SDOPosting object via the Header property. Use the Items property of this object to access any sub items such as Splits, and add a new transaction to the data files by using the Update method once the fields have been filled in.

Objects

The following table lists all the SDOPosting objects:

Object | Description
StockPost | Create Stock Transaction
TransactionPost | Create Audit Trail Transaction

Methods

SDOPosting objects have the following methods:

Methods | Description
AllocatePayment | Allows two transactions (i.e. SI and SR) to be allocated to one another. Note: Applies only to the TransactionPost object.
CanBeAllocated | A boolean expression, True or False.
GetTaxReversalHeader
IsPostable | A boolean expression, True or False.
Update | Updates the transaction to the data files.

Properties

SDOPosting objects have the following properties:

Properties | Description
Header | Sets the header items for the transaction.
Items | Sets the individual item lines (splits) for the transaction.
PostingNumber | Returns the Header Record Number of the transaction posted. Note: Applies only to the TransactionPost object.


AllocatePayment Method

Description

The AllocatePayment method allocates an amount from an existing transaction of type Credit, Discount, Payment, or Payment On Account, against an outstanding existing transaction of type Invoice.

Syntax

The AllocatePayment method has the following syntax:

object.AllocatePayment(nInvoice as Long, nCredit as Long, dfAmount as Double, dDate as Date)

with the following parts:

Part | Description
Object | Applies to one of the following types: SDORecord, SDORecordLinked and SDOIspPost.
nInvoice | The record number of the invoice in Split.Dta
nCredit | The record number of the payment in Split.Dta
dfAmount | The amount to allocate against the invoice
dDate | The date of the allocation

Return Values

The AllocatePayment method returns the following values:

Return Value | Description
True | The allocation was successfully updated.
False | The allocation could not be updated as the parameters contained one or more invalid values.

Remarks

The allocation does not need to be for the complete value of the invoice, part allocations are allowed. The dfAmount can also be less than the total value of the credit resulting in a part allocation but it must not be more than the total credit value)

Examples

This example uses the AllocatePayment method to allocate a sales receipt and sales discount against a sales invoice.

  'Error Handler
  On Error GoTo Error_Handler

  'Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oTransactionPost As SageDataObject300.TransactionPost
  Dim oHeaderData As SageDataObject300.HeaderData
  Dim oSplitData As SageDataObject300.SplitData
  Dim oControlData As SageDataObject300.ControlData
  Dim oSalesRecord As SageDataObject300.SalesRecord
  Dim oNominalData As SageDataObject300.NominalData

  'Declare Variables
  Dim szDataPath As String
  Dim iCtr As Short
  Dim bFlag As Boolean
  Dim lInvoiceHeader As Integer
  Dim lReceiptHeader As Integer
  Dim lReceiptSplit As Integer
  Dim lDiscountHeader As Integer
  Dim lDiscountSplit As Integer
  Dim lTotalAmount As Double
  Dim lAmountLeft As Double

  'Create the SDO Engine Object
  oSDO = New SageDataObject300.SDOEngine()

  'Create the Workspace
  oWS = oSDO.Workspaces.Add("Example")

  'Select company. The SelectCompany method takes the program install
  'folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  'A U.I. for company selection is presented to the user. If a company is selected,
  'the path will be passed to the szDataPath variable.
  'If not, or the Cancel button is selected, the variable will be left empty.

  If szDataPath <> "" Then

    'Connect to Data Files
    oWS.Connect(szDataPath, "", "", "Example")

    'Create an Instance of Objects
    oTransactionPost = oWS.CreateObject("TransactionPost")
    oControlData = oWS.CreateObject("ControlData")
    oSalesRecord = oWS.CreateObject("SalesRecord")
    oNominalData = oWS.CreateObject("NominalData")

    'Read First Customer
    oSalesRecord.MoveFirst()

    'Populate Header fields
    oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
    oTransactionPost.Header("DATE").Value = CDate(Today)
    oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
    oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoSI)
    oTransactionPost.Header("DETAILS").Value = CStr("Sales Allocated Invoice")
    oTransactionPost.Header("INV_REF").Value = CStr("INV001")

    'Loop for number of splits
    For iCtr = 1 To 2

      'Create a split item by adding an empty split to the Items
      'collection of the TransactionPost Object.
      oSplitData = oTransactionPost.Items.Add()

      'Fill in the Split fields
      oSplitData.Fields.Item("TYPE").Value = CByte(SageDataObject300.TransType.sdoSI)
      oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("4000")
      oSplitData.Fields.Item("TAX_CODE").Value = CShort(1)
      oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(100)
      oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(17.5)
      oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)
      oSplitData.Fields.Item("DETAILS").Value = CStr(oTransactionPost.Header("DETAILS").Value)

    Next iCtr

    'Update the TransactionPost Object
    If oTransactionPost.Update Then

      'Store Header Record Number of Invoice just Posted
      lInvoiceHeader = oTransactionPost.PostingNumber

      'Destroy Objects
      oTransactionPost = Nothing
      oSplitData = Nothing

      ' *********************************
      'Now Post Sales Receipt

      'Create an instance of TransactionPost for the Sales Receipt
      oTransactionPost = oWS.CreateObject("TransactionPost")

      'Fill in the Header fields
      oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
      oTransactionPost.Header("DATE").Value = CDate(Today)
      oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
      oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoSR)
      oTransactionPost.Header("DETAILS").Value = CStr("Test Sales Receipt")
      oTransactionPost.Header("INV_REF").Value = CStr("PAY001")
      oTransactionPost.Header("BANK_CODE").Value = CStr("1200")

      'Create a split item by adding an empty split to the Items
      'collection of the TransactionPost Object.
      oSplitData = oTransactionPost.Items.Add()

      'Fill in the Split fields - note a Sales Receipt only has one split
      oSplitData.Fields.Item("TYPE").Value = CByte(SageDataObject300.TransType.sdoSR)
      oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("1200")
      oSplitData.Fields.Item("TAX_CODE").Value = CShort(9)
      oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(200)
      oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(0)
      oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)
      oSplitData.Fields.Item("DETAILS").Value = CStr(oTransactionPost.Header("DETAILS").Value)

    End If

    'Update the TransactionPost object
    If oTransactionPost.Update Then

      'Store Header Record Number of Receipt just Posted
      lReceiptHeader = oTransactionPost.PostingNumber

      'Destroy Objects
      oTransactionPost = Nothing
      oSplitData = Nothing

      ' *********************************
      'Now Post Sales Discount

      'Read Control Data
      'for Default discount Nominal Code
      oControlData.Read(1)

      'Now read Nominal using the default sales discount
      oNominalData.Read(CInt(oControlData.Fields.Item("SDISCOUNT_NO").Value))

      'Create an instance of TransactionPost for the Sales Receipt
      oTransactionPost = oWS.CreateObject("TransactionPost")

      'Fill in the Header fields
      oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
      oTransactionPost.Header("DATE").Value = CDate(Today)
      oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
      oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoSD)
      oTransactionPost.Header("DETAILS").Value = CStr("Sales Discount")
      oTransactionPost.Header("INV_REF").Value = CStr("BACS")

      'Create a split item by adding an empty split to the Items
      'collection of the TransactionPost Object.
      oSplitData = oTransactionPost.Items.Add()

      'Fill in the Split fields - note a Sales Discount only has one split
      oSplitData.Fields.Item("TYPE").Value = CByte(SageDataObject300.TransType.sdoSD)
      oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr(oNominalData.Fields.Item("ACCOUNT_REF").Value)
      oSplitData.Fields.Item("TAX_CODE").Value = CShort(9)
      oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(35)
      oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(0)
      oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)
      oSplitData.Fields.Item("DETAILS").Value = CStr(oTransactionPost.Header("DETAILS").Value)

    End If

    'Update the TransactionPost object
    If oTransactionPost.Update Then

      'Store Header record number of receipt just posted
      lDiscountHeader = oTransactionPost.PostingNumber

      'Destroy Split
      oSplitData = Nothing
      'The AllocatePayment function needs the split record number
      'so we will need to read the header first and then obtain
      'the splits from there

      'Create an instance of HeaderData
      oHeaderData = oWS.CreateObject("HeaderData")

      'Read HeaderData for Receipt
      oHeaderData.Read(lReceiptHeader)

      'Store Split Number for Receipt
      lReceiptSplit = CInt(oHeaderData.Fields.Item("FIRST_SPLIT").Value)

      'Read HeaderData for Discount
      oHeaderData.Read(lDiscountHeader)

      'Store Split Number for Discount
      lDiscountSplit = CInt(oHeaderData.Fields.Item("FIRST_SPLIT").Value)

      'Read HeaderData for Invoice
      oHeaderData.Read(lInvoiceHeader)

      'Link to Splits
      oSplitData = oHeaderData.Link

      'Move to First Split
      oSplitData.MoveFirst()

    End If

    'Allocate First Split to Receipt
    If oTransactionPost.AllocatePayment(CInt(oSplitData.RecordNumber), CInt(lReceiptSplit), CDbl(117.5), CDate(Today)) Then

      'Move to Next Split
      oSplitData.MoveNext()

      'Allocate Second Split to Remainder of Receipt
      oTransactionPost.AllocatePayment(CInt(oSplitData.RecordNumber), CInt(lReceiptSplit), CDbl(82.5), CDate(Today))

      'Allocate remainder of second split to discount
      oTransactionPost.AllocatePayment(CInt(oSplitData.RecordNumber), CInt(lDiscountSplit), CDbl(35), CDate(Today))

      MsgBox("Posting and Allocation has been Successful", MsgBoxStyle.OKOnly, "SDO Examples")

    Else

      MsgBox("Routine Failed", MsgBoxStyle.OKOnly, "SDO Examples")

    End If

    'Disconnect.
    oWS.Disconnect()

  End If

  oTransactionPost = Nothing
  oSplitData = Nothing
  oHeaderData = Nothing
  oControlData = Nothing
  oSalesRecord = Nothing
  oNominalData = Nothing
  oWS = Nothing
  oSDO = Nothing

  Exit Sub

'Error Handling Code
Error_Handler:

  MsgBox("The SDO generated the following error: " & oSDO.LastError.Text, MsgBoxStyle.OKOnly, "SDO Examples")

Related Topics

Properties and Methods | Description
AddNew | Clears a buffer so that a new entry can be added to the data files.
CancelUpdate | Cancels an AddNew or Edit.
Edit | Allows the editing of an existing record.


PostingNumber Property

Description

The PostingNumber property returns the record number of the Header posted via the TransactionPost object.

Syntax

The PostingNumber property has the following syntax:

object.PostingNumber

with the following parts:

Part | Description
Object | Applies to a SDOPosting object

Values

The PostingNumber property returns an integer value.

Examples Using this Method

Posting a Purchase Payment
Posting a BACS Purchase Payment


SDORecord Objects

Description

The SDORecord objects encapsulate the data and index files giving fast access to records. You would typically use the record objects when adding and editing existing records as use of the objects ensure that both the data and index files are updated. Where a record object exists, you should use it instead of the equivalent data object.

Objects

The following table lists all the SDORecord objects:

Object | Description
AssetRecord | Fixed Asset Register
BankRemittanceRecord | Remittances
CompanyDeliveryRecord | Company Delivery Addresses
ContactAccountIdxRecord | Contact Records (by Account Index)
ContactDateIdxRecord | Contact Records (by Date Index)
CountryCodeRecord | Country Codes
InvoiceRecord | Invoice Records
NominalRecord | Nominal Records
POPRecord | Purchase Order Records
PriceRecord | Product Price List Records
PriceListRecord | Customer Price List Records
PurchaseDeliveryRecord | Suppliers Delivery Addresses
PurchaseRecord | Supplier Records
RemittanceRecord | Cheque Remittances
SalesDeliveryRecord | Customer Delivery Addresses
SalesRecord | Customer Records
SOPRecord | Sales Order Records
StockRecord | Stock Records
ToDoRecord | Task Manager

Methods

The SDORecord objects have the following methods:

Method | Description
AddNew | The AddNew method clears a buffer so that a new entry can be added to the data files. Changes to the data files do not occur until a subsequent Update method has been issued.
CancelUpdate | The CancelUpdate method allows you to cancel a previous AddNew or Edit.
Edit | The Edit method allows you to change the values of an existing record. These changes are committed to the data files when the Update method is called.
Find | Enables a search to take place on the indexed field for a record that matches the specified criteria. The find can be exact or partial.
Move | Moves to a specified record in the collection.
MoveFirst | Moves to the first record in the collection.
MoveLast | Moves to the last record in the collection.
MoveNext | Moves to the next record in the collection.
MovePrev | Moves to the last record in the collection.
Remove | Removes the current record and will throw an exception if the record cannot be removed.
Update | The Update method commits changes to the data files. Depending on the object being used, the method will perform certain validation checks and will return False if the data in the fields collection of the object is invalid.

Properties

The SDORecord objects have the following properties:

Property | Description
Count | Returns the number of records in the collection.
Details | Returns/Sets the details on the ContactAccountIdxRecord and ContactDateIdxRecord objects.
Fields | Returns the fields collection for the object.
RecordNumber | Returns the RecordNumber of the current record.


AddNew Method

Description

The AddNew method clears a buffer so that a new entry can be added to the data files. Changes to the data files do not occur until a subsequent Update method has been issued.

Syntax

The AddNew method has the following syntax:

object.AddNew

with the following parts:

Part | Description
Object | Applies to one of the following types: SDORecord and SDORecordLinked

Return Value(s)

The AddNew method returns the following values:

Value | Description
True | The method was successful and the buffer cleared for the new entry.
False | The method was unsuccessful, a new record cannot be added. This could be caused by a network error or a lack of disk space for the new record.

Remarks

Following a call to AddNew, you must call either Update or CancelUpdate.

Examples

This example uses the AddNew method in conjunction with Update to create a new Customer Account.

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oSalesRecord As SageDataObject300.SalesRecord

  ' Declare Variables
  Dim szDataPath As String

  ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then
    ' Connect to Data Files
    oWS.Connect szDataPath, "", "", "Example"

    ' Create an Instance of the SalesRecord Object
    Set oSalesRecord = oWS.CreateObject("SalesRecord")

    ' Add a New Record
    If oSalesRecord.AddNew Then

      ' Populate Fields
      oSalesRecord.Fields.Item("ACCOUNT_REF").Value = CStr("0123")
      oSalesRecord.Fields.Item("NAME").Value = CStr("New SDO Account")
      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 & Wear")
      oSalesRecord.Fields.Item("ADDRESS_5").Value = CStr("NE13 9AA")
      oSalesRecord.Fields.Item("CONTACT_NAME").Value = CStr("Bill Beckett")
      oSalesRecord.Fields.Item("TELEPHONE").Value = CStr("0845 1117733")
      oSalesRecord.Fields.Item("FAX").Value = CStr("0845 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("")

      ' Update the Record
      If oSalesRecord.Update Then

        ' Update Successful
        MsgBox ("Account: " & oSalesRecord.Fields.Item("ACCOUNT_REF") & " successfully created.")

      Else

        ' Update Unsuccessful
        MsgBox ("Failed to Create Record.")

      End If

    End If

    ' Disconnect
    oWS.Disconnect

  End If

  ' Destroy Objects
  Set oSalesRecord = Nothing
  Set oWS = Nothing
   Set oSDO = Nothing

  Exit Sub

' Error Handling Code
 Error_Handler:
  MsgBox "The SDO generated the following error: " & oSDO.LastError.Text

Related Topics

Properties and Methods | Description
CancelUpdate | Cancels the AddNew method clearing the buffer.
Edit | Allows the editing of an existing record.
Update | Updates the current record to the data file.


CancelUpdate Method

Description

The CancelUpdate method allows you to cancel a previous AddNew or Edit.

Syntax

The CancelUpdate method has the following syntax:

object.CancelUpdate

with the following parts:

Part | Description
Object | Applies to one of the following types : SDORecord and SDORecordLinked

Return Value(s)

The method returns no values.

Remarks

Prior to calling CancelUpdate, you must have previously have called either AddNew or Edit.

Examples

This example uses the CancelUpdate method to cancel the adding of a Customer Account.

    '
  Set Data Path
Const szDataPath = "C:\ProgramData\Sage\Accounts\2024\accdata\"

' Declare Objects
Dim oSDO As
  SageDataObject300.SDOEngine
Dim oWS As
  SageDataObject300.WorkSpace
Dim oSalesRecord As
  SageDataObject300.SalesRecord

' Create the SDO Engine Object
Set oSDO =  New
  SageDataObject300.SDOEngine

' Create the Workspace
Set oWS = oSDO.Workspaces.Add("Example")

' Connect to Data Files
oWS.Connect szDataPath, "", "",
  "Example"

' Create an Instance of the SalesRecord Object
Set oSalesRecord = oWS.CreateObject("SalesRecord")

' Add a New Record
If oSalesRecord.AddNew Then

' Populate Fields
oSalesRecord("ACCOUNT_REF") = CStr("0123")
oSalesRecord("NAME") = CStr("New SDO Account")
oSalesRecord("ADDRESS_1") = CStr("Building
  5")
oSalesRecord("ADDRESS_2") = CStr("North
  Park")
oSalesRecord("ADDRESS_3") = CStr("Newcastle Upon Tyne")
oSalesRecord("ADDRESS_4") = CStr("Tyne & Wear")
oSalesRecord("ADDRESS_5") = CStr("NE13
  9AA")
oSalesRecord("CONTACT_NAME") = CStr("Audrey Hepburn")
oSalesRecord("TELEPHONE") = CStr("0845
  1117733")
oSalesRecord("FAX") = CStr("0845
  2450294")
oSalesRecord("ANALYSIS_1") = CStr("")
oSalesRecord("ANALYSIS_2") = CStr("")
oSalesRecord("ANALYSIS_3") = CStr("")
oSalesRecord("TERMS") = CStr("30 days")
oSalesRecord("DEF_NOM_CODE") = CStr("4000")
oSalesRecord("VAT_REG_NUMBER") = CStr("")

' Cancel the Update
oSalesRecord.CancelUpdate

End If

' Disconnect and Destroy the SDO Objects
oWS.Disconnect
Set oSalesRecord =  Nothing
Set oSDO =  Nothing
Set oWS =  Nothing

Related Topics

Properties and Methods | Description
AddNew | Clears a buffer so that a new entry can be added to the data files.
Edit | Allows the editing of an existing record.
Update | Updates the current record to the data file.


Edit Method

Description

The Edit method allows you to change the values of an existing record. These changes are committed to the data files when the Update method is called.

Syntax

The Edit method has the following syntax:

object.Edit

with the following parts:

Part | Description
Object | Applies to one of the following types : SDORecord and SDORecordLinked

Return Value(s)

The method returns the following values:

Return Value | Description
True | Record was successfully put in Edit mode.
False | The record could not be edited as it is currently locked either in Sage 50 Accounts or by the SDO.

Remarks

Following a call to Edit, you must call either Update or CancelUpdate.

Examples

This example uses the Edit method in conjunction with Update to change the name of a Customer account.

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oSalesRecord As SageDataObject300.SalesRecord

  ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Connect to Data Files
  oWS.Connect szDataPath, "", "", "Example"

  ' Create an Instance of the SalesRecord Object
  Set oSalesRecord = oWS.CreateObject("SalesRecord")

  ' Move to the First Record
  oSalesRecord.MoveFirst

  ' Edit the Record
  If oSalesRecord.Edit Then

    ' Edit Fields
    oSalesRecord.Fields.Item("NAME").Value = CStr("Edited Name")

    ' Update the Record
    If oSalesRecord.Update Then

      ' Update Successful
      MsgBox ("Account " & oSalesRecord.Fields.Item("ACCOUNT_REF").Value & " successfully edited.")

    Else

      ' Update Unsuccessful
      MsgBox ("The record could not be edited.")

    End If

  End If

  ' Disconnect and Destroy the SDO Objects
  oWS.Disconnect
  Set oSalesRecord = Nothing
  Set oSDO = Nothing
  Set oWS = Nothing

Related Topics

Properties and Methods | Description
AddNew | Updates the current record to the data file.
CancelUpdate | Cancels the AddNew.


Details Property

Description

The Details property returns the details for customer and supplier contact information.

Syntax

The Details property has the following syntax:

object.Details

with the following parts:

Part | Description
Object | Applies to only the following objects: ContactAccountIdxRecord and ContactDateIdxRecord.

Values

The Details property returns an integer value.

Remarks

None

Example

The following example uses the Details property to return the details on all contact records:

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oContactAccountIdxRecord As SageDataObject300.ContactAccountIdxRecord

  ' Declare Variables
  Dim szDataPath As String

   ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then
    ' Connect to Data Files
    oWS.Connect szDataPath, "", "", "Example"

    ' Create an Instance of the ContactAccountIdxRecord object
    Set oContactAccountIdxRecord = oWS.CreateObject("ContactAccountIdxRecord")

    ' Loop through the contacts showing the details
    If oContactAccountIdxRecord.MoveFirst Then

      Do
       MsgBox oContactAccountIdxRecord.Details, vbOKOnly, "SDO Examples"
      Loop Until Not oContactAccountIdxRecord.MoveNext

    Else

      MsgBox "There are no contact details.", vbOKOnly, "SDO Examples"

    End If

    ' Disconnect
    oWS.Disconnect

  End If

  ' Destroy Objects
  Set oContactAccountIdxRecord = Nothing
   Set oWS = Nothing
  Set oSDO = Nothing

  Exit Sub

' Error Handling Code
 Error_Handler:
  MsgBox "The SDO generated the following error: " & oSDO.LastError.Text


SDORecordLinked Objects

Description

The SDORecordLinked objects encapsulate the data and index files giving fast access to records. You would typically use the record objects when adding and editing existing records as use of the objects ensure that both the data and index files are updated. Where a record object exists, you should use it instead of the equivalent data object.

The objects also have a 'Link' method allowing fast access to the transactions relating to that record.

Objects

The following table lists all the SDORecordLinked objects:

Object | Description
BankRecord | Bank Account Records
InvoiceRecord | Invoice Records
NominalRecord | Nominal Ledger Records
POPRecord | Purchase Order Records
PurchaseRecord | Supplier Account Records
SalesRecord | Customer Account Records
SOPRecord | Sales Order Records
StockRecord | Stock Records

Methods

The SDORecordLinked objects have the following methods:

Method | Description
AddNew | The AddNew method clears a buffer so that a new entry can be added to the data files. Changes to the data files do not occur until a subsequent Update method has been issued.
CanRemove | Enables a check to see if the current record can be deleted.
CancelUpdate | The CancelUpdate method allows you to cancel a previous AddNew or Edit.
Edit | The Edit method allows you to change the values of an existing record. These changes are committed to the data files when the Update method is called.
Find | Enables a search to take place on the indexed field for a record that matches the specified criteria. The find can be exact or partial.
FindControlAccount | Finds the specified control account. (Applies only to the NominalRecord object)
GetAgedBalances | Returns an AgedBalances object. (Applies only to the SalesRecord And PurchaseRecord objects)
GetBudget | Returns a budget value for a nominal code for a specified period (Applies only to the NominalRecord object).
Link | Links the 'transactions' relating to the header. For example, on a NominalRecord, this will return a collection holding the transactions for the current Nominal Code.
Move | Moves to a specified record in the collection.
MoveFirst | Moves to the first record in the collection.
MoveLast | Moves to the last record in the collection.
MoveNext | Moves to the next record in the collection.
MovePrev | Moves to the previous record in the collection.
Remove | Removes the current record and will throw an exception if the record cannot be removed. Prior to calling the Remove method you can call the CanRemove method to see if the record can be deleted.
Update | The Update method commits changes to the data files. Depending on the object being used, the method will perform certain validation checks and will return False if the data in the fields collection of the object is invalid.

Properties

The SDORecordLinked objects have the following properties:

Property | Description
ControlType | Returns the type of a Nominal Code. (Applies only to the NominalRecord object)
Count | Returns the number of records in the collection.
CreditMemo | Returns the text of a Credit Memo.
Fields | Returns the fields collection for the object.
MajorControl | Returns a boolean depending on whether the Nominal Code is a Major Control Account. (Applies only the NominalRecord object)
Memo | Returns the text of a Memo.
RecordNumber | Returns the RecordNumber of the current record.


CanRemove Method

Description

The CanRemove method attempts to ascertain whether or you can physically delete the current record of an object from the data files.

Syntax

The CanRemove method has the following syntax:

object.CanRemove

with the following parts:

Part | Description
Object | Applies to one of the following types: SDOFile, SDOIndexFile, SDOLinkedFile and SDOLinkedSubFile.

Return Value(s)

The Remove method returns the following values:

Return Value | Description
True | The record could be removed.
False | The record could not be removed.

Remarks

The CanRemove method should be used in conjunction with the Remove method.

Deletion of records will fail for the same reasons as in Sage 50. For example, you cannot delete a customer account if there is an outstanding balance or the account has transactions in the audit trail.

Example

This example uses the CanRemove method to find out if we can delete the first record in the Sales Record object.

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oSalesRecord As SageDataObject300.SalesRecord

  ' Declare Variables
  Dim bFlag As Boolean
  Dim szDataPath As String
   ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then
    ' Connect to Data Files
    oWS.Connect szDataPath, "", "", "Example"

    ' Create an Instance of the SetupData object
    Set oSalesRecord = oWS.CreateObject("SalesRecord")

    ' Move to the first customer
    oSalesRecord.Movefirst

    ' Can we deleted the record ?
    bflag = oSalesRecord.CanRemove

    ' Disconnect
    oWS.Disconnect

  End If

  ' Destroy Objects
  Set oSetupData = Nothing
  Set oWS = Nothing
  Set oSDO = Nothing

  Exit Sub

' Error Handling Code
Error_Handler:

  Select Case oSdo.LastError.Code

    ' Record has transactions
    Case Is = sdoDeleteFailedHasTrans
      Msgbox "Delete Failed due to: " & oSDO.LastError.Text

    ' Deletion Failed
    Case Is = sdoDeleteFailed
      Msgbox "Delete Failed due to: " & oSDO.LastError.Text

  End Select


FindControlAccount Method

Description

The FindControlAccount method is used to find a record using an indexed field as the basis for the search.

Syntax

The FindControlAccount method has the following syntax:

object.FindcontrolAccount (Control account constant)

with the following parts:

Part | Description
Object | Applies to the one following type: SDOLinkedFile
Control Account constant | A constant value which refers to an Sdo control account type.

Return Value(s)

The method returns the following values:

Value | Description
True | A match was found for the search criteria.
False | No match was found for the search criteria.

Remarks

The FindControlAccount method is only available on the Nominal Record object.

If the FindControlAccount method returns true the nominal record object will be positioned to that nominal ledger account.

Examples

This example uses the FindControlAccount method to search for Debtors control account.

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oNominalRecord As SageDataObject300.NominalRecord

  ' Declare Variables
  Dim bFlag As Boolean
  Dim szDataPath As String

  ' Create the SDO Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then

    ' Connect to Data Files
    oWS.Connect szDataPath, "", "", "Example"

     ' Create nominal Record Object
    Set oNominalRecord = oWS.CreateObject("NominalRecord")

    ' Attempt to find the Debtors control account for this company
    If oNominalRecord.FindControlAccount(sdoNtDebtors) Then

      MsgBox CStr("The find has been successful. The object is postioned at " &  _    oNominalRecord.Fields.Item("ACCOUNT_REF"))

    End If

    ' Disconnect & Destroy Objects
    oWS.Disconnect

  End If

  ' Destroy Objects
  Set oNominalRecord = Nothing
  Set oWS = Nothing
  Set oSDO = Nothing

  Exit Sub

  ' Error Handling Code
  Error_Handler:
    MsgBox "The SDO generated the following error: " & oSDO.LastError.Text
  End Sub


GetAgedBalances Method

Description

The GetAgedBalances method is used to return an object of type AgedBalances.

Syntax

The GetAgedBalances method has the following syntax:

Record.GetAgedBalances

with the following parts:

Part | Description
Record | Either a SalesRecord or PurchaseRecord

Return Value(s)

The method returns the following values:

Value | Description
AgedBalances | An object of type SageDataObjectN.AgedBalances (N denotes SDO version e.g. 180)

Remarks

The AgedBalances method is only available on the Sales Record and Purchase Record objects.

Examples

This example uses the AgedBalances method for Sales Record "ABS001" to show the aged balances.

' Declare Objects
 Dim oSDO As SageDataObject300.SDOEngine
 Dim oWS As SageDataObject300.WorkSpace
 Dim oSalesRecord As SageDataObject300.SalesRecord
 Dim oAgedBalances As SageDataObject300.AgedBalances

 ' Declare Variables
 Dim szDataPath As String

 ' Error Handler
 Try
   ' Create the SDO Engine object
   oSDO = New SageDataObject300.SDOEngine

   ' Create the Workspace
   oWS = oSDO.Workspaces.Add("Example")

   ' Select company. The SelectCompany method takes the program install folder as a parameter
   szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

   ' A U.I. for company selection is presented to the user. If a company is selected,
   ' the path will be passed to the szDataPath variable.
   ' If not, or the Cancel button is selected, the variable will be left empty.
   If szDataPath <> "" Then
     ' Connect to Data Files
     If oWS.Connect(szDataPath, "", "", "Example") Then

       ' Get the sales ledger record
        oSalesRecord = oWS.CreateObject("SalesRecord")
       oSalesRecord.Fields.Item("ACCOUNT_REF").Value = "ABS001"

       ' Do an exact match search for the account
       If (oSalesRecord.Find(False)) Then

         ' Create the aged balances object
         oAgedBalances = oSalesRecord.GetAgedBalances()

         ' Set the date you wish to use to calculate the aged balances.
         oAgedBalances.SetAgedBalanceDate(CDate(Now))

         ' Set the date you wish to use to include payments up to.
         oAgedBalances.SetIncludePaymentDate(CDate(Now))

         ' Set the ageing type. This can be:
         ' sdoAgeByCalendarMonth - Ages by Calendar Month,
         ' sdoAgeByPeriod - Aged By Periods,
         ' sdoAgeByDay - Aged By Periods and first day of the month following the transaction date.
         ' Here we are ageing by Periods.
         oAgedBalances.SetAgedMode(SageDataObject300.TransactionAgeingType.sdoAgeByPeriod)

         ' If we are ageing by periods then we can specify the periods for this calculation.
         oAgedBalances.SetAgedPeriodStart(1, CInt(30))
         oAgedBalances.SetAgedPeriodStart(2, CInt(60))
         oAgedBalances.SetAgedPeriodStart(3, CInt(90))
         oAgedBalances.SetOlderAgedPeriod(CInt(160))

         ' Set whether you want to include transactions that are dated
         '  after the aged balance date in the customer's total balance.
         ' 0 - do not include.
         ' 1 - include.
         oAgedBalances.SetIncludeFuture(0)

         ' Calculate the aged balances
         oAgedBalances.Calculate()

         ' Get the Future, Current, Total and Older Balances
         Dim strFuture As String
         Dim strCurrent As String
         Dim strTotal As String
         Dim strPeriod As String
         Dim strOlder As String

         strFuture = CStr(oAgedBalances.GetFutureBalance())
         strCurrent = CStr(oAgedBalances.GetCurrentBalance())
         strTotal = CStr(oAgedBalances.GetTotalBalance())
         strOlder = CStr(oAgedBalances.GetOlderBalance)

         Dim strMessage As String
         Dim oItem As Object
         Dim iCount As Integer = 1

         strMessage = "Future balance : " + strFuture + vbCrLf _
         + "Current balance : " + strCurrent + vbCrLf _
         + "Total balance : " + strTotal + vbCrLf

         ' Loop through each of the period balances (3)
         For Each oItem In oAgedBalances

           strMessage += "Period" + CStr(iCount) + vbTab + CStr(oItem) + vbTab
           iCount += 1

         Next oItem

         strMessage += "Older" + vbTab + strOlder
         strMessage += vbCrLf

         MessageBox.Show(strMessage, "Aged Results for account " + oSalesRecord.Fields.Item("ACCOUNT_REF").Value, MessageBoxButtons.OK, MessageBoxIcon.Information)

       Else

         MessageBox.Show("The sales ledger account 'ABS001' cannot be found.", "SDO Error", MessageBoxButtons.OK, MessageBoxIcon.Error)

       End If
     Else

       MessageBox.Show( "Could not logon to the data.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

     End If

   End If

 Catch ex As Exception
   ' Error Handling Code
   MessageBox.Show("The SDO generated the following error: " & ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

  Finally

   If Not oSalesRecord Is Nothing Then
     oSalesRecord = Nothing
   End If

   If Not oAgedBalances Is Nothing Then
     oAgedBalances = Nothing
   End If

   If Not oWS Is Nothing Then
     oWS.Disconnect()
     oWS = Nothing
     oSDO = Nothing
   End If
 End Try


GetBudget Method

Description

The GetBudget method is used to return budget information for nominal codes (dependent on the value of the Budgeting_Type field on SetupData).

Syntax

The GetBudget method has the following syntax:

Object.GetBudget (Period as Short, nYear as Short) as Double

with the following parts:

Part | Description
Object | Applies to the following object: NominalRecord.
Period | Zero-based period number pertaining to the month in question (0-11)
nYear

The year in which the financial year started. If this is set to zero, the current financial year will be used.

Return Value(s)

The GetBudget method returns the following values:

Value | Description
Budget Amount | A value of type Double which corresponds to the budget total for the specified period.
Invalid Mode Exception | This exception is thrown if the GetBudget method is used when the BUDGETING_TYPE field on SetupData is set to sdoDepartment.

Examples Using This Method

Reading Nominal Budgets


ControlType Property

The ControlType property enables you to determine if a Nominal Code is a Sage 50 Accounts Control Account.

Syntax

The ControlType property has the following syntax:

object.ControlType

with the following parts:

Part | Description
Object | Applies only to NominalRecord

Return Value(s)

The property returns an integer relating to the constants detailed in the table below:

Constant | Value | Description
sdoNtNormal | 0 | Nominal Account (i.e. Not a Control or Bank Account)
sdoNtBank | 1 | Bank Account
sdoNtDebtors | 2 | Debtors Control Account
sdoNtCreditors | 3 | Creditors Control Account
sdoNtDefaultBank | 4 | Default Bank Account
sdoNtSalesTax | 5 | Sales Tax Control Account
sdoNtPurchaseTax | 6 | Purchase Tax Control Account
sdoNtSalesDiscount | 7 | Sales Discount
sdoNtPurchaseDiscount | 8 | Purchase Discount
sdoNtRetainedEarnings | 9 | Retained Earning
sdoNtDefaultSales | 10 | Default Sales Account
sdoNtAccruals | 11 | Accruals Account
sdoNtPrepayments | 12 | Prepayments Account
sdoNtBadDebts | 13 | Bad Debts Account
sdoNtMispostings | 14 | Mispostings Account
sdoNtSuspense | 15 | Suspense Account
sdoNtDefFinance | 16 | Credit Charge


CreditMemo Property

Description

Allows access to the CreditMemo data. This data is stored separately by Sage 50 Accounts in the memo directory with a file name that corresponds to the ledger in question.

Syntax

The CreditMemo property has the following syntax:

object.CreditMemo

with the following parts:

Part | Description
Object | Applies to the following type SDORecordLinked.

Values

The CreditMemo property returns a string value.

Example

The following example uses the CreditMemo property to change the memo on a customer record:

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oSalesRecord As SageDataObject300.SalesRecord

  ' Declare Variables
  Dim szDataPath As String

   ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then
    ' Connect to Data Files
    oWS.Connect szDataPath, "", "", "Example"

    ' Create an Instance of the SalesRecord object
    Set oSalesRecord = oWS.CreateObject("SalesRecord")

    ' Get the First Sales Record and show it's Memo
    oSalesRecord.MoveFirst
    MsgBox oSalesRecord.CreditMemo

    ' Get the next Sales Record and add a Memo to it
    oSalesRecord.MoveNext
    oSalesRecord.Edit
    oSalesRecord.CreditMemo = CStr("Credit Memo text for Second customer")

    ' Update the Record
    bFlag = oSalesRecord.Update

    If bFlag Then
      MsgBox "Update Successful."
    Else
      MsgBox "Update Unsuccessful."
    End If

    ' Disconnect
    oWS.Disconnect

  End If

  ' Destroy Objects
  Set oSalesRecord = Nothing
   Set oWS = Nothing
  Set oSDO = Nothing

  Exit Sub

' Error Handling Code
 Error_Handler:
  MsgBox "The SDO generated the following error: " & oSDO.LastError.Text


MajorControl Property

Description

The MajorControl property attempts to ascertain whether or you not the Nominal record you are currently positioned on is a control account.

Syntax`

The MajorControl property has the following syntax:

object.MajorControl

with the following parts:

Part | Description
Object | Applies to one of the following types: SDOFile, SDOIndexFile, SDOLinkedFile and SDOLinkedSubFile.

Return Value(s)

The MajorControl property returns the following values:

Return Value | Description
True | The record is a control account.
False | The record is not a control account.

Remarks

The MajorControl property is only available on the Nominal Record object.

Example

This example uses the MajorControl to find out if the nominal record we are positioned on is a control account.

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oSalesRecord As SageDataObject300.SalesRecord

  ' Declare Variables
  Dim bFlag As Boolean
  Dim szDataPath As String

   ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then

    ' Connect to Data Files
    oWS.Connect szDataPath, "", "", "Example"

    ' Create Sales Record Object
    Set oNominalRecord = oWS.CreateObject("NominalRecord")

    oNominalRecord.MoveFirst

    Do

      If oNominalRecord.MajorControl Then

        MsgBox CStr("This record " & oNominalRecord.Fields.Item("ACCOUNT_REF") & " is a control account.")

      End If

    Loop Until Not oNominalRecord.MoveNext

    ' Disconnect & Destroy Objects
    oWS.Disconnect

  End If

  ' Destroy Objects
  Set oNominalRecord = Nothing
  Set oWS = Nothing
  Set oSDO = Nothing

  Exit Sub

' Error Handling Code
Error_Handler:
  MsgBox "The SDO generated the following error: " & oSDO.LastError.Text
End Sub


Memo Property

Description

Allows access to the Memo data. This data is stored separately by Sage 50 Accounts in the memo directory with a file name that corresponds to the ledger in question.

Syntax

The Memo property has the following syntax:

object.Memo

with the following parts:

Part | Description
Object | Applies to the following type SDORecordLinked.

Values

The Memo property returns a string value.

Example

The following example uses the Memo property to change the memo on a customer record:

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oSalesRecord As SageDataObject300.SalesRecord

  ' Declare Variables
  Dim szDataPath As String

   ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then
    ' Connect to Data Files
    oWS.Connect szDataPath, "", "", "Example"

    ' Create an Instance of the SalesRecord object
    Set oSalesRecord = oWS.CreateObject("SalesRecord")

    ' Get the First Sales Record and show it's Memo
    oSalesRecord.MoveFirst
    MsgBox oSalesRecord.Memo

    ' Get the next Sales Record and add a Memo to it
    oSalesRecord.MoveNext
    oSalesRecord.Edit
    oSalesRecord.Memo = CStr("Memo text for Second customer")

    ' Update the Record
    bFlag = oSalesRecord.Update

    If bFlag Then
      MsgBox "Update Successful."
    Else
      MsgBox "Update Unsuccessful."
    End If

    ' Disconnect
    oWS.Disconnect

  End If

  ' Destroy Objects
  Set oSalesRecord = Nothing
   Set oWS = Nothing
  Set oSDO = Nothing

  Exit Sub

' Error Handling Code
 Error_Handler:
  MsgBox "The SDO generated the following error: " & oSDO.LastError.Text


Examples

This help file contains code examples for the following development environments:

Microsoft .NET (VB & C#)
Using SDO with the Microsoft Excel 2000 Object Model in VB 6
Using SDO with the Microsoft Outlook 2000 Object Model in VB 6
Using SDO with the Microsoft Word 2000 Object Model in VB 6


Examples - Considerations When Using C# .NET

If you are developing with SDO using C# then there are some differences from using Visual Basic that must be taken into account. The examples in this help file also make use of a Helper Class as described below.

Accessing Fields

If you require access to a field on a record in C# you need to pass a reference to an object containing the field name unlike Visual Basic where you would pass it a string. Examples of this can be seen below. In this help file all examples make use of a Helper Class to make this easier.

E.g.

Visual Basic / .Net

oSalesRecord.Fields.Item("ACCOUNT_REF").Value = "ABC"
oSalesRecord.Fields.Item("NAME").Value = "The Sage Group plc";
oSalesRecord.Fields.Item("CONTACT_NAME").Value = "Chris Reed";
oSalesRecord.Fields.Item("TELEPHONE").Value = "0845 1117733";

C#

object AccountRef = "ACCOUNT_REF";
object AccountName = "NAME";
object Contact_Name = "CONTACT_NAME";
object Telephone = "TELEPHONE";

oSalesRecord.Fields.Item(ref AccountRef).value = "ABC";
oSalesRecord.Fields.Item(ref AccountName).Value = "The Sage Group plc";
oSalesRecord.Fields.Item(ref Contact_Name).Value = "Chris Reed";
oSalesRecord.Fields.Item(ref Telephone).Value = "0845 1117733";

Type Casting & Accessing Header Data

C# is a strongly typed language and as such there are some differences from Visual Basic when using SDO. An Example of this is when you need to instantiate a record object.

E.g.

Visual Basic / .Net

oSalesRecord = oWorkSpace.CreateObject("SalesRecord")

C#

oSalesRecord = (SageDataObject300.SalesRecord)oWorkSpace.CreateObject("SalesRecord");

This also affects how you access the header property on certain SDO objects as it needs to be cast as 'Header Data' before you can access the fields. All examples in this help file make use of a Helper Class to make accessing header data easier.

E.g.

Visual Basic / .Net

oTransactionPost.Header("ACCOUNT_REF").value = "ABC001"

C#

Object ACCOUNT_REF = "ACCOUNT_REF";

((SageDataObject300.HeaderData)oTransactionPost.Header).Fields.Item

  (ref ACCOUNT_REF).Value = "ABC001";

The Items.Add() Method

When using a Posting object if you need to add to the items collection you need to use the Items.Add() method. This is not exposed via intellisense so in C# you need to use reflection to access it. As with the accessing fields section this is simplified by using a Helper Class for all examples in this help file.

E.g.

Visual Basic / .Net

oSplitData = oTransactionPost.Items.Add

C#

oSplitData = (SageDataObject300.SplitData)oTransactionPost.Items.GetType().InvokeMember

             ("Add", System.Reflection.BindingFlags.InvokeMethod, null, oTransactionPost.Items, null);

Data Paths

In C# the backslash character '\' is used as an escape character and results in hard coded data paths needing to be formatted differently. There are two solutions for this, firstly to enter a double backslash '\\' or secondly to enter the '@' symbol before the string to cause all escape characters to be ignored. All examples in this help file will use the double backslash solution.

E.g.

Visual Basic / .Net

szdatapath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024\")

C#

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

// OR

szDataPath = oSDO.SelectCompany(@"C:\ProgramData\Sage\Accounts\2024\");


Examples - The C# Helper Class

There are two main areas of the SDO which work differently when used in C# as opposed to Visual Basic as discussed in the C# Considerations page. For this reason all examples in this help file make use of a Helper Class 'SDOHelper' to make things simpler. This Class contains three methods (Write, Read, Add). The complete class is shown below, followed by examples of its use.

public static class SDOHelper

{

  /// <summary>

  /// Writes to an SDO field

  /// </summary>

  /// <param name="oObject">The object to write to</param>

  /// <param name="fname">Name of the required field</param>

  /// <param name="value">Value you wish to write</param>

  public static void Write(Object oObject, String fname, Object value)

  {

    //Stores the required field name in an object

    Object Field = fname;

    //Uses reflection to access the objects fields collection

    //then passes a reference to the field required, setting its value

    //to what is required

    ((SageDataObject300.Fields)oObject.GetType().InvokeMember

      ("Fields", System.Reflection.BindingFlags.GetProperty, null, oObject, null)).Item

      (ref Field).Value = value;

  }

  /// <summary>

  /// Reads and SDO field and returns its value as an object

  /// </summary>

  /// <param name="oObject">The object to read from</param>

  /// <param name="fname">Name of the required field</param>

  /// <returns>Returns an Object containing the value from the field</returns>

  public static Object Read(Object oObject, String fname)

  {

    //Stores the required field name in an object

    Object Field = fname;

    //Uses reflection to access the objects fields collection

    //then passes a reference to the field required, returning its value

    return ((SageDataObject300.Fields)oObject.GetType().InvokeMember

      ("Fields", System.Reflection.BindingFlags.GetProperty, null, oObject, null)).Item

      (ref Field).Value;

  }

  /// <summary>

  /// Invokes the Add() method of an items collection

  /// </summary>

  /// <param name="oObject">The items collection you wish to invoke the Add() method on</param>

  /// <returns></returns>

  public static Object Add(Object oObject)

  {

    //Uses reflection to invoke the Add() Method on the required object

    return oObject.GetType().InvokeMember

      ("Add", System.Reflection.BindingFlags.InvokeMethod, null, oObject, null);

  }

}

Accessing Fields Using The SDOHelper.Write() / SDOHelper.Read() Methods

If you need to access a field on a record using C# you need to pass it a reference to an object containing the Field name rather than a string, as you would in Visual Basic. The examples below demonstrates the difference between the two languages. The third example demonstrates the use of the Helper Class to make this process easier using the Write() method to write values to fields and the Read() method to read values from fields.

E.g.

Visual Basic / .Net

'Declare Variables

Dim oSDO As SageDataObject300.SDOEngine = New SageDataObject300.SDOEngine()

Dim oWS As SageDataObject300.WorkSpace

Dim oSalesRecord As SageDataObject300.SalesRecord

Dim szDataPath As String

'Instantiate WorkSpace

oWS = oSDO.Workspaces.Add("Example")

'Show select company dialog

szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024\")

'Try a connection, will throw an exception if it fails

Try

  'Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE")

  'Instantiate the SalesRecord object

  oSalesRecord = oWS.CreateObject("SalesRecord")

  'Add a new record

  oSalesRecord.AddNew()

  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 3")

  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("Chris Reed")

  oSalesRecord.Fields.Item("TELEPHONE").Value = CStr("0845 1117733")

  oSalesRecord.Fields.Item("FAX").Value = CStr("0845 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

    MessageBox.Show("Account " & oSalesRecord.Fields.Item("ACCOUNT_REF").Value _

    & " has been created successfully")

  Else

    MessageBox.Show("The account could not be created")

  End If

  'Disconnect

  oWS.Disconnect()

Catch ex As Exception

  MessageBox.Show(ex.Message, "An Error Occurred!")

End Try

C# - Without a Helper Class

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.SalesRecord oSalesRecord;

String szDataPath;

//Declare objects to contain Field Names

Object ACCOUNT_REF = "ACCOUNT_REF";

Object NAME = "NAME";

Object ADDRESS_1 = "ADDRESS_1";

Object ADDRESS_2 = "ADDRESS_2";

Object ADDRESS_3 = "ADDRESS_3";

Object ADDRESS_4 = "ADDRESS_4";

Object ADDRESS_5 = "ADDRESS_5";

Object CONTACT_NAME = "CONTACT_NAME";

Object TELEPHONE = "TELEPHONE";

Object FAX = "FAX";

Object ANALYSIS_1 = "ANALYSIS_1";

Object ANALYSIS_2 = "ANALYSIS_2";

Object ANALYSIS_3 = "ANALYSIS_3";

Object TERMS = "TERMS";

Object DEF_NOM_CODE = "DEF_NOM_CODE";

Object VAT_REG_NUMBER = "VAT_REG_NUMBER";

Object COUNTRY_CODE = "COUNTRY_CODE";

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate the SalesRecord object

  oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");

  //Add a new record

  oSalesRecord.AddNew();

  oSalesRecord.Fields.Item(ref ACCOUNT_REF).Value = (String)"SAGEGRP";

  oSalesRecord.Fields.Item(ref NAME).Value = (String)"The Sage Group plc";

  oSalesRecord.Fields.Item(ref ADDRESS_1).Value = (String)"Building 3";

  oSalesRecord.Fields.Item(ref ADDRESS_2).Value = (String)"North Park";

  oSalesRecord.Fields.Item(ref ADDRESS_3).Value = (String)"Newcastle Upon Tyne";

  oSalesRecord.Fields.Item(ref ADDRESS_4).Value = (String)"Tyne and Wear";

  oSalesRecord.Fields.Item(ref ADDRESS_5).Value = (String)"NE13 9AA";

  oSalesRecord.Fields.Item(ref CONTACT_NAME).Value = (String)"Chris Reed";

  oSalesRecord.Fields.Item(ref TELEPHONE).Value = (String)"0845 1117733";

  oSalesRecord.Fields.Item(ref FAX).Value = (String)"0845 2450294";

  oSalesRecord.Fields.Item(ref ANALYSIS_1).Value = (String)"";

  oSalesRecord.Fields.Item(ref ANALYSIS_2).Value = (String)"";

  oSalesRecord.Fields.Item(ref ANALYSIS_3).Value = (String)"";

  oSalesRecord.Fields.Item(ref TERMS).Value = (String)"30 Days";

  oSalesRecord.Fields.Item(ref DEF_NOM_CODE).Value = (String)"4000";

  oSalesRecord.Fields.Item(ref VAT_REG_NUMBER).Value = (String)"";

  oSalesRecord.Fields.Item(ref COUNTRY_CODE).Value = (String)"GB";

  //Update the record

  if (oSalesRecord.Update())

  {

    MessageBox.Show("Account " + oSalesRecord.Fields.Item

          (ref ACCOUNT_REF).Value +

          " has been created successfully");

  }

  else

  {

    MessageBox.Show("The account could not be created");

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}

C# - Using a Helper Class (all examples in this help file use this method)

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.SalesRecord oSalesRecord;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate the SalesRecord object

  oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");

  //Add a new record

  oSalesRecord.AddNew();

  SDOHelper.Write(oSalesRecord, "ACCOUNT_REF", (String)"SAGEGRP");

  SDOHelper.Write(oSalesRecord, "NAME", (String)"The Sage Group Plc.");

  SDOHelper.Write(oSalesRecord, "ADDRESS_1", (String)"The Sage Group Plc.");

  SDOHelper.Write(oSalesRecord, "ADDRESS_2", (String)"Building 3");

  SDOHelper.Write(oSalesRecord, "ADDRESS_3", (String)"North Park");

  SDOHelper.Write(oSalesRecord, "ADDRESS_4", (String)"Newcastle Upon Tyne");

  SDOHelper.Write(oSalesRecord, "ADDRESS_5", (String)"NE13 9AA");

  SDOHelper.Write(oSalesRecord, "CONTACT_NAME", (String)"Chris Reed");

  SDOHelper.Write(oSalesRecord, "TELEPHONE", (String)"0845 111 7733");

  SDOHelper.Write(oSalesRecord, "FAX", (String)"0845 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");

  }

  else

  {

    MessageBox.Show("The account could not be created");

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}

Accessing Header Data Using The SDOHelper.Write() Method

You can use the Write() method in the same way as you would to access an objects fields to access an objects 'Header Data' as shown below.

E.g.

C# - Without a Helper Class

Object ACCOUNT_REF = "ACCOUNT_REF";

((SageDataObject300.HeaderData)oTransactionPost.Header).Fields.Item

  (ref ACCOUNT_REF).Value = "ABC001";

C# - Using a Helper Class (all examples in this help file use this method)

SDOHelper.Write(oTransactionPost.Header , "ACCOUNT_REF", (String)"ABC001");

The Items.Add() Method

As described in the C# Considerations page if you wish to add an item to a posting objects Items collection you need to use reflection. This is simplified in this help file using the Helper Class. Instead of manually using reflection you can pass the items collection to the Add() method of the Helper Class and it will return the required item.

E.g.

C# - Without a Helper Class

oSplitData = (SageDataObject300.SplitData)oTransactionPost.Items.GetType().InvokeMember

                ("Add", System.Reflection.BindingFlags.InvokeMethod, null, oTransactionPost.Items, null);

C# - Using a Helper Class (all examples in this help file use this method)

oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);


Examples - The C# Helper Class

Examples - The Improved C# Helper Class

There are two main areas of the SDO which work differently when used in C# as opposed to Visual Basic as discussed in the C# Considerations page. For this reason all examples in this help file make use of a Helper Class 'SDOHelper' to make things simpler. This Class contains three methods (Write, Read, Add). The complete class is shown below, followed by examples of its use.

In addition to the above, the example also implements the System.Runtime.InteropServices namespace allowing the FinalReleaseComObject() method to be called from the Marshal class as the Garbage collector is not aware of the unmanaged resources (SDO) wrapped by the managed resource (.Net). See article Improving Memory Usage

public static class SDOHelper

{

/// <summary>

/// Writes to an SDO field

/// </summary>

/// <param name="oObject">The object to write to</param>

/// <param name="fname">Name of the required field</param>

/// <param name="value">Value you wish to write</param>

public static void Write(Object oObject, String fname, Object value)

{

//Stores the required field name in an object

Fields fields = GetFields(oObject);

Field field = GetField(fields, fname);

field.Value = value;

Marshal.FinalReleaseComObject(field);

Marshal.FinalReleaseComObject(fields);

}

/// <summary>

/// Reads and SDO field and returns its value as an object

/// </summary>

/// <param name="oObject">The object to read from</param>

/// <param name="fname">Name of the required field</param>

/// <returns>Returns an Object containing the value from the field</returns>

public static Object Read(Object oObject, String fname)

{

//Stores the required field name in an object

Fields fields = GetFields(oObject);

Field field = GetField(fields, fname);

Object value = field.Value;

Marshal.FinalReleaseComObject(field);

Marshal.FinalReleaseComObject(fields);

return value;

}

public static Field GetField(Fields fields, string fName)

{

Object fieldName = fName;

return fields.Item(ref fieldName);

}

public static Fields GetFields(Object oObject)

{

return (Fields)oObject.GetType().InvokeMember("Fields", System.Reflection.BindingFlags.GetProperty, null, oObject, null);

}

/// <summary>

/// Invokes the Add() method of an items collection

/// </summary>

/// <param name="oObject">The items collection you wish to invoke the Add() method on</param>

/// <returns></returns>

public static Object Add(Object oObject)

{

//Uses reflection to invoke the Add() Method on the required object

return oObject.GetType().InvokeMember("Add", System.Reflection.BindingFlags.InvokeMethod, null, oObject, null);

}

}

Accessing Fields Using The SDOHelper.Write() / SDOHelper.Read() Methods

If you need to access a field on a record using C# you need to pass it a reference to an object containing the Field name rather than a string, as you would in Visual Basic. The examples below demonstrates the difference between the two languages. The third example demonstrates the use of the Helper Class to make this process easier using the Write() method to write values to fields and the Read() method to read values from fields.

E.g.

Visual Basic / .Net

'Declare Variables

Dim oSDO As SageDataObject300.SDOEngine = New SageDataObject300.SDOEngine()

Dim oWS As SageDataObject300.WorkSpace

Dim oSalesRecord As SageDataObject300.SalesRecord

Dim szDataPath As String

'Instantiate WorkSpace

oWS = oSDO.Workspaces.Add("Example")

'Show select company dialog

szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024\")

'Try a connection, will throw an exception if it fails

Try

  'Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE")

  'Instantiate the SalesRecord object

  oSalesRecord = oWS.CreateObject("SalesRecord")

  'Add a new record

  oSalesRecord.AddNew()

  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 3")

  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("Chris Reed")

  oSalesRecord.Fields.Item("TELEPHONE").Value = CStr("0845 1117733")

  oSalesRecord.Fields.Item("FAX").Value = CStr("0845 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

    MessageBox.Show("Account " & oSalesRecord.Fields.Item("ACCOUNT_REF").Value _

    & " has been created successfully")

  Else

    MessageBox.Show("The account could not be created")

  End If

  'Disconnect

  oWS.Disconnect()

Catch ex As Exception

  MessageBox.Show(ex.Message, "An Error Occurred!")

End Try

C# - Without a Helper Class

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.Workspaces workspaces = oSDO.Workspaces;

SageDataObject300.SalesRecord oSalesRecord;

String szDataPath;

//Declare objects to contain Field Names

Object ACCOUNT_REF = "ACCOUNT_REF";

Object NAME = "NAME";

Object ADDRESS_1 = "ADDRESS_1";

Object ADDRESS_2 = "ADDRESS_2";

Object ADDRESS_3 = "ADDRESS_3";

Object ADDRESS_4 = "ADDRESS_4";

Object ADDRESS_5 = "ADDRESS_5";

Object CONTACT_NAME = "CONTACT_NAME";

Object TELEPHONE = "TELEPHONE";

Object FAX = "FAX";

Object ANALYSIS_1 = "ANALYSIS_1";

Object ANALYSIS_2 = "ANALYSIS_2";

Object ANALYSIS_3 = "ANALYSIS_3";

Object TERMS = "TERMS";

Object DEF_NOM_CODE = "DEF_NOM_CODE";

Object VAT_REG_NUMBER = "VAT_REG_NUMBER";

Object COUNTRY_CODE = "COUNTRY_CODE";

//Instantiate WorkSpace

SageDataObject300.WorkSpace oWS = workspaces.Add(_workspace) as WorkSpace;

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate the SalesRecord object

  oSalesRecord = oWS.CreateObject("SalesRecord") as SageDataObject300.SalesRecord;

  //Add a new record

  oSalesRecord.AddNew();

  oSalesRecord.Fields.Item(ref ACCOUNT_REF).Value = (String)"SAGEGRP";

  oSalesRecord.Fields.Item(ref NAME).Value = (String)"The Sage Group plc";

  oSalesRecord.Fields.Item(ref ADDRESS_1).Value = (String)"Building 3";

  oSalesRecord.Fields.Item(ref ADDRESS_2).Value = (String)"North Park";

  oSalesRecord.Fields.Item(ref ADDRESS_3).Value = (String)"Newcastle Upon Tyne";

  oSalesRecord.Fields.Item(ref ADDRESS_4).Value = (String)"Tyne and Wear";

  oSalesRecord.Fields.Item(ref ADDRESS_5).Value = (String)"NE13 9AA";

  oSalesRecord.Fields.Item(ref CONTACT_NAME).Value = (String)"Chris Reed";

  oSalesRecord.Fields.Item(ref TELEPHONE).Value = (String)"0845 1117733";

  oSalesRecord.Fields.Item(ref FAX).Value = (String)"0845 2450294";

  oSalesRecord.Fields.Item(ref ANALYSIS_1).Value = (String)"";

  oSalesRecord.Fields.Item(ref ANALYSIS_2).Value = (String)"";

  oSalesRecord.Fields.Item(ref ANALYSIS_3).Value = (String)"";

  oSalesRecord.Fields.Item(ref TERMS).Value = (String)"30 Days";

  oSalesRecord.Fields.Item(ref DEF_NOM_CODE).Value = (String)"4000";

  oSalesRecord.Fields.Item(ref VAT_REG_NUMBER).Value = (String)"";

  oSalesRecord.Fields.Item(ref COUNTRY_CODE).Value = (String)"GB";

  //Update the record

  if (oSalesRecord.Update())

  {

    MessageBox.Show("Account " + oSalesRecord.Fields.Item

          (ref ACCOUNT_REF).Value +

          " has been created successfully");

  }

  else

  {

    MessageBox.Show("The account could not be created");

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}

C# - Using a Helper Class (all examples in this help file use this method)

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.Workspaces workspaces = oSDO.Workspaces;

SageDataObject300.SalesRecord oSalesRecord;

String szDataPath;

//Instantiate WorkSpace

SageDataObject300.WorkSpace oWS = workspaces.Add(_workspace) as WorkSpace;

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate the SalesRecord object

  oSalesRecord = oWS.CreateObject("SalesRecord") as SageDataObject300.SalesRecord;

  //Add a new record

  oSalesRecord.AddNew();

  SDOHelper.Write(oSalesRecord, "ACCOUNT_REF", (String)"SAGEGRP");

  SDOHelper.Write(oSalesRecord, "NAME", (String)"The Sage Group Plc.");

  SDOHelper.Write(oSalesRecord, "ADDRESS_1", (String)"The Sage Group Plc.");

  SDOHelper.Write(oSalesRecord, "ADDRESS_2", (String)"Building 3");

  SDOHelper.Write(oSalesRecord, "ADDRESS_3", (String)"North Park");

  SDOHelper.Write(oSalesRecord, "ADDRESS_4", (String)"Newcastle Upon Tyne");

  SDOHelper.Write(oSalesRecord, "ADDRESS_5", (String)"NE13 9AA");

  SDOHelper.Write(oSalesRecord, "CONTACT_NAME", (String)"Chris Reed");

  SDOHelper.Write(oSalesRecord, "TELEPHONE", (String)"0845 111 7733");

  SDOHelper.Write(oSalesRecord, "FAX", (String)"0845 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");

  }

  else

  {

    MessageBox.Show("The account could not be created");

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}

Accessing Header Data Using The SDOHelper.Write() Method

You can use the Write() method in the same way as you would to access an objects fields to access an objects 'Header Data' as shown below.

E.g.

C# - Without a Helper Class

Object ACCOUNT_REF = "ACCOUNT_REF";

((SageDataObject300.HeaderData)oTransactionPost.Header).Fields.Item

  (ref ACCOUNT_REF).Value = "ABC001";

C# - Using a Helper Class (all examples in this help file use this method)

SDOHelper.Write(oTransactionPost.Header , "ACCOUNT_REF", (String)"ABC001");

The Items.Add() Method

As described in the C# Considerations page if you wish to add an item to a posting objects Items collection you need to use reflection. This is simplified in this help file using the Helper Class. Instead of manually using reflection you can pass the items collection to the Add() method of the Helper Class and it will return the required item.

E.g.

C# - Without a Helper Class

oSplitData = (SageDataObject300.SplitData)oTransactionPost.Items.GetType().InvokeMember

                ("Add", System.Reflection.BindingFlags.InvokeMethod, null, oTransactionPost.Items, null);

C# - Using a Helper Class (all examples in this help file use this method)

oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);


Sage 50 Accounts - Example - Add a new country code

Example - Add a new country code

The example code below demonstrates how to Add a new country code.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oCountryCodeRecord As SageDataObject300.CountryCodeRecord

'Error Handler
Try

    ' Declare Variables
    Dim szDataPath As String

    ' Create the SDOEngine Object
    oSDO = New SageDataObject300.SDOEngine

    ' Create the Workspace
    oWS = oSDO.Workspaces.Add("Example")

    ' Select Company. The SelectCompany method takes the program install
    ' folder as a parameter
    szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

    ' A U.I. for company selection is presented to the user. If a company is selected,
    ' the path will be passed to the szDataPath variable.
    ' If not, or the Cancel button is selected, the variable will be left empty.
    If szDataPath <> "" Then

        ' Try to Connect - Will Throw an Exception if it Fails
        If oWS.Connect(szDataPath, "", "", "Example") Then

            ' Create an Instance of the CountryCodeRecord Object
            oCountryCodeRecord = oWS.CreateObject("CountryCodeRecord")

            oCountryCodeRecord.MoveFirst()

            ' Try to Add a New Record
            If oCountryCodeRecord.AddNew Then

                oCountryCodeRecord.Fields.Item("COUNTRY_CODE").Value = CStr("KS")
                oCountryCodeRecord.Fields.Item("COUNTRY_NAME").Value = CStr("Kosovo")
                oCountryCodeRecord.Fields.Item("EU_MEMBER").Value = CStr("0")
                oCountryCodeRecord.Fields.Item("VAT_FORMAT_1").Value = CStr("")
                oCountryCodeRecord.Fields.Item("VAT_FORMAT_2").Value = CStr("")
                oCountryCodeRecord.Fields.Item("VAT_FORMAT_3").Value = CStr("")
                oCountryCodeRecord.Fields.Item("VAT_FORMAT_4").Value = CStr("")
                oCountryCodeRecord.Fields.Item("VAT_FORMAT_5").Value = CStr("")

                ' Update the Record
                If oCountryCodeRecord.Update Then

                    ' The Update was Successful
                    MsgBox("Account " & oCountryCodeRecord.Fields.Item("COUNTRY_CODE").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

            oWS.Disconnect()

        End If

    End If

Catch ex As Exception

    ' Error Handling Code
    MessageBox.Show("The SDO generated the following error: " & ex.Message, "SDO Examples", _
    MessageBoxButtons.OK, MessageBoxIcon.Error)

End Try

' Destroy Objects
oCountryCodeRecord = Nothing
oWS = Nothing
oSDO = Nothing
C#.NET [image] Copy C# Code
//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.CountryCodeRecord oCountryCodeRecord;

String szDataPath;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try
{

    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

    //Instantiate Country Code Record
    oCountryCodeRecord = (SageDataObject300.CountryCodeRecord)oWS.CreateObject("CountryCodeRecord");

    oCountryCodeRecord.MoveFirst();

    oCountryCodeRecord.AddNew();

        SDOHelper.Write(oCountryCodeRecord, "COUNTRY_CODE", (String)"KS");
        SDOHelper.Write(oCountryCodeRecord, "COUNTRY_NAME", (String)"Kosovo");
        SDOHelper.Write(oCountryCodeRecord, "EU_MEMBER", (String)"0");
        SDOHelper.Write(oCountryCodeRecord, "VAT_FORMAT_1", (String)"");
        SDOHelper.Write(oCountryCodeRecord, "VAT_FORMAT_2", (String)"");
        SDOHelper.Write(oCountryCodeRecord, "VAT_FORMAT_3", (String)"");
        SDOHelper.Write(oCountryCodeRecord, "VAT_FORMAT_4", (String)"");
        SDOHelper.Write(oCountryCodeRecord, "VAT_FORMAT_5", (String)"");

    //Update the new record
    if (oCountryCodeRecord.Update())
    {
        MessageBox.Show("The country code was created successfully");
    }
    else
    {
        MessageBox.Show("The creation of the country code Failed");
    }

    //Disconnect
    oWS.Disconnect();
}

catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}


Sage 50 Accounts - Example - Calculate total Straight Line Depreciation

Example - Calculate total Straight Line Depreciation

The example code below demonstrates how to calculate the total Straight Line Depreciation for all of your Assets that use this method of depreciation. The code is fired on a Form_Load but the form has no other function.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
Public Class Form1

    'declarations
    Dim oSDO As SageDataObject300.SDOEngine
    Dim oWS As SageDataObject300.WorkSpace
    Dim oAssetDta As SageDataObject300.AssetData

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        ' Declare Variables
        Dim szDataPath As String

        Try

            ' Create the SDO Engine object
            oSDO = New SageDataObject300.SDOEngine()

            ' Create the Workspace
            oWS = oSDO.Workspaces.Add("Example")

            ' Select company. The SelectCompany method takes the program install folder as a parameter
            szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

            ' A U.I. for company selection is presented to the user. If a company is selected,
            ' the path will be passed to the szDataPath variable.
            ' If not, or the Cancel button is selected, the variable will be left empty.
            If szDataPath <> "" Then

                ' Connect to Data Files
                If oWS.Connect(szDataPath, "", "", "Example") Then

                    ' user code
                    userDefinedMethod()

                End If

            End If

        Catch

            Select Case oSDO.LastError.Code

                ' 3rd Party Integration NOT Enabled - Site Activation
                Case Is = SageDataObject300.ErrorCode.sdoNotRegistered
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")

                    ' Invalid Password
                Case Is = SageDataObject300.ErrorCode.sdoLogonPassword
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")

                    ' User is Already Logged On
                Case Is = SageDataObject300.ErrorCode.sdoLogonNameInUse
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")

                    ' Line 50 is in Exclusive Mode i.e. File Maintenance
                Case Is = SageDataObject300.ErrorCode.sdoLogonExclusive
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")

                    ' Invalid Data Path on Connect
                Case Is = SageDataObject300.ErrorCode.sdoBadDataPath
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")

                    ' Line 50 is not Same Version as SDO
                Case Is = SageDataObject300.ErrorCode.sdoWrongVersion
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")

            End Select

        End Try

    End Sub

    Private Sub userDefinedMethod()

        Dim assetCount As Integer = 0
        Dim rate As Double = 0.0
        Dim totDep As Double = 0.0

        Try

            ' Create AssetCategory Object
            oAssetDta = oWS.CreateObject("AssetData")

            ' open AssetData for reading
            Me.oAssetDta.Open(SageDataObject300.OpenMode.sdoRead)

            For i As Integer = 1 To Me.oAssetDta.Count

                ' iterate through all assets
                Me.oAssetDta.Read(i)

                ' check to see if this asset is using Straight Line Depreciation
                If SageDataObject300.DepreciationType.sdoSDP Then

                    ' assign depreciation rate as a double
                    rate = CType(Me.oAssetDta.Fields.Item("DEP_RATE").Value, Double)

                    ' message box showing the rate of depreciation (formatted to currency)
                    MsgBox("Monthly depreciation for " & Me.oAssetDta.Fields.Item("ASSET_REF").Value & _
                    ControlChars.NewLine & rate.ToString("c"))

                    ' count how many assets use this method
                    assetCount += 1

                    ' add total amounts of depreciation to date
                    totDep += CType(Me.oAssetDta.Fields.Item("DEP_TO_DATE").Value, Double)

                End If

            Next

            ' message box showing total depreciation, to date, of all assets using straight line depreciation
            ' (formatted to currency)
            MsgBox(assetCount & " Assets use Straight Line Depreciation." & ControlChars.NewLine & _
            "Total depreciation to date via this method is: " & totDep.ToString("c"))

            oWS.Disconnect()

        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try

    End Sub

End Class
C#.NET [image] Copy C# Code
//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.AssetData  oAssetData;
Int32 assetCount = 0;
Double rate = 0.0;
Double totDep = 0.0;

String szDataPath;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try
{

    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

    //Instantiate the Assetdata object
    oAssetData = (SageDataObject300.AssetData)oWS.CreateObject("AssetData");

    for (int i = 1; i <= oAssetData.Count(); i++)
    {
     //iterate through all assets
        oAssetData.Read(i);

        //Open the record
        oAssetData.Open(SageDataObject300.OpenMode.sdoRead);

        //Retrieve the DEP_METHOD_CODE
        Int16 deptype = (Int16)SDOHelper.Read(oAssetData, "DEP_METHOD_CODE");

        //Check to see if uses Straight Line Depreciation
        if (deptype == 1)
        {
            //assign depreciation rate as a double
            rate = (Double)SDOHelper.Read(oAssetData, "DEP_RATE");

            //Messagebox showing the rate of depreciation (formattyed to currency)
            MessageBox.Show("Monthly depreciating for " + SDOHelper.Read(oAssetData, "ASSET_REF") + Environment.NewLine +
                rate.ToString("c"));

            //Count how manay assets use this method
            assetCount += 1;

            //Add total amounts of depreciation to date
            totDep += (Double)SDOHelper.Read(oAssetData, "DEP_TO_DATE");

        }
    }

    //MessageBox showing total depreciiation to date of all assets using straigth line depreciation
    //(Formatted to currency)
    MessageBox.Show(assetCount + " Assets use staright line depreciation." + Environment.NewLine +
        "Total depreciation to date via this method is " + totDep.ToString("C"));

    //Disconnect
    oWS.Disconnect();

}
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}


Sage 50 Accounts - Example - Is Valid FPosting Date

Example - How to check VAT Schemes

A company data set can be setup with one of four VAT Schemes in Sage 50 Accounts. Standard VAT, Cash Accounting, Flat Rate Standard and Flat Rate Cash.

ASK Sage Articles

26095 How to use the Flat Rate VAT scheme - Invoice Based - Sage 50 Accounts 2011 and above
26097 How to use the Flat Rate VAT scheme - Cash Based - Sage 50 Accounts 2011 and above
26282 A complete guide to VAT reconciliation - Vat Cash Accounting
26281 A complete guide to VAT reconciliation - Standard VAT

About Flat Rate VAT Schemes.

Businesses that use a flat rate scheme, apply a pre-defined percentage to their turnover for the relevant VAT period. The percentage is based on the type of business.

How to use the Flat Rate VAT Schemes

The Flat Rate VAT scheme (FRS) offers small businesses an alternative to the normal transaction based method of VAT accounting. Eligible businesses calculate VAT due as a percentage of their total turnover.

Who qualifies for the scheme
You are eligible to join the scheme if you expect your turnover in the next 12 months to be:

  • No more than £150,000 taxable supplies.
  • No more than £187,500 total business income.
  • Taxable supplies are the total of supplies at the standard, zero and reduced VAT rates, excluding VAT and the value of any capital assets you expect to sell.
  • Total business income includes your taxable supplies and the value of exempt and other non-taxable income.

For further information about who qualifies for the Flat Rate VAT Scheme, please refer to HMRC Notice 733, available from their website at http://www.hmrc.gov.uk

Exceptions for Capital Assets
Under the Flat Rate Scheme, the purchase of capital assets costing £2000 or more including VAT, where VAT is recovered, should be recorded with a T25 tax code. When such assets are sold, full VAT should be declared and therefore the T25 tax code should be used on the sale as well.

If VAT is not recovered on the purchase then the normal tax codes apply, for example T1 for a standard rated sale. For further information about the purchase and sale of capital assets under the Flat Rate VAT scheme, please refer to HMRC.

To use the Flat Rate Scheme - Invoice based

  • Day to day processing in Sage Accounts is unchanged when using the Flat Rate VAT Scheme - Invoice Based.
  • Transactions are entered as normal and the standard, reduced and zero VAT rates are applied depending upon which tax code you select for each transaction.
  • VAT figures are not reduced on a transactional basis, the recalculation for the Flat Rate is applied when you calculate your VAT Return at the end of your VAT period.

SetupData field values that determine the current VAT Scheme

Object Name | Field Name | Value(sdoTinyInt) | Vat Scheme
SetupData | VAT_CASH_FLAG | 0 | Standard
 | VAT_SCHEME_FLAG | 0
 | FLAT_RATE_VAT_PERCENT | -

Object Name | Field Name | Value (sdoTinyInt) | Vat Scheme
SetupData | VAT_CASH_FLAG | 1 | Cash
 | VAT_SCHEME_FLAG | 1
 | FLAT_RATE_VAT_PERCENT | -

Object Name | Field Name | Value (sdoTinyInt) | Vat Scheme
SetupData | VAT_CASH_FLAG | 2 | Flat Rate Invoice Based
 | VAT_SCHEME_FLAG | 2
 | FLAT_RATE_VAT_PERCENT | Flat Rate (sdoDouble)

Object Name | Field Name | Value (sdoTinyInt) | Vat Scheme
SetupData | VAT_CASH_FLAG | 3 | Flat Rate Cash Based
 | VAT_SCHEME_FLAG | 3
 | FLAT_RATE_VAT_PERCENT | Your Rate (sdoDouble)

Examples

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You would need to create a Windows Form application and add a button for the following code examples to work.

VB.NET [image] Copy VB Code

' Create an Enum for each of the Schemes (using the Flags attribute)

<Flags()> Public Enum eVatSchemes

  Standard = 0

  CashAccounting = 2

  FlatRateInvoiceBased = 4

  FlatRateCashBased = 6

End Enum

Public Class Form1

  Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    ' Declare Objects

    Dim oSDO As SageDataObject300.SDOEngine

    Dim oWS As SageDataObject300.WorkSpace

    Dim oSetupData As SageDataObject300.SetupData

    ' Declare Variables

    Dim szDataPath As String

    Dim iSplitCount As Short

    ' Create the SDO Engine Object

    oSDO = New SageDataObject300.SDOEngine

    ' Create the Workspace

    oWS = oSDO.Workspaces.Add("Example")

    ' Select Company. The SelectCompany method takes the program install

    ' folder as a parameter

    szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

    ' A U.I. for company selection is presented to the user. If a company is selected,

    ' the path will be passed to the szDataPath variable.

    ' If not, or the Cancel button is selected, the variable will be left empty.

    If szDataPath <> "" Then

      ' Try to Connect - Will throw an exception if it fails

      If oWS.Connect(szDataPath, "", "", "Example") Then

        ' Create Instances of Objects

        oSetupData = oWS.CreateObject("SetupData")

        ' Read the Setup Data Record

        oSetupData.Read(1)

        ' Add all the flags together to get the unique vat scheme value

        Dim eVatScheme As eVatSchemes = CSByte(oSetupData.Fields.Item("VAT_CASH_FLAG").Value) + _                                                                        CSByte(oSetupData.Fields.Item("VAT_SCHEME_FLAG").Value)

        ' Display the eVatSchems enum name in a message

        MessageBox.Show(eVatScheme.ToString())

        ' Disconnect

        oWS.Disconnect()

      End If

    End If

    ' Destroy Objects

    oSetupData = Nothing

    oWS = Nothing

    oSDO = Nothing

  End Sub

End Class

C#.NET [image] Copy C# Code

 // Create an Enum for each of the Schemes (using the Flags attribute)

[Flags()]

  public enum eVatSchemes

  {

    Standard = 0,

    CashAccounting = 2,

    FlatRateInvoiceBased = 4,

    FlatRateCashBased = 6

  }

  public partial class Form1 : Form

 {

    public Form1()

    {

      InitializeComponent();

    }

    private void button1_Click(object sender, EventArgs e)

   {

     // Declare Objects

      SageDataObject300.SDOEngine oSDO = default(SageDataObject300.SDOEngine);

      SageDataObject300.WorkSpace oWS = default(SageDataObject300.WorkSpace);

      SageDataObject300.SetupData oSetupData = default(SageDataObject300.SetupData);

      // Declare Variables

      string szDataPath = null;

      // Create the SDO Engine Object

      oSDO = new SageDataObject300.SDOEngine();

      // Create the Workspace

      oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

      // Select Company. The SelectCompany method takes the program install

      // folder as a parameter

      szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

      // A U.I. for company selection is presented to the user. If a company is selected,

      // the path will be passed to the szDataPath variable.

      // If not, or the Cancel button is selected, the variable will be left empty.

     if (!string.IsNullOrEmpty(szDataPath))

     {

       // Try to Connect - Will throw an exception if it fails

       if (oWS.Connect(szDataPath, "", "", "Example"))

       {

         // Create Instances of Objects

         oSetupData = (SageDataObject300.SetupData)oWS.CreateObject("SetupData");

          // Read the Setup Data Record

          oSetupData.Read(1);

          // Add all the flags together to get the unique vat scheme value

          eVatSchemes eVatScheme = (eVatSchemes)((SByte)SDOHelper.Read(oSetupData, "VAT_CASH_FLAG")) +  ((SByte)SDOHelper.Read(oSetupData, "VAT_SCHEME_FLAG"));

          // Display the eVatSchems enum name in a message

          MessageBox.Show(eVatScheme.ToString());

          // Disconnect

          oWS.Disconnect();

        }

      }

      // Destroy Objects

      oSetupData = null;

      oWS = null;

      oSDO = null;

    }

  }


Sage 50 Accounts - Example - Connecting and Disconnecting

Example - Connecting and Disconnecting

The example code below demonstrates how to Connect and Disconnect from the Sage 50 Accounts database.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace

' Declare Variables
Dim szDataPath As String

' Create the SDOEngine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

' Try to Connect - Will Throw an Exception if it Fails
If oWS.Connect(szDataPath, "", "", "Example") Then
MsgBox("Connection Established", MsgBoxStyle.OKOnly, "SDO Examples")

' Disconnect
oWS.Disconnect()

End If

End If

' Destroy the Objects
oWS = Nothing
oSDO = Nothing

Exit Sub

' Error Handling Code
Error_Handler:

Select Case oSDO.LastError.Code

' 3rd Party Integration NOT Enabled - Site Activation
Case Is = SageDataObject300.ErrorCode.sdoNotRegistered
MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OKOnly, "SDO Examples")

' Invalid Password
Case Is = SageDataObject300.ErrorCode.sdoLogonPassword
MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OKOnly, "SDO Examples")

' User is Already Logged On
Case Is = SageDataObject300.ErrorCode.sdoLogonNameInUse
MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OKOnly, "SDO Examples")

' Sage 50 Accounts is in Exclusive Mode i.e. File Maintenance
Case Is = SageDataObject300.ErrorCode.sdoLogonExclusive
MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OKOnly, "SDO Examples")

' Invalid Data Path on Connect
Case Is = SageDataObject300.ErrorCode.sdoBadDataPath
MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OKOnly, "SDO Examples")

' Sage 50 Accounts is not Same Version as SDO
Case Is = SageDataObject300.ErrorCode.sdoWrongVersion
MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OKOnly, "SDO Examples")

End Select
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  MessageBox.Show("Connected!");

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Creating a Company Delivery Address

Example - Creating a Company Delivery Address

The example code below demonstrates how to create a Company Delivery Address.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
                              ' Declare Objects
Dim oSDO  As
                              SageDataObject300.SDOEngine
Dim oWS  As
                              SageDataObject300.WorkSpace
Dim oCompanyDeliveryRecord  As
                              SageDataObject300.CompanyDeliveryRecord

' Declare Variables
Dim szDataPath, strRef, strAddNo As  String
Dim bFlag  As
                               Boolean
Dim iAddNo  As
                               Integer = 0

' Error Handler
On Error GoTo  Error_Handler

' Create the SDO Engine object
oSDO =  New   SageDataObject300.SDOEngine()

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> ""  Then

' Connect to Data Files
If oWS.Connect(szDataPath, "", "", "Example")
                              Then

' Create an Instance of the Company Object
oCompanyDeliveryRecord = oWS.CreateObject("CompanyDeliveryRecord")

' Move to Last Record in the delivery address file
oCompanyDeliveryRecord.MoveLast()

' Set the Reference
                                  String
strRef = CStr("COMPANY ")

' Increment the last value
iAddNo = CInt(oCompanyDeliveryRecord.Fields.Item("ADDRESS_REF").Value) + 1

' Convert to a string
strAddNo = CStr(iAddNo)

' Pad with leading zeroes
strAddNo = New String("0", 4 - Len(strAddNo)) & strAddNo
strRef = strRef & strAddNo

' Add New Delivery Address
oCompanyDeliveryRecord.AddNew()

' Pass New Reference
oCompanyDeliveryRecord.Fields.Item("REFERENCE").Value = CStr(strRef)
oCompanyDeliveryRecord.Fields.Item("ACCOUNT_REF").Value = CStr("COMPANY ")
oCompanyDeliveryRecord.Fields.Item("DESCRIPTION").Value = CStr("New Delivery Address")

' Address Ref equals the number of the delivery address minus the zeros
oCompanyDeliveryRecord.Fields.Item("ADDRESS_REF").Value = CInt(iAddNo)
oCompanyDeliveryRecord.Fields.Item("NAME").Value = CStr("New SDO Account")
oCompanyDeliveryRecord.Fields.Item("ADDRESS_1").Value = CStr("Building
                                5")
oCompanyDeliveryRecord.Fields.Item("ADDRESS_2").Value = CStr("North
                                Park")
oCompanyDeliveryRecord.Fields.Item("ADDRESS_3").Value = CStr("Newcastle Upon
                                Tyne")
oCompanyDeliveryRecord.Fields.Item("ADDRESS_4").Value = CStr("Tyne
                                and Wear")
oCompanyDeliveryRecord.Fields.Item("ADDRESS_5").Value = CStr("NE13
                                9aa")
oCompanyDeliveryRecord.Fields.Item("TELEPHONE").Value = CStr("0845
                                1117733")
oCompanyDeliveryRecord.Fields.Item("FAX").Value = CStr("0845
                                2450294")
oCompanyDeliveryRecord.Fields.Item("CONTACT_NAME").Value = CStr("Michael
                                Kenney")
oCompanyDeliveryRecord.Fields.Item("EMAIL").Value = CStr("sagesoft.developers@sage.com")
oCompanyDeliveryRecord.Fields.Item("TAX_CODE").Value = CInt(1)

' Update New Record
bFlag = oCompanyDeliveryRecord.Update
If bFlag  Then

MsgBox("Delivery address successfully added.", MsgBoxStyle.OKOnly, "SDO Examples")

Else

MsgBox("Delivery address update Unsuccessful.", MsgBoxStyle.OKOnly, "SDO Examples")

End If

' Disconnect
oWS.Disconnect()

End If

oCompanyDeliveryRecord =  Nothing
oWS =  Nothing
oSDO =  Nothing

End If

Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.CompanyDeliveryRecord oCompanyDeliveryRecord;

String strRef;

String strAddNo;

Int32 iAddNo;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate Delivery Record

  oCompanyDeliveryRecord = (SageDataObject300.CompanyDeliveryRecord)oWS.CreateObject("CompanyDeliveryRecord");

  //Move to the last record in the delivery address file

  oCompanyDeliveryRecord.MoveLast();

  //Set the Reference String

  strRef = "COMPANY ";

  //Increment the last value

  iAddNo = (Int16)SDOHelper.Read(oCompanyDeliveryRecord, "ADDRESS_REF") + 1;

  //Convert to a string

  strAddNo = Convert.ToString(iAddNo);

  //Pad with leading zeroes

  strAddNo = strAddNo.PadLeft(4, Convert.ToChar("0"));

  strRef += strAddNo;

  //Add a new delivery address record

  oCompanyDeliveryRecord.AddNew();

  //Pass the new reference

  SDOHelper.Write(oCompanyDeliveryRecord, "REFERENCE", (String)strRef);

  SDOHelper.Write(oCompanyDeliveryRecord, "ACCOUNT_REF", (String)"COMPANY ");

  SDOHelper.Write(oCompanyDeliveryRecord, "DESCRIPTION", (String)"New Delivery Address");

  //Address ref equals the number of the delivery address minus the zeros

  SDOHelper.Write(oCompanyDeliveryRecord, "ADDRESS_REF", (Int32)iAddNo);

  SDOHelper.Write(oCompanyDeliveryRecord, "NAME", (String)"New SDO Account");

  SDOHelper.Write(oCompanyDeliveryRecord, "ADDRESS_1", (String)"Building 3");

  SDOHelper.Write(oCompanyDeliveryRecord, "ADDRESS_2", (String)"North Park");

  SDOHelper.Write(oCompanyDeliveryRecord, "ADDRESS_3", (String)"Newcastle Upon Tyne");

  SDOHelper.Write(oCompanyDeliveryRecord, "ADDRESS_4", (String)"Tyne and Wear");

  SDOHelper.Write(oCompanyDeliveryRecord, "ADDRESS_5", (String)"NE13 9AA");

  SDOHelper.Write(oCompanyDeliveryRecord, "TELEPHONE", (String)"0845 111 7733");

  SDOHelper.Write(oCompanyDeliveryRecord, "FAX", (String)"0845 245 0294");

  SDOHelper.Write(oCompanyDeliveryRecord, "CONTACT_NAME", (String)"Chris Reed");

  SDOHelper.Write(oCompanyDeliveryRecord, "EMAIL", (String)"developers.programme@sage.com");

  SDOHelper.Write(oCompanyDeliveryRecord, "TAX_CODE", (Int32)1);

  //Update the new record

  if (oCompanyDeliveryRecord.Update())

  {

    MessageBox.Show("Delivery Address Update Successful");

  }

  else

  {

    MessageBox.Show("Delivery Address Update Failed");

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Find unpaid bills

Example - Find unpaid bills

The example code below demonstrates how to find and display unpaid bills by accessing the BillData object which is part of Sage 50 Accounts' Task Manager.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
Public Class Form1

    'Declare Objects
    Dim oSDO As SageDataObject300.SDOEngine
    Dim oWS As SageDataObject300.WorkSpace
    Dim oBills As SageDataObject300.BillData

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        ' Declare Variables
        Dim szDataPath As String

        Try

            ' Create the SDO Engine object
            oSDO = New SageDataObject300.SDOEngine

            ' Create the Workspace
            oWS = oSDO.Workspaces.Add("Example")

            ' Select company. The SelectCompany method takes the program install folder as a parameter
            szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

            ' A U.I. for company selection is presented to the user. If a company is selected,
            ' the path will be passed to the szDataPath variable.
            ' If not, or the Cancel button is selected, the variable will be left empty.
            If szDataPath <> "" Then

                ' Connect to Data Files
                If oWS.Connect(szDataPath, "", "", "Example") Then

                    ' user code
                    findUnpaidBills()

                End If

            End If

        Catch

            Select Case oSDO.LastError.Code

                ' 3rd Party Integration NOT Enabled - Site Activation
                Case Is = SageDataObject300.ErrorCode.sdoNotRegistered
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")

                    ' Invalid Password
                Case Is = SageDataObject300.ErrorCode.sdoLogonPassword
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")

                    ' User is Already Logged On
                Case Is = SageDataObject300.ErrorCode.sdoLogonNameInUse
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")

                    ' Line 50 is in Exclusive Mode i.e. File Maintenance
                Case Is = SageDataObject300.ErrorCode.sdoLogonExclusive
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")

                    ' Invalid Data Path on Connect
                Case Is = SageDataObject300.ErrorCode.sdoBadDataPath
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")

                    ' Line 50 is not Same Version as SDO
                Case Is = SageDataObject300.ErrorCode.sdoWrongVersion
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")

            End Select

        End Try

        oWS.Disconnect()

    End Sub

    Private Sub findUnpaidBills()

        ' instantiate BILLDATA object
        oBills = oWS.CreateObject("BILLDATA")

        ' get count of objects
        Dim billCount As Integer = oBills.Count()

        ' loop through all bill objects
        For i As Integer = 1 To billCount

            ' read specific item
            oBills.Read(i)

            ' determine if fully paid or not
            Dim fullyPaid As Double
            fullyPaid = CType((oBills.Fields.Item("NET_AMOUNT").Value + oBills.Fields.Item("TAX_AMOUNT").Value) - _
                        (oBills.Fields.Item("NET_PAID").Value + oBills.Fields.Item("TAX_PAID").Value), Double)

            ' if outstanding then display details
            If Not fullyPaid = 0.0 Then

                MsgBox(CStr(oBills.Fields.Item("ACCOUNT_REF").Value) & ControlChars.NewLine & _
                       CDate(oBills.Fields.Item("BILL_DATE").Value) & ControlChars.NewLine & _
                       CDate(oBills.Fields.Item("DATE_PAID").Value) & ControlChars.NewLine & _
                       CStr(oBills.Fields.Item("DETAILS").Value) & ControlChars.NewLine & _
                       "£" & CDbl(oBills.Fields.Item("NET_AMOUNT").Value) & ControlChars.NewLine & _
                       "£" & CDbl(oBills.Fields.Item("NET_PAID").Value) & ControlChars.NewLine & _
                       CDate(oBills.Fields.Item("PAY_BY_DATE").Value) & ControlChars.NewLine & _
                       CStr(oBills.Fields.Item("REFERENCE").Value) & ControlChars.NewLine & _
                       "£" & CDbl(oBills.Fields.Item("TAX_AMOUNT").Value) & ControlChars.NewLine & _
                       "T" & CByte(oBills.Fields.Item("TAX_CODE").Value) & ControlChars.NewLine & _
                       "£" & CDbl(oBills.Fields.Item("TAX_PAID").Value) & ControlChars.NewLine)
            End If

            oBills.Close()

        Next i

    End Sub

End Class
C#.NET [image] Copy C# Code
public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        SageDataObject300.BillData oBills;

        public Form1()
        {
            InitializeComponent();

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            String szDataPath;

            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // User code method
                findUnpaidBills();

                //Disconnect
                oWS.Disconnect();

            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        void findUnpaidBills()
        {
            // instantiate BillData Object
            oBills = (SageDataObject300.BillData)oWS.CreateObject("BillData");

            // iterate through the BillData records
            for (int i = 1; i <= oBills.Count(); i++)

                {

                //read specific item
                oBills.Read(i);

                //Check to see if this itereation has been paid in full or is still outstanding
                Double fullyPaid;
                fullyPaid = ((Double) SDOHelper.Read(oBills, "NET_AMOUNT") + (Double) SDOHelper.Read(oBills, "TAX_AMOUNT")) -
                   ((Double)SDOHelper.Read(oBills, "NET_PAID") + (Double)SDOHelper.Read(oBills, "TAX_PAID"));

                if (fullyPaid !=  0.0)

                {

                    //If no payment has been made against the bill yet, the DATE_PAID value will ne NULL and cannot
                    // be displayed in the message box, so if value is null convert to a string, else convert the
                    //PAID_DATE to a string.

                    String paidYet;
                    if (SDOHelper.Read(oBills, "DATE_PAID") == null)
                    {
                        paidYet = "No payment made yet";
                    }
                    else
                    {
                        DateTime datetostring;
                        datetostring = (DateTime)SDOHelper.Read(oBills, "DATE_PAID");
                        paidYet = datetostring.ToString("d");
                    }

                    //Use a MessageBox to display the details of the outstanding bill
                    MessageBox.Show("Account Reference: " + (String)SDOHelper.Read(oBills, "ACCOUNT_REF") + Environment.NewLine +
                        "Bill Date:  " + (DateTime)SDOHelper.Read(oBills, "BILL_DATE") + Environment.NewLine +
                    "Date Paid:  " + paidYet + Environment.NewLine +
                    "Details:  " + (String)SDOHelper.Read(oBills, "DETAILS") + Environment.NewLine +
                    "Net Amount: £ " + (Double)SDOHelper.Read(oBills, "NET_AMOUNT") + Environment.NewLine +
                    "Net Paid: £ " + (Double)SDOHelper.Read(oBills, "NET_PAID") + Environment.NewLine +
                    "Pay By Date: " + (DateTime)SDOHelper.Read(oBills, "PAY_BY_DATE") + Environment.NewLine +
                    "Reference: " + (String)SDOHelper.Read(oBills, "REFERENCE") + Environment.NewLine +
                    "Tax Amount: £ " + (Double)SDOHelper.Read(oBills, "TAX_AMOUNT") + Environment.NewLine +
                    "Tax Code: " + (Int16)SDOHelper.Read(oBills, "TAX_CODE") + Environment.NewLine +
                    "Tax Paid: £ " + (Double)SDOHelper.Read(oBills, "TAX_PAID") + Environment.NewLine);

                }
                oBills.Close();
                }

        }
    }


Sage 50 Accounts - Example - List Company names in a ComboBox

Example - List Company names in a ComboBox

The example code below demonstrates how to list your company names in a ComboBox.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
Public Class Form1

    Private oWS As SageDataObject300.WorkSpace
    Private oSDO As SageDataObject300.SDOEngine
    Private oCompany As SageDataObject300.Company
    Private oCompanies As SageDataObject300.Companies

    Dim szDataPath As String

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        Try

            ' Create the SDO Engine Object
            oSDO = New SageDataObject300.SDOEngine

            ' Create the Workspace
            oWS = oSDO.Workspaces.Add("Example")

            ' Set the path to the Sage 50 Accounts COMPANY file's parent directory
            ' there is no need to connect to a company in this example (in fact, doing so will throw an error
            szDataPath = "C:\ProgramData\Sage\Accounts\2024"

            ' populate the comboBox with our available companies

            ' clear the comboBox first
            Me.ComboBox1.Items.Clear()

            ' get the companies from the COMPANY file
            oCompanies = oSDO.GetCompanies(szDataPath)

            ' move through the companies assigning each one to a company object then display in a comboBox
            oCompany = oCompanies.MoveFirst()
            For i As Integer = 1 To oCompanies.Count

                Me.ComboBox1.Items.Add(CStr(oCompany.Name))
                oCompany = oCompanies.MoveNext

            Next

        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try

    End Sub

End Class
C#.NET [image] Copy C# Code

            //Declare Variables
            SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
            SageDataObject300.WorkSpace oWS;
            SageDataObject300.Company oCompany;
            SageDataObject300.Companies oCompanies;

            String szDataPath;

            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            oCompanies = (SageDataObject300.Companies)
            oSDO.GetCompanies("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Move to the first company
            oCompany = (SageDataObject300.Company)oCompanies.MoveFirst();
            this.CompanyNamesComboBox.Items.Clear();

            //Loop through remaining companies
            for (Int16 i = 1; i <= oCompanies.Count; i++)
            {
                //Add the current company name to the combo box
                //the move to the next company
                this.CompanyNamesComboBox.Items.Add(oCompany.Name);
                oCompany = (SageDataObject300.Company)oCompanies.MoveNext();
            }


Sage 50 Accounts - Example - List Credit Charge Data

Example - List Credit Charge Data

The example code below demonstrates how to list credit charge data.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oCreditChargeData As SageDataObject300.CreditChargeData

'Error Handler
Try

    ' Declare Variables
    Dim szDataPath As String

    ' Create the SDOEngine Object
    oSDO = New SageDataObject300.SDOEngine

    ' Create the Workspace
    oWS = oSDO.Workspaces.Add("Example")

    ' Select Company.  The SelectCompany method takes the program install
    ' folder as a parameter
    szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024\")

    ' A U.I. for company selection is presented to the user. If a company is selected,
    ' the path will be passed to the szDataPath variable.
    ' If not, or the Cancel button is selected, the variable will be left empty.
    If szDataPath <> "" Then

        ' Try to Connect - Will Throw an Exception if it Fails
        If oWS.Connect(szDataPath, "", "", "Example") Then

            oCreditChargeData = oWS.CreateObject("CreditChargeData")

            oCreditChargeData.Open(SageDataObject300.OpenMode.sdoRead)

            For i As Integer = 1 To oCreditChargeData.Count

                oCreditChargeData.Read(i)

                'Use a messagebox to display values
                MessageBox.Show(oCreditChargeData.Fields.Item("ADDITIONAL_RATE").Value & " " & _
                oCreditChargeData.Fields.Item("BASE_RATE").Value & " " & _
                oCreditChargeData.Fields.Item("DATE_FROM").Value & " " & _
                oCreditChargeData.Fields.Item("EMPTY").Value)

            Next

            oWS.Disconnect()

        End If

    End If

Catch ex As Exception

    ' Error Handling Code
    MessageBox.Show("The SDO generated the following error: " & ex.Message, "SDO Examples", _
    MessageBoxButtons.OK, MessageBoxIcon.Error)

End Try

'Destry Objects
oCreditChargeData = Nothing
oWS = Nothing
oSDO = Nothing
C#.NET [image] Copy C# Code
          //Declare Variables
          SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
          SageDataObject300.WorkSpace oWS;
          SageDataObject300.CreditChargeData oCreditChargeData;

          String szDataPath;

          // instantiate WorkSpace
          oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

          // show select company dialog
          szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

          // try a connection, will throw an exception if it fails
          try
          {
              // leaving the username and password blank generates a login dialog
              oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

              // create CourierWWWData Object
              oCreditChargeData = (SageDataObject300.CreditChargeData)oWS.CreateObject("CreditChargeData");

              // open the data file in READ mode
              oCreditChargeData.Open(SageDataObject300.OpenMode.sdoRead);

              for (int i = 1; i <= oCreditChargeData.Count(); i++)
              {
                  // read item at current position in loop
                  oCreditChargeData.Read(i);

                  MessageBox.Show((Double)SDOHelper.Read(oCreditChargeData, "ADDITIONAL_RATE") + Environment.NewLine +
                      (Double)SDOHelper.Read(oCreditChargeData, "BASE_RATE") + Environment.NewLine +
                      (DateTime)SDOHelper.Read(oCreditChargeData, "DATE_FROM") + Environment.NewLine +
                      (Int16)SDOHelper.Read(oCreditChargeData, "EMPTY"));
              }

          }
          catch (Exception ex)
          {
              MessageBox.Show(ex.Message.ToString(), "SDO Examples");
          }


Sage 50 Accounts - Example - Reading and Editing Department Names

Example - Reading and Editing Department Names

The example code below demonstrates how to Read and Edit Department Names.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oDepartmentData As SageDataObject300.DepartmentData

' Declare Variables
Dim szDataPath As String

' Create SDO Engine Object
oSDO = New SageDataObject300.SDOEngine

' Create Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

' Try to Connect - Will throw an exception if it fails
If oWS.Connect(szDataPath, "", "", "Example") Then

' Create Objects
oDepartmentData = oWS.CreateObject("DepartmentData")

' Read Record
' Note: The DepartmentData object has an offset of 1, therefore record 1 is department 0
' Record 2 is Department 1 etc.
 oDepartmentData.Read(2)

' Populate Fields
' NOTE : The 'DEPT_REF' field must be unqiue
 oDepartmentData.Fields.Item("DEPT_REF").Value = CStr("00000001")
 oDepartmentData.Fields.Item("NAME").Value = CStr("SDO Department 1")

' Write Record
' Note: The DepartmentData object has an offset of 1, therefore record 1 is department 0
' Record 2 is Department 1 etc.
oDepartmentData.Write(2)

' Display New Department Name
MsgBox("The department name for department 1 has been changed to '" & oDepartmentData.Fields.Item("NAME").Value & "'", MsgBoxStyle.OKOnly, "SDO Examples")

' Disconnect
oWS.Disconnect()

End If

End If

oDepartmentData = Nothing
oWS = Nothing
oSDO = Nothing

Exit Sub
C#.NET [image] Copy C# Code

// Declare Objects

SageDataObject300.SDOEngine oSDO;

SageDataObject300.WorkSpace oWS;

SageDataObject300.DepartmentData oDepartmentData;

// Create SDO Engine Object

oSDO = new SageDataObject300.SDOEngine();

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

string szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

// A U.I. for company selection is presented to the user. If a company is selected,

// the path will be passed to the szDataPath variable.

// If not, or the Cancel button is selected, the variable will be left empty.

if (szDataPath != "")

{

    // Try to Connect - Will throw an exception if it fails

    if (oWS.Connect(szDataPath, "", "", "Example"))

    {

        // Create Objects

        oDepartmentData = (SageDataObject300.DepartmentData)oWS.CreateObject("DepartmentData");

        // Read Record

        // Note: The DepartmentData object has an offset of 1, therefore record 1 is department 0

        // Record 2 is Department 1 etc.

        oDepartmentData.Read(2);

        // Populate Fields

        // NOTE : The 'DEPT_REF' field must be unqiue

        SDOHelper.Write(oDepartmentData, "DEPT_REF", (string)"00000001");

        SDOHelper.Write(oDepartmentData, "Name", (string)"SDO Department 1");

        // Write Record

        // Note: The DepartmentData object has an offset of 1, therefore record 1 is department 0

        // Record 2 is Department 1 etc.

        oDepartmentData.Write(2);

        // Display New Department Name

        MessageBox.Show("The department name for department 1 has been changed to '" + SDOHelper.Read(oDepartmentData, "Name"));

        // Disconnect

        oWS.Disconnect();

    }

}


Sage 50 Accounts - Example - Reading a User's Access Rights

Example - Reading a User's Access Rights

The example code below demonstrates how to read a User's Access Rights.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
                                ' Declare Objects
Dim oSDO  As
                              SageDataObject300.SDOEngine
Dim  oWS  As
                              SageDataObject300.WorkSpace
Dim oAccessData  As
                              SageDataObject300.AccessData

' Declare Variables
Dim szDataPath  As String
Dim szUserName  As String

' Create the SDOEngine Object
oSDO =  New   SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company.  The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> ""  Then

' Try to Connect - Will Throw an Exception if it Fails
If oWS.Connect(szDataPath, "", "", "Example")
                               Then

' Create Objects
oAccessData = oWS.CreateObject("AccessData")

' Set User Name to search for and pad to 32 characters
szUserName = "SDOUser*"

' Search for the
                                  Specified User Name
If oAccessData.FindFirst("NAME", szUserName)
                               Then

' Display User Name and Access Levels for Customers & Suppliers
MsgBox("Found User : " & oAccessData.Fields.Item("NAME").Value & vbCrLf & vbCrLf & "Customer Access = " & Convert.ToString(oAccessData.Fields.Item("CUSTOMERS").Value) & vbCrLf & "Supplier Access = " & Convert.ToString(oAccessData.Fields.Item("SUPPLIERS").Value), MsgBoxStyle.OKOnly, "SDO Examples")

Else

MsgBox("Specified user could not be found", MsgBoxStyle.OKOnly, "SDO Examples")

End If

' Disconnect
oWS.Disconnect()

End If

End If

' Destroy the Objects
oAccessData =  Nothing
oWS =  Nothing
oSDO =  Nothing

Exit Sub
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.AccessData oAccessData;

String szDataPath;
String szUserName;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails
try
{
    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

    //Instantiate the Access Data Object
    oAccessData = (SageDataObject300.AccessData)oWS.CreateObject("AccessData");

    //Set UserName to search for and pad to 32 characters
    szUserName = "SDOUser*";

    //Search for the Specified User Name
    if (oAccessData.FindFirst("NAME", szUserName))
    {
        //Display User Name and Access Levels for Customers & Suppliers
        MessageBox.Show("Found User " + SDOHelper.Read(oAccessData, "NAME") + Environment.NewLine +
            "Customer Access = " + SDOHelper.Read(oAccessData, "CUSTOMERS") + Environment.NewLine +
            "Supplier Access = " + SDOHelper.Read(oAccessData, "SUPPLIERS"), "SDO Examples");
    }
    else
    {
        MessageBox.Show("Not found");
    }

    //Disconnect
    oWS.Disconnect();
}
//Error handling
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}


Sage 50 Accounts - Example - Reading Tax Codes

Example - Reading Tax Codes

The example code below demonstrates how to Read and list the Tax Codes.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set.

This example relies on you creating a form with a ListView control (lvTaxCodes) on it.

VB.NET [image] Copy VB Code
                              ' Declare Objects
Dim  oSDO  As
                              SageDataObject300.SDOEngine
Dim  oWS  As
                              SageDataObject300.WorkSpace
Dim oControlData  As
                              SageDataObject300.ControlData
Dim oListItem  As ListViewItem

' Declare Variables
Dim szDataPath  As String
Dim  szFieldName  As String
Dim cLoopcount  As Byte

' Create the SDOEngine Object
oSDO =  New   SageDataObject300.SDOEngine()

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024\")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If  szDataPath <> ""  Then

' Try to Connect - Will Throw an Exception if it Fails
Try

If oWS.Connect(szDataPath, "", "", "Example")
                               Then

' Create an Instance of and Read the record for the ControlData object
' ControlData has only one record
oControlData = oWS.CreateObject("ControlData")
oControlData.Read(1)

' Loop through the Tax Codes and add Details to the List View
For cLoopcount = 0
                               To 99

oListItem =
                                lvTaxCodes.Items.Add(cLoopcount)

szFieldName = "T" & cLoopcount & "_DESCRIPTION"
oListItem.SubItems.Add(1)
oListItem.SubItems(1).Text = oControlData.Fields.Item(szFieldName).Value

szFieldName = "T" & cLoopcount & "_RATE"
oListItem.SubItems.Add(2)
oListItem.SubItems(2).Text = CStr(Format(oControlData.Fields.Item(szFieldName).Value, "##,##0.00"))

Next

' Disconnect
oWS.Disconnect()

End If

Catch

'  Connect has failed so report the exception
MsgBox("The SDO generated the following error: " & oSDO.LastError.Text, MsgBoxStyle.OKOnly, "SDO Examples")

End Try

End If

' Destroy Objects
oControlData =  Nothing
oWS =  Nothing
oSDO =  Nothing
C#.NET [image] Copy C# Code

//=========================================================

//Method assumes that you already have a list view

//on your form with three columns (Code, Description, Rate)

//=========================================================

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.ControlData oControlData;

String szDataPath;

Object szFieldName;

ListViewItem lv;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate and read the Control Data record

  oControlData = (SageDataObject300.ControlData)oWS.CreateObject("ControlData");

  oControlData.Read(1);

  //Loop through tax codes and add the details to a list view

  for (Int32 i = 0; i <= 99; i++)

  {

    //Instantiate the list view item

    lv = new ListViewItem();

    //Add the code to the list view item

    lv.Text = "T" + i;

    //Build the field name (DESCRIPTION) object and add this field to the list view item

    szFieldName = "T" + i + "_DESCRIPTION";

    lv.SubItems.Add((String)oControlData.Fields.Item(ref szFieldName).Value);

    //Build the field name (RATE) object and add this field to the list view item

    szFieldName = "T" + i + "_RATE";

    lv.SubItems.Add(Convert.ToString(oControlData.Fields.Item(ref szFieldName).Value));

    //Add the item to the listview

    this.listView1.Items.Add(lv);

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Reading Account Status Data

Example - Reading Account Status Data

The example code below demonstrates how to read account status data.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oAccStatDta As SageDataObject300.AccountStatusData

' Declare Variables
Dim szDataPath As String

' Create the SDOEngine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
Try

    If szDataPath <> "" Then

        ' Try to Connect - Will Throw an Exception if it Fails
        If oWS.Connect(szDataPath, "", "", "Example") Then

            ' Create AccountStatusData Object
            oAccStatDta = oWS.CreateObject("AccountStatusData")

            ' open the data file in READ mode
            oAccStatDta.Open(SageDataObject300.OpenMode.sdoRead)

            ' iterate through the items in the AccountStatusData object
            For i As Integer = 1 To oAccStatDta.Count

                ' read item at current position in loop
                oAccStatDta.Read(i)

                ' Use  messagebox to display the On_HOLD and STATUS values, may be easier to display in a listview
                MessageBox.Show(oAccStatDta.Fields.Item("ON_HOLD").Value & " " & _
                oAccStatDta.Fields.Item("STATUS").Value)

            Next

        End If

    End If

    'Error handling code
Catch ex As Exception

    MessageBox.Show("The SDO generated the following error: " & ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

End Try
' Destroy the Objects
oAccStatDta = Nothing
oWS = Nothing
oSDO = Nothing
C#.NET [image] Copy C# Code
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        SageDataObject300.AccountStatusData oAccStatDta;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            // show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            // try a connection, will throw an exception if it fails
            try
            {
                // leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        void userDefinedMethod()
        {
            try
            {
                // create AccountStatusData Object
                oAccStatDta = (SageDataObject300.AccountStatusData)oWS.CreateObject("AccountStatusData");

                // open the data file in READ mode
                oAccStatDta.Open(SageDataObject300.OpenMode.sdoRead);

                // iterate through the items in the AccountStatusData object
                for (int i = 1; i <= oAccStatDta.Count(); i++)
                {
                    // read item at current position in loop
                    oAccStatDta.Read(i);

                    // get the int equivalent of the ON_HOLD value and show respective info...
                    switch (Convert.ToInt32(SDOHelper.Read(oAccStatDta, "ON_HOLD")))
                    {
                        case 0:
                            MessageBox.Show("Account open" + " --- " + (String)SDOHelper.Read(oAccStatDta, "STATUS"));
                            break;
                        case 1:
                            MessageBox.Show("Account ON HOLD" + " --- " + (String)SDOHelper.Read(oAccStatDta, "STATUS"));
                            break;
                    }
                }

                // disconnect
                oWS.Disconnect();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Data could not be read.", "SDO Examples");
            }
        }


Sage 50 Accounts - Example - Reading Asset Category Data

Example - Reading Asset Category Data

The example code below demonstrates how to read Asset Category data.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oAssetCat As SageDataObject300.AssetCategory

' Declare Variables
Dim szDataPath As String

' Create the SDOEngine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
Try

    If szDataPath <> "" Then

        ' Try to Connect - Will Throw an Exception if it Fails
        If oWS.Connect(szDataPath, "", "", "Example") Then

            ' Create AssetCategory Object
            oAssetCat = oWS.CreateObject("AssetCategory")

            ' open the data file in READ mode
            oAssetCat.Open(SageDataObject300.OpenMode.sdoRead)

            ' iterate through the items in the AccountStatusData object
            For i As Integer = 1 To oAssetCat.Count

                ' read first item
                oAssetCat.Read(i)

                'use a messagebox to show the values
                MessageBox.Show(oAssetCat.Fields.Item("NAME").Value)

            Next

        End If

    End If

    'Error handling code
Catch ex As Exception

    MessageBox.Show("The SDO generated the following error: " & ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

End Try
' Destroy the Objects
oAssetCat = Nothing
oWS = Nothing
oSDO = Nothing
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
String szDataPath;
SageDataObject300.AssetCategory oAssetCat;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails
try
{
    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "Example");

    //Instantiate the Asset Category Data object
    oAssetCat = (SageDataObject300.AssetCategory)oWS.CreateObject("AssetCategory");

    //Loop through each department
    for (int i = 1; i <= oAssetCat.Count(); i++)
    {
        //Read the department and add to the combo box
        oAssetCat.Read(i);
        comboBox1.Items.Add(SDOHelper.Read(oAssetCat, "NAME"));
    }

    //Disconnect
    oWS.Disconnect();
}
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}


Sage 50 Accounts - Example - Reading CourierWWWData

Example - Reading CourierWWWData

The example code below demonstrates how to read CourierWWWData.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oCourierWWWData As SageDataObject300.CourierWWWData

'Error Handler
Try

    ' Declare Variables
    Dim szDataPath As String

    ' Create the SDOEngine Object
    oSDO = New SageDataObject300.SDOEngine

    ' Create the Workspace
    oWS = oSDO.Workspaces.Add("Example")

    ' Select Company.  The SelectCompany method takes the program install
    ' folder as a parameter
    szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024\")

    ' A U.I. for company selection is presented to the user. If a company is selected,
    ' the path will be passed to the szDataPath variable.
    ' If not, or the Cancel button is selected, the variable will be left empty.
    If szDataPath <> "" Then

        ' Try to Connect - Will Throw an Exception if it Fails
        If oWS.Connect(szDataPath, "", "", "Example") Then

            'Create an instance of the CourierWWWdata object
            oCourierWWWData = oWS.CreateObject("CourierWWWData")

            'Open the record
            oCourierWWWData.Open(SageDataObject300.OpenMode.sdoRead)

            'Start the loop
            For i As Integer = 1 To oCourierWWWData.Count

                'Read the record
                oCourierWWWData.Read(i)

                'Use a messagebox to display values
                MessageBox.Show(oCourierWWWData.Fields.Item("NAME").Value & " " & oCourierWWWData.Fields.Item("SEARCH").Value & " " & oCourierWWWData.Fields.Item("WWW").Value)

            Next

            'Disconnect
            oWS.Disconnect()

        End If

    End If

Catch ex As Exception

    ' Error Handling Code
    MessageBox.Show("The SDO generated the following error: " & ex.Message, "SDO Examples", _
    MessageBoxButtons.OK, MessageBoxIcon.Error)

End Try

'Destroy Objects
oCourierWWWData = Nothing
oSDO = Nothing
oWS = Nothing
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.CourierWWWData oCourierWWWData;

String szDataPath;

// instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

// show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

// try a connection, will throw an exception if it fails
try
{
    // leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

    // create CourierWWWData Object
    oCourierWWWData = (SageDataObject300.CourierWWWData)oWS.CreateObject("CourierWWWData");

    // open the data file in READ mode
    oCourierWWWData.Open(SageDataObject300.OpenMode.sdoRead);

    for (int i = 1; i <= oCourierWWWData.Count(); i++)
    {
        // read item at current position in loop
        oCourierWWWData.Read(i);

        MessageBox.Show((String)SDOHelper.Read(oCourierWWWData, "NAME") + Environment.NewLine +
            (String)SDOHelper.Read(oCourierWWWData, "SEARCH") + Environment.NewLine +
            (String)SDOHelper.Read(oCourierWWWData, "WWW"));
    }

}
catch (Exception ex)
{
    MessageBox.Show("Data could not be read.", "SDO Examples");
}


Sage 50 Accounts - Example - Reading which users are logged in

Example - Reading which users are logged in

The example code below demonstrates how to read which users are logged on.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim qDta As SageDataObject300.QueueData

' Declare Variables
Dim szDataPath As String

' Create the SDOEngine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company.  The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024\")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
Try

    If szDataPath <> "" Then

        ' Try to Connect - Will Throw an Exception if it Fails
        If oWS.Connect(szDataPath, "", "", "Example") Then

            qDta = oWS.CreateObject("QueueData")

            qDta.Open(SageDataObject300.OpenMode.sdoRead)

            For i As Integer = 1 To qDta.Count
                qDta.Read(i)
                MsgBox(qDta.Fields.Item("ACCOUNT_REF").Value & ControlChars.NewLine & _
                qDta.Fields.Item("LOGON_NAME").Value & ControlChars.NewLine & _
                qDta.Fields.Item("STATION_NAME").Value)
            Next

            qDta.Close()

            qDta = Nothing

        End If

    End If

Catch ex As Exception
    ' Connect has failed so report the exception
    MsgBox("The SDO generated the following error: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")
End Try
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.QueueData oQueueData;

String szDataPath;

// instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

// show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

// try a connection, will throw an exception if it fails
try
{
    // leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

    // create QueueData Object
    oQueueData = (SageDataObject300.QueueData)oWS.CreateObject("QueueData");

    // open the data file in READ mode
    oQueueData.Open(SageDataObject300.OpenMode.sdoRead);

    for (int i = 1; i <= oQueueData.Count(); i++)
    {
        // read item at current position in loop
        oQueueData.Read(i);

        MessageBox.Show((String)SDOHelper.Read(oQueueData, "ACCOUNT_REF") + Environment.NewLine +
            (String)SDOHelper.Read(oQueueData, "LOGON_NAME") + Environment.NewLine +
            (String)SDOHelper.Read(oQueueData, "STATION_NAME"));
    }
    oQueueData.Close();
    oQueueData = null;
}
catch (Exception ex)
{
    MessageBox.Show("Data could not be read.", "SDO Examples");
}


Sage 50 Accounts - Example - View incomplete TODORECORDS

Example - View incomplete TODORECORDS

The example code below demonstrates how to view incomplete to do records.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
'declarations
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oToDoRecord As SageDataObject300.ToDoRecord

' Declare Variables
Dim szDataPath As String

Try

    ' Create the SDO Engine object
    oSDO = New SageDataObject300.SDOEngine()

    ' Create the Workspace
    oWS = oSDO.Workspaces.Add("Example")

    ' Select company. The SelectCompany method takes the program install folder as a parameter
    szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

    ' A U.I. for company selection is presented to the user. If a company is selected,
    ' the path will be passed to the szDataPath variable.
    ' If not, or the Cancel button is selected, the variable will be left empty.
    If szDataPath <> "" Then

        ' Connect to Data Files
        If oWS.Connect(szDataPath, "", "", "Example") Then

            'Create instance of the TODORECORD
            oToDoRecord = oWS.CreateObject("TODORECORD")

            'Count the records
            Dim ToDoCount As Integer = oToDoRecord.Count()

            'Loop through the TODORECORD records
            For i As Integer = 1 To ToDoCount

                oToDoRecord.Move(i)

                'Identify which records are completed
                Dim completed As Byte
                completed = CType(oToDoRecord.Fields.Item("COMPLETED").Value, Byte)

                If Not completed = CByte(1) Then

                    MsgBox("Date completed: " & oToDoRecord.Fields.Item("Date").Value & ControlChars.NewLine & _
                           "Assigned to: " & oToDoRecord.Fields.Item("Delegated_To").Value & ControlChars.NewLine & _
                           "Detail: " & oToDoRecord.Fields.Item("Details").Value & ControlChars.NewLine & _
                           "ToDo project: " & oToDoRecord.Fields.Item("Project").Value)
                End If

            Next i

        End If

    End If

Catch ex As Exception

    MessageBox.Show("The SDO generated the following error: " & ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

End Try
C#.NET [image] Copy C# Code
//Declarations
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.ToDoRecord oToDoRecord;
String szDataPath;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try
    {
        //Leaving the username and password blank generates a login dialog
        oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

        //Create instance of the TODORECORED
        oToDoRecord = (SageDataObject300.ToDoRecord)oWS.CreateObject("ToDoRecord");

        //Count the Records
        Int32 ToDoCount = oToDoRecord.Count;

        //Loop through the TODORECORDS
        for (int i = 1; i < ToDoCount; i++)
        {
            oToDoRecord.Move(i);

            //Identify which records are completed
            Int16 oCompleted;
            oCompleted = (Int16)SDOHelper.Read(oToDoRecord, "COMPLETED");

            if (!(oCompleted == (byte)1))
            {

                MessageBox.Show("Date completed: " + SDOHelper.Read(oToDoRecord, "DATE")
                    + Environment.NewLine + "Assigned to: " + SDOHelper.Read(oToDoRecord, "DELEGATED_TO")
                    + Environment.NewLine + "Detail: " + SDOHelper.Read(oToDoRecord, "DETAILS")
                    + Environment.NewLine + "ToDo project: " + SDOHelper.Read(oToDoRecord, "PROJECT"));
            }
        }

        //Disconnect
        oWS.Disconnect();
    }
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}


Sage 50 Accounts - Example - Create a New Customer Address

Example - Create a New Customer Address

The example code below demonstrates how to create a new customer address.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
       'Declare Objects
       Dim oSDO As SageDataObject300.SDOEngine
       Dim oWS As SageDataObject300.WorkSpace
       Dim oCustomerAddress As SageDataObject300.CustomerAddress
       Dim oCustomerAddresses As SageDataObject300.CustomerAddresses
       Dim oSalesRecord As SageDataObject300.SalesRecord
       Dim oCountry As SageDataObject300.Country
       Dim oTaxCode As SageDataObject300.TaxCode

       ' Declare Variables
       Dim szDataPath As String
       Dim bflag As Boolean

       ' Create the SDO Engine object
       oSDO = New SageDataObject300.SDOEngine

       ' Create the workspace
       oWS = oSDO.Workspaces.Add("Example")

       Try

           ' Select company. The SelectCompany method takes the program install
           ' folder as a parameter
           szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

           ' A U.I. for company selection is presented to the user. If a company 'is selected,
           ' the path will be passed to the szDataPath variable.
           ' If not, or the Cancel button is selected, the variable will be left 'empty.
           If szDataPath <> "" Then

               ' Connect to Data Files
               If oWS.Connect(szDataPath, "", "", "Example") Then

                   ' Create Sales Record Object
                   oSalesRecord = oWS.CreateObject("SALESRECORD")

                   'We need to position ourselves at the correct SalesRecord using the Find method
                   ' Populate index field with value to search for
                   oSalesRecord.Fields.Item("ACCOUNT_REF").Value = CStr("AAAA")

                   ' Perform Exact match find
                   bflag = oSalesRecord.Find(False)

                   If bflag Then

                       MsgBox("The find has been successful, the object is positioned to " & _
                         oSalesRecord.Fields.Item("NAME").Value, vbOKOnly Or vbInformation, "SDO")

                   'Instantiate the objects
                   oCustomerAddress = oWS.CreateCustomerAddress
                   oCustomerAddresses = oWS.CreateCustomerAddresses
                   oCountry = oWS.CreateCountry
                   oTaxCode = oWS.CreateTaxCode

                   'Create a new Customer addresses for this SalesRecord by using
                   'Count to find the next reference number

                   Dim i As Integer
                   i = oCustomerAddresses.Count + 1
                   oCustomerAddress.Load(oSalesRecord.Fields.Item("ACCOUNT_REF").Value, i)

                   oCustomerAddress.AddressLine1 = "Sage UK LTD"
                   oCustomerAddress.AddressLine2 = "North Park"
                   oCustomerAddress.AddressLine3 = "Newcastle Upon Tyne"
                   oCustomerAddress.AddressLine4 = "Tyne And Wear"
                   oCustomerAddress.AddressLine5 = "NE13 9AA"

                   ' Store the SalesRecord Country Code
                   Dim strCountryCode As String

                   strCountryCode = oSalesRecord.Fields.Item("COUNTRY_CODE").Value

                   ' Load the Country object using the oSalesRecord COUNTRY_CODE value
                   If oCountry.Load(strCountryCode) Then

                       ' Set the Country object on the Address
                       oCustomerAddress.Country = oCountry

                   End If

                   oCustomerAddress.AddressType = SageDataObject300.AddressTypes.sdoContactAddress
                   'As we have selected to create a contact address we need to create a role
                   oCustomerAddress.Role = "Account Manager"
                   oCustomerAddress.Contact = "Pete Brown"
                   oCustomerAddress.Description = "Accounts dept"
                   oCustomerAddress.EMail = "Support@Sage.com"
                   oCustomerAddress.Fax = "0191123456"
                   oCustomerAddress.Name() = oSalesRecord.Fields.Item("ACCOUNT_REF").Value
                   oCustomerAddress.Notes = "Notes"
                   oCustomerAddress.Telephone = "0191654321"
                   oCustomerAddress.Telephone2 = "0191456789"

                   ' Load the TaxCode object using the index
                   If oTaxCode.Load(1) Then
                       ' Set the TaxtCode object on the Address
                       oCustomerAddress.TaxCode = oTaxCode
                   End If

                   oCustomerAddress.VatNumber = oSalesRecord.Fields.Item("VAT_REG_NUMBER").Value

                   If oCustomerAddress.Update() Then

                       MessageBox.Show("Customer Address Updated")

                   Else

                       MessageBox.Show("Unable to Update Customer Address")

                   End If

                   Else

                       MsgBox("The find has not found a match to your criteria", vbOKOnly Or vbInformation, "SDO")

                   End If

               Else
                   MessageBox.Show("Failed to connect!")

               End If

           End If

       Catch ex As Exception
           ' Error Handling Code
           MessageBox.Show("The SDO generated the following error: " & ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

       Finally

           ' Disconnect
           oWS.Disconnect()

           ' Destroy Objects
           oSalesRecord = Nothing
           oCustomerAddress = Nothing
           oWS = Nothing
           oSDO = Nothing
       End Try
C#.NET [image] Copy C# Code
//Declare Objects
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.CustomerAddress oCustomerAddress;
SageDataObject300.CustomerAddresses oCustomerAddresses;
SageDataObject300.SalesRecord oSalesRecord;
SageDataObject300.Country oCountry;
SageDataObject300.TaxCode oTaxCode;

//Declare variables
String szDataPath;
Boolean bFlag;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog, taking the path to the company file as a parameter
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//If the select company screen is cancelled a blank string is returned to szDataPath
if (szDataPath != string.Empty)
{

    //Try a connection, will throw an exception if it fails
    try
    {
        //Leaving the username and password blank generates a login dialog
        oWS.Connect(szDataPath, "", "", "Example");

        //Instantiate Sales Record Object
        oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");

        //Locate the SalesRecord to set the Customer object to.
        SDOHelper.Write(oSalesRecord, "ACCOUNT_REF", (String)"AAAA");

        //If the SalesRecord is found

        if (oSalesRecord.Find(false))
        {
            //Load the Customer place holder object by passing in the SalesRecord Account Ref

            MessageBox.Show("Customer has been located");

        }
        else if (oSalesRecord.Find(true))
        {
            MessageBox.Show("Customer could not be located");

        }

        //Instantiate the objects
        oCustomerAddress = (SageDataObject300.CustomerAddress)oWS.CreateCustomerAddress();
        oCustomerAddresses = (SageDataObject300.CustomerAddresses)oWS.CreateCustomerAddresses();
        oCountry = (SageDataObject300.Country)oWS.CreateCountry();
        oTaxCode = (SageDataObject300.TaxCode)oWS.CreateTaxCode();

        //Create a new Customer addresses for this SalesRecord by using
        //Count to find the next reference number

        int i;
        Object nextRef = oCustomerAddresses.Count + 1;
        Object customerAdd = SDOHelper.Read(oSalesRecord, "ACCOUNT_REF");
        oCustomerAddress.Load(ref customerAdd , ref nextRef);

        oCustomerAddress.AddressLine1 = "Sage UK LTD";
        oCustomerAddress.AddressLine2 = "North Park";
        oCustomerAddress.AddressLine3 = "Newcastle Upon Tyne";
        oCustomerAddress.AddressLine4 = "Tyne And Wear";
        oCustomerAddress.AddressLine5 = "NE13 9AA";

        //Store the SalesRecord country code
        Object strCountryCode;

        strCountryCode = SDOHelper.Read(oSalesRecord, "COUNTRY_CODE");

        //Load the Country object using the oSalesRecord COUNTRY_CODE value
        if (oCountry.Load(ref strCountryCode))
        {
            //Set the Country object on the Address
            oCustomerAddress.Country = oCountry;
        }

        oCustomerAddress.AddressType = SageDataObject300.AddressTypes.sdoContactAddress;
        //As we have selected to create a contact address we need to create a role
        oCustomerAddress.Role = "Account Manager";
        oCustomerAddress.Contact = "Pete Brown";
        oCustomerAddress.Description = "Accounts dept";
        oCustomerAddress.EMail = "Support@Sage.com";
        oCustomerAddress.Fax = "0191123456";
        oCustomerAddress.Name = SDOHelper.Read(oSalesRecord, "ACCOUNT_REF").ToString();
        oCustomerAddress.Notes = "Notes";
        oCustomerAddress.Telephone = "0191654321";
        oCustomerAddress.Telephone2 = "0191456789";

        //Load the TaxCode object using the index
        Object taxCodeRef = 1;
        if (oTaxCode.Load(ref taxCodeRef))
        {
            //Set the TaxtCode object on the Address
            oCustomerAddress.TaxCode = oTaxCode;
        }

        oCustomerAddress.VatNumber = SDOHelper.Read(oSalesRecord, "VAT_REG_NUMBER").ToString();

        //Try to update
        if (oCustomerAddress.Update())
        {
            MessageBox.Show("Customer Address Updated");
        }
        else
        {
            MessageBox.Show("Unable to Update Customer Address");
        }

    }
    catch (Exception ex)
    {
        MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
    }
    finally
    {

        //Disconnect
        oWS.Disconnect();

    }

}


Sage 50 Accounts - Example - Create a New Company Address

Example - Create a New Company Address

The example code below demonstrates how to create a new company address.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
        'Declare Objects
        Dim oSDO As SageDataObject300.SDOEngine
        Dim oWS As SageDataObject300.WorkSpace
        Dim oSetupData As SageDataObject300.SetupData
        Dim oCompanyAddress As SageDataObject300.CompanyAddress
        Dim oCompanyAddresses As SageDataObject300.CompanyAddresses
        Dim oCountry As SageDataObject300.Country

        ' Declare Variables
        Dim szDataPath As String

        ' Create the SDO Engine object
        oSDO = New SageDataObject300.SDOEngine

        ' Create the workspace
        oWS = oSDO.Workspaces.Add("Example")

        Try

            ' Select company. The SelectCompany method takes the program install
            ' folder as a parameter
            szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

            ' A U.I. for company selection is presented to the user. If a company 'is selected,
            ' the path will be passed to the szDataPath variable.
            ' If not, or the Cancel button is selected, the variable will be left 'empty.
            If szDataPath <> "" Then

                ' Connect to Data Files
                If oWS.Connect(szDataPath, "", "", "Example") Then

                    'Instantiate the objects
                    oCompanyAddress = oWS.CreateCompanyAddress
                    oCompanyAddresses = oWS.CreateCompanyAddresses
                    oCountry = oWS.CreateCountry
                    oSetupData = oWS.CreateObject("SetupData")

                    'Read SetupData
                    oSetupData.Read(1)

                    'Create a new Company addresses  by using
                    'Count to find the next reference number

                    Dim i As Integer
                    i = oCompanyAddresses.Count + 1
                    oCompanyAddress.Load(i)

                    oCompanyAddress.AddressLine1 = "Sage UK LTD"
                    oCompanyAddress.AddressLine2 = "North Park"
                    oCompanyAddress.AddressLine3 = "Newcastle Upon Tyne"
                    oCompanyAddress.AddressLine4 = "Tyne And Wear"
                    oCompanyAddress.AddressLine5 = "NE13 9AA"

                    ' Store the SsteupData Country Code
                    Dim strCountryCode As String

                    strCountryCode = oSetupData.Fields.Item("COUNTRY_CODE").Value

                    ' Load the Country object using the SetupData COUNTRY_CODE value
                    If oCountry.Load(strCountryCode) Then

                        ' Set the Country object on the Address
                        oCompanyAddress.Country = oCountry

                    End If

                    oCompanyAddress.AddressType = SageDataObject300.AddressTypes.sdoDeliveryAddress
                    oCompanyAddress.Contact = "Pete Brown"
                    oCompanyAddress.Description = "Accounts dept"
                    oCompanyAddress.EMail = "Support@Sage.com"
                    oCompanyAddress.Fax = "0191123456"
                    oCompanyAddress.Name = "Pete Brown"
                    oCompanyAddress.Notes = "Notes"
                    oCompanyAddress.Telephone = "0191654321"
                    oCompanyAddress.Telephone2 = "0191456789"

                    'Try to update
                    If oCompanyAddress.Update() Then

                        MessageBox.Show("Company Address Updated")

                    Else

                        MessageBox.Show("Unable to Update Company Address")

                    End If

                Else
                    MessageBox.Show("Failed to connect!")

                End If

            End If

        Catch ex As Exception
            ' Error Handling Code
            MessageBox.Show("The SDO generated the following error: " & ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

        Finally

            ' Disconnect
            oWS.Disconnect()

        End Try
C#.NET [image] Copy C# Code
//Declare Objects
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.CompanyAddress oCompanyAddress;
SageDataObject300.CompanyAddresses oCompanyAddresses;
SageDataObject300.SetupData oSetupData;
SageDataObject300.Country oCountry;

//Declare variables
String szDataPath;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog, taking the path to the company file as a parameter
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//If the select company screen is cancelled a blank string is returned to szDataPath
if (szDataPath != string.Empty)
{

    //Try a connection, will throw an exception if it fails
    try
    {
        //Leaving the username and password blank generates a login dialog
        oWS.Connect(szDataPath, "", "", "Example");

        //Instantiate Supplier Record Object
        oCompanyAddress = (SageDataObject300.CompanyAddress)oWS.CreateCompanyAddress();
        oCompanyAddresses = (SageDataObject300.CompanyAddresses)oWS.CreateCompanyAddresses();
        oCountry = (SageDataObject300.Country)oWS.CreateCountry();
        oSetupData = (SageDataObject300.SetupData)oWS.CreateObject("SetupData");

        //Read SetupData
        oSetupData.Read(1);

        //Create a new Supplier addresses for this PurchaseRecord by using
        //Count to find the next reference number

        Object i;
        i = oCompanyAddresses.Count + 1;
        oCompanyAddress.Load(ref i);

        oCompanyAddress.AddressLine1 = "Sage UK LTD";
        oCompanyAddress.AddressLine2 = "North Park";
        oCompanyAddress.AddressLine3 = "Newcastle Upon Tyne";
        oCompanyAddress.AddressLine4 = "Tyne And Wear";
        oCompanyAddress.AddressLine5 = "NE13 9AA";

        //Store the SetupData country code
        Object strCountryCode;

        strCountryCode = SDOHelper.Read(oSetupData, "COUNTRY_CODE");

        //Load the Country object using the SetupData COUNTRY_CODE value
        if (oCountry.Load(ref strCountryCode))
        {
            //Set the Country object on the Address
            oCompanyAddress.Country = oCountry;
        }

        oCompanyAddress.AddressType = SageDataObject300.AddressTypes.sdoDeliveryAddress;
        oCompanyAddress.Contact = "Pete Brown";
        oCompanyAddress.Description = "Accounts dept";
        oCompanyAddress.EMail = "Support@Sage.com";
        oCompanyAddress.Fax = "0191123456";
        oCompanyAddress.Name = SDOHelper.Read(oSetupData, "NAME").ToString();
        oCompanyAddress.Notes = "Notes";
        oCompanyAddress.Telephone = "0191654321";
        oCompanyAddress.Telephone2 = "0191456789";

        //Try to update
        if (oCompanyAddress.Update())
        {
            MessageBox.Show("Company Address Updated");
        }
        else
        {
            MessageBox.Show("Unable to Update Company Address");
        }

    }
    //Error Handling
    catch (Exception ex)
    {
        MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
    }
    finally
    {

        //Disconnect
        oWS.Disconnect();

    }
}


Sage 50 Accounts - Example - Create a New Supplier Address

Example - Create a New Supplier Address

The example code below demonstrates how to create a new supplier address.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
        'Declare Objects
        Dim oSDO As SageDataObject300.SDOEngine
        Dim oWS As SageDataObject300.WorkSpace
        Dim oSupplierAddress As SageDataObject300.SupplierAddress
        Dim oSupplierAddresses As SageDataObject300.SupplierAddresses
        Dim oPurchaseRecord As SageDataObject300.PurchaseRecord
        Dim oCountry As SageDataObject300.Country
        Dim oTaxCode As SageDataObject300.TaxCode

        ' Declare Variables
        Dim szDataPath As String
        Dim bflag As Boolean

        ' Create the SDO Engine object
        oSDO = New SageDataObject300.SDOEngine

        ' Create the workspace
        oWS = oSDO.Workspaces.Add("Example")

        Try

            ' Select company. The SelectCompany method takes the program install
            ' folder as a parameter
            szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

            ' A U.I. for company selection is presented to the user. If a company 'is selected,
            ' the path will be passed to the szDataPath variable.
            ' If not, or the Cancel button is selected, the variable will be left 'empty.
            If szDataPath <> "" Then

                ' Connect to Data Files
                If oWS.Connect(szDataPath, "", "", "Example") Then

                    ' Create Sales Record Object
                    oPurchaseRecord = oWS.CreateObject("PurchaseRecord")

                    'We need to position ourselves at the correct PurchaseRecord using the Find method
                    ' Populate index field with value to search for
                    oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value = CStr("SUPPLIER")

                    ' Perform Exact match find
                    bflag = oPurchaseRecord.Find(False)

                    If bflag Then

                        MsgBox("The find has been successful, the object is positioned to " & _
                          oPurchaseRecord.Fields.Item("NAME").Value, vbOKOnly Or vbInformation, "SDO")

                    Else

                        MsgBox("The find has not found a match to your criteria", vbOKOnly Or vbInformation, "SDO")

                    End If

                    'Instantiate the objects
                    oSupplierAddress = oWS.CreateSupplierAddress
                    oSupplierAddresses = oWS.CreateSupplierAddresses
                    oCountry = oWS.CreateCountry
                    oTaxCode = oWS.CreateTaxCode

                    'Create a new Supplier addresses for this PurchaseRecord by using
                    'Count to find the next reference number

                    Dim i As Integer
                    i = oSupplierAddresses.Count + 1
                    oSupplierAddress.Load(oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value, i)

                    oSupplierAddress.AddressLine1 = "Sage UK LTD"
                    oSupplierAddress.AddressLine2 = "North Park"
                    oSupplierAddress.AddressLine3 = "Newcastle Upon Tyne"
                    oSupplierAddress.AddressLine4 = "Tyne And Wear"
                    oSupplierAddress.AddressLine5 = "NE13 9AA"

                    ' Store the PurchaseRecord Country Code
                    Dim strCountryCode As String

                    strCountryCode = oPurchaseRecord.Fields.Item("COUNTRY_CODE").Value

                    ' Load the Country object using the oPurchaseRecord COUNTRY_CODE value
                    If oCountry.Load(strCountryCode) Then

                        ' Set the Country object on the Address
                        oSupplierAddress.Country = oCountry

                    End If

                    oSupplierAddress.AddressType = SageDataObject300.AddressTypes.sdoContactAddress
                    'As we have selected to create a contact address we need to create a role
                    oSupplierAddress.Role = "Account Manager"
                    oSupplierAddress.Contact = "Pete Brown"
                    oSupplierAddress.Description = "Accounts dept"
                    oSupplierAddress.EMail = "Support@Sage.com"
                    oSupplierAddress.Fax = "0191123456"
                    oSupplierAddress.Name() = oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value
                    oSupplierAddress.Notes = "Notes"
                    oSupplierAddress.Telephone = "0191654321"
                    oSupplierAddress.Telephone2 = "0191456789"

                    ' Load the TaxCode object using the index
                    If oTaxCode.Load(1) Then
                        ' Set the TaxCode object on the Address
                        oSupplierAddress.TaxCode = oTaxCode
                    End If

                    oSupplierAddress.VatNumber = oPurchaseRecord.Fields.Item("VAT_REG_NUMBER").Value

                    'Try to update
                    If oSupplierAddress.Update() Then

                        MessageBox.Show("Supplier Address Updated")

                    Else

                        MessageBox.Show("Unable to Update Supplier Address")

                    End If

                Else
                    MessageBox.Show("Failed to connect!")

                End If

            End If

        Catch ex As Exception
            ' Error Handling Code
            MessageBox.Show("The SDO generated the following error: " & ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

        Finally

            ' Disconnect
            oWS.Disconnect()

            ' Destroy Objects
            oPurchaseRecord = Nothing
            oSupplierAddress = Nothing
            oWS = Nothing
            oSDO = Nothing
        End Try
C#.NET [image] Copy C# Code
    //Declare Objects
    SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
    SageDataObject300.WorkSpace oWS;
    SageDataObject300.SupplierAddress oSupplierAddress;
    SageDataObject300.SupplierAddresses oSupplierAddresses;
    SageDataObject300.PurchaseRecord oPurchaseRecord;
    SageDataObject300.Country oCountry;
    SageDataObject300.TaxCode oTaxCode;

    //Declare variables
    String szDataPath;
    Boolean bFlag;

    //Instantiate WorkSpace
    oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

    //Show select company dialog, taking the path to the company file as a parameter
    szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

    //If the select company screen is cancelled a blank string is returned to szDataPath
    if (szDataPath != string.Empty)
    {

        //Try a connection, will throw an exception if it fails
        try
        {
            //Leaving the username and password blank generates a login dialog
            oWS.Connect(szDataPath, "", "", "Example");

            //Instantiate Supplier Record Object
            oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");

            //Locate the PurchaseRecord to set the Supplier object to.
            SDOHelper.Write(oPurchaseRecord, "ACCOUNT_REF", (String)"SUPPLIER");

            //If the PurchaseRecord is found

            if (oPurchaseRecord.Find(false))
            {
                //Load the Supplier place holder object by passing in the PurchaseRecord Account Ref

                MessageBox.Show("Supplier has been located");

            }
            else if (oPurchaseRecord.Find(true))
            {
                MessageBox.Show("Supplier could not be located");

            }

            //Instantiate the objects
            oSupplierAddress = (SageDataObject300.SupplierAddress)oWS.CreateSupplierAddress();
            oSupplierAddresses = (SageDataObject300.SupplierAddresses)oWS.CreateSupplierAddresses();
            oCountry = (SageDataObject300.Country)oWS.CreateCountry();
            oTaxCode = (SageDataObject300.TaxCode)oWS.CreateTaxCode();

            //Create a new Supplier addresses for this PurchaseRecord by using
            //Count to find the next reference number

            int i;
            Object nextRef = oSupplierAddresses.Count + 1;
            Object SupplierAdd = SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF");
            oSupplierAddress.Load(ref SupplierAdd, ref nextRef);

            oSupplierAddress.AddressLine1 = "Sage UK LTD";
            oSupplierAddress.AddressLine2 = "North Park";
            oSupplierAddress.AddressLine3 = "Newcastle Upon Tyne";
            oSupplierAddress.AddressLine4 = "Tyne And Wear";
            oSupplierAddress.AddressLine5 = "NE13 9AA";

            //Store the PurchaseRecord country code
            Object strCountryCode;

            strCountryCode = SDOHelper.Read(oPurchaseRecord, "COUNTRY_CODE");

            //Load the Country object using the oPurchaseRecord COUNTRY_CODE value
            if (oCountry.Load(ref strCountryCode))
            {
                //Set the Country object on the Address
                oSupplierAddress.Country = oCountry;
            }

            oSupplierAddress.AddressType = SageDataObject300.AddressTypes.sdoContactAddress;
            //As we have selected to create a contact address we need to create a role
            oSupplierAddress.Role = "Account Manager";
            oSupplierAddress.Contact = "Pete Brown";
            oSupplierAddress.Description = "Accounts dept";
            oSupplierAddress.EMail = "Support@Sage.com";
            oSupplierAddress.Fax = "0191123456";
            oSupplierAddress.Name = SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF").ToString();
            oSupplierAddress.Notes = "Notes";
            oSupplierAddress.Telephone = "0191654321";
            oSupplierAddress.Telephone2 = "0191456789";

            //Load the TaxCode object using the index
            Object taxCodeRef = 1;
            if (oTaxCode.Load(ref taxCodeRef))
            {
                //Set the TaxtCode object on the Address
                oSupplierAddress.TaxCode = oTaxCode;
            }

            oSupplierAddress.VatNumber = SDOHelper.Read(oPurchaseRecord, "VAT_REG_NUMBER").ToString();

            //Try to update
            if (oSupplierAddress.Update())
            {
                MessageBox.Show("Supplier Address Updated");
            }
            else
            {
                MessageBox.Show("Unable to Update Supplier Address");
            }

        }
        catch (Exception ex)
        {
            MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
        }
        finally
        {

            //Disconnect
            oWS.Disconnect();

        }

    }

}


Sage 50 Accounts - Example - Edit a Customer Address

Example - Edit a Customer Address

The example code below demonstrates how to edit a Customer Address.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code

        Dim oSDO As SageDataObject300.SDOEngine
        Dim oWS As SageDataObject300.WorkSpace
        Dim oCustomerAddress As SageDataObject300.CustomerAddress
        Dim oCustomerAddresses As SageDataObject300.CustomerAddresses

        ' Declare Variables
        Dim szDataPath As String

        Try

            ' Create the SDO Engine object
            oSDO = New SageDataObject300.SDOEngine

            ' Create the workspace
            oWS = oSDO.Workspaces.Add("Example")

            ' Select company. The SelectCompany method takes the program install
            ' folder as a parameter
            szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

            ' A U.I. for company selection is presented to the user. If a company 'is selected,
            ' the path will be passed to the szDataPath variable.
            ' If not, or the Cancel button is selected, the variable will be left 'empty.
            If szDataPath <> "" Then

                ' Connect to Data Files
                If oWS.Connect(szDataPath, "SDO User", "", "Example") Then

                    'Create Instances of objects
                    oCustomerAddress = oWS.CreateCustomerAddress
                    oCustomerAddresses = oWS.CreateCustomerAddresses

                    'Declare and instantiate the Enumerator
                    Dim pEnum As System.Collections.IEnumerator = oCustomerAddresses.GetEnumerator

                    'Iterate through the Enumerator
                    While (pEnum.MoveNext())

                        'Set the object to the position of the Enumerator
                        oCustomerAddress = pEnum.Current

                        If oCustomerAddress.Customer.Reference = "A1D001" And oCustomerAddress.Description = "Manchester Branch" Then

                            oCustomerAddress.AddressLine1 = "Sage UK LTD"
                            oCustomerAddress.AddressLine2 = "North Park"
                            oCustomerAddress.AddressLine3 = "Newcastle Upon Tyne"
                            oCustomerAddress.AddressLine4 = "Tyne And Wear"
                            oCustomerAddress.AddressLine5 = "NE13 9AA"
                            oCustomerAddress.AddressType = SageDataObject300.AddressTypes.sdoContactAddress
                            oCustomerAddress.Contact = "Pete Brown"
                            oCustomerAddress.Description = "Head Office"
                            oCustomerAddress.EMail = "Support@Sage.com"
                            oCustomerAddress.Fax = "0191666666"
                            oCustomerAddress.Name() = "Customer Name"
                            oCustomerAddress.Notes = "Notes"
                            oCustomerAddress.Role = ""
                            oCustomerAddress.Telephone = "01915555555"
                            oCustomerAddress.Telephone2 = "01916666666"
                            oCustomerAddress.VatNumber = "123456789"

                            'Call the Update method
                            If oCustomerAddress.Update() Then

                                MessageBox.Show("Customer Address Updated")

                            Else

                                MessageBox.Show("Unable to Update Customer Address")

                            End If

                        End If

                    End While

                    ' Disconnect
                    oWS.Disconnect()
                Else
                    MessageBox.Show("Failed to connect!")

                End If

            End If

        Catch ex As Exception
            ' Error Handling Code
            MessageBox.Show("The SDO generated the following error: " & ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try

        ' Destroy Objects
        oCustomerAddresses = Nothing
        oCustomerAddress = Nothing
        oWS = Nothing
        oSDO = Nothing
C#.NET [image] Copy C# Code

            //Declare Objects
            SageDataObject300.SDOEngine oSDO;
            SageDataObject300.WorkSpace oWS;
            SageDataObject300.CustomerAddress oCustomerAddress;
            SageDataObject300.CustomerAddresses oCustomerAddresses;

            // Declare Variables
            string szDataPath;

            try
            {

                // Create the SDO Engine object
                oSDO = new SageDataObject300.SDOEngine();

                //Instantiate WorkSpace
                oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

                // Select company. The SelectCompany method takes the program install
                // folder as a parameter
                szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

                // A U.I. for company selection is presented to the user. If a company 'is selected,
                // the path will be passed to the szDataPath variable.
                // If not, or the Cancel button is selected, the variable will be left 'empty.
                if (szDataPath != "")
                {

                    // Connect to Data Files
                    if (oWS.Connect(szDataPath, "SDO User", "", "Example"))
                    {
                        //Create instances of objects
                        oCustomerAddress = (SageDataObject300.CustomerAddress)oWS.CreateCustomerAddress();
                        oCustomerAddresses = (SageDataObject300.CustomerAddresses)oWS.CreateCustomerAddresses();

                        //Declare and instantiate the Enumerator
                        System.Collections.IEnumerator pEnum = oCustomerAddresses.GetEnumerator();

                        //Iterate through the Enumberator
                        while (pEnum.MoveNext())
                        {

                            //Set the object to the position of the Enumerator
                            oCustomerAddress = (SageDataObject300.CustomerAddress)pEnum.Current;

                            //Declare a type of SageDataObject300.Customer and assign it the customer property
                            SageDataObject300.Customer customer = (SageDataObject300.Customer)oCustomerAddress.Customer;

                            if (customer.Reference == "A1D001" & (oCustomerAddress.Description == "Manchester Branch"))
                            {

                                oCustomerAddress.AddressLine1 = "Sage UK LTD";
                                oCustomerAddress.AddressLine2 = "North Park";
                                oCustomerAddress.AddressLine3 = "Newcastle Upon Tyne";
                                oCustomerAddress.AddressLine4 = "Tyne And Wear";
                                oCustomerAddress.AddressLine5 = "NE13 9AA";
                                oCustomerAddress.AddressType = SageDataObject300.AddressTypes.sdoContactAddress;
                                oCustomerAddress.Contact = "Pete Brown";
                                oCustomerAddress.Description = "Head Office";
                                oCustomerAddress.EMail = "Support@Sage.com";
                                oCustomerAddress.Fax = "0191666666";
                                oCustomerAddress.Name = "Customer Name";
                                oCustomerAddress.Notes = "Notes";
                                oCustomerAddress.Role = "";
                                oCustomerAddress.Telephone = "01915555555";
                                oCustomerAddress.Telephone2 = "01916666666";
                                oCustomerAddress.VatNumber = "123456789";

                                //Call the Update method
                                if (oCustomerAddress.Update())
                                {
                                    MessageBox.Show("Contact History Updated");
                                }

                                else
                                {
                                    MessageBox.Show("Unable to Update Contact History");
                                }

                            }

                        }

                        // Disconnect
                        oWS.Disconnect();
                    }
                    else
                    {
                        MessageBox.Show("Failed to connect!");
                    }
                }
            }

            catch (Exception ex)
            {
                // Error Handling Code
                MessageBox.Show("The SDO generated the following error: " + ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }


Sage 50 Accounts - Example - Find Customer Address using GetEnumerator

Example - Find Customer Address using GetEnumerator

The example code below demonstrates how to find a customer address using GetEnumerator.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
Public Class Form1

    'Declare Objects
    Dim oSDO As SageDataObject300.SDOEngine
    Dim oWS As SageDataObject300.WorkSpace

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        ' Declare Variables
        Dim szDataPath As String

        Try

            ' Create the SDO Engine object
            oSDO = New SageDataObject300.SDOEngine

            ' Create the Workspace
            oWS = oSDO.Workspaces.Add("Example")

            ' Select company. The SelectCompany method takes the program install folder as a parameter
            szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

            ' A U.I. for company selection is presented to the user. If a company is selected,
            ' the path will be passed to the szDataPath variable.
            ' If not, or the Cancel button is selected, the variable will be left empty.
            If szDataPath <> "" Then

                ' Connect to Data Files
                If oWS.Connect(szDataPath, "", "", "Example") Then

                    ' user code
                    userDefinedMethod()

                End If

            End If

        Catch
            Select Case oSDO.LastError.Code

                ' 3rd Party Integration NOT Enabled - Site Activation
                Case Is = SageDataObject300.ErrorCode.sdoNotRegistered
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")
                    ' Invalid Password
                Case Is = SageDataObject300.ErrorCode.sdoLogonPassword
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")
                    ' User is Already Logged On
                Case Is = SageDataObject300.ErrorCode.sdoLogonNameInUse
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")
                    ' Line 50 is in Exclusive Mode i.e. File Maintenance
                Case Is = SageDataObject300.ErrorCode.sdoLogonExclusive
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")
                    ' Invalid Data Path on Connect
                Case Is = SageDataObject300.ErrorCode.sdoBadDataPath
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")
                    ' Line 50 is not Same Version as SDO
                Case Is = SageDataObject300.ErrorCode.sdoWrongVersion
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")
            End Select

        End Try

        'Disconnect
        oWS.Disconnect()

    End Sub

    Private Sub userDefinedMethod()

        ' declare objects
        Dim oSuppAdds As SageDataObject300.CustomerAddresses
        Dim mySupAddsEnum As IEnumerator

        ' create the Customer Addresses collection
        oSuppAdds = oWS.CreateCustomerAddresses

        ' get the enumerator for the Customer Addresses collection
        mySupAddsEnum = oSuppAdds.GetEnumerator()

        ' use the enumerator to move through each item in the collection
        While (mySupAddsEnum.MoveNext)

            ' show the current Customer Account Reference for the current CustomerAddress
            MsgBox(mySupAddsEnum.Current.Customer.Reference)

            ' check the Customer Account Reference
            If mySupAddsEnum.Current.Customer.Reference = "CUSTOMER" Then

                ' show the first address line for the current [Customer Address] item
                MsgBox("Customer address 1 " & mySupAddsEnum.Current.addressline1)

            End If

        End While

    End Sub

End Class
C#.NET [image] Copy C# Code
public partial class Form1 : Form

 {
     public Form1()
     {
         InitializeComponent();
     }

     //Declare Objects
     private SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
     private SageDataObject300.WorkSpace oWS;
     //public interface IEnumerable { }

     private void Form1_Load(object sender, EventArgs e)
     {

         //Declare Variables
         String szDataPath;

         try
         {
             //Create the Workspace
             oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

             //Select company. The SelectCompany method takes the program install folder as a parameter
             szDataPath = oSDO.SelectCompany("C:\\Documents and Settings\\All Users\\Application Data\\Sage\\Accounts\\2023");

             //A U.I. for company selection is presented to the user. If a company is selected,
             //the path will be passed to the szDataPath variable.
             //If not, or the Cancel button is selected, the variable will be left empty.

             if(szDataPath != string.Empty)
             {
                 //Connect to Data Files
                 if(oWS.Connect(szDataPath, "", "", "Example"))
                 {
                     //user code
                     userDefinedMethod();
                 }
             }

         }
         catch(Exception ex)
         {
             MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
         }
         finally
         {
             //Disconnect
              oWS.Disconnect();
         }
     }

     private void userDefinedMethod()
     {
         //Declare Objects
         SageDataObject300.CustomerAddresses oCustAdds;
         System.Collections.IEnumerator myCustAddsEnum;
         SageDataObject300.Customer oCustomer;

         //Create the Customer Address Collection
         oCustAdds = (SageDataObject300.CustomerAddresses)oWS.CreateCustomerAddresses();
         oCustomer = (SageDataObject300.Customer)oWS.CreateCustomer();

         //Get the enumerator for the customer addresses collection
         myCustAddsEnum = oCustAdds.GetEnumerator();

         myCustAddsEnum.Reset();

         //Use the enumerator to move through each item in the collection
         while (myCustAddsEnum.MoveNext())

         {
             Object myEnum = ((SageDataObject300.CustomerAddress)myCustAddsEnum.Current).Customer;

             if (Convert.ToString(((SageDataObject300.Customer)myEnum).Reference) == "AAAA")
             {
                 //Show the first address line for the current Customer address item
                 MessageBox.Show("Record AAAA Customer address : " + ((SageDataObject300.CustomerAddress)myCustAddsEnum.Current).AddressLine1);
             }
         }
     }
 }


Sage 50 Accounts - Example - Find Supplier Address using GetEnumerator

Example - Find Supplier Address using GetEnumerator

The example code below demonstrates how to find a supplier address using GetEnumerator.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
Public Class Form1

    'Declare Objects
    Dim oSDO As SageDataObject300.SDOEngine
    Dim oWS As SageDataObject300.WorkSpace

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        ' Declare Variables
        Dim szDataPath As String

        Try

            ' Create the SDO Engine object
            oSDO = New SageDataObject300.SDOEngine

            ' Create the Workspace
            oWS = oSDO.Workspaces.Add("Example")

            ' Select company. The SelectCompany method takes the program install folder as a parameter
            szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

            ' A U.I. for company selection is presented to the user. If a company is selected,
            ' the path will be passed to the szDataPath variable.
            ' If not, or the Cancel button is selected, the variable will be left empty.
            If szDataPath <> "" Then

                ' Connect to Data Files
                If oWS.Connect(szDataPath, "", "", "Example") Then

                    ' user code
                    userDefinedMethod()

                End If

            End If

        Catch
            Select Case oSDO.LastError.Code

                ' 3rd Party Integration NOT Enabled - Site Activation
                Case Is = SageDataObject300.ErrorCode.sdoNotRegistered
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")
                    ' Invalid Password
                Case Is = SageDataObject300.ErrorCode.sdoLogonPassword
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")
                    ' User is Already Logged On
                Case Is = SageDataObject300.ErrorCode.sdoLogonNameInUse
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")
                    ' Line 50 is in Exclusive Mode i.e. File Maintenance
                Case Is = SageDataObject300.ErrorCode.sdoLogonExclusive
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")
                    ' Invalid Data Path on Connect
                Case Is = SageDataObject300.ErrorCode.sdoBadDataPath
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")
                    ' Line 50 is not Same Version as SDO
                Case Is = SageDataObject300.ErrorCode.sdoWrongVersion
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")
            End Select

        End Try

        'Disconnect
        oWS.Disconnect()

    End Sub

    Private Sub userDefinedMethod()

        ' declare objects
        Dim oSuppAdds As SageDataObject300.SupplierAddresses
        Dim mySupAddsEnum As IEnumerator

        ' create the Supplier Addresses collection
        oSuppAdds = oWS.CreateSupplierAddresses

        ' get the enumerator for the Supplier Addresses collection
        mySupAddsEnum = oSuppAdds.GetEnumerator()

        ' use the enumerator to move through each item in the collection
        While (mySupAddsEnum.MoveNext)

            ' show the current Supplier Account Reference for the current SupplierAddress
            MsgBox(mySupAddsEnum.Current.Supplier.Reference)

            ' check the Supplier Account Reference
            If mySupAddsEnum.Current.Supplier.Reference = "SUPPLIER" Then

                ' show the first address line for the current [Supplier Address] item
                MsgBox("Supplier address 1 " & mySupAddsEnum.Current.addressline1)

            End If

        End While

    End Sub

End Class
C#.NET [image] Copy C# Code
public Form1()
{
    InitializeComponent();
}
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
private void Form1_Load(object sender, EventArgs e)
{
       //Declare Variables
    String szDataPath;

    try
    {
        //Create the Workspace
        oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

        //Select company. The SelectCompany method takes the program install folder as a parameter
        szDataPath = oSDO.SelectCompany("C:\\Documents and Settings\\All Users\\Application Data\\Sage\\Accounts\\2023");

        //A U.I. for company selection is presented to the user. If a company is selected,
        //the path will be passed to the szDataPath variable.
        //If not, or the Cancel button is selected, the variable will be left empty.

        if(szDataPath != string.Empty)
        {
            //Connect to Data Files
            if(oWS.Connect(szDataPath, "", "", "Example"))
            {
                //user code
                userDefinedMethod();
            }
        }

    }
    catch(Exception ex)
    {
        MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
    }
    finally
    {
        //Disconnect
         oWS.Disconnect();
    }
}

private void userDefinedMethod()
{
    //Declare Objects
    SageDataObject300.SupplierAddresses oSuppAdds;
    System.Collections.IEnumerator mySuppAddsEnum;
    SageDataObject300.Customer oCustomer;

    //Create the Supplier Address Collection
    oSuppAdds = (SageDataObject300.SupplierAddresses)oWS.CreateSupplierAddresses();
    oCustomer = (SageDataObject300.Customer)oWS.CreateCustomer();

    //Get the enumerator for the supplier addresses collection
    mySuppAddsEnum = oSuppAdds.GetEnumerator();

    mySuppAddsEnum.Reset();

    //Use the enumerator to move through each item in the collection
    while (mySuppAddsEnum.MoveNext())

    {
        Object myEnum = ((SageDataObject300.SupplierAddress)mySuppAddsEnum.Current).Supplier;

        if (Convert.ToString(((SageDataObject300.Supplier)myEnum).Reference) == "SUPPLIER")
        {
            //Show the first address line for the current Supplier address item
            MessageBox.Show("Record SUPPLIER Supplier address : " + ((SageDataObject300.SupplierAddress)mySuppAddsEnum.Current).AddressLine1);
        }
    }
}


Sage 50 Accounts - Example - View Company Address properties

Example - View Company Address properties

The example code below demonstrates how to view company address properties.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
       ' Declare Objects
       Dim oSDO As SageDataObject300.SDOEngine
       Dim oWS As SageDataObject300.WorkSpace
       Dim oCompanyAddress As SageDataObject300.CompanyAddress
       Dim oCompanyAddresses As SageDataObject300.CompanyAddresses
       Dim i As Integer
       Dim lvitem As ListViewItem

       Try

           ' Declare Variables
           Dim szDataPath As String

           ' Create the SDO Engine object
           oSDO = New SageDataObject300.SDOEngine

           ' Create the workspace
           oWS = oSDO.Workspaces.Add("Example")

           ' Select company. The SelectCompany method takes the program install
           ' folder as a parameter
           szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")
           ' A U.I. for company selection is presented to the user. If a company 'is selected,
           ' the path will be passed to the szDataPath variable.
           ' If not, or the Cancel button is selected, the variable will be left 'empty.

           If szDataPath <> "" Then

               ' Connect to Data Files
               If oWS.Connect(szDataPath, "", "", "Example") Then

                   ' Create instances of objects
                   oCompanyAddress = oWS.CreateCompanyAddress
                   oCompanyAddresses = oWS.CreateCompanyAddresses

                   For Each oCompanyAddress In oCompanyAddresses

                       lvitem = New ListViewItem

                       lvitem.Text = oCompanyAddress.AddressLine1
                       lvitem.SubItems.Add(oCompanyAddress.AddressLine2)
                       lvitem.SubItems.Add(oCompanyAddress.AddressLine3)
                       lvitem.SubItems.Add(oCompanyAddress.AddressLine4)
                       lvitem.SubItems.Add(oCompanyAddress.AddressLine5)
                       lvitem.SubItems.Add(oCompanyAddress.AddressNumber)
                       lvitem.SubItems.Add(oCompanyAddress.AddressType)
                       lvitem.SubItems.Add(oCompanyAddress.Contact)
                       lvitem.SubItems.Add(oCompanyAddress.Country.Name)
                       lvitem.SubItems.Add(oCompanyAddress.Description)
                       lvitem.SubItems.Add(oCompanyAddress.EMail)
                       lvitem.SubItems.Add(oCompanyAddress.Fax)
                       lvitem.SubItems.Add(oCompanyAddress.Name)
                       lvitem.SubItems.Add(oCompanyAddress.Notes)
                       lvitem.SubItems.Add(oCompanyAddress.Role)
                       lvitem.SubItems.Add(oCompanyAddress.Telephone)
                       lvitem.SubItems.Add(oCompanyAddress.Telephone2)

                       Me.ListView1.Items.Add(lvitem)

                       lvitem = Nothing

                   Next

                   ' Disconnect
                   oWS.Disconnect()

               End If

           End If

       Catch ex As Exception
           ' Error Handling Code
           MessageBox.Show("The SDO generated the following error: " & ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)
       End Try

       ' Destroy Objects
       oCompanyAddress = Nothing
       oWS = Nothing
       oSDO = Nothing
C#.NET [image] Copy C# Code
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.CompanyAddress oCompanyAddress;
SageDataObject300.CompanyAddresses oCompanyAddresses;

ListViewItem lvitem;

//declare Variables
String szDataPath;

//Create the SDO Engive Object
oSDO = new SageDataObject300.SDOEngine();

//Create the Workspace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

try
{

    //Select company. The SelectCompany method takes the program install
    //folder as a parameter
    szDataPath = oSDO.SelectCompany("C:\\Documents and Settings\\All Users\\Application Data\\Sage\\Accounts\\2023");

    //A U.I. for company selection is presented to the user. If a company 'is selected,
    //the path will be passed to the szDataPath variable.
    //If not, or the Cancel button is selected, the variable will be left 'empty.

    if(szDataPath != string.Empty)
    {
        //Connect to the Data Files
        if (oWS.Connect(szDataPath, "", "", "Example"))
        {
            //Create instances of the objects
            oCompanyAddress = (SageDataObject300.CompanyAddress)oWS.CreateCompanyAddress();
            oCompanyAddresses = (SageDataObject300.CompanyAddresses)oWS.CreateCompanyAddresses();

            //Add the values for the Company Address properties to the listview for all addresses
            for (int i = 1; i < oCompanyAddresses.Count + 1; i++)
            {
                lvitem = new ListViewItem();
                Object addRef = i ;
                oCompanyAddress.Load(ref addRef);
                lvitem.Text = oCompanyAddress.AddressLine1;
                lvitem.SubItems.Add(oCompanyAddress.AddressLine2);
                lvitem.SubItems.Add(oCompanyAddress.AddressLine3);
                lvitem.SubItems.Add(oCompanyAddress.AddressLine4);
                lvitem.SubItems.Add(oCompanyAddress.AddressLine5);
                lvitem.SubItems.Add(Convert.ToString(oCompanyAddress.AddressNumber));
                lvitem.SubItems.Add(Convert.ToString(oCompanyAddress.AddressType));
                lvitem.SubItems.Add(oCompanyAddress.Contact);
                lvitem.SubItems.Add(((SageDataObject300.Country)oCompanyAddress.Country).Name);
                lvitem.SubItems.Add(oCompanyAddress.Description);
                lvitem.SubItems.Add(oCompanyAddress.EMail);
                lvitem.SubItems.Add(oCompanyAddress.Fax);
                lvitem.SubItems.Add(oCompanyAddress.Name);
                lvitem.SubItems.Add(oCompanyAddress.Notes);
                lvitem.SubItems.Add(oCompanyAddress.Role);
                lvitem.SubItems.Add(oCompanyAddress.Telephone);
                lvitem.SubItems.Add(oCompanyAddress.Telephone2);

                this.listView1.Items.Add(lvitem);

                addRef = null;
                lvitem = null;
            }
        }
    }
}

catch(Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}
finally
{
    //Disconnect
    oWS.Disconnect();
}


Sage 50 Accounts - Example - View Customer Address properties for all Customers

Example - View Customer Address properties for all Customers

The example code below demonstrates how to view customer address properties for all customers.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
       Dim oSDO As SageDataObject300.SDOEngine
       Dim oWS As SageDataObject300.WorkSpace
       Dim oCustomerAddress As SageDataObject300.CustomerAddress
       Dim oSalesRecord As SageDataObject300.SalesRecord

       Dim lvitem As ListViewItem

       ' Declare Variables
       Dim szDataPath As String

       Try

           ' Create the SDO Engine object
           oSDO = New SageDataObject300.SDOEngine

           ' Create the workspace
           oWS = oSDO.Workspaces.Add("Example")

           ' Select company. The SelectCompany method takes the program install
           ' folder as a parameter
           szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

           ' A U.I. for company selection is presented to the user. If a company 'is selected,
           ' the path will be passed to the szDataPath variable.
           ' If not, or the Cancel button is selected, the variable will be left 'empty.
           If szDataPath <> "" Then

               ' Connect to Data Files
               If oWS.Connect(szDataPath, "", "", "Example") Then
                   oSalesRecord = oWS.CreateObject("SALESRECORD")

                   'Move to first SalesRecord
                   oSalesRecord.MoveFirst()

                   'Loop through the Sales Records
                   Do

                       oCustomerAddress = oWS.CreateCustomerAddress

                       'Loop through Customer addresses for this SalesRecord

                       Dim i As Integer
                       i = 1
                       While oCustomerAddress.Load(oSalesRecord.Fields.Item("ACCOUNT_REF").Value, i)
                           lvitem = New ListViewItem
                           lvitem.Text = oCustomerAddress.AddressLine1
                           lvitem.SubItems.Add(oCustomerAddress.AddressLine2)
                           lvitem.SubItems.Add(oCustomerAddress.AddressLine3)
                           lvitem.SubItems.Add(oCustomerAddress.AddressLine4)
                           lvitem.SubItems.Add(oCustomerAddress.AddressLine5)
                           lvitem.SubItems.Add(oCustomerAddress.AddressNumber)
                           lvitem.SubItems.Add(oCustomerAddress.AddressType)
                           lvitem.SubItems.Add(oCustomerAddress.Contact)
                           lvitem.SubItems.Add(Convert.ToString(oCustomerAddress.Country.Name))
                           lvitem.SubItems.Add(Convert.ToString(oCustomerAddress.Customer.Reference))
                           lvitem.SubItems.Add(oCustomerAddress.Description)
                           lvitem.SubItems.Add(oCustomerAddress.EMail)
                           lvitem.SubItems.Add(oCustomerAddress.Fax)
                           lvitem.SubItems.Add(oCustomerAddress.Name)
                           lvitem.SubItems.Add(oCustomerAddress.Notes)
                           lvitem.SubItems.Add(oCustomerAddress.Role)
                           lvitem.SubItems.Add(Convert.ToString(oCustomerAddress.TaxCode.Name))
                           lvitem.SubItems.Add(oCustomerAddress.Telephone)
                           lvitem.SubItems.Add(oCustomerAddress.Telephone2)
                           lvitem.SubItems.Add(oCustomerAddress.VatNumber)

                           Me.ListView1.Items.Add(lvitem)

                           lvitem = Nothing
                           i = i + 1

                       End While

                       oCustomerAddress = Nothing

                   Loop Until (Not oSalesRecord.MoveNext)

                   ' Disconnect
                   oWS.Disconnect()
               Else
                   MessageBox.Show("Failed to connect!")

               End If

           End If

       Catch ex As Exception
           ' Error Handling Code
           MessageBox.Show("The SDO generated the following error: " & ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)
       End Try

       ' Destroy Objects
       oSalesRecord = Nothing
       oCustomerAddress = Nothing
       oWS = Nothing
       oSDO = Nothing
C#.NET [image] Copy C# Code
//Declare Objects
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.CustomerAddress oCustomerAddress;
SageDataObject300.SalesRecord oSalesRecord;

ListViewItem lvitem;

//Decalre Variables
String szDataPath;

//Create the SDO Engine Object
oSDO = new SageDataObject300.SDOEngine();

//Create the Workspace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Select company. The select company method taked the program install folder
//as a parameter
szDataPath = oSDO.SelectCompany("C:\\Documents and Settings\\All Users\\Application Data\\Sage\\Accounts\\2023");

//A U.I. for a company selection is presented to the user. If a company is selected
//the path will be passed to the szDataPath variable.
//If not, or the cancel button is selected, the variable will be left empty.

if (szDataPath != string.Empty)
{
    //Connect to the Data Files
    if (oWS.Connect(szDataPath, "", "", "Example"))
    {
        //Create an instance of the SalesRecord
        oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SALESRECORD");

        //Move to the first SalesRecord
        oSalesRecord.MoveFirst();

        //Loop through the Sales Records
        do
        {
            oCustomerAddress = (SageDataObject300.CustomerAddress)oWS.CreateCustomerAddress();

            //Loop through Customer address for this SalesRecord

            Int32 i;
            i = 1;
            Object addRef = i;
            Object custRef = SDOHelper.Read(oSalesRecord, "ACCOUNT_REF");
            while (oCustomerAddress.Load(ref custRef, ref addRef))
            {
                lvitem = new ListViewItem();
                lvitem.Text = oCustomerAddress.AddressLine1;
                lvitem.SubItems.Add(oCustomerAddress.AddressLine2);
                lvitem.SubItems.Add(oCustomerAddress.AddressLine3);
                lvitem.SubItems.Add(oCustomerAddress.AddressLine4);
                lvitem.SubItems.Add(oCustomerAddress.AddressLine5);
                lvitem.SubItems.Add(Convert.ToString(oCustomerAddress.AddressNumber));
                lvitem.SubItems.Add(Convert.ToString(oCustomerAddress.AddressType));
                lvitem.SubItems.Add(oCustomerAddress.Contact);
                lvitem.SubItems.Add(((SageDataObject300.Country)oCustomerAddress.Country).Name);
                lvitem.SubItems.Add(((SageDataObject300.Customer)oCustomerAddress.Customer).Reference);
                lvitem.SubItems.Add(oCustomerAddress.Description);
                lvitem.SubItems.Add(oCustomerAddress.EMail);
                lvitem.SubItems.Add(oCustomerAddress.Fax);
                lvitem.SubItems.Add(oCustomerAddress.Name);
                lvitem.SubItems.Add(oCustomerAddress.Notes);
                lvitem.SubItems.Add(oCustomerAddress.Role);
                lvitem.SubItems.Add(((SageDataObject300.TaxCode)oCustomerAddress.TaxCode).Name);
                lvitem.SubItems.Add(oCustomerAddress.Telephone);
                lvitem.SubItems.Add(oCustomerAddress.Telephone2);
                lvitem.SubItems.Add(oCustomerAddress.VatNumber);

                this.listView1.Items.Add(lvitem);

                lvitem = null;
                i = i + 1;
                addRef = i;

            }

        } while (oSalesRecord.MoveNext());

    }
    else
    {
        MessageBox.Show("Failed to connect");
    }

}


Sage 50 Accounts - Example - View Customer Addresses collection

Example - View Customer Addresses collection

The example code below demonstrates how to view the customer addresses collection.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
       Dim oSDO As SageDataObject300.SDOEngine
       Dim oWS As SageDataObject300.WorkSpace
       Dim oCustomerAddress As SageDataObject300.CustomerAddress
       Dim oCustomerAddresses As SageDataObject300.CustomerAddresses

       Dim lvitem As ListViewItem

       ' Declare Variables
       Dim szDataPath As String

       Try

           ' Create the SDO Engine object
           oSDO = New SageDataObject300.SDOEngine

           ' Create the workspace
           oWS = oSDO.Workspaces.Add("Example")

           ' Select company. The SelectCompany method takes the program install
           ' folder as a parameter
           szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

           ' A U.I. for company selection is presented to the user. If a company 'is selected,
           ' the path will be passed to the szDataPath variable.
           ' If not, or the Cancel button is selected, the variable will be left 'empty.
           If szDataPath <> "" Then

               ' Connect to Data Files
               If oWS.Connect(szDataPath, "", "", "Example") Then

                   oCustomerAddress = oWS.CreateCustomerAddress
                   oCustomerAddresses = oWS.CreateCustomerAddresses

                   'Loop through Customer addresses for this PurchaseRecord

                   For Each oCustomerAddress In oCustomerAddresses

                       lvitem = New ListViewItem
                       lvitem.Text = oCustomerAddress.AddressLine1
                       lvitem.SubItems.Add(oCustomerAddress.AddressLine2)
                       lvitem.SubItems.Add(oCustomerAddress.AddressLine3)
                       lvitem.SubItems.Add(oCustomerAddress.AddressLine4)
                       lvitem.SubItems.Add(oCustomerAddress.AddressLine5)
                       lvitem.SubItems.Add(oCustomerAddress.AddressNumber)
                       lvitem.SubItems.Add(oCustomerAddress.AddressType)
                       lvitem.SubItems.Add(oCustomerAddress.Contact)
                       lvitem.SubItems.Add(Convert.ToString(oCustomerAddress.Country.Name))
                       lvitem.SubItems.Add(Convert.ToString(oCustomerAddress.Customer.Reference))
                       lvitem.SubItems.Add(oCustomerAddress.Description)
                       lvitem.SubItems.Add(oCustomerAddress.EMail)
                       lvitem.SubItems.Add(oCustomerAddress.Fax)
                       lvitem.SubItems.Add(oCustomerAddress.Name)
                       lvitem.SubItems.Add(oCustomerAddress.Notes)
                       lvitem.SubItems.Add(oCustomerAddress.Role)
                       lvitem.SubItems.Add(Convert.ToString(oCustomerAddress.TaxCode.Name))
                       lvitem.SubItems.Add(oCustomerAddress.Telephone)
                       lvitem.SubItems.Add(oCustomerAddress.Telephone2)
                       lvitem.SubItems.Add(oCustomerAddress.VatNumber)

                       Me.ListView1.Items.Add(lvitem)

                       lvitem = Nothing

                   Next

                   oCustomerAddress = Nothing

                   ' Disconnect
                   oWS.Disconnect()
               Else
                   MessageBox.Show("Failed to connect!")
               End If

           End If

       Catch ex As Exception
           ' Error Handling Code
           MessageBox.Show("The SDO generated the following error: " & ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)
       End Try

       ' Destroy Objects
       oCustomerAddress = Nothing
       oWS = Nothing
       oSDO = Nothing

       Exit Sub
C#.NET [image] Copy C# Code

SageDataObject300.SDOEngine oSDO;

SageDataObject300.WorkSpace oWS;

SageDataObject300.CustomerAddresses oCustomerAddresses;

ListViewItem lvitem;

// Declare Variables

string szDataPath;

try

{

    // Create the SDO Engine object

    oSDO = new SageDataObject300.SDOEngine();

    //Instantiate WorkSpace

    oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

    // Select company

    szDataPath = oSDO.SelectCompany("C:\\Documents and Settings\\All Users\\Application Data\\Sage\\Accounts\\2023");

    // A U.I. for company selection is presented to the user. If a company 'is selected,

    // the path will be passed to the szDataPath variable.

    // If not, or the Cancel button is selected, the variable will be left 'empty.

    if (szDataPath != "")

    {

        // Connect to Data Files

        if (oWS.Connect(szDataPath, "", "", "Example"))

        {

            oCustomerAddresses = (SageDataObject300.CustomerAddresses)oWS.CreateCustomerAddresses();

            //Loop through Customer addresses for this PurchaseRecord

            foreach (SageDataObject300.CustomerAddress oCustomerAddress in oCustomerAddresses) {

                lvitem = new ListViewItem();

                lvitem.Text = oCustomerAddress.AddressLine1;

                lvitem.SubItems.Add(oCustomerAddress.AddressLine2);

                lvitem.SubItems.Add(oCustomerAddress.AddressLine3);

                lvitem.SubItems.Add(oCustomerAddress.AddressLine4);

                lvitem.SubItems.Add(oCustomerAddress.AddressLine5);

                lvitem.SubItems.Add(Convert.ToString(oCustomerAddress.AddressNumber));

                lvitem.SubItems.Add(Convert.ToString(oCustomerAddress.AddressType));

                lvitem.SubItems.Add(oCustomerAddress.Contact);

                lvitem.SubItems.Add(((SageDataObject300.Country)oCustomerAddress.Country).Name);

                lvitem.SubItems.Add(((SageDataObject300.Customer)oCustomerAddress.Customer).Reference);

                lvitem.SubItems.Add(oCustomerAddress.Description);

                lvitem.SubItems.Add(oCustomerAddress.EMail);

                lvitem.SubItems.Add(oCustomerAddress.Fax);

                lvitem.SubItems.Add(oCustomerAddress.Name);

                lvitem.SubItems.Add(oCustomerAddress.Notes);

                lvitem.SubItems.Add(oCustomerAddress.Role);

                lvitem.SubItems.Add(((SageDataObject300.TaxCode)oCustomerAddress.TaxCode).Name);

                lvitem.SubItems.Add(oCustomerAddress.Telephone);

                lvitem.SubItems.Add(oCustomerAddress.Telephone2);

                lvitem.SubItems.Add(oCustomerAddress.VatNumber);

                this.listView1.Items.Add(lvitem);

                lvitem = null;

            }

            // Disconnect

            oWS.Disconnect();

        }

        else

        {

            MessageBox.Show("Failed to connect!");

        }

    }

}

catch (Exception ex)

{

    // Error Handling Code

    MessageBox.Show("The SDO generated the following error: " + ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);

}


Sage 50 Accounts - Example - View DiaryEventLabels properties using Item method

Example - View Customer Address properties using Item method

The example code below demonstrates how to view customer addresses properties using the Item method.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
       'Declare Objects
       Dim oSDO As SageDataObject300.SDOEngine
       Dim oWS As SageDataObject300.WorkSpace
       Dim oCustomerAddresses As SageDataObject300.CustomerAddresses
       Dim lvitem As ListViewItem

       ' Declare Variables
       Dim szDataPath As String

       ' Create the SDO Engine object
       oSDO = New SageDataObject300.SDOEngine

       ' Create the workspace
       oWS = oSDO.Workspaces.Add("Example")

       Try

           ' Select company. The SelectCompany method takes the program install
           ' folder as a parameter
           szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

           ' A U.I. for company selection is presented to the user. If a company 'is selected,
           ' the path will be passed to the szDataPath variable.
           ' If not, or the Cancel button is selected, the variable will be left 'empty.
           If szDataPath <> "" Then

               ' Connect to Data Files
               If oWS.Connect(szDataPath, "", "", "Example") Then

                   'Instantiate the object
                   oCustomerAddresses = oWS.CreateCustomerAddresses

                   Dim i As Integer

                   'Using the item reference add the property values of all the Addresses in the collection
                   'to a listview
                   For i = 0 To oCustomerAddresses.Count - 1

                       lvitem = New ListViewItem

                       lvitem.Text = oCustomerAddresses.Item(i).AddressLine1
                       lvitem.SubItems.Add(oCustomerAddresses.Item(i).AddressLine2)
                       lvitem.SubItems.Add(oCustomerAddresses.Item(i).AddressLine3)
                       lvitem.SubItems.Add(oCustomerAddresses.Item(i).AddressLine4)
                       lvitem.SubItems.Add(oCustomerAddresses.Item(i).AddressLine5)
                       lvitem.SubItems.Add(oCustomerAddresses.Item(i).AddressNumber)
                       lvitem.SubItems.Add(oCustomerAddresses.Item(i).AddressType)
                       lvitem.SubItems.Add(oCustomerAddresses.Item(i).Contact)
                       lvitem.SubItems.Add(Convert.ToString(oCustomerAddresses.Item(i).Country.Name))
                       lvitem.SubItems.Add(Convert.ToString(oCustomerAddresses.Item(i).Customer.Reference))
                       lvitem.SubItems.Add(oCustomerAddresses.Item(i).Description)
                       lvitem.SubItems.Add(oCustomerAddresses.Item(i).EMail)
                       lvitem.SubItems.Add(oCustomerAddresses.Item(i).Fax)
                       lvitem.SubItems.Add(oCustomerAddresses.Item(i).Name)
                       lvitem.SubItems.Add(oCustomerAddresses.Item(i).Notes)
                       lvitem.SubItems.Add(oCustomerAddresses.Item(i).Role)
                       lvitem.SubItems.Add(Convert.ToString(oCustomerAddresses.Item(i).TaxCode.Name))
                       lvitem.SubItems.Add(oCustomerAddresses.Item(i).Telephone)
                       lvitem.SubItems.Add(oCustomerAddresses.Item(i).Telephone2)
                       lvitem.SubItems.Add(oCustomerAddresses.Item(i).VatNumber)

                       Me.ListView1.Items.Add(lvitem)

                       lvitem = Nothing
                   Next

                   oCustomerAddresses = Nothing

               Else
                   MessageBox.Show("Failed to connect!")
               End If

           End If

       Catch ex As Exception
           ' Error Handling Code
           MessageBox.Show("The SDO generated the following error: " & ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

       Finally

           ' Disconnect
           oWS.Disconnect()

           oCustomerAddresses = Nothing
           oWS = Nothing
           oSDO = Nothing

       End Try
C#.NET [image] Copy C# Code
            //Declare Objects
            SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
            SageDataObject300.WorkSpace oWS;
            SageDataObject300.CustomerAddresses oCustomerAddresses;
            SageDataObject300.Country oCountry;
            SageDataObject300.Customer oCustomer;

            //Declare Variables
            ListViewItem lvitem;
            String szDataPath;

            //Create the Workspace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            try
            {
                //Select Company. The SelectCompany takes the program install folder as a parameter
                szDataPath = oSDO.SelectCompany("C:\\Documents and Settings\\All Users\\Application Data\\Sage\\Accounts\\2023");

                //A U.I. for company selection is presented to the user. If a company 'is selected,
                //the path will be passed to the szDataPath variable.
                //If not, or the Cancel button is selected, the variable will be left 'empty.
                if (szDataPath != string.Empty)
                {
                    //Connect to the datafiles
                    if (oWS.Connect(szDataPath, "", "", "EXAMPLE"))
                    {
                        //Instantiate the object
                        oCustomerAddresses = (SageDataObject300.CustomerAddresses)oWS.CreateCustomerAddresses();
                        oCountry = (SageDataObject300.Country)oWS.CreateCountry();
                        oCustomer = (SageDataObject300.Customer)oWS.CreateCustomer();

                        //Using the item reference, add the property values of all
                        //the Addresses in the collection to a listview

                        for (int i = 0; i < oCustomerAddresses.Count - 1; i++)
                        {
                            lvitem = new ListViewItem();
                            Object addRef = i;

                            lvitem.Text = oCustomerAddresses.Item(ref addRef).AddressLine1;
                            lvitem.SubItems.Add(oCustomerAddresses.Item(ref addRef).AddressLine2);
                            lvitem.SubItems.Add(oCustomerAddresses.Item(ref addRef).AddressLine3);
                            lvitem.SubItems.Add(oCustomerAddresses.Item(ref addRef).AddressLine4);
                            lvitem.SubItems.Add(oCustomerAddresses.Item(ref addRef).AddressLine5);
                            lvitem.SubItems.Add(Convert.ToString(oCustomerAddresses.Item(ref addRef).AddressNumber));
                            lvitem.SubItems.Add(Convert.ToString(oCustomerAddresses.Item(ref addRef).AddressType));
                            lvitem.SubItems.Add(oCustomerAddresses.Item(ref addRef).Contact);
                            lvitem.SubItems.Add(((SageDataObject300.Country)oCustomerAddresses.Item(ref addRef).Country).Name);
                            lvitem.SubItems.Add(((SageDataObject300.Customer)oCustomerAddresses.Item(ref addRef).Customer).Reference);
                            lvitem.SubItems.Add(oCustomerAddresses.Item(ref addRef).Description);
                            lvitem.SubItems.Add(oCustomerAddresses.Item(ref addRef).EMail);
                            lvitem.SubItems.Add(oCustomerAddresses.Item(ref addRef).Fax);
                            lvitem.SubItems.Add(oCustomerAddresses.Item(ref addRef).Name);
                            lvitem.SubItems.Add(oCustomerAddresses.Item(ref addRef).Notes);
                            lvitem.SubItems.Add(oCustomerAddresses.Item(ref addRef).Role);
                           lvitem.SubItems.Add(((SageDataObject300.TaxCode)oCustomerAddresses.Item(ref addRef).TaxCode).Name);
                            lvitem.SubItems.Add(oCustomerAddresses.Item(ref addRef).Telephone);
                            lvitem.SubItems.Add(oCustomerAddresses.Item(ref addRef).Telephone2);
                            lvitem.SubItems.Add(oCustomerAddresses.Item(ref addRef).VatNumber);

                            this.listView1.Items.Add(lvitem);

                            lvitem = null;
                            i = i + 1;
                            addRef = i;

                        }
                    }
                    else
                    {
                        MessageBox.Show("Failed to Connect");
                    }
                }
            }
            //Error handling
            catch (Exception ex)
            {
                 MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }

            finally
            {
                //Disconnect
                oWS.Disconnect();

            }


Sage 50 Accounts - Example - View Supplier Address properties for all Suppliers

Example - View Supplier Address properties for all Suppliers

The example code below demonstrates how to view supplier address properties for all suppliers.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
      Dim oSDO As SageDataObject300.SDOEngine
      Dim oWS As SageDataObject300.WorkSpace
      Dim oSupplierAddress As SageDataObject300.SupplierAddress
      Dim oPurchaseRecord As SageDataObject300.PurchaseRecord

      Dim lvitem As ListViewItem

      ' Declare Variables
      Dim szDataPath As String

      Try

          ' Create the SDO Engine object
          oSDO = New SageDataObject300.SDOEngine

          ' Create the workspace
          oWS = oSDO.Workspaces.Add("Example")

          ' Select company. The SelectCompany method takes the program install
          ' folder as a parameter
          szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

          ' A U.I. for company selection is presented to the user. If a company 'is selected,
          ' the path will be passed to the szDataPath variable.
          ' If not, or the Cancel button is selected, the variable will be left 'empty.
          If szDataPath <> "" Then

              ' Connect to Data Files
              If oWS.Connect(szDataPath, "", "", "Example") Then
                  oPurchaseRecord = oWS.CreateObject("PURCHASERECORD")

                  'Move to first PurchaseRecord
                  oPurchaseRecord.MoveFirst()

                  'Loop through the Purchase Records
                  Do

                      oSupplierAddress = oWS.CreateSupplierAddress

                      'Loop through Supplier addresses for this PurchaseRecord

                      Dim i As Integer
                      i = 1
                      While oSupplierAddress.Load(oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value, i)
                          lvitem = New ListViewItem
                          lvitem.Text = oSupplierAddress.AddressLine1
                          lvitem.SubItems.Add(oSupplierAddress.AddressLine2)
                          lvitem.SubItems.Add(oSupplierAddress.AddressLine3)
                          lvitem.SubItems.Add(oSupplierAddress.AddressLine4)
                          lvitem.SubItems.Add(oSupplierAddress.AddressLine5)
                          lvitem.SubItems.Add(oSupplierAddress.AddressNumber)
                          lvitem.SubItems.Add(oSupplierAddress.AddressType)
                          lvitem.SubItems.Add(oSupplierAddress.Contact)
                          lvitem.SubItems.Add(Convert.ToString(oSupplierAddress.Country.Name))
                          lvitem.SubItems.Add(Convert.ToString(oSupplierAddress.Supplier.Reference))
                          lvitem.SubItems.Add(oSupplierAddress.Description)
                          lvitem.SubItems.Add(oSupplierAddress.EMail)
                          lvitem.SubItems.Add(oSupplierAddress.Fax)
                          lvitem.SubItems.Add(oSupplierAddress.Name)
                          lvitem.SubItems.Add(oSupplierAddress.Notes)
                          lvitem.SubItems.Add(oSupplierAddress.Role)
                          lvitem.SubItems.Add(Convert.ToString(oSupplierAddress.TaxCode.Name))
                          lvitem.SubItems.Add(oSupplierAddress.Telephone)
                          lvitem.SubItems.Add(oSupplierAddress.Telephone2)
                          lvitem.SubItems.Add(oSupplierAddress.VatNumber)

                          Me.ListView1.Items.Add(lvitem)

                          lvitem = Nothing
                          i = i + 1

                      End While

                      oSupplierAddress = Nothing

                  Loop Until (Not oPurchaseRecord.MoveNext)

                  ' Disconnect
                  oWS.Disconnect()
              Else
                  MessageBox.Show("Failed to connect!")
              End If

          End If

      Catch ex As Exception
          ' Error Handling Code
          MessageBox.Show("The SDO generated the following error: " & ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)
      End Try

      ' Destroy Objects
      oSupplierAddress = Nothing
      oWS = Nothing
      oSDO = Nothing
C#.NET [image] Copy C# Code
//Declare Objects
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.SupplierAddress oSupplierAddress;
SageDataObject300.PurchaseRecord oPurchaseRecord;

ListViewItem lvitem;

//Decalre Variables
String szDataPath;

//Create the SDO Engine Object
oSDO = new SageDataObject300.SDOEngine();

//Create the Workspace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Select company. The select company method taked the program install folder
//as a parameter
szDataPath = oSDO.SelectCompany("C:\\Documents and Settings\\All Users\\Application Data\\Sage\\Accounts\\2023");

//A U.I. for a company selection is presented to the user. If a company is selected
//the path will be passed to the szDataPath variable.
//If not, or the cancel button is selected, the variable will be left empty.

if (szDataPath != string.Empty)
{
    //Connect to the Data Files
    if (oWS.Connect(szDataPath, "", "", "Example"))
    {
        //Create an instance of the PurchaseRecord
        oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");

        //Move to the first PurchaseRecord
        oPurchaseRecord.MoveFirst();

        //Loop through the Sales Records
        do
        {
            oSupplierAddress = (SageDataObject300.SupplierAddress)oWS.CreateSupplierAddress();

            //Loop through Supplier address for this PurchaseRecord

            Int32 i;
            i = 1;
            Object addRef = i;
            Object custRef = SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF");
            while (oSupplierAddress.Load(ref custRef, ref addRef))
            {
                lvitem = new ListViewItem();
                lvitem.Text = oSupplierAddress.AddressLine1;
                lvitem.SubItems.Add(oSupplierAddress.AddressLine2);
                lvitem.SubItems.Add(oSupplierAddress.AddressLine3);
                lvitem.SubItems.Add(oSupplierAddress.AddressLine4);
                lvitem.SubItems.Add(oSupplierAddress.AddressLine5);
                lvitem.SubItems.Add(Convert.ToString(oSupplierAddress.AddressNumber));
                lvitem.SubItems.Add(Convert.ToString(oSupplierAddress.AddressType));
                lvitem.SubItems.Add(oSupplierAddress.Contact);
                lvitem.SubItems.Add(((SageDataObject300.Country)oSupplierAddress.Country).Name);
                lvitem.SubItems.Add(((SageDataObject300.Supplier)oSupplierAddress.Supplier).Reference);
                lvitem.SubItems.Add(oSupplierAddress.Description);
                lvitem.SubItems.Add(oSupplierAddress.EMail);
                lvitem.SubItems.Add(oSupplierAddress.Fax);
                lvitem.SubItems.Add(oSupplierAddress.Name);
                lvitem.SubItems.Add(oSupplierAddress.Notes);
                lvitem.SubItems.Add(oSupplierAddress.Role);
                lvitem.SubItems.Add(((SageDataObject300.TaxCode)oSupplierAddress.TaxCode).Name);
                lvitem.SubItems.Add(oSupplierAddress.Telephone);
                lvitem.SubItems.Add(oSupplierAddress.Telephone2);
                lvitem.SubItems.Add(oSupplierAddress.VatNumber);

                this.listView1.Items.Add(lvitem);

                lvitem = null;
                i = i + 1;
                addRef = i;

            }

        } while (oPurchaseRecord.MoveNext());

    }
    else
    {
        MessageBox.Show("Failed to connect");
    }

}


Sage 50 Accounts - Example - View Supplier Addresses collection

Example - View Supplier Addresses collection

The example code below demonstrates how to view the supplier addresses collection.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oSupplierAddress As SageDataObject300.SupplierAddress
Dim oSupplierAddresses As SageDataObject300.SupplierAddresses

Dim lvitem As ListViewItem

' Declare Variables
Dim szDataPath As String

Try

    ' Create the SDO Engine object
    oSDO = New SageDataObject300.SDOEngine

    ' Create the workspace
    oWS = oSDO.Workspaces.Add("Example")

    ' Select company. The SelectCompany method takes the program install
    ' folder as a parameter
    szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

    ' A U.I. for company selection is presented to the user. If a company 'is selected,
    ' the path will be passed to the szDataPath variable.
    ' If not, or the Cancel button is selected, the variable will be left 'empty.
    If szDataPath <> "" Then

        ' Connect to Data Files
        If oWS.Connect(szDataPath, "", "", "Example") Then

            oSupplierAddress = oWS.CreateSupplierAddress
            oSupplierAddresses = oWS.CreateSupplierAddresses

            'Loop through Supplier addresses for this PurchaseRecord

            For Each oSupplierAddress In oSupplierAddresses

                lvitem = New ListViewItem
                lvitem.Text = oSupplierAddress.AddressLine1
                lvitem.SubItems.Add(oSupplierAddress.AddressLine2)
                lvitem.SubItems.Add(oSupplierAddress.AddressLine3)
                lvitem.SubItems.Add(oSupplierAddress.AddressLine4)
                lvitem.SubItems.Add(oSupplierAddress.AddressLine5)
                lvitem.SubItems.Add(oSupplierAddress.AddressNumber)
                lvitem.SubItems.Add(oSupplierAddress.AddressType)
                lvitem.SubItems.Add(oSupplierAddress.Contact)
                lvitem.SubItems.Add(Convert.ToString(oSupplierAddress.Country.Name))
                lvitem.SubItems.Add(Convert.ToString(oSupplierAddress.Supplier.Reference))
                lvitem.SubItems.Add(oSupplierAddress.Description)
                lvitem.SubItems.Add(oSupplierAddress.EMail)
                lvitem.SubItems.Add(oSupplierAddress.Fax)
                lvitem.SubItems.Add(oSupplierAddress.Name)
                lvitem.SubItems.Add(oSupplierAddress.Notes)
                lvitem.SubItems.Add(oSupplierAddress.Role)
                lvitem.SubItems.Add(Convert.ToString(oSupplierAddress.TaxCode.Name))
                lvitem.SubItems.Add(oSupplierAddress.Telephone)
                lvitem.SubItems.Add(oSupplierAddress.Telephone2)
                lvitem.SubItems.Add(oSupplierAddress.VatNumber)

                Me.ListView1.Items.Add(lvitem)

                lvitem = Nothing

            Next

            oSupplierAddress = Nothing

            ' Disconnect
            oWS.Disconnect()
        Else
            MessageBox.Show("Failed to connect!")
        End If

    End If

Catch ex As Exception
    ' Error Handling Code
    MessageBox.Show("The SDO generated the following error: " & ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try

' Destroy Objects
oSupplierAddress = Nothing
oWS = Nothing
oSDO = Nothing

Exit Sub
C#.NET [image] Copy C# Code

SageDataObject300.SDOEngine oSDO;

SageDataObject300.WorkSpace oWS;

SageDataObject300.SupplierAddresses oSupplierAddresses;

ListViewItem lvitem;

// Declare Variables

string szDataPath;

try

{

    // Create the SDO Engine object

    oSDO = new SageDataObject300.SDOEngine();

    //Instantiate WorkSpace

    oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

    // Select company

    szDataPath = oSDO.SelectCompany("C:\\Documents and Settings\\All Users\\Application Data\\Sage\\Accounts\\2023");

    // A U.I. for company selection is presented to the user. If a company 'is selected,

    // the path will be passed to the szDataPath variable.

    // If not, or the Cancel button is selected, the variable will be left 'empty.

    if (szDataPath != "")

    {

        // Connect to Data Files

        if (oWS.Connect(szDataPath, "", "", "Example"))

        {

            oSupplierAddresses = (SageDataObject300.SupplierAddresses)oWS.CreateSupplierAddresses();

            //Loop through Supplier addresses for this PurchaseRecord

            foreach (SageDataObject300.SupplierAddress oSupplierAddress in oSupplierAddresses)

            {

                lvitem = new ListViewItem();

                lvitem.Text = oSupplierAddress.AddressLine1;

                lvitem.SubItems.Add(oSupplierAddress.AddressLine2);

                lvitem.SubItems.Add(oSupplierAddress.AddressLine3);

                lvitem.SubItems.Add(oSupplierAddress.AddressLine4);

                lvitem.SubItems.Add(oSupplierAddress.AddressLine5);

                lvitem.SubItems.Add(Convert.ToString(oSupplierAddress.AddressNumber));

                lvitem.SubItems.Add(Convert.ToString(oSupplierAddress.AddressType));

                lvitem.SubItems.Add(oSupplierAddress.Contact);

                lvitem.SubItems.Add(((SageDataObject300.Country)oSupplierAddress.Country).Name);

                lvitem.SubItems.Add(((SageDataObject300.Supplier)oSupplierAddress.Supplier).Reference);

                lvitem.SubItems.Add(oSupplierAddress.Description);

                lvitem.SubItems.Add(oSupplierAddress.EMail);

                lvitem.SubItems.Add(oSupplierAddress.Fax);

                lvitem.SubItems.Add(oSupplierAddress.Name);

                lvitem.SubItems.Add(oSupplierAddress.Notes);

                lvitem.SubItems.Add(oSupplierAddress.Role);

                lvitem.SubItems.Add(((SageDataObject300.TaxCode)oSupplierAddress.TaxCode).Name);

                lvitem.SubItems.Add(oSupplierAddress.Telephone);

                lvitem.SubItems.Add(oSupplierAddress.Telephone2);

                lvitem.SubItems.Add(oSupplierAddress.VatNumber);

                this.listView1.Items.Add(lvitem);

                lvitem = null;

            }

            // Disconnect

            oWS.Disconnect();

        }

        else

        {

            MessageBox.Show("Failed to connect!");

        }

    }

}

catch (Exception ex)

{

    // Error Handling Code

    MessageBox.Show("The SDO generated the following error: " + ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);

}


Sage 50 Accounts - Example - Create New Contact History Item

Example - Create New Contact History Item

The example code below demonstrates how to create a new contact history item. This type of entry can be created for either customers or suppliers. The Major Contact Type determines which properties can and should be populated as per the same logic as the Sage 50 Accounts UI. For example, the Start and End properties can only be specified on a SageDataObject300.ContactHistoryMajorContactType.sdoTelephone.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code

        'Declare Variables
        Dim oSDO As SageDataObject300.SDOEngine
        Dim oWS As SageDataObject300.WorkSpace
        Dim oContactHistory As SageDataObject300.ContactHistory
        Dim oContacthistorys As SageDataObject300.ContactHistorys

        ' Declare Variables
        Dim szDataPath As String

        Try

            ' Create the SDO Engine object
            oSDO = New SageDataObject300.SDOEngine

            ' Create the workspace
            oWS = oSDO.Workspaces.Add("Example")

            ' Select company. The SelectCompany method takes the program install
            ' folder as a parameter
            szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

            ' A U.I. for company selection is presented to the user. If a company 'is selected,
            ' the path will be passed to the szDataPath variable.
            ' If not, or the Cancel button is selected, the variable will be left 'empty.
            If szDataPath <> "" Then

                ' Connect to Data Files
                If oWS.Connect(szDataPath, "", "", "Example") Then

                    'Create instnces of objects
                    oContactHistory = oWS.CreateContactHistory
                    oContacthistorys = oWS.CreateContactHistorys

                    'Required properties for this Major Contact Type (Telephone)
                    'Required and relevant properties/outcomes differ depending on the Major Contact Type
                    oContactHistory.AccountRef = "A1D001"
                    oContactHistory.MajorContactType = SageDataObject300.ContactHistoryMajorContactType.sdoTelephone
                    oContactHistory.Subject = "SDO Example Create a New Contact History Item"
                    oContactHistory.ContactDate = DateTime.Today
                    oContactHistory.CustomerSupplier = SageDataObject300.ContactType.sdoCustomerContact
                    oContactHistory.OurContactUserName = "SDO User"
                    oContactHistory.Outcome = SageDataObject300.ContactHistoryOutcome.sdoLeftMessage

                    'Call the Update method
                    If (oContactHistory.Update()) Then

                        MessageBox.Show("Contact History Updated")
                    Else

                        MessageBox.Show("Unable to Update Contact History")

                    End If
                Else

                    MessageBox.Show("Failed to connect!")

                End If

            End If

        Catch ex As Exception
            ' Error Handling Code
            MessageBox.Show("The SDO generated the following error: " & ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try

        ' Destroy Objects

        oContactHistory = Nothing
        oContacthistorys = Nothing
        oWS = Nothing
        oSDO = Nothing
C#.NET [image] Copy C# Code

            //Declare Objects
            SageDataObject300.SDOEngine oSDO;
            SageDataObject300.WorkSpace oWS;
            SageDataObject300.ContactHistory oContactHistory;
            SageDataObject300.ContactHistorys oContactHistorys;

            // Declare Variables
            string szDataPath;

            try
            {

                // Create the SDO Engine object
                oSDO = new SageDataObject300.SDOEngine();

                //Instantiate WorkSpace
                oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

                // Select company. The SelectCompany method takes the program install
                // folder as a parameter
                szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2023");

                // A U.I. for company selection is presented to the user. If a company 'is selected,
                // the path will be passed to the szDataPath variable.
                // If not, or the Cancel button is selected, the variable will be left 'empty.
                if (szDataPath != "")
                {

                    // Connect to Data Files
                    if (oWS.Connect(szDataPath, "", "", "Example"))
                    {
                        //Create instances of objects
                        oContactHistory = (SageDataObject300.ContactHistory)oWS.CreateContactHistory();
                        oContactHistorys = (SageDataObject300.ContactHistorys)oWS.CreateContactHistorys();

                        //Required properties for this Major Contact Type (Telephone)
                        //Required and relevant properties/outcomes differ depending on the Major Contact Type
                        oContactHistory.AccountRef = "A1D001";
                        oContactHistory.MajorContactType = SageDataObject300.ContactHistoryMajorContactType.sdoTelephone;
                        oContactHistory.Subject = "SDO Example Create a New Contact History Item";
                        oContactHistory.ContactDate = DateTime.Today;
                        oContactHistory.CustomerSupplier = SageDataObject300.ContactType.sdoCustomerContact;
                        oContactHistory.OurContactUserName = "SDO User";
                        oContactHistory.Outcome = SageDataObject300.ContactHistoryOutcome.sdoLeftMessage;

                        //Call the Update method
                        if (oContactHistory.Update())
                        {
                            MessageBox.Show("Contact History Updated");
                        }

                        else
                        {
                            MessageBox.Show("Unable to Update Contact History");
                        }

                        // Disconnect
                        oWS.Disconnect();
                    }
                    else
                    {
                        MessageBox.Show("Failed to connect!");
                    }
                }
            }

            catch (Exception ex)
            {
                // Error Handling Code
                MessageBox.Show("The SDO generated the following error: " + ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }


Sage 50 Accounts - Example - Edit a Contact History Item

Example - Edit a Contact History Item

The example code below demonstrates how to edit an existing Contact History Item. The example requires an exisiting Contact History Item on a customer/supplier record with the reference "A1D001" and a Subject of "SDO Testing". A Sage 50 Accounts user is also required to be setup as " SDO User".

This example uses the GetEnumerator to move through the collection of ContactHistorys.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
'Declare Variables
        Dim oSDO As SageDataObject300.SDOEngine
        Dim oWS As SageDataObject300.WorkSpace
        Dim oContactHistory As SageDataObject300.ContactHistory
        Dim oContacthistorys As SageDataObject300.ContactHistorys

        ' Declare Variables
        Dim szDataPath As String

        Try

            ' Create the SDO Engine object
            oSDO = New SageDataObject300.SDOEngine

            ' Create the workspace
            oWS = oSDO.Workspaces.Add("Example")

            ' Select company. The SelectCompany method takes the program install
            ' folder as a parameter
            szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

            ' A U.I. for company selection is presented to the user. If a company 'is selected,
            ' the path will be passed to the szDataPath variable.
            ' If not, or the Cancel button is selected, the variable will be left 'empty.
            If szDataPath <> "" Then

                ' Connect to Data Files
                If oWS.Connect(szDataPath, "SDO User", "", "Example") Then

                    'Create instances of objects
                    oContactHistory = oWS.CreateContactHistory
                    oContacthistorys = oWS.CreateContactHistorys

                    'Declare and instantiate the Enumerator
                    Dim pEnum As System.Collections.IEnumerator = oContacthistorys.GetEnumerator

                    'Iterate through the Enumerator
                    While (pEnum.MoveNext())

                        'Set the object to the position of the Enumerator
                        oContactHistory = pEnum.Current

                        If oContactHistory.AccountRef = "A1D001" And oContactHistory.Subject = "SDO Testing" Then

                            oContactHistory.OurContactUserName = "SDO User"
                            oContactHistory.Balance = 99999.99
                            oContactHistory.Duration = 999999
                            oContactHistory.End = 1
                            oContactHistory.Start = 2
                            oContactHistory.Invoiced = 0
                            oContactHistory.Location = 1
                            oContactHistory.CustomerSupplier = SageDataObject300.ContactType.sdoCustomerContact
                            oContactHistory.Note1 = "Note1"
                            oContactHistory.FollowUpDate = DateTime.Today.AddDays(30)

                            'Call the Update method
                            If (oContactHistory.Update()) Then

                                MessageBox.Show("Contact History Updated")

                            Else

                                MessageBox.Show("Unable to Update Contact History")

                            End If

                        End If

                    End While

                Else
                    MessageBox.Show("Failed to connect!")

                End If

            End If

        Catch ex As Exception
            ' Error Handling Code
            MessageBox.Show("The SDO generated the following error: " & ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try

        ' Destroy Objects

        oContactHistory = Nothing
        oContacthistorys = Nothing
        oWS = Nothing
        oSDO = Nothing
C#.NET [image] Copy C# Code
//Declare Objects
            SageDataObject300.SDOEngine oSDO;
            SageDataObject300.WorkSpace oWS;
            SageDataObject300.ContactHistory oContactHistory;
            SageDataObject300.ContactHistorys oContactHistorys;

            // Declare Variables
            string szDataPath;

            try
            {

                // Create the SDO Engine object
                oSDO = new SageDataObject300.SDOEngine();

                //Instantiate WorkSpace
                oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

                // Select company. The SelectCompany method takes the program install
                // folder as a parameter
                szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2023");

                // A U.I. for company selection is presented to the user. If a company 'is selected,
                // the path will be passed to the szDataPath variable.
                // If not, or the Cancel button is selected, the variable will be left 'empty.
                if (szDataPath != "")
                {

                    // Connect to Data Files
                    if (oWS.Connect(szDataPath, "SDO User", "", "Example"))
                    {
                        //Create instances of objects
                        oContactHistory = (SageDataObject300.ContactHistory)oWS.CreateContactHistory();
                        oContactHistorys = (SageDataObject300.ContactHistorys)oWS.CreateContactHistorys();

                        //Declare and instantiate the Enumerator
                        System.Collections.IEnumerator pEnum = oContactHistorys.GetEnumerator();

                        //Iterate through the Enumberator
                        while (pEnum.MoveNext())
                        {

                            //Set the object to the position of the Enumerator
                            oContactHistory = (SageDataObject300.ContactHistory)pEnum.Current;

                            if ((oContactHistory.AccountRef == "A1D001") & (oContactHistory.Subject == "SDO Testing"))
                            {

                                oContactHistory.OurContactUserName = "SDO User";
                                oContactHistory.Balance = 99999.99;
                                oContactHistory.Duration = 999999;
                                oContactHistory.End = 1;
                                oContactHistory.Start = 2;
                                oContactHistory.Invoiced = 0;
                                oContactHistory.Location = 1;
                                oContactHistory.CustomerSupplier = SageDataObject300.ContactType.sdoCustomerContact;
                                oContactHistory.Note1 = "Note1";
                                oContactHistory.FollowUpDate = DateTime.Today.AddDays(30);

                                //Call the Update method
                                if (oContactHistory.Update())
                                {
                                    MessageBox.Show("Contact History Updated");
                                }

                                else
                                {
                                    MessageBox.Show("Unable to Update Contact History");
                                }

                            }

                        }

                        // Disconnect
                        oWS.Disconnect();
                    }
                    else
                    {
                        MessageBox.Show("Failed to connect!");
                    }
                }
            }

            catch (Exception ex)
            {
                // Error Handling Code
                MessageBox.Show("The SDO generated the following error: " + ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }


Sage 50 Accounts - Example - Deleting a Contact History Item

Example - Deleting a Contact History Item

The example code below demonstrates how to delete an existing Contact History Item. The example requires an exisiting Contact History Item on a customer/supplier record with the reference "A1D001" and a Subject of "SDO Testing". A Sage 50 Accounts user is also required to be setup as " SDO User".

This example uses the GetEnumerator to move through the collection of ContactHistorys.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code

        'Declare Variables
        Dim oSDO As SageDataObject300.SDOEngine
        Dim oWS As SageDataObject300.WorkSpace
        Dim oContactHistory As SageDataObject300.ContactHistory
        Dim oContacthistorys As SageDataObject300.ContactHistorys

        ' Declare Variables
        Dim szDataPath As String
        Dim bFlag As Boolean = False

        Try

            ' Create the SDO Engine object
            oSDO = New SageDataObject300.SDOEngine

            ' Create the workspace
            oWS = oSDO.Workspaces.Add("Example")

            ' Select company. The SelectCompany method takes the program install
            ' folder as a parameter
            szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

            ' A U.I. for company selection is presented to the user. If a company 'is selected,
            ' the path will be passed to the szDataPath variable.
            ' If not, or the Cancel button is selected, the variable will be left 'empty.
            If szDataPath <> "" Then

                ' Connect to Data Files
                If oWS.Connect(szDataPath, "SDO User", "", "Example") Then

                    'Create instnces of objects
                    oContactHistory = oWS.CreateContactHistory
                    oContacthistorys = oWS.CreateContactHistorys

                    'Declare and instantiate the Enumerator
                    Dim pEnum As System.Collections.IEnumerator = oContacthistorys.GetEnumerator

                    'Iterate through the Enumberator
                    While (pEnum.MoveNext())

                        'Set the object to the position of the Enumerator
                        oContactHistory = pEnum.Current

                        If oContactHistory.AccountRef = "A1D001" And oContactHistory.Subject = "SDO Testing" Then

                            bFlag = True

                            'Call the Update method
                            If (oContactHistory.Delete()) Then

                                MessageBox.Show("Contact History Deleted")

                            Else

                                MessageBox.Show("Unable to Delete Contact History")

                            End If

                        End If

                    End While

                    If bFlag = False Then

                        MessageBox.Show("Unable to find specified Contact History")

                    End If

                Else
                    MessageBox.Show("Failed to connect!")

                End If

            End If

        Catch ex As Exception
            ' Error Handling Code
            MessageBox.Show("The SDO generated the following error: " & ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try

        ' Destroy Objects

        oContactHistory = Nothing
        oContacthistorys = Nothing
        oWS = Nothing
        oSDO = Nothing
C#.NET [image] Copy C# Code

            //Declare Objects
            SageDataObject300.SDOEngine oSDO;
            SageDataObject300.WorkSpace oWS;
            SageDataObject300.ContactHistory oContactHistory;
            SageDataObject300.ContactHistorys oContactHistorys;

            // Declare Variables
            string szDataPath;
            bool bFlag = false;

            try
            {

                // Create the SDO Engine object
                oSDO = new SageDataObject300.SDOEngine();

                //Instantiate WorkSpace
                oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

                // Select company. The SelectCompany method takes the program install
                // folder as a parameter
                szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

                // A U.I. for company selection is presented to the user. If a company 'is selected,
                // the path will be passed to the szDataPath variable.
                // If not, or the Cancel button is selected, the variable will be left 'empty.
                if (szDataPath != "")
                {

                    // Connect to Data Files
                    if (oWS.Connect(szDataPath, "SDO User", "", "Example"))
                    {
                        //Create instances of objects
                        oContactHistory = (SageDataObject300.ContactHistory)oWS.CreateContactHistory();
                        oContactHistorys = (SageDataObject300.ContactHistorys)oWS.CreateContactHistorys();

                        //Declare and instantiate the Enumerator
                        System.Collections.IEnumerator pEnum = oContactHistorys.GetEnumerator();

                        //Iterate through the Enumberator
                        while (pEnum.MoveNext())
                        {

                            //Set the object to the position of the Enumerator
                            oContactHistory = (SageDataObject300.ContactHistory)pEnum.Current;

                            if ((oContactHistory.AccountRef == "A1D001") & (oContactHistory.Subject == "SDO Testing"))
                            {
                                bFlag = true;

                                //Call the Delete method
                                if (oContactHistory.Delete())
                                {
                                    MessageBox.Show("Contact History Deleted");
                                }

                                else
                                {
                                    MessageBox.Show("Unable to Delete Contact History");
                                }

                            }

                        }
                        if (!bFlag )
                        {
                            MessageBox.Show("Unable to find specified Contact History Item");
                        }

                        // Disconnect
                        oWS.Disconnect();
                    }
                    else
                    {
                        MessageBox.Show("Failed to connect!");
                    }
                }
            }

            catch (Exception ex)
            {
                // Error Handling Code
                MessageBox.Show("The SDO generated the following error: " + ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }


Sage 50 Accounts - Example - Accessing a Customer Memo

Example - Accessing a Customer Memo

The example code below demonstrates how to access a Customer Memo.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

The code also includes a generic error handler. Clearly, you would respond differently depending on the actual exception thrown.

VB.NET [image] Copy VB Code
 ' Declare Objects
Dim oSDO  As SageDataObject300.SDOEngine
Dim oWS  As SageDataObject300.WorkSpace
Dim oSalesRecord  As SageDataObject300.SalesRecord

' Declare Variables
Dim szDataPath  As  String

' Create the SDO Engine Object
oSDO =  New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company  The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> ""  Then

' Try to Connect - Will throw
    an exception if it fails
If oWS.Connect(szDataPath, "", "", "Example")  Then

' Create Instance of Purchase Record Object
oSalesRecord = oWS.CreateObject("SalesRecord")

' Get the First Purchase Record and add a Memo to it
oSalesRecord.MoveFirst()
oSalesRecord.Edit()
oSalesRecord.Memo = CStr("Memo text generated by SDO")

' Update the Record
If oSalesRecord.Update  Then

MsgBox("Added Memo to Account: " & oSalesRecord.Fields.Item("ACCOUNT_REF").Value, MsgBoxStyle.OKOnly, "SDO Example")

Else

MsgBox("Memo Update Unsuccessful.", MsgBoxStyle.OKOnly, "SDO Example")

End  If

' Get the First Purchase Record and Read the
    Memo
oSalesRecord.MoveFirst()
MsgBox("Memo text for account : " & oSalesRecord.Fields.Item("ACCOUNT_REF").Value & vbCrLf & vbCrLf & oSalesRecord.Memo, MsgBoxStyle.OKOnly, "SDO Example")

' Disconnect
oWS.Disconnect()

End  If

End  If

' Destroy the Objects
oSalesRecord =  Nothing
oWS =  Nothing
oSDO =  Nothing

Exit  Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.SalesRecord oSalesRecord;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate Sales Record object

  oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");

  //Get the first Sales Record and add a memo to it

  oSalesRecord.MoveFirst();

  oSalesRecord.Edit();

  oSalesRecord.Memo = (String)"Memo text for the first Customer";

  //Update the record

  if (oSalesRecord.Update())

  {

    MessageBox.Show("Added Memo to Account: " + SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));

  }

  else

  {

    MessageBox.Show("Failed to add the memo");

  }

  //Get the first Sales record and read the memo

  oSalesRecord.MoveFirst();

  MessageBox.Show(oSalesRecord.Memo);

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example -�Allocating an existing�Sales Credit Note to an existing Sales Invoice

Example - Allocating an existing Sales Credit Note to an existing Sales Invoice

The example code below demonstrates how to allocate an existing sales credit note against an existing sales invoice.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oSalesRecord As SageDataObject300.SalesRecord
Dim oTransactionPost As SageDataObject300.TransactionPost
Dim oInvoiceSplitData As SageDataObject300.SplitData
Dim oInvoiceHeaderData As SageDataObject300.HeaderData
Dim oCreditHeaderData As SageDataObject300.HeaderData

' Declare Variables
Dim szDataPath As String
Dim bTransactionFound As Boolean
Dim dInvoiceValue As Double
Dim iCreditSplit, iInvoiceSplit As Integer

 ' Create the SDO Engine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

' Try to Connect - Will throw an exception if it fails
If oWS.Connect(szDataPath, "", "", "Example") Then

' Create Instance Objects to Post the Credit Note
oSalesRecord = oWS.CreateObject("SalesRecord")
oTransactionPost = oWS.CreateObject("TransactionPost")
oCreditHeaderData = oWS.CreateObject("HeaderData")

' Initialise Index Field with value to search
oSalesRecord.Fields.Item("ACCOUNT_REF").Value = CStr ("SWA001")

' Perform Find for an exact match
If oSalesRecord.Find(False) Then
'Link to the Credit Splits
oCreditHeaderData = oSalesRecord.Link
oCreditHeaderData.MoveFirst()

Do
If oCreditHeaderData.Fields.Item("INV_REF").Value = CStr("61") Then

' Set the credit transaction found flag
bTransactionFound = True

' Store the Credit note Split number
iCreditSplit = CInt(oCreditHeaderData.Fields.Item("FIRST_SPLIT").Value)

' Exit the loop
Exit Do

End If

Loop Until Not oCreditHeaderData.MoveNext

If bTransactionFound Then
'Set the found flag to false
bTransactionFound = False

' Transaction found
MsgBox("Credit Note transaction has been found.", MsgBoxStyle.OKOnly, "SDO Examples")

'Find the Sales Invoice
oInvoiceHeaderData = oSalesRecord.Link

' Move to the first Header on the Customer account
oInvoiceHeaderData.MoveFirst()

Do
If oInvoiceHeaderData.Fields.Item("INV_REF").Value = CStr("51") Then

' Set the invoice transaction found flag
bTransactionFound = True

'Store the Invoice Split number and aount to allocate
oInvoiceSplitData = oInvoiceHeaderData.Link
oInvoiceSplitData.MoveFirst()
iInvoiceSplit = oInvoiceSplitData.RecordNumber

dInvoiceValue = CDbl(oInvoiceSplitData.Fields.Item("NET_AMOUNT").Value) + CDbl(oInvoiceSplitData.Fields.Item("TAX_AMOUNT").Value) - CDbl(oInvoiceSplitData.Fields.Item("AMOUNT_PAID").Value)

' Exit the loop
Exit Do

End If

Loop Until Not oInvoiceHeaderData.MoveNext

If bTransactionFound Then
' Invoice transaction found
MsgBox("Invoice transaction has been found.", MsgBoxStyle.OKOnly, "SDO Examples")

' Allocate Credit Against Invoice
If oTransactionPost.AllocatePayment(CInt(iInvoiceSplit), CInt(iCreditSplit), CDbl(dInvoiceValue), CDate(Now))

MsgBox("Allocation successful.", MsgBoxStyle.OKOnly, "SDO Examples")
Else
MsgBox("Allocation unsuccessful.", MsgBoxStyle.OKOnly, "SDO Examples")
End If
Else
' Invoice transaction not found
MsgBox("Invoice transaction has NOT been found.", MsgBoxStyle.OKOnly, "SDO Examples")
End If
Else
' Credit transaction not found
MsgBox("Credit transaction has NOT been found.", MsgBoxStyle.OKOnly, "SDO Examples")
End If
Else
' Account not found
MsgBox("Sales ledger account NOT found.", MsgBoxStyle.OKOnly, "SDO Examples")
End If
End If

' Disconnect
oWS.Disconnect()

End If
' Destroy Objects
oSalesRecord = Nothing
oInvoiceHeaderData = Nothing
oInvoiceSplitData = Nothing
oCreditHeaderData = Nothing
oTransactionPost = Nothing
oSDO = Nothing
oWS = Nothing

Exit Sub
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.SalesRecord oSalesRecord;
            SageDataObject300.TransactionPost oTransactionPost;
            SageDataObject300.SplitData oCreditSplitData;
            SageDataObject300.HeaderData oInvoiceHeaderData;
            SageDataObject300.HeaderData oCreditHeaderData;
            bool bTransactionFound = false;
            bool bRecordFound = false;
            double dCreditValue = 0;
            int iCreditSplit = 0;
            int iInvoiceSplit = 0;

            try
            {
                // Create an Instance of the SalesRecord Object
                oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");
                oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");
                oCreditHeaderData = (SageDataObject300.HeaderData)oWS.CreateObject("HeaderData");

                // Initialise Index Field with value to search
                SDOHelper.Write(oSalesRecord, "ACCOUNT_REF", (String)"CUST0001");

                // Perform Find for an exact match
                bRecordFound = oSalesRecord.Find(false);

                if (bRecordFound)
                {
                    // Link to Credit Splits
                    oCreditHeaderData = (SageDataObject300.HeaderData)oSalesRecord.Link;
                    oCreditHeaderData.MoveFirst();

                    do
                    {
                        if ((String)SDOHelper.Read(oCreditHeaderData, "INV_REF") == (String)"SC0001")
                        {
                            // Set the credit transaction found flag
                            bTransactionFound = true;

                            // Store the Credit note Split number and Amount to allocate
                            oCreditSplitData = (SageDataObject300.SplitData)oCreditHeaderData.Link;
                            oCreditSplitData.MoveFirst();
                            iCreditSplit = (int)oCreditSplitData.RecordNumber;
                            dCreditValue = ((double)SDOHelper.Read(oCreditSplitData, "NET_AMOUNT") + (double)SDOHelper.Read(oCreditSplitData, "TAX_AMOUNT")) -
                                (double)SDOHelper.Read(oCreditSplitData, "AMOUNT_PAID");

                            // Exit the loop
                            break;
                        }
                    } while (!(!oCreditHeaderData.MoveNext()));

                    if (bTransactionFound)
                    {
                        //Set the found flag to false
                        bTransactionFound = false;

                        // Transaction found
                        MessageBox.Show("Credit Note transaction has been found.");

                        //Find the Sales Invoice
                        oInvoiceHeaderData = (SageDataObject300.HeaderData)oSalesRecord.Link;

                        // Move to the first Header on Customer account
                        oInvoiceHeaderData.MoveFirst();

                        do
                        {
                            if ((String)SDOHelper.Read(oInvoiceHeaderData, "INV_REF") == (string)"SI0001")
                            {
                                // Set the invoice transaction found flag
                                bTransactionFound = true;

                                //Store the Invoice Split number
                                iInvoiceSplit = (int)SDOHelper.Read(oInvoiceHeaderData, "FIRST_SPLIT");

                                // Exit the loop
                                break;
                            }
                        } while (!(!oInvoiceHeaderData.MoveNext()));

                        if (bTransactionFound)
                        {
                            // Invoice transaction found
                            MessageBox.Show("Invoice transaction has been found.");

                            // Allocate Credit Against Invoice
                            if (oTransactionPost.AllocatePayment((int)iInvoiceSplit, (int)iCreditSplit, (double)dCreditValue, (DateTime)DateTime.Now))
                            {

                                MessageBox.Show("Allocation successful.");
                            }
                            else
                            {
                                MessageBox.Show("Allocation unsuccessful.");
                            }
                        }
                        else
                        {
                            // Invoice transaction not found
                            MessageBox.Show("Invoice transaction not found.");
                        }
                    }
                    else
                    {
                        // Credit transaction not found
                        MessageBox.Show("Credit transaction not found.");
                    }
                }
                else
                {
                    // Account not found
                    MessageBox.Show("Sales Ledger account not found.");
                }

                // Disconnect
                oWS.Disconnect();
            }
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example -�Allocating a Sales Payment to a�Sales Payment On Account

Example - Allocating a Sales Payment to a Sales Payment On Account

The example code below demonstrates how to allocate a new Sales Payment to an existing Sales Payment On Account (Sales Payments can also allocate to Sales Receipts and Sales Credits).
Clearly, this example could be modified so that existing SPs or SCs were used instead.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code

    'Declare Objects
    Dim oSDO As SageDataObject300.SDOEngine
    Dim oWS As SageDataObject300.WorkSpace
    Dim oTransactionPost As SageDataObject300.TransactionPost
    Dim oHeaderData As SageDataObject300.HeaderData
    Dim oSplitData As SageDataObject300.SplitData
    Dim oSalesRecord As SageDataObject300.SalesRecord

    'Declare Variables
    Dim szDataPath As String
    Dim SPTranHeader As Integer
    Dim SPTranSplit As Integer
    Dim SATranSplit As Integer

    Dim AllocationAmount As Double = CDbl(160)

    'Create the SDO Engine Object
    oSDO = New SageDataObject300.SDOEngine()

    'Create the Workspace
    oWS = oSDO.Workspaces.Add("Example")

    'Select company. The SelectCompany method takes the program install
    'folder as a parameter
    szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

    'A U.I. for company selection is presented to the user. If a company is selected,
    'the path will be passed to the szDataPath variable.
    'If not, or the Cancel button is selected, the variable will be left empty
    If Not szDataPath = "" Then

        'Connect to Data Files
        If Not oWS.Connect(szDataPath, "", "", "Example") Then

            MsgBox("Connection failed!", vbOKOnly, "SDO Examples")

            'Disconnect
            oWS.Disconnect()

            oWS = Nothing
            oSDO = Nothing

            Exit Sub

        End If

    Else

        MsgBox("Invalid data path", vbOKOnly, "SDO Exmaples")

        oWS = Nothing
        oSDO = Nothing

        Exit Sub

    End If

    'Post SP Transaction

    'Create an Instance of Objects
    oTransactionPost = oWS.CreateObject("TransactionPost")
    oSalesRecord = oWS.CreateObject("SalesRecord")

    'Get Customer "A1D001"
    oSalesRecord.Fields.Item("ACCOUNT_REF").Value = CStr("CUST001")

    If Not oSalesRecord.Find(False) Then

        MsgBox("Customer not found!", vbOKOnly, "SDO Examples")

        'Disconnect
        oWS.Disconnect()

        oTransactionPost = Nothing
        oSplitData = Nothing
        oHeaderData = Nothing
        oSalesRecord = Nothing
        oWS = Nothing
        oSDO = Nothing

        Exit Sub

    End If

    'Populate Header fields
    oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
    oTransactionPost.Header("DATE").Value = DateTime.Now
    oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoSP)
    oTransactionPost.Header("DETAILS").Value = CStr("Sales Payment to Allocate")
    oTransactionPost.Header("INV_REF").Value = CStr("SPA1")
    oTransactionPost.Header("BANK_CODE").Value = CStr("1210")

    ' Populate Foreign Currency Fields
    oTransactionPost.Header("CURRENCY").Value = oSalesRecord.Fields.Item("CURRENCY").Value

    'SPs have only one split
    oSplitData = oTransactionPost.Items.Add()

    'Fill in the Split fields
    oSplitData.Fields.Item("TYPE").Value = CByte(oTransactionPost.Header("TYPE").Value)
    oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr(oTransactionPost.Header("BANK_CODE").Value)
    oSplitData.Fields.Item("TAX_CODE").Value = CInt(9)
    oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(AllocationAmount)
    oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(0)
    oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)
    oSplitData.Fields.Item("DETAILS").Value = CStr(oTransactionPost.Header("DETAILS").Value)

    'Update the TransactionPost Object
    If oTransactionPost.Update Then

        MsgBox("SP Transaction Posted Successfully", vbOKOnly, "SDO Examples")

    Else

        MsgBox("SP Transaction Post Failed", vbOKOnly, "SDO Examples")

    End If

    'Store Header RecordNumber of SP
    SPTranHeader = oTransactionPost.PostingNumber

    'Destroy Objects
    oSplitData = Nothing

    'Find SA Transaction and Obtain Split Record Number

    'Create an instance of SplitData
    oSplitData = oWS.CreateObject("SplitData")

    'Need to find SA transaction with date 29/08/2006 and amount of �160, outstanding

    oSplitData.MoveFirst()

    Dim bFound As Boolean = False

    'Search SplitData for the correct transaction
    'NOTE: it is possible that the transaction may not be unique based on the above criteria

    Do

        If oSplitData.Fields.Item("TYPE").Value = CByte(SageDataObject300.TransType.sdoSA) _
        And oSplitData.Fields.Item("DATE").Value = CDate("22/02/2017") _
        And oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(AllocationAmount) _
        And oSplitData.Fields.Item("AMOUNT_PAID").Value = CDbl(0) Then

            bFound = True
            Exit Do

        End If

    Loop Until Not oSplitData.MoveNext

    'Check if the transaction is found
    If Not bFound Then

        MsgBox("No Valid SA Transaction", vbOKOnly, "SDO Examples")

        'Disconnect
        oWS.Disconnect()

        oTransactionPost = Nothing
        oSplitData = Nothing
        oHeaderData = Nothing
        oSalesRecord = Nothing
        oWS = Nothing
        oSDO = Nothing

        Exit Sub

    End If

    SATranSplit = oSplitData.RecordNumber

    'Destroy Objects
    oSplitData = Nothing

    'Obtain Split Number for SP (AllocatePayment requires split record numbers)
    'Create an instance of HeaderData
    oHeaderData = oWS.CreateObject("HeaderData")

    'Read HeaderData for SP
    oHeaderData.Read(SPTranHeader)

    'Store Split Number for SP
    SPTranSplit = CInt(oHeaderData.Fields.Item("FIRST_SPLIT").Value)

    'ALLOCATE TRANSACTIONS

    'Allocate SP and SA split transactions together
    If oTransactionPost.AllocatePayment(SPTranSplit, SATranSplit, AllocationAmount, DateTime.Now) Then

        MsgBox("SP and SA allocation successful", vbOKOnly, "SDO Examples")

    Else

        MsgBox("Allocation Failed", vbOKOnly, "SDO Examples")

    End If

    'Disconnect
    oWS.Disconnect()

    oTransactionPost = Nothing
    oSplitData = Nothing
    oHeaderData = Nothing
    oSalesRecord = Nothing
    oWS = Nothing
    oSDO = Nothing

    Exit Sub
End Sub
�
C#.NET [image] Copy C# Code
        //Declare Objects
        SageDataObject300.SDOEngine oSDO;
        SageDataObject300.WorkSpace oWS;
        SageDataObject300.TransactionPost oTransactionPost;
        SageDataObject300.HeaderData oHeaderData;
        SageDataObject300.SplitData oSplitData;
        SageDataObject300.SalesRecord oSalesRecord;

        //Declare Variables
        string szDataPath;
        int SPTranHeader;
        int SPTranSplit;
        int SATranSplit;

        double AllocationAmount = (double)160;

        //Create the SDO Engine Object
        oSDO = new SageDataObject300.SDOEngine();

        //Create the Workspace
        oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

        //Select company. The SelectCompany method takes the program install
        //folder as a parameter
        szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

        //A U.I. for company selection is presented to the user. If a company is selected,
        //the path will be passed to the szDataPath variable.
        //If not, or the Cancel button is selected, the variable will be left empty
        if (!(szDataPath == ""))
        {

            //Connect to Data Files
            if (!oWS.Connect(szDataPath, "", "", "Example"))
            {

                MessageBox.Show("Connection failed!");

                //Disconnect
                oWS.Disconnect();

                oWS = null;
                oSDO = null;

                return;

            }
        }

        else
        {

            MessageBox.Show("Invalid data path");

            oWS = null;
            oSDO = null;

            return;

        }

        //Post SP Transaction

        //Create an Instance of Objects
        oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");
        oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");

        //Get Customer "A1D001"
        SDOHelper.Write(oSalesRecord,"ACCOUNT_REF", (string)"A1D001");

        if (!oSalesRecord.Find(false))
        {

            MessageBox.Show("Customer not found!");

            //Disconnect
            oWS.Disconnect();

            oTransactionPost = null;
            oSplitData = null;
            oHeaderData = null;
            oSalesRecord = null;
            oWS = null;
            oSDO = null;

            return;

        }

        //Populate Header fields
        SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));
        SDOHelper.Write(oTransactionPost.Header, "DATE", DateTime.Now);
        SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)(SageDataObject300.TransType.sdoSP));
        SDOHelper.Write(oTransactionPost.Header, "DETAILS", (String)("Sales Payment to Allocate"));
        SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)("SPA1"));
        SDOHelper.Write(oTransactionPost.Header, "BANK_CODE",(String)("1210"));

        //Populate the foreign currency fields
        SDOHelper.Write(oTransactionPost.Header, "CURRENCY", SDOHelper.Read(oSalesRecord, "CURRENCY"));

        //SPs have only one split
        oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

        //Fill in the Split fields
        SDOHelper.Write(oSplitData, "TYPE", Convert.ToByte(SDOHelper.Read(oTransactionPost.Header, "TYPE")));
        SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)SDOHelper.Read(oTransactionPost.Header, "BANK_CODE"));
        SDOHelper.Write(oSplitData, "TAX_CODE", (int)9);
        SDOHelper.Write(oSplitData, "NET_AMOUNT", (double)AllocationAmount);
        SDOHelper.Write(oSplitData, "TAX_AMOUNT", (double)0);
        SDOHelper.Write(oSplitData, "DATE", (System.DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));
        SDOHelper.Write(oSplitData, "DETAILS", (string)SDOHelper.Read(oTransactionPost.Header, "DETAILS"));

        //Update the TransactionPost Object
        if (oTransactionPost.Update())
        {

            MessageBox.Show("SP Transaction Posted Successfully");
        }

        else
        {

            MessageBox.Show("SP Transaction Post Failed");

        }

        //Store Header RecordNumber of SP
        SPTranHeader = oTransactionPost.PostingNumber;

        //Destroy Objects
        oSplitData = null;

        //Find SA Transaction and Obtain Split Record Number

        //Create an instance of SplitData
        oSplitData = (SageDataObject300.SplitData)oWS.CreateObject("SplitData");

        //Need to find SA transaction with date 08/06/2010 and amount of £160, outstanding

        oSplitData.MoveFirst();

        bool bFound = false;

        //Search SplitData for the correct transaction
        //NOTE: it is possible that the transaction may not be unique based on the above criteria

        do {

            if (Convert.ToByte(SDOHelper.Read(oSplitData, "TYPE")) == (Convert.ToByte (SageDataObject300.TransType.sdoSA)) &
                (DateTime)SDOHelper.Read(oSplitData, "DATE") == (System.DateTime)DateTime.Parse("08/06/2010") &
                (Double)SDOHelper.Read(oSplitData, "NET_AMOUNT") == (double)AllocationAmount &
                 ((Double)SDOHelper.Read(oSplitData, "AMOUNT_PAID") == (double)0));
            {

                bFound = true;
                break;
            }
        }

        while (!oSplitData.MoveNext());

        //Check if the transaction is found
        if (!bFound)
        {

            MessageBox.Show("No Valid SA Transaction");

            //Disconnect
            oWS.Disconnect();

            oTransactionPost = null;
            oSplitData = null;
            oHeaderData = null;
            oSalesRecord = null;
            oWS = null;
            oSDO = null;

            return;

        }

        SATranSplit = oSplitData.RecordNumber;

        //Destroy Objects
        oSplitData = null;

        //Obtain Split Number for SP (AllocatePayment requires split record numbers)
        //Create an instance of HeaderData
        oHeaderData = (SageDataObject300.HeaderData)oWS.CreateObject("HeaderData");

        //Read HeaderData for SP
        oHeaderData.Read(SPTranHeader);

        //Store Split Number for SP
        SPTranSplit = (int)SDOHelper.Read(oHeaderData, "FIRST_SPLIT");

        //ALLOCATE TRANSACTIONS

        //Allocate SP and SA split transactions together
        if (oTransactionPost.AllocatePayment(SPTranSplit, SATranSplit, AllocationAmount, DateTime.Now))
        {

            MessageBox.Show("SP and SA allocation successful");
        }

        else
        {

            MessageBox.Show("Allocation Failed");

        }

        //Disconnect
        oWS.Disconnect();

        oTransactionPost = null;
        oSplitData = null;
        oHeaderData = null;
        oSalesRecord = null;
        oWS = null;
        oSDO = null;


Sage 50 Accounts - Example - Creating a Customer Delivery Address

Example - Creating a Customer Delivery Address

The example code below demonstrates how to create a Customer Delivery Address.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
                              ' Declare Objects
Dim  oSDO  As
                              SageDataObject300.SDOEngine
Dim  oWS  As
                              SageDataObject300.WorkSpace
Dim oSalesRecord  As
                              SageDataObject300.SalesRecord
Dim oSalesDeliveryRecord  As
                              SageDataObject300.SalesDeliveryRecord

' Declare Variables
Dim  szDataPath  As String
Dim bFound  As Boolean
Dim bEnd  As Boolean
Dim iAddNo  As Integer
Dim strRef  As String
Dim strAddNo  As String
Dim bFlag  As Boolean

' Error Handler
On Error GoTo Error_Handler

' Create the SDO Engine object
oSDO =  New   SageDataObject300.SDOEngine()

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> ""  Then

' Connect to Data Files
If oWS.Connect(szDataPath, "", "", "Example")
                              Then

' Create Instances of the Sales Objects
oSalesRecord = oWS.CreateObject("SalesRecord")
oSalesDeliveryRecord = oWS.CreateObject("SalesDeliveryRecord")

' Read the first customer record
oSalesRecord.MoveFirst()

' Initialise flag's
bEnd = False
bFound = False

' Move to First Record in the delivery address file
oSalesDeliveryRecord.MoveFirst()

' Search records for last occurrence in the file of this customer
' or until we have read all the records in the file
Do

' Do we have a match ?
If (oSalesDeliveryRecord.Fields.Item("ACCOUNT_REF").Value = oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
                               Then

' Yes, so store the address ref
iAddNo = oSalesDeliveryRecord.Fields.Item("ADDRESS_REF").Value

' Set the found flag to true
bFound = True

Else

' If we have already found a match we must have stepped of it now
' so end our search
If
                                   (bFound)  Then bEnd = True

End If

Loop Until (bEnd  Or Not
                              oSalesDeliveryRecord.MoveNext)

' Spacefill the Account Reference to 8 chars
strRef = oSalesRecord.Fields.Item("ACCOUNT_REF").Value & Space$(8 -
                              Len(oSalesRecord.Fields.Item("ACCOUNT_REF").Value))

' Did we find one ?
If bFound  Then

' Yes, so increment last value
iAddNo = iAddNo + 1

' Convert to a string
strAddNo = CStr(iAddNo)

' Pad with leading zeroes
strAddNo = New String("0", 4 - Len(strAddNo)) & strAddNo

' Form the complete reference string
strRef = strRef & strAddNo

Else

' No, so start at 1
strRef = strRef & "0001"
iAddNo = 1

End If

' Add New Delivery Address
oSalesDeliveryRecord.AddNew()

' Pass New Reference
oSalesDeliveryRecord.Fields.Item("REFERENCE").Value = CStr(strRef)
oSalesDeliveryRecord.Fields.Item("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
oSalesDeliveryRecord.Fields.Item("DESCRIPTION").Value = CStr("New Delivery Address")

' Address Ref equals the number of the delivery address minus the zeros
oSalesDeliveryRecord.Fields.Item("ADDRESS_REF").Value = CInt(iAddNo)
oSalesDeliveryRecord.Fields.Item("NAME").Value = CStr("New SDO Account")
oSalesDeliveryRecord.Fields.Item("ADDRESS_1").Value = CStr("Building
                                5")
oSalesDeliveryRecord.Fields.Item("ADDRESS_2").Value = CStr("North
                                Park")
oSalesDeliveryRecord.Fields.Item("ADDRESS_3").Value = CStr("Newcastle Upon
                                Tyne")
oSalesDeliveryRecord.Fields.Item("ADDRESS_4").Value = CStr("Tyne
                                and Wear")
oSalesDeliveryRecord.Fields.Item("ADDRESS_5").Value = CStr("NE13
                                9AA")
oSalesDeliveryRecord.Fields.Item("TELEPHONE").Value = CStr("0845
                                1117733")
oSalesDeliveryRecord.Fields.Item("FAX").Value = CStr("0845
                                2450294")
oSalesDeliveryRecord.Fields.Item("CONTACT_NAME").Value = CStr("Richard
                                Johnson")
oSalesDeliveryRecord.Fields.Item("EMAIL").Value = CStr("sagesoft.developers@sage.com")
oSalesDeliveryRecord.Fields.Item("TAX_CODE").Value = CInt(1)

' Update New Record
bFlag = oSalesDeliveryRecord.Update

If bFlag  Then

MsgBox("Delivery address successfully added.", MsgBoxStyle.OKOnly, "SDO Examples")

Else

MsgBox("Delivery address update Unsuccessful.", MsgBoxStyle.OKOnly, "SDO Examples")

End If

' Disconnect
oWS.Disconnect()

End If

End If

' Destroy Objects
oSalesRecord =  Nothing
oSalesDeliveryRecord =  Nothing
oWS =  Nothing
oSDO =  Nothing

Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.SalesRecord oSalesRecord;

SageDataObject300.SalesDeliveryRecord oSalesDeliveryRecord;

String szDataPath;

Boolean bFound;

Boolean bEnd;

Int32 iAddNo = 0;

String strRef;

String strAddNo;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate Record Objects

  oSalesDeliveryRecord = (SageDataObject300.SalesDeliveryRecord)oWS.CreateObject("SalesDeliveryRecord");

  oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");

  //Read the first Customer record

  oSalesRecord.MoveFirst();

  //Initialise Flags

  bEnd = false;

  bFound = false;

  //Move to the first record in the Sales Delivery Address file

  oSalesDeliveryRecord.MoveFirst();

  //Search the records for the last occurrence in the file of this customer

  //or until we have read all the records in the file

  do

  {

    //Do we have a match?

    if (SDOHelper.Read(oSalesDeliveryRecord, "ACCOUNT_REF")== SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"))

    {

      //Yes, so store the address reference

      iAddNo = (Int32)SDOHelper.Read(oSalesDeliveryRecord, "ADDRESS_REF");

      //Set the found flag to true

      bFound = true;

    }

    else

    {

      //If we have already found a match we must have stepped off it now

      //so end our search

      if (bFound) { bEnd = true; }

    }

  } while (!bEnd & oSalesRecord.MoveNext());

  //Pad the Account Reference to 8 characters

  strRef = (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF");

  strRef = strRef.PadRight(8, Convert.ToChar(32));

  //Did we find one

  if (bFound)

  {

    //Yes, so increment the last value

    iAddNo ++;

    //Convert to a string

    strAddNo = iAddNo.ToString();

    //Pad with leading zeros

    strAddNo = strAddNo.PadLeft(4, Convert.ToChar((Int16)0));

    //Form the complete reference string

    strRef += strAddNo;

  }

  else

  {

    //No, so start at 1

    strRef += "0001";

  }

  //Add the new delivery address

  oSalesDeliveryRecord.AddNew();

  //Pass the new reference

  SDOHelper.Write(oSalesDeliveryRecord, "REFERENCE", (String)strRef);

  SDOHelper.Write(oSalesDeliveryRecord, "ACCOUNT_REF", (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));

  SDOHelper.Write(oSalesDeliveryRecord, "DESCRIPTION", (String)"New Delivery Address");

  //ADDRESS_REF equals the number of the delivery address minus the zeros

  SDOHelper.Write(oSalesDeliveryRecord, "ADDRESS_REF", (Int32)iAddNo);

  SDOHelper.Write(oSalesDeliveryRecord, "NAME", (String)"New SDO Account");

  SDOHelper.Write(oSalesDeliveryRecord, "ADDRESS_1", (String)"Building 3");

  SDOHelper.Write(oSalesDeliveryRecord, "ADDRESS_2", (String)"North Park");

  SDOHelper.Write(oSalesDeliveryRecord, "ADDRESS_3", (String)"Newcastle Upon Tyne");

  SDOHelper.Write(oSalesDeliveryRecord, "ADDRESS_4", (String)"Tyne and Wear");

  SDOHelper.Write(oSalesDeliveryRecord, "ADDRESS_5", (String)"NE13 9AA");

  SDOHelper.Write(oSalesDeliveryRecord, "TELEPHONE", (String)"0845 111 7733");

  SDOHelper.Write(oSalesDeliveryRecord, "FAX", (String)"0845 245 0294");

  SDOHelper.Write(oSalesDeliveryRecord, "CONTACT_NAME", (String)"Chris Reed");

  SDOHelper.Write(oSalesDeliveryRecord, "EMAIL", (String)"developers.programme@sage.com");

  SDOHelper.Write(oSalesDeliveryRecord, "TAX_CODE", (Int16)1);

  //Update the new record

  if (oSalesDeliveryRecord.Update())

  {

    MessageBox.Show("Delivery Address Successfully Added");

  }

  else

  {

    MessageBox.Show("Delivery Address Update Failed");

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Creating a Customer Price List Price

Example - Creating a Customer Price List Price

The example code below demonstrates how to create a new Price List Record. It then assigns the Price List to a Customer and adds a Stock Item with price to the Price List.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.
VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oPriceListRecord As SageDataObject300.PriceListRecord
Dim oPriceRecord As SageDataObject300.PriceRecord
Dim oSalesRecord As SageDataObject300.SalesRecord
Dim oStockRecord As SageDataObject300.StockRecord

' Declare Variables
Dim szDataPath, szReference As String
Dim szAccRef As String

 ' Error Handler
 Try

   ' Create the SDO Engine Object
   oSDO = New SageDataObject300.SDOEngine

   ' Create the Workspace
   oWS = oSDO.Workspaces.Add("Example")

   ' Select Company. The SelectCompany method takes the program install
   ' folder as a parameter
   szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

   ' A U.I. for company selection is presented to the user. If a company is selected,
   ' the path will be passed to the szDataPath variable.
   ' If not, or the Cancel button is selected, the variable will be left empty.
   If szDataPath <> "" Then

     ' Try to Connect - Will throw an exception if it fails
     If oWS.Connect(szDataPath, "", "", "Example") Then

       ' Create Instances of Objects
       oPriceListRecord = oWS.CreateObject("PriceListRecord")
       oPriceRecord = oWS.CreateObject("PriceRecord")
       oSalesRecord = oWS.CreateObject("SalesRecord")
       oStockRecord = oWS.CreateObject("StockRecord")

       ' Read the First Customer
       oSalesRecord.MoveFirst

       ' Read the first Stock Record
       oStockRecord.MoveFirst

       ' Populate New Price List Record
       oPriceListRecord.AddNew()
       szReference = "TESTLIST"
       oPriceListRecord.Fields.Item("TYPE").Value = CByte(SageDataObject300.priceTypes.pricePriceList)
       oPriceListRecord.Fields.Item("REFERENCE").Value = CStr(szReference)
       oPriceListRecord.Fields.Item("NAME").Value = CStr("New Customer Price List")
       oPriceListRecord.Fields.Item("CURRENCY").Value = CDbl(1)

       ' Update the Record
       If oPriceListRecord.Update Then

         MessageBox.Show("Price List Record Update Successful.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Information)

         ' Edit Customer's Record
         oSalesRecord.Edit()

         ' Set Price List Field
         oSalesRecord.Fields.Item("PRICE_LIST_REF").Value = CStr(szReference)

         ' Update The Record
         If oSalesRecord.Update Then

            MessageBox.Show("Sales Record Update Successful.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Information)

           ' Populate New Price Record
           oPriceRecord.AddNew

           ' Pad with spaces up to 8 chars
           szReference = szReference.PadRight(8, Chr(32))

           ' Discount Type ( from the enum PriceListType )
           oPriceRecord.Fields.Item("DISCOUNT_TYPE").Value = CByte(SageDataObject300.PriceListType.plFixed)

           ' If this was a special price then use the constanst priceSpecial
           oPriceRecord.Fields.Item("TYPE").Value = CByte(SageDataObject300.priceTypes.pricePriceList)
           oPriceRecord.Fields.Item("STORED_PRICE").Value = CDbl(10)
           oPriceRecord.Fields.Item("VALUE").Value = CDbl(10)

           ' Add P denotes a price list adding Customer Price List reference and stock code
           ' Note: An S to denote Special Price and U donates a Supplier Price.
           ' Here szReference is the Price List Record Reference. For Special Price it is the Customer Account
           '  Reference and for Supplier Price it is the Supplier Account Reference.
           oPriceRecord.Fields.Item("REFERENCE").Value = CStr("P") & CStr(szReference) & CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
           oPriceRecord.Fields.Item("EXT_REF").Value = CStr(szReference)
           oPriceRecord.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)

           ' Update the Record
           If oPriceRecord.Update Then

             MessageBox.Show("Price Record Update Successful.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Information)

           Else

             MessageBox.Show("Price Record Update Unsuccessful.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Information)

           End If

         Else

           MessageBox.Show("Sales Record Update Unsuccessful.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

         End If
       Else

         MessageBox.Show("Price List Record Update Unsuccessful.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

       End If

     Else

       MessageBox.Show( "Could not logon to the data.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

     End If

   End If

  ' Error Handling Code
 Catch ex As Exception

   MessageBox.Show("The SDO generated the following error: " & ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

 Finally
   ' Destroy Objects
   If Not oSalesRecord Is Nothing Then
     oSalesRecord = Nothing
   End If

   If Not oStockRecord Is Nothing Then
     oStockRecord = Nothing
   End If

   If Not oPriceRecord Is Nothing Then
     oPriceRecord = Nothing
   End If

   If Not oPriceListRecord Is Nothing Then
     oPriceListRecord  = Nothing
   End If

   If Not oWS Is Nothing Then
     oWS.Disconnect()
     oWS = Nothing
     oSDO = Nothing
   End If
 End Try
C#.NET [image] Copy C# Code
//Declare Objects
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.PriceListRecord oPriceListRecord;
SageDataObject300.PriceRecord oPriceRecord;
SageDataObject300.SalesRecord oSalesRecord;
SageDataObject300.StockRecord oStockRecord;

//Declare Varibles
String szDataPath, szReference, szAccRef;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try
{

    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

    //Create instances of the objects
    oPriceListRecord = (SageDataObject300.PriceListRecord)oWS.CreateObject("PriceListRecord");
    oPriceRecord = (SageDataObject300.PriceRecord)oWS.CreateObject("PriceRecord");
    oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");
    oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");

    //Read the First Customer
    oSalesRecord.MoveFirst();

    //Read the first Stock Records
    oStockRecord.MoveFirst();

    //Populate new price list record
    oPriceListRecord.AddNew();
    szReference = "TESTLIST";
    SDOHelper.Write(oPriceListRecord, "TYPE", SageDataObject300.priceTypes.pricePriceList);
    SDOHelper.Write(oPriceListRecord, "REFERENCE", (String)szReference);
    SDOHelper.Write(oPriceListRecord, "NAME", (String)"New Customer Price List");
    SDOHelper.Write(oPriceListRecord, "CURRENCY", (Double)1);

    //Try to update the record
    if (oPriceListRecord.Update())

    {
        MessageBox.Show("Price List Record Update Successful.");

        //Edit Customer's Record
        oSalesRecord.Edit();

        //Set Price List Field
        SDOHelper.Write(oSalesRecord, "PRICE_LIST_REF", (String)szReference);

        //Update the record
        if (oSalesRecord.Update())

        {
            MessageBox.Show("Sales Record Update Successful.");

            //Populate new Price Record
            oPriceRecord.AddNew();

            //Pad with spaces up To 8 chars
            szReference = szReference.PadRight(8, (' '));

            //Discount Type (From the enum PriceListType)
            SDOHelper.Write(oPriceRecord, "DISCOUNT_TYPE", SageDataObject300.PriceListType.plFixed);

            //If this was a special price then use then constant priceSpecial
            SDOHelper.Write(oPriceRecord, "TYPE", SageDataObject300.priceTypes.pricePriceList);
            SDOHelper.Write(oPriceRecord, "STORED_PRICE", (Double)10);
            SDOHelper.Write(oPriceRecord, "VALUE", (Double)10);

            //Add P denotes a price list adding Customer Price List reference and stock code
            //Note: An S to denote Special Price and U donates a Supplier price
            //Here szReference is the Price List Record Reference. For Special Price it is the Customer Account
            //Reference and for Supplier Price it is the Supplier Account Reference.
            SDOHelper.Write(oPriceRecord, "REFERENCE", (String)"P" + (String)szReference + (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));
            SDOHelper.Write(oPriceRecord, "EXT_REF", (String)szReference);
            SDOHelper.Write(oPriceRecord, "STOCK_CODE", SDOHelper.Read(oStockRecord, "STOCK_CODE"));

            //Update the Records
            if (oPriceRecord.Update())
                {
                MessageBox.Show("Price Record Update Successfull");
                }
            else
            {
                MessageBox.Show("Price Record Update Unsuccessful");
            }
        }
        else
        {
            MessageBox.Show("Sales Record Update Unsuccessful");
        }
    }
    else
    {
        MessageBox.Show("Price List Record Update Unsuccessful");
    }
    //Disconnect
    oWS.Disconnect();
}

//error Handling
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}


Sage 50 Accounts - Example - Creating a New Customer Record

Example - Creating a New Customer Record

The example code below demonstrates how to create a new Customer Record.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
                                ' Declare Objects
Dim oSDO As
                                SageDataObject300.SDOEngine
Dim oWS As
                                SageDataObject300.WorkSpace
Dim oSalesRecord As
                                SageDataObject300.SalesRecord

' Declare Variables
Dim szDataPath As
                              String

' Create the SDOEngine Object
oSDO = New
                                SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company. The
                                  SelectCompany method takes the
                                  program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the
                                  user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left
                              empty.
If szDataPath <> ""
                                Then

' 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("0845 1117733")
oSalesRecord.Fields.Item("FAX").Value =
                                  CStr("0845 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

End If

' Destroy Objects
oSalesRecord = Nothing
oWS = Nothing
oSDO = Nothing

Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.SalesRecord oSalesRecord;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog, taking the path to the company file as a parameter

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//If the select company screen is cancelled a blank string is returned to szDataPath

if (szDataPath != string.Empty)

{

  //Try a connection, will throw an exception if it fails

  try

  {

    //Leaving the username and password blank generates a login dialog

    oWS.Connect(szDataPath, "", "", "Example");

    //Instantiate Sales Record Object

    oSalesRecord = (SageDataObject300.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)"0845 111 7733");

      SDOHelper.Write(oSalesRecord, "FAX", (String)"0845 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();

  }

  catch (Exception ex)

  {

    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

  }

}


Sage 50 Accounts - Example - Creating a New Customer Price List Record

Example - Creating a New Customer Price List Record

The example code below demonstrates how to create a new Customer Price List Record.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
                                ' Declare Objects
Dim oSDO  As
                              SageDataObject300.SDOEngine
Dim oWS  As
                              SageDataObject300.WorkSpace
Dim oPriceListRecord  As
                              SageDataObject300.PriceListRecord
Dim oSalesRecord  As
                              SageDataObject300.SalesRecord

' Declare Variables
Dim szDataPath  As
                               String
Dim szReference  As
                               String

' Create the SDO Engine Object
oSDO =  New   SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company.  The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user.
                                  If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> ""  Then

' Try to Connect - Will throw an
                                  exception if it fails
If oWS.Connect(szDataPath, "", "", "Example")
                               Then

' Create Instances of Objects
oPriceListRecord = oWS.CreateObject("PriceListRecord")
oSalesRecord = oWS.CreateObject("SalesRecord")

' Read the First Customer
oSalesRecord.MoveFirst()

' Populate New Price List Record
oPriceListRecord.AddNew()
szReference = "TESTLIST"
oPriceListRecord.Fields.Item("REFERENCE").Value =
                              CStr(szReference)
oPriceListRecord.Fields.Item("NAME").Value = CStr("New Customer Price List")
oPriceListRecord.Fields.Item("TYPE").Value = CByte(SageDataObject300.PriceTypes.pricePriceList)

' Update the Record
If oPriceListRecord.Update
                               Then

MsgBox("Update Successful.", MsgBoxStyle.OKOnly, "SDO Examples")

Else

MsgBox("Update Unsuccessful.", MsgBoxStyle.OKOnly, "SDO Examples")

End  If

' Edit Customer's Record
oSalesRecord.Edit()

' Set Price List Field
oSalesRecord.Fields.Item("PRICE_LIST_REF").Value = CStr(szReference)

' Update The Record
If oSalesRecord.Update
                               Then

MsgBox("Update Successful.", MsgBoxStyle.OKOnly, "SDO Examples")

Else

MsgBox("Update Unsuccessful.", MsgBoxStyle.OKOnly, "SDO Examples")

End If

' Disconnect
oWS.Disconnect()

End If

End If

' Destroy Objects
oSalesRecord =  Nothing
oPriceListRecord =  Nothing
oWS =  Nothing
oSDO =  Nothing

Exit Sub
C#.NET [image] Copy C# Code
            // Declare Objects
                SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
                SageDataObject300.WorkSpace oWS;
                SageDataObject300.PriceListRecord oPriceListRecord;
                SageDataObject300.SalesRecord oSalesRecord;

                // Declare Variables
                String szDataPath = null;
                String szReference = null;

                // Create the Workspace
                oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

                // Select Company. The SelectCompany method takes the program install
                // folder as a parameter
                szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Acounts\\2023");

                try
                {

                // A U.I. for company selection is presented to the user. If a company is selected,
                // the path will be passed to the szDataPath variable.
                // If not, or the Cancel button is selected, the variable will be left empty.
                if (!string.IsNullOrEmpty(szDataPath))
                {

                    // Try to Connect - Will throw an exception if it fails
                    if (oWS.Connect(szDataPath, "", "", "Example"))
                    {

                        // Create Instances of Objects
                        oPriceListRecord = (SageDataObject300.PriceListRecord)oWS.CreateObject("PriceListRecord");
                        oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");

                        // Read the First Customer
                        oSalesRecord.MoveFirst();

                        // Populate New Price List Record
                        oPriceListRecord.AddNew();
                        szReference = "TESTLIST";
                        SDOHelper.Write(oPriceListRecord, "REFERENCE", (string)szReference);
                        SDOHelper.Write(oPriceListRecord, "NAME", (string)"New Customer Price List");
                        SDOHelper.Write(oPriceListRecord, "TYPE", (byte)SageDataObject300.priceTypes.pricePriceList);

                        // Update the Record
                        if (oPriceListRecord.Update())
                        {
                            MessageBox.Show("Update Successful.");
                        }
                        else
                        {
                            MessageBox.Show("Update Unsuccessful.");
                        }

                        // Edit Customer's Record
                        oSalesRecord.Edit();

                        // Set Price List Field
                        SDOHelper.Write(oSalesRecord, "PRICE_LIST_REF",(string)szReference);

                        // Update The Record
                        if (oSalesRecord.Update())
                        {

                            MessageBox.Show("Update Successful.");
                        }
                        else
                        {
                            MessageBox.Show("Update Unsuccessful.");
                        }

                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

            }
            finally
            {
                // Disconnect
                oWS.Disconnect();

                // Destroy Objects
                oSalesRecord = null;
                oPriceListRecord = null;
                oWS = null;
                oSDO = null;
            }


Sage 50 Accounts - Example - Deleting an Existing Customer Record

Example - Deleting an Existing Customer Record

The example code below demonstrates how to delete an existing Customer Record.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oSalesRecord As SageDataObject300.SalesRecord

' Declare Variables
Dim szDataPath As String

' Create the SDOEngine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

' 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")

' Move to the First Record
oSalesRecord.MoveFirst

' Check to see if the Record can be deleted
If oSalesRecord.CanRemove Then

' Delete the Record
If oSalesRecord.Remove Then

' The Delete was Successful
MsgBox( "Account " & oSalesRecord.Fields.Item("ACCOUNT_REF").Value & " was deleted successfully.", MsgBoxStyle.OKOnly, "SDO Examples")

Else

' The Delete was Unsuccessful
MsgBox("The account could not be deleted.", MsgBoxStyle.OKOnly, "SDO Examples")

End If

Else

MsgBox("The account cannot be deleted.", MsgBoxStyle.OKOnly, "SDO Examples")

End If

' Disconnect
oWS.Disconnect()

End If

End If

' Destroy Objects
oSalesRecord = Nothing
oWS = Nothing
oSDO = Nothing

Exit Sub
C#.NET [image] Copy C# Code
                // Declare Objects
                SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
                SageDataObject300.WorkSpace oWS;
                SageDataObject300.SalesRecord oSalesRecord;

                // Declare Variables
                string szDataPath = null;

                //Instantiate WorkSpace
                oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

                // Select Company. The SelectCompany method takes the program install
                // folder as a parameter
                szDataPath = oSDO.SelectCompany("C:\\Documents and Settings\\All Users\\Application Data\\Sage\\Accounts\\2023");

                // A U.I. for company selection is presented to the user. If a company is selected,
                // the path will be passed to the szDataPath variable.
                // If not, or the Cancel button is selected, the variable will be left empty.
                if (!string.IsNullOrEmpty(szDataPath))
                {

                    // Try to Connect - Will Throw an Exception if it Fails
                    if (oWS.Connect(szDataPath, "", "", "Example"))
                    {

                        // Create an Instance of the SalesRecord Object
                        oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");

                        // Move to the First Record
                        oSalesRecord.MoveLast();

                        // Check to see if the Record can be deleted
                        if (oSalesRecord.CanRemove())
                        {

                            // Delete the Record
                            if (oSalesRecord.Remove())
                            {
                                // The Delete was Successful
                                 MessageBox.Show("Account " + SDOHelper.Read(oSalesRecord, "ACCOUNT_REF") + " was deleted successfully.");
                            }
                            else
                            {
                                // The Delete was Unsuccessful
                                MessageBox.Show("The account could not be deleted.");

                            }
                        }
                        else
                        {
                            MessageBox.Show("The account cannot be deleted.");
                        }

                        // Disconnect
                        oWS.Disconnect();

                    }
                }

                // Destroy Objects
                oSalesRecord = null;
                oWS = null;
                oSDO = null;


Sage 50 Accounts - Example - Editing an Existing Customer Record

Example - Editing an Existing Customer Record

The example code below demonstrates how to edit an existing Customer Record.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
   ' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim  oWS As SageDataObject300.WorkSpace
Dim  oSalesRecord As SageDataObject300.SalesRecord

' Declare Variables
Dim szDataPath  As String

' Create the SDOEngine Object
oSDO =  New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user.  If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> ""  Then

' 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")

' Move to the First Record
oSalesRecord.MoveFirst

' Edit the Record
If oSalesRecord.Edit  Then

' Change the Account Name
oSalesRecord.Fields.Item("NAME").Value = CStr("Amended Company Name")

' Update the Record
If oSalesRecord.Update  Then

' The Update was Successful
MsgBox("Account " &
                              oSalesRecord.Fields.Item("ACCOUNT_REF").Value & " was edited successfully.", MsgBoxStyle.OKOnly, "SDO Examples")

Else

' The Update was Unsuccessful
MsgBox("The account could not be
                              edited.", MsgBoxStyle.OKOnly, "SDO Examples")

End If

End If

' Disconnect
oWS.Disconnect()

End If

End If

' Destroy Objects
oSalesRecord =  Nothing
oWS =  Nothing
oSDO =  Nothing

Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.SalesRecord oSalesRecord;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate the Sales Record object

  oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");

  //Move to the first record

  oSalesRecord.MoveFirst();

  //Edit the record

  if (oSalesRecord.Edit())

  {

    //Change the Account Name

    SDOHelper.Write(oSalesRecord, "NAME", (String)"Amended Company Name");

    //Update the record

    if (oSalesRecord.Update())

    {

      MessageBox.Show("Account " + SDOHelper.Read(oSalesRecord, "ACCOUNT_REF") +

        " Was edited Successfully");

    }

    else

    {

      MessageBox.Show("The Account Could Not Be Edited");

    }

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example -�Generating a Customer Best Price

Example - Generating a Customer Best Price

The example code below demonstrates how to return the best price for a given customer, and stock code in Sage 50 Accounts.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oPricing As SageDataObject300.Pricing
Dim oSalesRecord As SageDataObject300.SalesRecord
Dim oStockRecord As SageDataObject300.StockRecord

' Declare Variables
Dim szDataPath As String
Dim dPrice As Double

' Create the SDO Engine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install
' folder as a parameter

szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.

If szDataPath <> "" Then

' Connect to Data Files
oWS.Connect szDataPath, "", "", "Example"

' Create stock and sales objects then move first
oSalesRecord = oWS.CreateObject("SalesRecord")
oStockRecord = oWS.CreateObject("StockRecord")
oSalesRecord.MoveFirst
oStockRecord.MoveFirst

' Create instance of the Pricing Object
oPricing = oWS.CreateObject("Pricing")

' Get the Price
dPrice = oPricing.CustomerUnitPrice(oSalesRecord.Fields.Item("ACCOUNT_REF").Value, oStockRecord.Fields.Item("STOCK_CODE").Value)
MsgBox(dPrice)

End If

' Destroy Objects
oWS = Nothing
oSDO = Nothing
oPricing = Nothing
oSalesRecord = Nothing
oStockRecord = Nothing

Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.Pricing oPricing;

SageDataObject300.SalesRecord oSalesRecord;

SageDataObject300.StockRecord oStockRecord;

String szDataPath;

Double dPrice;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate objects and move to first records

  oPricing = (SageDataObject300.Pricing)oWS.CreateObject("Pricing");

  oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");

  oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");

  oSalesRecord.MoveFirst();

  oStockRecord.MoveFirst();

  //Get the price and return into the dPrice variable

  dPrice = oPricing.CustomerUnitPrice

    (

    (String)SDOHelper.Read(oSalesRecord,"ACCOUNT_REF"),

    (String)SDOHelper.Read(oStockRecord,"STOCK_CODE")

    );

  MessageBox.Show(dPrice.ToString());

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Is Date Valid For Lock Date

Example - Is Date Valid For Lock Date

This example uses the IsDateValidForLockDate to identify if the user has access to post the transaction to the ledgers.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code

' Declare Objects

Dim oSDO As SageDataObject300.SDOEngine

Dim oWS As SageDataObject300.WorkSpace

Dim oSalesRecord As SageDataObject300.SalesRecord

Dim oTransactionPost As SageDataObject300.TransactionPost

Dim oSplitData As SageDataObject300.SplitData

Dim oLastError As New SageDataObject300.ErrorCode

Dim oSetupData As SageDataObject300.SetupData

' Declare Variables

Dim szDataPath As String

Dim iSplitCount As Short

' Create the SDO Engine Object

oSDO = New SageDataObject300.SDOEngine

' Create the Workspace

oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install

' folder as a parameter

szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,

' the path will be passed to the szDataPath variable.

' If not, or the Cancel button is selected, the variable will be left empty.

If szDataPath <> "" Then

' Try to Connect - Will throw an exception if it fails

If oWS.Connect(szDataPath, "", "", "Example") Then

' Create Instances of Objects

oTransactionPost = oWS.CreateObject("TransactionPost")

oSalesRecord = oWS.CreateObject("SalesRecord")

oSetupData = oWS.CreateObject("SetupData")

'Check to ensure date is not locked for posting

Select Case oSetupData.IsDateValidForLockDate(Date.Now)

Case SageDataObject300.LockDatePermission.sdoLockDatePostingDenied

MessageBox.Show("The user does not have access to post into locked periods")

Case SageDataObject300.LockDatePermission.sdoLockDatePostingPermitted, _

SageDataObject300.LockDatePermission.sdoLockDateUserCanOverride

' Read the First Customer

oSalesRecord.MoveFirst()

' Populate Header fields

' Note:

' The ACCOUNT_REF field must be populated with a valid

' Customer Account Reference

oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)

oTransactionPost.Header("Date").Value = CDate(Today)

oTransactionPost.Header("Posted_Date").Value = CDate(Today)

oTransactionPost.Header("Type").Value = CByte(SageDataObject300.TransType.sdoSI)

oTransactionPost.Header("Details").Value = CStr("Test Sales Invoice")

oTransactionPost.Header("Inv_Ref").Value = CStr("INV001")

' Loop for the Number of Splits

' Note:

' The Transaction can have 1 or many splits

For iSplitCount = 1 To 2

' Add a split to the Header Item's collection

oSplitData = oTransactionPost.Items.Add

' Populate Split Fields

oSplitData.Fields.Item("TYPE").Value = oTransactionPost.Header("TYPE").Value

oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("4000")

oSplitData.Fields.Item("TAX_CODE").Value = CShort(1)

oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(100)

oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(20)

oSplitData.Fields.Item("DETAILS").Value = CStr("Split Details")

oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)

Next iSplitCount

Try

oTransactionPost.Update()

MessageBox.Show("Transaction Posted successfully")

Catch ex As Exception

MessageBox.Show("The SDO generated the following error: " & ex.Message)

End Try

End Select

' Disconnect

oWS.Disconnect()

End If

End If

' Destroy Objects

oTransactionPost = Nothing

oSplitData = Nothing

oSalesRecord = Nothing

oWS = Nothing

oSDO = Nothing
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.SalesRecord oSalesrecord;

SageDataObject300.TransactionPost oTransactionPost;

SageDataObject300.SplitData oSplitData;

SageDataObject300.SetupData oSetupData;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

//Leaving the username and password blank generates a login dialog

oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

//Instantiate Objects

oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

oSalesrecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");

oSetupData = (SageDataObject300.SetupData)oWS.CreateObject("SetupData");

//Check to ensure date is not locked for posting

switch (oSetupData.IsDateValidForLockDate(DateTime.Today))

{

case SageDataObject300.LockDatePermission.sdoLockDatePostingDenied:

{

MessageBox.Show("The user does not have access to post into locked periods");

break;

}

case SageDataObject300.LockDatePermission.sdoLockDatePostingPermitted:

case SageDataObject300.LockDatePermission.sdoLockDateUserCanOverride:

{

//Read the first customer

oSalesrecord.MoveFirst();

//Populate Header Fields

//Note:

//The Account_Ref field must be populated with a valid

//Customer account reference

SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF",

(String)SDOHelper.Read(oSalesrecord, "ACCOUNT_REF"));

SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);

SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);

SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoSI);

SDOHelper.Write(oTransactionPost.Header, "DETAILS", (String)"Test Sales Invoice");

SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"INV001");

//Loop for the number of splits

//Note:

//The transaction can have 1 or many splits

for (Int16 i = 1; i <= 2; i++)

{

//Add a split to the headers item collection

oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

//Populate split fields

SDOHelper.Write(oSplitData, "TYPE",

SDOHelper.Read(oTransactionPost.Header, "TYPE"));

SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"4000");

SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)1);

SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)100);

SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)17.5);

SDOHelper.Write(oSplitData, "DETAILS", (String)"Split Details ");

SDOHelper.Write(oSplitData, "DATE",

(DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));

}

//Update the transaction post object

if (oTransactionPost.Update())

{

MessageBox.Show("Transaction Posted Successfully");

}

else

{

MessageBox.Show("Transaction Post Failed");

}

}

}

//Disconnect

oWS.Disconnect();

}

catch (Exception ex)

{

MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Is Date User Valid For Lock Date

Example - Is Date User Valid For Lock Date

This example uses the IsDateUserValidForLockDate to identify if the user has access to post the transaction on a given date to the ledgers.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code

' Declare Objects

Dim oSDO As SageDataObject300.SDOEngine

Dim oWS As SageDataObject300.WorkSpace

Dim oSalesRecord As SageDataObject300.SalesRecord

Dim oTransactionPost As SageDataObject300.TransactionPost

Dim oSplitData As SageDataObject300.SplitData

Dim oLastError As New SageDataObject300.ErrorCode

Dim oSetupData As SageDataObject300.SetupData

' Declare Variables

Dim szDataPath As String

Dim iSplitCount As Short

' Create the SDO Engine Object

oSDO = New SageDataObject300.SDOEngine

' Create the Workspace

oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install

' folder as a parameter

szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,

' the path will be passed to the szDataPath variable.

' If not, or the Cancel button is selected, the variable will be left empty.

If szDataPath <> "" Then

' Try to Connect - Will throw an exception if it fails

If oWS.Connect(szDataPath, "", "", "Example") Then

' Create Instances of Objects

oTransactionPost = oWS.CreateObject("TransactionPost")

oSalesRecord = oWS.CreateObject("SalesRecord")

oSetupData = oWS.CreateObject("SetupData")

'Check to ensure date is not locked for posting

Select Case oSetupData.IsDateUserValidForLockDate(Date.Now, "SDO1")

Case SageDataObject300.LockDatePermission.sdoLockDatePostingDenied

MessageBox.Show("The user does not have access to post into locked periods")

Case SageDataObject300.LockDatePermission.sdoLockDatePostingPermitted, _

SageDataObject300.LockDatePermission.sdoLockDateUserCanOverride

' Read the First Customer

oSalesRecord.MoveFirst()

' Populate Header fields

' Note:

' The ACCOUNT_REF field must be populated with a valid

' Customer Account Reference

oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)

oTransactionPost.Header("Date").Value = CDate(Today)

oTransactionPost.Header("Posted_Date").Value = CDate(Today)

oTransactionPost.Header("Type").Value = CByte(SageDataObject300.TransType.sdoSI)

oTransactionPost.Header("Details").Value = CStr("Test Sales Invoice")

oTransactionPost.Header("Inv_Ref").Value = CStr("INV001")

' Loop for the Number of Splits

' Note:

' The Transaction can have 1 or many splits

For iSplitCount = 1 To 2

' Add a split to the Header Item's collection

oSplitData = oTransactionPost.Items.Add

' Populate Split Fields

oSplitData.Fields.Item("TYPE").Value = oTransactionPost.Header("TYPE").Value

oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("4000")

oSplitData.Fields.Item("TAX_CODE").Value = CShort(1)

oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(100)

oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(20)

oSplitData.Fields.Item("DETAILS").Value = CStr("Split Details")

oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)

Next iSplitCount

Try

oTransactionPost.Update()

MessageBox.Show("Transaction Posted successfully")

Catch ex As Exception

MessageBox.Show("The SDO generated the following error: " & ex.Message)

End Try

End Select

' Disconnect

oWS.Disconnect()

End If

End If

' Destroy Objects

oTransactionPost = Nothing

oSplitData = Nothing

oSalesRecord = Nothing

oWS = Nothing

oSDO = Nothing
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.SalesRecord oSalesrecord;

SageDataObject300.TransactionPost oTransactionPost;

SageDataObject300.SplitData oSplitData;

SageDataObject300.SetupData oSetupData;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

//Leaving the username and password blank generates a login dialog

oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

//Instantiate Objects

oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

oSalesrecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");

oSetupData = (SageDataObject300.SetupData)oWS.CreateObject("SetupData");

//Check to ensure date is not locked for posting

switch (oSetupData.IsDateUserValidForLockDate(DateTime.Today, "SDO1"))

{

case SageDataObject300.LockDatePermission.sdoLockDatePostingDenied:

{

MessageBox.Show("The user does not have access to post into locked periods");

break;

}

case SageDataObject300.LockDatePermission.sdoLockDatePostingPermitted:

case SageDataObject300.LockDatePermission.sdoLockDateUserCanOverride:

{

//Read the first customer

oSalesrecord.MoveFirst();

//Populate Header Fields

//Note:

//The Account_Ref field must be populated with a valid

//Customer account reference

SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF",

(String)SDOHelper.Read(oSalesrecord, "ACCOUNT_REF"));

SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);

SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);

SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoSI);

SDOHelper.Write(oTransactionPost.Header, "DETAILS", (String)"Test Sales Invoice");

SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"INV001");

//Loop for the number of splits

//Note:

//The transaction can have 1 or many splits

for (Int16 i = 1; i <= 2; i++)

{

//Add a split to the headers item collection

oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

//Populate split fields

SDOHelper.Write(oSplitData, "TYPE",

SDOHelper.Read(oTransactionPost.Header, "TYPE"));

SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"4000");

SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)1);

SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)100);

SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)17.5);

SDOHelper.Write(oSplitData, "DETAILS", (String)"Split Details ");

SDOHelper.Write(oSplitData, "DATE",

(DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));

}

//Update the transaction post object

if (oTransactionPost.Update())

{

MessageBox.Show("Transaction Posted Successfully");

}

else

{

MessageBox.Show("Transaction Post Failed");

}

}

}

//Disconnect

oWS.Disconnect();

}

catch (Exception ex)

{

MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Posting a Sales Invoice and Receipt - VAT Cash Accounting

Example - Posting a Sales Invoice and Receipt - VAT Cash Accounting

The example code below demonstrates how to post a sales invoice and receipt when the tax scheme is VAT cash accounting.

The VAT Cash Accounting scheme allows a business to reclaim VAT on receipts and payments instead of invoices raised. It is available to companies with turnovers below a certain threshold. HM Revenue and Customs (HMRC) devised the VAT Cash Accounting scheme to assist small businesses with their cash flow. For further information about VAT Cash Accounting, the local VAT Office can be contacted. As a result, when posting sales receipts using the SDO to a company configured for cash accounting, some changes must be made. The tax code and tax amounts that are posted are going to differ from posting a sales receipt when the company is configured for standard VAT. As VAT is liable when funds are received from the customer rather than when the invoice is issued, the sales receipt must be posted with a tax code that matches the original invoice and with the tax amount. (Example - Check VAT Scheme)

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code

' Declare Objects

Dim oSDO As SageDataObject300.SDOEngine

Dim oWS As SageDataObject300.WorkSpace

Dim oTransactionPost As SageDataObject300.TransactionPost

Dim oHeaderData As SageDataObject300.HeaderData

Dim oSplitData As SageDataObject300.SplitData

Dim oSalesRecord As SageDataObject300.SalesRecord

' Declare Variables

Dim szDataPath As String

Dim iCtr As Integer

Dim lInvoiceHeader As Integer

Dim lReceiptHeader As Integer

Dim lReceiptSplit As Integer

' Create the SDO Engine Object

oSDO = New SageDataObject300.SDOEngine()

' Create the Workspace

oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install

' folder as a parameter

szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,

' the path will be passed to the szDataPath variable.

' If not, or the Cancel button is selected, the variable will be left empty.

' Connect to Data Files

Try

oWS.Connect(szDataPath, "", "", "Example")

' Create an Instance of Objects

oTransactionPost = oWS.CreateObject("TransactionPost")

oSalesRecord = oWS.CreateObject("SalesRecord")

' Read First Customer

oSalesRecord.MoveFirst()

' Populate Header fields

oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)

oTransactionPost.Header("DATE").Value = CDate(Today)

oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)

oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoSI)

oTransactionPost.Header("DETAILS").Value = CStr("Cash Accounting Invoice")

oTransactionPost.Header("INV_REF").Value = CStr("INV001")

' Loop for number of split's

For iCtr = 1 To 2

' Create a split item by adding an empty split to the Items

' collection of the TransactionPost Object.

oSplitData = oTransactionPost.Items.Add()

' Fill in the Split fields

oSplitData.Fields.Item("TYPE").Value = CByte(SageDataObject300.TransType.sdoSI)

oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("4000")

oSplitData.Fields.Item("TAX_CODE").Value = CShort(1)

oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(100)

oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(17.5)

oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)

oSplitData.Fields.Item("DETAILS").Value = CStr(oTransactionPost.Header("DETAILS").Value)

Next iCtr

' Update the TransactionPost Object

If oTransactionPost.Update() Then

MessageBox.Show("Invoice Posted")

' Store Header Record Number of Invoice just Posted

lInvoiceHeader = oTransactionPost.PostingNumber

' Destroy Objects

oTransactionPost = Nothing

oSplitData = Nothing

' *********************************

' Now Post Sales Receipt

' Create an instance of TransactionPost for the Sales Receipt

oTransactionPost = oWS.CreateObject("TransactionPost")

' Fill in the Header fields

oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)

oTransactionPost.Header("DATE").Value = CDate(Today)

oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)

oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoSR)

oTransactionPost.Header("DETAILS").Value = CStr("Test Sales Receipt")

oTransactionPost.Header("INV_REF").Value = CStr("PAY001")

oTransactionPost.Header("BANK_CODE").Value = CStr("1200")

' Create a split item by adding an empty split to the Items

' collection of the TransactionPost Object.

oSplitData = oTransactionPost.Items.Add()

' Fill in the Split fields - note a Sales Receipt only has one split

' As this is Cash accounting the tax code will be T1, and also you will need to post

' the tax amount of the two splits

oSplitData.Fields.Item("TYPE").Value = CByte(SageDataObject300.TransType.sdoSR)

oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("1200")

oSplitData.Fields.Item("TAX_CODE").Value = CShort(1)

oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(200)

oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(35)

oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)

oSplitData.Fields.Item("DETAILS").Value = CStr(oTransactionPost.Header("DETAILS").Value)

' Update the TransactionPost object

If oTransactionPost.Update() Then

MessageBox.Show("Receipt Posted")

' Store Header Record Number of Receipt just Posted

lReceiptHeader = oTransactionPost.PostingNumber

' Destroy Objects

oTransactionPost = Nothing

oSplitData = Nothing

' The AllocatePayment function needs the split record number

' so we will need to read the header first and then obtain

' the split's from there ' Create an instance of HeaderData

oHeaderData = oWS.CreateObject("HeaderData")

' Read HeaderData for Receipt

oHeaderData.Read(lReceiptHeader)

' Store Split Number for Receipt

lReceiptSplit = CInt(oHeaderData.Fields.Item("FIRST_SPLIT").Value)

' Read HeaderData for Invoice

oHeaderData.Read(lInvoiceHeader)

' Link to Split's

oSplitData = oHeaderData.Link

' Move to First Split

oSplitData.MoveFirst()

' Create an instance of TransactionPost for the Sales Receipt

oTransactionPost = oWS.CreateObject("TransactionPost")

' Allocate First Split to Receipt

If oTransactionPost.AllocatePayment(CInt(oSplitData.RecordNumber), CInt(lReceiptSplit), CDbl(117.5), CDate(Today)) Then

MessageBox.Show("First Split Allocated")

' Move to Next Split

oSplitData.MoveNext()

' Allocate Second Split to Remainder of Receipt

If oTransactionPost.AllocatePayment(CInt(oSplitData.RecordNumber), CInt(lReceiptSplit), CDbl(117.5), CDate(Today)) Then

MessageBox.Show("Second Split Allocated")

End If

End If

Else

MessageBox.Show("Could not post sales reciept")

End If

Else

MessageBox.Show("Could not post invoice")

End If

Catch ex As Exception

MessageBox.Show(ex.Message.ToString())

Finally

' Disconnect.

oWS.Disconnect()

End Try

oTransactionPost = Nothing

oSplitData = Nothing

oHeaderData = Nothing

oSalesRecord = Nothing

oWS = Nothing

oSDO = Nothing

End Sub
C#.NET [image] Copy C# Code

//Declare Objects

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.TransactionPost oTransactionPost;

SageDataObject300.HeaderData oHeaderData;

SageDataObject300.SplitData oSplitData = null;

SageDataObject300.SalesRecord oSalesrecord;

// Declare Variables

String szDataPath;

Int32 iInvoiceHeader = 0;

Int32 iReceiptHeader = 0;

Int32 iReceiptSplit = 0;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try {

//Leaving the username and password blank generates a login dialog

oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

//Instantiate Objects

oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

oSalesrecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");

//Read the first customer

oSalesrecord.MoveFirst();

//Populate Header Fields

//Note:

//The Account_Ref field must be populated with a valid

//Customer account reference

SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oSalesrecord, "ACCOUNT_REF"));

SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);

SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);

SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoSI);

SDOHelper.Write(oTransactionPost.Header, "DETAILS", (String)"Cash Accounting Invoice");

SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"INV001");

//Loop for the number of splits

//Note:

//The transaction can have 1 or many splits

for (Int16 i = 1; i <= 2; i++) {

//Add a split to the headers item collection

oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

//Populate split fields

SDOHelper.Write(oSplitData, "TYPE", SDOHelper.Read(oTransactionPost.Header, "TYPE"));

SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"4000");

SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)1);

SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)100);

SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)17.5);

SDOHelper.Write(oSplitData, "DETAILS", (String)"Cash Accounting Invoice Split");

SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE")); }

//Update the transaction post object

if (oTransactionPost.Update()) { MessageBox.Show("Invoice Posted Successfully");

//Store Header Record Number of Invoice just Posted

iInvoiceHeader = oTransactionPost.PostingNumber;

//Destroy Objects

oTransactionPost = null;

oSplitData = null;

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

// Now Post Sales Reciept

// Create an instance of TransactionPost for the Sales Receipt

oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

//Populate the header fields

SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oSalesrecord, "ACCOUNT_REF"));

SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);

SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);

SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoSR);

SDOHelper.Write(oTransactionPost.Header, "DETAILS", (String)"Cash Accounting Sales Receipt");

SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"PAY001"); SDOHelper.Write(oTransactionPost.Header, "BANK_CODE", (String)"1200");

//Create a split item by adding an empty split to the items

//collection of the TransactionPost Object.

oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

//Populate the split fields

//Note: a Sales receipt only has one split

//As this is Cash accounting the tax code will be T1, and also you will need to post

//the tax amount of the two splits

SDOHelper.Write(oSplitData, "TYPE", (Byte)SageDataObject300.TransType.sdoSR);

SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"1200");

SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)1);

SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)200);

SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)35);

SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));

SDOHelper.Write(oSplitData, "DETAILS", (String)SDOHelper.Read(oTransactionPost.Header, "DETAILS"));

//Update the Transaction Post object

if (oTransactionPost.Update()) { MessageBox.Show("Receipt Posted");

//Store the record number of the receipt just posted

iReceiptHeader = oTransactionPost.PostingNumber;

//Destroy the objects

oTransactionPost = null;

oSplitData = null;

// The Allocate function needs the split record number

//so we will need to read the header first and then obtain

//the split's from there

//Instantiate Header Data object

oHeaderData = (SageDataObject300.HeaderData)oWS.CreateObject("HeaderData");

//Read HeaderData for Receipt

oHeaderData.Read(iReceiptHeader);

// Store Split Number for Receipt

iReceiptSplit = (Int32)SDOHelper.Read(oHeaderData, "FIRST_SPLIT");

// Read HeaderData for Invoice

oHeaderData.Read(iInvoiceHeader);

// Link to Split's

oSplitData = (SageDataObject300.SplitData)oHeaderData.Link;

//Move to First Split

oSplitData.MoveFirst();

// Create an instance of TransactionPost for the Sales Receipt

oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

//Allocate the first split to the receipt

if (oTransactionPost.AllocatePayment((Int32)oSplitData.RecordNumber, (Int32)iReceiptSplit, (Double)117.5, (DateTime)DateTime.Today)) {

//Move to the next split

oSplitData.MoveNext();

//Allocate the second split to the remainder of the receipt

oTransactionPost.AllocatePayment((Int32)oSplitData.RecordNumber, (Int32)iReceiptSplit, (Double)117.5, (DateTime)DateTime.Today);

MessageBox.Show("Posting allocation has been successful");

}

else

{ MessageBox.Show("Routine Failed");

} } }

else { MessageBox.Show("Invoice Post Failed");

} }

catch (Exception ex) { MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}

finally {

//Disconnect

oWS.Disconnect();

}

}

}


Sage 50 Accounts - Example - Posting a Customer Batch Sales Invoice

Example - Posting a Customer Batch Sales Invoice

The example code below demonstrates how to post a Customer Batch Sales Invoice.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
                                ' Declare Objects
Dim oSDO  As
                              SageDataObject300.SDOEngine
Dim oWS  As
                              SageDataObject300.WorkSpace
Dim oSalesRecord  As
                              SageDataObject300.SalesRecord
Dim oTransactionPost  As
                              SageDataObject300.TransactionPost
Dim oSplitData  As
                              SageDataObject300.SplitData

' Declare Variables
Dim szDataPath  As
                               String
Dim iSplitCount  As
                               Short

' Create the SDO Engine Object
oSDO =  New   SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company.  The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> ""  Then

' Try to Connect - Will throw an
                                  exception if it fails
If oWS.Connect(szDataPath, "", "", "Example")
                               Then

' Create Instances of Objects
oTransactionPost = oWS.CreateObject("TransactionPost")
oSalesRecord = oWS.CreateObject("SalesRecord")

' Read the First Customer
oSalesRecord.MoveFirst()

' Populate Header fields

' Note:
' The ACCOUNT_REF field must be populated with a valid
' Customer Account Reference
oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("Date").Value = CDate(Today)
oTransactionPost.Header("Posted_Date").Value = CDate(Today)
oTransactionPost.Header("Type").Value = CByte(SageDataObject300.TransType.sdoSI)
oTransactionPost.Header("Inv_Ref").Value = CStr("INV001")

' Populate the foreign currency fields
oTransactionPost.Header("CURRENCY").Value = oSalesRecord.Fields.Item("CURRENCY").Value

' Loop for the Number of Splits
' Note:
' The Transaction can have 1 or many splits
For iSplitCount = 1
                               To 2

' Add a split to the Header Item's collection
oSplitData = oTransactionPost.Items.Add

' Populate Split Fields
oSplitData.Fields.Item("TYPE").Value =
                                oTransactionPost.Header("TYPE").Value
oSplitData.Fields.Item("NOMINAL_CODE").Value =
                              CStr("4000")
oSplitData.Fields.Item("TAX_CODE").Value =
                              CShort(1)
oSplitData.Fields.Item("NET_AMOUNT").Value =
                              CDbl(100)
oSplitData.Fields.Item("TAX_AMOUNT").Value =
                              CDbl(17.5)
oSplitData.Fields.Item("DATE").Value =
                              CDate(oTransactionPost.Header("DATE").Value)

Next iSplitCount

' Update the TransactionPost object
If oTransactionPost.Update
                               Then

MsgBox("Transaction Posted successfully", MsgBoxStyle.OKOnly, "SDO Examples")

Else

MsgBox("Transaction Post Failed", MsgBoxStyle.OKOnly, "SDO Examples")

End  If

' Disconnect
oWS.Disconnect()

End  If

End  If

' Destroy Objects
oTransactionPost =  Nothing
oSplitData =  Nothing
oSalesRecord =  Nothing
oWS =  Nothing
oSDO =  Nothing

Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.SalesRecord oSalesRecord;

SageDataObject300.TransactionPost oTransactionPost;

SageDataObject300.SplitData oSplitData;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate Objects

  oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

  oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");

  //Read the first customer

  oSalesRecord.MoveFirst();

  //Populate Header Fields

  //Note:

  //The Account_Ref field must be populated with a valid

  //Customer account reference

  SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF",

    (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));

  SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);

  SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);

  SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoSI);

  SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"INV001");

  //Populate the foreign currency fields

  SDOHelper.Write(oTransactionPost.Header, "CURRENCY", SDOHelper.Read(oSalesRecord, "CURRENCY"));

  //Loop for the number of splits

  //Note:

  //The transaction can have 1 or many splits

  for (Int16 i = 1; i <= 2; i++)

  {

    //Add a split to the headers item collection

    oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

    //Populate split fields

    SDOHelper.Write(oSplitData,"TYPE",

    SDOHelper.Read(oTransactionPost.Header,"TYPE"));

    SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"4000");

    SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)1);

    SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)100);

    SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)17.5);

    SDOHelper.Write(oSplitData, "DETAILS", (String)"Split Details ");

    SDOHelper.Write(oSplitData, "DATE",

      (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));

  }

  //Update the transaction post object

  if (oTransactionPost.Update())

  {

    MessageBox.Show("Transaction Posted Successfully");

  }

  else

  {

    MessageBox.Show("Transaction Post Failed");

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Posting a Customer Batch Sales Credit Note

Example - Posting a Customer Batch Sales Credit Note

The example code below demonstrates how to post a Customer Batch Sales Credit Note.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code

                                  ' Declare Objects
Dim oSDO  As
                                SageDataObject300.SDOEngine
Dim oWS  As
                                SageDataObject300.WorkSpace
Dim oSalesRecord  As
                                SageDataObject300.SalesRecord
Dim oTransactionPost  As
                                SageDataObject300.TransactionPost
Dim oSplitData  As
                                SageDataObject300.SplitData

' Declare Variables
Dim szDataPath  As
                                 String
Dim iSplitCount  As
                                 Short

' Create the SDO Engine Object
oSDO =  New   SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company.  The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> ""  Then

' Try to Connect - Will throw an
    exception if it fails
If oWS.Connect(szDataPath, "", "", "Example")  Then

' Create Instances of Objects
oTransactionPost = oWS.CreateObject("TransactionPost")
oSalesRecord = oWS.CreateObject("SalesRecord")

' Read the First Customer
oSalesRecord.MoveFirst()

' Populate Header fields
' Note:
' The ACCOUNT_REF field must be populated with a valid
' Customer Account Reference
oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value = CDate(Today)
oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoSC)
oTransactionPost.Header("INV_REF").Value = CStr("CRD001")

' Populate the foreign currency fields
oTransactionPost.Header("CURRENCY").Value = oSalesRecord.Fields.Item("CURRENCY").Value

' Loop for the Number of Splits
' Note:
' The Transaction can have 1 or many splits
For iSplitCount = 1  To 2

' Add a split to the Header Item's collection
oSplitData = oTransactionPost.Items.Add

' Populate Split Fields
oSplitData.Fields.Item("TYPE").Value = oTransactionPost.Header("TYPE").Value
oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("4000")
oSplitData.Fields.Item("TAX_CODE").Value = CShort(1)
oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(100)
oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(17.5)
oSplitData.Fields.Item("DETAILS").Value = Cstr("Split Details")
oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)

Next iSplitCount

' Update the TransactionPost
    Object
If oTransactionPost.Update  Then

' Transaction Post Successful
MsgBox("Transaction Posted
                                  successfully.", MsgBoxStyle.OKOnly, "SDO Examples")

Else

' Transaction Post Failed
MsgBox("Transaction Post
                                  Failed.", MsgBoxStyle.OKOnly, "SDO Examples")

End  If

' Disconnect
oWS.Disconnect()

End  If

End  If

' Destroy Objects
oTransactionPost =  Nothing
oSplitData =  Nothing
oSalesRecord =  Nothing
oWS =  Nothing
oSDO =  Nothing

Exit  Sub
C#.NET [image] Copy C# Code
                // Declare Objects
                SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
                SageDataObject300.WorkSpace oWS;
                SageDataObject300.SalesRecord oSalesRecord;
                SageDataObject300.TransactionPost oTransactionPost;
                SageDataObject300.SplitData oSplitData;

                //Declare Variables
                String szDataPath;

                //Instantiate WorkSpace
                oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

                //Show select company dialog
                szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

                //Try a connection, will throw an exception if it fails
                try
                {
                    //Leaving the username and password blank generates a login dialog
                    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                    //Instantiate Objects
                    oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");
                    oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");

                    //Read the first customer
                    oSalesRecord.MoveFirst();

                    //Populate Header Fields
                    //Note:
                    //The Account_Ref field must be populated with a valid
                    //Customer account reference
                    SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF",
                      (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));
                    SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);
                    SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);
                    SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoSC);
                    SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"CRED001");

                    //Populate the foreign currency fields

                    SDOHelper.Write(oTransactionPost.Header, "CURRENCY", SDOHelper.Read(oSalesRecord, "CURRENCY"));

                    //Loop for the number of splits
                    //Note:
                    //The transaction can have 1 or many splits
                    for (Int16 i = 1; i <= 2; i++)
                    {
                        //Add a split to the headers item collection
                        oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                        //Populate split fields
                        SDOHelper.Write(oSplitData, "TYPE",
                        SDOHelper.Read(oTransactionPost.Header, "TYPE"));
                        SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"4000");
                        SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)1);
                        SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)100);
                        SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)17.5);
                        SDOHelper.Write(oSplitData, "DETAILS", (String)"Split Details ");
                        SDOHelper.Write(oSplitData, "DATE",
                          (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));
                    }

                    //Update the transaction post object
                    if (oTransactionPost.Update())
                    {
                        MessageBox.Show("Transaction Posted Successfully");
                    }

                    else
                    {
                        MessageBox.Show("Transaction Post Failed");
                    }

                }

                catch (Exception ex)
                {
                    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
                }
                finally
                {
                    //Disconnect
                    oWS.Disconnect();
                }


Sage 50 Accounts - Example - Posting a Customer Sales�Payment

Example - Posting a Customer Sales Payment

The example code below demonstrates how to post a Customer Sales Payment.

NOTE: It is important to populate the ACCOUNT_REF and BANK_CODE fields on the transaction header, and ensure that the NOMINAL_CODE field on the transaction split is identical to the bank code. Without these, TransactionPost.Update will not return True.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
'Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oSalesRecord As SageDataObject300.SalesRecord
Dim oTransactionPost As SageDataObject300.TransactionPost
Dim oSplitData As SageDataObject300.SplitData

'Declare Variables
Dim szDataPath As String
Dim iSplitCount As Short

'Create the SDO Engine Object
oSDO = New SageDataObject300.SDOEngine

'Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

'Select Company. The SelectCompany method takes the program install
'folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

'A U.I. for company selection is presented to the user. If a company is selected,
'the path will be passed to the szDataPath variable.
'If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

'Try to Connect - Will throw an exception if it fails
If oWS.Connect(szDataPath, "", "", "Example") Then

'Create Instances of Objects
oTransactionPost = oWS.CreateObject("TransactionPost")
oSalesRecord = oWS.CreateObject("SalesRecord")

'Read the First Customer
oSalesRecord.MoveFirst()

'Populate Header fields

'Note:
'The ACCOUNT_REF field must be populated with a validCustomer Account Reference
oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value = DateTime.Now.ToShortDateString
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoSP)
oTransactionPost.Header("INV_REF").Value = CStr("SP1")
oTransactionPost.Header("BANK_CODE").Value = CStr("1200")

'Populate the foreign currency fields
oTransactionPost.Header("CURRENCY").Value = oSalesRecord.Fields.Item("CURRENCY").Value

'NOTE: **The SP transaction cannot have multiple splits**
'Add a split to the Header Item's collection
oSplitData = oTransactionPost.Items.Add

'Populate Split Fields
oSplitData.Fields.Item("TYPE").Value = CByte(oTransactionPost.Header("TYPE").Value)
oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr(oTransactionPost.Header("BANK_CODE").Value)
oSplitData.Fields.Item("TAX_CODE").Value = CInt(9)
oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(100)
oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(0)
oSplitData.Fields.Item("DETAILS").Value = Cstr("Split Details")
oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)

'Update the TransactionPost object
If oTransactionPost.Update Then

MsgBox("Transaction Posted successfully", MsgBoxStyle.OKOnly, "SDO Examples")

Else

MsgBox("Transaction Post Failed", MsgBoxStyle.OKOnly, "SDO Examples")

End If

'Disconnect
oWS.Disconnect()

End If

End If

'Destroy Objects
oTransactionPost = Nothing
oSplitData = Nothing
oSalesRecord = Nothing
oWS = Nothing
oSDO = Nothing

Exit Sub
C#.NET [image] Copy C# Code
        //Declare Variables
            SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
            SageDataObject300.WorkSpace oWS;
            SageDataObject300.TransactionPost oTransactionPost;
            SageDataObject300.SplitData oSplitdata;
            SageDataObject300.SalesRecord oSalesRecord;
            String szDataPath;

            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails

            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                //Instantiate Objects
                oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");
                oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");

                //Read the first customer
                oSalesRecord.MoveFirst();

                //Fill in the header fields
                SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF",
                  (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));
                SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);
                SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);
                SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoSP);
                SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"Pay001");
                SDOHelper.Write(oTransactionPost.Header, "BANK_CODE", (String)"1200");

                //Populate the foreign currency fields
                SDOHelper.Write(oTransactionPost.Header, "CURRENCY", SDOHelper.Read(oSalesRecord, "CURRENCY"));

                //Create a split item by adding an empty split to the items
                //collection of the TranactionPost Object
                oSplitdata = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                //Populate the split fields
                //Note: a sales Receipt only has one split
                SDOHelper.Write(oSplitdata, "TYPE", (Byte)SageDataObject300.TransType.sdoSA);
                SDOHelper.Write(oSplitdata, "NOMINAL_CODE", (String)"1200");
                SDOHelper.Write(oSplitdata, "TAX_CODE", (Int16)9);
                SDOHelper.Write(oSplitdata, "NET_AMOUNT", (Double)200);
                SDOHelper.Write(oSplitdata, "TAX_AMOUNT", (Double)0);
                SDOHelper.Write(oSplitdata, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));
                SDOHelper.Write(oSplitdata, "DETAILS", (String)SDOHelper.Read(oTransactionPost.Header, "DETAILS"));

                //Update the TransactionPost object
                if (oTransactionPost.Update())
                {
                    MessageBox.Show("Transaction Post Was Successful");
                }

                else
                {
                    MessageBox.Show("Transaction Failed To Post");
                }

                //Disconnect
                oWS.Disconnect();
            }

            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
            finally
            {
                //Disconnect
                oWS.Disconnect();
            }


Sage 50 Accounts - Example - Posting a Foreign Currency Sales Invoice

Example - Posting a Foreign Currency Sales Invoice

The example code below demonstrates how to post a Foreign Currency Sales Invoice.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
                                ' Declare Objects
Dim oSDO  As
                              SageDataObject300.SDOEngine
Dim oWS  As
                              SageDataObject300.WorkSpace
Dim oSalesRecord  As
                              SageDataObject300.SalesRecord
Dim oTransactionPost  As
                              SageDataObject300.TransactionPost
Dim oSplitData  As
                              SageDataObject300.SplitData
Dim oCurrencyData As   SageDataObject300.CurrencyData

' Declare Variables
Dim szDataPath  As
                               String
Dim iSplitCount  As
                               Short

' Create the SDO Engine Object
oSDO =  New   SageDataObject300.SDOEngine

' Create the Workspace
oWS =
                                oSDO.Workspaces.Add("Example")

' Select Company.  The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> ""  Then

' Try to Connect - Will throw an
                                  exception if it fails
If oWS.Connect(szDataPath, "", "", "Example")
                               Then

' Create Instances of Objects
oTransactionPost =

                                oWS.CreateObject("TransactionPost")
oSalesRecord =
                                oWS.CreateObject("SalesRecord")
oCurrencyData =
                                oWS.CreateObject("CurrencyData")

' Read the First Customer
oSalesRecord.MoveFirst()

' Read the Currency
                                  File
oCurrencyData.Read(Convert.ToByte(oSalesRecord.Fields.Item("CURRENCY").Value)
                                +
                                1)

' Populate Header fields

' Note:
' The ACCOUNT_REF field must be populated with a valid
' Customer Account Reference
oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value = CDate(Today)
oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoSI)
oTransactionPost.Header("DETAILS").Value = CStr("Test Sales Invoice")
oTransactionPost.Header("INV_REF").Value = CStr("INV001")

' Populate Foreign
                              Currency Fields
oTransactionPost.Header("FOREIGN_RATE").Value =
                                oCurrencyData.Fields.Item("EXCHANGE_RATE").Value
oTransactionPost.Header("CURRENCY").Value =

                                oSalesRecord.Fields.Item("CURRENCY").Value

' Loop for the Number of Splits
' Note:
' The Transaction can have 1 or many splits
For iSplitCount = 1
                               To 2

' Add a split to the Header Item's collection
oSplitData = oTransactionPost.Items.Add

' Populate Split Fields
oSplitData.Fields.Item("TYPE").Value =

                                oTransactionPost.Header("TYPE").Value
oSplitData.Fields.Item("NOMINAL_CODE").Value =
                              CStr("4000")
oSplitData.Fields.Item("TAX_CODE").Value =
                              CShort(1)
oSplitData.Fields.Item("FOREIGN_NET_AMOUNT").Value =
                              CDbl(100)
oSplitData.Fields.Item("FOREIGN_TAX_AMOUNT").Value =
                              CDbl(17.5)
oSplitData.Fields.Item("DATE").Value =
                              CDate(oTransactionPost.Header("DATE").Value)

Next iSplitCount

' Update the TransactionPost object
If oTransactionPost.Update
                               Then

MsgBox("Transaction Posted successfully", MsgBoxStyle.OKOnly, "SDO Examples")

Else

MsgBox("Transaction Post Failed", MsgBoxStyle.OKOnly, "SDO Examples")

End  If

' Disconnect
oWS.Disconnect()

End  If

End  If

' Destroy Objects
oTransactionPost =  Nothing
oSplitData =  Nothing
oSalesRecord =  Nothing
oCurrencyData = Nothing
oWS =
                               Nothing
oSDO =  Nothing

Exit  Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.SalesRecord oSalesecord;

SageDataObject300.TransactionPost oTransactionPost;

SageDataObject300.SplitData oSplitData;

SageDataObject300.CurrencyData oCurrencyData;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate Objects

  oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

  oSalesecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");

  oCurrencyData = (SageDataObject300.CurrencyData)oWS.CreateObject("CurrencyData");

  //Read the first customer

  oSalesecord.MoveFirst();

  //Read the currency file depending on the currency specified in the customer record

  oCurrencyData.Read(Convert.ToInt32(SDOHelper.Read(oSalesecord, "CURRENCY"))+1);

  //Populate the header fields

  //Note:

  //The ACCOUNT_REF field must be populated with a valid

  //customer account reference

  SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oSalesecord, "ACCOUNT_REF"));

  SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);

  SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);

  SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoSI);

  SDOHelper.Write(oTransactionPost.Header, "DETAILS", (String)"Test Sales Invoice");

  SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"INV001");

  //Populate foreign currency fields

  SDOHelper.Write(oTransactionPost.Header, "FOREIGN_RATE", SDOHelper.Read(oCurrencyData, "EXCHANGE_RATE"));

  SDOHelper.Write(oTransactionPost.Header, "CURRENCY", SDOHelper.Read(oSalesecord, "CURRENCY"));

  //Loop for the number of splits

  //Note:

  //The transaction can have 1 or many splits

  for (Int16 i = 1; i <= 2; i++)

  {

    //Add a split to the headers items collection

    oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

    //Populate the split fields

    SDOHelper.Write(oSplitData, "TYPE", (Byte)SageDataObject300.TransType.sdoSI);

    SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"4000");

    SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)1);

    SDOHelper.Write(oSplitData, "FOREIGN_NET_AMOUNT", (Double)100);

    SDOHelper.Write(oSplitData, "FOREIGN_TAX_AMOUNT", (Double)17.5);

    SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));

  }

  //Update the Transaction Post object

  if (oTransactionPost.Update())

  {

    MessageBox.Show("Transaction Posted Successfully");

  }

  else

  {

    MessageBox.Show("Transaction Post Failed");

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Posting a Foreign Currency Sales Credit Note

Example - Posting a Foreign Currency Sales Credit Note

The example code below demonstrates how to post a Foreign Currency Sales Credit Note.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oSalesRecord As SageDataObject300.SalesRecord
Dim oTransactionPost As SageDataObject300.TransactionPost
Dim oSplitData As SageDataObject300.SplitData
Dim oCurrencyData As SageDataObject300.CurrencyData

' Declare Variables
Dim szDataPath As String
Dim iSplitCount As Short

' Create the SDO Engine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

' Try to Connect - Will throw an exception if it fails
If oWS.Connect(szDataPath, "", "", "Example") Then

' Create Instances of Objects
oTransactionPost = oWS.CreateObject("TransactionPost")
oSalesRecord = oWS.CreateObject("SalesRecord")
oCurrencyData = oWS.CreateObject("CurrencyData")

' Read the First Customer
oSalesRecord.MoveFirst()

' Read the Currency File
oCurrencyData.Read(Convert.ToByte(oSalesRecord.Fields.Item("CURRENCY").Value) + 1)

' Populate Header fields

' Note:
' The ACCOUNT_REF field must be populated with a valid
' Customer Account Reference
oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value = CDate(Today)
oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoSC)
oTransactionPost.Header("DETAILS").Value = CStr("Test Sales Credit Note")
oTransactionPost.Header("INV_REF").Value = CStr("CRD001")

' Populate Foreign Currency Fields
oTransactionPost.Header("FOREIGN_RATE").Value = oCurrencyData.Fields.Item("EXCHANGE_RATE").Value
oTransactionPost.Header("CURRENCY").Value = oSalesRecord.Fields.Item("CURRENCY").Value

' Loop for the Number of Splits
' Note:
' The Transaction can have 1 or many splits
For iSplitCount = 1 To 2

' Add a split to the Header Item's collection
oSplitData = oTransactionPost.Items.Add

' Populate Split Fields
oSplitData.Fields.Item("TYPE").Value = oTransactionPost.Header("TYPE").Value
oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("4000")
oSplitData.Fields.Item("TAX_CODE").Value = CShort(1)
oSplitData.Fields.Item("FOREIGN_NET_AMOUNT").Value = CDbl(100)
oSplitData.Fields.Item("FOREIGN_TAX_AMOUNT").Value = CDbl(17.5)
oSplitData.Fields.Item("DETAILS").Value = Cstr("Split Details")
oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)

Next iSplitCount

' Update the TransactionPost Object
If oTransactionPost.Update Then

' Transaction Post Successful
MsgBox("Transaction Posted successfully.", MsgBoxStyle.OKOnly, "SDO Examples")

Else

' Transaction Post Failed
MsgBox("Transaction Post Failed.", MsgBoxStyle.OKOnly, "SDO Examples")

End If

' Disconnect
 oWS.Disconnect()

End If

End If

' Destroy Objects
oTransactionPost = Nothing
oSplitData = Nothing
oSalesRecord = Nothing
 oCurrencyData = Nothing
oWS = Nothing
oSDO = Nothing

Exit Sub
C#.NET [image] Copy C# Code
            //Declare Variables
            SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
            SageDataObject300.WorkSpace oWS;
            SageDataObject300.SalesRecord oSalesecord;
            SageDataObject300.TransactionPost oTransactionPost;
            SageDataObject300.SplitData oSplitData;
            SageDataObject300.CurrencyData oCurrencyData;
            String szDataPath;

            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                //Instantiate Objects
                oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");
                oSalesecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");
                oCurrencyData = (SageDataObject300.CurrencyData)oWS.CreateObject("CurrencyData");

                //Read the first customer (must have currency set to non base)
                oSalesecord.MoveLast();

                //Read the currency file depending on the currency specified in the customer record
                oCurrencyData.Read(Convert.ToInt32(SDOHelper.Read(oSalesecord, "CURRENCY")) + 1);

                //Populate the header fields
                //Note:
                //The ACCOUNT_REF field must be populated with a valid
                //customer account reference
                SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oSalesecord, "ACCOUNT_REF"));
                SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);
                SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);
                SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoSC);
                SDOHelper.Write(oTransactionPost.Header, "DETAILS", (String)"Test Sales Credit Note");
                SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"CRD001");

                //Populate foreign currency fields
                SDOHelper.Write(oTransactionPost.Header, "FOREIGN_RATE", SDOHelper.Read(oCurrencyData, "EXCHANGE_RATE"));
                SDOHelper.Write(oTransactionPost.Header, "CURRENCY", SDOHelper.Read(oSalesecord, "CURRENCY"));

                //Loop for the number of splits
                //Note:
                //The transaction can have 1 or many splits
                for (Int16 i = 1; i <= 2; i++)
                {
                    //Add a split to the headers items collection
                    oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                    //Populate the split fields
                    SDOHelper.Write(oSplitData, "TYPE", (Byte)SageDataObject300.TransType.sdoSC);
                    SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"4000");
                    SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)1);
                    SDOHelper.Write(oSplitData, "FOREIGN_NET_AMOUNT", (Double)100);
                    SDOHelper.Write(oSplitData, "FOREIGN_TAX_AMOUNT", (Double)17.5);
                    SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));
                }

                //Update the Transaction Post object
                if (oTransactionPost.Update())
                {
                    MessageBox.Show("Transaction Posted Successfully");
                }

                else
                {
                    MessageBox.Show("Transaction Post Failed");
                }
            }

            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
            finally
            {
                //Disconnect
                oWS.Disconnect();
            }


Sage 50 Accounts - Example - Posting a�Sales Credit Note and Allocating it to Outstanding Invoices

Example - Posting a Sales Credit Note and Allocating it to Outstanding Invoices

The example code below demonstrates how to post a sales credit note and then allocate it against existing sales invoices.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oSalesRecord As SageDataObject300.SalesRecord
Dim oTransactionPost As SageDataObject300.TransactionPost
Dim oInvoiceSplitData As SageDataObject300.SplitData
Dim oCreditSplitData As SageDataObject300.SplitData
Dim oInvoiceHeaderData As SageDataObject300.HeaderData
Dim oCreditHeaderData As SageDataObject300.HeaderData

' Declare Variables
Dim szDataPath As String
Dim bRecordFound, bAllocated As Boolean
Dim dInvoiceValue, dCreditValue, dAllocateValue, dCreditTotalOutstanding As Double
Dim iSplitCount, iInvoiceTotalOutstanding As Integer

 ' Create the SDO Engine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

' Try to Connect - Will throw an exception if it fails
If oWS.Connect(szDataPath, "", "", "Example") Then

' Create Instance Objects to Post the Credit Note
oSalesRecord = oWS.CreateObject("SalesRecord")
oTransactionPost = oWS.CreateObject("TransactionPost")
oCreditHeaderData = oWS.CreateObject("HeaderData")

' Initialise Index Field with value to search
oSalesRecord.Fields.Item("ACCOUNT_REF").Value = CStr ("ABS001")

' Perform Find for an exact match
If oSalesRecord.Find(False) Then
' Populate Header fields
' Note:
' The ACCOUNT_REF field must be populated with a valid
' Customer Account Reference

oTransactionPost.Header("ACCOUNT_REF").Value = CStr (oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value = CDate(Now)
oTransactionPost.Header("POSTED_DATE").Value = CDate(Now)
oTransactionPost.Header("TYPE").Value = CByte (SageDataObject300.TransType.sdoSC)
oTransactionPost.Header("DETAILS").Value = CStr ("Test Sales Credit Note")
oTransactionPost.Header("INV_REF").Value = CStr ("CRD001")

' Loop for the Number of Splits
' Note:
' The Transaction can have 1 or many splits

For iSplitCount = 1 To 2

' Add a split to the Header Item's collection
oInvoiceSplitData = oTransactionPost.Items.Add

' Populate Split Fields
oInvoiceSplitData.Fields.Item("TYPE").Value = oTransactionPost.Header("TYPE").Value
oInvoiceSplitData.Fields.Item("NOMINAL_CODE").Value = CStr ("4000")
oInvoiceSplitData.Fields.Item("TAX_CODE").Value = CShort (1)
oInvoiceSplitData.Fields.Item("NET_AMOUNT").Value = CDbl (100)
oInvoiceSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl (17.5)
oInvoiceSplitData.Fields.Item("DETAILS").Value = Cstr("Split Details")
oInvoiceSplitData.Fields.Item("DATE").Value = CDate

Next iSplitCount

' Update the TransactionPost Object
If oTransactionPost.Update Then

' Transaction Post Successful
MsgBox("Credit Note transaction Posted successfully.", MsgBoxStyle.OKOnly, "SDO Examples")

' Read the HeaderData for Credit
oCreditHeaderData.Read(oTransactionPost.PostingNumber)

' Create a new Transaction post object
oTransactionPost = Nothing
oTransactionPost = oWS.CreateObject("TransactionPost")

'Calculate the total outstanding on the Credit Note
dCreditTotalOutstanding = CDbl(oCreditHeaderData.Fields.Item("NET_AMOUNT").Value) + CDbl(oCreditHeaderData.Fields.Item("TAX_AMOUNT").Value) - CDbl(oCreditHeaderData.Fields.Item("AMOUNT_PAID").Value)

'Link to the Credit Splits
oCreditSplitData = oCreditHeaderData.Link
oCreditSplitData.MoveFirst()

'Calculate the Credit Split amount outstanding
dCreditValue = CDbl(oCreditSplitData.Fields.Item("NET_AMOUNT").Value) + CDbl(oCreditSplitData.Fields.Item("TAX_AMOUNT").Value) - CDbl(oCreditSplitData.Fields.Item("AMOUNT_PAID").Value)

' Link to Invoice Headers
oInvoiceHeaderData = oSalesRecord.Link

' Move to the first Header on the Customer account
oInvoiceHeaderData.MoveFirst()

' Loop through the Headers until an Invoice that has an outstanding amount is found
Do
iInvoiceTotalOutstanding = CDbl(oInvoiceHeaderData.Fields.Item("NET_AMOUNT").Value) + CDbl(oInvoiceHeaderData.Fields.Item("TAX_AMOUNT").Value) - CDbl(oInvoiceHeaderData.Fields.Item("AMOUNT_PAID").Value)

If Convert.ToByte(oInvoiceHeaderData.Fields.Item("TYPE").Value) = Convert.ToByte(SageDataObject300.TransType.sdoSI) And iInvoiceTotalOutstanding > 0 Then

'Link to Splits
oInvoiceSplitData = oInvoiceHeaderData.Link
oInvoiceSplitData.MoveFirst()

' Calculate the Invoice Split amount outstanding
dInvoiceValue = CDbl(oInvoiceSplitData.Fields.Item("NET_AMOUNT").Value) + CDbl(oInvoiceSplitData.Fields.Item("TAX_AMOUNT").Value) - CDbl(oInvoiceSplitData.Fields.Item("AMOUNT_PAID").Value)

Do

If Math.Round(CDec(dInvoiceValue), 2, MidpointRounding.AwayFromZero ) > 0 Then

' Calculate the amount to allocate
If dInvoiceValue > dCreditValue Then
dAllocateValue = dCreditValue

' Allocate Credit Against Invoice
bAllocated = oTransactionPost.AllocatePayment(CInt(oInvoiceSplitData.RecordNumber), CInt(oCreditSplitData.RecordNumber), CDbl(dAllocateValue), CDate(Now))
dCreditTotalOutstanding - = dAllocateValue
dInvoiceValue - = dAllocateValue
If Not oCreditSplitData.MoveNext() Then

Exit Do
Else
dCreditValue = CDbl(oCreditSplitData.Fields.Item("NET_AMOUNT").Value) + CDbl(oCreditSplitData.Fields.Item("TAX_AMOUNT").Value) - CDbl(oCreditSplitData.Fields.Item("AMOUNT_PAID").Value)

End If
Else
If dInvoiceValue < dCreditValue Then
dAllocateValue = dInvoiceValue

' Allocate Credit Against Invoice
bAllocated = oTransactionPost.AllocatePayment(CInt(oInvoiceSplitData.RecordNumber), CInt(oCreditSplitData.RecordNumber), CDbl(dAllocateValue), CDate(Now))
dCreditTotalOutstanding - = dAllocateValue
dCreditValue - = dAllocateValue
If Not oInvoiceSplitData.MoveNext() Then
Exit Do
Else
dInvoiceValue = CDbl(oInvoiceSplitData.Fields.Item("NET_AMOUNT").Value) + CDbl(oInvoiceSplitData.Fields.Item("TAX_AMOUNT").Value) - CDbl(oInvoiceSplitData.Fields.Item("AMOUNT_PAID").Value)
End If
Else
dAllocateValue = dInvoiceValue

' Allocate Credit Against Invoice
bAllocated = oTransactionPost.AllocatePayment(CInt(oInvoiceSplitData.RecordNumber), CInt(oCreditSplitData.RecordNumber), CDbl(dAllocateValue), CDate(Now))
If Not oCreditSplitData.MoveNext() Then
Exit Do
Else
dCreditValue = CDbl(oCreditSplitData.Fields.Item("NET_AMOUNT").Value) + CDbl(oCreditSplitData.Fields.Item("TAX_AMOUNT").Value) - CDbl(oCreditSplitData.Fields.Item("AMOUNT_PAID").Value)
If Not oInvoiceSplitData.MoveNext() Then
Exit Do
Else
dInvoiceValue = CDbl(oInvoiceSplitData.Fields.Item("NET_AMOUNT").Value) + CDbl(oInvoiceSplitData.Fields.Item("TAX_AMOUNT").Value) - CDbl(oInvoiceSplitData.Fields.Item("AMOUNT_PAID").Value)

End If

End If

End If

End If
Else
 oInvoiceSplitData.MoveNext
dInvoiceValue = CDbl(oInvoiceSplitData.Fields.Item("NET_AMOUNT").Value) + CDbl(oInvoiceSplitData.Fields.Item("TAX_AMOUNT").Value) - CDbl(oInvoiceSplitData.Fields.Item("AMOUNT_PAID").Value)

End If

Loop Until dCreditTotalOutstanding = 0

End If

Loop Until Not oInvoiceHeaderData.MoveNext Or dCreditTotalOutstanding = 0

Else

' Transaction Post Failed
MsgBox("Credit Note transaction Post Failed.", MsgBoxStyle.OKOnly, "SDO Examples")
Exit Sub
End If
End If

' Disconnect
oWS.Disconnect()

End If

End If

' Destroy Objects
oSalesRecord = Nothing
oInvoiceHeaderData = Nothing
oInvoiceSplitData = Nothing
oCreditHeaderData = Nothing
oCreditSplitData = Nothing
oTransactionPost = Nothing
oSDO = Nothing
oWS = Nothing

Exit Sub
C#.NET [image] Copy C# Code
// Declare Objects
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.SalesRecord oSalesRecord;
SageDataObject300.TransactionPost oTransactionPost;
SageDataObject300.SplitData oInvoiceSplitData;
SageDataObject300.SplitData oCreditSplitData;
SageDataObject300.HeaderData oInvoiceHeaderData;
SageDataObject300.HeaderData oCreditHeaderData;

// Declare Variables
string szDataPath;
bool bRecordFound;
bool bAllocated;
double dInvoiceValue;
double dCreditValue;
double dAllocateValue;
double dCreditTotalOutstanding;
int iSplitCount;
double iInvoiceTotalOutstanding;

// Create the Workspace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

// Select Company  The SelectCompany method takes the program install
// folder as a parameter
szDataPath = oSDO.SelectCompany("C:\\Documents and Settings\\All Users\\Application Data\\Sage\\Accounts\\2023");

// A U.I. for company selection is presented to the user. If a company is selected,
// the path will be passed to the szDataPath variable.
// If not, or the Cancel button is selected, the variable will be left empty.
if (szDataPath != "")
{

    // Try to Connect - Will throw an exception if it fails
    if (oWS.Connect(szDataPath, "", "", "Example"))
    {

        // Create Instance Objects to Post the Credit Note
        oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");
        oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");
        oCreditHeaderData = (SageDataObject300.HeaderData)oWS.CreateObject("HeaderData");

        // Initialise Index Field with value to search
        SDOHelper.Write(oSalesRecord,"ACCOUNT_REF",  (string)"ABS001");

        // Perform Find for an exact match
        if (oSalesRecord.Find(false))
        {

            // Populate Header fields
            // Note:
            // The ACCOUNT_REF field must be populated with a valid
            // Customer Account Reference

            SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));
            SDOHelper.Write(oTransactionPost.Header, "DATE", DateTime.Now);
            SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (System.DateTime)DateTime.Today);
            SDOHelper.Write(oTransactionPost.Header, "TYPE", (byte)SageDataObject300.TransType.sdoSC);
            SDOHelper.Write(oTransactionPost.Header, "DETAILS", (string)"Sales Payment to Allocate");
            SDOHelper.Write(oTransactionPost.Header, "INV_REF",(string)"CRD001");

            // Loop for the Number of Splits
            // Note:
            // The Transaction can have 1 or many splits

            for (iSplitCount = 1; iSplitCount <= 2; iSplitCount++)
            {

                // Add a split to the Header Item's collection
                oInvoiceSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                // Populate Split Fields
                 SDOHelper.Write(oInvoiceSplitData, "TYPE", (Convert.ToByte(SDOHelper.Read(oTransactionPost.Header, "TYPE"))));
                 SDOHelper.Write(oInvoiceSplitData, "NOMINAL_CODE",  (String)"4000");
                 SDOHelper.Write(oInvoiceSplitData, "TAX_CODE", (short)1);
                 SDOHelper.Write(oInvoiceSplitData, "NET_AMOUNT", (Double)100);
                 SDOHelper.Write(oInvoiceSplitData, "TAX_AMOUNT", (Double)17.5);
                 SDOHelper.Write(oInvoiceSplitData, "DETAILS",(String)"Split Details");
                 SDOHelper.Write(oInvoiceSplitData, "DATE", (System.DateTime)System.DateTime.Today);

            }

            // Update the TransactionPost Object
            if (oTransactionPost.Update())
            {

                // Transaction Post Successful
                MessageBox.Show("Credit Note transaction Posted successfully.");

                // Read the HeaderData for Credit
                oCreditHeaderData.Read(oTransactionPost.PostingNumber);

                // Create a new Transaction post object
                oTransactionPost = null;
                oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

                //Calculate the total outstanding on the Credit Note
                dCreditTotalOutstanding = (Double)SDOHelper.Read(oCreditHeaderData, "NET_AMOUNT") +
                    ((Double)SDOHelper.Read(oCreditHeaderData, "TAX_AMOUNT")) -
                    (Double)SDOHelper.Read(oCreditHeaderData, "AMOUNT_PAID");

                //Link to the Credit Splits
                oCreditSplitData = (SageDataObject300.SplitData)oCreditHeaderData.Link;
                oCreditSplitData.MoveFirst();

                //Calculate the Credit Split amount outstanding
                dCreditValue = (Double)SDOHelper.Read(oCreditSplitData, "NET_AMOUNT") +
                    (Double)SDOHelper.Read(oCreditSplitData, "TAX_AMOUNT") -
                    (Double)SDOHelper.Read(oCreditSplitData, "AMOUNT_PAID");

                // Link to Invoice Headers
                oInvoiceHeaderData = (SageDataObject300.HeaderData)oSalesRecord.Link;

                // Move to the first Header on the Customer account
                oInvoiceHeaderData.MoveFirst();

                // Loop through the Headers until an Invoice that has an outstanding amount is found
                do
                {
                    iInvoiceTotalOutstanding = (Double)SDOHelper.Read(oInvoiceHeaderData, "NET_AMOUNT") +
                        (Double)SDOHelper.Read(oInvoiceHeaderData, "TAX_AMOUNT") -
                        (Double)SDOHelper.Read(oInvoiceHeaderData, "AMOUNT_PAID");

                    if (Convert.ToByte(SDOHelper.Read(oInvoiceHeaderData, "TYPE")) ==
                        Convert.ToByte(SageDataObject300.TransType.sdoSI) &
                        iInvoiceTotalOutstanding > 0)
                    {

                        //Link to Splits
                        oInvoiceSplitData = (SageDataObject300.SplitData) oInvoiceHeaderData.Link;
                        oInvoiceSplitData.MoveFirst();

                        // Calculate the Invoice Split amount outstanding
                        dInvoiceValue = (double)SDOHelper.Read(oInvoiceSplitData, "NET_AMOUNT") +
                            (Double)SDOHelper.Read(oInvoiceSplitData, "TAX_AMOUNT") -
                            (Double)SDOHelper.Read(oInvoiceSplitData, "AMOUNT_PAID");

                        do
                        {

                            if (Math.Round((Decimal)dInvoiceValue, 2, MidpointRounding.AwayFromZero) > 0)
                            {

                                // Calculate the amount to allocate
                                if (dInvoiceValue > dCreditValue)
                                {
                                    dAllocateValue = dCreditValue;

                                    // Allocate Credit Against Invoice
                                    bAllocated = oTransactionPost.AllocatePayment((int)oInvoiceSplitData.RecordNumber,
                                        (int)oCreditSplitData.RecordNumber, (double)dAllocateValue,
                                        (System.DateTime)DateTime.Today);
                                    dCreditTotalOutstanding -= dAllocateValue;
                                    dInvoiceValue -= dAllocateValue;
                                    if (!oCreditSplitData.MoveNext())
                                    {

                                        break;
                                    }
                                    else
                                    {
                                        dCreditValue = (Double)SDOHelper.Read(oCreditSplitData, "NET_AMOUNT") +
                                            (Double)SDOHelper.Read(oCreditSplitData, "TAX_AMOUNT") -
                                            (Double)SDOHelper.Read(oCreditSplitData, "AMOUNT_PAID");

                                    }
                                }
                                else
                                {
                                    if (dInvoiceValue < dCreditValue)
                                    {
                                        dAllocateValue = dInvoiceValue;

                                        // Allocate Credit Against Invoice
                                        bAllocated = oTransactionPost.AllocatePayment((int)oInvoiceSplitData.RecordNumber,
                                            (int)oCreditSplitData.RecordNumber, (double)dAllocateValue, (System.DateTime)DateTime.Today);
                                        dCreditTotalOutstanding -= dAllocateValue;
                                        dCreditValue -= dAllocateValue;
                                        if (!oInvoiceSplitData.MoveNext())
                                        {
                                            break;
                                        }
                                        else
                                        {
                                            dInvoiceValue = (Double)SDOHelper.Read(oInvoiceSplitData, "NET_AMOUNT") +
                                                (Double)SDOHelper.Read(oInvoiceSplitData, "TAX_AMOUNT") -
                                                (Double)SDOHelper.Read(oInvoiceSplitData, "AMOUNT_PAID");
                                        }
                                    }
                                    else
                                    {
                                        dAllocateValue = dInvoiceValue;

                                        // Allocate Credit Against Invoice
                                        bAllocated = oTransactionPost.AllocatePayment((int)oInvoiceSplitData.RecordNumber,
                                            (int)oCreditSplitData.RecordNumber, (double)dAllocateValue, (System.DateTime)DateTime.Now);
                                        if (!oCreditSplitData.MoveNext())
                                        {
                                            break;
                                        }
                                        else
                                        {
                                            dCreditValue = (Double)SDOHelper.Read(oCreditSplitData, "NET_AMOUNT") +
                                                (Double)SDOHelper.Read(oCreditSplitData, "TAX_AMOUNT") -
                                                (Double)SDOHelper.Read(oCreditSplitData, "AMOUNT_PAID");
                                            if (!oInvoiceSplitData.MoveNext())
                                            {
                                                break;
                                            }
                                            else
                                            {
                                                dInvoiceValue = (double)SDOHelper.Read(oInvoiceSplitData, "NET_AMOUNT") +
                                                    (double)SDOHelper.Read(oInvoiceSplitData, "TAX_AMOUNT") -
                                                    (double)SDOHelper.Read(oInvoiceSplitData, "AMOUNT_PAID");

                                            }

                                        }

                                    }

                                }
                            }
                            else
                            {
                                oInvoiceSplitData.MoveNext();
                                dInvoiceValue = (Double)SDOHelper.Read(oInvoiceSplitData, "NET_AMOUNT") +
                                    (Double)SDOHelper.Read(oInvoiceSplitData, "TAX_AMOUNT") -
                                    (Double)SDOHelper.Read(oInvoiceSplitData, "AMOUNT_PAID");

                            }
                        }

                        while (!(dCreditTotalOutstanding == 0));

                    }
                }

                while (!(!oInvoiceHeaderData.MoveNext() | dCreditTotalOutstanding == 0));
            }

            else
            {

                // Transaction Post Failed
                MessageBox.Show("Credit Note transaction Post Failed.");
                return;
            }
        }

        // Disconnect
        oWS.Disconnect();

    }

}

// Destroy Objects
oSalesRecord = null;
oInvoiceHeaderData = null;
oInvoiceSplitData = null;
oCreditHeaderData = null;
oCreditSplitData = null;
oTransactionPost = null;
oSDO = null;
oWS = null;

return;


Sage 50 Accounts - Example - Reading sales delivery records

Example - Reading sales delivery records

The example code below demonstrates how to read sales delivery records.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
        Dim oSDO As SageDataObject300.SDOEngine
        Dim oWS As SageDataObject300.WorkSpace
        Dim oSalesRecord As SageDataObject300.SalesRecord
        Dim oSalesDeliveryRecord As SageDataObject300.SalesDeliveryRecord

        ' Declare Variables
        Dim szDataPath As String
        Dim bFound As Boolean
        Dim bEnd As Boolean
        Dim bFlag As Boolean

        ' Create the SDO Engine object
        oSDO = New SageDataObject300.SDOEngine

        ' Create the Workspace
        oWS = oSDO.Workspaces.Add("Example")

        ' Select company. The SelectCompany method takes the program install folder as a
        ' parameter
        szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

        ' A U.I. for company selection is presented to the user. If a company is
        ' selected, the path will be passed to the szDataPath variable.
        ' If not, or the Cancel button is selected, the variable will be left empty.
        If szDataPath <> "" Then

            ' Connect to Data Files
            If oWS.Connect(szDataPath, "", "", "Example") Then

                ' Create Instances of the Sales Objects
                oSalesRecord = oWS.CreateObject("SalesRecord")
                oSalesDeliveryRecord = oWS.CreateObject("SalesDeliveryRecord")

                ' Read the first supplier record
                oSalesRecord.MoveFirst()

                ' Initialise flag's
                bEnd = False
                bFound = False

                ' Move to First Record in the delivery address file
                oSalesDeliveryRecord.MoveFirst()

                ' Search records for occurrences in the file of this customer's delivery address'
                ' or until we have read all the records in the file
                Do

                    ' Do we have a match ?
                    If (oSalesDeliveryRecord.Fields.Item("ACCOUNT_REF").Value = _
                    oSalesRecord.Fields.Item("ACCOUNT_REF").Value) Then

                        ' If yes, set the found flag to true
                        bFound = True

                        'Display the details for the delivery address
                        MessageBox.Show(oSalesRecord.Fields.Item("NAME").Value & " " & _
                        oSalesDeliveryRecord.Fields.Item("NAME").Value & " " & _
                        oSalesDeliveryRecord.Fields.Item("ADDRESS_1").Value & " " & _
                        oSalesDeliveryRecord.Fields.Item("ADDRESS_2").Value & " " & _
                        oSalesDeliveryRecord.Fields.Item("ADDRESS_3").Value & " " & _
                        oSalesDeliveryRecord.Fields.Item("ADDRESS_4").Value & " " & _
                        oSalesDeliveryRecord.Fields.Item("ADDRESS_5").Value)

                    Else

                        ' If we have already found a match we must have stepped of it now
                        ' so end our search

                        If (bFound) Then

                            bEnd = True

                        End If

                    End If

                Loop Until (bEnd Or Not oSalesDeliveryRecord.MoveNext)

                ' Disconnect
                oWS.Disconnect()

            End If

        End If

        ' Destroy Objects
        oSalesRecord = Nothing
        oSalesDeliveryRecord = Nothing
        oWS = Nothing
        oSDO = Nothing

                                    Exit Sub
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.SalesRecord oSalesRecord;
SageDataObject300.SalesDeliveryRecord oSalesDeliveryRecord;

String szDataPath;
Boolean bFound;
Boolean bEnd;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails
try
{
    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

    //Instantiate the Sales Record and Sales Delivery Record objects
    oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");
    oSalesDeliveryRecord = (SageDataObject300.SalesDeliveryRecord)oWS.CreateObject("SalesDeliveryRecord");

    //Read the first supplier record
    oSalesRecord.MoveFirst();

    //Initialise flags
    bEnd = false;
    bFound = false;

    //Move to the first record in the delivery address file
    oSalesDeliveryRecord.MoveFirst();

    //Search records for occurrences in the file of this customer's delivery address
    //or until we have read all the records in the file

    do
    {
        // Do we have a match ?
        if ((String)SDOHelper.Read(oSalesDeliveryRecord, "ACCOUNT_REF") == (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"))
        {
            //If yes, set the found flag to true
            bFound = true;

            //Display the details for the delivery address
            MessageBox.Show(SDOHelper.Read(oSalesDeliveryRecord, "ACCOUNT_REF") + Environment.NewLine +
                SDOHelper.Read(oSalesDeliveryRecord, "NAME") + Environment.NewLine +
                SDOHelper.Read(oSalesDeliveryRecord, "REFERENCE") + Environment.NewLine +
                SDOHelper.Read(oSalesDeliveryRecord, "ADDRESS_1") + Environment.NewLine +
                SDOHelper.Read(oSalesDeliveryRecord, "ADDRESS_2") + Environment.NewLine +
                SDOHelper.Read(oSalesDeliveryRecord, "ADDRESS_3") + Environment.NewLine +
                SDOHelper.Read(oSalesDeliveryRecord, "ADDRESS_4") + Environment.NewLine +
                SDOHelper.Read(oSalesDeliveryRecord, "ADDRESS_5") + Environment.NewLine);

        }
        else

        //If we have already found a match we must have stepped of it now
        //so end our search
        {

            if (bFound == true)
            {
                bEnd = true;

            }

        }

    } while (!((bEnd | !oSalesDeliveryRecord.MoveNext())));

    //Disconnect
    oWS.Disconnect();

}
//error handling
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}


Sage 50 Accounts - Example - View Customer Aged Balances

Example - View Customer Aged Balances

The example code below demonstrates how to view customer aged balances.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
 ' Declare Objects
 Dim oSDO As SageDataObject300.SDOEngine
 Dim oWS As SageDataObject300.WorkSpace
 Dim oSalesRecord As SageDataObject300.SalesRecord
 Dim oAgedBalances As SageDataObject300.AgedBalances

 ' Declare Variables
 Dim szDataPath As String

 ' Error Handler
 Try
   ' Create the SDO Engine object
   oSDO = New SageDataObject300.SDOEngine

   ' Create the Workspace
   oWS = oSDO.Workspaces.Add("Example")

   ' Select company. The SelectCompany method takes the program install folder as a parameter
   szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

   ' A U.I. for company selection is presented to the user. If a company is selected,
   ' the path will be passed to the szDataPath variable.
   ' If not, or the Cancel button is selected, the variable will be left empty.
   If szDataPath <> "" Then
     ' Connect to Data Files
     If oWS.Connect(szDataPath, "", "", "Example") Then

       ' Get the sales ledger record
        oSalesRecord = oWS.CreateObject("SalesRecord")
       oSalesRecord.Fields.Item("ACCOUNT_REF").Value = "ABS001"

       ' Do an exact match search for the account
       If (oSalesRecord.Find(False)) Then

         ' Create the aged balances object
         oAgedBalances = oSalesRecord.GetAgedBalances()

         ' Set the date you wish to use to calculate the aged balances.
         oAgedBalances.SetAgedBalanceDate(CDate(Now))

         ' Set the date you wish to use to include payments up to.
         oAgedBalances.SetIncludePaymentDate(CDate(Now))

         ' Set the ageing type. This can be:
         ' sdoAgeByCalendarMonth - Ages by Calendar Month,
         ' sdoAgeByPeriod - Aged By Periods,
         ' sdoAgeByDay - Aged By Periods and first day of the month following the transaction date.
         ' Here we are ageing by Periods.
         oAgedBalances.SetAgedMode(SageDataObject300.TransactionAgeingType.sdoAgeByPeriod)

         ' If we are ageing by periods then we can specify the periods for this calculation.
         oAgedBalances.SetAgedPeriodStart(1, CInt(30))
         oAgedBalances.SetAgedPeriodStart(2, CInt(60))
         oAgedBalances.SetAgedPeriodStart(3, CInt(90))
         oAgedBalances.SetOlderAgedPeriod(CInt(160))

         ' Set whether you want to include transactions that are dated
         '  after the aged balance date in the customer's total balance.
         ' 0 - do not include.
         ' 1 - include.
         oAgedBalances.SetIncludeFuture(0)

         ' Calculate the aged balances
         oAgedBalances.Calculate()

         ' Get the Future, Current, Total and Older Balances
         Dim strFuture As String
         Dim strCurrent As String
         Dim strTotal As String
         Dim strPeriod As String
         Dim strOlder As String

         strFuture = CStr(oAgedBalances.GetFutureBalance())
         strCurrent = CStr(oAgedBalances.GetCurrentBalance())
         strTotal = CStr(oAgedBalances.GetTotalBalance())
         strOlder = CStr(oAgedBalances.GetOlderBalance)

         Dim strMessage As String
         Dim oItem As Object
         Dim iCount As Integer = 1

         strMessage = "Future balance : " + strFuture + vbCrLf _
         + "Current balance : " + strCurrent + vbCrLf _
         + "Total balance : " + strTotal + vbCrLf

         ' Loop through each of the period balances (3)
         For Each oItem In oAgedBalances

           strMessage += "Period" + CStr(iCount) + vbTab + CStr(oItem) + vbTab
           iCount += 1

         Next oItem

         strMessage += "Older" + vbTab + strOlder
         strMessage += vbCrLf

         MessageBox.Show(strMessage, "Aged Results for account " + oSalesRecord.Fields.Item("ACCOUNT_REF").Value, MessageBoxButtons.OK, MessageBoxIcon.Information)

       Else

         MessageBox.Show("The sales ledger account 'ABS001' cannot be found.", "SDO Error", MessageBoxButtons.OK, MessageBoxIcon.Error)

       End If
     Else

       MessageBox.Show( "Could not logon to the data.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

     End If

   End If

 Catch ex As Exception
   ' Error Handling Code
   MessageBox.Show("The SDO generated the following error: " & ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

  Finally

   If Not oSalesRecord Is Nothing Then
     oSalesRecord = Nothing
   End If

   If Not oAgedBalances Is Nothing Then
     oAgedBalances = Nothing
   End If

   If Not oWS Is Nothing Then
     oWS.Disconnect()
     oWS = Nothing
     oSDO = Nothing
   End If
 End Try
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.SalesRecord oSalesRecord;
SageDataObject300.AgedBalances oAgedBalances;

String szDataPath;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails
try
{
    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

    //Get the sales ledger record
    oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");
    SDOHelper.Write(oSalesRecord, "ACCOUNT_REF", "AAAA");

    //Do an exact match search on account
    if (oSalesRecord.Find(false))

    {
        //Create the aged balances object
        oAgedBalances = (SageDataObject300.AgedBalances)oSalesRecord.GetAgedBalances();

    //Set the date you wish to calculate the aged balances
    oAgedBalances.SetAgedBalanceDate((DateTime)DateTime.Today);

    //Set the date you wish to use to include payments up to.
    oAgedBalances.SetIncludePaymentDate((DateTime)DateTime.Today);

    //Set the ageing type. This can be:
    //sdoAgeByCalendarMonth - Ages by Calendar Month,
    //sdoAgeByPeriod - Aged By Periods,
    //sdoAgeByDay - Aged By Periods and first day of the month following the transaction date.
    //Here we are ageing by Periods.
    oAgedBalances.SetAgedMode(SageDataObject300.TransactionAgeingType.sdoAgeByPeriod);

    //If we are ageing by periods then we can specify the periods for this calculation
    oAgedBalances.SetAgedPeriodStart(1, (Int32)30);
    oAgedBalances.SetAgedPeriodStart(2, (Int32)60);
    oAgedBalances.SetAgedPeriodStart(3, (Int32)90);
    oAgedBalances.SetOlderAgedPeriod((Int32)160);

    //Set whether you want to include transactions that are dated
    //after the aged balance date in the customer's tottal balance.
    //0 - do not include
    //1 - include.
    oAgedBalances.SetIncludeFuture(0);

    //Calculate the aged balances
    oAgedBalances.Calculate();

    //Get the furure, curent total and older balances
    String strFuture;
    String strCurrent;
    String strTotal;
    String strOlder;

    strFuture = Convert.ToString(oAgedBalances.GetFutureBalance());
    strCurrent = Convert.ToString(oAgedBalances.GetCurrentBalance());
    strTotal = Convert.ToString(oAgedBalances.GetTotalBalance());
    strOlder = Convert.ToString(oAgedBalances.GetOlderBalance());

    String strMessage;
    Int32 iCount  = 1;

    strMessage = "Future balance : " + strFuture + Environment.NewLine +
        "Current balance : " + strCurrent + Environment.NewLine +
        "Total balance : " + strTotal + Environment.NewLine;

    for (int i = 1; i <= oAgedBalances.Count; i++)
   {
       Object oItem = i;
       strMessage += "Period" + Convert.ToString(iCount) + (char)9 + oAgedBalances.Item(ref oItem) + (char)9;
       iCount += 1;
    }

    strMessage += "Older" + (char)9 + strOlder;
    strMessage += Environment.NewLine;

    MessageBox.Show(strMessage, "Aged Results for Account " + SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));

    }
    else
    {
        MessageBox.Show("The sales ledger account 'TEST' cannot be found", "SDO ERROR");
    }

    //Disconnect
    oWS.Disconnect();

}
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}


Sage 50 Accounts - Example - View Customer Aged Periods

Example - View Customer Aged Periods

The example code below demonstrates how to view customer aged periods.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
 ' Declare Objects
 Dim oSDO As SageDataObject300.SDOEngine
 Dim oWS As SageDataObject300.WorkSpace
 Dim oSalesRecord As SageDataObject300.SalesRecord
 Dim oAgedBalances As SageDataObject300.AgedBalances

 ' Declare Variables
 Dim szDataPath As String

 ' Error Handler
 Try
   ' Create the SDO Engine object
   oSDO = New SageDataObject300.SDOEngine

   ' Create the Workspace
   oWS = oSDO.Workspaces.Add("Example")

   ' Select company. The SelectCompany method takes the program install folder as a parameter
   szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

   ' A U.I. for company selection is presented to the user. If a company is selected,
   ' the path will be passed to the szDataPath variable.
   ' If not, or the Cancel button is selected, the variable will be left empty.
   If szDataPath <> "" Then
     ' Connect to Data Files
     If oWS.Connect(szDataPath, "", "", "Example") Then

       ' Get the sales ledger record
        oSalesRecord = oWS.CreateObject("SalesRecord")
       oSalesRecord.Fields.Item("ACCOUNT_REF").Value = "ABS001"

       ' Do an exact match search for the account
       If (oSalesRecord.Find(False)) Then

         ' Create the aged balances object
         oAgedBalances = oSalesRecord.GetAgedBalances()

         ' Display the values calculated
         MessageBox.Show("Period 1: " & CStr(oAgedBalances.GetAgedPeriodStart(1)) & vbCrLf & _
         "Period 2: " & CStr(oAgedBalances.GetAgedPeriodStart(2)) & vbCrLf & _
         "Period 3: " & CStr(oAgedBalances.GetAgedPeriodStart(3)) & vbCrLf & _
         "Older: " & CStr(oAgedBalances.GetOlderAgedPeriod), _
         "Aged periods for account " + oSalesRecord.Fields.Item("ACCOUNT_REF").Value, MessageBoxButtons.OK, MessageBoxIcon.Information)

       Else

         MessageBox.Show("The sales ledger account 'ABS001' cannot be found.", "SDO Error", MessageBoxButtons.OK, MessageBoxIcon.Error)

       End If
     Else

       MessageBox.Show( "Could not logon to the data.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

     End If

   End If

 Catch ex As Exception
   ' Error Handling Code
   MessageBox.Show("The SDO generated the following error: " & ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

  Finally

   If Not oSalesRecord Is Nothing Then
     oSalesRecord = Nothing
   End If

   If Not oAgedBalances Is Nothing Then
     oAgedBalances = Nothing
   End If

   If Not oWS Is Nothing Then
     oWS.Disconnect()
     oWS = Nothing
     oSDO = Nothing
   End If
 End Try
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.SalesRecord oSalesRecord;
SageDataObject300.AgedBalances oAgedBalances;

String szDataPath;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails
try
{
    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

    //Get the sales ledger record
    oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");
    SDOHelper.Write(oSalesRecord, "ACCOUNT_REF", "AAAA");

    //Do an exact match search on account
    if (oSalesRecord.Find(false))
    {
        //Create the aged balances object
        oAgedBalances = (SageDataObject300.AgedBalances)oSalesRecord.GetAgedBalances();

        //Display the values calculated
        MessageBox.Show("Supplier: " + SDOHelper.Read(oSalesRecord, "ACCOUNT_REF") + Environment.NewLine +
            "Period 1: " + Convert.ToString(oAgedBalances.GetAgedPeriodStart(1)) + Environment.NewLine +
            "Period 2: " + Convert.ToString(oAgedBalances.GetAgedPeriodStart(2)) + Environment.NewLine +
            "Period 3: " + Convert.ToString(oAgedBalances.GetAgedPeriodStart(3)) + Environment.NewLine +
            "Older : " + Convert.ToString(oAgedBalances.GetOlderAgedPeriod()), "Aged periods for account " +
            SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));
    }
    else
    {
        MessageBox.Show("The sales ledger account " + SDOHelper.Read(oSalesRecord, "ACCOUNT_REF") + " Could not be found");
    }

    //Disconnect
    oWS.Disconnect();

}
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}


Sage 50 Accounts - Example - Creating a New Diary Event

Example - Creating a New Diary Event

The example code below demonstrates how to create a New Diary Event DiaryEvent.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. The code is also assuming the use of a Helper Class, if you have not already done so we would advise reading Considerations When Using C# before continuing. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
Public Class Form1

    'declare objects
    Dim oSDO As SageDataObject300.SDOEngine
    Dim oWS As SageDataObject300.WorkSpace
    Dim oDiaryEvent As SageDataObject300.DiaryEvent
    Dim oDRP As SageDataObject300.DiaryRecurrencePattern
    Dim oDiaryLabel As SageDataObject300.DiaryEventLabel

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        ' Declare Variables
        Dim szDataPath As String

        ' Create the SDO Engine object
        oSDO = New SageDataObject300.SDOEngine

        ' Create the workspace
        oWS = oSDO.Workspaces.Add("SageExample")

        ' Select company. The SelectCompany method takes the program install
        ' folder as a parameter
        szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

        ' A U.I. for company selection is presented to the user. If a company 'is selected,
        ' the path will be passed to the szDataPath variable.
        ' If not, or the Cancel button is selected, the variable will be left 'empty.
        If szDataPath <> "" Then

            ' Connect to Data Files
            If oWS.Connect(szDataPath, "", "", "Sage Example") Then

                MessageBox.Show("Connection Established")
                userDefinedMethod()

            End If

        End If

        ' Disconnect
        oWS.Disconnect()

    End Sub

    Public Sub userDefinedMethod()

        Try

            ' instantiate objects
            oDiaryEvent = oWS.CreateDiaryEvent
            oDRP = oWS.CreateDiaryRecurrencePattern
            oDiaryLabel = oWS.CreateDiaryEventLabel

            ' set the DiaryRecurrencePattern properties
            oDRP.RecurrencePeriod = SageDataObject300.DiaryRecurrencePeriod.sdoWeeklyRecurrence
            oDRP.WeeklyDaysOfWeek = SageDataObject300.DiaryRecurrenceDay.sdoWednesday
            oDRP.WeeklyIntervalInWeeks = 1
            oDRP.EndType = SageDataObject300.DiaryRecurrenceEndType.sdoEndDate
            oDRP.StartDate = Date.Parse("27/08/2008 15:00:00")
            oDRP.StartTime = Date.Parse("27/08/2008 15:00:00")
            oDRP.EndDate = Date.Now.AddYears(1)
            oDRP.DurationInMinutes = 30
            oDRP.Update()

            'Create the DiaryEvent Label, the value 2 = Appointment
            oDiaryLabel.Load(2)

            ' set the DiaryEvent properties
            oDiaryEvent.OccurrenceType = SageDataObject300.DiaryEventOccurenceType.sdoRecurrenceMaster
            oDiaryEvent.Subject = "Weekly meeting with the Development team"
            oDiaryEvent.Location = "Meeting Room 1"
            oDiaryEvent.UserName = ""
            oDiaryEvent.StartTime = Date.Parse("27/08/2008 15:00:00")
            oDiaryEvent.EndTime = oDiaryEvent.StartTime.AddMinutes(30)
            oDiaryEvent.HasReminder = True
            oDiaryEvent.ReminderMinutesBeforeStart = 15
            oDiaryEvent.RecurrencePattern = oDRP
            oDiaryEvent.Label = oDiaryLabel

            ' persist changes to the database
            oDiaryEvent.Update()

            MsgBox("The diary entry has been added to your calendar")

        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try

    End Sub

End Class
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.DiaryEvent oDiaryEvent;
            SageDataObject300.DiaryRecurrencePattern oDRP;
            SageDataObject300.DiaryEventLabel oDiaryLabel;

            try
            {
                // Instantiate objects
                oDiaryEvent = (SageDataObject300.DiaryEvent)oWS.CreateDiaryEvent();
                oDRP = (SageDataObject300.DiaryRecurrencePattern)oWS.CreateDiaryRecurrencePattern();
                oDiaryLabel = (SageDataObject300.DiaryEventLabel)oWS.CreateDiaryEventLabel();

                // Set the DiaryRecurrencePattern properties
                oDRP.RecurrencePeriod = SageDataObject300.DiaryRecurrencePeriod.sdoWeeklyRecurrence;
                oDRP.WeeklyDaysOfWeek = (int)SageDataObject300.DiaryRecurrenceDay.sdoWednesday;
                oDRP.WeeklyIntervalInWeeks = 1;
                oDRP.EndType = SageDataObject300.DiaryRecurrenceEndType.sdoEndDate;
                oDRP.StartDate = System.DateTime.Parse("27/08/2008 15:00:00");
                oDRP.StartTime = System.DateTime.Parse("27/08/2008 15:00:00");
                oDRP.EndDate = System.DateTime.Now.AddYears(1);
                oDRP.DurationInMinutes = 30;
                oDRP.Update();

                // Create the DiaryEvent Label, the value 2 = Appointment
                Object app = (int)2;
                oDiaryLabel.Load(ref app);

                // Set the DiaryEvent properties
                oDiaryEvent.OccurrenceType = SageDataObject300.DiaryEventOccurenceType.sdoRecurrenceMaster;
                oDiaryEvent.Subject = "Weekly meeting with the Development team";
                oDiaryEvent.Location = "Meeting Room 1";
                oDiaryEvent.UserName = "";
                oDiaryEvent.StartTime = System.DateTime.Parse("27/08/2008 15:00:00");
                oDiaryEvent.EndTime = oDiaryEvent.StartTime.AddMinutes(30);
                oDiaryEvent.HasReminder = Convert.ToInt32(true);
                oDiaryEvent.ReminderMinutesBeforeStart = 15;
                oDiaryEvent.RecurrencePattern = oDRP;
                oDiaryEvent.Label = oDiaryLabel;

                // Persist changes to the database
                if (oDiaryEvent.Update())
                {
                    MessageBox.Show("The diary entry has been added to your calendar");
                }
                else
                {
                    MessageBox.Show("The diary entry could not be added to your calendar");
                }

                // Disconnect
                oWS.Disconnect();
            }
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - View DiaryEventLabels properties using Item method

Example - View DiaryEventLabels properties using Item method

The example code below demonstrates how to view DiaryEventLabels properties using the Item method.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
      ' Declare Objects
      Dim oSDO As SageDataObject300.SDOEngine
      Dim oWS As SageDataObject300.WorkSpace
      Dim oDiaryEventLabels As SageDataObject300.DiaryEventLabels

      ' Declare Variables
      Dim szDataPath As String
      Dim lvitem As ListViewItem

      ' Create the SDOEngine Object
      oSDO = New SageDataObject300.SDOEngine

      ' Create the Workspace
      oWS = oSDO.Workspaces.Add("Example")
      Try
          ' Select Company. The SelectCompany method takes the program install
          ' folder as a parameter
          szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

          ' A U.I. for company selection is presented to the user. If a company is selected,
          ' the path will be passed to the szDataPath variable.
          ' If not, or the Cancel button is selected, the variable will be left empty.
          If szDataPath <> "" Then

              ' Try to Connect - Will Throw an Exception if it Fails
              If oWS.Connect(szDataPath, "", "", "Example") Then

                  'Instantiate the object
                  oDiaryEventLabels = oWS.CreateDiaryEventLabels()

                  'Using the item reference, add the property values of all
                  'the DiaryEventLabels in the collection to a listview
                  'A more practical approach would be to display the .Name property in a combobox for the
                  'user to select what type of diary event to schedule

                  Dim i As Integer
                  For i = 0 To oDiaryEventLabels.Count - 1

                      lvitem = New ListViewItem

                      lvitem.Text = oDiaryEventLabels.Item(i).Color
                      lvitem.SubItems.Add(oDiaryEventLabels.Item(i).Name)
                      lvitem.SubItems.Add(oDiaryEventLabels.Item(i).ReadOnly)
                      lvitem.SubItems.Add(oDiaryEventLabels.Item(i).UniqueID)

                      Me.ListView1.Items.Add(lvitem)

                      lvitem = Nothing

                  Next

              End If

          End If

      Catch ex As Exception

          ' Error Handling Code
          MessageBox.Show("The SDO generated the following error: " & ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

      Finally

          oWS.Disconnect()

      End Try
C#.NET [image] Copy C# Code
//Declare Objects
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.DiaryEventLabels oDiaryEventLabels;

//Declare Variables
ListViewItem lvitem;
String szDataPath;

//Create the Workspace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

try
{
    //Select Company. The SelectCompany takes the program install folder as a parameter
    szDataPath = oSDO.SelectCompany("C:\\Documents and Settings\\All Users\\Application Data\\Sage\\Accounts\\2023");

    //A U.I. for company selection is presented to the user. If a company 'is selected,
    //the path will be passed to the szDataPath variable.
    //If not, or the Cancel button is selected, the variable will be left 'empty.
    if (szDataPath != string.Empty)
    {
        //Connect to the datafiles
        if (oWS.Connect(szDataPath, "", "", "EXAMPLE"))
        {
            //Instantiate the object
            oDiaryEventLabels = (SageDataObject300.DiaryEventLabels)oWS.CreateDiaryEventLabels();

            //Using the item reference, add the property values of all
            //the DiaryEventLabels in the collection to a listview
            //A more practical approach would be to display the .Name property in a combobox for the
            //user to select what type of diary event to schedule

            for (int i = 0; i < oDiaryEventLabels.Count; i++)
            {
                lvitem = new ListViewItem();
                Object diaryRef = i;

                lvitem.Text = Convert.ToString(oDiaryEventLabels.Item(ref diaryRef).Color);
                lvitem.SubItems.Add(Convert.ToString(oDiaryEventLabels.Item(ref diaryRef).Name));
                lvitem.SubItems.Add(Convert.ToString(oDiaryEventLabels.Item(ref diaryRef).ReadOnly));
                lvitem.SubItems.Add(Convert.ToString(oDiaryEventLabels.Item(ref diaryRef).UniqueID));

                this.listView1.Items.Add(lvitem);

                lvitem = null;
            }
        }
        else
        {
            MessageBox.Show("Failed to Connect");
        }
    }
}
//Error handling
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}

finally
{
    //Disconnect
    oWS.Disconnect();

}


Sage 50 Accounts - Example - View DiaryRecurrencePatterns properties using Item method

Example - View DiaryRecurrencePatterns properties using Item method

The example code below demonstrates how to view DiaryRecurrencePatterns properties using the Item method.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oDRPS As SageDataObject300.DiaryRecurrencePatterns

' Declare Variables
Dim szDataPath As String
Dim lvitem As ListViewItem

' Create the SDOEngine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")
Try
    ' Select Company. The SelectCompany method takes the program install
    ' folder as a parameter
    szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

    ' A U.I. for company selection is presented to the user. If a company is selected,
    ' the path will be passed to the szDataPath variable.
    ' If not, or the Cancel button is selected, the variable will be left empty.
    If szDataPath <> "" Then

        ' Try to Connect - Will Throw an Exception if it Fails
        If oWS.Connect(szDataPath, "", "", "Example") Then

            'Instantiate the object
            oDRPS = oWS.CreateDiaryRecurrencePatterns()

            'Using the item reference, add the property values of all
            'the DiaryEventLabels in the collection to a listview

            Dim i As Integer
            For i = 0 To oDRPS.Count - 1

                lvitem = New ListViewItem

                lvitem.Text = oDRPS.Item(i).DailyIntervalInDays
                lvitem.SubItems.Add(oDRPS.Item(i).DailyWeekdaysOnly)
                lvitem.SubItems.Add(oDRPS.Item(i).DurationInMinutes)
                lvitem.SubItems.Add(oDRPS.Item(i).EndDate)
                lvitem.SubItems.Add(oDRPS.Item(i).EndType)
                lvitem.SubItems.Add(oDRPS.Item(i).MonthlyDayOfMonth)
                lvitem.SubItems.Add(oDRPS.Item(i).MonthlyIntervalInMonths)
                lvitem.SubItems.Add(oDRPS.Item(i).MonthlyNthDayOccurrence)
                lvitem.SubItems.Add(oDRPS.Item(i).MonthlyNthDayOfWeek)
                lvitem.SubItems.Add(oDRPS.Item(i).MonthlyNthIntervalInMonths)
                lvitem.SubItems.Add(oDRPS.Item(i).RecurrencePeriod)
                lvitem.SubItems.Add(oDRPS.Item(i).StartDate)
                lvitem.SubItems.Add(oDRPS.Item(i).StartTime)
                lvitem.SubItems.Add(oDRPS.Item(i).TotalOccurrences)
                lvitem.SubItems.Add(oDRPS.Item(i).UniqueID)
                lvitem.SubItems.Add(oDRPS.Item(i).WeeklyDaysOfWeek)
                lvitem.SubItems.Add(oDRPS.Item(i).WeeklyIntervalInWeeks)
                lvitem.SubItems.Add(oDRPS.Item(i).YearlyDayOfMonth)
                lvitem.SubItems.Add(oDRPS.Item(i).YearlyMonthOfYear)
                lvitem.SubItems.Add(oDRPS.Item(i).YearlyNthDayOccurrence)
                lvitem.SubItems.Add(oDRPS.Item(i).YearlyNthDayOfWeek)
                lvitem.SubItems.Add(oDRPS.Item(i).YearlyNthMonthOfYear)

                Me.ListView1.Items.Add(lvitem)

                lvitem = Nothing

            Next

        End If

    End If

Catch ex As Exception

    ' Error Handling Code
    MessageBox.Show("The SDO generated the following error: " & ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

Finally

    oWS.Disconnect()

End Try
C#.NET [image] Copy C# Code
//Declare Objects
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.DiaryRecurrencePatterns oDRPS;

//Declare Variables
ListViewItem lvitem;
String szDataPath;

//Create the Workspace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

try
{
    //Select Company. The SelectCompany takes the program install folder as a parameter
    szDataPath = oSDO.SelectCompany("C:\\Documents and Settings\\All Users\\Application Data\\Sage\\Accounts\\2023");

    //A U.I. for company selection is presented to the user. If a company 'is selected,
    //the path will be passed to the szDataPath variable.
    //If not, or the Cancel button is selected, the variable will be left 'empty.
    if (szDataPath != string.Empty)
    {
        //Connect to the datafiles
        if (oWS.Connect(szDataPath, "", "", "EXAMPLE"))
        {
            //Instantiate the object
            oDRPS = (SageDataObject300.DiaryRecurrencePatterns)oWS.CreateDiaryRecurrencePatterns();

            //Using the item reference, add the property values of all
            //the DiaryRecurrencePatterns in the collection to a listview

            for (int i = 0; i < oDRPS.Count; i++)
            {
                lvitem = new ListViewItem();
                Object diaryRef = i;

                lvitem.Text = Convert.ToString(oDRPS.Item(ref diaryRef).DailyIntervalInDays);
                lvitem.SubItems.Add(Convert.ToString(oDRPS.Item(ref diaryRef).DailyWeekdaysOnly));
                lvitem.SubItems.Add(Convert.ToString(oDRPS.Item(ref diaryRef).DurationInMinutes));
                lvitem.SubItems.Add(Convert.ToString(oDRPS.Item(ref diaryRef).EndDate));
                lvitem.SubItems.Add(Convert.ToString(oDRPS.Item(ref diaryRef).EndType));
                lvitem.SubItems.Add(Convert.ToString(oDRPS.Item(ref diaryRef).MonthlyDayOfMonth));
                lvitem.SubItems.Add(Convert.ToString(oDRPS.Item(ref diaryRef).MonthlyIntervalInMonths));
                lvitem.SubItems.Add(Convert.ToString(oDRPS.Item(ref diaryRef).MonthlyNthDayOccurrence));
                lvitem.SubItems.Add(Convert.ToString(oDRPS.Item(ref diaryRef).MonthlyNthDayOfWeek));
                lvitem.SubItems.Add(Convert.ToString(oDRPS.Item(ref diaryRef).MonthlyNthIntervalInMonths));
                lvitem.SubItems.Add(Convert.ToString(oDRPS.Item(ref diaryRef).RecurrencePeriod));
                lvitem.SubItems.Add(Convert.ToString(oDRPS.Item(ref diaryRef).StartDate));
                lvitem.SubItems.Add(Convert.ToString(oDRPS.Item(ref diaryRef).StartTime));
                lvitem.SubItems.Add(Convert.ToString(oDRPS.Item(ref diaryRef).TotalOccurrences));
                lvitem.SubItems.Add(Convert.ToString(oDRPS.Item(ref diaryRef).UniqueID));
                lvitem.SubItems.Add(Convert.ToString(oDRPS.Item(ref diaryRef).WeeklyDaysOfWeek));
                lvitem.SubItems.Add(Convert.ToString(oDRPS.Item(ref diaryRef).WeeklyIntervalInWeeks));
                lvitem.SubItems.Add(Convert.ToString(oDRPS.Item(ref diaryRef).YearlyDayOfMonth));
                lvitem.SubItems.Add(Convert.ToString(oDRPS.Item(ref diaryRef).YearlyMonthOfYear));
                lvitem.SubItems.Add(Convert.ToString(oDRPS.Item(ref diaryRef).YearlyNthDayOccurrence));
                lvitem.SubItems.Add(Convert.ToString(oDRPS.Item(ref diaryRef).YearlyNthDayOfWeek));
                lvitem.SubItems.Add(Convert.ToString(oDRPS.Item(ref diaryRef).YearlyNthMonthOfYear));

                this.listView1.Items.Add(lvitem);

                lvitem = null;
            }
        }
        else
        {
            MessageBox.Show("Failed to Connect");
        }
    }
}
//Error handling
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}

finally
{
    //Disconnect
    oWS.Disconnect();

}


Sage 50 Accounts - Example - Reading Project Cost Codes

Example - Reading Disputed Reasons

The example code below demonstrates how to Read and list the Disputed Reasons as seen via the Sage 50 Accounts GUI in the Settings Configuration editor.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set.

VB.NET [image] Copy VB Code
    'Declare Variables
    Dim oSDO As SageDataObject300.SDOEngine = New SageDataObject300.SDOEngine()
    Dim oWS As SageDataObject300.WorkSpace
    Dim oDisputedReason As SageDataObject300.DisputedReason
    Dim szDataPath As String

    'Instantiate WorkSpace
    oWS = oSDO.Workspaces.Add("Example")

    'Show select company dialog
    szDataPath = oSDO.SelectCompany"C:\\ProgramData\\Sage\\Accounts\\2024")

    'Try a connection, will throw an exception if it fails
    Try
        'Leaving the username and password blank generates a login dialog
        oWS.Connect(szDataPath, "", "", "SDO EXAMPLE")

        'Instantiate the DisputedReason object
        oDisputedReason = oWS.CreateDisputedReason()

        'There are 1000 Dipute Reasons, some of which may not have a name

        For i As Integer = 1 To 1000
            'Declare an object to hold the integer value
            Dim iDispReason As Object = i

            'Pass the object as a reference to the Load method
            oDisputedReason.Load(iDispReason)

            'Filter for only reasons that have a name
            If oDisputedReason.Name <> "" Then
                'Display the DisputedReason Name
                MessageBox.Show(oDisputedReason.Name.ToString())
            End If
        Next

        'Disconnect
        oWS.Disconnect()

    Catch ex As Exception
        'Show the exception error message
        MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Try

End Sub
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.DisputedReason oDisputedReason;
String szDataPath;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails
try
{
    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");
    //Instantiate the DisputedReason object
    oDisputedReason = (SageDataObject300.DisputedReason)oWS.CreateDisputedReason();

    //There are 1000 Dipute Reasons, some of which may not have a name
    for (int i = 1; i <= 1000; i++)
    {
        //Declare an object to hold the integer value
        object iDispReason = i;

        //Pass the object as a reference to the Load method
        oDisputedReason.Load(ref iDispReason);
        //Filter for only reasons that have a name
        if (oDisputedReason.Name != "")
            //Display the DisputedReason Name
        {
        MessageBox.Show(oDisputedReason.Name.ToString());
        }
    }

    // Disconnect
    oWS.Disconnect();
}
catch (Exception ex)
{
    // Show the exception error message
    MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
}


Sage 50 Accounts - Example - Using Document Addresses

Example - Using Document Addresses

The example code below demonstrates how to use the DocumentAddress object.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oDocumentTypes As SageDataObject300.DocumentTypes
Dim oDocumentType As SageDataObject300.DocumentType
Dim oDocumentAddress As SageDataObject300.DocumentAddress
Dim oDocumentAddresses As SageDataObject300.DocumentAddresses
Dim oCustomerAddress As SageDataObject300.CustomerAddress
Dim oCustomer As SageDataObject300.Customer
Dim oTraderType As SageDataObject300.TraderType
Dim lvItem As New ListViewItem
Dim myProperties As PropertyCollection

' Declare Variables
Dim szDataPath As String
Dim iSplitCount As Short

' Create the SDO Engine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

' Try to Connect
If oWS.Connect(szDataPath, "", "", "Example") Then

' instantiate the required objects
oDocumentAddresses = oWS.CreateDocumentAddresses
oDocumentTypes = oWS.CreateDocumentTypes
oDocumentType = oWS.CreateDocumentType
oCustomer = oWS.CreateCustomer

' Load the customer placeholder object by passing the account ref required
oCustomer.Load("ABS001")

' Declare boolean variable
Dim foundDocType As Boolean
foundDocType = False

' Loop through the Document Type collection until Statement Document is located
For Each oDocumentType In oDocumentTypes
If oDocumentType.Description = "Statements" Then
foundDocType = True
Exit For
End If
Next

' If the Document type could not be located
If Not foundDocType Then
MsgBox("Failed to find DocumentType for Statements")
Exit Sub
End If

' Declare boolean variable
Dim foundDocAddr As Boolean
foundDocAddr = False
oTraderType = SageDataObject300.TraderType.sdoCustomer

' Loop through the DocumentAddresses collection until the matching address is found
For Each oDocumentAddress In oDocumentAddresses
If (oDocumentAddress.AccountRefn = oCustomer.Reference And _
oDocumentAddress.AccountType = oTraderType And _
oDocumentAddress.DocumentTypeID = oDocumentType.UniqueID) Then
foundDocAddr = True
Exit For
End If
Next

If Not foundDocAddr Then
MsgBox("Failed to find DocumentAddress record for ABS001's statements")
Exit Sub
End If

' Return the Document Address number
MsgBox("Address number is " + CStr(oDocumentAddress.AddressNumber))

' Set the Customer Address object to equal that of the Document Addrees Customer Address property
oCustomerAddress = oDocumentAddress.CustomerAddress

' Show the First Line of the Address
MsgBox(oCustomerAddress.AddressLine1)

' Disconnect
oWS.Disconnect()

End If

End If

' Destroy Objects
oWS = Nothing
oSDO = Nothing
C#.NET [image] Copy C# Code
//Declare Objects
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.SalesRecord oSalesRecord;
SageDataObject300.DocumentTypes oDocumentTypes;
SageDataObject300.DocumentType oDocumentType;
SageDataObject300.DocumentAddress oDocumentAddress;
SageDataObject300.DocumentAddresses oDocumentAddresses;
SageDataObject300.CustomerAddress oCustomerAddress;
SageDataObject300.Customer oCustomer;
SageDataObject300.TraderType oTraderType;

//Decalre Variables
String szDataPath;

//Create the Workspace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Select Company.  The SelectCompany method takes the program install
//folder as a parameter
szDataPath = oSDO.SelectCompany("C:\\Documents and Settings\\All Users\\Application Data\\Sage\\Accounts\\2023");

try
{
    //A U.I. for company selection is presented to the user. If a company is selected,
    //the path will be passed to the szDataPath variable.
    //If not, or the Cancel button is selected, the variable will be left empty.

    if (szDataPath != string.Empty)
    {
        if (oWS.Connect(szDataPath, "", "", "Example"))
        {
            //Instantiate the required objects
            oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SALESRECORD");
            oDocumentAddresses = (SageDataObject300.DocumentAddresses)oWS.CreateDocumentAddresses();
            oDocumentAddress = (SageDataObject300.DocumentAddress)oWS.CreateDocumentAddress();
            oDocumentTypes = (SageDataObject300.DocumentTypes)oWS.CreateDocumentTypes();
            oDocumentType = (SageDataObject300.DocumentType)oWS.CreateDocumentType();
            oCustomer = (SageDataObject300.Customer)oWS.CreateCustomer();
            oCustomerAddress = (SageDataObject300.CustomerAddress)oWS.CreateCustomerAddress();

            //Load the customer placeholder object by passing the SalesRecord account ref required
            oSalesRecord.MoveFirst();
            Object salesRef = SDOHelper.Read(oSalesRecord, "ACCOUNT_REF");

            if (oCustomer.Load(ref salesRef))
            {
                //Declare boolean variable
                Boolean foundDocType;
                foundDocType = false;

                //Loop through the Document type collection until Satement Document is located
                for (int i = 1; i < oDocumentTypes.Count; i++)
                {
                    Object typeRef = i;
                    oDocumentType.Load(ref typeRef);
                    if (oDocumentType.Description == "Statements")
                    {
                        foundDocType = true;
                        break;
                    }
                }

                //If the Document type could not be located
                if (!foundDocType)
                {
                    MessageBox.Show("Failed to find DocumentType for Statements");
                    //Need to exit the sub
                    return;
                }

                //Declare boolean variables
                Boolean foundDocAddr;
                foundDocAddr = false;
                oTraderType = SageDataObject300.TraderType.sdoCustomer;

                foreach (SageDataObject300.DocumentAddress oDocAdd in oDocumentAddresses)
                {
                    String strDocAccType = Convert.ToString(oDocAdd.AccountType);
                    String strTradType = Convert.ToString(oTraderType);

                    if (oDocAdd.AccountRefn == oCustomer.Reference &
                       strDocAccType.ToString() == strTradType.ToString() &
                        oDocAdd.DocumentTypeID == oDocumentType.UniqueID)
                    {
                        foundDocAddr = true;
                        oDocumentAddress = oDocAdd;
                        break;
                    }
                }

                if (!foundDocAddr)
                {
                    MessageBox.Show("Failed to find Doument Address for first Sales record's statements");
                    //exit sub
                    return;
                }

                //Return the Document address number
                MessageBox.Show("Address number is " + Convert.ToString(oDocumentAddress.AddressNumber));

                //Set the Customer Address object to equal that of the Document Address Customer Address property
                //oCustomerAddress = oDocumentAddress.CustomerAddress;
                Object custRef = SDOHelper.Read(oSalesRecord, "ACCOUNT_REF");
                Object addRef = oDocumentAddress.AddressNumber;
                oCustomerAddress.Load(ref custRef, ref addRef);

                //Show the Address that Statements are sent to
                MessageBox.Show("Statements are sent to : " + Environment.NewLine +
                  oCustomerAddress.AddressLine1 + Environment.NewLine +
                  oCustomerAddress.AddressLine2 + Environment.NewLine +
                  oCustomerAddress.AddressLine3 + Environment.NewLine +
                  oCustomerAddress.AddressLine4 + Environment.NewLine +
                  oCustomerAddress.AddressLine5 + Environment.NewLine);
            }
            else
            {
                MessageBox.Show("Could not load customer");
            }
        }
        else
        {
            MessageBox.Show("Could not connect");
        }
    }
    else
    {
        MessageBox.Show("Empty DataPath");
    }
}
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}

finally
{
    //Disconnect
    oWS.Disconnect();
}


Sage 50 Accounts - Example - View DocumentType LoadType properties

Example - View DocumentType LoadType properties

The example code below demonstrates how to use the LoadType method of the DocumentType object to view the properties of the type.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
Public Class Form1

    'Declare Objects
    Dim oSDO As SageDataObject300.SDOEngine
    Dim oWS As SageDataObject300.WorkSpace

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        ' Declare Variables
        Dim szDataPath As String

        Try

            ' Create the SDO Engine object
            oSDO = New SageDataObject300.SDOEngine

            ' Create the Workspace
            oWS = oSDO.Workspaces.Add("Example")

            ' Select company. The SelectCompany method takes the program install folder as a parameter
            szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

            ' A U.I. for company selection is presented to the user. If a company is selected,
            ' the path will be passed to the szDataPath variable.
            ' If not, or the Cancel button is selected, the variable will be left empty.
            If szDataPath <> "" Then

                ' Connect to Data Files
                If oWS.Connect(szDataPath, "", "", "Example") Then

                    ' user code
                    userDefinedMethod()

                End If

            End If

        Catch
            Select Case oSDO.LastError.Code

                ' 3rd Party Integration NOT Enabled - Site Activation
                Case Is = SageDataObject300.ErrorCode.sdoNotRegistered
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")
                    ' Invalid Password
                Case Is = SageDataObject300.ErrorCode.sdoLogonPassword
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")
                    ' User is Already Logged On
                Case Is = SageDataObject300.ErrorCode.sdoLogonNameInUse
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")
                    ' Line 50 is in Exclusive Mode i.e. File Maintenance
                Case Is = SageDataObject300.ErrorCode.sdoLogonExclusive
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")
                    ' Invalid Data Path on Connect
                Case Is = SageDataObject300.ErrorCode.sdoBadDataPath
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")
                    ' Line 50 is not Same Version as SDO
                Case Is = SageDataObject300.ErrorCode.sdoWrongVersion
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")
            End Select

        End Try

        'Disconnect
        oWS.Disconnect()

    End Sub

    Private Sub userDefinedMethod()

        Dim oDocumentType As SageDataObject300.DocumentType

        Dim lvItem As New ListViewItem

        oDocumentType = oWS.CreateDocumentType

        Dim ty As Object
        Dim i As Integer

        For i = 1 To 9

            ty = i

            oDocumentType.LoadType(ty)
            lvItem = New ListViewItem
            lvItem.Text = oDocumentType.Description.ToString
            lvItem.SubItems.Add(oDocumentType.Type.ToString)
            lvItem.SubItems.Add(oDocumentType.UniqueID.ToString)
            lvItem.SubItems.Add(oDocumentType.UsedForCustomers.ToString)
            lvItem.SubItems.Add(oDocumentType.UsedForSuppliers.ToString)

            Me.ListView1.Items.Add(lvItem)

        Next

        ' Disconnect
        oWS.Disconnect()

        ' Destroy Objects
        oWS = Nothing
        oSDO = Nothing

    End Sub

End Class
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.DocumentType oDocType;
            ListViewItem lvItem;

            try
            {
                // Instantiate objects
                oDocType = (SageDataObject300.DocumentType)oWS.CreateDocumentType();

                //
                Object ty;
                int i;

                // Loop through the Document Types
                for (i = 1; i < 10; i++)
                {
                    // Set ty
                    ty = i;

                    // Load the Document Type
                    oDocType.LoadType(ref ty);

                    // Add details to listView
                    lvItem = new ListViewItem();
                    lvItem.Text = oDocType.Description.ToString();
                    lvItem.SubItems.Add(oDocType.Type.ToString());
                    lvItem.SubItems.Add(oDocType.UniqueID.ToString());
                    lvItem.SubItems.Add(oDocType.UsedForCustomers.ToString());
                    lvItem.SubItems.Add(oDocType.UsedForSuppliers.ToString());

                    this.listView.Items.Add(lvItem);
                }

                // Disconnect
                oWS.Disconnect();
            }
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Accessing a Supplier Memo

Example - Accessing a Supplier Memo

The example code below demonstrates how to access a Supplier Memo.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

The code also includes a generic error handler. Clearly, you would respond differently depending on the actual exception thrown.

VB.NET [image] Copy VB Code

        ' Declare Objects

        Dim oSDO As SageDataObject300.SDOEngine

        Dim oWS As SageDataObject300.WorkSpace

        Dim oPurchaseRecord As SageDataObject300.PurchaseRecord

        ' Declare Variables

        Dim szDataPath As String

        ' Create the SDO Engine Object

        oSDO = New SageDataObject300.SDOEngine

        ' Create the Workspace

        oWS = oSDO.Workspaces.Add("Example")

        ' Select Company. The SelectCompany method takes the program install

        ' folder as a parameter

        szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

        ' A U.I. for company selection is presented to the user. If a company is 'selected,

        ' the path will be passed to the szDataPath variable.

        ' If not, or the Cancel button is selected, the variable will be left 'empty.

        If szDataPath <> "" Then

            ' Try to Connect - Will throw an exception if it fails

            If oWS.Connect(szDataPath, "", "", "Example") Then

                ' Create Instance of Purchase Record Object

                oPurchaseRecord = oWS.CreateObject("PurchaseRecord")

                ' Get the First Purchase Record and add a Memo to it

                oPurchaseRecord.MoveFirst()

                oPurchaseRecord.Edit()

                oPurchaseRecord.Memo = CStr("Memo text for First Supplier")

                ' Update the Record

                If oPurchaseRecord.Update Then

                    MsgBox("Added Memo to Account : " & oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value, MsgBoxStyle.OkOnly, "SDO Example")

                Else

                    MsgBox("Memo Update Unsuccessful.", MsgBoxStyle.OkOnly, "SDO Example")

                End If

                'Get the First Purchase Record and Read the memo

                oPurchaseRecord.MoveFirst()

                MsgBox(oPurchaseRecord.Memo, MsgBoxStyle.OkOnly, "SDO Example")

                ' Disconnect

                oWS.Disconnect()

            End If

        End If

        oPurchaseRecord = Nothing

        oSDO = Nothing

        oWS = Nothing

        Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.PurchaseRecord oPurchaseRecord;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate Purchase Record object

  oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");

  //Get the first Purchase Record and add a memo to it

  oPurchaseRecord.MoveFirst();

  oPurchaseRecord.Edit();

  oPurchaseRecord.Memo = (String)"Memo text for the first supplier";

  //Update the record

  if (oPurchaseRecord.Update())

  {

    MessageBox.Show("Added Memo to Account: " + SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"));

  }

  else

  {

    MessageBox.Show("Failed to add the memo");

  }

  //Get the first purchase record and read the memo

  oPurchaseRecord.MoveFirst();

  MessageBox.Show(oPurchaseRecord.Memo);

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example -�Allocating an existing�Purchase Credit Note to an existing�Purchase Invoice

Example - Allocating an existing Purchase Credit Note to an existing Purchase Invoice

The example code below demonstrates how to allocate an existing purchase credit note against an existing purchase invoice.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oPurchaseRecord As SageDataObject300.PurchaseRecord
Dim oTransactionPost As SageDataObject300.TransactionPost
Dim oCreditSplitData As SageDataObject300.SplitData
Dim oInvoiceHeaderData As SageDataObject300.HeaderData
Dim oCreditHeaderData As SageDataObject300.HeaderData

' Declare Variables
Dim szDataPath As String
Dim bTransactionFound As Boolean
Dim dCreditValue As Double
Dim iCreditSplit, iInvoiceSplit As Integer

 ' Create the SDO Engine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

' Try to Connect - Will throw an exception if it fails
If oWS.Connect(szDataPath, "", "", "Example") Then

' Create Instance Objects to Post the Credit Note
oPurchaseRecord = oWS.CreateObject("PurchaseRecord")
oTransactionPost = oWS.CreateObject("TransactionPost")
oCreditHeaderData = oWS.CreateObject("HeaderData")

' Initialise Index Field with value to search
oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value = CStr ("QUA001")

' Perform Find for an exact match
If oPurchaseRecord.Find(False) Then
'Link to the Credit Splits
oCreditHeaderData = oPurchaseRecord.Link
oCreditHeaderData.MoveFirst()

Do
If oCreditHeaderData.Fields.Item("INV_REF").Value = CStr("566") Then

' Set the credit transaction found flag
bTransactionFound = True

' Store the Credit note Split number and Amount to allocate
                  oCreditSplitData = oCreditHeaderData.Link
                  oCreditSplitData.MoveFirst()
                  iCreditSplit = CInt(oCreditSplitData.RecordNumber)
                  dCreditValue = CDbl(oCreditSplitData.Fields.Item("NET_AMOUNT").Value) + CDbl(oCreditSplitData.Fields.Item("TAX_AMOUNT").Value) - CDbl(oCreditSplitData.Fields.Item("AMOUNT_PAID").Value)

                  ' Exit the loop
                  Exit Do

          End If

          Loop Until Not oCreditHeaderData.MoveNext

          If bTransactionFound Then
              'Set the found flag to false
              bTransactionFound = False

              ' Transaction found
              MsgBox("Credit Note transaction has been found.", MsgBoxStyle.OKOnly, "SDO Examples")

              'Find the Purchase Invoice
               oInvoiceHeaderData = oPurchaseRecord.Link

              ' Move to the first Header on Supplier account
              oInvoiceHeaderData.MoveFirst()

              Do
                 If oInvoiceHeaderData.Fields.Item("INV_REF").Value = CStr("5656") Then

                      ' Set the invoice transaction found flag
                      bTransactionFound = True

                      'Store the Invoice Split number
                      iInvoiceSplit = CInt(oInvoiceHeaderData.Fields.Item("FIRST_SPLIT").Value)

                       ' Exit the loop
                       Exit Do

                  End If

              Loop Until Not oInvoiceHeaderData.MoveNext

              If bTransactionFound Then
                  ' Invoice transaction found
                  MsgBox("Invoice transaction has been found.", MsgBoxStyle.OKOnly, "SDO Examples")

                  ' Allocate Credit Against Invoice
                  If oTransactionPost.AllocatePayment(CInt(iInvoiceSplit), CInt(iCreditSplit), CDbl(dCreditValue), CDate(Now))

                      MsgBox("Allocation successful.", MsgBoxStyle.OKOnly, "SDO Examples")
                  Else
                      MsgBox("Allocation unsuccessful.", MsgBoxStyle.OKOnly, "SDO Examples")
                  End If
              Else
                  ' Invoice transaction not found
                  MsgBox("Invoice transaction has NOT been found.", MsgBoxStyle.OKOnly, "SDO Examples")
              End If
          Else
              ' Credit transaction not found
              MsgBox("Credit transaction has NOT been found.", MsgBoxStyle.OKOnly, "SDO Examples")
          End If
      Else
          ' Account not found
          MsgBox("Purchase ledger account NOT found.", MsgBoxStyle.OKOnly, "SDO Examples")
      End If
    End If

       ' Disconnect
       oWS.Disconnect()

  End If
  ' Destroy Objects
  oPurchaseRecord = Nothing
  oInvoiceHeaderData = Nothing
  oCreditSplitData = Nothing
  oCreditHeaderData = Nothing
  oTransactionPost = Nothing
  oSDO = Nothing
  oWS = Nothing

   Exit Sub
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.PurchaseRecord oPurchaseRecord;
            SageDataObject300.TransactionPost oTransactionPost;
            SageDataObject300.SplitData oCreditSplitData;
            SageDataObject300.HeaderData oInvoiceHeaderData;
            SageDataObject300.HeaderData oCreditHeaderData;
            bool bTransactionFound = false;
            bool bRecordFound = false;
            double dCreditValue = 0;
            int iCreditSplit = 0;
            int iInvoiceSplit = 0;

            try
            {
                // Create an Instance of the PurchaseRecord Object
                oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");
                oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");
                oCreditHeaderData = (SageDataObject300.HeaderData)oWS.CreateObject("HeaderData");

                // Initialise Index Field with value to search
                SDOHelper.Write(oPurchaseRecord, "ACCOUNT_REF", (String)"CON001");

                // Perform Find for an exact match
                bRecordFound = oPurchaseRecord.Find(false);

                if (bRecordFound)
                {
                    // Link to Credit Splits
                    oCreditHeaderData = (SageDataObject300.HeaderData)oPurchaseRecord.Link;
                    oCreditHeaderData.MoveFirst();

                    do
                    {
                        if ((String)SDOHelper.Read(oCreditHeaderData, "INV_REF") == (String)"PC0001")
                        {
                            // Set the credit transaction found flag
                            bTransactionFound = true;

                            // Store the Credit note Split number and Amount to allocate
                            oCreditSplitData = (SageDataObject300.SplitData)oCreditHeaderData.Link;
                            oCreditSplitData.MoveFirst();
                            iCreditSplit = (int)oCreditSplitData.RecordNumber;
                            dCreditValue = ((double)SDOHelper.Read(oCreditSplitData, "NET_AMOUNT") + (double)SDOHelper.Read(oCreditSplitData, "TAX_AMOUNT")) -
                                (double)SDOHelper.Read(oCreditSplitData, "AMOUNT_PAID");

                            // Exit the loop
                            break;
                        }
                    } while (!(!oCreditHeaderData.MoveNext()));

                    if (bTransactionFound)
                    {
                        //Set the found flag to false
                        bTransactionFound = false;

                        // Transaction found
                        MessageBox.Show("Credit Note transaction has been found.");

                        //Find the Purchase Invoice
                        oInvoiceHeaderData = (SageDataObject300.HeaderData)oPurchaseRecord.Link;

                        // Move to the first Header on Supplier account
                        oInvoiceHeaderData.MoveFirst();

                        do
                        {
                            if ((String)SDOHelper.Read(oInvoiceHeaderData, "INV_REF") == (string)"PI0001")
                            {
                                // Set the invoice transaction found flag
                                bTransactionFound = true;

                                //Store the Invoice Split number
                                iInvoiceSplit = (int)SDOHelper.Read(oInvoiceHeaderData, "FIRST_SPLIT");

                                // Exit the loop
                                break;
                            }
                        } while (!(!oInvoiceHeaderData.MoveNext()));

                        if (bTransactionFound)
                        {
                            // Invoice transaction found
                            MessageBox.Show("Invoice transaction has been found.");

                            // Allocate Credit Against Invoice
                            if (oTransactionPost.AllocatePayment((int)iInvoiceSplit, (int)iCreditSplit, (double)dCreditValue, (DateTime)DateTime.Now))
                            {

                                MessageBox.Show("Allocation successful.");
                            }
                            else
                            {
                                MessageBox.Show("Allocation unsuccessful.");
                            }
                        }
                        else
                        {
                            // Invoice transaction not found
                            MessageBox.Show("Invoice transaction not found.");
                        }
                    }
                    else
                    {
                        // Credit transaction not found
                        MessageBox.Show("Credit transaction not found.");
                    }
                }
                else
                {
                    // Account not found
                    MessageBox.Show("Purchase Ledger account not found.");
                }

                // Disconnect
                oWS.Disconnect();
            }
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Creating a New Supplier Record

Example - Creating a New Supplier Record

The example code below demonstrates how to create a new Supplier Record.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oPurchaseRecord As SageDataObject300.PurchaseRecord

' Declare Variables
Dim szDataPath As String

' Create the SDOEngine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

' Try to Connect - Will Throw an Exception if it Fails
If oWS.Connect(szDataPath, "", "", "Example") Then

' Create an Instance of the PurchaseRecord Object
oPurchaseRecord = oWS.CreateObject("PurchaseRecord")

' Try to Add a New Record
If oPurchaseRecord.AddNew Then

oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value = CStr("SAGEGRP")
oPurchaseRecord.Fields.Item("NAME").Value = CStr("The Sage Group plc")
oPurchaseRecord.Fields.Item("ADDRESS_1").Value = CStr("Building 5")
oPurchaseRecord.Fields.Item("ADDRESS_2").Value = CStr("North Park")
oPurchaseRecord.Fields.Item("ADDRESS_3").Value = CStr("Newcastle Upon Tyne")
oPurchaseRecord.Fields.Item("ADDRESS_4").Value = CStr("Tyne and Wear")
oPurchaseRecord.Fields.Item("ADDRESS_5").Value = CStr("NE13 9AA")
oPurchaseRecord.Fields.Item("CONTACT_NAME").Value = CStr("Michael Kenney")
oPurchaseRecord.Fields.Item("TELEPHONE").Value = CStr("0845 1117733")
oPurchaseRecord.Fields.Item("FAX").Value = CStr("0845 2450294")
oPurchaseRecord.Fields.Item("ANALYSIS_1").Value = CStr("")
oPurchaseRecord.Fields.Item("ANALYSIS_2").Value = CStr("")
oPurchaseRecord.Fields.Item("ANALYSIS_3").Value = CStr("")
oPurchaseRecord.Fields.Item("TERMS").Value = CStr("30 Days")
oPurchaseRecord.Fields.Item("DEF_NOM_CODE").Value = CStr("5000")
oPurchaseRecord.Fields.Item("VAT_REG_NUMBER").Value = CStr("")
oPurchaseRecord.Fields.Item("COUNTRY_CODE").Value = CStr("GB")

' Update the Record
If oPurchaseRecord.Update Then

' The Update was Successful
MsgBox "Account " & oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value & " was created successfully."

Else

' The Update was Unsuccessful
MsgBox "The account could not be created."

End If

End If

' Disconnect
oWS.Disconnect

End If

End If

' Destroy Objects
oSDO = Nothing
oWS = Nothing
oPurchaseRecord = Nothing

Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.PurchaseRecord oPurchaseRecord;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate the Purchase Record Object

  oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");

  //Try to add a new record

  if (oPurchaseRecord.AddNew())

  {

    SDOHelper.Write(oPurchaseRecord, "ACCOUNT_REF", (String)"SAGEGRP");

    SDOHelper.Write(oPurchaseRecord, "NAME", (String)"The Sage Group Plc.");

    SDOHelper.Write(oPurchaseRecord, "ADDRESS_1", (String)"Building 3");

    SDOHelper.Write(oPurchaseRecord, "ADDRESS_2", (String)"North Park");

    SDOHelper.Write(oPurchaseRecord, "ADDRESS_3", (String)"Newcastle Upon Tyne");

    SDOHelper.Write(oPurchaseRecord, "ADDRESS_4", (String)"Tyne and Wear");

    SDOHelper.Write(oPurchaseRecord, "ADDRESS_5", (String)"NE13 9AA");

    SDOHelper.Write(oPurchaseRecord, "CONTACT_NAME", (String)"Chris Reed");

    SDOHelper.Write(oPurchaseRecord, "TELEPHONE", (String)"0845 111 7733");

    SDOHelper.Write(oPurchaseRecord, "FAX", (String)"0845 245 0294");

    SDOHelper.Write(oPurchaseRecord, "ANALYSIS_1", (String)"");

    SDOHelper.Write(oPurchaseRecord, "ANALYSIS_2", (String)"");

    SDOHelper.Write(oPurchaseRecord, "ANALYSIS_3", (String)"");

    SDOHelper.Write(oPurchaseRecord, "TERMS", (String)"30 Days");

    SDOHelper.Write(oPurchaseRecord, "DEF_NOM_CODE", (String)"5000");

    SDOHelper.Write(oPurchaseRecord, "VAT_REG_NUMBER", (String)"");

    SDOHelper.Write(oPurchaseRecord, "COUNTRY_CODE", (String)"GB");

    //Update the record

    if (oPurchaseRecord.Update())

    {

      MessageBox.Show("Account: " + SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF")

        + " Was Created Successfully");

    }

    else

    {

      MessageBox.Show("The Account Could Not Be Created");

    }

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex){

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Creating a Supplier Delivery Address

Example - Creating a Supplier Delivery Address

The example code below demonstrates how to create a Supplier Delivery Address.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
                              ' Declare Objects
Dim  oSDO  As
                              SageDataObject300.SDOEngine
Dim  oWS  As
                              SageDataObject300.WorkSpace
Dim oPurchaseRecord  As
                              SageDataObject300.PurchaseRecord
Dim oPurchaseDeliveryRecord  As
                              SageDataObject300.PurchaseDeliveryRecord

' Declare Variables
Dim  szDataPath  As String
Dim bFound  As Boolean
Dim bEnd  As Boolean
Dim iAddNo  As Integer
Dim strRef  As String
Dim strAddNo  As String
Dim bFlag  As Boolean

' Error Handler
On Error GoTo Error_Handler

' Create the SDO Engine object
oSDO =  New   SageDataObject300.SDOEngine()

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> ""  Then

' Connect to Data Files
If oWS.Connect(szDataPath, "", "", "Example")
                              Then

' Create Instances of the
                                  Purchase Objects
oPurchaseRecord = oWS.CreateObject("PurchaseRecord")
oPurchaseDeliveryRecord =
                                oWS.CreateObject("PurchaseDeliveryRecord")

' Read the first Supplier
                                  record
oPurchaseRecord.MoveFirst()

' Initialise flag's
bEnd = False
bFound = False

' Move to First Record in the delivery address file
oPurchaseDeliveryRecord.MoveFirst()

' Search records for last occurrence in the file of this
                                  Supplier
' or until we have read all the records in the file
Do

' Do we have a match ?
If (oPurchaseDeliveryRecord.Fields.Item("ACCOUNT_REF").Value =
                                oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value)  Then

' Yes, so store the address ref
iAddNo = oPurchaseDeliveryRecord.Fields.Item("ADDRESS_REF").Value

' Set the found flag to true
bFound = True

Else

' If we have already found a match we must have stepped of it now
' so end our search
If
                                   (bFound)  Then bEnd = True

End If

Loop Until (bEnd  Or Not
                              oPurchaseDeliveryRecord.MoveNext)

' Spacefill the Account Reference to 8 chars
strRef = oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value & Space$(8 -
                              Len(oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value))

' Did we find one ?
If bFound  Then

' Yes, so increment last value
iAddNo = iAddNo + 1

' Convert to a string
strAddNo = CStr(iAddNo)

' Pad with leading zeroes
strAddNo = New String("0", 4 - Len(strAddNo)) & strAddNo

' Form the complete reference string
strRef = strRef & strAddNo

Else

' No, so start at 1
strRef = strRef & "0001"
iAddNo = 1

End If

' Add New Delivery Address
oPurchaseDeliveryRecord.AddNew()

' Pass New Reference
oPurchaseDeliveryRecord.Fields.Item("REFERENCE").Value =
                              CStr(strRef)
oPurchaseDeliveryRecord.Fields.Item("ACCOUNT_REF").Value =
                              CStr(oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value)
oPurchaseDeliveryRecord.Fields.Item("DESCRIPTION").Value =
                              CStr("New Delivery Address")

' Address Ref equals the number of the delivery address minus the zeros
oPurchaseDeliveryRecord.Fields.Item("ADDRESS_REF").Value =
                              CInt(iAddNo)
oPurchaseDeliveryRecord.Fields.Item("NAME").Value =
                              CStr("New SDO Account")
oPurchaseDeliveryRecord.Fields.Item("ADDRESS_1").Value =
                              CStr("Building 5")
oPurchaseDeliveryRecord.Fields.Item("ADDRESS_2").Value =
                              CStr("North Park")
oPurchaseDeliveryRecord.Fields.Item("ADDRESS_3").Value =
                              CStr("Newcastle Upon Tyne")
oPurchaseDeliveryRecord.Fields.Item("ADDRESS_4").Value =
                              CStr("Tyne and Wear")
oPurchaseDeliveryRecord.Fields.Item("ADDRESS_5").Value =
                              CStr("NE13 9AA")
oPurchaseDeliveryRecord.Fields.Item("TELEPHONE").Value =
                              CStr("0845 1117733")
oPurchaseDeliveryRecord.Fields.Item("FAX").Value =
                              CStr("0845 2450294")
oPurchaseDeliveryRecord.Fields.Item("CONTACT_NAME").Value =
                              CStr("Michael Kenney")
oPurchaseDeliveryRecord.Fields.Item("EMAIL").Value =
                              CStr("sagesoft.developers@sage.com")
oPurchaseDeliveryRecord.Fields.Item("TAX_CODE").Value =
                              CInt(1)

' Update New Record
bFlag = oPurchaseDeliveryRecord.Update

If bFlag  Then

MsgBox("Delivery address successfully added.", MsgBoxStyle.OKOnly, "SDO Examples")

Else

MsgBox("Delivery address update Unsuccessful.", MsgBoxStyle.OKOnly, "SDO Examples")

End If

' Disconnect
oWS.Disconnect()

End If

End If

' Destroy Objects
oPurchaseRecord =  Nothing
oPurchaseDeliveryRecord =  Nothing
oWS =  Nothing
oSDO =  Nothing

Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.PurchaseRecord oPurchaseRecord;

SageDataObject300.PurchaseDeliveryRecord oPurchaseDeliveryRecord;

String szDataPath;

Boolean bFound;

Boolean bEnd;

Int32 iAddNo = 0;

String strRef;

String strAddNo;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate Objects

  oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");

  oPurchaseDeliveryRecord =

    (SageDataObject300.PurchaseDeliveryRecord)oWS.CreateObject("PurchaseDeliveryRecord");

  //Read the first supplier record

  oPurchaseRecord.MoveFirst();

  //Initialise Flags

  bEnd = false;

  bFound = false;

  //move to the first record in the delivery address file

  oPurchaseDeliveryRecord.MoveFirst();

  //Search the records for last occurrence in the file of this supplier

  //or until we have read all the records in the file

  do

  {

    //Do we have a match

    if (SDOHelper.Read(oPurchaseDeliveryRecord, "ACCOUNT_REF") ==

      SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"))

    {

      //Yes, so store the address ref

      iAddNo = (Int32)SDOHelper.Read(oPurchaseRecord, "ADDRESS_REF");

      //Set the found flag to true

      bFound = true;

    }

    else

    {

      //If we have already found a match we must have stepped off it now

      //so end our search

      if (bFound) { bEnd = true; }

    }

  } while (!bEnd & oPurchaseRecord.MoveNext());

  //Pad the account reference to 8 chars

  strRef = (String)SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF");

  strRef = strRef.PadRight(8, Convert.ToChar(32));

  //Did we find one?

  if (bFound)

  {

    //Yes, so increment last value

    iAddNo += 1;

    //Convert to a string

    strAddNo = Convert.ToString(iAddNo);

    //Pad with leading zeros

    strAddNo = strAddNo.PadLeft(4, Convert.ToChar((Int16)0));

    //Form the complete reference string

    strRef = strRef + strAddNo;

  }

  else

  {

    //No, so start at 1

    strRef += "0001";

    iAddNo = 1;

  }

  //Add a new delivery address

  oPurchaseDeliveryRecord.AddNew();

  //Pass the new reference

  SDOHelper.Write(oPurchaseDeliveryRecord, "REFERENCE", (String)strRef);

  SDOHelper.Write(oPurchaseDeliveryRecord, "ACCOUNT_REF",

    (String)SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"));

  SDOHelper.Write(oPurchaseDeliveryRecord, "DESCRIPTION", (String)"New Delivery Address");

  //Address Ref equals the number of delivery addresses minus the zeros

  SDOHelper.Write(oPurchaseDeliveryRecord, "ADDRESS_REF", (Int32)iAddNo);

  SDOHelper.Write(oPurchaseDeliveryRecord, "NAME", (String)"New SDO Account");

  SDOHelper.Write(oPurchaseDeliveryRecord, "ADDRESS_1", (String)"Building 3");

  SDOHelper.Write(oPurchaseDeliveryRecord, "ADDRESS_2", (String)"North Park");

  SDOHelper.Write(oPurchaseDeliveryRecord, "ADDRESS_3", (String)"Newcastle Upon Tyne");

  SDOHelper.Write(oPurchaseDeliveryRecord, "ADDRESS_4", (String)"Tyne and Wear");

  SDOHelper.Write(oPurchaseDeliveryRecord, "ADDRESS_5", (String)"NE13 9AA");

  SDOHelper.Write(oPurchaseDeliveryRecord, "TELEPHONE", (String)"0845 111 7733");

  SDOHelper.Write(oPurchaseDeliveryRecord, "FAX", (String)"0845 245 0294");

  SDOHelper.Write(oPurchaseDeliveryRecord, "CONTACT_NAME", (String)"Chris Reed");

  SDOHelper.Write(oPurchaseDeliveryRecord, "EMAIL", (String)"developers.programme@sage.com");

  SDOHelper.Write(oPurchaseDeliveryRecord, "TAX_CODE", (Int32)1);

  //Update the new record

  if (oPurchaseDeliveryRecord.Update())

  {

    MessageBox.Show("Delivery Address Successfully Added");

  }

  else

  {

    MessageBox.Show("Delivery Address Update Failed");

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Deleting an Existing Supplier Record

Example - Deleting an Existing Supplier Record

The example code below demonstrates how to delete an existing Supplier Record.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oPurchaseRecord As SageDataObject300.PurchaseRecord

' Declare Variables
Dim szDataPath As String

' Create the SDOEngine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

' Try to Connect - Will Throw an Exception if it Fails
If oWS.Connect(szDataPath, "", "", "Example") Then

' Create an Instance of the PurchaseRecord Object
oPurchaseRecord = oWS.CreateObject("PurchaseRecord")

' Move to the First Record
oPurchaseRecord.MoveFirst

' Check to see if the Record can be deleted
If oPurchaseRecord.CanRemove Then

' Delete the Record
If oPurchaseRecord.Remove Then

' The Delete was Successful
MsgBox "Account " & oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value & " was deleted successfully."

Else

' The Delete was Unsuccessful
MsgBox "The account could not be deleted."

End If

Else

MsgBox "The account cannot be deleted."

End If

' Disconnect
oWS.Disconnect

End If

End If

' Destroy Objects
oSDO = Nothing
oWS = Nothing
oPurchaseRecord = Nothing

Exit Sub
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.PurchaseRecord oPurchaseRecord;

            try
            {
                // Create an Instance of the PurchaseRecord Object
                oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");

                // Move to the First Record
                oPurchaseRecord.MoveLast();

                // Check to see if the Record can be deleted
                if (oPurchaseRecord.CanRemove())
                {

                    // Delete the Record
                    if (oPurchaseRecord.Remove())
                    {
                        // The Delete was Successful
                        MessageBox.Show("Account " + SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF") + " was deleted successfully.");
                    }
                    else
                    {
                        // The Delete was Unsuccessful
                        MessageBox.Show("The account could not be deleted.");
                    }
                }
                else
                {
                    MessageBox.Show("The account cannot be deleted.");
                }

                // Disconnect
                oWS.Disconnect();
            }
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Editing an Existing Supplier Record

Example - Editing an Existing Supplier Record

The example code below demonstrates how to edit an existing Supplier Record.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
                                ' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim  oWS As SageDataObject300.WorkSpace
Dim oPurchaseRecord As SageDataObject300.PurchaseRecord

' Declare Variables
Dim szDataPath  As String

' Create the SDOEngine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user.  If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> ""  Then

' Try to Connect - Will Throw an Exception if it Fails
If  oWS.Connect(szDataPath, "", "", "Example")
                               Then

' Create an Instance of the
                                  PurchaseRecord Object
oPurchaseRecord =
                                oWS.CreateObject("PurchaseRecord")

' Move to the First Record
oPurchaseRecord.MoveFirst

' Edit the Record
If oPurchaseRecord.Edit
                               Then

' Change the Account Name
oPurchaseRecord.Fields.Item("NAME").Value =
                              CStr("Amended Company Name")

' Update the Record
If oPurchaseRecord.Update
                               Then

' The Update was Successful
MsgBox("Account " &
                              oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value & " was edited successfully.")

Else

' The Update was Unsuccessful
MsgBox("The account could not be
                                edited.")

End If

End If

' Disconnect
oWS.Disconnect

End If

End If

' Destroy Objects
oSDO =  Nothing
oWS =  Nothing
oPurchaseRecord =  Nothing
Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.PurchaseRecord oPurchaseRecord;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate the Purchase Record object

  oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");

  //Move to the first record

  oPurchaseRecord.MoveFirst();

  //Edit the record

  if (oPurchaseRecord.Edit())

  {

    //Change the Account Name

    SDOHelper.Write(oPurchaseRecord, "NAME", (String)"Amended Company Name");

    //Update the record

    if (oPurchaseRecord.Update())

    {

      MessageBox.Show("Account " + SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF") +

      " Was edited Successfully");

    }

    else

    {

      MessageBox.Show("The Account Could Not Be Edited");

    }

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example -�Generating a�Supplier Best Price

Example - Generating a Supplier Best Price

The example code below demonstrates how to return the best price for a given supplier, and stock code in Sage 50 Accounts.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oPricing As SageDataObject300.Pricing
Dim oPurchaseRecord As SageDataObject300.PurchaseRecord
Dim oStockRecord As SageDataObject300.StockRecord

' Declare Variables
Dim szDataPath As String
Dim dPrice As Double

' Create the SDO Engine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install
' folder as a parameter

szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.

If szDataPath <> "" Then

' Connect to Data Files
oWS.Connect szDataPath, "", "", "Example"

' Create stock and purchase objects then move first
oPurchaseRecord = oWS.CreateObject("PurchaseRecord")
oStockRecord = oWS.CreateObject("StockRecord")
oPurchaseRecord.MoveFirst
oStockRecord.MoveFirst

' Create instance of the Pricing Object
oPricing = oWS.CreateObject("Pricing")

' Get the Price
dPrice = oPricing.SupplierUnitPrice(oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value, oStockRecord.Fields.Item("STOCK_CODE").Value)
MsgBox(dPrice)

End If

' Destroy Objects
oWS = Nothing
oSDO = Nothing
oPricing = Nothing
oPurchaseRecord = Nothing
oStockRecord = Nothing

Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.Pricing oPricing;

SageDataObject300.PurchaseRecord oPurchaseRecord;

SageDataObject300.StockRecord oStockRecord;

String szDataPath;

Double dPrice;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate Objects and move to first

  oPricing = (SageDataObject300.Pricing)oWS.CreateObject("Pricing");

  oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");

  oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");

  oPurchaseRecord.MoveFirst();

  oStockRecord.MoveFirst();

  //Get the Price

  dPrice = oPricing.SupplierUnitPrice

    (

    (String)SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"),

    (String)SDOHelper.Read(oStockRecord, "STOCK_CODE")

    );

  MessageBox.Show(dPrice.ToString());

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Looping through supplier delivery addresses

Example - Looping through supplier delivery addresses

The example code below demonstrates how to loop through supplier delivery adresses.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

The code also includes a generic error handler. Clearly, you would respond differently depending on the actual exception thrown.

VB.NET [image] Copy VB Code
  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oPurchaseRecord As SageDataObject300.PurchaseRecord
  Dim oPurchaseDeliveryRecord As SageDataObject300.PurchaseDeliveryRecord

  ' Declare Variables
  Dim szDataPath As String
  Dim bFound As Boolean
  Dim bEnd As Boolean
  Dim bFlag As Boolean

  ' Create the SDO Engine object
  oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  oWS = oSDO.Workspaces.Add("Example")

  ' Select company. The SelectCompany method takes the program install folder as a
  ' parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is
  ' selected, the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then

   ' Connect to Data Files
   If oWS.Connect(szDataPath, "", "", "Example") Then

    ' Create Instances of the Purchase Objects
    oPurchaseRecord = oWS.CreateObject("PurchaseRecord")
    oPurchaseDeliveryRecord = oWS.CreateObject("PurchaseDeliveryRecord")

    ' Read the first supplier record
    oPurchaseRecord.MoveFirst()

    ' Initialise flag's
    bEnd = False
    bFound = False

    ' Move to First Record in the delivery address file
    oPurchaseDeliveryRecord.MoveFirst()

    ' Search records for occurrences in the file of this customer's delivery address'

    ' or until we have read all the records in the file

    Do

     ' Do we have a match ?

     If (oPurchaseDeliveryRecord.Fields.Item("ACCOUNT_REF").Value = _

     oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value) Then

      ' If yes, set the found flag to true

      bFound = True

      'Display the details for the delivery address

      MessageBox.Show(oPurchaseRecord.Fields.Item("NAME").Value & " " & _

      oPurchaseDeliveryRecord.Fields.Item("NAME").Value & " " & _

      oPurchaseDeliveryRecord.Fields.Item("ADDRESS_1").Value & " " & _

      oPurchaseDeliveryRecord.Fields.Item("ADDRESS_2").Value & " " & _

      oPurchaseDeliveryRecord.Fields.Item("ADDRESS_3").Value & " " & _

      oPurchaseDeliveryRecord.Fields.Item("ADDRESS_4").Value & " " & _

      oPurchaseDeliveryRecord.Fields.Item("ADDRESS_5").Value)

     Else

      ' If we have already found a match we must have stepped of it now

      ' so end our search

      If (bFound) Then

       bEnd = True

      End If

     End If

    Loop Until (bEnd Or Not oPurchaseDeliveryRecord.MoveNext)

    ' Disconnect

    oWS.Disconnect()

   End If

  End If

  ' Destroy Objects

  oPurchaseRecord = Nothing

  oPurchaseDeliveryRecord = Nothing

  oWS = Nothing

  oSDO = Nothing

  Exit Sub

                                                        C#.NET

                                 [image] Copy C# Code

 //Declare Variables

 SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

 SageDataObject300.WorkSpace oWS;

 SageDataObject300.PurchaseRecord oPurchaseRecord;

 SageDataObject300.PurchaseDeliveryRecord oPurchaseDeliveryRecord;

 String szDataPath;

 Boolean bFound;

 Boolean bEnd;

 //Instantiate WorkSpace

 oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

 //Show select company dialog

 szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

 //Try a connection, will throw an exception if it fails

 try

 {

     //Leaving the username and password blank generates a login dialog

     oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

     //Instantiate the Purchase Record and Purchase Delivery Record objects

     oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");

     oPurchaseDeliveryRecord = (SageDataObject300.PurchaseDeliveryRecord)oWS.CreateObject("PurchaseDeliveryRecord");

     //Read the first supplier record

     oPurchaseRecord.MoveFirst();

     //Initialise flags

     bEnd = false;

     bFound = false;

     //Move to the first record in the delivery address file

     oPurchaseDeliveryRecord.MoveFirst();

     //Search records for occurrences in the file of this customer's delivery address

     //or until we have read all the records in the file

     do

     {

         // Do we have a match ?

         if ((String)SDOHelper.Read(oPurchaseDeliveryRecord, "ACCOUNT_REF") == (String)SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"))

         {

             //If yes, set the found flag to true

             bFound = true;

             //Display the details for the delivery address

             MessageBox.Show(SDOHelper.Read(oPurchaseDeliveryRecord, "ACCOUNT_REF") + Environment.NewLine +

                 SDOHelper.Read(oPurchaseDeliveryRecord, "NAME") + Environment.NewLine +

                 SDOHelper.Read(oPurchaseDeliveryRecord, "REFERENCE") + Environment.NewLine +

                 SDOHelper.Read(oPurchaseDeliveryRecord, "ADDRESS_1") + Environment.NewLine +

                 SDOHelper.Read(oPurchaseDeliveryRecord, "ADDRESS_2") + Environment.NewLine +

                 SDOHelper.Read(oPurchaseDeliveryRecord, "ADDRESS_3") + Environment.NewLine +

                 SDOHelper.Read(oPurchaseDeliveryRecord, "ADDRESS_4") + Environment.NewLine +

                 SDOHelper.Read(oPurchaseDeliveryRecord, "ADDRESS_5") + Environment.NewLine);

         }

         else

             //If we have already found a match we must have stepped of it now

             //so end our search

         {

             if (bFound == true)

             {

                 bEnd = true;

             }

         }

     } while (!((bEnd | !oPurchaseDeliveryRecord.MoveNext())));

     //Disconnect

     oWS.Disconnect();

 }

//error handling

 catch (Exception ex)

 {

     MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

 }

                                     © Sage (UK) Ltd
                                    Click
                                                here to send feedback on this article.


Sage 50 Accounts - Example - Posting a Supplier Batch Purchase Invoice

Example - Posting a Supplier Batch Purchase Invoice

The example code below demonstrates how to post a Supplier Batch Purchase Invoice.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code

' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oPurchaseRecord As SageDataObject300.PurchaseRecord
Dim oTransactionPost As SageDataObject300.TransactionPost
Dim oSplitData As SageDataObject300.SplitData

' Declare Variables
Dim szDataPath As String
Dim iCtr As Short

' Create the SDO Engine Object
 oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is 'selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left 'empty.
 If szDataPath <> "" Then

' Connect to Data Files
If oWS.Connect(szDataPath, "", "", "Example") Then

' Create Instances of Objects
oTransactionPost = oWS.CreateObject("TransactionPost")
oPurchaseRecord = oWS.CreateObject("PurchaseRecord")
' Read the first Supplier
oPurchaseRecord.MoveFirst()

' Populate Header fields

' Note:
' The ACCOUNT_REF field must be populated with a valid
' Supplier Account Reference
oTransactionPost.Header("ACCOUNT_REF").Value = CStr (oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value = CDate(Today)
oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoPI)
oTransactionPost.Header("INV_REF").Value = CStr("INV001")

' Populate the foreign currency fields
oTransactionPost.Header("CURRENCY").Value = oPurchaseRecord.Fields.Item("CURRENCY").Value

' Loop for the Number of Splits
' Note:
' The Transaction can have 1 or many splits
For iCtr = 1 To 2
' Add a split to the Header Item's collection
oSplitData = oTransactionPost.Items.Add

' Populate Split Fields
 oSplitData.Fields.Item("TYPE").Value = oTransactionPost.Header("TYPE").Value
oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("4000")
oSplitData.Fields.Item("TAX_CODE").Value = CShort(1)
oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(100)
oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(17.5)
oSplitData.Fields.Item("DETAILS").Value = Cstr("Split Details")
oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)

Next iCtr
' Update the TransactionPost object
If oTransactionPost.Update Then
MsgBox("Transaction Posted successfully", MsgBoxStyle.OKOnly, "SDO Examples")

Else
MsgBox("Transaction Post Failed", MsgBoxStyle.OKOnly, "SDO Examples")

 End If

'Disconnect
oWS.Disconnect()

End If

 End If
'Destroy Objects
oTransactionPost = Nothing
oSplitData = Nothing
oPurchaseRecord = Nothing
oSDO = Nothing
oWS = Nothing

Exit Sub

C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.PurchaseRecord oPurchaseRecord;

SageDataObject300.TransactionPost oTransactionPost;

SageDataObject300.SplitData oSplitData;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate Objects

  oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

  oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");

  //Read the first Supplier

  oPurchaseRecord.MoveFirst();

  //Populate the Header Fields

  //Note:

  //The ACCOUNT_REF field must be populated with a valid

  //Supplier Account Reference

  SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF",

    (String)SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"));

  SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);

  SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);

  SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoPI);

  SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"INV001");

  //Populate the foreign currency fields

  SDOHelper.Write(oTransactionPost.Header, "CURRENCY", SDOHelper.Read(oPurchaseRecord, "CURRENCY"));

  //Loop for the number of splits

  //Note:

  //The transaction can have 1 or many splits

  for (Int16 i = 1; i <= 2; i++)

  {

    //Add a split to the header items collection

    oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

    //Populate the split fields

    SDOHelper.Write(oSplitData, "TYPE", SDOHelper.Read(oTransactionPost.Header, "TYPE"));

    SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"4000");

    SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)1);

    SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)100);

    SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)17.5);

    SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));

  }

  //Update the TransactionPost object

  if (oTransactionPost.Update())

  {

    MessageBox.Show("Transaction Posted Successfully");

  }

  else

  {

    MessageBox.Show("Transaction Post Failed");

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Posting a Supplier Batch Purchase Credit Note

Example - Posting a Supplier Batch Purchase Credit Note

The example code below demonstrates how to post a Supplier Batch Purchase Credit Note.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code

                                  ' Declare Objects
Dim oSDO  As
                                SageDataObject300.SDOEngine
Dim oWS  As
                                SageDataObject300.WorkSpace
Dim  oPurchaseRecord  As
                                SageDataObject300.PurchaseRecord
Dim oTransactionPost  As
                                SageDataObject300.TransactionPost
Dim oSplitData  As
                                SageDataObject300.SplitData

' Declare Variables
Dim szDataPath  As
                                 String
Dim iSplitCount  As
                                 Short

' Create the SDO Engine Object
oSDO =  New   SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company.  The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> ""  Then

' Try to Connect - Will throw an
    exception if it fails
If oWS.Connect(szDataPath, "", "", "Example")  Then

' Create Instances of Objects
oTransactionPost = oWS.CreateObject("TransactionPost")
oPurchaseRecord = oWS.CreateObject("PurchaseRecord")

' Read the First Supplier
oPurchaseRecord.MoveFirst()

' Populate Header fields

' Note:
' The ACCOUNT_REF field must be populated with a valid
' Supplier Account Reference
oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value = CDate(Today)
oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoPC)
oTransactionPost.Header("INV_REF").Value = CStr("CRD001")

' Populate the foreign currency fields
oTransactionPost.Header("CURRENCY").Value = oPurchaseRecord.Fields.Item("CURRENCY").Value

' Loop for the Number of Splits
' Note:
' The Transaction can have 1 or many splits
For iSplitCount = 1  To 2

' Add a split to the Header Item's collection
oSplitData = oTransactionPost.Items.Add

' Populate Split Fields
oSplitData.Fields.Item("TYPE").Value = oTransactionPost.Header("TYPE").Value
oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("4000")
oSplitData.Fields.Item("TAX_CODE").Value = CShort(1)
oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(100)
oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(17.5)
oSplitData.Fields.Item("DETAILS").Value = Cstr("Split Details")
oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)

Next iSplitCount

' Update the TransactionPost
    Object
If oTransactionPost.Update  Then

' Transaction Post Successful
MsgBox("Transaction Posted
                                  successfully.", MsgBoxStyle.OKOnly, "SDO Examples")

Else

' Transaction Post Failed
MsgBox("Transaction Post
                                  Failed.", MsgBoxStyle.OKOnly, "SDO Examples")

End  If

' Disconnect
oWS.Disconnect()

End  If

End  If

' Destroy Objects
oTransactionPost =  Nothing
oSplitData =  Nothing
oPurchaseRecord =  Nothing
oWS =  Nothing
oSDO =  Nothing

Exit  Sub
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.PurchaseRecord oPurchaseRecord;
            SageDataObject300.TransactionPost oTransactionPost;
            SageDataObject300.SplitData oSplitData;

            try
            {
                //Instantiate Objects
                oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");
                oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");

                //Read the first Supplier
                oPurchaseRecord.MoveFirst();

                //Populate the Header Fields

                //Note:
                //The ACCOUNT_REF field must be populated with a valid
                //Supplier Account Reference
                SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"));
                SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);
                SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);
                SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoPC);
                SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"PR001");

                //Populate the foreign currency fields
                SDOHelper.Write(oTransactionPost.Header, "CURRENCY", SDOHelper.Read(oPurchaseRecord, "CURRENCY"));

                //Add a split to the header items collection
                oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                //Populate the split fields
                SDOHelper.Write(oSplitData, "TYPE", SDOHelper.Read(oTransactionPost.Header, "TYPE"));
                SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"4000");
                SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)1);
                SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)100);
                SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)17.5);
                SDOHelper.Write(oSplitData, "DETAILS", (String)"PC Split Deatils");
                SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));

                //Update the TransactionPost object
                if (oTransactionPost.Update())
                {
                    MessageBox.Show("Transaction Posted Successfully");
                }
                else
                {
                    MessageBox.Show("Transaction Post Failed");
                }

                // Disconnect
                oWS.Disconnect();
            }
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Posting a Supplier Purchase Receipt

Example - Posting a Supplier Purchase Receipt

The example code below demonstrates how to post a Supplier Purchase Receipt.

NOTE: It is important to populate the ACCOUNT_REF and BANK_CODE fields on the transaction header, and ensure that the NOMINAL_CODE field on the transaction split is identical to the bank code. Without these, TransactionPost.Update will not return True.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code

'Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oPurchaseRecord As SageDataObject300.PurchaseRecord
Dim oTransactionPost As SageDataObject300.TransactionPost
Dim oSplitData As SageDataObject300.SplitData

'Declare Variables
Dim szDataPath As String

'Create the SDO Engine Object
 oSDO = New SageDataObject300.SDOEngine

'Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

'Select Company. The SelectCompany method takes the program install
'folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

'A U.I. for company selection is presented to the user. If a company is 'selected,
'the path will be passed to the szDataPath variable.
'If not, or the Cancel button is selected, the variable will be left 'empty.
 If szDataPath <> "" Then

'Connect to Data Files
If oWS.Connect(szDataPath, "", "", "Example") Then

'Create Instances of Objects
oTransactionPost = oWS.CreateObject("TransactionPost")
oPurchaseRecord = oWS.CreateObject("PurchaseRecord")
'Read the first Supplier
oPurchaseRecord.MoveFirst()

'Populate Header fields

'Note:
'The ACCOUNT_REF field must be populated with a valid Supplier Account Reference
oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value = CDate(Date.Today)
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoPR)
oTransactionPost.Header("INV_REF").Value = CStr("PR1")
 oTransactionPost.Header("BANK_CODE").Value = CStr("1200")

'Populate the foreign currency fields
oTransactionPost.Header("CURRENCY").Value = oPurchaseRecord.Fields.Item("CURRENCY").Value

'NOTE: **The PR transaction cannot have multiple splits**
'Add a split to the Header Item's collection
oSplitData = oTransactionPost.Items.Add

'Populate Split Fields
 oSplitData.Fields.Item("TYPE").Value = CByte(oTransactionPost.Header("TYPE").Value)
oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr(oTransactionPost.Header("BANK_CODE").Value)
oSplitData.Fields.Item("TAX_CODE").Value = CInt(9)
oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(100)
oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(0)
oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)
'Update the TransactionPost object
If oTransactionPost.Update Then
MsgBox("Transaction Posted successfully", MsgBoxStyle.OKOnly, "SDO Examples")

Else
MsgBox("Transaction Post Failed", MsgBoxStyle.OKOnly, "SDO Examples")

 End If

'Disconnect
oWS.Disconnect()

End If

 End If
'Destroy Objects
oTransactionPost = Nothing
oSplitData = Nothing
oPurchaseRecord = Nothing
oSDO = Nothing
oWS = Nothing

Exit Sub

C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.PurchaseRecord oPurchaseRecord;
            SageDataObject300.TransactionPost oTransactionPost;
            SageDataObject300.SplitData oSplitData;

            try
            {
                //Instantiate Objects
                oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");
                oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");

                //Read the first Supplier
                oPurchaseRecord.MoveFirst();

                //Populate the Header Fields

                //Note:
                //The ACCOUNT_REF field must be populated with a valid
                //Supplier Account Reference
                SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"));
                SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);
                SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoPR);
                SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"PR001");
                SDOHelper.Write(oTransactionPost.Header, "BANK_CODE", (String)"1200");

                //Populate the foreign currency fields
                SDOHelper.Write(oTransactionPost.Header, "CURRENCY", SDOHelper.Read(oPurchaseRecord, "CURRENCY"));

                //Add a split to the header items collection (only 1 split per PR)
                oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                //Populate the split fields
                SDOHelper.Write(oSplitData, "TYPE", SDOHelper.Read(oTransactionPost.Header, "TYPE"));
                SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)SDOHelper.Read(oTransactionPost.Header, "BANK_CODE"));
                SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)9);
                SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)100);
                SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)17.5);
                SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));

                //Update the TransactionPost object
                if (oTransactionPost.Update())
                {
                    MessageBox.Show("Transaction Posted Successfully");
                }
                else
                {
                    MessageBox.Show("Transaction Post Failed");
                }

                // Disconnect
                oWS.Disconnect();
            }
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Posting a Foreign Currency Purchase Invoice

Example - Posting a Foreign Currency Purchase Invoice

The example code below demonstrates how to post a Foreign Currency Purchase Invoice.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oPurchaseRecord As SageDataObject300.PurchaseRecord
Dim oTransactionPost As SageDataObject300.TransactionPost
Dim oSplitData As SageDataObject300.SplitData
Dim oCurrencyData As SageDataObject300.CurrencyData

' Declare Variables
Dim szDataPath As String
Dim iCtr As Short

' Create the SDO Engine Object
 oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is 'selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left 'empty.
 If szDataPath <> "" Then

' Connect to Data Files
If oWS.Connect(szDataPath, "", "", "Example") Then

' Create Instances of Objects
oTransactionPost = oWS.CreateObject("TransactionPost")
oPurchaseRecord = oWS.CreateObject("PurchaseRecord")
 oCurrencyData = oWS.CreateObject("CurrencyData")

' Read the first Customer
oPurchaseRecord.MoveFirst()

' Read the Currency Data
oCurrencyData.Read(Convert.ToByte(oPurchaseRecord.Fields.Item("CURRENCY").Value) + 1)

' Populate Header fields
' Note:
' The ACCOUNT_REF field must be populated with a valid
' Customer Account Reference
oTransactionPost.Header("ACCOUNT_REF").Value = CStr (oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value = CDate(Today)
oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoPI)
oTransactionPost.Header("DETAILS").Value = CStr("Test Purchase Invoice")
oTransactionPost.Header("INV_REF").Value = CStr("INV001")

' Populate Foreign Currency Fields
oTransactionPost.Header("FOREIGN_RATE").Value = CDbl (oCurrencyData.Fields.Item("EXCHANGE_RATE").Value)
oTransactionPost.Header("CURRENCY").Value = oPurchaseRecord.Fields.Item("CURRENCY").Value

' Loop for the Number of Splits
' Note:
' The Transaction can have 1 or many splits
For iCtr = 1 To 2

' Add a split to the Header Item's collection
oSplitData = oTransactionPost.Items.Add

' Populate Split Fields
 oSplitData.Fields.Item("TYPE").Value = oTransactionPost.Header("TYPE").Value
oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("4000")
oSplitData.Fields.Item("TAX_CODE").Value = CShort(1)
oSplitData.Fields.Item("FOREIGN_NET_AMOUNT").Value = CDbl(100)
oSplitData.Fields.Item("FOREIGN_TAX_AMOUNT").Value = CDbl(17.5)
oSplitData.Fields.Item("DETAILS").Value = Cstr("Split Details")
oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)

Next iCtr

' Update the TransactionPost object
If oTransactionPost.Update Then

MsgBox("Transaction Posted successfully", MsgBoxStyle.OKOnly, "SDO Examples")

Else
MsgBox("Transaction Post Failed", MsgBoxStyle.OKOnly, "SDO Examples")

 End If

'Disconnect
oWS.Disconnect()

End If

 End If

'Destroy Objects
oTransactionPost = Nothing
oSplitData = Nothing
oPurchaseRecord = Nothing
oCurrencyData = Nothing
oSDO = Nothing
oWS = Nothing

Exit Sub
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.PurchaseRecord oPurchaseRecord;
            SageDataObject300.TransactionPost oTransactionPost;
            SageDataObject300.SplitData oSplitData;
            SageDataObject300.CurrencyData oCurrencyData;

            try
            {
                //Instantiate Objects
                oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");
                oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");
                oCurrencyData = (SageDataObject300.CurrencyData)oWS.CreateObject("CurrencyData");

                //Read the first Supplier
                oPurchaseRecord.MoveFirst();

                //Read the currency file depending on the currency specified in the Supplier record
                oCurrencyData.Read(Convert.ToInt32(SDOHelper.Read(oPurchaseRecord, "CURRENCY")) + 1);

                //Populate the header fields

                //Note:
                //The ACCOUNT_REF field must be populated with a valid
                //Supplier account reference
                SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"));
                SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);
                SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);
                SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoPI);
                SDOHelper.Write(oTransactionPost.Header, "DETAILS", (String)"Test Purchase Invoice");
                SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"INV001");

                //Populate foreign currency fields
                SDOHelper.Write(oTransactionPost.Header, "FOREIGN_RATE", SDOHelper.Read(oCurrencyData, "EXCHANGE_RATE"));
                SDOHelper.Write(oTransactionPost.Header, "CURRENCY", SDOHelper.Read(oPurchaseRecord, "CURRENCY"));

                //Loop for the number of splits
                //Note:
                //The transaction can have 1 or many splits
                for (Int16 i = 1; i <= 2; i++)
                {
                    //Add a split to the headers items collection
                    oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                    //Populate the split fields
                    SDOHelper.Write(oSplitData, "TYPE", (Byte)SageDataObject300.TransType.sdoPI);
                    SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"4000");
                    SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)1);
                    SDOHelper.Write(oSplitData, "FOREIGN_NET_AMOUNT", (Double)100);
                    SDOHelper.Write(oSplitData, "FOREIGN_TAX_AMOUNT", (Double)17.5);
                    SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));
                }

                //Update the Transaction Post object
                if (oTransactionPost.Update())
                {
                    MessageBox.Show("Transaction Posted Successfully");
                }
                else
                {
                    MessageBox.Show("Transaction Post Failed");
                }

                // Disconnect
                oWS.Disconnect();
            }
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Posting a Foreign Currency Purchase Credit Note

Example - Posting a Foreign Currency Purchase Credit Note

The example code below demonstrates how to post a Foreign Currency Purchase Credit Note.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oPurchaseRecord As SageDataObject300.PurchaseRecord
Dim oTransactionPost As SageDataObject300.TransactionPost
Dim oSplitData As SageDataObject300.SplitData
Dim oCurrencyData As SageDataObject300.CurrencyData

' Declare Variables
Dim szDataPath As String
Dim iSplitCount As Short

' Create the SDO Engine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

' Try to Connect - Will throw an exception if it fails
If oWS.Connect(szDataPath, "", "", "Example") Then

' Create Instances of Objects
oTransactionPost = oWS.CreateObject("TransactionPost")
oPurchaseRecord = oWS.CreateObject("PurchaseRecord")
oCurrencyData = oWS.CreateObject("CurrencyData")

' Read the First Supplier
oPurchaseRecord.MoveFirst()

' Read the Currency Data
oCurrencyData.Read(Convert.ToByte(oPurchaseRecord.Fields.Item("CURRENCY").Value) + 1)

' Populate Header fields

' Note:
' The ACCOUNT_REF field must be populated with a valid
' Supplier Account Reference
oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value = CDate(Today)
oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoPC)
oTransactionPost.Header("DETAILS").Value = CStr("Test Purchase Credit Note")
oTransactionPost.Header("INV_REF").Value = CStr("CRD001")

' Populate Foreign Currency Fields
oTransactionPost.Header("FOREIGN_RATE").Value = CDBl (oCurrencyData.Fields.Item("EXCHANGE_RATE").Value)
oTransactionPost.Header("CURRENCY").Value = oPurchaseRecord.Fields.Item("CURRENCY").Value

' Loop for the Number of Splits
' Note:
' The Transaction can have 1 or many splits
For iSplitCount = 1 To 2

' Add a split to the Header Item's collection
oSplitData = oTransactionPost.Items.Add

' Populate Split Fields
oSplitData.Fields.Item("TYPE").Value = oTransactionPost.Header("TYPE").Value
oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("4000")
oSplitData.Fields.Item("TAX_CODE").Value = CShort(1)
oSplitData.Fields.Item("FOREIGN_NET_AMOUNT").Value = CDbl(100)
oSplitData.Fields.Item("FOREIGN_TAX_AMOUNT").Value = CDbl(17.5)
oSplitData.Fields.Item("DETAILS").Value = Cstr("Split Details")
oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)

Next iSplitCount

' Update the TransactionPost Object
If oTransactionPost.Update Then

' Transaction Post Successful
MsgBox("Transaction Posted successfully.", MsgBoxStyle.OKOnly, "SDO Examples")

Else

' Transaction Post Failed
MsgBox("Transaction Post Failed.", MsgBoxStyle.OKOnly, "SDO Examples")

End If

' Disconnect
 oWS.Disconnect()

End If

End If

' Destroy Objects
oTransactionPost = Nothing
oSplitData = Nothing
oPurchaseRecord = Nothing
 oCurrencyData = Nothing
oWS = Nothing
oSDO = Nothing

Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.PurchaseRecord oPurchaseRecord;

SageDataObject300.TransactionPost oTransactionPost;

SageDataObject300.SplitData oSplitData;

SageDataObject300.CurrencyData oCurrencyData;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate objects

  oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

  oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");

  oCurrencyData = (SageDataObject300.CurrencyData)oWS.CreateObject("CurrencyData");

  //Read the first supplier

  oPurchaseRecord.MoveFirst();

  //Read the currency data

  oCurrencyData.Read(Convert.ToInt32(SDOHelper.Read(oPurchaseRecord, "CURRENCY")) + 1);

  //Populate the header fields

  //Note:

  //The ACCOUNT_REF field must be populated with a valid

  //supplier account reference

  SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF",

    (String)SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"));

  SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);

  SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);

  SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoPC);

  SDOHelper.Write(oTransactionPost.Header, "DETAILS", (String)"Test Purchase Credit Note");

  SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"CRD001");

  //Populate foreign currency fields

  SDOHelper.Write(oTransactionPost.Header, "FOREIGN_RATE", SDOHelper.Read(oCurrencyData, "EXCHANGE_RATE"));

  SDOHelper.Write(oTransactionPost.Header, "CURRENCY", SDOHelper.Read(oPurchaseRecord, "CURRENCY"));

  //Loop for the number of splits

  //Note:

  //The transaction can have 1 or many splits

  for (Int16 i = 1; i<= 2; i++)

  {

    //Add a split to the headers item collection

    oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

    //Populate split fields

    SDOHelper.Write(oSplitData, "TYPE", (Byte)SageDataObject300.TransType.sdoPC);

    SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"4000");

    SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)1);

    SDOHelper.Write(oSplitData, "FOREIGN_NET_AMOUNT", (Double)100);

    SDOHelper.Write(oSplitData, "FOREIGN_TAX_AMOUNT", (Double)17.5);

    SDOHelper.Write(oSplitData, "DATE", SDOHelper.Read(oTransactionPost.Header, "DATE"));

  }

  //Update the Transaction Post object

  if (oTransactionPost.Update())

  {

    MessageBox.Show("Transaction Posted Successfully");

  }

  else

  {

    MessageBox.Show("Transaction Post Failed");

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - View Supplier Aged Balances

Example - View Supplier Aged Balances

The example code below demonstrates how to view supplier aged balances.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.
VB.NET [image] Copy VB Code
 ' Declare Objects
 Dim oSDO As SageDataObject300.SDOEngine
 Dim oWS As SageDataObject300.WorkSpace
 Dim oPurchaseRecord As SageDataObject300.PurchaseRecord
 Dim oAgedBalances As SageDataObject300.AgedBalances

 ' Declare Variables
 Dim szDataPath As String

 ' Error Handler
 Try
   ' Create the SDO Engine object
   oSDO = New SageDataObject300.SDOEngine

   ' Create the Workspace
   oWS = oSDO.Workspaces.Add("Example")

   ' Select company. The SelectCompany method takes the program install folder as a parameter
   szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

   ' A U.I. for company selection is presented to the user. If a company is selected,
   ' the path will be passed to the szDataPath variable.
   ' If not, or the Cancel button is selected, the variable will be left empty.
   If szDataPath <> "" Then
     ' Connect to Data Files
     If oWS.Connect(szDataPath, "", "", "Example") Then

       ' Get the sales ledger record
        oPurchaseRecord = oWS.CreateObject("PurchaseRecord")
       oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value = "CON001"

       ' Do an exact match search for the account
       If (oPurchaseRecord.Find(False)) Then

         ' Create the aged balances object
         oAgedBalances = oPurchaseRecord.GetAgedBalances()

         ' Set the date you wish to use to calculate the aged balances.
         oAgedBalances.SetAgedBalanceDate(CDate(Now))

         ' Set the date you wish to use to include payments up to.
         oAgedBalances.SetIncludePaymentDate(CDate(Now))

         ' Set the ageing type. This can be:
         ' sdoAgeByCalendarMonth - Ages by Calendar Month,
         ' sdoAgeByPeriod - Aged By Periods,
         ' sdoAgeByDay - Aged By Periods and first day of the month following the transaction date.
         ' Here we are ageing by Periods.
         oAgedBalances.SetAgedMode(SageDataObject300.TransactionAgeingType.sdoAgeByPeriod)

         ' If we are ageing by periods then we can specify the periods for this calculation.
         oAgedBalances.SetAgedPeriodStart(1, CInt(30))
         oAgedBalances.SetAgedPeriodStart(2, CInt(60))
         oAgedBalances.SetAgedPeriodStart(3, CInt(90))
         oAgedBalances.SetOlderAgedPeriod(CInt(160))

         ' Set whether you want to include transactions that are dated
         '  after the aged balance date in the customer's total balance.
         ' 0 - do not include.
         ' 1 - include.
         oAgedBalances.SetIncludeFuture(0)

         ' Calculate the aged balances
         oAgedBalances.Calculate()

         ' Get the Future, Current, Total and Older Balances
         Dim strFuture As String
         Dim strCurrent As String
         Dim strTotal As String
         Dim strPeriod As String
         Dim strOlder As String

         strFuture = CStr(oAgedBalances.GetFutureBalance())
         strCurrent = CStr(oAgedBalances.GetCurrentBalance())
         strTotal = CStr(oAgedBalances.GetTotalBalance())
         strOlder = CStr(oAgedBalances.GetOlderBalance)

         Dim strMessage As String
         Dim oItem As Object
         Dim iCount As Integer = 1

         strMessage = "Future balance : " + strFuture + vbCrLf _
         + "Current balance : " + strCurrent + vbCrLf _
         + "Total balance : " + strTotal + vbCrLf

         ' Loop through each of the period balances (3)
         For Each oItem In oAgedBalances

           strMessage += "Period" + CStr(iCount) + vbTab + CStr(oItem) + vbTab
           iCount += 1

         Next oItem

         strMessage += "Older" + vbTab + strOlder
         strMessage += vbCrLf

         MessageBox.Show(strMessage, "Aged Results for account " + oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value, MessageBoxButtons.OK, MessageBoxIcon.Information)

       Else

         MessageBox.Show("The purchase ledger account 'CON001' cannot be found.", "SDO Error", MessageBoxButtons.OK, MessageBoxIcon.Error)

       End If
     Else

       MessageBox.Show( "Could not logon to the data.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

     End If

   End If

 Catch ex As Exception
   ' Error Handling Code
   MessageBox.Show("The SDO generated the following error: " & ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

  Finally

   If Not oPurchaseRecord Is Nothing Then
     oPurchaseRecord = Nothing
   End If

   If Not oAgedBalances Is Nothing Then
     oAgedBalances = Nothing
   End If

   If Not oWS Is Nothing Then
     oWS.Disconnect()
     oWS = Nothing
     oSDO = Nothing
   End If
 End Try
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.PurchaseRecord oPurchaseRecord;
SageDataObject300.AgedBalances oAgedBalances;

String szDataPath;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails
try
{
    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

    //Get the sales ledger record
    oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");
    SDOHelper.Write(oPurchaseRecord, "ACCOUNT_REF", "SUPPLIER");

    //Do an exact match search on account
    if (oPurchaseRecord.Find(false))
    {
        //Create the aged balances object
        oAgedBalances = (SageDataObject300.AgedBalances)oPurchaseRecord.GetAgedBalances();

        //Set the date you wish to calculate the aged balances
        oAgedBalances.SetAgedBalanceDate((DateTime)DateTime.Today);

        //Set the date you wish to use to include payments up to.
        oAgedBalances.SetIncludePaymentDate((DateTime)DateTime.Today);

        //Set the ageing type. This can be:
        //sdoAgeByCalendarMonth - Ages by Calendar Month,
        //sdoAgeByPeriod - Aged By Periods,
        //sdoAgeByDay - Aged By Periods and first day of the month following the transaction date.
        //Here we are ageing by Periods.
        oAgedBalances.SetAgedMode(SageDataObject300.TransactionAgeingType.sdoAgeByPeriod);

        //If we are ageing by periods then we can specify the periods for this calculation
        oAgedBalances.SetAgedPeriodStart(1, (Int32)30);
        oAgedBalances.SetAgedPeriodStart(2, (Int32)60);
        oAgedBalances.SetAgedPeriodStart(3, (Int32)90);
        oAgedBalances.SetOlderAgedPeriod((Int32)160);

        //Set whether you want to include transactions that are dated
        //after the aged balance date in the customer's tottal balance.
        //0 - do not include
        //1 - include.
        oAgedBalances.SetIncludeFuture(0);

        //Calculate the aged balances
        oAgedBalances.Calculate();

        //Get the furure, curent total and older balances
        String strFuture;
        String strCurrent;
        String strTotal;
        String strOlder;

        strFuture = Convert.ToString(oAgedBalances.GetFutureBalance());
        strCurrent = Convert.ToString(oAgedBalances.GetCurrentBalance());
        strTotal = Convert.ToString(oAgedBalances.GetTotalBalance());
        strOlder = Convert.ToString(oAgedBalances.GetOlderBalance());

        String strMessage;
        Int32 iCount = 1;

        strMessage = "Future balance : " + strFuture + Environment.NewLine +
            "Current balance : " + strCurrent + Environment.NewLine +
            "Total balance : " + strTotal + Environment.NewLine;

        for (int i = 1; i <= oAgedBalances.Count; i++)
        {
            Object oItem = i;
            strMessage += "Period" + Convert.ToString(iCount) + (char)9 + oAgedBalances.Item(ref oItem) + (char)9;
            iCount += 1;
        }

        strMessage += "Older" + (char)9 + strOlder;
        strMessage += Environment.NewLine;

        MessageBox.Show(strMessage, "Aged Results for Account " + SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"));

    }
    else
    {
        MessageBox.Show("The sales ledger account 'TEST' cannot be found", "SDO ERROR");
    }

    //Disconnect
    oWS.Disconnect();

}
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}


Sage 50 Accounts - Example - View Supplier Aged Periods

Example - View Supplier Aged Periods

The example code below demonstrates how to view supplier aged periods.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
 ' Declare Objects
 Dim oSDO As SageDataObject300.SDOEngine
 Dim oWS As SageDataObject300.WorkSpace
 Dim oPurchaseRecord As SageDataObject300.PurchaseRecord
 Dim oAgedBalances As SageDataObject300.AgedBalances

 ' Declare Variables
 Dim szDataPath As String

 ' Error Handler
 Try
   ' Create the SDO Engine object
   oSDO = New SageDataObject300.SDOEngine

   ' Create the Workspace
   oWS = oSDO.Workspaces.Add("Example")

   ' Select company. The SelectCompany method takes the program install folder as a parameter
   szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

   ' A U.I. for company selection is presented to the user. If a company is selected,
   ' the path will be passed to the szDataPath variable.
   ' If not, or the Cancel button is selected, the variable will be left empty.
   If szDataPath <> "" Then
     ' Connect to Data Files
     If oWS.Connect(szDataPath, "", "", "Example") Then

       ' Get the sales ledger record
        oPurchaseRecord = oWS.CreateObject("PurchaseRecord")
       oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value = "CON001"

       ' Do an exact match search for the account
       If (oPurchaseRecord.Find(False)) Then

         ' Create the aged balances object
         oAgedBalances = oPurchaseRecord.GetAgedBalances()

         ' Display the values calculated
         MessageBox.Show("Period 1: " & CStr(oAgedBalances.GetAgedPeriodStart(1)) & vbCrLf & _
         "Period 2: " & CStr(oAgedBalances.GetAgedPeriodStart(2)) & vbCrLf & _
         "Period 3: " & CStr(oAgedBalances.GetAgedPeriodStart(3)) & vbCrLf & _
         "Older: " & CStr(oAgedBalances.GetOlderAgedPeriod), _
         "Aged periods for account " + oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value, MessageBoxButtons.OK, MessageBoxIcon.Information)

       Else

         MessageBox.Show("The purchase ledger account 'ACON001' cannot be found.", "SDO Error", MessageBoxButtons.OK, MessageBoxIcon.Error)

       End If
     Else

       MessageBox.Show( "Could not logon to the data.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

     End If

   End If

 Catch ex As Exception
   ' Error Handling Code
   MessageBox.Show("The SDO generated the following error: " & ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

  Finally

   If Not oPurchaseRecord Is Nothing Then
     oPurchaseRecord = Nothing
   End If

   If Not oAgedBalances Is Nothing Then
     oAgedBalances = Nothing
   End If

   If Not oWS Is Nothing Then
     oWS.Disconnect()
     oWS = Nothing
     oSDO = Nothing
   End If
 End Try
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.PurchaseRecord oPurchaseRecord;
SageDataObject300.AgedBalances oAgedBalances;

String szDataPath;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails
try
{
    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

    //Get the sales ledger record
    oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");
    SDOHelper.Write(oPurchaseRecord, "ACCOUNT_REF", "SUPPLIER");

    //Do an exact match search on account
    if (oPurchaseRecord.Find(false))
    {
        //Create the aged balances object
        oAgedBalances = (SageDataObject300.AgedBalances)oPurchaseRecord.GetAgedBalances();

        //Display the values calculated
        MessageBox.Show("Supplier: " + SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF") + Environment.NewLine +
            "Period 1: " + Convert.ToString(oAgedBalances.GetAgedPeriodStart(1)) + Environment.NewLine +
            "Period 2: " + Convert.ToString(oAgedBalances.GetAgedPeriodStart(2)) + Environment.NewLine +
            "Period 3: " + Convert.ToString(oAgedBalances.GetAgedPeriodStart(3)) + Environment.NewLine +
            "Older : " + Convert.ToString(oAgedBalances.GetOlderAgedPeriod()), "Aged periods for account " +
            SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"));
    }
    else
    {
        MessageBox.Show("The purchase ledger account " + SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF") + " Could not be found");
    }

    //Disconnect
    oWS.Disconnect();

}
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}


Sage 50 Accounts - Example - Accessing a Nominal Account Memo

Example - Accessing a Nominal Account Memo

The example code below demonstrates how to access a Nominal Account Memo.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code

        ' Declare Objects

        Dim oSDO As SageDataObject300.SDOEngine

        Dim oWS As SageDataObject300.WorkSpace

        Dim oNominalRecord As SageDataObject300.NominalRecord

        ' Declare Variables

        Dim szDataPath As String

        Dim bFlag As Boolean

        ' Create the SDO Engine object

        oSDO = New SageDataObject300.SDOEngine

        ' Create the workspace

        oWS = oSDO.Workspaces.Add("Example")

        ' Select company. The SelectCompany method takes the program install

        ' folder as a parameter

        szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

        ' A U.I. for company selection is presented to the user. If a company is 'selected,

        ' the path will be passed to the szDataPath variable.

        ' If not, or the Cancel button is selected, the variable will be 'left empty.

        If szDataPath <> "" Then

            ' Connect to Data Files

            If oWS.Connect(szDataPath, "", "", "Example") Then

                ' Create instance on NominalRecord object

                oNominalRecord = oWS.CreateObject("NominalRecord")

                ' Add memo to first nominal code.

                ' Move to the first record

                oNominalRecord.MoveFirst()

                ' Edit the record

                oNominalRecord.Edit()

                ' Populate memo field

                oNominalRecord.Memo = CStr("SDO Generated memo")

                ' Update the record

                If oNominalRecord.Update Then

                    MsgBox("Memo Saved Successfully", MsgBoxStyle.OkOnly, "SDO Examples")

                Else

                    MsgBox("Memo Has Not Been Saved", MsgBoxStyle.OkOnly, "SDO Examples")

                End If

                ' Read memo

                ' Move to first record

                oNominalRecord.MoveFirst()

                ' Read memo

                MsgBox("Memo for nominal code " & oNominalRecord.Fields.Item("ACCOUNT_REF").Value & " " & "reads : " & oNominalRecord.Memo, MsgBoxStyle.OkOnly, "SDO Examples")

                ' Disconnect

                oWS.Disconnect()

            End If

        End If

        ' Destroy Objects

        oNominalRecord = Nothing

        oWS = Nothing

        oSDO = Nothing

        Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.NominalRecord oNominalRecord;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate the Nominal Record object

  oNominalRecord = (SageDataObject300.NominalRecord)oWS.CreateObject("NominalRecord");

  //Move to the first nominal record so we can add the memo

  oNominalRecord.MoveFirst();

  //Edit the record

  oNominalRecord.Edit();

  //Populate the memo field

  oNominalRecord.Memo = (String)"SDO Generated Memo";

  //Update the record

  if (oNominalRecord.Update())

  {

    MessageBox.Show("Memo Created Successfully");

  }

  else

  {

    MessageBox.Show("Failed to Add Memo");

  }

  //Read the memo back and display in a message box

  oNominalRecord.MoveFirst();

  MessageBox.Show("Memo for nominal code: " + SDOHelper.Read(oNominalRecord, "ACCOUNT_REF")

    + " Reads,\n\n" + oNominalRecord.Memo);

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Creating a New Accrual Record

Example - Creating a New Accrual Record

The example code below demonstrates how to create a new Accrual Record.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
                                ' Declare Objects
Dim oSDO As
                              SageDataObject300.SDOEngine
Dim oWS As
                              SageDataObject300.WorkSpace
Dim oAccrualData As
                              SageDataObject300.AccrualData
Dim oControlData As
                              SageDataObject300.ControlData
Dim oNominalData As
                              SageDataObject300.NominalData

' Declare Variables
Dim szDataPath As
                                String

' Create the SDO Engine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the
                                        program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user.
                                        If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left
                                    empty.
If szDataPath <> ""
                                  Then

' Connect to Data Files
If oWS.Connect(szDataPath,
                                        "", "",
                                        "Example") Then

' Create Instances of Objects
oAccrualData =
                                    oWS.CreateObject("AccrualData")
oControlData = oWS.CreateObject("ControlData")
oNominalData = oWS.CreateObject("NominalData")

' Read Control Data
' for Default Accruals Nominal
                                  Code
oControlData.Read(1)

' Now read Nominal using the
                                  default accruals code
oNominalData.Read(CInt(oControlData.Fields.Item("ACCRUALS_NO").Value))

' Populate the fields
oAccrualData.Fields.Item("NAME").Value = CStr("SDO
                                  Generated Accrual")
oAccrualData.Fields.Item("AMOUNT").Value
                                = CDbl(1200#)
oAccrualData.Fields.Item("DEPT_NUMBER").Value =
                                CShort(0)
oAccrualData.Fields.Item("MONTHS_TO_POST").Value
                                  = CShort(3)
oAccrualData.Fields.Item("MONTHS_POSTED").Value
                                      = CShort(0)
oAccrualData.Fields.Item("NOMINAL_CODE_2").Value
                                = CStr(oNominalData.Fields.Item("ACCOUNT_REF").Value)
oAccrualData.Fields.Item("NOMINAL_CODE_1").Value
                                = CStr("0010")

' Write the record
If oAccrualData.Write(CShort(oAccrualData.Count
                                  + 1)) Then

MsgBox("Posting has been
                                  Successful", MsgBoxStyle.OKOnly, "SDO EXample")

Else

MsgBox("Posting
                                  Failed", MsgBoxStyle.OKOnly, "SDO EXample")

End If

End If

End If

' Disconnect
oWS.Disconnect()

' Destroy Objects
oAccrualData = Nothing
oControlData = Nothing
oNominalData = Nothing
oWS = Nothing
oSDO = Nothing

Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.AccrualData oAccrualData;

SageDataObject300.ControlData oControlData;

SageDataObject300.NominalData oNominalData;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate Objects

  oAccrualData = (SageDataObject300.AccrualData)oWS.CreateObject("AccrualData");

  oControlData = (SageDataObject300.ControlData)oWS.CreateObject("ControlData");

  oNominalData = (SageDataObject300.NominalData)oWS.CreateObject("NominalData");

  //Read Control Data

  //for the default accruals nominal code

  oControlData.Read(1);

  //Read the nominal using the default accruals code

  oNominalData.Read((Int32)SDOHelper.Read(oControlData, "ACCRUALS_NO"));

  //Populate the fields

  SDOHelper.Write(oAccrualData, "NAME", (String)"SDO Generated Accrual");

  SDOHelper.Write(oAccrualData, "AMOUNT", (Double)1200);

  SDOHelper.Write(oAccrualData, "DEPT_NUMBER", (Int16)0);

  SDOHelper.Write(oAccrualData, "MONTHS_TO_POST", (Int16)3);

  SDOHelper.Write(oAccrualData, "MONTHS_POSTED", (Int16)0);

  SDOHelper.Write(oAccrualData, "NOMINAL_CODE_2",

    (String)SDOHelper.Read(oNominalData, "ACCOUNT_REF"));

  SDOHelper.Write(oAccrualData, "NOMINAL_CODE_1", (String)"0010");

  //Write the record

  if (oAccrualData.Write((Int16)oAccrualData.Count() + 1))

  {

    MessageBox.Show("Accrual Created Successfully");

  }

  else

  {

    MessageBox.Show("Accrual Was Not Created");

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Creating a New Charity Fund

Example - Creating a New Charity Fund

The example code below demonstrates how to create a new Charity Fund.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
'Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oCharityFund As SageDataObject300.CharityFund
Dim oCharityFundType As SageDataObject300.CharityFundType
Dim oNominal As SageDataObject300.Nominal

'Declare Variables
Dim szDataPath As String

'Create the SDO Engine object
oSDO = New SageDataObject300.SDOEngine
'Create the workspace
oWS = oSDO.Workspaces.Add("Example")

'Select company. The SelectCompany method takes the program install
'folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")
'A U.I. for company selection is presented to the user. If a company 'is selected,
'the path will be passed to the szDataPath variable.
'If not, or the Cancel button is selected, the variable will be left 'empty.
If szDataPath <> "" Then

'Connect to Data Files
 If oWS.Connect(szDataPath, "", "", "Example") Then

'Create Objects
oCharityFund = oWS.CreateCharityFund
oCharityFundType = oWS.CreateCharityFundType
oNominal = oWS.CreateNominal

'Set properties
oCharityFund.Contact = CStr("Paul")
oCharityFund.Description = CStr("Fund Description")
oCharityFund.HeldBy = CStr("Institution")

'Load and set Fund Type: 1 = Unrestricted, 2 = Restricted, 3 = Endowed
oCharityFundType.Load(1)
oCharityFund.FundType = oCharityFundType

'Set Nominal Code
oNominal.Load("4000")
oCharityFund.Nominal = oNominal
'Update the record
 If oCharityFund.Update Then

MsgBox("Fund Posted Successfully", MsgBoxStyle.OKOnly, "SDO Examples")

Else

MsgBox("Fund Not Posted", MsgBoxStyle.OKOnly, "SDO Examples")

End If

'Disconnect
oWS.Disconnect()
End If

 End If

'Destroy Objects
oCharityFund = Nothing
oCharityFundType = Nothing
oNominal = Nothing
oWS = Nothing
oSDO = Nothing

Exit Sub
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.CharityFund oCharityFund;
SageDataObject300.CharityFundType oCharityFundType;
SageDataObject300.Nominal oNominal;

String szDataPath;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try
{
    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

    //Instantiate Country Code Record
    oCharityFund = (SageDataObject300.CharityFund)oWS.CreateCharityFund();
    oCharityFundType = (SageDataObject300.CharityFundType)oWS.CreateCharityFundType();
    oNominal = (SageDataObject300.Nominal)oWS.CreateNominal();

    //Set properties
    oCharityFund.Contact = (String)"Pete";
    oCharityFund.Description = (String)"Fund Description";
    oCharityFund.HeldBy = (String)"Institution";

    //Load and set Fund Type: 1 = Unrestricted, 2 = Restricted, 3 = Endowed
    Object ofundType = 1;
    oCharityFundType.Load(ref ofundType);
    oCharityFund.FundType = oCharityFundType;

    //Set Nominal Code
    Object oNominalCode = 4000;
    oNominal.Load(ref oNominalCode);
    oCharityFund.Nominal = oNominal;

    //Update the record
    if (oCharityFund.Update())
    {
         MessageBox.Show("Fund Posted Successfully");
    }
else
    {
        MessageBox.Show("Fund not posted");
    }

    //Disconnect
    oWS.Disconnect();
}

catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}


Sage 50 Accounts - Example - Creating a New Nominal Account

Example - Creating a New Nominal Account

The example code below demonstrates how to create a new Nominal Account.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oNominalRecord As SageDataObject300.NominalRecord

' Declare Variables
Dim szDataPath As String

' Create the SDO Engine object
oSDO = New SageDataObject300.SDOEngine
' Create the workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")
' A U.I. for company selection is presented to the user. If a company 'is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left 'empty.
If szDataPath <> "" Then

' Connect to Data Files
 If oWS.Connect(szDataPath, "", "", "Example") Then

' Create instance on NominalRecord object
 oNominalRecord = oWS.CreateObject("NominalRecord")

' Call the AddNew method
oNominalRecord.AddNew()

' Populate fields
 oNominalRecord.Fields.Item("ACCOUNT_REF").Value = CStr("0001")
oNominalRecord.Fields.Item("NAME").Value = CStr("SDO Created Nominal Code")
oNominalRecord.Fields.Item("ACCOUNT_TYPE").Value = CByte(SageDataObject300.NominalType.sdoTypeNormal)

' Update the record
If oNominalRecord.Update Then

MsgBox("Record Posted Successfully", MsgBoxStyle.OKOnly, "SDO Examples")

Else

MsgBox("Record Not Posted", MsgBoxStyle.OKOnly, "SDO Examples")

 End If

' Disconnect
oWS.Disconnect()

End If

 End If

' Destroy Objects
oNominalRecord = Nothing
oWS = Nothing
oSDO = Nothing

Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.NominalRecord oNominalRecord;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate the Nominal Record object

  oNominalRecord = (SageDataObject300.NominalRecord)oWS.CreateObject("NominalRecord");

  //Call the AddNew Method

  oNominalRecord.AddNew();

  //Populate Fields

  SDOHelper.Write(oNominalRecord, "ACCOUNT_REF", (String)"0001");

  SDOHelper.Write(oNominalRecord, "NAME", (String)"SDO Created Nominal");

  SDOHelper.Write(oNominalRecord, "ACCOUNT_TYPE", (Byte)SageDataObject300.NominalType.sdoTypeNormal);

  //Update the record

  if (oNominalRecord.Update())

  {

    MessageBox.Show("Record Created Successfully");

  }

  else

  {

    MessageBox.Show("Failed to Create Record");

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Creating a New Prepayment Record

Example - Creating a New Prepayment Record

The example code below demonstrates how to create a new Prepayment Record.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
 Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oPrepayData As SageDataObject300.PrepayData
Dim oControlData As SageDataObject300.ControlData
Dim oNominalData As SageDataObject300.NominalData

' Declare Variables
 Dim szDataPath As String

' Create the SDO Engine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install
' folder as a parameter
 szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

 ' A U.I. for company selection is presented to the user. If a company is 'selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left 'empty.
If szDataPath <> "" Then

' Connect to Data Files
If oWS.Connect(szDataPath, "", "", "Example") Then

' Create Instances of Objects
oPrepayData = oWS.CreateObject("PrepayData")
oControlData = oWS.CreateObject("ControlData")
oNominalData = oWS.CreateObject("NominalData")

' Read Control Data
' for Default Prepayment Nominal Code
oControlData.Read(1)

' Now read Nominal using the default prepayment code
 oNominalData.Read(CInt(oControlData.Fields.Item("PREPAYMENTS_NO").Value))

' Populate the fields
oPrepayData.Fields.Item("NAME").Value = CStr("SDO Generated Prepayment")
oPrepayData.Fields.Item("AMOUNT").Value = CDbl(1200#)
 oPrepayData.Fields.Item("DEPT_NUMBER").Value = CShort(0)
 oPrepayData.Fields.Item("MONTHS_TO_POST").Value = CShort(3)
 oPrepayData.Fields.Item("MONTHS_POSTED").Value = CShort(0)
 oPrepayData.Fields.Item("NOMINAL_CODE_2").Value = CStr(oNominalData.Fields.Item("ACCOUNT_REF").Value)
oPrepayData.Fields.Item("NOMINAL_CODE_1").Value = CStr("0010")

' Write the record
 If oPrepayData.Write(CShort(oPrepayData.Count + 1)) Then

MsgBox("Posting has been Successful", MsgBoxStyle.OKOnly, "SDO Example")

Else

MsgBox("Posting Failed", MsgBoxStyle.OKOnly, "SDO Example")

End If

' Disconnect
oWS.Disconnect()

End If
End If

 ' Destroy Objects
oPrepayData = Nothing
oControlData = Nothing
oNominalData = Nothing
oWS = Nothing
 oSDO = Nothing

Exit Sub
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.PrepayData oPrepayData;
SageDataObject300.ControlData oControlData;
SageDataObject300.NominalData oNominalData;

String szDataPath;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try
{
    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

    //Instantiate Country Code Record
    oPrepayData = (SageDataObject300.PrepayData)oWS.CreateObject("PrepayData");
    oControlData = (SageDataObject300.ControlData)oWS.CreateObject("ControlData");
    oNominalData = (SageDataObject300.NominalData)oWS.CreateObject("NominalData");

    //Read Control Data
    //For Default Prepayment Nominal Code
    oControlData.Read(1);

    //Now read Nominal using the default prepayment code
    oNominalData.Read((Int32)(SDOHelper.Read(oControlData, "PREPAYMENTS_NO")));

    //Populate the fields
    SDOHelper.Write(oPrepayData, "NAME", (String)"SDO Genereated Prepayment");
    SDOHelper.Write(oPrepayData, "AMOUNT", Convert.ToDouble("1200"));
    SDOHelper.Write(oPrepayData, "DEPT_NUMBER", (Int16)0);
    SDOHelper.Write(oPrepayData, "MONTHS_TO_POST", (Int16)3);
    SDOHelper.Write(oPrepayData, "MONTHS_POSTED", (Int16)0);
    SDOHelper.Write(oPrepayData, "NOMINAL_CODE_2", (String)SDOHelper.Read(oNominalData, "ACCOUNT_REF"));
    SDOHelper.Write(oPrepayData, "NOMINAL_CODE_1", (String)"0010");

    //Write the record

    if (oPrepayData.Write((Int16)oPrepayData.Count() + 1))
    {
        MessageBox.Show("Psoting has been Successfull", "SDO Example");
    }
    else
    {
        MessageBox.Show("Posting failed", "SDO Example");
    }

    //Disconnect
    oWS.Disconnect();
}

catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}


Sage 50 Accounts - Example - Posting Journal Entries

Example - Posting Journal Entries

The example code below demonstrates how to post Journal Entries using the TransactionPost object. Since the release of Sage 50 Accounts 2015 an object has been created(JOURNALPOST) specifically for posting journal transactions. Apart from the Nominal Codes in use this is identical to a Bank Transfer.

Note: There is no Rollback or Commit in SDO so, if something interrupts this process, you can end up with a one sided entry in your Accounts program. If this does happen you will need to deliberately post a one sided journal entry to correct any error.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
                                'Declare Objects
Dim oSDO As
                              SageDataObject300.SDOEngine
Dim oWS As
                              SageDataObject300.WorkSpace
Dim oTransactionPost As
                              SageDataObject300.TransactionPost
Dim oSplitData As
                              SageDataObject300.SplitData

' Declare Variables
Dim bFlag As
                                Boolean
Dim szDataPath As
                                String

' Create the SDO Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the
                                  program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user.
                                  If a company is 'selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left
                              'empty.
If szDataPath <> "" Then

' Connect to Data Files
oWS.Connect(szDataPath, "", "", "Example")

' Create Instances of Objects
oTransactionPost =
                                oWS.CreateObject("TransactionPost")

' Populate Header fields

' Note:
' You must ensure the Bank_Code field on the header
' is the same as the Nominal_Code on the split
oTransactionPost.Header("BANK_CODE").Value = CStr("2200")
oTransactionPost.Header("DATE").Value = CDate(Today)
oTransactionPost.Header("POSTED_DATE").Value =
                                CDate(Today)
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoJD)
oTransactionPost.Header("DETAILS").Value = CStr("SDO
                                Journal Entry")
oTransactionPost.Header("INV_REF").Value = CStr("SDO")

' Note:
' A JC and JD only have 1 split

' Add a split to the Header Item's collection
oSplitData = oTransactionPost.Items.Add

' Populate Split Fields
oSplitData.Fields.Item("TYPE").Value =
                                oTransactionPost.Header("TYPE").Value
oSplitData.Fields.Item("NOMINAL_CODE").Value =
                                CStr(oTransactionPost.Header("BANK_CODE").Value)
oSplitData.Fields.Item("TAX_CODE").Value = CShort(9)
oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(100)
oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(0)
oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)
oSplitData.Fields.Item("DETAILS").Value = CStr(oTransactionPost.Header("DETAILS").Value)

' Update the TransactionPost object
If oTransactionPost.Update
                                Then

MsgBox("Transaction Posted Successfully",
                                MsgBoxStyle.OKOnly, "SDO Examples")

Else

MsgBox("Transaction Posting Failed",
                                MsgBoxStyle.OKOnly, "SDO Examples")

End If

' Destroy Objects
oTransactionPost = Nothing
oSplitData = Nothing

' Create Instances of Objects
oTransactionPost = oWS.CreateObject("TransactionPost")

' Populate Header fields

' Note:
' You must ensure the Bank_Code field on the header
' is the same as the Nominal_Code on the split

oTransactionPost.Header("BANK_CODE").Value = CStr("2202")
oTransactionPost.Header("DATE").Value = CDate(Today)
oTransactionPost.Header("POSTED_DATE").Value =
                                CDate(Today)
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoJC)
oTransactionPost.Header("DETAILS").Value = CStr("SDO
                                Journal Entry")
oTransactionPost.Header("INV_REF").Value = CStr("SDO")

' Note:
' A JC and JD only have 1 split

' Add a split to the Header Item's collection
oSplitData = oTransactionPost.Items.Add

' Populate Split Fields
oSplitData.Fields.Item("TYPE").Value =
                                oTransactionPost.Header("TYPE").Value
oSplitData.Fields.Item("NOMINAL_CODE").Value =
                                CStr(oTransactionPost.Header("BANK_CODE").Value)
oSplitData.Fields.Item("TAX_CODE").Value = CShort(9)
oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(100)
oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl
                                  (0)
oSplitData.Fields.Item("DATE").Value
                                  = CDate (oTransactionPost.Header("DATE").Value)
oSplitData.Fields.Item("DETAILS").Value =
                                      CStr (oTransactionPost.Header("DETAILS").Value)

' Update the TransactionPost object
If oTransactionPost.Update
                                        Then

MsgBox("Transaction
                                          Posted Successfully", MsgBoxStyle.OKOnly, "SDO Examples")

Else

MsgBox("Transaction
                                          Posting Failed", MsgBoxStyle.OKOnly, "SDO Examples")

End If

'
                                          Disconnect
oWS.Disconnect

End If

'

                                                Destroy Objects
oTransactionPost = Nothing
oSplitData =Nothing
oSDO = Nothing
oWS = Nothing

Exit Sub
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.TransactionPost oTransactionPost;
            SageDataObject300.SplitData oSplitData;

            try
            {
                // Instantiate the TransactionPost object
                oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

                // Populate the Header Fields

                // Note:
                //   You must ensure the NOMINAL_CODE field on the header (actually called BANK_CODE)
                //   is the same as the NOMINAL_CODE on the split
                SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);
                SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);
                SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoJC);
                SDOHelper.Write(oTransactionPost.Header, "DETAILS", (String)"SDO Journal Entry");
                SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"SDO");
                SDOHelper.Write(oTransactionPost.Header, "BANK_CODE", (String)"2200");

                // Create a split item by adding an empty split to the items
                //   Collection of the TransactionPost object
                oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                // Fill in the split fields - note JC's and JD's only have one split
                SDOHelper.Write(oSplitData, "TYPE", Convert.ToByte(SDOHelper.Read(oTransactionPost.Header, "TYPE")));
                SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)SDOHelper.Read(oTransactionPost.Header, "BANK_CODE"));
                SDOHelper.Write(oSplitData, "TAX_CODE", (Int32)9);
                SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)100);
                SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)0);
                SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));
                SDOHelper.Write(oSplitData, "DETAILS", (String)SDOHelper.Read(oTransactionPost.Header, "DETAILS"));

                // Update the Transaction Post object
                //   if it updates then post the 2nd part of the Journal Entry
                if (oTransactionPost.Update())
                {
                    // Destroy objects
                    oTransactionPost = null;
                    oSplitData = null;

                    // Instantiate the TransactionPost object
                    oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

                    // Note:
                    //   You must ensure the NOMINAL_CODE field on the header (actually called BANK_CODE)
                    //   is the same as the NOMINAL_CODE on the split
                    SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);
                    SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);
                    SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoJD);
                    SDOHelper.Write(oTransactionPost.Header, "DETAILS", (String)"SDO Journal Entry");
                    SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"SDO");
                    SDOHelper.Write(oTransactionPost.Header, "BANK_CODE", (String)"2202");

                    // Create a split item by adding an empty split to the items
                    //   Collection of the TransactionPost object
                    oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                    // Fill in the split fields - note JC's and JD's only have one split
                    SDOHelper.Write(oSplitData, "TYPE", Convert.ToByte(SDOHelper.Read(oTransactionPost.Header, "TYPE")));
                    SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)SDOHelper.Read(oTransactionPost.Header, "BANK_CODE"));
                    SDOHelper.Write(oSplitData, "TAX_CODE", (Int32)9);
                    SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)100);
                    SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)0);
                    SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));
                    SDOHelper.Write(oSplitData, "DETAILS", (String)SDOHelper.Read(oTransactionPost.Header, "DETAILS"));

                    // Post this part too
                    if (oTransactionPost.Update())
                    {
                        MessageBox.Show("Transactions Posted successfully", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    }
                    else
                    {
                        MessageBox.Show("Transactions Failed To Post", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }

                // Disconnect
                oWS.Disconnect();
            }
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Reading Financial Budgets

Example - Reading Financial Budgets

The example code below demonstrates how to read financial budgets using FinancialBudget business objects.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oFinancialBudget As SageDataObject300.FinBudget
Dim oFinancialBudgets As SageDataObject300.FinBudgets
Dim oDepartment As SageDataObject300.Department
Dim oNominal As SageDataObject300.Nominal
Dim lvItem As ListViewItem
Dim szDataPath As String

' Create SDO Engine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
 oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

' Connect to Data Files
If oWS.Connect(szDataPath, "", "", "SDO Examples") Then

' Create Business Objects
 oFinancialBudget = oWS.CreateFinancialBudget
oFinancialBudgets = oWS.CreateFinancialBudgets
oDepartment = oWS.CreateDepartment
oNominal = oWS.CreateNominal

' If there is more than 1 transaction
If oFinancialBudgets.Count > 0 Then

' Add the columns to the ListView
Me.listView.Columns.Clear()
Me.ListView.Columns.Add("Dept No", 60, HorizontalAlignment.Left)
Me.ListView.Columns.Add("Dept Name", 100, HorizontalAlignment.Left)
Me.ListView.Columns.Add("Nom Code", 80, HorizontalAlignment.Left)
Me.ListView.Columns.Add("Nomimal Cat", 80, HorizontalAlignment.Left)
Me.ListView.Columns.Add("Budget", 80, HorizontalAlignment.Left)
Me.ListView.Columns.Add("Actual", 80, HorizontalAlignment.Left)
Me.ListView.Columns.Add("Period", 70, HorizontalAlignment.Left)
Me.ListView.Columns.Add("Details", 50, HorizontalAlignment.Left)
Me.ListView.Columns.Add("Year", 50, HorizontalAlignment.Left)
Me.ListView.Items.Clear()

' For each Financial Budget, add details to listview
For Each oFinancialBudget In oFinancialBudgets

oDepartment = oFinancialBudget.Department
oNominal = oFinancialBudget.Nominal

lvItem = New ListViewItem

lvItem.Text = oDepartment.DepartmentID
lvItem.SubItems.Add(oDepartment.Name)
lvItem.SubItems.Add(oNominal.Reference)
lvItem.SubItems.Add(oFinancialBudget.NomCategory)
lvItem.SubItems.Add(oFinancialBudget.Budget)
lvItem.SubItems.Add(oFinancialBudget.Actual)
lvItem.SubItems.Add(oFinancialBudget.Period)
lvItem.SubItems.Add(oFinancialBudget.Year)

Me.ListView.Items.Add(lvItem)

Next

End If

' Disconnect from workspace object
oWS.Disconnect()

End If
End If

' Destroy Objects
szDataPath = Nothing
oDepartment = Nothing
oNominal = Nothing
lvItem = Nothing
oFinancialBudget = Nothing
oFinancialBudgets = Nothing
oWS = Nothing
oSDO = Nothing

Exit Sub
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare objects
            SageDataObject300.FinBudgets oFinancialBudgets;
            SageDataObject300.Department oDepartment;
            SageDataObject300.Nominal oNominal;
            ListViewItem lvItem;

            try
            {
                // Create Business Objects
                oFinancialBudgets = (SageDataObject300.FinBudgets)oWS.CreateFinancialBudgets();
                oDepartment = (SageDataObject300.Department)oWS.CreateDepartment();
                oNominal = (SageDataObject300.Nominal)oWS.CreateNominal();

                                // If there is more than 1 transaction
                if (oFinancialBudgets.Count > 0)
                {
                    // Clear the listView
                    this.listView.Items.Clear();

                    // For each Financial Budget, add details to listview
                    foreach (SageDataObject300.FinBudget oFinancialBudget in oFinancialBudgets)
                    {
                        oDepartment = (SageDataObject300.Department)oFinancialBudget.Department;
                        oNominal = (SageDataObject300.Nominal)oFinancialBudget.Nominal;

                        lvItem = new ListViewItem();

                        lvItem.Text = oDepartment.DepartmentID.ToString();
                        lvItem.SubItems.Add(oDepartment.Name);
                        lvItem.SubItems.Add(oNominal.Reference);
                        lvItem.SubItems.Add(oFinancialBudget.NomCategory.ToString());
                        lvItem.SubItems.Add(oFinancialBudget.Budget.ToString());
                        lvItem.SubItems.Add(oFinancialBudget.Actual.ToString());
                        lvItem.SubItems.Add(oFinancialBudget.Period.ToString());
                        lvItem.SubItems.Add(oFinancialBudget.Year.ToString());

                        this.listView.Items.Add(lvItem);
                    }
                }

                // Disconnect
                oWS.Disconnect();
            }
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Reading the Chart of Accounts

Example - Reading the Chart of Accounts

The example code below demonstrates how to read the Chart of Accounts.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oChartData As SageDataObject300.ChartData
Dim oCategory As SageDataObject300.Category

' Declare Variables
Dim szDataPath As String
 Dim bFlag As Boolean
Dim iCategoryCount As Short

' Create the SDO Engine object
oSDO = New SageDataObject300.SDOEngine
' Create the workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is 'selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left 'empty.
If szDataPath <> "" Then

' Connect to Data Files
If oWS.Connect(szDataPath, "", "", "Example") Then

' Create objects
oChartData = oWS.CreateObject("ChartData")
oCategory = oWS.CreateObject("Category")

oChartData.Read(1)
txtChartName.Text = oChartData.Fields.Item("CHART_NAME").Value

' Populate Category Headings
lblSales.Text = oChartData.Fields.Item("NAME_SALES").Value
lblPurchases.Text = oChartData.Fields.Item("NAME_PURCHASE").Value
lblExpenses.Text = oChartData.Fields.Item("NAME_EXPENSE").Value
lblOverheads.Text = oChartData.Fields.Item("NAME_OVERHEADS").Value
lblFixedAssets.Text = oChartData.Fields.Item("NAME_FIXED_ASSETS").Value
lblCurrentAssets.Text = oChartData.Fields.Item("NAME_CURRENT_ASSETS").Value
lblLongTermLiabilities.Text = oChartData.Fields.Item("NAME_LONG_TERM_LIABILITIES").Value
lblCurrentLiabilities.Text = oChartData.Fields.Item("NAME_CURRENT_LIABILITIES").Value

' Populate Sales Categories List, first 80 records
For iCategoryCount = 1 To 80
oCategory.Read(iCategoryCount)
If oCategory.Fields.Item("NAME").Value <> "" Then

lstSales.Items.Add(oCategory.Fields.Item("NAME").Value & vbTab & vbTab & oCategory.Fields.Item("LOW").Value & " - " & oCategory.Fields.Item("HIGH").Value)

End If

Next iCategoryCount
' Populate Purchase Categories list, Record 81 to 160
For iCategoryCount = 81 To 160
oCategory.Read(iCategoryCount)

If oCategory.Fields.Item("NAME").Value <> "" Then

lstPurchase.Items.Add(oCategory.Fields.Item("NAME").Value & vbTab & vbTab & oCategory.Fields.Item("LOW").Value & " - " & oCategory.Fields.Item("HIGH").Value)

End If

Next iCategoryCount
' Populate Expenses Categories list, Records 161 to 240
For iCategoryCount = 161 To 240
oCategory.Read(iCategoryCount)
If oCategory.Fields.Item("NAME").Value <> "" Then

lstDirectExpenses.Items.Add(oCategory.Fields.Item("NAME").Value & vbTab & vbTab & oCategory.Fields.Item("LOW").Value & " - " & oCategory.Fields.Item("HIGH").Value)

End If

Next iCategoryCount

'Populate Overhead Categories list, Records 241 to 320
For iCategoryCount = 241 To 320
oCategory.Read(iCategoryCount)
If oCategory.Fields.Item("NAME").Value <> "" Then

lstOverheads.Items.Add(oCategory.Fields.Item("NAME").Value & vbTab & vbTab & oCategory.Fields.Item("LOW").Value & " - " & oCategory.Fields.Item("HIGH").Value)

End If

Next iCategoryCount

' Populate Fixed Asset Categories list, Records 321 to 400
For iCategoryCount = 321 To 400
oCategory.Read(iCategoryCount)

If oCategory.Fields.Item("NAME").Value <> "" Then

lstFixedAssets.Items.Add(oCategory.Fields.Item("NAME").Value & vbTab & vbTab & oCategory.Fields.Item("LOW").Value & " - " & oCategory.Fields.Item("HIGH").Value)

End If

Next iCategoryCount

' Populate Current Asset Categories, Record 401 to 480
For iCategoryCount = 401 To 480
oCategory.Read(iCategoryCount)

If oCategory.Fields.Item("NAME").Value <> "" Then

lstCurrentAssets.Items.Add(oCategory.Fields.Item("NAME").Value & vbTab & vbTab & oCategory.Fields.Item("LOW").Value & " - " & oCategory.Fields.Item("HIGH").Value)
End If

Next iCategoryCount

'Populate Current Liabilities Categories, Records 481 to 560
For iCategoryCount = 481 To 560
oCategory.Read(iCategoryCount)

If oCategory.Fields.Item("NAME").Value <> "" Then
lstCurrentLiabilities.Items.Add(oCategory.Fields.Item("NAME").Value & vbTab & vbTab & oCategory.Fields.Item("LOW").Value & " - " & oCategory.Fields.Item("HIGH").Value)

End If
Next iCategoryCount

'Populate Long Term Liabilities Categories, Record 561 to 640
For iCategoryCount = 561 To 640
oCategory.Read(iCategoryCount)

If oCategory.Fields.Item("NAME").Value <> "" Then
lstLongTermLiabilities.Items.Add(oCategory.Fields.Item("NAME").Value & vbTab & vbTab & oCategory.Fields.Item("LOW").Value & " - " & oCategory.Fields.Item("HIGH").Value)

End If

Next iCategoryCount

' Disconnect
oWS.Disconnect()

End If
End If

' Destroy Objects
oChartData = Nothing
oCategory = Nothing
oSDO = Nothing
oWS = Nothing

Exit Sub
C#.NET [image] Copy C# Code
           //Declare Variables

           SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
           SageDataObject300.WorkSpace oWS;
           SageDataObject300.ChartData oChartData;
           SageDataObject300.Category oCategory;

           String szDataPath;

           //Instantiate WorkSpace
           oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

           //Show select company dialog
           szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

           //Try a connection, will throw an exception if it fails

           try
           {

               //Leaving the username and password blank generates a login dialog
               oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

               //Instantiate Delivery Record
               oChartData = (SageDataObject300.ChartData)oWS.CreateObject("ChartData");
               oCategory = (SageDataObject300.Category)oWS.CreateObject("Category");

               oChartData.Read(1);
               txtChartname.Text = Convert.ToString(SDOHelper.Read(oChartData, "CHART_NAME"));

               //Populate Category Headings
               lblSales.Text = Convert.ToString(SDOHelper.Read(oChartData, "NAME_SALES"));
               lblPurchase.Text = Convert.ToString(SDOHelper.Read(oChartData, "NAME_PURCHASE"));
               lblExpenses.Text = Convert.ToString(SDOHelper.Read(oChartData, "NAME_EXPENSE"));
               lblOverheads.Text = Convert.ToString(SDOHelper.Read(oChartData, "NAME_OVERHEADS"));
               lblFixedAssets.Text = Convert.ToString(SDOHelper.Read(oChartData, "NAME_FIXED_ASSETS"));
               lblCurrentAssets.Text = Convert.ToString(SDOHelper.Read(oChartData, "NAME_CURRENT_ASSETS"));
               lblLongtermliabilities.Text = Convert.ToString(SDOHelper.Read(oChartData, "NAME_LONG_TERM_LIABILITIES"));
               lblCurrentLiabilities.Text = Convert.ToString(SDOHelper.Read(oChartData, "NAME_CURRENT_LIABILITIES"));

               Int32 iCategoryCount;

               //Populate Sales Categories List, First 80 records
            for (iCategoryCount = 1; iCategoryCount <= 80; iCategoryCount++)
            {
                oCategory.Read(iCategoryCount);

                    if (Convert.ToString(SDOHelper.Read(oCategory, "NAME")) != "")
                    {
                        lstSales.Items.Add(Convert.ToString(SDOHelper.Read(oCategory, "NAME")) + (char)9 + SDOHelper.Read(oCategory, "LOW") +
                        " - " + SDOHelper.Read(oCategory, "HIGH"));
                    }
            }

            //Populate Purchase Categories list, Record 81 to 160
            for (iCategoryCount = 81; iCategoryCount <= 160; iCategoryCount++)
            {
                oCategory.Read(iCategoryCount);

                if (Convert.ToString(SDOHelper.Read(oCategory, "NAME")) != "")
                {
                    lstPurchase.Items.Add(Convert.ToString(SDOHelper.Read(oCategory, "NAME")) + (char)9 + SDOHelper.Read(oCategory, "LOW") +
                    " - " + SDOHelper.Read(oCategory, "HIGH"));
                }
            }

            //Populate Expenses Categories list, Records 161 to 240
            for (iCategoryCount = 161; iCategoryCount <= 240; iCategoryCount++)
            {
                oCategory.Read(iCategoryCount);

                if (Convert.ToString(SDOHelper.Read(oCategory, "NAME")) != "")
                {
                    lstDirectExpenses.Items.Add(Convert.ToString(SDOHelper.Read(oCategory, "NAME")) + (char)9 + SDOHelper.Read(oCategory, "LOW") +
                    " - " + SDOHelper.Read(oCategory, "HIGH"));
                }
            }

            //'Populate Overhead Categories list, Records 241 to 320
            for (iCategoryCount = 241; iCategoryCount <= 320; iCategoryCount++)
            {
                oCategory.Read(iCategoryCount);

                if (Convert.ToString(SDOHelper.Read(oCategory, "NAME")) != "")
                {
                    lstOverheads.Items.Add(Convert.ToString(SDOHelper.Read(oCategory, "NAME")) + (char)9 + SDOHelper.Read(oCategory, "LOW") +
                    " - " + SDOHelper.Read(oCategory, "HIGH"));
                }
            }

            //Populate Fixed Asset Categories list, Records 321 to 400
            for (iCategoryCount = 321; iCategoryCount <= 400; iCategoryCount++)
            {
                oCategory.Read(iCategoryCount);

                if (Convert.ToString(SDOHelper.Read(oCategory, "NAME")) != "")
                {
                    lstFixedAssets.Items.Add(Convert.ToString(SDOHelper.Read(oCategory, "NAME")) + (char)9 + SDOHelper.Read(oCategory, "LOW") +
                    " - " + SDOHelper.Read(oCategory, "HIGH"));
                }
            }

            //Populate Current Asset Categories, Record 401 to 480
            for (iCategoryCount = 401; iCategoryCount <= 480; iCategoryCount++)
            {
                oCategory.Read(iCategoryCount);

                if (Convert.ToString(SDOHelper.Read(oCategory, "NAME")) != "")
                {
                    lstCurrentAssets.Items.Add(Convert.ToString(SDOHelper.Read(oCategory, "NAME")) + (char)9 + SDOHelper.Read(oCategory, "LOW") +
                    " - " + SDOHelper.Read(oCategory, "HIGH"));
                }
            }

            //'Populate Current Liabilities Categories, Records 481 to 560
            for (iCategoryCount = 481; iCategoryCount <= 560; iCategoryCount++)
            {
                oCategory.Read(iCategoryCount);

                if (Convert.ToString(SDOHelper.Read(oCategory, "NAME")) != "")
                {
                    lstCurrentliabilities.Items.Add(Convert.ToString(SDOHelper.Read(oCategory, "NAME")) + (char)9 + SDOHelper.Read(oCategory, "LOW") +
                    " - " + SDOHelper.Read(oCategory, "HIGH"));
                }
            }

            //'Populate Long Term Liabilities Categories, Record 561 to 640
            for (iCategoryCount = 561; iCategoryCount <= 640; iCategoryCount++)
            {
                oCategory.Read(iCategoryCount);

                if (Convert.ToString(SDOHelper.Read(oCategory, "NAME")) != "")
                {
                    lstlongtermliabilities.Items.Add(Convert.ToString(SDOHelper.Read(oCategory, "NAME")) + (char)9 + SDOHelper.Read(oCategory, "LOW") +
                    " - " + SDOHelper.Read(oCategory, "HIGH"));
                }
            }

               //Disconnect
               oWS.Disconnect();
           }

           catch (Exception ex)
           {
               MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
           }


Sage 50 Accounts - Example - Reading Information from Different Charts Of Accounts

Example - Reading Information from Different Charts Of Accounts

The example code below demonstrates how to read information from any chart of account.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
'Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace

Dim oChartdata As SageDataObject300.ChartData
Dim oCategory As SageDataObject300.Category

'Declare Variables
Dim szDataPath As String

'Create the SDOEngine Object
oSDO = New SageDataObject300.SDOEngine

'Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

'Select Company. The SelectCompany method takes the program install
'folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

'A U.I. for company selection is presented to the user. If a company is selected,
'the path will be passed to the szDataPath variable.
'If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

'Try to Connect - Will Throw an Exception if it Fails
If oWS.Connect(szDataPath, "", "", "Example") Then
'Create ChartData object
'The CreateObject on the oCategory line is not needed as GetChart method will populate the object
oChartdata = oWS.CreateObject("ChartData")

'The GetChart method takes a one-based index and implies the X.COA file
'Example here - we'll read data from 3.COA
oCategory = oChartdata.GetChart(3)

'There are 720 values in each Category record - 80 types (Name, Low, High) for each
'9 category accounts (Sales, Purchases, Overheads etc)
'Hence, if you want the yth category type's information in the nth category account,
'then read value (80(n-1) + y)

 'This loop will show all values for all of the categories within 3.COA
For oValue As Integer = 1 To 720

oCategory.Read(oValue)

Debug.WriteLine(CStr (oCategory.Fields.Item("NAME").Value))
Debug.WriteLine(CStr (oCategory.Fields.Item("LOW").Value))
Debug.WriteLine(CStr (oCategory.Fields.Item("HIGH").Value))

Next oValue

'Disconnect
oWS.Disconnect()

End If

End If

'Destroy the Objects
oWS = Nothing
oSDO = Nothing

Exit Sub
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.ChartData oChartData;
            SageDataObject300.Category oCategory;

            try
            {
                /* Create ChartData object
                     CreateObject on oCategory is not needed because GetChart() will populate the object */
                oChartData = (SageDataObject300.ChartData)oWS.CreateObject("ChartData");

                /* The GetChart method takes a one-based index and implies the X.COA file
                      we'll read data from 3.COA */
                oCategory = (SageDataObject300.Category)oChartData.GetChart((Int16)3);

                /* There are 720 values in each Category record - 80 types (Name, Low, High) for each
                     9 category accounts (Sales, Purchases, Overheads etc)
                     Hence, if you want the yth category type's information in the nth category account,
                     then read value (80(n-1) + y) */

                // This loop will show all values for all of the categories within 3.COA
                for (int oValue = 1; oValue < 721; oValue++)
                {
                    oCategory.Read((int)oValue);

                    Console.WriteLine((String)SDOHelper.Read(oCategory, "NAME") + "\t\t" +
                        (String)SDOHelper.Read(oCategory, "LOW") + "\t" +
                        (String)SDOHelper.Read(oCategory, "HIGH"));
                }

                // Disconnect
                oWS.Disconnect();
            }
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Reading Nominal Budgets using the GetBudget method

Example - Reading Nominal Budgets using the GetBudget method

The example code below demonstrates how to read different budgets for a nominal code using the GetBudget method.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oNominalRecord As SageDataObject300.NominalRecord
Dim oSetupData As SageDataObject300.SetupData

 'Declare Variables
Dim szDataPath As String
Dim Month As Short
 Dim Budget As Double
Dim Msg As String

'Create the SDO Engine object
oSDO = New SageDataObject300.SDOEngine
'Create the workspace
oWS = oSDO.Workspaces.Add("Example")

'Select company. The SelectCompany method takes the program install
'folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")
'A U.I. for company selection is presented to the user. If a company 'is selected,
'the path will be passed to the szDataPath variable.
'If not, or the Cancel button is selected, the variable will be left 'empty.
If szDataPath <> "" Then

'Connect to Data Files
 If oWS.Connect(szDataPath, "", "", "Example") Then

'Create objects
 oNominalRecord = oWS.CreateObject("NominalRecord")
oSetupData = oWS.CreateObject("SetupData")
oSetupData.Read(1)

'Move to the appropriate nominal record
oNominalRecord.Fields.Item("ACCOUNT_REF").Value = "4000"
If Not oNominalRecord.Find(False) Then

MsgBox("Account Not Found", vbOKOnly, "SDO Examples")

'Close SetupData file
oSetupData.Close()
'Disconnect
oWS.Disconnect()
'Destroy Objects
oNominalRecord = Nothing
oSetupData = Nothing
oWS = Nothing
oSDO = Nothing

Exit Sub

End If

'Check to see if BudgetingType is set to Department Overview (sdoDepartment)
'in order to avoid invalid mode exception
If oSetupData.Fields.Item("BUDGETING_TYPE").Value = SageDataObject300.BudgetingType.sdoDepartment Then

MsgBox("Budgeting Type set to Department Overview - GetBudget Method will fail", vbOKOnly, "SDO Examples")

'Close SetupData file
oSetupData.Close()
'Disconnect
oWS.Disconnect()
'Destroy Objects
oNominalRecord = Nothing
oSetupData = Nothing
oWS = Nothing
oSDO = Nothing

Exit Sub

End If

'Cycle through the months for the current year's budget for the nominal code
'When querying current year, can also pass 0 as the second parameter to GetBudget
Msg = "Nominal Budgets for Current Year:" & vbNewLine
For Month = 0 To 11
Budget = oNominalRecord.GetBudget(Month, CInt(oSetupData.Fields.Item("FINYEAR_YEAR").Value))
Msg &= "Month " & Month.ToString & " = �" & Format(Budget, "#,##0.00") & vbNewLine
Next
MsgBox(CStr(Msg))

'Cycle through the months for the forecast budget for the nominal code
Msg = "Nominal Budgets for Next (Forecast) Year:" & vbNewLine
For Month = 0 To 11
Budget = oNominalRecord.GetBudget(Month, CInt(oSetupData.Fields.Item("FINYEAR_YEAR").Value + 1))
Msg &= "Month " & Month.ToString & " = �" & Format(Budget, "#,##0.00") & vbNewLine
Next
MsgBox(CStr(Msg))

'Cycle through the months for the prior year budget for the nominal code
'NB Sage 50 Accounts stores prior year budgets for five years
Msg = "Nominal Budgets for Prior Year:" & vbNewLine
For Month = 0 To 11
Budget = oNominalRecord.GetBudget(Month, CInt(oSetupData.Fields.Item("FINYEAR_YEAR").Value - 1))
Msg &= "Month " & Month.ToString & " = �" & Format(Budget, "#,##0.00") & vbNewLine
Next
MsgBox(CStr(Msg))

'Close SetupData file
oSetupData.Close()

        'Disconnect
        oWS.Disconnect()
     End If

  End If

  'Destroy Objects
  oNominalRecord = Nothing
  oSetupData = Nothing
  oWS = Nothing
  oSDO =Nothing

  Exit Sub
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.NominalRecord oNominalRecord;
            SageDataObject300.SetupData oSetupData;

            // Declare variables
            Int16 Month;
            Double Budget;
            String Msg;

            try
            {
                // Instantiate Objects
                oNominalRecord = (SageDataObject300.NominalRecord)oWS.CreateObject("NominalRecord");
                oSetupData = (SageDataObject300.SetupData)oWS.CreateObject("SetupData");

                // Read SetuData
                oSetupData.Read(1);

                // Move to required Nominal Account
                SDOHelper.Write(oNominalRecord, "ACCOUNT_REF", (String)"4000");
                if (oNominalRecord.Find(false))
                {
                    // Check to see if BudgetingType is set to Department Overview (sdoDepartment)
                    // in order to avoid invalid mode exception
                    if (!(Convert.ToByte(SDOHelper.Read(oSetupData, "BUDGETING_TYPE")) == Convert.ToByte(SageDataObject300.BudgetingType.sdoDepartment)))
                    {
                        // Cycle through the months for the current year's budget for the nominal code
                        // When querying current year, can also pass 0 as the second parameter to GetBudget
                        Msg = "Nominal Budgets for Current Year: \n";
                        for (Month = 0; Month <= 11; Month++)
                        {
                            Budget = oNominalRecord.GetBudget(Month, (Int16)(SDOHelper.Read(oSetupData, "FINYEAR_YEAR")));
                            Msg += "Month " + Month.ToString() + " = £" + (Budget + "\n");
                        }
                        MessageBox.Show(Msg);

                        // Cycle through the months for the forecast budget for the nominal code
                        Msg = "Nominal Budgets for Next (Forecast) Year: \n";
                        for (Month = 0; Month <= 11; Month++)
                        {
                            Int16 nextBudget = (Int16)(SDOHelper.Read(oSetupData, "FINYEAR_YEAR"));

                            Budget = oNominalRecord.GetBudget(Month, (Int16)(nextBudget + 1));
                            Msg += "Month " + Month.ToString() + " = £" + (Budget + "\n");
                        }
                        MessageBox.Show(Msg);

                        // Cycle through the months for the prior year budget for the nominal code
                        // NB Sage 50 Accounts stores prior year budgets for five years
                        Msg = "Nominal Budgets for Prior Year: \n";
                        for (Month = 0; Month <= 11; Month++)
                        {
                            Int16 lastBudget = (Int16)(SDOHelper.Read(oSetupData, "FINYEAR_YEAR"));

                            Budget = oNominalRecord.GetBudget(Month, (Int16)(lastBudget - 1));
                            Msg += "Month " + Month.ToString() + " = £" + (Budget + "\n");
                        }
                        MessageBox.Show(Msg);
                    }
                    else
                    {
                        MessageBox.Show("Budgeting Type set to Department Overview - GetBudget Method will fail", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    }
                }
                else
                {
                    MessageBox.Show("Account not found", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }

                // Close SetupData
                oSetupData.Close();

                // Disconnect
                oWS.Disconnect();
            }
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Reading Nominal Codes

Example - Reading Nominal Codes

The example code below demonstrates how to read nominal codes into a combo box using the NominalRecord object.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim ONomRec As SageDataObject10.NominalRecord
Dim szDataPath As String

'Select company. The SelectCompany method takes the program install
'folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' Create the SDOEngine Object and Workspace.
oSDO = New SageDataObject300.SDOEngine
oWS = oSDO.Workspaces.Add("Example")

' Connects to Company
Try
oWS.Connect(szDataPath, "", "", "Example")
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try

' Create Nominal Object
ONomRec = oWS.CreateObject("NominalRecord")

' Move to first nominal object and iterate through returning Nominal Account Ref (nominal Code)
ONomRec.MoveFirst()

Do
Me.ComboBox1.Items.Add(ONomRec.Fields.Item("ACCOUNT_REF").Value)
Loop Until Not ONomRec.MoveNext

oWS.Disconnect()

' Destroy the Objects
oWS = Nothing
oSDO = Nothing
Exit Sub

C#.NET [image] Copy C# Code

        //Declare Variables

        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

        SageDataObject300.WorkSpace oWS;

        String szDataPath;

        public Form1()

        {

            InitializeComponent();

        }

        private void Form1_Load(object sender, EventArgs e)

        {

            //Instantiate WorkSpace

            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog

            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails

            try

            {

                //Leaving the username and password blank generates a login dialog

                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code

                userDefinedMethod();

            }

            catch (Exception ex)

            {

                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

            }

        }

        private void userDefinedMethod()

        {

            // Declare required objects

            SageDataObject300.NominalRecord oNominalRecord;

            try

            {

                // Instantiate Objects

                oNominalRecord = (SageDataObject300.NominalRecord)oWS.CreateObject("NominalRecord");

                // Move to required Nominal Account

                oNominalRecord.MoveFirst();

                // Populate Combo Box

                for (int i = 0; i < oNominalRecord.Count; i++)

                {

                    comboBox1.Items.Add(SDOHelper.Read(oNominalRecord, "ACCOUNT_REF"));

                    oNominalRecord.MoveNext();

                }

                // Close SetupData

                oNominalRecord = null;

                // Disconnect

                oWS.Disconnect();

            }

            catch (Exception ex)

            {

                // Show the exception error message

                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);

            }

        }// userDefinedMethod

    }// class

}// namespace


Sage 50 Accounts - Example - Creating a New Bank Account Record

Example - Return Nominal Activity

The example code below demonstrates how to return Nominal Split Transactions via a Link List. It is not possible to use the Record object Link method to return the Header or Split Data from the Nominal Record as not every associated transaction will have a HeaderData record. For example, an SI transaction with an ACCOUNT_REF of AAA001 with multiple splits would create a SplitData record for each of the splits on the Nominal Record but the HeaderData record would be linked to the ACCOUNT_REF AAA001.

In order to return the associated Splits of a NominalRecord we must use a Link List which is essentially what the Record object Link method does. By finding the First and Last Split of the NominalRecord we can iterate the collection using the SplitData Next_Nominal.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oNominalRecord As SageDataObject300.NominalRecord
Dim oSplitData As SageDataObject300.SplitData

' Declare Variables
Dim szDataPath As String

' Create the SDOEngine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company.  The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024\")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

    ' Try to Connect - Will Throw an Exception if it Fails
    If oWS.Connect(szDataPath, "", "", "Example") Then

        ' Create an Instance of the NominalRecord Object
        oNominalRecord = oWS.CreateObject("NominalRecord")

        ' Find the Nominal false is a full match
        oNominalRecord.Fields.Item("ACCOUNT_REF").Value = CStr("4000")

        If oNominalRecord.Find(False) Then

            'Instantiate the SplitData object with the Link method
            oSplitData = oWS.CreateObject("SPLITDATA")

            'move to the first split of the Nominal
            oSplitData.Read(CInt(oNominalRecord.Fields.Item("FIRST_SPLIT").Value))

            'Loop through all of the Splits linked to this nominal code
            Do
                'Read the next split of the Link List
                oSplitData.Read(CInt(oSplitData.Fields.Item("NEXT_NOMINAL").Value))

            Loop Until oSplitData.RecordNumber = (oNominalRecord.Fields.Item("LAST_SPLIT").Value)

        End If

        ' Disconnect
        oWS.Disconnect()

    End If

End If

' Destroy the Objects
oWS = Nothing
oSDO = Nothing

Exit Sub
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.NominalRecord oNominalRecord;
SageDataObject300.SplitData oSplitData;

String szDataPath;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails
try
{
    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");
    MessageBox.Show("Connected!");

    //Create an Instance of the NominalRecord object
    oNominalRecord = (SageDataObject300.NominalRecord)(oWS.CreateObject("NOMINALRECORD"));

    //Find the NominalRecord False being a full match
    SDOHelper.Write(oNominalRecord, "ACCOUNT_REF", "4000");

    if (oNominalRecord.Find(false))
    {
        //Instantiate the SplitData object
        oSplitData = (SageDataObject300.SplitData)(oWS.CreateObject("SPLITDATA"));

        //move to the first split of the Nominal
        oSplitData.Read(Convert.ToInt16(SDOHelper.Read(oNominalRecord, "FIRST_SPLIT")));

        //Loop through all of the Splits linked to this account
        do
        {
            //Read the next split of the Link List
            oSplitData.Read(Convert.ToInt16(SDOHelper.Read(oSplitData, "NEXT_NOMINAL")));

        } while (oSplitData.RecordNumber <= Convert.ToInt16(SDOHelper.Read(oNominalRecord, "LAST_SPLIT")));
    }

    //Disconnect
    oWS.Disconnect();
}
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}


Sage 50 Accounts - Example - Accessing a Bank Account Memo

Example - Accessing a Bank Account Memo

The example code below demonstrates how to create a access a Bank Account Memo.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code

        ' Declare Objects         Dim oSDO As SageDataObject300.SDOEngine        Dim oWS As SageDataObject300.WorkSpace        Dim oBankRecord As SageDataObject300.BankRecord        ' Declare Variables         Dim szDataPath As String        ' Create the SDO Engine object        oSDO = New SageDataObject300.SDOEngine        ' Create the workspace         oWS = oSDO.Workspaces.Add("Example")        ' Select company. The SelectCompany method takes the program install        ' folder as a parameter         szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\

")        ' A U.I. for company selection is presented to the user. If a company is selected,        ' the path will be passed to the szDataPath variable.        ' If not, or the Cancel button is selected, the variable will be left empty.         If szDataPath <> "" Then            ' Connect to Data Files             If oWS.Connect(szDataPath, "", "", "Example") Then                ' Create instance on BankRecord object                 oBankRecord = oWS.CreateObject("BankRecord")                ' Add memo to first nominal code.                ' Move to the first record                 oBankRecord.MoveFirst()                ' Edit the record                 oBankRecord.Edit()                ' Populate memo field                 oBankRecord.Memo = CStr("SDO Generated memo")                ' Update the record                 If oBankRecord.Update Then                    ' Record posted successfully                     MsgBox("Memo Saved Successfully", MsgBoxStyle.OkOnly, "SDO Examples")                Else                    ' Record did not post                     MsgBox("Memo Has Not Been Saved", MsgBoxStyle.OkOnly, "SDO Examples")                End If                ' Disconnect & Destroy Objects                 oWS.Disconnect()            End If            ' Read memo             ' Move to first record             oBankRecord.MoveFirst()            ' read memo             MsgBox("Memo for Bank Account " & oBankRecord.Fields.Item("ACCOUNT_REF").Value & " " & "reads : " & oBankRecord.Memo, MsgBoxStyle.OkOnly, "SDO Examples")        End If        oBankRecord = Nothing        oWS = Nothing        oSDO = Nothing

        Exit Sub
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.BankRecord oBankRecord;

            try
            {
                //Instantiate Objects
                oBankRecord = (SageDataObject300.BankRecord)oWS.CreateObject("BankRecord");

                //Read the first Bank Account
                oBankRecord.MoveFirst();

                oBankRecord.Edit();
                oBankRecord.Memo = (String)"Memo text for the first Bank Record";

                //Update the TransactionPost Object
                if (oBankRecord.Update())
                {
                    MessageBox.Show("Memo added Successfully");
                }
                else
                {
                    MessageBox.Show("Memo could not be added");
                }

                //Get the first Bank record and read the memo
                oBankRecord.MoveFirst();
                MessageBox.Show(oBankRecord.Memo);

                // Disconnect
                oWS.Disconnect();
            }
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Creating a New Bank Account Record

Example - Creating a New Bank Account Record

The example code below demonstrates how to create a new Bank Account Record.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Unless you are using a nominal code which already exists, you must create a
' new nominal account before creating the bank account.

' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oBankRecord As SageDataObject300.BankRecord
Dim oNominalRecord As SageDataObject300.NominalRecord

' Declare Variables
Dim szDataPath As String

' Create the SDO Engine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

' Connect to Data Files
If oWS.Connect(szDataPath, "", "", "Example") Then

' Create Instances of Objects
oBankRecord = oWS.CreateObject("BankRecord")
oNominalRecord = oWS.CreateObject("NominalRecord")

' Create the nominal record for the bank account
If (oNominalRecord.AddNew) Then

oNominalRecord.Fields.Item("ACCOUNT_REF").Value = CStr("1291")
oNominalRecord.Fields.Item("NAME").Value = CStr("SDO Bank Account")

' We must set the Nominal ACCOUNT_TYPE field to 2, which denotes a bank account.
oNominalRecord.Fields.Item("ACCOUNT_TYPE").Value = CByte(2)

' Post the Nominal Account
If oNominalRecord.Update Then

MsgBox("Nominal Account Created Successfully", MsgBoxStyle.OKOnly, "SDO Examples")

Else

MsgBox("Nominal Account Was Not Created", MsgBoxStyle.OKOnly, "SDO Examples")

End If

End If

If oBankRecord.AddNew Then

' Populate the fields
' The ACCOUNT_REF field must equal the Nominal Code for the Account
oBankRecord.Fields.Item("ACCOUNT_REF").Value = CStr("1291")
oBankRecord.Fields.Item("NAME").Value = CStr("SDO Bank Account")
oBankRecord.Fields.Item("ACCOUNT_NUMBER").Value = CStr("01234567")
oBankRecord.Fields.Item("ACCOUNT_NAME").Value = CStr("SDO Bank Account")
oBankRecord.Fields.Item("ACCOUNT_TYPE").Value = CByte(1)
oBankRecord.Fields.Item("ADDRESS_1").Value = CStr("Address 1")
oBankRecord.Fields.Item("ADDRESS_2").Value = CStr("Address 2")
oBankRecord.Fields.Item("ADDRESS_3").Value = CStr("Address 3")
oBankRecord.Fields.Item("ADDRESS_4").Value = CStr("Address 4")
oBankRecord.Fields.Item("ADDRESS_5").Value = CStr("Address 5")
oBankRecord.Fields.Item("CONTACT_NAME").Value = CStr("Chris Burke")
oBankRecord.Fields.Item("E_MAIL").Value = CStr("dev@sage.com")
oBankRecord.Fields.Item("TELEPHONE").Value = CStr("0845 1117733")
oBankRecord.Fields.Item("FAX").Value = CStr("0845 2450294")
oBankRecord.Fields.Item("SORT_CODE").Value = CStr("00-11-22")
oBankRecord.Fields.Item("WWW").Value = CStr("www.uk.sage.com")

' Post the Bank Account
If oBankRecord.Update Then

MsgBox("Bank Account Created Successfully", MsgBoxStyle.OKOnly, "SDO Examples")

Else

MsgBox("Bank Account Was Not Created", MsgBoxStyle.OKOnly, "SDO Examples")

End If
End If

' Disconnect.
oWS.Disconnect()

End If

End If

oBankRecord = Nothing
oNominalRecord = Nothing
oWS = Nothing
oSDO = Nothing

Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.BankRecord oBankRecord;

SageDataObject300.NominalRecord oNominalRecord;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate Objects

  oBankRecord = (SageDataObject300.BankRecord)oWS.CreateObject("BankRecord");

  oNominalRecord = (SageDataObject300.NominalRecord)oWS.CreateObject("NominalRecord");

  //Create the nominal record for the bank account

  if (oNominalRecord.AddNew())

  {

    SDOHelper.Write(oNominalRecord, "ACCOUNT_REF", (String)"1291");

    SDOHelper.Write(oNominalRecord, "NAME",(String)"SDO Bank Account");

    //We must set the nominal ACCOUNT_TYPE field to 2, which denotes a bank account

    SDOHelper.Write(oNominalRecord,"ACCOUNT_TYPE",(Byte)2);

    //Post the nominal account

    if (oNominalRecord.Update())

    {

      MessageBox.Show("Nominal Account Created Successfully");

    }

    else

    {

      MessageBox.Show("Nominal Account Was Not Created");

    }

  }

  //Create the Bank Account

  if (oBankRecord.AddNew())

  {

    //Populate the fields

    //The ACCOUNT_REF field must equal the Nominal Code for the account

    SDOHelper.Write(oBankRecord, "ACCOUNT_REF", (String)"1291");

    SDOHelper.Write(oBankRecord,"NAME",(String)"SDO Bank Account");

    SDOHelper.Write(oBankRecord,"ACCOUNT_NUMBER",(String)"01234567");

    SDOHelper.Write(oBankRecord,"ACCOUNT_NAME",(String)"SDO Bank Account");

    SDOHelper.Write(oBankRecord, "ACCOUNT_TYPE", (Byte)1);

    SDOHelper.Write(oBankRecord, "ADDRESS_1", (String)"ADDRESS 1");

    SDOHelper.Write(oBankRecord, "ADDRESS_2", (String)"ADDRESS 2");

    SDOHelper.Write(oBankRecord, "ADDRESS_3", (String)"ADDRESS 3");

    SDOHelper.Write(oBankRecord, "ADDRESS_4", (String)"ADDRESS 4");

    SDOHelper.Write(oBankRecord, "ADDRESS_5", (String)"ADDRESS 5");

    SDOHelper.Write(oBankRecord, "CONTACT_NAME", (String)"Chris Reed");

    SDOHelper.Write(oBankRecord, "E_MAIL", (String)"developers.programme@sage.com");

    SDOHelper.Write(oBankRecord, "TELEPHONE", (String)"0845 111 7733");

    SDOHelper.Write(oBankRecord, "FAX", (String)"0845 245 0294");

    SDOHelper.Write(oBankRecord, "SORT_CODE", (String)"00-1-22");

    SDOHelper.Write(oBankRecord, "WWW", (String)"www.sage.co.uk");

    //Post the Bank Account

    if (oBankRecord.Update())

    {

      MessageBox.Show("Bank Account Created Successfully");

    }

    else

    {

      MessageBox.Show("Bank Account Was Not Created");

    }

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Creating a New Recurring Entry

Example - Creating a New Recurring Entry

The example code below demonstrates how to create a new Recurring Entry.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
                                ' Declare Objects
Dim oSDO  As
                              SageDataObject300.SDOEngine
Dim oWS  As
                              SageDataObject300.WorkSpace
Dim oRecurringData  As
                              SageDataObject300.RecurringData

' Declare Variables
Dim szDataPath  As String
Dim bFlag  As Boolean

' Create the SDO Engine Object
oSDO =  New   SageDataObject300.SDOEngine()

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> ""  Then

' Connect to Data Files
If oWS.Connect(szDataPath, "", "", "Example")
                               Then

' Create Instances of Objects
oRecurringData = oWS.CreateObject("RecurringData")

' Populate The Fields
oRecurringData.Fields.Item("DEPARTMENT").Value =
                              CShort(0)
oRecurringData.Fields.Item("DETAILS").Value = CStr("SDO Recurring Entry")
oRecurringData.Fields.Item("BANK_CODE").Value =
                              CStr("1200")
oRecurringData.Fields.Item("START_DATE").Value =
                              CDate(Today)
oRecurringData.Fields.Item("NOMINAL_CODE").Value =
                              CStr("7000")
oRecurringData.Fields.Item("TYPE").Value = CByte(0)     ' Bank Payment
oRecurringData.Fields.Item("REFERENCE").Value =
                              CStr("SDO REF")
oRecurringData.Fields.Item("NET_AMOUNT").Value =
                              CDbl(1000.0#)
oRecurringData.Fields.Item("TAX_AMOUNT").Value =
                              CDbl(175.0#)
oRecurringData.Fields.Item("TAX_CODE").Value =
                              CByte(1)
oRecurringData.Fields.Item("FREQUENCY_TYPE").Value =
                              CByte(1)      ' Weekly
oRecurringData.Fields.Item("FREQUENCY").Value =
                              CShort(2) ' 2 weeks
oRecurringData.Fields.Item("REQUIRED_POSTINGS").Value =
                              CShort(10)

' Write the record to the database
bFlag = oRecurringData.Write(oRecurringData.Count + 1)

If bFlag  Then

MsgBox("Recurring Entry Posted", MsgBoxStyle.OKOnly, "SDO Examples")

Else

MsgBox("Recurring Entry Has Not Been Posted", MsgBoxStyle.OKOnly, "SDO Examples")

End If

'Disconnect
oWS.Disconnect()

End If

End If

oRecurringData = Nothing
oWS = Nothing
oSDO = Nothing

Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.RecurringData oRecurringData;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate the RecurringData Object

  oRecurringData = (SageDataObject300.RecurringData)oWS.CreateObject("RecurringData");

  //Populate the Fields

  SDOHelper.Write(oRecurringData,"DEPARTMENT",(Int16)0);

  SDOHelper.Write(oRecurringData, "DETAILS", (String)"SDO Recurring Entry");

  SDOHelper.Write(oRecurringData, "BANK_CODE", (String)"1200");

  SDOHelper.Write(oRecurringData, "START_DATE", (DateTime)DateTime.Today);

  SDOHelper.Write(oRecurringData, "NOMINAL_CODE", (String)"7000");

  SDOHelper.Write(oRecurringData, "TYPE", (Byte)0); //Bank Payment

  SDOHelper.Write(oRecurringData, "REFERENCE", (String)"SDO REF");

  SDOHelper.Write(oRecurringData, "NET_AMOUNT", (Double)1000.00);

  SDOHelper.Write(oRecurringData, "TAX_AMOUNT", (Double)175.00);

  SDOHelper.Write(oRecurringData, "TAX_CODE", (Byte)1);

  SDOHelper.Write(oRecurringData, "FREQUENCY_TYPE", (Byte)1); //Weekly

  SDOHelper.Write(oRecurringData, "FREQUENCY", (Int16)2); //2 Weeks

  SDOHelper.Write(oRecurringData, "REQUIRED_POSTINGS", (Int16)10);

  //Write the record to the database

  if (oRecurringData.Write(oRecurringData.Count() + 1))

  {

    MessageBox.Show("Recurring Entry Posted");

  }

  else

  {

    MessageBox.Show("Recurring Entry Has not Been Posted");

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Find 'Bank' reconciled transactions

Example - Find 'Bank' reconciled transactions

The example code below demonstrates how to iterate through your bank account transactions, if the main account is set for reconciliation, and list those transactions and whether they have been reconciled or not.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
Public Class Form1

    'declarations
    Dim oSDO As SageDataObject300.SDOEngine
    Dim oWS As SageDataObject300.WorkSpace
    Dim oBnkDta As SageDataObject300.BankData
    Dim oBnkIdx As SageDataObject300.BankIndex
    Dim oBnkHdrDta As SageDataObject300.BankHeaderData

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        ' Declare Variables
        Dim szDataPath As String

        Try

            ' Create the SDO Engine object
            oSDO = New SageDataObject300.SDOEngine()

            ' Create the Workspace
            oWS = oSDO.Workspaces.Add("Example")

            ' Select company. The SelectCompany method takes the program install folder as a parameter
            szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

            ' A U.I. for company selection is presented to the user. If a company is selected,
            ' the path will be passed to the szDataPath variable.
            ' If not, or the Cancel button is selected, the variable will be left empty.
            If szDataPath <> "" Then

                ' Connect to Data Files
                If oWS.Connect(szDataPath, "", "", "Example") Then

                    ' user code
                    getBanksForReconciliation()

                End If

            End If

        Catch

            Select Case oSDO.LastError.Code

                ' 3rd Party Integration NOT Enabled - Site Activation
                Case Is = SageDataObject300.ErrorCode.sdoNotRegistered
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")

                    ' Invalid Password
                Case Is = SageDataObject300.ErrorCode.sdoLogonPassword
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")

                    ' User is Already Logged On
                Case Is = SageDataObject300.ErrorCode.sdoLogonNameInUse
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")

                    ' Line 50 is in Exclusive Mode i.e. File Maintenance
                Case Is = SageDataObject300.ErrorCode.sdoLogonExclusive
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")

                    ' Invalid Data Path on Connect
                Case Is = SageDataObject300.ErrorCode.sdoBadDataPath
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")

                    ' Line 50 is not Same Version as SDO
                Case Is = SageDataObject300.ErrorCode.sdoWrongVersion
                    MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")

            End Select

        End Try

    End Sub

    Private Sub getBanksForReconciliation()

        ' declare listView
        Dim lvi As ListViewItem

        'clear the listView of any data
        Me.ListView1.Items.Clear()

        ' create objects
        Me.oBnkDta = oWS.CreateObject("BankData")
        Me.oBnkIdx = oWS.CreateObject("BankIndex")

        ' must pad A/c Ref to 8 places
        If Me.oBnkIdx.FindFirst("ACCOUNT_REF", "1200".PadRight(8, " ")) Then

            ' get the record number
            Dim myIdx As Integer = Me.oBnkIdx.IndexRecordNumber

            ' find BankData from BankIndex
            If Me.oBnkDta.FindFirst("BANK_REF", myIdx) Then

                ' we're only interested if the Bank Account is set for reconciliation
                If Me.oBnkDta.Fields.Item("NO_RECONCILIATION_FLAG").Value = 0 Then

                    ' create BankHeaderData object
                    Me.oBnkHdrDta = oWS.CreateObject("BankHeaderData")

                    ' only want to read the information
                    Me.oBnkDta.Open(SageDataObject300.OpenMode.sdoRead)

                    ' loop through all BankHeaderData records that match our Bank Account Ref
                    Me.oBnkHdrDta.MoveFirst()
                    Do

                        If Me.oBnkHdrDta.Fields.Item("BANK_CODE").Value = Me.oBnkDta.Fields.Item("ACCOUNT_REF").Value Then

                            ' create new listView item
                            lvi = New ListViewItem

                            ' get required fields to display in the listView
                            lvi.Text = CStr(oBnkHdrDta.Fields.Item("BANK_CODE").Value)
                            lvi.SubItems.Add(CStr(oBnkHdrDta.Fields.Item("FIRST_SPLIT").Value))

                            ' uses the recFlag method to return a string stating whether reconciled or not
                            lvi.SubItems.Add(CStr(recFlag(oBnkHdrDta.Fields.Item("BANK_FLAG").Value)))

                            ' add the items to the listView
                            ListView1.Items.Add(lvi)

                        End If

                    Loop Until Not Me.oBnkHdrDta.MoveNext

                End If

            End If

        End If

    End Sub

    Private Function recFlag(ByVal num As Integer) As String

        ' can use the 'Constant' values within SDO help files
        If num = 82 Or num = 1 Then
            Return "Reconciled"
        Else
            Return "Not Reconciled or Not Applicable"
        End If

    End Function

End Class
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.BankData oBnkDta;
SageDataObject300.BankIndex oBnkIdx;
SageDataObject300.BankHeaderData oBnkHdrDta;

String szDataPath;
String opete;

try
{
        //Instantiate WorkSpace
        oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

        //Show select company dialog
        szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

        //Leaving the username and password blank generates a login dialog
        oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

        ListViewItem lvi;

        listView1.Items.Clear();

        //Instantiate the BankData and BankIndexobject
        oBnkDta = (SageDataObject300.BankData)oWS.CreateObject("BankData");
        oBnkIdx = (SageDataObject300.BankIndex)oWS.CreateObject("BankIndex");

        //must pad A/C Ref to 8 places
        if(oBnkDta.FindFirst("ACCOUNT_REF", "1200".PadRight(8, ' ')))
        {
            //get the record number
            Int32 myIdx = oBnkIdx.IndexRecordNumber;

            //Find BankData from BankIndex
            if (oBnkDta.FindFirst("BANK_REF", myIdx))

            {

                //we're only interested if the Bank Account is set for reconciliation
                if (Convert.ToByte(SDOHelper.Read(oBnkDta, "NO_RECONCILIATION_FLAG")) == (Byte)0)
                {
                    //Create BankHeaderData object
                    oBnkHdrDta = (SageDataObject300.BankHeaderData)oWS.CreateObject("BankHeaderData");

                    //Only want to read the information
                    oBnkDta.Open(SageDataObject300.OpenMode.sdoRead);

                    oBnkHdrDta.MoveFirst();

                    do
                    {

                        if (Convert.ToString(SDOHelper.Read(oBnkHdrDta, "BANK_CODE")) == Convert.ToString(SDOHelper.Read(oBnkDta, "ACCOUNT_REF")))
                        {
                            //CreateAccessibilityInstance new ListView item
                            lvi = new ListViewItem();

                            // Get required fields to display in the listview

                            lvi.Text = (String)SDOHelper.Read(oBnkHdrDta, "BANK_CODE");
                            lvi.SubItems.Add(Convert.ToString((SDOHelper.Read(oBnkHdrDta, "FIRST_SPLIT"))));

                            //uses the recFlag method to return a string stating whether reconciled or not
                            lvi.SubItems.Add(Convert.ToString((recFlag(Convert.ToInt32(SDOHelper.Read(oBnkHdrDta, "BANK_FLAG"))))));

                            //Add the items to the listview
                            listView1.Items.Add(lvi);

                        }

                    }
                    while (!(!oBnkHdrDta.MoveNext()));
                }
            }

            //Disconnect
            oWS.Disconnect();

        }
    }
    catch (Exception ex)
    {
        MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
    }
}

private string recFlag(int num)
{
    // can use the 'Constant' values within SDO help files
    if (num == 82 | num == 1)
    {
        return "Reconciled";
    }
    else
    {
        return "Not Reconciled or Not Applicable";
    }

}


Sage 50 Accounts - Example - Finding a SplitRecord through HeaderData Unique_Ref field

Example - Finding a SplitRecord through HeaderData Unique_Ref field

The following code shows how to locate the SplitData from the stored HeaderData Unique_Ref field.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code

Dim oSdo As New SageDataObject300.SDOEngine

Dim oWs As SageDataObject300.WorkSpace

Dim oSalesRecord As SageDataObject300.SalesRecord

Dim oSplitData As SageDataObject300.SplitData

Dim oTransactionPost As SageDataObject300.TransactionPost

Dim oHeaderData As SageDataObject300.HeaderData

' Declare Variables

Dim szDataPath As String

Dim iUniqueRef As String

' Create the Workspace

oWs = oSdo.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install

' folder as a parameter

szDataPath = oSdo.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is 'selected,

' the path will be passed to the szDataPath variable.

' If not, or the Cancel button is selected, the variable will be left 'empty.

If szDataPath <> "" Then

' Connect to Data Files

If oWs.Connect(szDataPath, "", "", "Example") Then

' Create Instances of Objects

oTransactionPost = oWs.CreateObject("TransactionPost")

oSalesRecord = oWs.CreateObject("SalesRecord")

' Read the First Customer

oSalesRecord.MoveFirst()

' Populate Header fields

' Note:

' The ACCOUNT_REF field must be populated with a valid

' Customer Account Reference

oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)

oTransactionPost.Header("Date").Value = CDate(Today)

oTransactionPost.Header("Posted_Date").Value = CDate(Today)

oTransactionPost.Header("Type").Value = CByte(SageDataObject300.TransType.sdoSI)

oTransactionPost.Header("Details").Value = CStr("Test Sales Invoice")

oTransactionPost.Header("Inv_Ref").Value = CStr("INV001")

' Loop for the Number of Splits

' Note:

' The Transaction can have 1 or many splits

For iSplitCount As Integer = 1 To 2

' Add a split to the Header Item's collection

oSplitData = oTransactionPost.Items.Add

' Populate Split Fields

oSplitData.Fields.Item("TYPE").Value = oTransactionPost.Header("TYPE").Value

oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("4000")

oSplitData.Fields.Item("TAX_CODE").Value = CShort(1)

oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(100)

oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(15.0)

oSplitData.Fields.Item("DETAILS").Value = CStr("Split Details")

oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)

Next iSplitCount

' Update the TransactionPost object

If oTransactionPost.Update Then

MsgBox("Transaction Posted successfully", MsgBoxStyle.OkOnly, "SDO Examples")

'Destroy the HeaderData and SplitData

oHeaderData = Nothing

oSplitData = Nothing

'Instantiate the HeaderData object

oHeaderData = oWs.CreateObject("HeaderData")

''**********Move to the HeaderData record*************

oHeaderData.Read(oTransactionPost.PostingNumber)

''**********Set the iUniqueRef variable to HeaderData record Unique_Ref value***********

iUniqueRef = (oHeaderData.Fields.Item("UNIQUE_REF").Value)

'To locate the Header using the Unique_Ref use the following.

If oHeaderData.FindFirst("Unique_Ref", CInt(iUniqueRef)) = True Then

'Instantiate the SplitData against the HeaderData Link method

oSplitData = oHeaderData.Link

'move to the first split

oSplitData.MoveFirst()

'you can now obtain the split record number for the allocation

MessageBox.Show(oSplitData.RecordNumber)

Else

MsgBox("Transaction Post Failed", MsgBoxStyle.OkOnly, "SDO Examples")

End If

End If

End If

End If

'Disconnect from the data

oWs.Disconnect()

'Destroy the objects

oSdo = Nothing

oWs = Nothing

oTransactionPost = Nothing

oHeaderData = Nothing

oSalesRecord = Nothing

oSplitData = Nothing

End Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.SalesRecord oSalesrecord;

SageDataObject300.TransactionPost oTransactionPost;

SageDataObject300.SplitData oSplitData;

SageDataObject300.HeaderData oHeaderData;

String szDataPath, iUniqueRef;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

//Leaving the username and password blank generates a login dialog

oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

//Instantiate Objects

oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

oSalesrecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");

//Read the first customer

oSalesrecord.MoveFirst();

//Populate Header Fields

//Note:

//The Account_Ref field must be populated with a valid

//Customer account reference

SDOHelper.SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF",

(String)SDOHelper.SDOHelper.Read(oSalesrecord, "ACCOUNT_REF"));

SDOHelper.SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);

SDOHelper.SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);

SDOHelper.SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoSI);

SDOHelper.SDOHelper.Write(oTransactionPost.Header, "DETAILS", (String)"Test Sales Invoice");

SDOHelper.SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"INV001");

//Loop for the number of splits

//Note:

//The transaction can have 1 or many splits

for (Int16 i = 1; i <= 2; i++)

{

//Add a split to the headers item collection

oSplitData = (SageDataObject300.SplitData)SDOHelper.SDOHelper.Add(oTransactionPost.Items);

//Populate split fields

SDOHelper.SDOHelper.Write(oSplitData, "TYPE",

SDOHelper.SDOHelper.Read(oTransactionPost.Header, "TYPE"));

SDOHelper.SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"4000");

SDOHelper.SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)1);

SDOHelper.SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)100);

SDOHelper.SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)17.5);

SDOHelper.SDOHelper.Write(oSplitData, "DETAILS", (String)"Split Details ");

SDOHelper.SDOHelper.Write(oSplitData, "DATE",

(DateTime)SDOHelper.SDOHelper.Read(oTransactionPost.Header, "DATE"));

}

//Update the transaction post object

if (oTransactionPost.Update())

{

MessageBox.Show("Transaction Posted Successfully");

oSplitData = null;

// Instantiate the HeaderData object

oHeaderData = (SageDataObject300.HeaderData)oWS.CreateObject("HeaderData");

// Move to the HeaderData Object

oHeaderData.Read(oTransactionPost.PostingNumber);

// Set the iUniqueRef variable to HeaderData record Unique_Ref value

iUniqueRef = SDOHelper.SDOHelper.Read(oHeaderData, "UNIQUE_REF").ToString();

// To locate the header using the Unique_Ref use the following

if ((oHeaderData.FindFirst("UNIQUE_REF", Int32.Parse(iUniqueRef))) == true)

{

//Instantiate the SplitData against the HeaderData Link method

oSplitData = (SageDataObject300.SplitData)oHeaderData.Link;

// Move to the first split

oSplitData.MoveFirst();

//You can now obtain the split record number for the allocation

MessageBox.Show(oSplitData.RecordNumber.ToString());

}

else

{

MessageBox.Show("Transaction Post Failed");

}

}

else

{

MessageBox.Show("Transaction Post Failed");

}

}

// Catch any exceptions

catch (Exception ex)

{

MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}

// Be sure to disconnect

finally

{

//Disconnect

oWS.Disconnect();

}


Sage 50 Accounts - Example - Posting a Bank Payment

Example - Posting a Bank Payment

The example code below demonstrates how to post a Bank Payment.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oBankRecord As SageDataObject300.BankRecord
Dim oTransactionPost As SageDataObject300.TransactionPost
Dim oSplitData As SageDataObject300.SplitData

' Declare Variables
Dim szDataPath As String

' Create the SDO Engine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company the select company method takes the program install
' directory as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.

If szDataPath <> "" Then

    ' Connect to Data Files
    If oWS.Connect(szDataPath, "", "", "Example") Then

        ' Create Instances of Objects
        oTransactionPost = oWS.CreateObject("TransactionPost")
        oBankRecord = oWS.CreateObject("BankRecord")

        ' Read the first Bank Account
        oBankRecord.MoveFirst()

        ' Populate Header fields
        oTransactionPost.Header("BANK_CODE").Value = CStr(oBankRecord.Fields.Item("ACCOUNT_REF").Value)
        oTransactionPost.Header("DATE").Value = CDate(Today)
        oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
        oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoBP)
        oTransactionPost.Header("DETAILS").Value = CStr("Test Bank Payment")
        oTransactionPost.Header("INV_REF").Value = CStr("BP001")

        ' Create a split item by adding an empty split to the Items
        ' collection of the TransactionPost Object.
        oSplitData = oTransactionPost.Items.Add()

        ' Fill in the Split fields
        oSplitData.Fields.Item("TYPE").Value = CByte(SageDataObject300.TransType.sdoBP)
        oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("4000")
        oSplitData.Fields.Item("TAX_CODE").Value = CShort(9)
        oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(200)
        oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(0)
        oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)
        oSplitData.Fields.Item("DETAILS").Value = CStr(oTransactionPost.Header("DETAILS").Value)

        ' Update the TransactionPost object
        If oTransactionPost.Update Then

            MsgBox("Transaction Posted successfully", MsgBoxStyle.OkOnly, "SDO Examples")

        Else

            MsgBox("Transaction Post Failed", MsgBoxStyle.OkOnly, "SDO Examples")

        End If

        ' Disconnect
        oWS.Disconnect()

    End If

End If

oTransactionPost = Nothing
oSplitData = Nothing
oBankRecord = Nothing
oSDO = Nothing
oWS = Nothing

Exit Sub
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.BankRecord oBankRecord;
            SageDataObject300.TransactionPost oTransactionPost;
            SageDataObject300.SplitData oSplitData;

            try
            {
                //Instantiate Objects
                oBankRecord = (SageDataObject300.BankRecord)oWS.CreateObject("BankRecord");
                oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

                //Read the first Bank Account
                oBankRecord.MoveFirst();

                //Populate Header Fields

                //Note:
                //The ACCOUNT_REF field must be populated with a valid
                //Bank Account Reference
                SDOHelper.Write(oTransactionPost.Header, "BANK_CODE", (String)SDOHelper.Read(oBankRecord, "ACCOUNT_REF"));
                SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);
                SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);
                SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoBP);
                SDOHelper.Write(oTransactionPost.Header, "DETAILS", (String)"Test Bank Payment");
                SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"BP001");

                //Create a split item by adding an empty split to the items
                //collection of the transaction object
                oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                //Fill in the split Fields
                SDOHelper.Write(oSplitData, "TYPE", (Byte)SageDataObject300.TransType.sdoBP);
                SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"6000");
                SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)9);
                SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)200);
                SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)0);
                SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));
                SDOHelper.Write(oSplitData, "DETAILS", (String)SDOHelper.Read(oTransactionPost.Header, "DETAILS"));

                //Update the TransactionPost Object
                if (oTransactionPost.Update())
                {
                    MessageBox.Show("Transaction Posted Successfully");
                }
                else
                {
                    MessageBox.Show("Transaction Post Failed");
                }

                // Disconnect
                oWS.Disconnect();
            }
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Posting a Bank Payment and Cheque

Example - Posting a Bank Payment and Cheque

The example code below demonstrates how to post a Bank Payment and create a Cheque that can be printed through the Sage 50 Accounts UI.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
        ' Declare Objects
        Dim oSDO As SageDataObject300.SDOEngine
        Dim oWS As SageDataObject300.WorkSpace
        Dim oBankRecord As SageDataObject300.BankRecord
        Dim oTransactionPost As SageDataObject300.TransactionPost
        Dim oSplitData As SageDataObject300.SplitData
        Dim oSetupData As SageDataObject300.SetupData
        Dim oRemittanceRecord As SageDataObject300.RemittanceRecord

        Dim oURNInt, oIndexInt As Integer
        Dim oURNString, oIndexString As String

        ' Declare Variables
        Dim szDataPath As String

        ' Create the SDO Engine Object
        oSDO = New SageDataObject300.SDOEngine

        ' Create the Workspace
        oWS = oSDO.Workspaces.Add("Example")

        ' Select company the select company method takes the program install
        ' directory as a parameter
        szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

        ' A U.I. for company selection is presented to the user. If a company is selected,
        ' the path will be passed to the szDataPath variable.
        ' If not, or the Cancel button is selected, the variable will be left empty.

        Try

            If szDataPath <> "" Then

                ' Connect to Data Files
                If oWS.Connect(szDataPath, "", "", "Example") Then

                    ' Create Instances of Objects
                    oTransactionPost = oWS.CreateObject("TransactionPost")
                    oBankRecord = oWS.CreateObject("BankRecord")

                    ' Read the first Bank Account
                    oBankRecord.MoveFirst()

                    ' Populate Header fields
                    oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oBankRecord.Fields.Item("ACCOUNT_REF").Value)
                    oTransactionPost.Header("DATE").Value = CDate(Today)
                    oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
                    oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoBP)
                    oTransactionPost.Header("DETAILS").Value = CStr("Test Bank Payment")
                    oTransactionPost.Header("INV_REF").Value = CStr("BP001")
                    oTransactionPost.Header("BANK_CODE").Value = CStr("1200")

                    ' Create a split item by adding an empty split to the Items
                    ' collection of the TransactionPost Object.
                    oSplitData = oTransactionPost.Items.Add()

                    ' Fill in the Split fields
                    oSplitData.Fields.Item("TYPE").Value = CByte(SageDataObject300.TransType.sdoBP)
                    oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("5000")
                    oSplitData.Fields.Item("TAX_CODE").Value = CShort(9)
                    oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(200)
                    oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(0)
                    oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)
                    oSplitData.Fields.Item("DETAILS").Value = CStr(oTransactionPost.Header("DETAILS").Value)

                    ' Update the TransactionPost object
                    If oTransactionPost.Update Then

                        MsgBox("Transaction Posted successfully", MsgBoxStyle.OkOnly, "SDO Examples")

                        'Create a Cheque by processing the remittance
                        oSetupData = oWS.CreateObject("SetupData")
                        oRemittanceRecord = oWS.CreateObject("RemittanceRecord")

                        ' Create the URN by incrementing the last cheque number
                        oURNInt = oSetupData.Fields.Item("LAST_CHEQUE").Value
                        oURNInt = oURNInt + 1
                        oURNString = CStr(oURNInt)

                        ' Pad the URN with spaces
                        oURNString = oURNString.PadLeft(7, "0")

                        ' The INDEX number of the BP entry . Here we are paying 1 BP so the first BP entry has an INDEX value
                        ' of 1.
                        oIndexInt = 1
                        oIndexString = CStr(oIndexInt).PadLeft(8, "0")

                        ' Add a New Remittance Record
                        oRemittanceRecord.AddNew()

                        ' Populate Fields Remittance Bank Invoice Details
                        oRemittanceRecord.Fields.Item("BANK").Value = CStr("1200")
                        oRemittanceRecord.Fields.Item("DETAILS").Value = CStr("SDO Created")
                        oRemittanceRecord.Fields.Item("GROSS_AMOUNT").Value = CDbl(-200)
                        oRemittanceRecord.Fields.Item("INDEX").Value = CStr(oIndexString)
                        oRemittanceRecord.Fields.Item("LASTLINE_FLAG").Value = CShort(0)
                        oRemittanceRecord.Fields.Item("NAME").Value = CStr("SDO Created")
                        oRemittanceRecord.Fields.Item("NET_AMOUNT").Value = CDbl(0)
                        oRemittanceRecord.Fields.Item("PAYMENT_AMOUNT").Value = CDbl(-200)
                        oRemittanceRecord.Fields.Item("PAYMENT_DATE").Value = CDate(Today)
                        oRemittanceRecord.Fields.Item("PAYMENT_FLAG").Value = CShort(1)
                        oRemittanceRecord.Fields.Item("PAYMENT_NO").Value = CInt(5)
                        oRemittanceRecord.Fields.Item("TAX_CODE").Value = CStr("n/a")
                        oRemittanceRecord.Fields.Item("TRAN_TYPE").Value = CStr("BP")
                        oRemittanceRecord.Fields.Item("URN").Value = CStr(oURNString)
                        oRemittanceRecord.Fields.Item("VAT_AMOUNT").Value = CDbl(0)

                        'Post Invoice
                        If oRemittanceRecord.Update Then

                            ' Increment the last cheque number
                            oSetupData.Fields.Item("LAST_CHEQUE").Value = oURNInt
                            oSetupData.Write(1)
                            MessageBox.Show("BP and Cheque Entry Posted", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)

                        Else
                            MessageBox.Show("BP and Cheque Entry Has Not Been Posted", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)
                        End If

                    Else
                        MsgBox("Transaction Post Failed", MsgBoxStyle.OkOnly, "SDO Examples")
                    End If

                Else
                    MsgBox("The find has not found a match to your criteria", vbOKOnly Or vbInformation, "SDO")
                End If

                ' Disconnect
                oWS.Disconnect()

            End If

            'End If

        Catch ex As Exception

            MessageBox.Show(ex.Message.ToString())

        End Try

        oTransactionPost = Nothing
        oSplitData = Nothing
        oBankRecord = Nothing
        oSetupData = Nothing
        oRemittanceRecord = Nothing
        oSDO = Nothing
        oWS = Nothing

        Exit Sub
C#.NET [image] Copy C# Code
            // Declare Objects
            SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
            SageDataObject300.WorkSpace oWS;
            SageDataObject300.BankRecord oBankRecord;
            SageDataObject300.TransactionPost oTransactionPost;
            SageDataObject300.SplitData oSplitData;
            SageDataObject300.SetupData oSetupData;
            SageDataObject300.RemittanceRecord oRemittanceRecord;

            // Declare Variables
            String szDataPath;
            String oURNString;
            String oIndexString;
            Int32 oURNInt;
            Int32 oIndexInt;

            // Error Handler
            try
            {
                //Instantiate WorkSpace
                oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

                // Select company. The SelectCompany method takes the program install folder as a parameter
                szDataPath = oSDO.SelectCompany("C:\\Documents and Settings\\All Users\\Application Data\\Sage\\Accounts\\2023");

                // A U.I. for company selection is presented to the user. If a company is selected,
                // the path will be passed to the szDataPath variable.
                // If not, or the Cancel button is selected, the variable will be left empty.
                if (szDataPath != "")
                {
                    // Connect to Data Files
                    oWS.Connect(szDataPath, "", "", "Example");

                    // Create Instances of Objects
                    oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");
                    oBankRecord = (SageDataObject300.BankRecord)oWS.CreateObject("BankRecord");

                   // Read the first Bank Account
                    oBankRecord.MoveFirst();

                    // Populate Header fields
                    SDOHelper.Write (oTransactionPost.Header,"ACCOUNT_REF",SDOHelper.Read (oBankRecord,"ACCOUNT_REF"));
                    SDOHelper.Write(oTransactionPost.Header,"DATE",DateTime.Today);
                    SDOHelper.Write(oTransactionPost.Header,"POSTED_DATE",DateTime.Today);
                    SDOHelper.Write(oTransactionPost.Header,"TYPE",SageDataObject300.TransType.sdoBP);
                    SDOHelper.Write(oTransactionPost.Header,"DETAILS","Test Bank Payment");
                    SDOHelper.Write(oTransactionPost.Header,"INV_REF","BP001");
                    SDOHelper.Write(oTransactionPost.Header,"BANK_CODE","1200");

                    // Create a split item by adding an empty split to the Items
                    // collection of the TransactionPost Object.
                    oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                    // Fill in the Split fields
                    SDOHelper.Write(oSplitData,"TYPE",SageDataObject300.TransType.sdoBP);
                    SDOHelper.Write(oSplitData,"NOMINAL_CODE","5000");
                    SDOHelper.Write(oSplitData,"TAX_CODE",9);
                    SDOHelper.Write(oSplitData,"NET_AMOUNT",200);
                    SDOHelper.Write(oSplitData,"TAX_AMOUNT",0);
                    SDOHelper.Write(oSplitData,"DATE",SDOHelper.Read(oTransactionPost.Header,"DATE"));
                    SDOHelper.Write(oSplitData,"DETAILS",SDOHelper.Read(oTransactionPost.Header,"DETAILS"));

                                // Update the TransactionPost object
                                if (oTransactionPost.Update())
                                {
                                    MessageBox.Show("Transaction Posted successfully","SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);

                        // Create a Cheque by processing the remittance
                        oSetupData = (SageDataObject300.SetupData)oWS.CreateObject("SetupData");
                        oRemittanceRecord =(SageDataObject300.RemittanceRecord) oWS.CreateObject("RemittanceRecord");

                        // Create the URN by incrementing the last cheque number
                        oURNInt = (int)SDOHelper.Read(oSetupData,"LAST_CHEQUE");
                        oURNInt = oURNInt + 1;
                        oURNString = Convert.ToString(oURNInt);

                        // Pad the URN with spaces
                        // oURNString = oURNString.PadLeft(7, "0");
                        oURNString = oURNString.PadLeft(7,'0');

                        // The INDEX number of the BP entry . Here we are paying 1 BP so the first BP entry has an INDEX value
                        // of 1.
                        oIndexInt = 1;
                        oIndexString = (Convert.ToString(oIndexInt)).PadLeft(8, '0');

                        // Add a New Remittance Record
                        oRemittanceRecord.AddNew();

                        // Populate Fields Remittance Bank Invoice Details
                        SDOHelper.Write (oRemittanceRecord,"BANK","1200");
                        SDOHelper.Write (oRemittanceRecord,"DETAILS","SDO Created");
                        SDOHelper.Write (oRemittanceRecord,"GROSS_AMOUNT",-200);
                        SDOHelper.Write (oRemittanceRecord,"INDEX",oIndexString);
                        SDOHelper.Write (oRemittanceRecord,"LASTLINE_FLAG",0);
                        SDOHelper.Write (oRemittanceRecord,"NAME","SDO Created");
                        SDOHelper.Write (oRemittanceRecord,"NET_AMOUNT",0);
                        SDOHelper.Write (oRemittanceRecord,"PAYMENT_AMOUNT",-200);
                        SDOHelper.Write (oRemittanceRecord,"PAYMENT_DATE",DateTime.Today);
                        SDOHelper.Write (oRemittanceRecord,"PAYMENT_FLAG",1);
                        SDOHelper.Write (oRemittanceRecord,"PAYMENT_NO",5);
                        SDOHelper.Write (oRemittanceRecord,"TAX_CODE","n/a");
                        SDOHelper.Write (oRemittanceRecord,"TRAN_TYPE","BP");
                        SDOHelper.Write (oRemittanceRecord,"URN",oURNString);
                        SDOHelper.Write (oRemittanceRecord,"VAT_AMOUNT",0);

                                        //Post Invoice
                                        if (oRemittanceRecord.Update())
                                        {
                            // Increment the last cheque number
                            SDOHelper.Write (oSetupData,"LAST_CHEQUE",oURNInt);
                            oSetupData.Write(1);

                            MessageBox.Show("BP and Cheque Entry Posted", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);

                                        }

                                        else
                                        {
                                           MessageBox.Show("BP and Cheque Entry Has Not Been Posted", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                                        }

                                    }

                                }

                }

            // Error Handling Code
            catch (Exception ex)
            {
                switch (ex.Source)
                {
                    case "Sage Data Objects":

                        MessageBox.Show("The SDO generated the following error: " + oSDO.LastError.Text, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        break;
                    default:

                        MessageBox.Show("A non-SDO error has been generated: " + ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        break;
                }
            }
    }


Sage 50 Accounts - Example - Posting a Bank Receipt

Example - Posting a Bank Receipt

The example code below demonstrates how to post a Bank Receipt.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
                                ' Declare Objects
Dim oSDO  As
                              SageDataObject300.SDOEngine
Dim oWS  As
                              SageDataObject300.WorkSpace
Dim oBankRecord  As
                              SageDataObject300.BankRecord
Dim oTransactionPost  As
                              SageDataObject300.TransactionPost
Dim oSplitData  As
                              SageDataObject300.SplitData

' Declare Variables
Dim szDataPath  As String

' Create the SDO Engine Object
oSDO =  New   SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install
' directory as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> ""  Then

' Connect to Data Files
If oWS.Connect(szDataPath, "", "", "Example")
                               Then

' Create Instances of Objects
oTransactionPost = oWS.CreateObject("TransactionPost")
oBankRecord = oWS.CreateObject("BankRecord")

' Read the first Bank Account
oBankRecord.MoveFirst()

' Populate Header fields
' Note:
' The ACCOUNT_REF field must be populated with a valid
' Bank Account Reference
oTransactionPost.Header("BANK_CODE").Value = CStr(oBankRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value = CDate(Today)
oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoBR)
oTransactionPost.Header("DETAILS").Value = CStr("Test Bank Receipt")
oTransactionPost.Header("INV_REF").Value = CStr("BP001")

' Create a split item by adding an empty split to the Items
' collection of the TransactionPost Object.
oSplitData = oTransactionPost.Items.Add()

' Fill in the Split fields
oSplitData.Fields.Item("TYPE").Value = CByte(SageDataObject300.TransType.sdoBR)
oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("7000")
oSplitData.Fields.Item("TAX_CODE").Value = CShort(9)
oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(200)
oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(0)
oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)
oSplitData.Fields.Item("DETAILS").Value = CStr(oTransactionPost.Header("DETAILS").Value)

' Update the TransactionPost object
If oTransactionPost.Update
                               Then

MsgBox("Transaction Posted successfully", MsgBoxStyle.OKOnly, "SDO Examples")

Else

MsgBox("Transaction Post Failed", MsgBoxStyle.OKOnly, "SDO Examples")

End If

' Disconnect
oWS.Disconnect()

End If

End If

oTransactionPost =  Nothing
oSplitData =  Nothing
oBankRecord =  Nothing
oSDO =  Nothing
oWS =  Nothing

Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.BankRecord oBankRecord;

SageDataObject300.TransactionPost oTransactionPost;

SageDataObject300.SplitData oSplitData;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate Objects

  oBankRecord = (SageDataObject300.BankRecord)oWS.CreateObject("BankRecord");

  oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

  //Read the first Bank Account

  oBankRecord.MoveFirst();

  //Populate Header Fields

  //Note:

  //The ACCOUNT_REF field must be populated with a valid

  SDOHelper.Write(oTransactionPost.Header, "BANK_CODE", (String)SDOHelper.Read(oBankRecord, "ACCOUNT_REF"));

  SDOHelper.Write(oTransactionPost.Header, "DATE",(DateTime)DateTime.Today);

  SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);

  SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoBR);

  SDOHelper.Write(oTransactionPost.Header, "DETAILS", (String)"Test Bank Payment");

  SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"BP001");

  //Create a split item by adding an empty split to the items

  //collection of the transaction object

  oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

  //Fill in the split Fields

  SDOHelper.Write(oSplitData,"TYPE",(Byte)SageDataObject300.TransType.sdoBR);

  SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"7000");

  SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)9);

  SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)200);

  SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)0);

  SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header,"DATE"));

  SDOHelper.Write(oSplitData, "DETAILS", (String)SDOHelper.Read(oTransactionPost.Header, "DETAILS"));

  //Update the TransactionPost Object

  if (oTransactionPost.Update())

  {

    MessageBox.Show("Transaction Posted Successfully");

  }

  else

  {

    MessageBox.Show("Transaction Post Failed");

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Posting a Purchase Payment

Example - Posting a Purchase Payment

The example code below demonstrates how to post a Purchase Payment.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oTransactionPost As SageDataObject300.TransactionPost
Dim oHeaderData As SageDataObject300.HeaderData
Dim oSplitData As SageDataObject300.SplitData
Dim oControlData As SageDataObject300.ControlData
Dim oPurchaseRecord As SageDataObject300.PurchaseRecord
Dim oNominalData As SageDataObject300.NominalData

' Declare Variables
Dim szDataPath As String
Dim iCtr As Short
Dim lInvoiceHeader As Integer
Dim lPaymentHeader As Integer
Dim lPaymentSplit As Integer
Dim lDiscountHeader As Integer
Dim lDiscountSplit As Integer

' Create the SDO Engine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install
' folder as a parameter
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

' Try to Connect - Will throw an exception if it fails
If oWS.Connect(szDataPath, "", "", "Example") Then

' Create an Instance of Objects
oTransactionPost = oWS.CreateObject("TransactionPost")
oControlData = oWS.CreateObject("ControlData")
oPurchaseRecord = oWS.CreateObject("PurchaseRecord")
oNominalData = oWS.CreateObject("NominalData")

' Read First Customer
oPurchaseRecord.MoveFirst()

' Populate Header Fields
oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value = CDate(Today)
oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoPI)
oTransactionPost.Header("DETAILS").Value = CStr("Purchase Allocated Invoice")
oTransactionPost.Header("INV_REF").Value = CStr("INV001")

' Populate the foreign currency fields
oTransactionPost.Header("CURRENCY").Value = oSalesRecord.Fields.Item("CURRENCY").Value

' Loop for Number of Splits
For iCtr = 1 To 2

' Create a split item by adding an empty split to the Items
' collection of the TransactionPost Object.
oSplitData = oTransactionPost.Items.Add()

' Fill in the Split fields
oSplitData.Fields.Item("TYPE").Value = CByte(SageDataObject300.TransType.sdoPI)
oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("4000")
oSplitData.Fields.Item("TAX_CODE").Value = CShort(1)
oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(100)
oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(17.5)
oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)
oSplitData.Fields.Item("DETAILS").Value = CStr(oTransactionPost.Header("DETAILS").Value)

Next iCtr

' Update the TransactionPost Object
' If Successful
If oTransactionPost.Update Then

' Store Header Record Number of Invoice just Posted
lInvoiceHeader = oTransactionPost.PostingNumber

' Destroy Objects
oTransactionPost = Nothing
oSplitData = Nothing

' *********************************
' Now Post Purchase Payment

' Create an instance of TransactionPost for the Purchase Payment
oTransactionPost = oWS.CreateObject("TransactionPost")

' Fill in the Header fields
oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value = CDate(Today)
oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoPP)
oTransactionPost.Header("DETAILS").Value = CStr("Test Purchase Payment")
oTransactionPost.Header("INV_REF").Value = CStr("PAY001")
oTransactionPost.Header("BANK_CODE").Value = CStr("1200")

' Populate the foreign currency fields
oTransactionPost.Header("CURRENCY").Value = oSalesRecord.Fields.Item("CURRENCY").Value

' Create a split item by adding an empty split to the Items
' collection of the TransactionPost Object.
oSplitData = oTransactionPost.Items.Add()

' Fill in the Split fields - note a Purchase Payment only has one split
oSplitData.Fields.Item("TYPE").Value = CByte(SageDataObject300.TransType.sdoPP)
oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("1200")
oSplitData.Fields.Item("TAX_CODE").Value = CShort(9)
oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(200)
oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(0)
oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)
oSplitData.Fields.Item("DETAILS").Value = CStr(oTransactionPost.Header("DETAILS").Value)

End If
' Update the TransactionPost object
' If Successful
If oTransactionPost.Update Then

' Store Header Record Number of Payment just Posted
lPaymentHeader = oTransactionPost.PostingNumber

' Destroy Objects
oTransactionPost = Nothing
oSplitData = Nothing

' *********************************
' Now Post Purchase Discount

' Read Control Data
' for Default discount Nominal Code
oControlData.Read(1)

' Now read Nominal using the Default Purchase Discount Record Number
oNominalData.Read(CInt(oControlData.Fields.Item("PDISCOUNT_NO").Value))

' Create an instance of TransactionPost for the Purchase Discount
oTransactionPost = oWS.CreateObject("TransactionPost")

' Fill in the Header fields
oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value = CDate(Today)
oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoPD)
oTransactionPost.Header("DETAILS").Value = CStr("Sales Discount")
oTransactionPost.Header("INV_REF").Value = CStr("BACS")

' Populate the foreign currency fields
oTransactionPost.Header("CURRENCY").Value = oSalesRecord.Fields.Item("CURRENCY").Value

' Create a split item by adding an empty split to the Items
' collection of the TransactionPost Object.
oSplitData = oTransactionPost.Items.Add()

' Fill in the Split fields - note a Sales Discount only has one split
oSplitData.Fields.Item("TYPE").Value = CByte(SageDataObject300.TransType.sdoPD)
oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr(oNominalData.Fields.Item("ACCOUNT_REF").Value)
oSplitData.Fields.Item("TAX_CODE").Value = CShort(9)
oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(35)
oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(0)
oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)

End If

' Update the TransactionPost object
If oTransactionPost.Update Then

' Store Header record number of Payment just posted
lDiscountHeader = oTransactionPost.PostingNumber

' Destroy oSplitData
oSplitData = Nothing

' The AllocatePayment function needs the split record number
' so we will need to read the header first and then obtain
' the split's from there

' Create an instance of HeaderData
oHeaderData = oWS.CreateObject("HeaderData")

' Read HeaderData for Payment
oHeaderData.Read(lPaymentHeader)

' Store Split Number for Payment
lPaymentSplit= oHeaderData.Fields.Item("FIRST_SPLIT").Value

' Read HeaderData for Discount
oHeaderData.Read(lDiscountHeader)

' Store Split Number for Discount
lDiscountSplit = oHeaderData.Fields.Item("FIRST_SPLIT").Value

' Read HeaderData for Invoice
oHeaderData.Read(lInvoiceHeader)

' Link to Splits
oSplitData = oHeaderData.Link

' Move to First Split
oSplitData.MoveFirst()

End If

' Allocate First Split to Payment
If oTransactionPost.AllocatePayment(CInt(oSplitData.RecordNumber), CInt(lPaymentSplit), CDbl(117.5), CDate(Today)) Then

' Move to Next Split
oSplitData.MoveNext()

End If
' Allocate Second Split to Remainder of Payment
If oTransactionPost.AllocatePayment(CInt(oSplitData.RecordNumber), CInt(lPaymentSplit), CDbl(82.5), CDate(Today)) Then

' Allocate remainder of second split to discount
If oTransactionPost.AllocatePayment(CInt(oSplitData.RecordNumber), CInt(lDiscountSplit), CDbl(35), CDate(Today)) Then

MsgBox("Posting and Allocation has been Successful", MsgBoxStyle.OKOnly, "SDO Examples")

Else

MsgBox("Routine Failed", MsgBoxStyle.OKOnly, "SDO Examples")

End If

End If

' Disconnect
oWS.Disconnect()

End If

End If

' Destroy Objects

oTransactionPost = Nothing
oSplitData = Nothing
oHeaderData = Nothing
oControlData = Nothing
oPurchaseRecord = Nothing
oNominalData = Nothing
oWS = Nothing
oSDO = Nothing

Exit Sub
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.TransactionPost oTransactionPost;
            SageDataObject300.HeaderData oHeaderData;
            SageDataObject300.SplitData oSplitData = null;
            SageDataObject300.ControlData oControlData;
            SageDataObject300.PurchaseRecord oPurchaseRecord;
            SageDataObject300.NominalData oNominalData;
            Int32 lInvoiceHeader = 0;
            Int32 lReceiptHeader = 0;
            Int32 lReceiptSplit = 0;
            Int32 lDiscountHeader = 0;
            Int32 lDiscountSplit = 0;

            try
            {
                //Instantiate Objects
                oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");
                oControlData = (SageDataObject300.ControlData)oWS.CreateObject("ControlData");
                oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");
                oNominalData = (SageDataObject300.NominalData)oWS.CreateObject("NominalData");

                //Read the first supplier
                oPurchaseRecord.MoveFirst();

                //Populate Header Fields
                SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"));
                SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);
                SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);
                SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoPI);
                SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"INV001");

                //Populate the foreign currency fields
                SDOHelper.Write(oTransactionPost.Header, "CURRENCY", SDOHelper.Read(oPurchaseRecord, "CURRENCY"));

                //Loop for number of splits
                for (Int16 i = 1; i <= 2; i++)
                {
                    //Create a split item by adding an empty split to the items
                    //collection of the TransactionPost Object.
                    oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                    //Populate the split fields
                    SDOHelper.Write(oSplitData, "TYPE", (Byte)SageDataObject300.TransType.sdoPI);
                    SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"5000");
                    SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)1);
                    SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)100);
                    SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)17.5);
                    SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));
                    SDOHelper.Write(oSplitData, "DETAILS", (String)SDOHelper.Read(oTransactionPost.Header, "DETAILS"));
                }

                //Update the Transaction Post object
                if (oTransactionPost.Update())
                {
                    //Store the header record number of the invoice just posted
                    lInvoiceHeader = oTransactionPost.PostingNumber;

                    //Destroy the objects
                    oTransactionPost = null;
                    oSplitData = null;

                    //**********************
                    //Now Post Purchase Receipt
                    //**********************

                    //Re-Instantiate the Transaction Post object for the Purchase receipt
                    oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

                    //Populate the header fields
                    SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"));
                    SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);
                    SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);
                    SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoPP);
                    SDOHelper.Write(oTransactionPost.Header, "DETAILS", (String)"Test Purchase Payment");
                    SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"PAY001");
                    SDOHelper.Write(oTransactionPost.Header, "BANK_CODE", (String)"1200");

                    //Populate the foreign currency fields
                    SDOHelper.Write(oTransactionPost.Header, "CURRENCY", SDOHelper.Read(oPurchaseRecord, "CURRENCY"));

                    //Create a split item by adding an empty split to the items
                    //collection of the TransactionPost Object.
                    oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                    //Populate the split fields
                    //Note: a Purchase receipt only has one split
                    SDOHelper.Write(oSplitData, "TYPE", (Byte)SageDataObject300.TransType.sdoPP);
                    SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"1200");
                    SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)9);
                    SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)200);
                    SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)0);
                    SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));
                    SDOHelper.Write(oSplitData, "DETAILS", (String)SDOHelper.Read(oTransactionPost.Header, "DETAILS"));

                    //Update the Transaction Post object
                    if (oTransactionPost.Update())
                    {
                        //Store the record number of the receipt just posted
                        lReceiptHeader = oTransactionPost.PostingNumber;

                        //Destroy the objects
                        oTransactionPost = null;
                        oSplitData = null;

                        //***************************
                        //Now post the Purchase discount
                        //***************************

                        //Read control data
                        //for the default discount nominal code
                        oControlData.Read(1);

                        //Now read the nominal using the default Purchase discount
                        oNominalData.Read((Int32)SDOHelper.Read(oControlData, "PDISCOUNT_NO"));

                        //Re-Instantiate the Transaction Post object for the Discount
                        oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

                        //Populate the Header Fields
                        SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"));
                        SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);
                        SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);
                        SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoPD);
                        SDOHelper.Write(oTransactionPost.Header, "DETAILS", (String)"Purchase Discount");
                        SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"DISC0001");

                        //Populate the foreign currency fields
                        SDOHelper.Write(oTransactionPost.Header, "CURRENCY", SDOHelper.Read(oPurchaseRecord, "CURRENCY"));

                        //Create a split item by adding an empty split to the items
                        //collection of the TransactionPost Object.
                        oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                        //Populate the split fields
                        //Note: a Purchase Discount only has one split
                        SDOHelper.Write(oSplitData, "TYPE", (Byte)SageDataObject300.TransType.sdoPD);
                        SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)SDOHelper.Read(oNominalData, "ACCOUNT_REF"));
                        SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)9);
                        SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)35);
                        SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)0);
                        SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));
                        SDOHelper.Write(oSplitData, "DETAILS", (String)SDOHelper.Read(oTransactionPost.Header, "DETAILS"));

                        //Update the Transaction Post Object
                        if (oTransactionPost.Update())
                        {
                            //Store the header record number of the discount just posted
                            lDiscountHeader = oTransactionPost.PostingNumber;

                            //Destroy the split
                            oSplitData = null;

                            //The AllocatePayment function needs the split record number
                            //so we will need to read the header first and then obtain
                            //the splits from there

                            //Instantiate Header Data object
                            oHeaderData = (SageDataObject300.HeaderData)oWS.CreateObject("HeaderData");

                            //Read the HeaderData for the receipt
                            oHeaderData.Read(lReceiptHeader);

                            //Store the split number for the receipt
                            lReceiptSplit = (Int32)SDOHelper.Read(oHeaderData, "FIRST_SPLIT");

                            //Read the HeaderData for the Discount
                            oHeaderData.Read(lDiscountHeader);

                            //Store the split number for the discount
                            lDiscountSplit = (Int32)SDOHelper.Read(oHeaderData, "FIRST_SPLIT");

                            //Read the HeaderData for the invoice
                            oHeaderData.Read(lInvoiceHeader);

                            //Link the Splits
                            oSplitData = (SageDataObject300.SplitData)oHeaderData.Link;

                            //Move to the first split
                            oSplitData.MoveFirst();
                        }
                    }
                }
                //Allocate the first split to the receipt
                if (oTransactionPost.AllocatePayment((Int32)oSplitData.RecordNumber, (Int32)lReceiptSplit, (Double)117.5, (DateTime)DateTime.Today))
                {
                    //Move to the next split
                    oSplitData.MoveNext();

                    //Allocate the second split to the remainder of the receipt
                    oTransactionPost.AllocatePayment((Int32)oSplitData.RecordNumber, (Int32)lReceiptSplit, (Double)82.5, (DateTime)DateTime.Today);

                    //Allocate the remainder of the second split to the discount
                    oTransactionPost.AllocatePayment((Int32)oSplitData.RecordNumber, (Int32)lDiscountSplit, (Double)35, (DateTime)DateTime.Today);

                    MessageBox.Show("Posting allocation has been successful");
                }
                else
                {
                    MessageBox.Show("Routine Failed");
                }

                // Disconnect
                oWS.Disconnect();
            }
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Posting and Allocating a Sales Invoice, Discount and Receipt

cc Sage 50 Accounts - Example - Posting and Allocating a Sales Invoice, Discount and Receipt

Example - Posting and Allocating a Sales Invoice, Discount and Receipt

The example code below demonstrates how to post a Sales Invoice, Sale Discount, Sales Receipt and then allocate the 3 transactions.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oTransactionPost As SageDataObject300.TransactionPost
Dim oHeaderData As SageDataObject300.HeaderData
Dim oSplitData As SageDataObject300.SplitData
Dim oControlData As SageDataObject300.ControlData
Dim oSalesRecord As SageDataObject300.SalesRecord
Dim oNominalData As SageDataObject300.NominalData

' Declare Variables
Dim szDataPath As String
Dim iCtr As Short
Dim lInvoiceHeader As Integer
Dim lReceiptHeader As Integer
Dim lReceiptSplit As Integer
Dim lDiscountHeader As Integer
Dim lDiscountSplit As Integer

' Create the SDO Engine Object
oSDO = New SageDataObject300.SDOEngine()

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install
' folder as a parameter
            szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.

If szDataPath <> "" Then

' Connect to Data Files
oWS.Connect(szDataPath, "", "", "Example")

' Create an Instance of Objects
oTransactionPost = oWS.CreateObject("TransactionPost")
oControlData = oWS.CreateObject("ControlData")
oSalesRecord = oWS.CreateObject("SalesRecord")
oNominalData = oWS.CreateObject("NominalData")

' Read First Customer
 oSalesRecord.MoveFirst()

' Populate Header fields
oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value = CDate(Today)
oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoSI)
oTransactionPost.Header("DETAILS").Value = CStr("Sales Allocated Invoice")
oTransactionPost.Header("INV_REF").Value = CStr("INV001")

' Populate the foreign currency fields
oTransactionPost.Header("CURRENCY").Value = oSalesRecord.Fields.Item("CURRENCY").Value

' Loop for number of split's
For iCtr = 1 To 2

' Create a split item by adding an empty split to the Items
' collection of the TransactionPost Object.
oSplitData = oTransactionPost.Items.Add()

' Fill in the Split fields
oSplitData.Fields.Item("TYPE").Value = CByte(SageDataObject300.TransType.sdoSI)
oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("4000")
oSplitData.Fields.Item("TAX_CODE").Value = CShort(1)
oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(100)
oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(17.5)
oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)
oSplitData.Fields.Item("DETAILS").Value = CStr(oTransactionPost.Header("DETAILS").Value)

Next iCtr

' Update the TransactionPost Object
If oTransactionPost.Update Then

' Store Header Record Number of Invoice just Posted
lInvoiceHeader = oTransactionPost.PostingNumber

' Destroy Objects
oTransactionPost = Nothing
oSplitData = Nothing

' *********************************
' Now Post Sales Receipt

' Create an instance of TransactionPost for the Sales Receipt
oTransactionPost = oWS.CreateObject("TransactionPost")

' Fill in the Header fields
oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value = CDate(Today)
oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoSR)
oTransactionPost.Header("DETAILS").Value = CStr("Test Sales Receipt")
oTransactionPost.Header("INV_REF").Value = CStr("PAY001")
oTransactionPost.Header("BANK_CODE").Value = CStr("1200")

' Populate the foreign currency fields
oTransactionPost.Header("CURRENCY").Value = oSalesRecord.Fields.Item("CURRENCY").Value

' Create a split item by adding an empty split to the Items
' collection of the TransactionPost Object.
oSplitData = oTransactionPost.Items.Add()

' Fill in the Split fields - note a Sales Receipt only has one split
oSplitData.Fields.Item("TYPE").Value = CByte(SageDataObject300.TransType.sdoSR)
oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("1200")
oSplitData.Fields.Item("TAX_CODE").Value = CShort(9)
oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(200)
oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(0)
oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)
oSplitData.Fields.Item("DETAILS").Value = CStr(oTransactionPost.Header("DETAILS").Value)

End If

' Update the TransactionPost object
If oTransactionPost.Update Then

' Store Header Record Number of Receipt just Posted
lReceiptHeader = oTransactionPost.PostingNumber

' Destroy Objects
oTransactionPost = Nothing
oSplitData = Nothing

' *********************************
' Now Post Sales Discount

' Read Control Data
' for Default discount Nominal Code
oControlData.Read(1)

' Now read Nominal using the default sales discount
oNominalData.Read(CInt(oControlData.Fields.Item("SDISCOUNT_NO").Value))

' Create an instance of TransactionPost for the Sales Receipt
oTransactionPost = oWS.CreateObject("TransactionPost")

' Fill in the Header fields
oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value = CDate(Today)
oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoSD)
oTransactionPost.Header("DETAILS").Value = CStr("Sales Discount")
oTransactionPost.Header("INV_REF").Value = CStr("BACS")

' Populate the foreign currency fields
oTransactionPost.Header("CURRENCY").Value = oSalesRecord.Fields.Item("CURRENCY").Value

' Create a split item by adding an empty split to the Items
' collection of the TransactionPost Object.
oSplitData = oTransactionPost.Items.Add()

' Fill in the Split fields - note a Sales Discount only has one split
oSplitData.Fields.Item("TYPE").Value = CByte(SageDataObject300.TransType.sdoSD)
oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr(oNominalData.Fields.Item("ACCOUNT_REF").Value)
oSplitData.Fields.Item("TAX_CODE").Value = CShort(9)
oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(35)
oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(0)
oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)

End If

' Update the TransactionPost object
If oTransactionPost.Update Then

' Store Header record number of receipt just posted
lDiscountHeader = oTransactionPost.PostingNumber

' Destroy Dplit
oSplitData = Nothing
' The AllocatePayment function needs the split record number
' so we will need to read the header first and then obtain
' the split's from there

' Create an instance of HeaderData
oHeaderData = oWS.CreateObject("HeaderData")

' Read HeaderData for Receipt
oHeaderData.Read(lReceiptHeader)

' Store Split Number for Receipt
lReceiptSplit = CInt(oHeaderData.Fields.Item("FIRST_SPLIT").Value)

' Read HeaderData for Discount
oHeaderData.Read(lDiscountHeader)

' Store Split Number for Discount
lDiscountSplit = CInt(oHeaderData.Fields.Item("FIRST_SPLIT").Value)

' Read HeaderData for Invoice
oHeaderData.Read(lInvoiceHeader)

' Link to Split's
oSplitData = oHeaderData.Link

' Move to First Split
oSplitData.MoveFirst()

End If

' Allocate First Split to Receipt
If oTransactionPost.AllocatePayment(CInt(oSplitData.RecordNumber), CInt(lReceiptSplit), CDbl(117.5), CDate(Today)) Then

' Move to Next Split
oSplitData.MoveNext()

' Allocate Second Split to Remainder of Receipt
oTransactionPost.AllocatePayment(CInt(oSplitData.RecordNumber), CInt(lReceiptSplit), CDbl(82.5), CDate(Today))

' Allocate remainder of second split to discount
oTransactionPost.AllocatePayment(CInt(oSplitData.RecordNumber), CInt(lDiscountSplit), CDbl(35), CDate(Today))

MsgBox("Posting and Allocation has been Successful", MsgBoxStyle.OKOnly, "SDO Examples")

Else

MsgBox("Routine Failed", MsgBoxStyle.OKOnly, "SDO Examples")

End If

' Disconnect.
oWS.Disconnect()

End If

oTransactionPost = Nothing
oSplitData = Nothing
oHeaderData = Nothing
oControlData = Nothing
oSalesRecord = Nothing
oNominalData = Nothing
oWS = Nothing
oSDO = Nothing

Exit Sub
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.TransactionPost oTransactionPost;
            SageDataObject300.HeaderData oHeaderData;
            SageDataObject300.SplitData oSplitData = null;
            SageDataObject300.ControlData oControlData;
            SageDataObject300.SalesRecord oSalesRecord;
            SageDataObject300.NominalData oNominalData;
            Int32 lInvoiceHeader = 0;
            Int32 lReceiptHeader = 0;
            Int32 lReceiptSplit = 0;
            Int32 lDiscountHeader = 0;
            Int32 lDiscountSplit = 0;

            try
            {
                //Instantiate Objects
                oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");
                oControlData = (SageDataObject300.ControlData)oWS.CreateObject("ControlData");
                oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");
                oNominalData = (SageDataObject300.NominalData)oWS.CreateObject("NominalData");

                //Read the first customer
                oSalesRecord.MoveFirst();

                //Populate Header Fields
                SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));
                SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);
                SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);
                SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoSI);
                SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"INV001");

                //Populate the foreign currency fields
                SDOHelper.Write(oTransactionPost.Header, "CURRENCY", SDOHelper.Read(oSalesRecord, "CURRENCY"));

                //Loop for number of splits
                for (Int16 i = 1; i <= 2; i++)
                {
                    //Create a split item by adding an empty split to the items
                    //collection of the TransactionPost Object.
                    oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                    //Populate the split fields
                    SDOHelper.Write(oSplitData, "TYPE", (Byte)SageDataObject300.TransType.sdoSI);
                    SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"4000");
                    SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)1);
                    SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)100);
                    SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)17.5);
                    SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));
                    SDOHelper.Write(oSplitData, "DETAILS", (String)SDOHelper.Read(oTransactionPost.Header, "DETAILS"));
                }

                //Update the Transaction Post object
                if (oTransactionPost.Update())
                {
                    //Store the header record number of the invoice just posted
                    lInvoiceHeader = oTransactionPost.PostingNumber;

                    //Destroy the objects
                    oTransactionPost = null;
                    oSplitData = null;

                    //**********************
                    //Now Post Sales Receipt
                    //**********************

                    //Re-Instantiate the Transaction Post object for the sales receipt
                    oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

                    //Populate the header fields
                    SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));
                    SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);
                    SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);
                    SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoSR);
                    SDOHelper.Write(oTransactionPost.Header, "DETAILS", (String)"Test Sales Receipt");
                    SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"PAY001");
                    SDOHelper.Write(oTransactionPost.Header, "BANK_CODE", (String)"1200");

                    //Populate the foreign currency fields
                    SDOHelper.Write(oTransactionPost.Header, "CURRENCY", SDOHelper.Read(oSalesRecord, "CURRENCY"));

                    //Create a split item by adding an empty split to the items
                    //collection of the TransactionPost Object.
                    oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                    //Populate the split fields
                    //Note: a Sales receipt only has one split
                    SDOHelper.Write(oSplitData, "TYPE", (Byte)SageDataObject300.TransType.sdoSR);
                    SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"1200");
                    SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)9);
                    SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)200);
                    SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)0);
                    SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));
                    SDOHelper.Write(oSplitData, "DETAILS", (String)SDOHelper.Read(oTransactionPost.Header, "DETAILS"));

                    //Update the Transaction Post object
                    if (oTransactionPost.Update())
                    {
                        //Store the record number of the receipt just posted
                        lReceiptHeader = oTransactionPost.PostingNumber;

                        //Destroy the objects
                        oTransactionPost = null;
                        oSplitData = null;

                        //***************************
                        //Now post the sales discount
                        //***************************

                        //Read control data
                        //for the default discount nominal code
                        oControlData.Read(1);

                        //Now read the nominal using the default sales discount
                        oNominalData.Read((Int32)SDOHelper.Read(oControlData, "SDISCOUNT_NO"));

                        //Re-Instantiate the Transaction Post object for the Discount
                        oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

                        //Populate the Header Fields
                        SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));
                        SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);
                        SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);
                        SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoSD);
                        SDOHelper.Write(oTransactionPost.Header, "DETAILS", (String)"Sales Discount");
                        SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"DISC0001");

                        //Populate the foreign currency fields
                        SDOHelper.Write(oTransactionPost.Header, "CURRENCY", SDOHelper.Read(oSalesRecord, "CURRENCY"));

                        //Create a split item by adding an empty split to the items
                        //collection of the TransactionPost Object.
                        oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                        //Populate the split fields
                        //Note: a Sales Discount only has one split
                        SDOHelper.Write(oSplitData, "TYPE", (Byte)SageDataObject300.TransType.sdoSD);
                        SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)SDOHelper.Read(oNominalData, "ACCOUNT_REF"));
                        SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)9);
                        SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)35);
                        SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)0);
                        SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));
                        SDOHelper.Write(oSplitData, "DETAILS", (String)SDOHelper.Read(oTransactionPost.Header, "DETAILS"));

                        //Update the Transaction Post Object
                        if (oTransactionPost.Update())
                        {
                            //Store the header record number of the discount just posted
                            lDiscountHeader = oTransactionPost.PostingNumber;

                            //Destroy the split
                            oSplitData = null;

                            //The AllocatePayment function needs the split record number
                            //so we will need to read the header first and then obtain
                            //the splits from there

                            //Instantiate Header Data object
                            oHeaderData = (SageDataObject300.HeaderData)oWS.CreateObject("HeaderData");

                            //Read the HeaderData for the receipt
                            oHeaderData.Read(lReceiptHeader);

                            //Store the split number for the receipt
                            lReceiptSplit = (Int32)SDOHelper.Read(oHeaderData, "FIRST_SPLIT");

                            //Read the HeaderData for the Discount
                            oHeaderData.Read(lDiscountHeader);

                            //Store the split number for the discount
                            lDiscountSplit = (Int32)SDOHelper.Read(oHeaderData, "FIRST_SPLIT");

                            //Read the HeaderData for the invoice
                            oHeaderData.Read(lInvoiceHeader);

                            //Link the Splits
                            oSplitData = (SageDataObject300.SplitData)oHeaderData.Link;

                            //Move to the first split
                            oSplitData.MoveFirst();
                        }
                    }
                }
                //Allocate the first split to the receipt
                if (oTransactionPost.AllocatePayment((Int32)oSplitData.RecordNumber, (Int32)lReceiptSplit, (Double)117.5, (DateTime)DateTime.Today))
                {
                    //Move to the next split
                    oSplitData.MoveNext();

                    //Allocate the second split to the remainder of the receipt
                    oTransactionPost.AllocatePayment((Int32)oSplitData.RecordNumber, (Int32)lReceiptSplit, (Double)82.5, (DateTime)DateTime.Today);

                    //Allocate the remainder of the second split to the discount
                    oTransactionPost.AllocatePayment((Int32)oSplitData.RecordNumber, (Int32)lDiscountSplit, (Double)35, (DateTime)DateTime.Today);

                    MessageBox.Show("Posting allocation has been successful");
                }
                else
                {
                    MessageBox.Show("Routine Failed");
                }

                // Disconnect
                oWS.Disconnect();
            }
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Posting a Bank Transfer

Example - Posting a Bank Transfer

The example code below demonstrates how to post a Bank Transfer.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
                                ' Declare Objects
Dim oSDO  As
                              SageDataObject300.SDOEngine
Dim oWS  As
                              SageDataObject300.WorkSpace
Dim oTransactionPost  As
                              SageDataObject300.TransactionPost
Dim oSplitData  As
                              SageDataObject300.SplitData

' Declare Variables
Dim bFlag  As Boolean
Dim szDataPath  As
                                  String

' Create the SDO Object
oSDO =  New   SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The select company method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.

If szDataPath <> ""  Then

' Connect to Data Files
If oWS.Connect(szDataPath, "", "", "Example")
                              Then

' Create Instances of Objects
oTransactionPost = oWS.CreateObject("TransactionPost")

' Populate Header fields

' Note:
' You must ensure the Bank_Code field on the header
' is the same as the NOMINAL_CODE on the split
oTransactionPost.Header("BANK_CODE").Value = CStr("1200")
oTransactionPost.Header("DATE").Value = CDate(Today)
oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoJC)
oTransactionPost.Header("DETAILS").Value = CStr("Bank Transfer")
oTransactionPost.Header("INV_REF").Value = CStr("SDO")

' Note:
' A JC and JD only have 1 split

' Add a split to the Header Item's collection
oSplitData = oTransactionPost.Items.Add

' Populate Split Fields
oSplitData.Fields.Item("TYPE").Value = oTransactionPost.Header("TYPE").Value
oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr(oTransactionPost.Header("BANK_CODE").Value)
oSplitData.Fields.Item("TAX_CODE").Value = CShort(9)
oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(100)
oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(0)
oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)
oSplitData.Fields.Item("DETAILS").Value = CStr(oTransactionPost.Header("DETAILS").Value)

' Update the TransactionPost object
If oTransactionPost.Update
                              Then

'   Destroy Objects
oTransactionPost =  Nothing
oSplitData =  Nothing

' Create Instances of Objects
oTransactionPost = oWS.CreateObject("TransactionPost")

' Populate Header fields

' Note:
' You must ensure the Bank_Code field on the header
' is the same as the NOMINAL_CODE on the split
oTransactionPost.Header("BANK_CODE").Value = CStr("1210")
oTransactionPost.Header("DATE").Value = CDate(Today)
oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoJD)
oTransactionPost.Header("DETAILS").Value = CStr("Bank Transfer")
oTransactionPost.Header("INV_REF").Value = CStr("SDO")

' Note:
' A JC and JD only have 1 split

' Add a split to the Header Item's collection
oSplitData = oTransactionPost.Items.Add

' Populate Split Fields
oSplitData.Fields.Item("TYPE").Value = oTransactionPost.Header("TYPE").Value
oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr(oTransactionPost.Header("BANK_CODE").Value)
oSplitData.Fields.Item("TAX_CODE").Value = CShort(9)
oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(100)
oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(0)
oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)
oSplitData.Fields.Item("DETAILS").Value = CStr(oTransactionPost.Header("DETAILS").Value)

End If

' Update the TransactionPost object
If oTransactionPost.Update
                              Then

' Transaction Post Successfull
MsgBox("Transactions Posted successfully", MsgBoxStyle.OKOnly, "SDO Examples")

Else

' Transaction Post Failed
MsgBox("Transaction Post Failed", MsgBoxStyle.OKOnly, "SDO Examples")

End If

' Disconnect
oWS.Disconnect()

End If

End If

oTransactionPost =  Nothing
oSplitData =  Nothing
oWS =  Nothing
oSDO =  Nothing

Exit Sub
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.TransactionPost oTransactionPost;
            SageDataObject300.SplitData oSplitData;

            try
            {
                // Instantiate the TransactionPost object
                oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

                // Populate the Header Fields

                // Note:
                //   You must ensure the Bank_Code field on the header
                //   is the same as the NOMINAL_CODE on the split
                SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);
                SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);
                SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoJC);
                SDOHelper.Write(oTransactionPost.Header, "DETAILS", (String)"Bank Trfr");
                SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"SDO");
                SDOHelper.Write(oTransactionPost.Header, "BANK_CODE", (String)"1200");

                // Create a split item by adding an empty split to the items
                //   Collection of the TransactionPost object
                oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                // Fill in the split fields - note JC's and JD's only have one split
                SDOHelper.Write(oSplitData, "TYPE", Convert.ToByte(SDOHelper.Read(oTransactionPost.Header, "TYPE")));
                SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"1200");
                SDOHelper.Write(oSplitData, "TAX_CODE", (Int32)9);
                SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)100);
                SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)0);
                SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));
                SDOHelper.Write(oSplitData, "DETAILS", (String)SDOHelper.Read(oTransactionPost.Header, "DETAILS"));

                // Update the Transaction Post object
                if (oTransactionPost.Update())
                {
                    // Destroy objects
                    oTransactionPost = null;
                    oSplitData = null;

                    // Instantiate the TransactionPost object
                    oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

                    // Note:
                    //   You must ensure the Bank_Code field on the header
                    //   is the same as the NOMINAL_CODE on the split
                    SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);
                    SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);
                    SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoJD);
                    SDOHelper.Write(oTransactionPost.Header, "DETAILS", (String)"Bank Trfr");
                    SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"SDO");
                    SDOHelper.Write(oTransactionPost.Header, "BANK_CODE", (String)"1210");

                    // Create a split item by adding an empty split to the items
                    //   Collection of the TransactionPost object
                    oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                    // Fill in the split fields - note JC's and JD's only have one split
                    SDOHelper.Write(oSplitData, "TYPE", Convert.ToByte(SDOHelper.Read(oTransactionPost.Header, "TYPE")));
                    SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"1210");
                    SDOHelper.Write(oSplitData, "TAX_CODE", (Int32)9);
                    SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)100);
                    SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)0);
                    SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));
                    SDOHelper.Write(oSplitData, "DETAILS", (String)SDOHelper.Read(oTransactionPost.Header, "DETAILS"));

                    if (oTransactionPost.Update())
                    {
                         MessageBox.Show("Transactions Posted successfully", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    }
                    else
                    {
                        MessageBox.Show("Transaction Failed To Post", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }

                // Disconnect
                oWS.Disconnect();
            }
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Posting a BACS Purchase Payment

Example - Posting a BACS Purchase Payment

The example code below demonstrates how to post a Purchase Payment which will appear in the Sage 50 Accounts Bank/E Payments option. In order to do this the Purchase Record - Online Payments ("BACS") option has to be set to true (1) and the Purchase Payment transaction has to have a reference ("INV_REF") of "(BACS)".

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code

' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oPurchaseRecord As SageDataObject300.PurchaseRecord
Dim oTransactionPost As SageDataObject300.TransactionPost
Dim oSplitData As SageDataObject300.SplitData
Dim oHeaderData As SageDataObject300.HeaderData

' Declare Variables
Dim szDataPath As String
Dim bTransactionFound, bPosted, bAllocated As Boolean
Dim dPaymentValue As Double
Dim lPaymentSplit, lInvoiceSplit As Long

' Error Handler
Try

' Create the SDO Engine object
oSDO = New SageDataObject300.SDOEngine()

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

' Connect to Data Files
oWS.Connect(szDataPath, "", "", "Example")

' Create an instance of the PurchaseRecord object
oPurchaseRecord = oWS.CreateObject("PurchaseRecord")

' Initialise Index Field with value to search
oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value = CStr("CON001")

' Perform Find for an exact match
If oPurchaseRecord.Find(False) Then

' Check if the Purchase Record has been set to allow online payments
' if not then change the setting on the Purchase Record.
If oPurchaseRecord.Fields.Item("BACS").Value = CShort(0) Then

oPurchaseRecord.Edit()
oPurchaseRecord.Fields.Item("BACS").Value = CShort(1)
oPurchaseRecord.Update()

End If

' Link to Headers
oHeaderData = oPurchaseRecord.Link

' Move to the first Header on the Purchase Ledger account
oHeaderData.MoveFirst()

' Attempt to find an Invoice.
' Loop through the Headers until the Invoice Reference is found
Do

If oHeaderData.Fields.Item("INV_REF").Value = CStr("18") Then

' Set the invoice transaction found flag
bTransactionFound = True

' Exit the loop
Exit Do

End If

Loop Until Not oHeaderData.MoveNext

If bTransactionFound Then

' Link to Splits
oSplitData = oHeaderData.Link

' Move to first Split
oSplitData.MoveFirst()

' Calculate Purchase Payment Value
dPaymentValue = CDbl(oSplitData.Fields.Item("NET_AMOUNT").Value) + CDbl(oSplitData.Fields.Item("TAX_AMOUNT").Value) - CDbl(oSplitData.Fields.Item("AMOUNT_PAID").Value)

' Store Split Number for Invoice
lInvoiceSplit = oSplitData.RecordNumber

If dPaymentValue > 0 Then

' Create an instance of TransactionPost for the Purchase Payment
oTransactionPost = oWS.CreateObject("TransactionPost")

' Fill in the Header fields
oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value = CDate(Today)
oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoPP)
oTransactionPost.Header("DETAILS").Value = CStr("Purchase Payment")
oTransactionPost.Header("INV_REF").Value = CStr("(BACS)") ' Note: This is important.
oTransactionPost.Header("BANK_CODE").Value = CStr("1200")
oTransactionPost.Header("USER_NAME").Value = CStr("SDO")

 'Populate the foreign currency fields
oTransactionPost.Header("CURRENCY").Value = oPurchaseRecord.Fields.Item("CURRENCY").Value

' Destroy Existing Split Object
oSplitData = Nothing

' Create a split item by adding an empty split to the Items
' collection of the TransactionPost Object.
oSplitData = oTransactionPost.Items.Add()

' Fill in the Split fields - note a Purchase Payment only has one split
oSplitData.Fields.Item("TYPE").Value = CByte(SageDataObject300.TransType.sdoPP)
oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("1200")
oSplitData.Fields.Item("TAX_CODE").Value = CInt(9)
oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(dPaymentValue)
oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(0)
oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)
oSplitData.Fields.Item("DETAILS").Value = CStr(oTransactionPost.Header("DETAILS").Value)
oSplitData.Fields.Item("USER_NAME").Value = CStr("SDO")

' Update the TransactionPost object
bPosted = oTransactionPost.Update

If bPosted Then

' Read HeaderData for Payment
oHeaderData.Read(oTransactionPost.PostingNumber)

' Store Split Number for Payment
lPaymentSplit = oHeaderData.Fields.Item("FIRST_SPLIT").Value

' Allocate Payment Against Invoice
bAllocated = oTransactionPost.AllocatePayment(CLng(lInvoiceSplit), CLng(lPaymentSplit), CDbl(dPaymentValue), CDate(Today))

If bAllocated Then

MessageBox.Show("Purchase payment posted and allocated successfully. ", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Information)

End If

End If

End If

End If

End If

End If

' Error Handling Code
 Catch ex As Exception

Select Case ex.Source

Case "Sage Data Objects"

MessageBox.Show("The SDO generated the following error: " & oSDO.LastError.Text, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

Case Else

MessageBox.Show("A non-SDO error has been generated: " & ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

End Select

Finally

If Not oWS Is Nothing Then
' Disconnect
oWS.Disconnect()
oWS = Nothing
End If

' Destroy Objects
If Not oSDO Is Nothing Then oSDO = Nothing
If Not oPurchaseRecord Is Nothing Then oPurchaseRecord = Nothing
If Not oHeaderData Is Nothing Then oHeaderData = Nothing
If Not oSplitData Is Nothing Then oSplitData = Nothing
If Not oTransactionPost Is Nothing Then oTransactionPost = Nothing

End Try

C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.PurchaseRecord oPurchaseRecord;
            SageDataObject300.TransactionPost oTransactionPost;
            SageDataObject300.SplitData oSplitData;
            SageDataObject300.HeaderData oHeaderData;
            String szDataPath;
            Double dPaymentValue;
            Int32 lPaymentSplit, lInvoiceSplit;
            Boolean bTransactionFound = false;

            try
            {
                //Instantiate the Purchase Record object
                oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");

                //Initialise Index Field with value to search
                SDOHelper.Write(oPurchaseRecord, "ACCOUNT_REF", (String)"SUPP0001");

                //Perform a find for an exact match
                if (oPurchaseRecord.Find(false))
                {
                    // Check if the Purchase Record has been set to allow online payments
                    //   if not then change the setting on the Purchase Record
                    if ((Int16)SDOHelper.Read(oPurchaseRecord, "BACS") == (Int16)0)
                    {
                        oPurchaseRecord.Edit();
                        SDOHelper.Write(oPurchaseRecord, "BACS", (Int16)1);
                        oPurchaseRecord.Update();
                    }

                    //Link to headers
                    oHeaderData = (SageDataObject300.HeaderData)oPurchaseRecord.Link;

                    //Move to the first header on the purchase ledger account
                    oHeaderData.MoveFirst();

                    //Attempt to find an invoice
                    //Loop through the headers until the invoice reference is found
                    do
                    {
                        if ((String)SDOHelper.Read(oHeaderData, "INV_REF") == (String)"0001")
                        {
                            //Set the invoice transaction found flag
                            bTransactionFound = true;
                            break; //exit the do loop

                        }
                    } while (oHeaderData.MoveNext());

                    if (bTransactionFound)
                    {
                        //Link to Splits
                        oSplitData = (SageDataObject300.SplitData)oHeaderData.Link;

                        //Move to the first split
                        oSplitData.MoveFirst();

                        //Calculate Purchase Payment Value
                        dPaymentValue = (Double)SDOHelper.Read(oSplitData, "NET_AMOUNT") + (Double)SDOHelper.Read(oSplitData, "TAX_AMOUNT") - (Double)SDOHelper.Read(oSplitData, "AMOUNT_PAID");

                        //Store split number for invoice
                        lInvoiceSplit = (Int32)oSplitData.RecordNumber;

                        if (dPaymentValue > 0)
                        {
                            //Create and instance of the TransactionPost object for the purchase payment
                            oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

                            //Populate the Header Fields
                            SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"));
                            SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);
                            SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);
                            SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoPP);
                            SDOHelper.Write(oTransactionPost.Header, "DETAILS", (String)"Purchase Payment");
                            SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"BACS"); /* **IMPORTANT** */
                            SDOHelper.Write(oTransactionPost.Header, "BANK_CODE", (String)"1200");

                            //Populate the foreign currency fields
                            SDOHelper.Write(oTransactionPost.Header, "CURRENCY", SDOHelper.Read(oPurchaseRecord, "CURRENCY"));

                            //Destroy Existing Split Object
                            oSplitData = null;

                            //Create a split item by adding an empty split to the items
                            //Collection of the TransactionPost object
                            oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                            //Fill in the split fields - note a purchase payment only has one split
                            SDOHelper.Write(oSplitData, "TYPE", (Byte)SageDataObject300.TransType.sdoPP);
                            SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"1200");
                            SDOHelper.Write(oSplitData, "TAX_CODE", (Int32)9);
                            SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)dPaymentValue);
                            SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)0);
                            SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));
                            SDOHelper.Write(oSplitData, "DETAILS", (String)SDOHelper.Read(oTransactionPost.Header, "DETAILS"));

                            //Update the Transaction Post object
                            if (oTransactionPost.Update())
                            {
                                //Read Header Data for Payment
                                oHeaderData.Read(oTransactionPost.PostingNumber);

                                //Store Split Number for Payment
                                lPaymentSplit = (Int32)SDOHelper.Read(oHeaderData, "FIRST_SPLIT");

                                //Allocate payment against invoice
                                if (oTransactionPost.AllocatePayment((Int32)lInvoiceSplit, (Int32)lPaymentSplit, (Double)dPaymentValue, (DateTime)DateTime.Today))
                                {
                                    MessageBox.Show("Purchase Payment posted, and allocated successfully");
                                }
                                else
                                {
                                    MessageBox.Show("Allocation Failed");
                                }
                            }
                            else
                            {
                                MessageBox.Show("Transaction Failed To Post");
                            }
                        }
                    }
                }

                // Disconnect
                oWS.Disconnect();
            }
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Posting a Sales Receipt Against an Existing Invoice

Example - Posting a Sales Receipt Against an Existing Invoice

The example code below demonstrates how to post a Sales Receipt and allocate it to an existing invoice.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
                              ' Declare Objects
Dim oSDO  As
                              SageDataObject300.SDOEngine
Dim oWS  As
                              SageDataObject300.WorkSpace
Dim  oSalesRecord  As
                              SageDataObject300.SalesRecord
Dim oTransactionPost  As
                              SageDataObject300.TransactionPost
Dim oSplitData As SageDataObject300.SplitData
Dim oHeaderData  As
                              SageDataObject300.HeaderData

' Declare Variables
Dim szDataPath  As String
Dim bRecordFound, bTransactionFound, bPosted, bAllocated
                               As Boolean
Dim dReceiptValue  As Double
Dim  lReceiptSplit, lInvoiceSplit As Long

' Create the SDO Engine object
oSDO =  New SageDataObject300.SDOEngine()

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to   the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> ""  Then

' Connect to Data Files
oWS.Connect(szDataPath, "", "", "Example")

' Create an instance of the SalesRecord object
oSalesRecord = oWS.CreateObject("SalesRecord")

' Initialise Index Field with value to search
oSalesRecord.Fields.Item("ACCOUNT_REF").Value = CStr("ABS001")

' Perform Find for an exact match
bRecordFound = oSalesRecord.Find(False)

If bRecordFound  Then

' Link to Headers
oHeaderData = oSalesRecord.Link

' Move to the first Header on the Purchase Ledger account
oHeaderData.MoveFirst()

' Attempt to find an Invoice.
' Loop through the Headers until the Invoice Reference is found
Do

If oHeaderData.Fields.Item("INV_REF").Value =
                              CStr("58")  Then

' Set the invoice transaction found flag
bTransactionFound = True

' Exit the loop
Exit Do

End If

Loop Until Not oHeaderData.MoveNext

If  bTransactionFound
                               Then

' Link to
                                  Splits
oSplitData = oHeaderData.Link

' Move to first Split
oSplitData.MoveFirst()

' Calculate Sales Receipt Value
dReceiptValue = CDbl(oSplitData.Fields.Item("NET_AMOUNT").Value) + CDbl(oSplitData.Fields.Item("TAX_AMOUNT").Value) -
                              CDbl(oSplitData.Fields.Item("AMOUNT_PAID").Value)

' Store Split Number for Invoice
lInvoiceSplit = oSplitData.RecordNumber

If dReceiptValue > 0
                               Then

' Create an instance of TransactionPost for the Sales Receipt
oTransactionPost = oWS.CreateObject("TransactionPost")

' Fill in the Header fields
oTransactionPost.Header("ACCOUNT_REF").Value =
                              CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value =
                              CDate(Today)
oTransactionPost.Header("POSTED_DATE").Value =
                              CDate(Today)
oTransactionPost.Header("TYPE").Value =
                              CByte(SageDataObject300.TransType.sdoSR)
oTransactionPost.Header("INV_REF").Value =
                              CStr("BACS")
oTransactionPost.Header("BANK_CODE").Value = CStr("1200")

' Populate the foreign currency fields
oTransactionPost.Header("CURRENCY").Value = oSalesRecord.Fields.Item("CURRENCY").Value

' Destroy Existing Split Object
oSplitData =  Nothing

' Create a split item by adding an empty split to the Items
' collection of the TransactionPost Object.
oSplitData = oTransactionPost.Items.Add()

' Fill in the Split fields - note a Sales Receipt only has one split
oSplitData.Fields.Item("TYPE").Value =
                              CByte(SageDataObject300.TransType.sdoSR)
oSplitData.Fields.Item("NOMINAL_CODE").Value =
                              CStr("1200")
oSplitData.Fields.Item("TAX_CODE").Value =
                              CInt(9)
oSplitData.Fields.Item("NET_AMOUNT").Value =
                              CDbl(dReceiptValue)
oSplitData.Fields.Item("TAX_AMOUNT").Value =
                              CDbl(0)
oSplitData.Fields.Item("DATE").Value =
                              CDate(oTransactionPost.Header("DATE").Value)
oSplitData.Fields.Item("DETAILS").Value =
                              CStr(oTransactionPost.Header("DETAILS").Value)

' Update the TransactionPost object
bPosted = oTransactionPost.Update

If bPosted
                               Then

' Read HeaderData for Receipt
oHeaderData.Read(oTransactionPost.PostingNumber)

' Store Split Number for Receipt
lReceiptSplit = oHeaderData.Fields.Item("FIRST_SPLIT").Value

' Allocate Receipt Against Invoice
bAllocated =
                                oTransactionPost.AllocatePayment(CLng(lInvoiceSplit),
                              CLng(lReceiptSplit), CDbl(dReceiptValue),
                              CDate(Today))

If bAllocated
                               Then

MsgBox("Sales receipt posted, and allocated successfully.")

End If

End If

End If

End If

End If

' Disconnect
oWS.Disconnect()

End If

' Destroy Objects
oSalesRecord =  Nothing
oHeaderData =  Nothing
oSplitData =  Nothing
oTransactionPost =  Nothing
oSDO =  Nothing
oWS =  Nothing

Exit Sub
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.SalesRecord oSalesRecord;
            SageDataObject300.TransactionPost oTransactionPost;
            SageDataObject300.SplitData oSplitData;
            SageDataObject300.HeaderData oHeaderData;
            Double dPaymentValue;
            Int32 lPaymentSplit, lInvoiceSplit;
            Boolean bTransactionFound = false;

            try
            {
                //Instantiate the Sales Record object
                oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");

                //Initialise Index Field with value to search
                SDOHelper.Write(oSalesRecord, "ACCOUNT_REF", (String)"CUST0001");

                //Perform a find for an exact match
                if (oSalesRecord.Find(false))
                {
                    //Link to headers
                    oHeaderData = (SageDataObject300.HeaderData)oSalesRecord.Link;

                    //Move to the first header on the Sales ledger account
                    oHeaderData.MoveFirst();

                    //Attempt to find an invoice
                    //Loop through the headers until the invoice reference is found
                    do
                    {
                        if ((String)SDOHelper.Read(oHeaderData, "INV_REF") == (String)"0001")
                        {
                            //Set the invoice transaction found flag
                            bTransactionFound = true;
                            break; //exit the do loop
                        }
                    } while (oHeaderData.MoveNext());

                    if (bTransactionFound)
                    {
                        //Link to Splits
                        oSplitData = (SageDataObject300.SplitData)oHeaderData.Link;

                        //Move to the first split
                        oSplitData.MoveFirst();

                        //Calculate Sales Receipt Value
                        dPaymentValue = (Double)SDOHelper.Read(oSplitData, "NET_AMOUNT") + (Double)SDOHelper.Read(oSplitData, "TAX_AMOUNT") -  (Double)SDOHelper.Read(oSplitData, "AMOUNT_PAID");

                        //Store split number for invoice
                        lInvoiceSplit = (Int32)oSplitData.RecordNumber;

                        if (dPaymentValue > 0)
                        {
                            //Create and instance of the TransactionPost object for the Sales Receipt
                            oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

                            //Populate the Header Fields
                            SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));
                            SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);
                            SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);
                            SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoSR);
                            SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"REC0001");
                            SDOHelper.Write(oTransactionPost.Header, "BANK_CODE", (String)"1200");

                            //Populate the foreign currency fields
                            SDOHelper.Write(oTransactionPost.Header, "CURRENCY", SDOHelper.Read(oSalesRecord, "CURRENCY"));

                            //Destroy Existing Split Object
                            oSplitData = null;

                            //Create a split item by adding an empty split to the items
                            //Collection of the TransactionPost object
                            oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                            //Fill in the split fields - note a Sales Receipt only has one split
                            SDOHelper.Write(oSplitData, "TYPE", (Byte)SageDataObject300.TransType.sdoSR);
                            SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"1200");
                            SDOHelper.Write(oSplitData, "TAX_CODE", (Int32)9);
                            SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)dPaymentValue);
                            SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)0);
                            SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));
                            SDOHelper.Write(oSplitData, "DETAILS", (String)SDOHelper.Read(oTransactionPost.Header, "DETAILS"));

                            //Update the Transaction Post object
                            if (oTransactionPost.Update())
                            {
                                //Read Header Data for receipt
                                oHeaderData.Read(oTransactionPost.PostingNumber);

                                //Store Split Number for receiptt
                                lPaymentSplit = (Int32)SDOHelper.Read(oHeaderData, "FIRST_SPLIT");

                                //Allocate receipt against invoice
                                if (oTransactionPost.AllocatePayment((Int32)lInvoiceSplit, (Int32)lPaymentSplit, (Double)dPaymentValue, (DateTime)DateTime.Today))
                                {
                                    MessageBox.Show("Sales Receipt posted, and allocated successfully");
                                }
                                else
                                {
                                    MessageBox.Show("Allocation Failed");
                                }
                            }
                            else
                            {
                                MessageBox.Show("Transaction Failed To Post");
                            }
                        }
                    }
                }

                // Disconnect
                oWS.Disconnect();
            }
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Posting a Purchase Payment Against an Existing Invoice

Example - Posting a Purchase Payment Against an Existing Invoice

The example code below demonstrates how to post a Purchase Payment and allocate it to an existing invoice.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
                              ' Declare Objects
Dim oSDO  As
                              SageDataObject300.SDOEngine
Dim oWS  As
                              SageDataObject300.WorkSpace
Dim  oPurchaseRecord  As
                              SageDataObject300.PurchaseRecord
Dim oTransactionPost  As
                              SageDataObject300.TransactionPost
Dim oSplitData As SageDataObject300.SplitData
Dim oHeaderData  As
                              SageDataObject300.HeaderData

' Declare Variables
Dim szDataPath  As String
Dim bRecordFound, bTransactionFound, bPosted, bAllocated
                               As Boolean
Dim  dPaymentValue  As Double
Dim  lPaymentSplit, lInvoiceSplit As Long

' Create the SDO Engine object
oSDO =  New SageDataObject300.SDOEngine()

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to   the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> ""  Then

' Connect to Data Files
oWS.Connect(szDataPath, "", "", "Example")

' Create an instance of the PurchaseRecord object
oPurchaseRecord = oWS.CreateObject("PurchaseRecord")

' Initialise Index Field with value to search
oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value = CStr("CON001")

' Perform Find for an exact match
bRecordFound = oPurchaseRecord.Find(False)

If bRecordFound  Then

' Link to Headers
oHeaderData = oPurchaseRecord.Link

' Move to the first Header on the Purchase Ledger account
oHeaderData.MoveFirst()

' Attempt to find an Invoice.
' Loop through the Headers until the Invoice Reference is found
Do

If oHeaderData.Fields.Item("INV_REF").Value =
                              CStr("18")  Then

' Set the invoice transaction found flag
bTransactionFound = True

' Exit the loop
Exit Do

End If

Loop Until Not oHeaderData.MoveNext

If  bTransactionFound
                               Then

' Link to
                                  Splits
oSplitData = oHeaderData.Link

' Move to first Split
oSplitData.MoveFirst()

' Calculate Purchase
                                  Payment Value
dPaymentValue = CDbl(oSplitData.Fields.Item("NET_AMOUNT").Value) + CDbl(oSplitData.Fields.Item("TAX_AMOUNT").Value) -
                                       CDbl(oSplitData.Fields.Item("AMOUNT_PAID").Value)

' Store Split Number for Invoice
lInvoiceSplit = oSplitData.RecordNumber

If  dPaymentValue > 0
                               Then

' Create an instance of TransactionPost for the
                                  Purchase Payment
oTransactionPost = oWS.CreateObject("TransactionPost")

' Fill in the Header fields
oTransactionPost.Header("ACCOUNT_REF").Value =
                              CStr(oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value =
                              CDate(Today)
oTransactionPost.Header("POSTED_DATE").Value =
                              CDate(Today)
oTransactionPost.Header("TYPE").Value =
                              CByte(SageDataObject300.TransType.sdoPP)
oTransactionPost.Header("INV_REF").Value =
                              CStr("BACS")
oTransactionPost.Header("BANK_CODE").Value = CStr("1200")

' Populate the foreign currency fields
oTransactionPost.Header("CURRENCY").Value = oPurchaseRecord.Fields.Item("CURRENCY").Value

' Destroy Existing Split Object
oSplitData =  Nothing

' Create a split item by adding an empty split to the Items
' collection of the TransactionPost Object.
oSplitData = oTransactionPost.Items.Add()

' Fill in the Split fields - note a
                                  Purchase Payment only has one split
oSplitData.Fields.Item("TYPE").Value =
                              CByte(SageDataObject300.TransType.sdoPP)
oSplitData.Fields.Item("NOMINAL_CODE").Value =
                              CStr("1200")
oSplitData.Fields.Item("TAX_CODE").Value =
                              CInt(9)
oSplitData.Fields.Item("NET_AMOUNT").Value =
                              CDbl(dPaymentValue)
oSplitData.Fields.Item("TAX_AMOUNT").Value =
                              CDbl(0)
oSplitData.Fields.Item("DATE").Value =
                              CDate(oTransactionPost.Header("DATE").Value)
oSplitData.Fields.Item("DETAILS").Value =
                              CStr(oTransactionPost.Header("DETAILS").Value)

' Update the TransactionPost object
bPosted = oTransactionPost.Update

If bPosted
                               Then

' Read HeaderData for Payment
oHeaderData.Read(oTransactionPost.PostingNumber)

' Store Split Number for Payment
lPaymentSplit = oHeaderData.Fields.Item("FIRST_SPLIT").Value

' Allocate
                                  Payment Against Invoice
bAllocated =
                                oTransactionPost.AllocatePayment(CLng(lInvoiceSplit),
                              CLng(lPaymentSplit), CDbl(dPaymentValue),
                              CDate(Today))

If bAllocated
                               Then

MsgBox("Purchase Payment posted, and allocated successfully.")

End If

End If

End If

End If

End If

' Disconnect
oWS.Disconnect()

End If

' Destroy Objects
oPurchaseRecord =  Nothing
oHeaderData =  Nothing
oSplitData =  Nothing
oTransactionPost =  Nothing
oSDO =  Nothing
oWS =  Nothing

Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.PurchaseRecord oPurchaseRecord;

SageDataObject300.TransactionPost oTransactionPost;

SageDataObject300.SplitData oSplitData;

SageDataObject300.HeaderData oHeaderData;

String szDataPath;

Double dPaymentValue;

Int32 lPaymentSplit, lInvoiceSplit;

Boolean bTransactionFound = false;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate the Purchase Record object

  oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");

  //Initialise Index Field with value to search

  SDOHelper.Write(oPurchaseRecord,"ACCOUNT_REF",(String)"CON001");

  //Perform a find for an exact match

  if (oPurchaseRecord.Find(false))

  {

    //Link to headers

    oHeaderData = (SageDataObject300.HeaderData)oPurchaseRecord.Link;

    //Move to the first header on the purchase ledger account

    oHeaderData.MoveFirst();

    //Attempt to find an invoice

    //Loop through the headers until the invoice reference is found

    do

    {

      if ((String)SDOHelper.Read(oHeaderData,"INV_REF") ==

        (String)"18")

      {

        //Set the invoice transaction found flag

        bTransactionFound = true;

        break; //exit the do loop

      }

    } while (oHeaderData.MoveNext());

    if (bTransactionFound)

    {

      //Link to Splits

      oSplitData = (SageDataObject300.SplitData)oHeaderData.Link;

      //Move to the first split

      oSplitData.MoveFirst();

      //Calculate Purchase Payment Value

      dPaymentValue = (Double)SDOHelper.Read(oSplitData, "NET_AMOUNT") +

        (Double)SDOHelper.Read(oSplitData, "TAX_AMOUNT") -

        (Double)SDOHelper.Read(oSplitData, "AMOUNT_PAID");

      //Store split number for invoice

      lInvoiceSplit = (Int32)oSplitData.RecordNumber;

      if (dPaymentValue > 0)

      {

        //Create and instance of the TransactionPost object for the purchase payment

        oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

        //Populate the Header Fields

        SDOHelper.Write(oTransactionPost.Header,"ACCOUNT_REF",

          (String)SDOHelper.Read(oPurchaseRecord,"ACCOUNT_REF"));

        SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);

        SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);

        SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoPP);

        SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"BACS");

        SDOHelper.Write(oTransactionPost.Header, "BANK_CODE", (String)"1200");

        //Populate the foreign currency fields

        SDOHelper.Write(oTransactionPost.Header,"CURRENCY", SDOHelper.Read(oPurchaseRecord,"CURRENCY"));

        //Destroy Existing Split Object

        oSplitData = null;

        //Create a split item by adding an empty split to the items

        //Collection of the TransactionPost object

        oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

        //Fill in the split fields - note a purchase payment only has one split

        SDOHelper.Write(oSplitData,"TYPE",(Byte)SageDataObject300.TransType.sdoPP);

        SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"1200");

        SDOHelper.Write(oSplitData, "TAX_CODE", (Int32)9);

        SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)dPaymentValue);

        SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)0);

        SDOHelper.Write(oSplitData, "DATE",(DateTime)SDOHelper.Read(oTransactionPost.Header,"DATE"));

        SDOHelper.Write(oSplitData, "DETAILS",(String)SDOHelper.Read(oTransactionPost.Header, "DETAILS"));

        //Update the Transaction Post object

        if (oTransactionPost.Update())

        {

          //Read Header Data for Payment

          oHeaderData.Read(oTransactionPost.PostingNumber);

          //Store Split Number for Payment

          lPaymentSplit = (Int32)SDOHelper.Read(oHeaderData, "FIRST_SPLIT");

          //Allocate payment against invoice

          if (oTransactionPost.AllocatePayment((Int32)lInvoiceSplit, (Int32)lPaymentSplit,

            (Double)dPaymentValue, (DateTime)DateTime.Today))

          {

            MessageBox.Show("Purchase Payment posted, and allocated successfully");

          }

          else

          {

            MessageBox.Show("Allocation Failed");

          }

        }

        else

        {

          MessageBox.Show("Transaction Failed To Post");

        }

      }

    }

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Posting a Purchase Payment And Cheque

Example - Posting a Purchase Payment And Cheque

The example code below demonstrates how to post a Purchase Payment and allocate it to an existing invoice. It also creates a cheque for the payment.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code

 ' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oSetupData As SageDataObject300.SetupData
Dim oRemittanceRecord As SageDataObject300.RemittanceRecord
Dim oPurchaseRecord As SageDataObject300.PurchaseRecord
Dim oTransactionPost As SageDataObject300.TransactionPost
Dim oSplitData As SageDataObject300.SplitData
Dim oHeaderData As SageDataObject300.HeaderData

' Declare Variables
Dim szDataPath, oURNString,
                                  oIndexString, oInvRef As String
Dim bTransactionFound, bAllocated As Boolean
Dim dPaymentValue As Double
Dim oURNInt,
                                  oIndexInt As Integer
Dim lPaymentSplit,
                                  lInvoiceSplit As Long

' Error Handler
Try

' Create the SDO Engine object
oSDO = New SageDataObject300.SDOEngine()

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany
    method takes the program install folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is
    presented to the user. If a company is selected,
' the path will be passed to the
    szDataPath variable.
' If not, or the Cancel button is
    selected, the variable will be left empty.
If szDataPath
                                <> "" Then

' Connect to Data Files
oWS.Connect(szDataPath, "", "",
                                "Example")

' Create an instance of the
    PurchaseRecord object
oPurchaseRecord = oWS.CreateObject("PurchaseRecord")

' Initialise Index Field with value to
    search
oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value = CStr("CON001")

' Perform Find for an exact match
If oPurchaseRecord.Find(False) Then

' Link to Headers
oHeaderData = oPurchaseRecord.Link

' Move to the first Header on the
    Purchase Ledger account
oHeaderData.MoveFirst()

' Attempt to find an Invoice.
' Loop through the Headers until the
    Invoice Reference is found
Do

If oHeaderData.Fields.Item("INV_REF").Value = CStr("18") Then

' Set the invoice transaction found
    flag
bTransactionFound = True

' Exit the loop
Exit Do

End If

Loop  oHeaderData.MoveNext

If bTransactionFound Then

' Store the invoice Reference
oInvRef = CStr(oHeaderData.Fields.Item("INV_REF").Value)

' Link to Splits
oSplitData = oHeaderData.Link

' Move to first Split
oSplitData.MoveFirst()

' Calculate Purchase Payment Value
dPaymentValue = CDbl(oSplitData.Fields.Item("NET_AMOUNT").Value)
                                  + CDbl(oSplitData.Fields.Item("TAX_AMOUNT").Value)
                                  - CDbl(oSplitData.Fields.Item("AMOUNT_PAID").Value)

' Store Split Number for Invoice
lInvoiceSplit = oSplitData.RecordNumber

If dPaymentValue
                                > 0 Then

' Create an instance of TransactionPost
    for the Purchase Payment
oTransactionPost = oWS.CreateObject("TransactionPost")

' Fill in the Header fields
oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value = CDate(Today)
oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoPP)
oTransactionPost.Header("BANK_CODE").Value = CStr("1200")

' Populate the foreign currency fields
oTransactionPost.Header("CURRENCY").Value = oPurchaseRecord.Fields.Item("CURRENCY").Value)

' Destroy Existing Split Object
oSplitData = Nothing

' Create a split item by adding an
    empty split to the Items
'
    collection of the TransactionPost
    Object.
oSplitData =
                                  oTransactionPost.Items.Add()

' Fill in the Split fields - note a
    Purchase Payment only has one split
oSplitData.Fields.Item("TYPE").Value = CByte(SageDataObject300.TransType.sdoPP)
oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("1200")
oSplitData.Fields.Item("TAX_CODE").Value = CInt(9)
oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(dPaymentValue)
oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(0)
oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)
oSplitData.Fields.Item("DETAILS").Value = CStr("SDO
                                  Purchase Payment")

' Update the TransactionPost object
If oTransactionPost.Update Then

' Read HeaderData for Payment
oHeaderData.Read(oTransactionPost.PostingNumber)

' Store Split Number for Payment
lPaymentSplit = oHeaderData.Fields.Item("FIRST_SPLIT").Value

' Allocate Payment Against Invoice
bAllocated = oTransactionPost.AllocatePayment(CLng(lInvoiceSplit), CLng(lPaymentSplit), CDbl(dPaymentValue), CDate(Today))

If bAllocated Then

MessageBox.Show("Purchase Payment posted, and allocated successfully.",
                                "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)

' Process the remittance
oSetupData = oWS.CreateObject("SetupData")
oRemittanceRecord = oWS.CreateObject("RemittanceRecord")

' Destroy Existing Split Object and
    re-create
oSplitData = Nothing

oSplitData = oWS.CreateObject("SplitData")

' Read the Invoice Split
oSplitData.Read(CInt(lInvoiceSplit))

' Create the URN by incrementing the
    last cheque number
oURNInt = oSetupData.Fields.Item("LAST_CHEQUE").Value
oURNInt = oURNInt + 1
oURNString = CStr(oURNInt)

' Pad the URN with spaces
oURNString = oURNString.PadLeft(7, "0")

' The INDEX number of the PI entry .
    Here we are paying 1 PI so the first PI entry has an INDEX value
' of 0, a second one would be 1 etc.
oIndexInt = 1
oIndexString = CStr(oIndexInt).PadLeft(8,
                                "0")

' Add a New Remittance Record
oRemittanceRecord.AddNew()

' Populate Fields Remittance Purchase Invoice Details
oRemittanceRecord.Fields.Item("ACCOUNT_REF").Value = CStr(oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value)
oRemittanceRecord.Fields.Item("ADDRESS_1").Value = CStr(oPurchaseRecord.Fields.Item("ADDRESS_1").Value)
oRemittanceRecord.Fields.Item("ADDRESS_2").Value = CStr(oPurchaseRecord.Fields.Item("ADDRESS_2").Value)
oRemittanceRecord.Fields.Item("ADDRESS_3").Value = CStr(oPurchaseRecord.Fields.Item("ADDRESS_3").Value)
oRemittanceRecord.Fields.Item("ADDRESS_4").Value = CStr(oPurchaseRecord.Fields.Item("ADDRESS_4").Value)
oRemittanceRecord.Fields.Item("ADDRESS_5").Value = CStr(oPurchaseRecord.Fields.Item("ADDRESS_5").Value)
oRemittanceRecord.Fields.Item("BANK").Value = CStr("1200")
oRemittanceRecord.Fields.Item("DATE").Value = CDate(oSplitData.Fields.Item("DATE").Value)
oRemittanceRecord.Fields.Item("DETAILS").Value = CStr(oSplitData.Fields.Item("DETAILS").Value)
oRemittanceRecord.Fields.Item("FAX").Value = CStr(oPurchaseRecord.Fields.Item("FAX").Value)
oRemittanceRecord.Fields.Item("GROSS_AMOUNT").Value = CDbl(dPaymentValue)
oRemittanceRecord.Fields.Item("INV_REF").Value = CStr(oInvRef)
oRemittanceRecord.Fields.Item("INDEX").Value = CStr(oIndexString)
oRemittanceRecord.Fields.Item("LASTLINE_FLAG").Value = CShort(0)
oRemittanceRecord.Fields.Item("NAME").Value = CStr(oPurchaseRecord.Fields.Item("NAME").Value)
oRemittanceRecord.Fields.Item("NET_AMOUNT").Value = CDbl(oSplitData.Fields.Item("NET_AMOUNT").Value)
oRemittanceRecord.Fields.Item("PAYMENT_AMOUNT").Value = CDbl(0
                                  - (CDbl(dPaymentValue)))
oRemittanceRecord.Fields.Item("PAYMENT_DATE").Value = CDate(Today)
oRemittanceRecord.Fields.Item("PAYMENT_FLAG").Value = CShort(0)

' Note The PAYMENT_NO field is used to update the bank transaction with the cheque number.  This
' is a PI transaction so the PI will not be updated with the cheque reference number
oRemittanceRecord.Fields.Item("PAYMENT_NO").Value = CInt(oSplitData.Fields.Item("TRAN_NUMBER").Value)
oRemittanceRecord.Fields.Item("PRINTED_FLAG").Value = CShort(0)
oRemittanceRecord.Fields.Item("TAX_CODE").Value = CStr("T")
                                & CStr(oSplitData.Fields.Item("TAX_CODE").Value)
oRemittanceRecord.Fields.Item("TELEPHONE").Value =
                                  oPurchaseRecord.Fields.Item("TELEPHONE").Value
oRemittanceRecord.Fields.Item("TRAN_TYPE").Value = CStr("PI")
oRemittanceRecord.Fields.Item("URN").Value = CStr(oURNString)
oRemittanceRecord.Fields.Item("VAT_AMOUNT").Value = CDbl(oSplitData.Fields.Item("TAX_AMOUNT").Value)

'Post Invoice
If oRemittanceRecord.Update Then

MessageBox.Show("PI Remittance Entry Posted", "SDO
                                  Examples", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)

Else

MessageBox.Show("PI Remittance Entry Has Not Been Posted", "SDO
                                  Examples", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)

End If

oRemittanceRecord = Nothing

oRemittanceRecord = oWS.CreateObject("RemittanceRecord")

' Positiion osplitdata to first split
oSplitData.Read(lPaymentSplit)

' Increment the Index number
oIndexInt = CInt(oIndexInt
                                  + 1)
oIndexString = CStr(oIndexInt).PadLeft(8,
                                "0")

' Add a New Remittance Record
oRemittanceRecord.AddNew()

' Populate Fields Remittance Purchase Payment Details
oRemittanceRecord.Fields.Item("ACCOUNT_REF").Value =
                                  oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value
oRemittanceRecord.Fields.Item("ADDRESS_1").Value =
                                  oPurchaseRecord.Fields.Item("ADDRESS_1").Value
oRemittanceRecord.Fields.Item("ADDRESS_2").Value =
                                  oPurchaseRecord.Fields.Item("ADDRESS_2").Value
oRemittanceRecord.Fields.Item("ADDRESS_3").Value =
                                  oPurchaseRecord.Fields.Item("ADDRESS_3").Value
oRemittanceRecord.Fields.Item("ADDRESS_4").Value =
                                  oPurchaseRecord.Fields.Item("ADDRESS_4").Value
oRemittanceRecord.Fields.Item("ADDRESS_5").Value =
                                  oPurchaseRecord.Fields.Item("ADDRESS_5").Value
oRemittanceRecord.Fields.Item("BANK").Value = CStr(oSplitData.Fields.Item("NOMINAL_CODE").Value)
oRemittanceRecord.Fields.Item("DATE").Value = CDate(Today)
oRemittanceRecord.Fields.Item("DETAILS").Value = CStr(oSplitData.Fields.Item("DETAILS").Value)
oRemittanceRecord.Fields.Item("FAX").Value =
                                  oPurchaseRecord.Fields.Item("FAX").Value
oRemittanceRecord.Fields.Item("GROSS_AMOUNT").Value = CDbl(0.0#)
oRemittanceRecord.Fields.Item("INDEX").Value = CStr(oIndexString)
oRemittanceRecord.Fields.Item("LASTLINE_FLAG").Value = CShort(0)
oRemittanceRecord.Fields.Item("NAME").Value =
                                  oPurchaseRecord.Fields.Item("NAME").Value
oRemittanceRecord.Fields.Item("NET_AMOUNT").Value = CDbl(oSplitData.Fields.Item("NET_AMOUNT").Value)
oRemittanceRecord.Fields.Item("PAYMENT_AMOUNT").Value = CDbl(0
                                  - CDbl(oSplitData.Fields.Item("NET_AMOUNT").Value))
oRemittanceRecord.Fields.Item("PAYMENT_DATE").Value = CDate(Today)
oRemittanceRecord.Fields.Item("PAYMENT_FLAG").Value = CShort(1)

' The PAYMENT_NO field is used to update the bank transaction with the cheque number.  To do this we
' need to pass the payment's last split's transaction number.
oRemittanceRecord.Fields.Item("PAYMENT_NO").Value = CInt(oSplitData.Fields.Item("TRAN_NUMBER").Value)
oRemittanceRecord.Fields.Item("PRINTED_FLAG").Value = CShort(0)
oRemittanceRecord.Fields.Item("TAX_CODE").Value = CStr("T9")
oRemittanceRecord.Fields.Item("TELEPHONE").Value = CStr(oPurchaseRecord.Fields.Item("TELEPHONE").Value)
oRemittanceRecord.Fields.Item("TRAN_TYPE").Value = CStr("PP")
oRemittanceRecord.Fields.Item("URN").Value = CStr(oURNString)
oRemittanceRecord.Fields.Item("VAT_AMOUNT").Value = CDbl(0.0#)

' Post Payment
If oRemittanceRecord.Update Then

MessageBox.Show("PP Remittance Entry Posted", "SDO
                                  Examples", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)

' Increment the last cheque number
oSetupData.Fields.Item("LAST_CHEQUE").Value = oURNInt
oSetupData.Write(1)

Else

MessageBox.Show("PP Remittance Entry Has Not Been Posted", "SDO
                                  Examples", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)

End If

End If

End If

End If

End If

End If

End If

' Error Handling Code
Catch ex As Exception

Select Case ex.Source

Case "Sage
                                  Data Objects"

MessageBox.Show("The SDO generated the following error: " &
                                oSDO.LastError.Text, "SDO Examples", MessageBoxButtons.OK,
                                  MessageBoxIcon.Error)

Case Else

MessageBox.Show("A non-SDO error has been generated: " &
                                ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

End Select

Finally

' Destroy Objects
If Not oWS Is Nothing Then
' Disconnect
oWS.Disconnect()
oWS = Nothing
oSDO = Nothing
End If

If Not oPurchaseRecord Is Nothing Then
oPurchaseRecord = Nothing
End If

If Not oHeaderData Is Nothing Then
oHeaderData = Nothing
End If

If Not oSplitData Is Nothing Then
oSplitData = Nothing
End If

If Not oSetupData Is Nothing Then
oSetupData = Nothing
End If

If Not oRemittanceRecord Is Nothing Then
oRemittanceRecord = Nothing
End If

If Not oTransactionPost Is Nothing Then
oTransactionPost = Nothing
End If

End Try
C#.NET [image] Copy C# Code
    // Declare Objects
    SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
    SageDataObject300.WorkSpace oWS;
    SageDataObject300.SetupData oSetupData;
    SageDataObject300.RemittanceRecord oRemittanceRecord;
    SageDataObject300.PurchaseRecord oPurchaseRecord;
    SageDataObject300.TransactionPost oTransactionPost;
    SageDataObject300.SplitData oSplitData;
    SageDataObject300.HeaderData oHeaderData;

    // Declare Variables
    String szDataPath;
    String oURNString;
    String oIndexString;
    String oInvRef;
    Boolean bTransactionFound = false;
    Boolean bAllocated;
    Double dPaymentValue;
    Int32 oURNInt;
    Int32 oIndexInt;
    Int64 lPaymentSplit;
    Int64 lInvoiceSplit;

    // Error Handler
    try
    {

        //Instantiate WorkSpace
        oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

        // Select company. The SelectCompany method takes the program install folder as a parameter
        szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

        // A U.I. for company selection is presented to the user. If a company is selected,
        // the path will be passed to the szDataPath variable.
        // If not, or the Cancel button is selected, the variable will be left empty.
        if (szDataPath != "")
        {

            // Connect to Data Files
            oWS.Connect(szDataPath, "", "", "Example");

            // Create an instance of the PurchaseRecord object
            oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");

            // Initialise Index Field with value to search
            SDOHelper.Write(oPurchaseRecord, "ACCOUNT_REF", "TEST");

            // Perform Find for an exact match
            if (oPurchaseRecord.Find(false))
            {

                // Link to Headers
                oHeaderData = (SageDataObject300.HeaderData)oPurchaseRecord.Link;

                // Move to the first Header on the Purchase Ledger account
                oHeaderData.MoveFirst();

                //Attempt to find an Invoice.
                //Loop through the Headers until the Invoice Reference is found
                do
                {
                    //Change the value according to the previous messagebox
                    if (Convert.ToString((SDOHelper.Read(oHeaderData, "INV_REF"))) == "1")
                    {

                        // Set the invoice transaction found flag
                        bTransactionFound = true;

                        // Exit the loop
                        break;

                    }
                    else
                    {
                        MessageBox.Show("INV_REF not found", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                    }
                }

                while (oHeaderData.MoveNext());

                if (bTransactionFound == true)
                {
                    // Store the invoice Reference
                    oInvRef = (String)SDOHelper.Read(oHeaderData, "INV_REF");

                    // Link to Splits
                    oSplitData = (SageDataObject300.SplitData)oHeaderData.Link;

                    // Move to first Split
                    oSplitData.MoveFirst();

                    // Calculate Purchase Payment Value
                    dPaymentValue = (Double)SDOHelper.Read(oSplitData, "NET_AMOUNT") + (Double)SDOHelper.Read(oSplitData, "TAX_AMOUNT") - (double)SDOHelper.Read(oSplitData, "AMOUNT_PAID");

                    // Store Split Number for Invoice
                    lInvoiceSplit = oSplitData.RecordNumber;

                    if (dPaymentValue > 0)
                    {

                        // Create an instance of TransactionPost for the Purchase Payment
                        oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

                        // Fill in the Header fields
                        SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"));
                        SDOHelper.Write(oTransactionPost.Header, "DATE", DateTime.Today);
                        SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", DateTime.Today);
                        SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoPP);
                        SDOHelper.Write(oTransactionPost.Header, "BANK_CODE", (String)"1200");

                        // Populate the foreign currency fields
                        SDOHelper.Write(oTransactionPost.Header, "CURRENCY", SDOHelper.Read(oPurchaseRecord, "CURRENCY"));

                        // Destroy Existing Split Object
                        oSplitData = null;

                        // Create a split item by adding an empty split to the Items
                        // collection of the TransactionPost Object.
                        oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                        // Fill in the Split fields - note a Purchase Payment only has one split
                        SDOHelper.Write(oSplitData, "TYPE", (Byte)SageDataObject300.TransType.sdoPP);
                        SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"1200");
                        SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)9);
                        SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)dPaymentValue);
                        SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)0);
                        SDOHelper.Write(oSplitData, "DATE", SDOHelper.Read(oTransactionPost.Header, "DATE"));
                        SDOHelper.Write(oSplitData, "DETAILS", (String)"SDO Purchase Payment");

                        // Update the TransactionPost object
                        if (oTransactionPost.Update())
                        {

                            // Read HeaderData for Payment
                            oHeaderData.Read(oTransactionPost.PostingNumber);

                            // Store Split Number for Payment
                            lPaymentSplit = (Int32)SDOHelper.Read(oHeaderData, "FIRST_SPLIT");

                            // Allocate Payment Against Invoice
                            bAllocated = oTransactionPost.AllocatePayment((Int32)lInvoiceSplit, (Int32)lPaymentSplit, (Double)dPaymentValue, (DateTime)DateTime.Today);

                            if (bAllocated)
                            {

                                MessageBox.Show("Purchase Payment posted, and allocated successfully.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);

                                // Process the remittance
                                oSetupData = (SageDataObject300.SetupData)oWS.CreateObject("SetupData");
                                oRemittanceRecord = (SageDataObject300.RemittanceRecord)oWS.CreateObject("RemittanceRecord");

                                // Destroy Existing Split Object and re-create
                                oSplitData = null;

                                oSplitData = (SageDataObject300.SplitData)oWS.CreateObject("SplitData");

                                // Read the Invoice Split
                                oSplitData.Read((int)lInvoiceSplit);

                                // Create the URN by incrementing the last remittance number
                                oURNInt = (Int32)SDOHelper.Read(oSetupData, "LAST_CHEQUE");
                                oURNInt = oURNInt + 1;
                                oURNString = Convert.ToString(oURNInt);

                                // Pad the URN with spaces
                                oURNString = oURNString.PadLeft(7, '0');

                                // The INDEX number of the PI entry . Here we are paying 1 PI so the first PI entry has an INDEX value
                                // of 0, a second one would be 1 etc.
                                oIndexInt = 1;
                                oIndexString = (Convert.ToString(oIndexInt)).PadLeft(8, '0');

                                // Add a New Remittance Record
                                oRemittanceRecord.AddNew();

                                // Populate Fields Remittance Purchase Invoice Details
                                SDOHelper.Write(oRemittanceRecord, "ACCOUNT_REF", SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"));
                                SDOHelper.Write(oRemittanceRecord, "ADDRESS_1", SDOHelper.Read(oPurchaseRecord, "ADDRESS_1"));
                                SDOHelper.Write(oRemittanceRecord, "ADDRESS_2", SDOHelper.Read(oPurchaseRecord, "ADDRESS_2"));
                                SDOHelper.Write(oRemittanceRecord, "ADDRESS_3", SDOHelper.Read(oPurchaseRecord, "ADDRESS_3"));
                                SDOHelper.Write(oRemittanceRecord, "ADDRESS_4", SDOHelper.Read(oPurchaseRecord, "ADDRESS_4"));
                                SDOHelper.Write(oRemittanceRecord, "ADDRESS_5", SDOHelper.Read(oPurchaseRecord, "ADDRESS_5"));
                                SDOHelper.Write(oRemittanceRecord, "BANK", (String)"1200");
                                SDOHelper.Write(oRemittanceRecord, "DATE", SDOHelper.Read(oSplitData, "DATE"));
                                SDOHelper.Write(oRemittanceRecord, "DETAILS", SDOHelper.Read(oSplitData, "DETAILS"));
                                SDOHelper.Write(oRemittanceRecord, "FAX", SDOHelper.Read(oPurchaseRecord, "FAX"));
                                SDOHelper.Write(oRemittanceRecord, "GROSS_AMOUNT", (Double)dPaymentValue);
                                SDOHelper.Write(oRemittanceRecord, "INV_REF", (String)oInvRef);
                                SDOHelper.Write(oRemittanceRecord, "INDEX", (String)oIndexString);
                                SDOHelper.Write(oRemittanceRecord, "LASTLINE_FLAG", (Int16)0);
                                SDOHelper.Write(oRemittanceRecord, "NAME", SDOHelper.Read(oPurchaseRecord, "NAME"));
                                SDOHelper.Write(oRemittanceRecord, "NET_AMOUNT", SDOHelper.Read(oSplitData, "NET_AMOUNT"));
                                SDOHelper.Write(oRemittanceRecord, "PAYMENT_AMOUNT", (Double)0 - (Double)dPaymentValue);
                                SDOHelper.Write(oRemittanceRecord, "PAYMENT_DATE", (DateTime)DateTime.Today);
                                SDOHelper.Write(oRemittanceRecord, "PAYMENT_FLAG", (Int16)0);

                                // Note The PAYMENT_NO field is used to update the bank transaction with the cheque number.  This
                                // is a PI transaction so the PI will not be updated with the cheque reference number

                                SDOHelper.Write(oRemittanceRecord, "PAYMENT_NO", (Int32)SDOHelper.Read(oSplitData, "TRAN_NUMBER"));
                                SDOHelper.Write(oRemittanceRecord, "PRINTED_FLAG", (Int16)0);
                                SDOHelper.Write(oRemittanceRecord, "TAX_CODE", (String)"T" + Convert.ToString(SDOHelper.Read(oSplitData, "TAX_CODE")));
                                SDOHelper.Write(oRemittanceRecord, "TELEPHONE", (String)SDOHelper.Read(oPurchaseRecord, "TELEPHONE"));
                                SDOHelper.Write(oRemittanceRecord, "TRAN_TYPE", (String)"PI");
                                SDOHelper.Write(oRemittanceRecord, "URN", (String)oURNString);
                                SDOHelper.Write(oRemittanceRecord, "VAT_AMOUNT", (Double)SDOHelper.Read(oSplitData, "TAX_AMOUNT"));

                                //Post Invoice
                                if (oRemittanceRecord.Update())
                                {

                                    MessageBox.Show("PI Remittance Entry Posted", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                                }

                                else
                                {

                                    MessageBox.Show("PI Remittance Entry Has Not Been Posted", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);

                                }

                                oRemittanceRecord = null;

                                oRemittanceRecord = (SageDataObject300.RemittanceRecord)oWS.CreateObject("RemittanceRecord");

                                // Positiion osplitdata to first split
                                oSplitData.Read(Convert.ToInt32(lPaymentSplit));

                                // Increment the Index number
                                oIndexInt = (int)oIndexInt + 1;
                                oIndexString = (Convert.ToString(oIndexInt)).PadLeft(8, '0');

                                // Add a New Remittance Record
                                oRemittanceRecord.AddNew();

                                // Populate Fields Remittance Purchase Payment Details
                                SDOHelper.Write(oRemittanceRecord, "VAT_AMOUNT", SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"));
                                SDOHelper.Write(oRemittanceRecord, "ADDRESS_1", SDOHelper.Read(oPurchaseRecord, "ADDRESS_1"));
                                SDOHelper.Write(oRemittanceRecord, "ADDRESS_2", SDOHelper.Read(oPurchaseRecord, "ADDRESS_2"));
                                SDOHelper.Write(oRemittanceRecord, "ADDRESS_3", SDOHelper.Read(oPurchaseRecord, "ADDRESS_3"));
                                SDOHelper.Write(oRemittanceRecord, "ADDRESS_4", SDOHelper.Read(oPurchaseRecord, "ADDRESS_4"));
                                SDOHelper.Write(oRemittanceRecord, "ADDRESS_5", SDOHelper.Read(oPurchaseRecord, "ADDRESS_5"));
                                SDOHelper.Write(oRemittanceRecord, "BANK", (String)SDOHelper.Read(oSplitData, "NOMINAL_CODE"));
                                SDOHelper.Write(oRemittanceRecord, "DATE", (DateTime)DateTime.Today);
                                SDOHelper.Write(oRemittanceRecord, "DETAILS", (String)SDOHelper.Read(oSplitData, "DETAILS"));
                                SDOHelper.Write(oRemittanceRecord, "FAX", SDOHelper.Read(oPurchaseRecord, "FAX"));
                                SDOHelper.Write(oRemittanceRecord, "GROSS_AMOUNT", (Double)0.0);
                                SDOHelper.Write(oRemittanceRecord, "INDEX", (String)oIndexString);
                                SDOHelper.Write(oRemittanceRecord, "LASTLINE_FLAG", (Int16)0);
                                SDOHelper.Write(oRemittanceRecord, "NAME", SDOHelper.Read(oPurchaseRecord, "NAME"));
                                SDOHelper.Write(oRemittanceRecord, "NET_AMOUNT", (Double)SDOHelper.Read(oSplitData, "NET_AMOUNT"));
                                SDOHelper.Write(oRemittanceRecord, "PAYMENT_AMOUNT", (Double)0 - (Double)SDOHelper.Read(oSplitData, "NET_AMOUNT"));
                                SDOHelper.Write(oRemittanceRecord, "PAYMENT_DATE", (DateTime)DateTime.Today);
                                SDOHelper.Write(oRemittanceRecord, "PAYMENT_FLAG", (Int16)1);

                                // The PAYMENT_NO field is used to update the bank transaction with the cheque number.  To do this we
                                // need to pass the payment's last split's transaction number.

                                SDOHelper.Write(oRemittanceRecord, "PAYMENT_NO", (Int32)SDOHelper.Read(oSplitData, "TRAN_NUMBER"));
                                SDOHelper.Write(oRemittanceRecord, "PRINTED_FLAG", (Int16)0);
                                SDOHelper.Write(oRemittanceRecord, "TAX_CODE", (String)"T9");
                                SDOHelper.Write(oRemittanceRecord, "TELEPHONE", (String)SDOHelper.Read(oPurchaseRecord, "TELEPHONE"));
                                SDOHelper.Write(oRemittanceRecord, "TRAN_TYPE", (String)"PP");
                                SDOHelper.Write(oRemittanceRecord, "URN", (String)oURNString);
                                SDOHelper.Write(oRemittanceRecord, "VAT_AMOUNT", (Double)0.0);

                                // Post Payment
                                if (oRemittanceRecord.Update())
                                {

                                    MessageBox.Show("PP Remittance Entry Posted", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);

                                    // Increment the last cheque number
                                    SDOHelper.Write(oSetupData, "LAST_CHEQUE", oURNInt);
                                    oSetupData.Write(1);
                                }

                                else
                                {

                                    MessageBox.Show("PP Remittance Entry Has Not Been Posted", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);

                                }

                            }

                        }

                    }
                    else
                    {
                        MessageBox.Show("No Payment Outstanding", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                    }

                }

            }
            else
            {
                MessageBox.Show("Purchase Record Not Found", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
            }

        }
        //Disconnect
        oWS.Disconnect();
    }

    // Error Handling Code
    catch (Exception ex)
    {

        switch (ex.Source)
        {

            case "Sage Data Objects":

                MessageBox.Show("The SDO generated the following error: " + oSDO.LastError.Text, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                break;

            default:

                MessageBox.Show("A non-SDO error has been generated: " + ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                break;

        }

    }

}


Sage 50 Accounts - Example - Posting a Purchase Payment And Remittance

Example - Posting a Purchase Payment And Remittance

The example code below demonstrates how to post a Purchase Payment and allocate it to an existing invoice. It also creates a remittance for the payment.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
        ' Declare Objects
        Dim oSDO As SageDataObject300.SDOEngine
        Dim oWS As SageDataObject300.WorkSpace
        Dim oSetupData As SageDataObject300.SetupData
        Dim oBankRemittanceRecord As SageDataObject300.BankRemittanceRecord
        Dim oPurchaseRecord As SageDataObject300.PurchaseRecord
        Dim oTransactionPost As SageDataObject300.TransactionPost
        Dim oSplitData As SageDataObject300.SplitData
        Dim oHeaderData As SageDataObject300.HeaderData

        ' Declare Variables
        Dim szDataPath, oURNString, oIndexString, oInvRef As String
        Dim bTransactionFound, bAllocated As Boolean
        Dim dPaymentValue As Double
        Dim oURNInt, oIndexInt As Integer
        Dim lPaymentSplit, lInvoiceSplit As Long

        ' Error Handler
        Try

            ' Create the SDO Engine object
            oSDO = New SageDataObject300.SDOEngine()

            ' Create the Workspace
            oWS = oSDO.Workspaces.Add("Example")

            ' Select company. The SelectCompany method takes the program install folder as a parameter
            szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

            ' A U.I. for company selection is presented to the user. If a company is selected,
            ' the path will be passed to the szDataPath variable.
            ' If not, or the Cancel button is selected, the variable will be left empty.
            If szDataPath <> "" Then

                ' Connect to Data Files
                oWS.Connect(szDataPath, "", "", "Example")

                ' Create an instance of the PurchaseRecord object
                oPurchaseRecord = oWS.CreateObject("PurchaseRecord")

                ' Initialise Index Field with value to search
                oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value = CStr("SUPP002")

                ' Perform Find for an exact match
                If oPurchaseRecord.Find(False) Then

                    ' Link to Headers
                    oHeaderData = oPurchaseRecord.Link

                    ' Move to the first Header on the Purchase Ledger account
                    oHeaderData.MoveFirst()

                    ' Attempt to find an Invoice.
                    ' Loop through the Headers until the Invoice Reference is found
                    Do

                        If oHeaderData.Fields.Item("INV_REF").Value = CStr("7") Then

                            ' Set the invoice transaction found flag
                            bTransactionFound = True

                            ' Exit the loop
                            Exit Do

                        End If

                    Loop Until Not oHeaderData.MoveNext

                    If bTransactionFound Then

                        ' Store the invoice Reference
                        oInvRef = CStr(oHeaderData.Fields.Item("INV_REF").Value)

                        ' Link to Splits
                        oSplitData = oHeaderData.Link

                        ' Move to first Split
                        oSplitData.MoveFirst()

                        ' Calculate Purchase Payment Value
                        dPaymentValue = CDbl(oSplitData.Fields.Item("NET_AMOUNT").Value) + CDbl(oSplitData.Fields.Item("TAX_AMOUNT").Value) - CDbl(oSplitData.Fields.Item("AMOUNT_PAID").Value)

                        ' Store Split Number for Invoice
                        lInvoiceSplit = oSplitData.RecordNumber

                        If dPaymentValue > 0 Then

                            ' Create an instance of TransactionPost for the Purchase Payment
                            oTransactionPost = oWS.CreateObject("TransactionPost")

                            ' Fill in the Header fields
                            oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value)
                            oTransactionPost.Header("DATE").Value = CDate(Today)
                            oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
                            oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoPP)
                            oTransactionPost.Header("DETAILS").Value = CStr("SDO Purchase Payment")
                            oTransactionPost.Header("BANK_CODE").Value = CStr("1200")

                            ' Populate the foreign currency fields
                            oTransactionPost.Header("CURRENCY").Value = oPurchaseRecord.Fields.Item("CURRENCY").Value)

                            ' Destroy Existing Split Object
                            oSplitData = Nothing

                            ' Create a split item by adding an empty split to the Items
                            '  collection of the TransactionPost Object.
                            oSplitData = oTransactionPost.Items.Add()

                            ' Fill in the Split fields - note a Purchase Payment only has one split
                            oSplitData.Fields.Item("TYPE").Value = CByte(SageDataObject300.TransType.sdoPP)
                            oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("1200")
                            oSplitData.Fields.Item("TAX_CODE").Value = CInt(9)
                            oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(dPaymentValue)
                            oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(0)
                            oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)
                            oSplitData.Fields.Item("DETAILS").Value = CStr("SDO Purchase Payment")

                            ' Update the TransactionPost object
                            If oTransactionPost.Update Then

                                ' Read HeaderData for Payment
                                oHeaderData.Read(oTransactionPost.PostingNumber)

                                ' Store Split Number for Payment
                                lPaymentSplit = oHeaderData.Fields.Item("FIRST_SPLIT").Value

                                ' Allocate Payment Against Invoice
                                bAllocated = oTransactionPost.AllocatePayment(CLng(lInvoiceSplit), CLng(lPaymentSplit), CDbl(dPaymentValue), CDate(Today))

                                If bAllocated Then

                                    MessageBox.Show("Purchase Payment posted, and allocated successfully.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)

                                    ' Process the remittance
                                    oSetupData = oWS.CreateObject("SetupData")
                                    oBankRemittanceRecord = oWS.CreateObject("BankRemittanceRecord")

                                    ' Destroy Existing Split Object and re-create
                                    oSplitData = Nothing

                                    oSplitData = oWS.CreateObject("SplitData")

                                    ' Read the Invoice Split
                                    oSplitData.Read(CInt(lInvoiceSplit))

                                    ' Create the URN by incrementing the last remittance number
                                    oURNInt = oSetupData.Fields.Item("LAST_REMITTANCE").Value
                                    oURNInt = oURNInt + 1
                                    oURNString = CStr(oURNInt)

                                    ' Pad the URN with spaces
                                    oURNString = oURNString.PadLeft(7, "0")

                                    ' The INDEX number of the PI entry . Here we are paying 1 PI so the first PI entry has an INDEX value
                                    ' of 1, a second one would be 2 etc.
                                    oIndexInt = 1
                                    oIndexString = CStr(oIndexInt).PadLeft(8, "0")

                                    ' Add a New Remittance Record
                                    oBankRemittanceRecord.AddNew()

                                    ' Populate Fields Remittance Purchase Invoice Details
                                    oBankRemittanceRecord.Fields.Item("ACCOUNT_REF").Value = CStr(oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value)
                                    oBankRemittanceRecord.Fields.Item("ADDRESS_1").Value = CStr(oPurchaseRecord.Fields.Item("ADDRESS_1").Value)
                                    oBankRemittanceRecord.Fields.Item("ADDRESS_2").Value = CStr(oPurchaseRecord.Fields.Item("ADDRESS_2").Value)
                                    oBankRemittanceRecord.Fields.Item("ADDRESS_3").Value = CStr(oPurchaseRecord.Fields.Item("ADDRESS_3").Value)
                                    oBankRemittanceRecord.Fields.Item("ADDRESS_4").Value = CStr(oPurchaseRecord.Fields.Item("ADDRESS_4").Value)
                                    oBankRemittanceRecord.Fields.Item("ADDRESS_5").Value = CStr(oPurchaseRecord.Fields.Item("ADDRESS_5").Value)
                                    oBankRemittanceRecord.Fields.Item("BANK").Value = CStr("1200")
                                    oBankRemittanceRecord.Fields.Item("DATE").Value = CDate(oSplitData.Fields.Item("DATE").Value)
                                    oBankRemittanceRecord.Fields.Item("DETAILS").Value = CStr(oSplitData.Fields.Item("DETAILS").Value)
                                    oBankRemittanceRecord.Fields.Item("FAX").Value = CStr(oPurchaseRecord.Fields.Item("FAX").Value)
                                    oBankRemittanceRecord.Fields.Item("GROSS_AMOUNT").Value = CDbl(dPaymentValue)
                                    oBankRemittanceRecord.Fields.Item("INV_REF").Value = CStr(oInvRef)
                                    oBankRemittanceRecord.Fields.Item("INDEX").Value = CStr(oIndexString)
                                    oBankRemittanceRecord.Fields.Item("LASTLINE_FLAG").Value = CShort(0)
                                    oBankRemittanceRecord.Fields.Item("NAME").Value = CStr(oPurchaseRecord.Fields.Item("NAME").Value)
                                    oBankRemittanceRecord.Fields.Item("NET_AMOUNT").Value = CDbl(oSplitData.Fields.Item("NET_AMOUNT").Value)
                                    oBankRemittanceRecord.Fields.Item("PAYMENT_AMOUNT").Value = CDbl(0 - (CDbl(dPaymentValue)))
                                    oBankRemittanceRecord.Fields.Item("PAYMENT_DATE").Value = CDate(Today)
                                    oBankRemittanceRecord.Fields.Item("PAYMENT_FLAG").Value = CShort(0)
                                    oBankRemittanceRecord.Fields.Item("PAYMENT_NO").Value = CInt(oSplitData.Fields.Item("HEADER_NUMBER").Value)
                                    oBankRemittanceRecord.Fields.Item("PRINTED_FLAG").Value = CShort(0)
                                    oBankRemittanceRecord.Fields.Item("TAX_CODE").Value = CStr("T") & CStr(oSplitData.Fields.Item("TAX_CODE").Value)
                                    oBankRemittanceRecord.Fields.Item("TELEPHONE").Value = oPurchaseRecord.Fields.Item("TELEPHONE").Value
                                    oBankRemittanceRecord.Fields.Item("TRAN_TYPE").Value = CStr("PI")
                                    oBankRemittanceRecord.Fields.Item("URN").Value = CStr(oURNString)
                                    oBankRemittanceRecord.Fields.Item("VAT_AMOUNT").Value = CDbl(oSplitData.Fields.Item("TAX_AMOUNT").Value)

                                    'Post Invoice
                                    If oBankRemittanceRecord.Update Then

                                        MessageBox.Show("PI Remittance Entry Posted", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)

                                    Else

                                        MessageBox.Show("PI Remittance Entry Has Not Been Posted", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)

                                    End If

                                    oBankRemittanceRecord = Nothing

                                    oBankRemittanceRecord = oWS.CreateObject("BankRemittanceRecord")

                                    ' Positiion osplitdata to first split
                                    oSplitData.Read(lPaymentSplit)

                                    ' Increment the Index number
                                    oIndexInt = CInt(oIndexInt + 1)
                                    oIndexString = CStr(oIndexInt).PadLeft(8, "0")

                                    ' Add a New Remittance Record
                                    oBankRemittanceRecord.AddNew()

                                    ' Populate Fields Remittance Purchase Payment Details
                                    oBankRemittanceRecord.Fields.Item("ACCOUNT_REF").Value = oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value
                                    oBankRemittanceRecord.Fields.Item("ADDRESS_1").Value = oPurchaseRecord.Fields.Item("ADDRESS_1").Value
                                    oBankRemittanceRecord.Fields.Item("ADDRESS_2").Value = oPurchaseRecord.Fields.Item("ADDRESS_2").Value
                                    oBankRemittanceRecord.Fields.Item("ADDRESS_3").Value = oPurchaseRecord.Fields.Item("ADDRESS_3").Value
                                    oBankRemittanceRecord.Fields.Item("ADDRESS_4").Value = oPurchaseRecord.Fields.Item("ADDRESS_4").Value
                                    oBankRemittanceRecord.Fields.Item("ADDRESS_5").Value = oPurchaseRecord.Fields.Item("ADDRESS_5").Value
                                    oBankRemittanceRecord.Fields.Item("BANK").Value = CStr(oSplitData.Fields.Item("NOMINAL_CODE").Value)
                                    oBankRemittanceRecord.Fields.Item("DATE").Value = CDate(Today)
                                    oBankRemittanceRecord.Fields.Item("DETAILS").Value = CStr(oSplitData.Fields.Item("DETAILS").Value)
                                    oBankRemittanceRecord.Fields.Item("FAX").Value = oPurchaseRecord.Fields.Item("FAX").Value
                                    oBankRemittanceRecord.Fields.Item("GROSS_AMOUNT").Value = CDbl(0.0#)
                                    oBankRemittanceRecord.Fields.Item("INDEX").Value = CStr(oIndexString)
                                    oBankRemittanceRecord.Fields.Item("LASTLINE_FLAG").Value = CShort(0)
                                    oBankRemittanceRecord.Fields.Item("NAME").Value = oPurchaseRecord.Fields.Item("NAME").Value
                                    oBankRemittanceRecord.Fields.Item("NET_AMOUNT").Value = CDbl(oSplitData.Fields.Item("NET_AMOUNT").Value)
                                    oBankRemittanceRecord.Fields.Item("PAYMENT_AMOUNT").Value = CDbl(0 - CDbl(oSplitData.Fields.Item("NET_AMOUNT").Value))
                                    oBankRemittanceRecord.Fields.Item("PAYMENT_DATE").Value = CDate(Today)
                                    oBankRemittanceRecord.Fields.Item("PAYMENT_FLAG").Value = CShort(1)
                                    oBankRemittanceRecord.Fields.Item("PAYMENT_NO").Value = CInt(oSplitData.Fields.Item("HEADER_NUMBER").Value)
                                    oBankRemittanceRecord.Fields.Item("PRINTED_FLAG").Value = CShort(0)
                                    oBankRemittanceRecord.Fields.Item("TAX_CODE").Value = CStr("T9")
                                    oBankRemittanceRecord.Fields.Item("TELEPHONE").Value = CStr(oPurchaseRecord.Fields.Item("TELEPHONE").Value)
                                    oBankRemittanceRecord.Fields.Item("TRAN_TYPE").Value = CStr("PP")
                                    oBankRemittanceRecord.Fields.Item("URN").Value = CStr(oURNString)
                                    oBankRemittanceRecord.Fields.Item("VAT_AMOUNT").Value = CDbl(0.0#)

                                    ' Post Payment
                                    If oBankRemittanceRecord.Update Then

                                        MessageBox.Show("PP Remittance Entry Posted", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)

                                        ' Increment the last cheque number
                                        oSetupData.Fields.Item("LAST_CHEQUE").Value = oURNInt
                                        oSetupData.Write(1)

                                    Else

                                        MessageBox.Show("PP Remittance Entry Has Not Been Posted", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)

                                    End If

                                End If

                            End If

                        End If

                    End If

                End If

            End If

            ' Error Handling Code
        Catch ex As Exception

            Select Case ex.Source

                Case "Sage Data Objects"

                    MessageBox.Show("The SDO generated the following error: " & oSDO.LastError.Text, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

                Case Else

                    MessageBox.Show("A non-SDO error has been generated: " & ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

            End Select

        Finally

            ' Destroy Objects
            If Not oWS Is Nothing Then
                ' Disconnect
                oWS.Disconnect()
                oWS = Nothing
                oSDO = Nothing
            End If

            If Not oPurchaseRecord Is Nothing Then
                oPurchaseRecord = Nothing
            End If

            If Not oHeaderData Is Nothing Then
                oHeaderData = Nothing
            End If

            If Not oSplitData Is Nothing Then
                oSplitData = Nothing
            End If

            If Not oSetupData Is Nothing Then
                oSetupData = Nothing
            End If

            If Not oBankRemittanceRecord Is Nothing Then
                oBankRemittanceRecord = Nothing
            End If

            If Not oTransactionPost Is Nothing Then
                oTransactionPost = Nothing
            End If

        End Try
C#.NET [image] Copy C# Code
            // Declare Objects
            SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
            SageDataObject300.WorkSpace oWS;
            SageDataObject300.SetupData oSetupData;
            SageDataObject300.BankRemittanceRecord oBankRemittanceRecord;
            SageDataObject300.PurchaseRecord oPurchaseRecord;
            SageDataObject300.TransactionPost oTransactionPost;
            SageDataObject300.SplitData oSplitData;
            SageDataObject300.HeaderData oHeaderData;

            // Declare Variables
            String szDataPath;
            String oURNString;
            String oIndexString;
            String oInvRef;
            Boolean bTransactionFound = false;
            Boolean bAllocated;
            Double dPaymentValue;
            Int32 oURNInt;
            Int32 oIndexInt;
            Int64 lPaymentSplit;
            Int64 lInvoiceSplit;

            // Error Handler
            try
            {

                //Instantiate WorkSpace
                oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

                // Select company. The SelectCompany method takes the program install folder as a parameter
                szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

                // A U.I. for company selection is presented to the user. If a company is selected,
                // the path will be passed to the szDataPath variable.
                // If not, or the Cancel button is selected, the variable will be left empty.
                if (szDataPath != "")
                {

                    // Connect to Data Files
                    oWS.Connect(szDataPath, "", "", "Example");

                    // Create an instance of the PurchaseRecord object
                    oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");

                    // Initialise Index Field with value to search
                   SDOHelper.Write(oPurchaseRecord, "ACCOUNT_REF", "CON001");

                    // Perform Find for an exact match
                    if (oPurchaseRecord.Find(false))
                    {

                        // Link to Headers
                        oHeaderData = (SageDataObject300.HeaderData)oPurchaseRecord.Link;

                        // Move to the first Header on the Purchase Ledger account
                        oHeaderData.MoveFirst();

                        //Attempt to find an Invoice.
                        //Loop through the Headers until the Invoice Reference is found
                        do
                        {
                            //Change the value according to the previous messagebox
                            if (Convert.ToString((SDOHelper.Read(oHeaderData, "INV_REF"))) == "17")

                            {
                                // Set the invoice transaction found flag
                                bTransactionFound = true;

                                // Exit the loop
                                break;
                            }
                            else
                            {
                                MessageBox.Show("INV_REF not found", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                            }
                        }

                        while (oHeaderData.MoveNext());

                        if (bTransactionFound == true)
                        {
                            // Store the invoice Reference
                            oInvRef = (String)SDOHelper.Read(oHeaderData, "INV_REF");

                            // Link to Splits
                            oSplitData = (SageDataObject300.SplitData)oHeaderData.Link;

                            // Move to first Split
                            oSplitData.MoveFirst();

                            // Calculate Purchase Payment Value
                            dPaymentValue = (Double)SDOHelper.Read(oSplitData, "NET_AMOUNT") + (Double)SDOHelper.Read(oSplitData, "TAX_AMOUNT") - (double)SDOHelper.Read(oSplitData, "AMOUNT_PAID");

                            // Store Split Number for Invoice
                            lInvoiceSplit = oSplitData.RecordNumber;

                            if (dPaymentValue > 0)
                            {

                                // Create an instance of TransactionPost for the Purchase Payment
                                oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

                                // Fill in the Header fields
                                SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"));
                                SDOHelper.Write(oTransactionPost.Header, "DATE", DateTime.Today);
                                SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", DateTime.Today);
                                SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoPP);
                                SDOHelper.Write(oTransactionPost.Header, "DETAILS", (String)"SDO Purchase Payment");
                                SDOHelper.Write(oTransactionPost.Header, "BANK_CODE", (String)"1200");

                                // Populate the foreign currency fields
                                SDOHelper.Write(oTransactionPost.Header, "CURRENCY", SDOHelper.Read(oPurchaseRecord, "CURRENCY"));

                                // Destroy Existing Split Object
                                oSplitData = null;

                                // Create a split item by adding an empty split to the Items
                                // collection of the TransactionPost Object.
                                oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                                // Fill in the Split fields - note a Purchase Payment only has one split
                                SDOHelper.Write(oSplitData, "TYPE", (Byte)SageDataObject300.TransType.sdoPP);
                                SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"1200");
                                SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)9);
                                SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)dPaymentValue);
                                SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)0);
                                SDOHelper.Write(oSplitData, "DATE", SDOHelper.Read(oTransactionPost.Header, "DATE"));
                                SDOHelper.Write(oSplitData, "DETAILS", (String)"SDO Purchase Payment");

                                // Update the TransactionPost object
                                if (oTransactionPost.Update())
                                {

                                    // Read HeaderData for Payment
                                    oHeaderData.Read(oTransactionPost.PostingNumber);

                                    // Store Split Number for Payment
                                    lPaymentSplit = (Int32)SDOHelper.Read(oHeaderData, "FIRST_SPLIT");

                                    // Allocate Payment Against Invoice
                                    bAllocated = oTransactionPost.AllocatePayment((Int32)lInvoiceSplit, (Int32)lPaymentSplit, (Double)dPaymentValue, (DateTime)DateTime.Today);

                                    if (bAllocated)
                                    {

                                        MessageBox.Show("Purchase Payment posted, and allocated successfully.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);

                                        // Process the remittance
                                        oSetupData = (SageDataObject300.SetupData)oWS.CreateObject("SetupData");
                                        oBankRemittanceRecord = (SageDataObject300.BankRemittanceRecord)oWS.CreateObject("BankRemittanceRecord");

                                        // Destroy Existing Split Object and re-create
                                        oSplitData = null;

                                        oSplitData = (SageDataObject300.SplitData)oWS.CreateObject("SplitData");

                                        // Read the Invoice Split
                                        oSplitData.Read((int)lInvoiceSplit);

                                        // Create the URN by incrementing the last remittance number
                                        oURNInt = (Int32)SDOHelper.Read(oSetupData, "LAST_REMITTANCE");
                                        oURNInt = oURNInt + 1;
                                        oURNString = Convert.ToString(oURNInt);

                                        // Pad the URN with spaces
                                        oURNString = oURNString.PadLeft(7, '0');

                                        // The INDEX number of the PI entry . Here we are paying 1 PI so the first PI entry has an INDEX value
                                        // of 1, a second one would be 2 etc.
                                        oIndexInt = 1;
                                        oIndexString = (Convert.ToString(oIndexInt)).PadLeft(8, '0');

                                        // Add a New Remittance Record
                                        oBankRemittanceRecord.AddNew();

                                        // Populate Fields Remittance Purchase Invoice Details
                                        SDOHelper.Write(oBankRemittanceRecord, "ACCOUNT_REF", SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"));
                                        SDOHelper.Write(oBankRemittanceRecord, "ADDRESS_1", SDOHelper.Read(oPurchaseRecord, "ADDRESS_1"));
                                        SDOHelper.Write(oBankRemittanceRecord, "ADDRESS_2", SDOHelper.Read(oPurchaseRecord, "ADDRESS_2"));
                                        SDOHelper.Write(oBankRemittanceRecord, "ADDRESS_3", SDOHelper.Read(oPurchaseRecord, "ADDRESS_3"));
                                        SDOHelper.Write(oBankRemittanceRecord, "ADDRESS_4", SDOHelper.Read(oPurchaseRecord, "ADDRESS_4"));
                                        SDOHelper.Write(oBankRemittanceRecord, "ADDRESS_5", SDOHelper.Read(oPurchaseRecord, "ADDRESS_5"));
                                        SDOHelper.Write(oBankRemittanceRecord, "BANK", (String)"1200");
                                        SDOHelper.Write(oBankRemittanceRecord, "DATE", SDOHelper.Read(oSplitData, "DATE"));
                                        SDOHelper.Write(oBankRemittanceRecord, "DETAILS", SDOHelper.Read(oSplitData, "DETAILS"));
                                        SDOHelper.Write(oBankRemittanceRecord, "FAX", SDOHelper.Read(oPurchaseRecord, "FAX"));
                                        SDOHelper.Write(oBankRemittanceRecord, "GROSS_AMOUNT", (Double)dPaymentValue);
                                        SDOHelper.Write(oBankRemittanceRecord, "INV_REF", (String)oInvRef);
                                        SDOHelper.Write(oBankRemittanceRecord, "INDEX", (String)oIndexString);
                                        SDOHelper.Write(oBankRemittanceRecord, "LASTLINE_FLAG", (Int16)0);
                                        SDOHelper.Write(oBankRemittanceRecord, "NAME", SDOHelper.Read(oPurchaseRecord, "NAME"));
                                        SDOHelper.Write(oBankRemittanceRecord, "NET_AMOUNT", SDOHelper.Read(oSplitData, "NET_AMOUNT"));
                                        SDOHelper.Write(oBankRemittanceRecord, "PAYMENT_AMOUNT", (Double)0 - (Double)dPaymentValue);
                                        SDOHelper.Write(oBankRemittanceRecord, "PAYMENT_DATE", (DateTime)DateTime.Today);
                                        SDOHelper.Write(oBankRemittanceRecord, "PAYMENT_FLAG", (Int16)0);
                                        SDOHelper.Write(oBankRemittanceRecord, "PAYMENT_NO", (Int32)SDOHelper.Read(oSplitData, "HEADER_NUMBER"));
                                        SDOHelper.Write(oBankRemittanceRecord, "PRINTED_FLAG", (Int16)0);
                                        SDOHelper.Write(oBankRemittanceRecord, "TAX_CODE", (String)"T" + Convert.ToString(SDOHelper.Read(oSplitData, "TAX_CODE")));
                                        SDOHelper.Write(oBankRemittanceRecord, "TELEPHONE", (String)SDOHelper.Read(oPurchaseRecord, "TELEPHONE"));
                                        SDOHelper.Write(oBankRemittanceRecord, "TRAN_TYPE", (String)"PI");
                                        SDOHelper.Write(oBankRemittanceRecord, "URN", (String)oURNString);
                                        SDOHelper.Write(oBankRemittanceRecord, "VAT_AMOUNT", (Double)SDOHelper.Read(oSplitData, "TAX_AMOUNT"));

                                        //Post Invoice
                                        if (oBankRemittanceRecord.Update())
                                        {

                                            MessageBox.Show("PI Remittance Entry Posted", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                                        }

                                        else
                                        {

                                            MessageBox.Show("PI Remittance Entry Has Not Been Posted", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);

                                        }

                                        oBankRemittanceRecord = null;

                                        oBankRemittanceRecord = (SageDataObject300.BankRemittanceRecord)oWS.CreateObject("BankRemittanceRecord");

                                        // Positiion osplitdata to first split
                                        oSplitData.Read(Convert.ToInt32(lPaymentSplit));

                                        // Increment the Index number
                                        oIndexInt = (int)oIndexInt + 1;
                                        oIndexString = (Convert.ToString(oIndexInt)).PadLeft(8, '0');

                                        // Add a New Remittance Record
                                        oBankRemittanceRecord.AddNew();

                                        // Populate Fields Remittance Purchase Payment Details
                                        SDOHelper.Write(oBankRemittanceRecord, "ACCOUNT_REF", SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"));
                                        SDOHelper.Write(oBankRemittanceRecord, "ADDRESS_1", SDOHelper.Read(oPurchaseRecord, "ADDRESS_1"));
                                        SDOHelper.Write(oBankRemittanceRecord, "ADDRESS_2", SDOHelper.Read(oPurchaseRecord, "ADDRESS_2"));
                                        SDOHelper.Write(oBankRemittanceRecord, "ADDRESS_3", SDOHelper.Read(oPurchaseRecord, "ADDRESS_3"));
                                        SDOHelper.Write(oBankRemittanceRecord, "ADDRESS_4", SDOHelper.Read(oPurchaseRecord, "ADDRESS_4"));
                                        SDOHelper.Write(oBankRemittanceRecord, "ADDRESS_5", SDOHelper.Read(oPurchaseRecord, "ADDRESS_5"));
                                        SDOHelper.Write(oBankRemittanceRecord, "BANK", (String)SDOHelper.Read(oSplitData, "NOMINAL_CODE"));
                                        SDOHelper.Write(oBankRemittanceRecord, "DATE", (DateTime)DateTime.Today);
                                        SDOHelper.Write(oBankRemittanceRecord, "DETAILS", (String)SDOHelper.Read(oSplitData, "DETAILS"));
                                        SDOHelper.Write(oBankRemittanceRecord, "FAX", SDOHelper.Read(oPurchaseRecord, "FAX"));
                                        SDOHelper.Write(oBankRemittanceRecord, "GROSS_AMOUNT", (Double)0.0);
                                        SDOHelper.Write(oBankRemittanceRecord, "INDEX", (String)oIndexString);
                                        SDOHelper.Write(oBankRemittanceRecord, "LASTLINE_FLAG", (Int16)0);
                                        SDOHelper.Write(oBankRemittanceRecord, "NAME", SDOHelper.Read(oPurchaseRecord, "NAME"));
                                        SDOHelper.Write(oBankRemittanceRecord, "NET_AMOUNT", (Double)SDOHelper.Read(oSplitData, "NET_AMOUNT"));
                                        SDOHelper.Write(oBankRemittanceRecord, "PAYMENT_AMOUNT", (Double)0 - (Double)SDOHelper.Read(oSplitData, "NET_AMOUNT"));
                                        SDOHelper.Write(oBankRemittanceRecord, "PAYMENT_DATE", (DateTime)DateTime.Today);
                                        SDOHelper.Write(oBankRemittanceRecord, "PAYMENT_FLAG", (Int16)1);
                                        SDOHelper.Write(oBankRemittanceRecord, "PAYMENT_NO", (Int32)SDOHelper.Read(oSplitData, "HEADER_NUMBER"));
                                        SDOHelper.Write(oBankRemittanceRecord, "PRINTED_FLAG", (Int16)0);
                                        SDOHelper.Write(oBankRemittanceRecord, "TAX_CODE", (String)"T9");
                                        SDOHelper.Write(oBankRemittanceRecord, "TELEPHONE", (String)SDOHelper.Read(oPurchaseRecord, "TELEPHONE"));
                                        SDOHelper.Write(oBankRemittanceRecord, "TRAN_TYPE", (String)"PP");
                                        SDOHelper.Write(oBankRemittanceRecord, "URN", (String)oURNString);
                                        SDOHelper.Write(oBankRemittanceRecord, "VAT_AMOUNT", (Double)0.0);

                                        // Post Payment
                                        if (oBankRemittanceRecord.Update())
                                        {

                                            MessageBox.Show("PP Remittance Entry Posted", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);

                                            // Increment the last cheque number
                                            SDOHelper.Write(oSetupData, "LAST_REMITTANCE", oURNInt);
                                            oSetupData.Write(1);
                                        }

                                        else
                                        {

                                            MessageBox.Show("PP Remittance Entry Has Not Been Posted", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);

                                        }

                                    }

                                }

                            }
                            else
                            {
                                MessageBox.Show("No Payment Outstanding", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                            }

                        }

                    }
                    else
                    {
                        MessageBox.Show("Purchase Record Not Found", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                    }

                }
            }

            // Error Handling Code
            catch (Exception ex)
            {

                switch (ex.Source)
                {

                    case "Sage Data Objects":

                        MessageBox.Show("The SDO generated the following error: " + oSDO.LastError.Text, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        break;

                    default:

                        MessageBox.Show("A non-SDO error has been generated: " + ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        break;

                }
            }


Sage 50 Accounts - Example - Posting a Sales Receipt on Account (SA)

Example - Posting a Sales Receipt on Account (SA)

The example code below demonstrates how to post a Sales Receipt on Account (SA).

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
                                ' Declare Objects
Dim oSDO  As
                              SageDataObject300.SDOEngine
Dim oWS  As
                              SageDataObject300.WorkSpace
Dim oTransactionPost  As
                              SageDataObject300.TransactionPost
Dim oHeaderData  As
                              SageDataObject300.HeaderData
Dim oSplitData  As
                              SageDataObject300.SplitData
Dim oSalesRecord  As
                              SageDataObject300.SalesRecord

' Declare Variables
Dim szDataPath  As String

' Create the SDO Engine Object
oSDO =  New   SageDataObject300.SDOEngine()

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.

If szDataPath <> ""  Then

' Connect to Data Files
If oWS.Connect(szDataPath, "", "", "Example")
                              Then

' Create an Instance of Objects
oTransactionPost = oWS.CreateObject("TransactionPost")
oSalesRecord = oWS.CreateObject("SalesRecord")

' Read First Customer
oSalesRecord.MoveFirst()

' Create an instance of TransactionPost for the Sales Receipt
oTransactionPost = oWS.CreateObject("TransactionPost")

' Fill in the Header fields
oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value = CDate(Today)
oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoSA)
oTransactionPost.Header("DETAILS").Value = CStr("Test Sales
                                Receipt on Account")
oTransactionPost.Header("INV_REF").Value = CStr("PAY001")
oTransactionPost.Header("BANK_CODE").Value = CStr("1200")

' Populate the foreign currency fields
oTransactionPost.Header("CURRENCY").Value = oSalesRecord.Fields.Item("CURRENCY").Value

' Create a split item by adding an empty split to the Items
' collection of the TransactionPost Object.
oSplitData = oTransactionPost.Items.Add()

' Fill in the Split fields - note a Sales Receipt only has one split
oSplitData.Fields.Item("TYPE").Value = CByte(SageDataObject300.TransType.sdoSA)
oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("1200")
oSplitData.Fields.Item("TAX_CODE").Value = CShort(9)
oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(200)
oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(0)
oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)
oSplitData.Fields.Item("DETAILS").Value = CStr(oTransactionPost.Header("DETAILS").Value)

' Update the TransactionPost object
If oTransactionPost.Update  Then

MsgBox ("Transaction post was
                                successful")

End If

' Disconnect
oWS.Disconnect()

End If

End If

' Destroy Objects
oTransactionPost = Nothing
oSplitData =  Nothing
oHeaderData = Nothing
oSalesRecord = Nothing
oWS =  Nothing
oSDO =  Nothing

Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.TransactionPost oTransactionPost;

SageDataObject300.SplitData oSplitdata;

SageDataObject300.SalesRecord oSalesRecord;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate Objects

  oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

  oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");

  //Read the first customer

  oSalesRecord.MoveFirst();

  //Fill in the header fields

  SDOHelper.Write(oTransactionPost.Header,"ACCOUNT_REF",

    (String)SDOHelper.Read(oSalesRecord,"ACCOUNT_REF"));

  SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);

  SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);

  SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoSA);

  SDOHelper.Write(oTransactionPost.Header, "DETAILS", (String)"Test Sales Receipt on Account");

  SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"Pay001");

  SDOHelper.Write(oTransactionPost.Header, "BANK_CODE", (String)"1200");

  //Populate the foreign currency fields

  SDOHelper.Write(oTransactionPost.Header,"CURRENCY", SDOHelper.Read(oSalesRecord,"CURRENCY"));

  //Create a split item by adding an empty split to the items

  //collection of the TranactionPost Object

  oSplitdata = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

  //Populate the split fields

  //Note: a sales Receipt only has one split

  SDOHelper.Write(oSplitdata,"TYPE",(Byte)SageDataObject300.TransType.sdoSA);

  SDOHelper.Write(oSplitdata, "NOMINAL_CODE", (String)"1200");

  SDOHelper.Write(oSplitdata, "TAX_CODE", (Int16)9);

  SDOHelper.Write(oSplitdata, "NET_AMOUNT", (Double)200);

  SDOHelper.Write(oSplitdata, "TAX_AMOUNT", (Double)0);

  SDOHelper.Write(oSplitdata, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header,"DATE"));

  SDOHelper.Write(oSplitdata, "DETAILS", (String)SDOHelper.Read(oTransactionPost.Header, "DETAILS"));

  //Update the TransactionPost object

  if (oTransactionPost.Update())

  {

    MessageBox.Show("Transaction Post Was Successful");

  }

  else

  {

    MessageBox.Show("Transaction Failed To Post");

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Posting a Purchase Payment on Account (PA)

Example - Posting a Purchase Payment on Account (PA)

The example code below demonstrates how to post a Purchase Payment on Account (PA).

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
   ' Declare Objects
Dim oSDO  As SageDataObject300.SDOEngine
Dim oWS  As SageDataObject300.WorkSpace
Dim oTransactionPost  As SageDataObject300.TransactionPost
Dim oHeaderData  As SageDataObject300.HeaderData
Dim oSplitData  As SageDataObject300.SplitData
Dim oPurchaseRecord  As SageDataObject300.PurchaseRecord

' Declare Variables
Dim szDataPath  As String

' Create the SDO Engine Object
oSDO =  New SageDataObject300.SDOEngine()

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.

If szDataPath <> ""  Then

' Connect to Data Files
If oWS.Connect(szDataPath, "", "", "Example") Then

' Create an Instance of Objects
oTransactionPost =
                              oWS.CreateObject("TransactionPost")
oPurchaseRecord = oWS.CreateObject("PurchaseRecord")

' Read First Supplier
oPurchaseRecord.MoveFirst()

' Create an instance of
    TransactionPost for the Purchase Payment
oTransactionPost =
                              oWS.CreateObject("TransactionPost")

' Fill in the Header fields
oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value = CDate(Today)
oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoPA)
oTransactionPost.Header("INV_REF").Value = CStr("PAY001")
oTransactionPost.Header("BANK_CODE").Value = CStr("1200")

' Populate the foreign currency fields
oTransactionPost.Header("CURRENCY").Value = oPurchaseRecord.Fields.Item("CURRENCY").Value)

' Create a split item by adding an empty split to the Items
' collection of the TransactionPost Object.
oSplitData = oTransactionPost.Items.Add()

' Fill in the Split fields - note a
    Purchase Payment only has one split
oSplitData.Fields.Item("TYPE").Value = CByte(SageDataObject300.TransType.sdoPA)
oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("1200")
oSplitData.Fields.Item("TAX_CODE").Value = CShort(9)
oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(200)
oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(0)
oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)
oSplitData.Fields.Item("DETAILS").Value = CStr(oTransactionPost.Header("DETAILS").Value)

' Update the TransactionPost object
If oTransactionPost.Update  Then

MsgBox ("Transaction post was
                              successful")

End If

' Disconnect
oWS.Disconnect()

End If

End If

' Destroy Objects
oTransactionPost = Nothing
oSplitData =  Nothing
oHeaderData = Nothing
oPurchaseRecord = Nothing
oWS =  Nothing
oSDO =  Nothing

Exit Sub
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.TransactionPost oTransactionPost;
            SageDataObject300.SplitData oSplitData;
            SageDataObject300.PurchaseRecord oPurchaseRecord;

            try
            {
                //Instantiate Objects
                oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");
                oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");

                //Read the first Supplier
                oPurchaseRecord.MoveFirst();

                //Fill in the header fields
                SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"));
                SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);
                SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);
                SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoPA);
                SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"Pay001");
                SDOHelper.Write(oTransactionPost.Header, "BANK_CODE", (String)"1200");

                //Populate the foreign currency fields
                SDOHelper.Write(oTransactionPost.Header, "CURRENCY", SDOHelper.Read(oPurchaseRecord, "CURRENCY"));

                //Create a split item by adding an empty split to the items
                //collection of the TranactionPost Object
                oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                //Populate the split fields
                //Note: a Purchase Payment only has one split
                SDOHelper.Write(oSplitData, "TYPE", (Byte)SageDataObject300.TransType.sdoPA);
                SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"1200");
                SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)9);
                SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)200);
                SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)0);
                SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));
                SDOHelper.Write(oSplitData, "DETAILS", (String)SDOHelper.Read(oTransactionPost.Header, "DETAILS"));

                //Update the TransactionPost object
                if (oTransactionPost.Update())
                {
                    MessageBox.Show("Transaction Post Was Successful");
                }
                else
                {
                    MessageBox.Show("Transaction Failed To Post");
                }

                // Disconnect
                oWS.Disconnect();
            }
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Allocating a Receipt to an Invoice with Multiple Splits

Example - Allocating a Receipt to an Invoice with Multiple Splits

The example code below demonstrates how to allocate a receipt to an invoice with multiple splits.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
                                ' Declare Objects
Dim oSDO  As
                              SageDataObject300.SDOEngine
Dim oWS  As
                              SageDataObject300.WorkSpace
Dim oSalesRecord  As
                              SageDataObject300.SalesRecord
Dim oTransactionPost  As
                              SageDataObject300.TransactionPost
Dim oSplitData  As
                              SageDataObject300.SplitData
Dim oHeaderData  As
                              SageDataObject300.HeaderData

' Declare Variables
Dim szDataPath  As String
Dim bRecordFound, bTransactionFound, bPosted, bAllocated
                               As Boolean
Dim dReceiptValue  As Double
Dim lReceiptSplit, lInvoiceSplit, lInvoiceHeader
                               As Integer

' Create the SDO Engine object
oSDO =  New   SageDataObject300.SDOEngine()

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to   the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> ""  Then

' Connect to Data Files
If oWS.Connect(szDataPath, "", "", "Example")
                              Then

' Create an instance of the SalesRecord object
oSalesRecord = oWS.CreateObject("SalesRecord")

' Initialise Index Field with value to search
oSalesRecord.Fields.Item("ACCOUNT_REF").Value =
                              CStr("CUST001")

' Perform Find for an exact match
If oSalesRecord.Find(False)
                              Then

' Link to Headers
oHeaderData = oSalesRecord.Link

' Move to the first Header on the
                                  Customer account
oHeaderData.MoveFirst()

' Attempt to find an Invoice.
' Loop through the Headers until the Invoice Reference is found
Do

If oHeaderData.Fields.Item("INV_REF").Value = CStr("1")
                               Then

' Set the invoice transaction found flag
bTransactionFound = True

' Store Header Record Number of Invoice
lInvoiceHeader =
                              CInt(oHeaderData.RecordNumber)

' Exit the loop
Exit Do

End If

Loop Until Not oHeaderData.MoveNext

If bTransactionFound
                               Then

' Calculate Sales Receipt Value
dReceiptValue = CDbl(oHeaderData.Fields.Item("NET_AMOUNT").Value) + CDbl(oHeaderData.Fields.Item("TAX_AMOUNT").Value) -
                              CDbl(oHeaderData.Fields.Item("AMOUNT_PAID").Value)

If dReceiptValue > 0
                               Then

' Create an instance of TransactionPost for the Sales Receipt
oTransactionPost = oWS.CreateObject("TransactionPost")

' Fill in the Header fields
oTransactionPost.Header("ACCOUNT_REF").Value =
                              CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value =
                              CDate(Today)
oTransactionPost.Header("POSTED_DATE").Value =
                              CDate(Today)
oTransactionPost.Header("TYPE").Value =
                              CByte(SageDataObject300.TransType.sdoSR)
oTransactionPost.Header("DETAILS").Value =
                              CStr("Sales Receipt")
oTransactionPost.Header("INV_REF").Value =
                              CStr("SDO")
oTransactionPost.Header("BANK_CODE").Value =
                              CStr("1200")

' Populate the foreign currency fields
oTransactionPost.Header("CURRENCY").Value = oSalesRecord.Fields.Item("CURRENCY").Value

' Create a split item by adding an empty split to the Items
' collection of the TransactionPost Object.
oSplitData = oTransactionPost.Items.Add()

' Fill in the Split fields - note a Sales Receipt only has one split
oSplitData.Fields.Item("TYPE").Value =
                              CByte(SageDataObject300.TransType.sdoSR)
oSplitData.Fields.Item("NOMINAL_CODE").Value =
                              CStr("1200")
oSplitData.Fields.Item("TAX_CODE").Value =
                              CInt(9)
oSplitData.Fields.Item("NET_AMOUNT").Value =
                              CDbl(dReceiptValue)
oSplitData.Fields.Item("TAX_AMOUNT").Value =
                              CDbl(0)
oSplitData.Fields.Item("DATE").Value =
                              CDate(oTransactionPost.Header("DATE").Value)
oSplitData.Fields.Item("DETAILS").Value =
                              CStr(oTransactionPost.Header("DETAILS").Value)

' Update the TransactionPost object
If oTransactionPost.Update
                              Then

' Read HeaderData for Receipt
oHeaderData.Read(oTransactionPost.PostingNumber)

' Store Split Number for Receipt
lReceiptSplit = CInt(oHeaderData.Fields.Item("FIRST_SPLIT").Value)

' Read HeaderData for Invoice
oHeaderData.Read(lInvoiceHeader)

' Link to Splits
oSplitData = oHeaderData.Link

' Move to First Split
oSplitData.MoveFirst()

Do

' Calculate the Split amount to be paid
dReceiptValue = CDbl(oSplitData.Fields.Item("NET_AMOUNT").Value) +
                              CDbl(oSplitData.Fields.Item("TAX_AMOUNT").Value) -
                              CDbl(oSplitData.Fields.Item("AMOUNT_PAID").Value)

If dReceiptValue > 0  Then

' Allocate Receipt Against Invoice
bAllocated = oTransactionPost.AllocatePayment(CInt(oSplitData.RecordNumber),
                              CInt(lReceiptSplit), CDbl(dReceiptValue),
                              CDate(Today))

End If

Loop Until Not oSplitData.MoveNext

If bAllocated  Then

MsgBox("Sales receipt posted, and allocated successfully.")

End If

End If

End If

End If

End If

' Disconnect
oWS.Disconnect()

End If

End If

' Destroy Objects
oSalesRecord =  Nothing
oHeaderData =  Nothing
oSplitData =  Nothing
oTransactionPost =  Nothing
oSDO =  Nothing
oWS =  Nothing

Exit Sub
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.TransactionPost oTransactionPost;
            SageDataObject300.HeaderData oHeaderData;
            SageDataObject300.SplitData oSplitData = null;
            SageDataObject300.SalesRecord oSalesRecord;
            Int32 iInvoiceHeader = 0;
            Int32 iReceiptSplit = 0;
            Double dReceiptValue = 0;

            try
            {
                // Instantiate Objects
                oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");

                // Initialise Index Field with value to search
                SDOHelper.Write(oSalesRecord, "ACCOUNT_REF", (String)"CUST0001");

                // Read the first customer account
                oSalesRecord.Find(false);

                // Link the Headers
                oHeaderData = (SageDataObject300.HeaderData)oSalesRecord.Link;

                // only perform steps if there is a header
                if (oHeaderData.Count > 0)
                {
                    // Move the first Header
                    oHeaderData.MoveFirst();

                    do
                    {
                        // Find the required Header based on the Reference
                        if ((String)SDOHelper.Read(oHeaderData, "INV_REF") == (String)"1")
                        {
                            // Calculate the Sales Receipt Value
                            dReceiptValue += ((Double)SDOHelper.Read(oHeaderData, "NET_AMOUNT") + (Double)SDOHelper.Read(oHeaderData, "TAX_AMOUNT")) - (Double)SDOHelper.Read(oHeaderData, "AMOUNT_PAID");

                            // Store the header number
                            iInvoiceHeader = (Int32)oHeaderData.RecordNumber;
                        }

                    } while (!(!oHeaderData.MoveNext()));
                }

                if (dReceiptValue > 0)
                {
                    // Initialise TransactionPost Object
                    oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

                    // Populate Header Fields
                    SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));
                    SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);
                    SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);
                    SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoSR);
                    SDOHelper.Write(oTransactionPost.Header, "DETAILS", (String)"Sales Receipt");
                    SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"SDO SR");
                    SDOHelper.Write(oTransactionPost.Header, "BANK_CODE", (String)"1200");

                    //Populate the foreign currency fields
                    SDOHelper.Write(oTransactionPost.Header, "CURRENCY", SDOHelper.Read(oSalesRecord, "CURRENCY"));

                    // Create a split item by adding an empty split to the items
                    // Collection of the TransactionPost Object.
                    oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                    //Populate the split fields
                    SDOHelper.Write(oSplitData, "TYPE", (Byte)SageDataObject300.TransType.sdoSR);
                    SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"1200");
                    SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)9);
                    SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)dReceiptValue);
                    SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)0);
                    SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));
                    SDOHelper.Write(oSplitData, "DETAILS", (String)SDOHelper.Read(oTransactionPost.Header, "DETAILS"));

                    // Update the TransactionPost object
                    if (oTransactionPost.Update())
                    {
                        // Store the header record number of the invoice just posted
                        oHeaderData.Read(oTransactionPost.PostingNumber);

                        // Store split number for the receipt
                        iReceiptSplit = (Int32)SDOHelper.Read(oHeaderData, "FIRST_SPLIT");

                        // Read header for the SI
                        oHeaderData.Read(iInvoiceHeader);

                        // Link to the splits
                        oSplitData = (SageDataObject300.SplitData)oHeaderData.Link;

                        // Move to the first split
                        oSplitData.MoveFirst();

                        do
                        {
                            // clear dReceiptValue
                            dReceiptValue = 0;

                            // Calculate the split amounts to pay
                            dReceiptValue = ((Double)SDOHelper.Read(oSplitData, "NET_AMOUNT") + (Double)SDOHelper.Read(oSplitData, "TAX_AMOUNT")) - (Double)SDOHelper.Read(oSplitData, "AMOUNT_PAID");

                            if (dReceiptValue > 0)
                            {
                                if (oTransactionPost.AllocatePayment((Int32)oSplitData.RecordNumber, (Int32)iReceiptSplit, (Double)dReceiptValue, (DateTime)DateTime.Now))
                                {
                                    MessageBox.Show("Posting allocation has been successful");
                                }
                                else
                                {
                                    MessageBox.Show("Allocation Failed");
                                }
                            }

                        } while (!(!oSplitData.MoveNext()));
                    }
                }

                // Disconnect
                oWS.Disconnect();
            }
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Posting a Foreign Currency Sales Receipt

Example - Posting a Foreign Currency Sales Receipt

The example code below demonstrates how to post a Sales Receipt.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oTransactionPost As SageDataObject300.TransactionPost
Dim oHeaderData As SageDataObject300.HeaderData
Dim oSplitData As SageDataObject300.SplitData
Dim oControlData As SageDataObject300.ControlData
Dim oSalesRecord As SageDataObject300.SalesRecord
Dim oNominalData As SageDataObject300.NominalData
Dim oCurrencyData As SageDataObject300.CurrencyData

' Declare Variables
Dim szDataPath As String
Dim iCtr As Short
Dim bFlag As Boolean
Dim lInvoiceHeader As Integer
Dim lReceiptHeader As Integer
Dim lReceiptSplit As Integer
Dim lDiscountHeader As Integer
Dim lDiscountSplit As Integer
Dim lTotalAmount As Double
Dim lAmountLeft As Double

' Create the SDO Engine Object
oSDO = New SageDataObject300.SDOEngine()

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.

If szDataPath <> "" Then

' Connect to Data Files
oWS.Connect(szDataPath, "", "", "Example")

' Create an Instance of Objects
oTransactionPost = oWS.CreateObject("TransactionPost")
oControlData = oWS.CreateObject("ControlData")
oSalesRecord = oWS.CreateObject("SalesRecord")
oNominalData = oWS.CreateObject("NominalData")
oCurrencyData = oWS.CreateObject("CurrencyData")

' Read First Customer
 oSalesRecord.MoveFirst()

' Read Currency Data
 oCurrencyData.Read(Convert.ToByte(oSalesRecord.Fields.Item("CURRENCY").Value) + 1)

' Populate Header fields
oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value = CDate(Today)
oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoSI)
oTransactionPost.Header("DETAILS").Value = CStr("Sales Allocated Invoice")
oTransactionPost.Header("INV_REF").Value = CStr("INV001")

' Populate Foreign Currency Fields
oTransactionPost.Header("FOREIGN_RATE").Value = oCurrencyData.Fields.Item("EXCHANGE_RATE").Value
oTransactionPost.Header("CURRENCY").Value = oSalesRecord.Fields.Item("CURRENCY").Value

' Loop for number of split's
For iCtr = 1 To 2

' Create a split item by adding an empty split to the Items
' collection of the TransactionPost Object.
oSplitData = oTransactionPost.Items.Add()

' Fill in the Split fields
oSplitData.Fields.Item("TYPE").Value = CByte(SageDataObject300.TransType.sdoSI)
oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("4000")
oSplitData.Fields.Item("TAX_CODE").Value = CShort(1)
oSplitData.Fields.Item("FOREIGN_NET_AMOUNT").Value = CDbl(100)
oSplitData.Fields.Item("FOREIGN_TAX_AMOUNT").Value = CDbl(17.5)
oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)
oSplitData.Fields.Item("DETAILS").Value = CStr(oTransactionPost.Header("DETAILS").Value)

Next iCtr

' Update the TransactionPost Object
If oTransactionPost.Update Then

' Store Header Record Number of Invoice just Posted
lInvoiceHeader = oTransactionPost.PostingNumber

' Destroy Objects
oTransactionPost = Nothing
oSplitData = Nothing

' *********************************
' Now Post Sales Receipt

' Create an instance of TransactionPost for the Sales Receipt
oTransactionPost = oWS.CreateObject("TransactionPost")

' Fill in the Header fields
oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value = CDate(Today)
oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoSR)
oTransactionPost.Header("DETAILS").Value = CStr("Test Sales Receipt")
oTransactionPost.Header("INV_REF").Value = CStr("PAY001")
oTransactionPost.Header("BANK_CODE").Value = CStr("1220")

' Populate Foreign Currency Fields
oTransactionPost.Header("FOREIGN_RATE").Value = oCurrencyData.Fields.Item("EXCHANGE_RATE").Value
oTransactionPost.Header("CURRENCY").Value = oSalesRecord.Fields.Item("CURRENCY").Value

' Create a split item by adding an empty split to the Items
' collection of the TransactionPost Object.
oSplitData = oTransactionPost.Items.Add()

' Fill in the Split fields - note a Sales Receipt only has one split
oSplitData.Fields.Item("TYPE").Value = CByte(SageDataObject300.TransType.sdoSR)
oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("1200")
oSplitData.Fields.Item("TAX_CODE").Value = CShort(9)
oSplitData.Fields.Item("FOREIGN_NET_AMOUNT").Value = CDbl(200)
oSplitData.Fields.Item("FOREIGN_TAX_AMOUNT").Value = CDbl(0)
oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)
oSplitData.Fields.Item("DETAILS").Value = CStr(oTransactionPost.Header("DETAILS").Value)

End If

' Update the TransactionPost object
If oTransactionPost.Update Then

' Store Header Record Number of Receipt just Posted
lReceiptHeader = oTransactionPost.PostingNumber

' Destroy Objects
oTransactionPost = Nothing
oSplitData = Nothing

' *********************************
' Now Post Sales Discount

' Read Control Data
' for Default discount Nominal Code
oControlData.Read(1)

' Now read Nominal using the default sales discount
oNominalData.Read(CInt(oControlData.Fields.Item("SDISCOUNT_NO").Value))

' Create an instance of TransactionPost for the Sales Receipt
oTransactionPost = oWS.CreateObject("TransactionPost")

' Fill in the Header fields
oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value = CDate(Today)
oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoSD)
oTransactionPost.Header("DETAILS").Value = CStr("Sales Discount")
oTransactionPost.Header("INV_REF").Value = CStr("BACS")

' Populate Foreign Currency Field
oTransactionPost.Header("FOREIGN_RATE").Value = oCurrencyData.Fields.Item("EXCHANGE_RATE").Value
oTransactionPost.Header("CURRENCY").Value = oSalesRecord.Fields.Item("CURRENCY").Value

' Create a split item by adding an empty split to the Items
' collection of the TransactionPost Object.
oSplitData = oTransactionPost.Items.Add()

' Fill in the Split fields - note a Sales Discount only has one split
oSplitData.Fields.Item("TYPE").Value = CByte(SageDataObject300.TransType.sdoSD)
oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr(oNominalData.Fields.Item("ACCOUNT_REF").Value)
oSplitData.Fields.Item("TAX_CODE").Value = CShort(9)
 oSplitData.Fields.Item("FOREIGN_NET_AMOUNT").Value = CDbl(35)
oSplitData.Fields.Item("FOREIGN_TAX_AMOUNT").Value = CDbl(0)
oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)
oSplitData.Fields.Item("DETAILS").Value = CStr(oTransactionPost.Header("DETAILS").Value)

End If

' Update the TransactionPost object
If oTransactionPost.Update Then

' Store Header record number of receipt just posted
lDiscountHeader = oTransactionPost.PostingNumber

' Destroy Dplit
oSplitData = Nothing

' The AllocatePayment function needs the split record number
' so we will need to read the header first and then obtain
' the split's from there

' Create an instance of HeaderData
oHeaderData = oWS.CreateObject("HeaderData")
' Read HeaderData for Receipt
oHeaderData.Read(lReceiptHeader)

' Store Split Number for Receipt
lReceiptSplit = CInt (oHeaderData.Fields.Item("FIRST_SPLIT").Value)

' Read HeaderData for Discount
oHeaderData.Read(lDiscountHeader)

' Store Split Number for Discount
lDiscountSplit = CInt (oHeaderData.Fields.Item("FIRST_SPLIT").Value)

' Read HeaderData for Invoice
oHeaderData.Read(lInvoiceHeader)

' Link to Split's
oSplitData = oHeaderData.Link

' Move to First Split
oSplitData.MoveFirst()

End If

' Allocate First Split to Receipt
If oTransactionPost.AllocatePayment(CInt(oSplitData.RecordNumber), CInt(lReceiptSplit), CDbl(117.5), CDate(Today)) Then

' Move to Next Split
oSplitData.MoveNext()

' Allocate Second Split to Remainder of Receipt
oTransactionPost.AllocatePayment(CInt(oSplitData.RecordNumber), CInt(lReceiptSplit), CDbl(82.5), CDate(Today))

' Allocate remainder of second split to discount
oTransactionPost.AllocatePayment(CInt(oSplitData.RecordNumber), CInt(lDiscountSplit), CDbl(35), CDate(Today))

MsgBox("Posting and Allocation has been Successful", MsgBoxStyle.OKOnly, "SDO Examples")

Else

MsgBox("Routine Failed", MsgBoxStyle.OKOnly, "SDO Examples")

End If

' Disconnect.
oWS.Disconnect()

End If

oTransactionPost = Nothing
oSplitData = Nothing
oHeaderData = Nothing
oControlData = Nothing
oSalesRecord = Nothing
oNominalData = Nothing
 oCurrencyData = Nothing
oWS = Nothing
oSDO = Nothing

Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.TransactionPost oTransactionPost;

SageDataObject300.HeaderData oHeaderData;

SageDataObject300.SplitData oSplitData = null;

SageDataObject300.ControlData oControlData;

SageDataObject300.SalesRecord oSalesRecord;

SageDataObject300.NominalData oNominalData;

SageDataObject300.CurrencyData oCurrencyData;

String szDataPath;

Int32 lInvoiceHeader = 0;

Int32 lReceiptHeader = 0;

Int32 lReceiptSplit = 0;

Int32 lDiscountHeader = 0;

Int32 lDiscountSplit = 0;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate Objects

  oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

  oControlData = (SageDataObject300.ControlData)oWS.CreateObject("ControlData");

  oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");

  oNominalData = (SageDataObject300.NominalData)oWS.CreateObject("NominalData");

  oCurrencyData = (SageDataObject300.CurrencyData)oWS.CreateObject("CurrencyData");

  //Read the first customer

  oSalesRecord.MoveFirst();

  //Read the currency data

  oCurrencyData.Read(Convert.ToInt32(SDOHelper.Read(oSalesRecord, "CURRENCY"))+1);

  //Populate Header Fields

  SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF",(String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));

  SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);

  SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);

  SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoSI);

  SDOHelper.Write(oTransactionPost.Header, "DETAILS", (String)"Foreign Sales Invoice");

  SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"INV001");

  //Populate Foreign Currency Fields

  SDOHelper.Write(oTransactionPost.Header, "FOREIGN_RATE", SDOHelper.Read(oCurrencyData, "EXCHANGE_RATE"));

  SDOHelper.Write(oTransactionPost.Header, "CURRENCY", SDOHelper.Read(oSalesRecord, "CURRENCY"));

  //Loop for number of splits

  for (Int16 i = 1; i <= 2; i++)

  {

    //Create a split item by adding an empty split to the items

    //collection of the TransactionPost Object.

    oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

    //Populate the split fields

    SDOHelper.Write(oSplitData, "TYPE", (Byte)SageDataObject300.TransType.sdoSI);

    SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"4000");

    SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)1);

    SDOHelper.Write(oSplitData, "FOREIGN_NET_AMOUNT", (Double)100);

    SDOHelper.Write(oSplitData, "FOREIGN_TAX_AMOUNT", (Double)17.5);

    SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));

    SDOHelper.Write(oSplitData, "DETAILS", (String)SDOHelper.Read(oTransactionPost.Header, "DETAILS"));

  }

  //Update the Transaction Post object

  if (oTransactionPost.Update())

  {

    //Store the header record number of the invoice just posted

    lInvoiceHeader = oTransactionPost.PostingNumber;

    //Destroy the objects

    oTransactionPost = null;

    oSplitData = null;

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

    //Now Post Sales Receipt

    //Re-Instantiate the Transaction Post object for the sales receipt

    oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

    //Populate the header fields

    SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF",

      (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));

    SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);

    SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);

    SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoSR);

    SDOHelper.Write(oTransactionPost.Header, "DETAILS", (String)"Test Sales Receipt");

    SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"PAY001");

    //Bank Code must relate to an account with the correct currency

    SDOHelper.Write(oTransactionPost.Header, "BANK_CODE", (String)"1220");

    //Populate the foreign currency fields

    SDOHelper.Write(oTransactionPost.Header, "FOREIGN_RATE", SDOHelper.Read(oCurrencyData, "EXCHANGE_RATE"));

    SDOHelper.Write(oTransactionPost.Header, "CURRENCY", SDOHelper.Read(oSalesRecord, "CURRENCY"));

    //Create a split item by adding an empty split to the items

    //collection of the TransactionPost Object.

    oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

    //Populate the split fields

    //Note: a Sales receipt only has one split

    SDOHelper.Write(oSplitData, "TYPE", (Byte)SageDataObject300.TransType.sdoSR);

    SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"1200");

    SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)9);

    SDOHelper.Write(oSplitData, "FOREIGN_NET_AMOUNT", (Double)200);

    SDOHelper.Write(oSplitData, "FOREIGN_TAX_AMOUNT", (Double)0);

    SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));

    SDOHelper.Write(oSplitData, "DETAILS", (String)SDOHelper.Read(oTransactionPost.Header, "DETAILS"));

  }

  //Update the Transaction Post object

  if (oTransactionPost.Update())

  {

    //Store the record number of the receipt just posted

    lReceiptHeader = oTransactionPost.PostingNumber;

    //Destroy the objects

    oTransactionPost = null;

    oSplitData = null;

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

    //Now post the sales discount

    //Read control data

    //for the default discount nominal code

    oControlData.Read(1);

    //Now read the nominal using the default sales discount

    oNominalData.Read((Int32)SDOHelper.Read(oControlData, "SDISCOUNT_NO"));

    //Re-Instantiate the Transaction Post object for the Sales Receipt

    oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

    //Populate the Header Fields

    SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF",

      (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));

    SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);

    SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);

    SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoSD);

    SDOHelper.Write(oTransactionPost.Header, "DETAILS", (String)"Sales Discount");

    SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"BACS");

    //Populate the foreign currency fields

    SDOHelper.Write(oTransactionPost.Header, "FOREIGN_RATE", SDOHelper.Read(oCurrencyData, "EXCHANGE_RATE"));

    SDOHelper.Write(oTransactionPost.Header, "CURRENCY", SDOHelper.Read(oSalesRecord, "CURRENCY"));

    //Create a split item by adding an empty split to the items

    //collection of the TransactionPost Object.

    oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

    //Populate the split fields

    //Note: a Sales Discount only has one split

    SDOHelper.Write(oSplitData, "TYPE", (Byte)SageDataObject300.TransType.sdoSD);

    SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)SDOHelper.Read(oNominalData, "ACCOUNT_REF"));

    SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)9);

    SDOHelper.Write(oSplitData, "FOREIGN_NET_AMOUNT", (Double)35);

    SDOHelper.Write(oSplitData, "FOREIGN_TAX_AMOUNT", (Double)0);

    SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));

    SDOHelper.Write(oSplitData, "DETAILS", (String)SDOHelper.Read(oTransactionPost.Header, "DETAILS"));

  }

  //Update the Transaction Post Object

  if (oTransactionPost.Update())

  {

    //Store the header record number of the discount just posted

    lDiscountHeader = oTransactionPost.PostingNumber;

    //Destroy the split

    oSplitData = null;

    //The AllocatePayment function needs the split record number

    //so we will need to read the header first and then obtain

    //the splits from there

    //Instantiate Header Data object

    oHeaderData = (SageDataObject300.HeaderData)oWS.CreateObject("HeaderData");

    //Read the HeaderData for the receipt

    oHeaderData.Read(lReceiptHeader);

    //Store the split number for the receipt

    lReceiptSplit = (Int32)SDOHelper.Read(oHeaderData, "FIRST_SPLIT");

    //Read the HeaderData for the Discount

    oHeaderData.Read(lDiscountHeader);

    //Store the split number for the discount

    lDiscountSplit = (Int32)SDOHelper.Read(oHeaderData, "FIRST_SPLIT");

    //Read the HeaderData for the invoice

    oHeaderData.Read(lInvoiceHeader);

    //Link the Splits

    oSplitData = (SageDataObject300.SplitData)oHeaderData.Link;

    //Move to the first split

    oSplitData.MoveFirst();

  }

  //Allocate the first split to the receipt

  if (oTransactionPost.AllocatePayment((Int32)oSplitData.RecordNumber,(Int32)lReceiptSplit,

    (Double)117.5,(DateTime)DateTime.Today))

  {

    //Move to the next split

    oSplitData.MoveNext();

    //Allocate the second split to the remainder of the receipt

    oTransactionPost.AllocatePayment((Int32)oSplitData.RecordNumber,(Int32)lReceiptSplit,

      (Double)82.5,(DateTime)DateTime.Today);

    //Allocate the remainder of the second split to the discount

    oTransactionPost.AllocatePayment((Int32)oSplitData.RecordNumber,(Int32)lDiscountSplit,

      (Double)35,(DateTime)DateTime.Today);

    MessageBox.Show("Posting allocation has been successful");

  }

  else

  {

    MessageBox.Show("Routine Failed");

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Posting a Foreign Currency Purchase Payment

Example - Posting a Foreign Currency Purchase Payment

The example code below demonstrates how to post a Foreign Currency Purchase Payment.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oTransactionPost As SageDataObject300.TransactionPost
Dim oHeaderData As SageDataObject300.HeaderData
Dim oSplitData As SageDataObject300.SplitData
Dim oControlData As SageDataObject300.ControlData
Dim oPurchaseRecord As SageDataObject300.PurchaseRecord
Dim oNominalData As SageDataObject300.NominalData
Dim oCurrencyData As SageDataObject300.CurrencyData

' Declare Variables
Dim szDataPath As String
Dim iCtr As Short
Dim bFlag As Boolean
Dim lInvoiceHeader As Integer
Dim lReceiptHeader As Integer
Dim lReceiptSplit As Integer
Dim lDiscountHeader As Integer
Dim lDiscountSplit As Integer
Dim lTotalAmount As Double
Dim lAmountLeft As Double

' Create the SDO Engine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

' Try to Connect - Will throw an exception if it fails
If oWS.Connect(szDataPath, "", "", "Example") Then

' Create an Instance of Objects
oTransactionPost = oWS.CreateObject("TransactionPost")
oControlData = oWS.CreateObject("ControlData")
oPurchaseRecord = oWS.CreateObject("PurchaseRecord")
oNominalData = oWS.CreateObject("NominalData")
oCurrencyData = oWS.CreateObject("CurrencyData")

' Read First Customer
oPurchaseRecord.MoveFirst()

' Read Currency File
oCurrencyData.Read(Convert.ToByte(oPurchaseRecord.Fields.Item("CURRENCY").Value) + 1)

' Populate Header Fields
oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value = CDate(Today)
oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoPI)
oTransactionPost.Header("DETAILS").Value = CStr("Purchase Allocated Invoice")
oTransactionPost.Header("INV_REF").Value = CStr("INV001")

' Populate Foreign Currency Fields
oTransactionPost.Header("FOREIGN_RATE").Value = oCurrencyData.Fields.Item("EXCHANGE_RATE").Value
oTransactionPost.Header("CURRENCY").Value = oPurchaseRecord.Fields.Item("CURRENCY").Value

' Loop for Number of Splits
For iCtr = 1 To 2

' Create a split item by adding an empty split to the Items
' collection of the TransactionPost Object.
oSplitData = oTransactionPost.Items.Add()

' Fill in the Split fields
oSplitData.Fields.Item("TYPE").Value = CByte(SageDataObject300.TransType.sdoPI)
oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("4000")
oSplitData.Fields.Item("TAX_CODE").Value = CShort(1)
oSplitData.Fields.Item("FOREIGN_NET_AMOUNT").Value = CDbl(100)
oSplitData.Fields.Item("FOREIGN_TAX_AMOUNT").Value = CDbl(17.5)
oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)
oSplitData.Fields.Item("DETAILS").Value = CStr(oTransactionPost.Header("DETAILS").Value)

Next iCtr

' Update the TransactionPost Object
' If Successful
If oTransactionPost.Update Then

' Store Header Record Number of Invoice just Posted
lInvoiceHeader = oTransactionPost.PostingNumber

' Destroy Objects
oTransactionPost = Nothing
oSplitData = Nothing

' *********************************
' Now Post Sales Receipt

' Create an instance of TransactionPost for the Sales Receipt
oTransactionPost = oWS.CreateObject("TransactionPost")

' Fill in the Header fields
oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value = CDate(Today)
oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoPP)
oTransactionPost.Header("DETAILS").Value = CStr("Test Purchase Payment")
oTransactionPost.Header("INV_REF").Value = CStr("PAY001")
oTransactionPost.Header("BANK_CODE").Value = CStr("1220")

' Populate Foreign Currency Fields
oTransactionPost.Header("FOREIGN_RATE").Value = oCurrencyData.Fields.Item("EXCHANGE_Rate").Value
oTransactionPost.Header("CURRENCY").Value = oPurchaseRecord.Fields.Item("CURRENCY").Value

' Create a split item by adding an empty split to the Items
' collection of the TransactionPost Object.
oSplitData = oTransactionPost.Items.Add()

' Fill in the Split fields - note a Sales Receipt only has one split
oSplitData.Fields.Item("TYPE").Value = CByte(SageDataObject300.TransType.sdoPP)
oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("1200")
oSplitData.Fields.Item("TAX_CODE").Value = CShort(9)
oSplitData.Fields.Item("FOREIGN_NET_AMOUNT").Value = CDbl(200)
oSplitData.Fields.Item("FOREIGN_TAX_AMOUNT").Value = CDbl(0)
oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)
oSplitData.Fields.Item("DETAILS").Value = CStr(oTransactionPost.Header("DETAILS").Value)

End If

' Update the TransactionPost object
' If Successful
If oTransactionPost.Update Then

' Store Header Record Number of Receipt just Posted
lReceiptHeader = oTransactionPost.PostingNumber

' Destroy Objects
oTransactionPost = Nothing
oSplitData = Nothing

' *********************************
' Now Post Sales Discount

' Read Control Data
' for Default discount Nominal Code
oControlData.Read(1)

' Now read Nominal using the Default Sales Discount Record Number
oNominalData.Read(CInt(oControlData.Fields.Item("SDISCOUNT_NO").Value))

' Create an instance of TransactionPost for the Sales Discount
oTransactionPost = oWS.CreateObject("TransactionPost")

' Fill in the Header fields
oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value = CDate(Today)
oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoPD)
oTransactionPost.Header("DETAILS").Value = CStr("Sales Discount")
oTransactionPost.Header("INV_REF").Value = CStr("BACS")

' Populate Foreign Currency Fields
oTransactionPost.Header("FOREIGN_RATE").Value = oCurrencyData.Fields.Item("EXCHANGE_RATE").Value
oTransactionPost.Header("CURRENCY").Value = oPurchaseRecord.Fields.Item("CURRENCY").Value

' Create a split item by adding an empty split to the Items
' collection of the TransactionPost Object.
oSplitData = oTransactionPost.Items.Add()

' Fill in the Split fields - note a Sales Discount only has one split
oSplitData.Fields.Item("TYPE").Value = CByte(SageDataObject300.TransType.sdoPD)
oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr(oNominalData.Fields.Item("ACCOUNT_REF").Value)
oSplitData.Fields.Item("TAX_CODE").Value = CShort(9)
oSplitData.Fields.Item("FOREIGN_NET_AMOUNT").Value = CDbl(35)
oSplitData.Fields.Item("FOREIGN_TAX_AMOUNT").Value = CDbl(0)
oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)
oSplitData.Fields.Item("DETAILS").Value = CStr(oTransactionPost.Header("DETAILS").Value)

End If

' Update the TransactionPost object
If oTransactionPost.Update Then

' Store Header record number of receipt just posted
lDiscountHeader = oTransactionPost.PostingNumber

' Destroy oSplitData
oSplitData = Nothing

' The AllocatePayment function needs the split record number
' so we will need to read the header first and then obtain
' the split's from there

' Create an instance of HeaderData
oHeaderData = oWS.CreateObject("HeaderData")

' Read HeaderData for Receipt
oHeaderData.Read(lReceiptHeader)

' Store Split Number for Receipt
lReceiptSplit = oHeaderData.Fields.Item("FIRST_SPLIT").Value

' Read HeaderData for Discount
oHeaderData.Read(lDiscountHeader)

' Store Split Number for Discount
lDiscountSplit = oHeaderData.Fields.Item("FIRST_SPLIT").Value

' Read HeaderData for Invoice
oHeaderData.Read(lInvoiceHeader)

' Link to Splits
oSplitData = oHeaderData.Link

' Move to First Split
oSplitData.MoveFirst()

End If

' Allocate First Split to Receipt
If oTransactionPost.AllocatePayment(CInt(oSplitData.RecordNumber), CInt(lReceiptSplit), CDbl(117.5), CDate(Today)) Then

' Move to Next Split
oSplitData.MoveNext()

End If

' Allocate Second Split to Remainder of Receipt
If oTransactionPost.AllocatePayment(CInt(oSplitData.RecordNumber), CInt(lReceiptSplit), CDbl(82.5), CDate(Today)) Then

' Allocate remainder of second split to discount
If oTransactionPost.AllocatePayment(CInt(oSplitData.RecordNumber), CInt(lDiscountSplit), CDbl(35), CDate(Today)) Then

MsgBox("Posting and Allocation has been Successful", MsgBoxStyle.OKOnly, "SDO Examples")

Else

MsgBox("Routine Failed", MsgBoxStyle.OKOnly, "SDO Examples")

End If

End If

' Disconnect
oWS.Disconnect()

End If

End If

' Destroy Objects

oTransactionPost = Nothing
oSplitData = Nothing
oHeaderData = Nothing
oControlData = Nothing
oPurchaseRecord = Nothing
oNominalData = Nothing
 oCurrencyData = Nothing
oWS = Nothing
oSDO = Nothing

Exit Sub
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.TransactionPost oTransactionPost;
            SageDataObject300.HeaderData oHeaderData;
            SageDataObject300.SplitData oSplitData = null;
            SageDataObject300.ControlData oControlData;
            SageDataObject300.PurchaseRecord oPurchaseRecord;
            SageDataObject300.NominalData oNominalData;
            SageDataObject300.CurrencyData oCurrencyData;
            Int32 iInvoiceHeader = 0;
            Int32 iPaymentHeader = 0;
            Int32 iPaymentSplit = 0;

            try
            {
                // Instantiate Objects
                oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");
                oControlData = (SageDataObject300.ControlData)oWS.CreateObject("ControlData");
                oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");
                oNominalData = (SageDataObject300.NominalData)oWS.CreateObject("NominalData");
                oCurrencyData = (SageDataObject300.CurrencyData)oWS.CreateObject("CurrencyData");

                // Read the first bank account
                oPurchaseRecord.MoveFirst();

                // Read the currency data
                oCurrencyData.Read(Convert.ToByte(SDOHelper.Read(oPurchaseRecord, "CURRENCY")) + 1);

                // Populate Header Fields
                SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"));
                SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);
                SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);
                SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoPI);
                SDOHelper.Write(oTransactionPost.Header, "DETAILS", (String)"Foreign Purchase Invoice");
                SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"PI001");

                //Populate Foreign Currency Fields
                SDOHelper.Write(oTransactionPost.Header, "FOREIGN_RATE", SDOHelper.Read(oCurrencyData, "EXCHANGE_RATE"));
                SDOHelper.Write(oTransactionPost.Header, "CURRENCY", SDOHelper.Read(oPurchaseRecord, "CURRENCY"));

                //Loop for number of splits
                for (Int16 i = 1; i <= 2; i++)
                {
                    //Create a split item by adding an empty split to the items
                    //collection of the TransactionPost Object.
                    oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                    //Populate the split fields
                    SDOHelper.Write(oSplitData, "TYPE", (Byte)SageDataObject300.TransType.sdoPI);
                    SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"5000");
                    SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)7);
                    SDOHelper.Write(oSplitData, "FOREIGN_NET_AMOUNT", (Double)100);
                    SDOHelper.Write(oSplitData, "FOREIGN_TAX_AMOUNT", (Double)0);
                    SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));
                    SDOHelper.Write(oSplitData, "DETAILS", (String)SDOHelper.Read(oTransactionPost.Header, "DETAILS"));
                }

                // Update the TransactionPost object
                if (oTransactionPost.Update())
                {
                    // Store the header record number of the invoice just posted
                    iInvoiceHeader = oTransactionPost.PostingNumber;

                    // Destroy the objects
                    oTransactionPost = null;
                    oSplitData = null;

                    //*************************
                    //Now Post Purchase Payment
                    //*************************

                    // Re-Instantiate the Transaction Post object for the Purchase Payment
                    oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

                    // Populate the header fields
                    SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"));
                    SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);
                    SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);
                    SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoPP);
                    SDOHelper.Write(oTransactionPost.Header, "DETAILS", (String)"Test Purchase Payment");
                    SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"PAY001");

                    // Bank Code must relate to an account with the correct currency
                    SDOHelper.Write(oTransactionPost.Header, "BANK_CODE", (String)"1220");

                    //Populate the foreign currency fields
                    SDOHelper.Write(oTransactionPost.Header, "FOREIGN_RATE", SDOHelper.Read(oCurrencyData, "EXCHANGE_RATE"));
                    SDOHelper.Write(oTransactionPost.Header, "CURRENCY", SDOHelper.Read(oPurchaseRecord, "CURRENCY"));

                    // Create a split item by adding an empty split to the items
                    //   collection of the TransactionPost Object.
                    oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                    // Populate the split fields
                    //   Note: a Purchase Payment only has one split
                    SDOHelper.Write(oSplitData, "TYPE", (Byte)SageDataObject300.TransType.sdoPP);
                    SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"1201");
                    SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)9);
                    SDOHelper.Write(oSplitData, "FOREIGN_NET_AMOUNT", (Double)200);
                    SDOHelper.Write(oSplitData, "FOREIGN_TAX_AMOUNT", (Double)0);
                    SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));
                    SDOHelper.Write(oSplitData, "DETAILS", (String)SDOHelper.Read(oTransactionPost.Header, "DETAILS"));
                }
                // Update this TransactionPost object (for the PP)
                if (oTransactionPost.Update())
                {
                    // Store the record number of the payment just posted
                    iPaymentHeader = oTransactionPost.PostingNumber;

                    // Destroy the split
                    oSplitData = null;

                    // The AllocatePayment function needs the split record number
                    //   so we will need to read the header first and then obtain
                    //   the splits from there

                    // Instantiate Header Data object
                    oHeaderData = (SageDataObject300.HeaderData)oWS.CreateObject("HeaderData");

                    // Read the HeaderData for the receipt
                    oHeaderData.Read(iPaymentHeader);

                    // Store the split number for the receipt
                    iPaymentSplit = (Int32)SDOHelper.Read(oHeaderData, "FIRST_SPLIT");

                    // Read the HeaderData for the invoice
                    oHeaderData.Read(iInvoiceHeader);

                    // Link the Splits
                    oSplitData = (SageDataObject300.SplitData)oHeaderData.Link;

                    // Move to the first split
                    oSplitData.MoveFirst();
                }

                //Allocate the first split to the payment (must allocate the base_net not the foreign_net)
                if (oTransactionPost.AllocatePayment((Int32)oSplitData.RecordNumber, (Int32)iPaymentSplit, (Double)SDOHelper.Read(oSplitData, "NET_AMOUNT"), (DateTime)DateTime.Today))
                {
                    //Move to the next split
                    oSplitData.MoveNext();

                    //Allocate the second split to the remainder of the payment
                    oTransactionPost.AllocatePayment((Int32)oSplitData.RecordNumber, (Int32)iPaymentSplit, (Double)SDOHelper.Read(oSplitData, "NET_AMOUNT"), (DateTime)DateTime.Today);

                    MessageBox.Show("Posting allocation has been successful");
                }
                else
                {
                    MessageBox.Show("Routine Failed");
                }

                // Disconnect
                oWS.Disconnect();
            }
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Posting a Foreign Currency Bank Receipt

Example - Posting a Foreign Currency Bank Receipt

The example code below demonstrates how to post a Foreign Currency Bank Receipt.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oBankRecord As SageDataObject300.BankRecord
Dim oTransactionPost As SageDataObject300.TransactionPost
Dim oSplitData As SageDataObject300.SplitData
Dim oCurrencyData As SageDataObject300.CurrencyData

' Declare Variables
Dim szDataPath As String

' Create the SDO Engine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install
' directory as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

' Connect to Data Files
If oWS.Connect(szDataPath, "", "", "Example") Then

' Create Instances of Objects
oTransactionPost = oWS.CreateObject("TransactionPost")
oBankRecord = oWS.CreateObject("BankRecord")
oCurrencyData = oWS.CreateObject("CurrencyData")

' Read the first Bank Account
oBankRecord.MoveFirst()

' Read the Currency Data
oCurrencyData.Read(Convert.ToByte(oBankRecord.Fields.Item("CURRENCY").Value) + 1)

' Populate Header fields
' Note:
' The ACCOUNT_REF field must be populated with a valid
' Bank Account Reference
oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oBankRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value = CDate(Today)
oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoBR)
oTransactionPost.Header("INV_REF").Value = CStr("BP001")
oTransactionPost.Header("BANK_CODE").Value = CStr("1220")

' Populate the Foreign Currency Fields
oTransactionPost.Header("FOREIGN_RATE").Value = CDbl (oCurrencyData.Fields.Item("EXCHANGE_RATE").Value)
oTransactionPost.Header("CURRENCY").Value = oBankRecord.Fields.Item("CURRENCY").Value

' Create a split item by adding an empty split to the Items
' collection of the TransactionPost Object.
oSplitData = oTransactionPost.Items.Add()

' Fill in the Split fields
oSplitData.Fields.Item("TYPE").Value = CByte(SageDataObject300.TransType.sdoBR)
oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("7000")
oSplitData.Fields.Item("TAX_CODE").Value = CShort(9)
oSplitData.Fields.Item("FOREIGN_NET_AMOUNT").Value = CDbl(200)
oSplitData.Fields.Item("FOREIGN_TAX_AMOUNT").Value = CDbl(0)
oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)
oSplitData.Fields.Item("DETAILS").Value = CStr(oTransactionPost.Header("DETAILS").Value)

' Update the TransactionPost object
If oTransactionPost.Update Then

MsgBox("Transaction Posted successfully", MsgBoxStyle.OKOnly, "SDO Examples")

Else

MsgBox("Transaction Post Failed", MsgBoxStyle.OKOnly, "SDO Examples")

End If

' Disconnect
oWS.Disconnect()

End If

End If

' Destroy Objects
oTransactionPost = Nothing
oSplitData = Nothing
oBankRecord = Nothing
 oCurrencyData = Nothing
oSDO = Nothing
oWS = Nothing

Exit Sub
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.TransactionPost oTransactionPost;
            SageDataObject300.SplitData oSplitData = null;
            SageDataObject300.BankRecord oBankRecord;
            SageDataObject300.CurrencyData oCurrencyData;

            try
            {
                // Instantiate Objects
                oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");
                oBankRecord = (SageDataObject300.BankRecord)oWS.CreateObject("BankRecord");
                oCurrencyData = (SageDataObject300.CurrencyData)oWS.CreateObject("CurrencyData");

                // Read the first bank account
                oBankRecord.MoveFirst();

                // Read the currency data
                oCurrencyData.Read(Convert.ToByte(SDOHelper.Read(oBankRecord, "CURRENCY")) + 1);

                // Populate Header Fields
                SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oBankRecord, "ACCOUNT_REF"));
                SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);
                SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);
                SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoBR);
                SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"BP001");
                SDOHelper.Write(oTransactionPost.Header, "BANK_CODE", (String)"1220");

                //Populate Foreign Currency Fields
                SDOHelper.Write(oTransactionPost.Header, "FOREIGN_RATE", SDOHelper.Read(oCurrencyData, "EXCHANGE_RATE"));
                SDOHelper.Write(oTransactionPost.Header, "CURRENCY", SDOHelper.Read(oBankRecord, "CURRENCY"));

                // Create a split item by adding an empty split to the items
                //   collection of the transaction object
                oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                //Fill in the split Fields
                SDOHelper.Write(oSplitData, "TYPE", (Byte)SageDataObject300.TransType.sdoBR);
                SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"7000");
                SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)9);
                SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)200);
                SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)0);
                SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));
                SDOHelper.Write(oSplitData, "DETAILS", (String)SDOHelper.Read(oTransactionPost.Header, "DETAILS"));

                // Update the TransactionPost object
                if (oTransactionPost.Update())
                {
                    MessageBox.Show("Transaction Posted successfully", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
                else
                {
                    MessageBox.Show("Transaction Post Failed", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

                // Disconnect
                oWS.Disconnect();
            }
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Posting a Foreign Currency Bank Payment

Example - Posting a Foreign Currency Bank Payment

The example code below demonstrates how to post a Bank Payment.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
                                ' Declare Objects
Dim oSDO As
                              SageDataObject300.SDOEngine
Dim oWS As
                              SageDataObject300.WorkSpace
Dim oBankRecord As
                              SageDataObject300.BankRecord
Dim oTransactionPost As
                              SageDataObject300.TransactionPost
Dim
                              oCurrencyData As SageDataObject300.CurrencyData
Dim oSplitData As
                              SageDataObject300.SplitData

' Declare Variables
Dim szDataPath As String

' Create the SDO Engine Object
oSDO = New
                              SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company the select company method takes the
                                  program install
' directory as a parameter
szDataPath =
                                oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024\")

' A U.I. for company selection is presented to the user. If a company is
                                  selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left
                              empty.

If szDataPath <> ""
                                Then

' Connect to Data Files
If oWS.Connect(szDataPath,
                              "", "", "Example") Then

' Create Instances of Objects
oTransactionPost =

                                oWS.CreateObject("TransactionPost")
oBankRecord =
                                oWS.CreateObject("BankRecord")
oCurrencyData =
                                oWS.CreateObject("CurrencyData")

' Read the first Bank Account
oBankRecord.MoveFirst()

' Read the Currency
                                  File
oCurrencyData.Read(Convert.ToByte(oBankRecord.Fields.Item("CURRENCY").Value)
                                +
                                1)

' Populate Header fields
oTransactionPost.Header("ACCOUNT_REF").Value =
                                CStr(oBankRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value =
                                CDate(Today)
oTransactionPost.Header("POSTED_DATE").Value =
                                CDate(Today)
oTransactionPost.Header("TYPE").Value =
                                CByte(SageDataObject300.TransType.sdoBP)
oTransactionPost.Header("INV_REF").Value =
                                CStr("BP001")
oTransactionPost.Header("BANK_CODE").Value =
                                CStr("1220")

' Populate Foreign Currency
                                  Fields
oTransactionPost.Header("FOREIGN_RATE").Value
                                = CDbl
                                (oCurrencyData.Fields.Item("EXCHANGE_RATE").Value)
oTransactionPost.Header("CURRENCY").Value =
                                    oBankRecord.Fields.Item("CURRENCY").Value

' Create a split item by
                                    adding an empty split to the Items
' collection of the TransactionPost Object.
oSplitData=
                                    oTransactionPost.Items.Add()

' Fill in the Split fields
oSplitData.Fields.Item("TYPE").Value = CByte(SageDataObject300.TransType.sdoBP)
oSplitData.Fields.Item("NOMINAL_CODE").Value =
                                        CStr("4000")
oSplitData.Fields.Item("TAX_CODE").Value =
                                        CShort(9)
oSplitData.Fields.Item("FOREIGN_NET_AMOUNT").Value = CDbl(200)
oSplitData.Fields.Item("FOREIGN_TAX_AMOUNT").Value = CDbl(0)
oSplitData.Fields.Item("DATE").Value =
                                        CDate(oTransactionPost.Header("DATE").Value)
oSplitData.Fields.Item("DETAILS").Value =
                                        CStr(oTransactionPost.Header("DETAILS").Value)

' Update the TransactionPost
                                  object
If oTransactionPost.Update
                              Then

MessageBox.Show("Transaction
                              Posted successfully", MsgBoxStyle.OKOnly, "SDO Examples")

Else

MessageBox.Show("Transaction
                              Post Failed", MsgBoxStyle.OKOnly, "SDO Examples")

End If

' Disconnect
oWS.Disconnect()

End If

End If

oTransactionPost = Nothing
oSplitData = Nothing
oBankRecord = Nothing
oCurrencyData = Nothing
oSDO = Nothing
oWS =   Nothing

Exit Sub
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.TransactionPost oTransactionPost;
            SageDataObject300.SplitData oSplitData = null;
            SageDataObject300.BankRecord oBankRecord;
            SageDataObject300.CurrencyData oCurrencyData;

            try
            {
                // Instantiate Objects
                oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");
                oBankRecord = (SageDataObject300.BankRecord)oWS.CreateObject("BankRecord");
                oCurrencyData = (SageDataObject300.CurrencyData)oWS.CreateObject("CurrencyData");

                // Read the first bank account
                oBankRecord.MoveFirst();

                // Read the currency data
                oCurrencyData.Read(Convert.ToByte(SDOHelper.Read(oBankRecord, "CURRENCY")) + 1);

                // Populate Header Fields
                SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oBankRecord, "ACCOUNT_REF"));
                SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);
                SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);
                SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoBP);
                SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"BP001");
                SDOHelper.Write(oTransactionPost.Header, "BANK_CODE", (String)"1220");

                //Populate Foreign Currency Fields
                SDOHelper.Write(oTransactionPost.Header, "FOREIGN_RATE", SDOHelper.Read(oCurrencyData, "EXCHANGE_RATE"));
                SDOHelper.Write(oTransactionPost.Header, "CURRENCY", SDOHelper.Read(oBankRecord, "CURRENCY"));

                // Create a split item by adding an empty split to the items
                //   collection of the transaction object
                oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                //Fill in the split Fields
                SDOHelper.Write(oSplitData, "TYPE", (Byte)SageDataObject300.TransType.sdoBP);
                SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"4000");
                SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)9);
                SDOHelper.Write(oSplitData, "FOREIGN_NET_AMOUNT", (Double)200);
                SDOHelper.Write(oSplitData, "FOREIGN_TAX_AMOUNT", (Double)0);
                SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));
                SDOHelper.Write(oSplitData, "DETAILS", (String)SDOHelper.Read(oTransactionPost.Header, "DETAILS"));

                // Update the TransactionPost object
                if (oTransactionPost.Update())
                {
                    MessageBox.Show("Transaction Posted successfully", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
                else
                {
                    MessageBox.Show("Transaction Post Failed", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

                // Disconnect
                oWS.Disconnect();
            }
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Allocating a multi-split Sales Credit to a multi-split Sales Invoice

Example - Allocating a multi-split Sales Credit to a multi-split Sales Invoice

The following code shows how to iterate through the splits of an outstanding SC and allocate the respective amounts to an outstanding SI. The process below is fired from a form_load event but is equally suitable when not using controls.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code

Public Class Form1

' Declare Objects

Dim oSDO As SageDataObject300.SDOEngine

Dim oWS As SageDataObject300.WorkSpace

Dim oSalesRecord As SageDataObject300.SalesRecord

Dim oTransPost As SageDataObject300.TransactionPost

Dim oHdrDta As SageDataObject300.HeaderData

Dim oSpltDta As SageDataObject300.SplitData

' Declare Variables

Dim szDataPath As String

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

Try

' Create the SDO Engine Object

oSDO = New SageDataObject300.SDOEngine

' Create the Workspace

oWS = oSDO.Workspaces.Add("Example")

' Select Company The SelectCompany method takes the program install

' folder as a parameter

szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,

' the path will be passed to the szDataPath variable.

' If not, or the Cancel button is selected, the variable will be left empty.

If szDataPath <> "" Then

' Try to Connect - Will throw an exception if it fails

If oWS.Connect(szDataPath, "", "", "Example") Then

' Create Instance Objects

oSalesRecord = oWS.CreateObject("SalesRecord")

oHdrDta = oWS.CreateObject("HeaderData")

oTransPost = oWS.CreateObject("TransactionPost")

' Initialise Index Field with value to search

oSalesRecord.Fields.Item("ACCOUNT_REF").Value = CStr("ALLOC001")

' Perform Find for an exact match then calculate amount to allocate

If oSalesRecord.Find(False) Then

makeThePayment()

End If

End If

End If

Catch

Select Case oSDO.LastError.Code

' 3rd Party Integration NOT Enabled - Site Activation

Case Is = SageDataObject300.ErrorCode.sdoNotRegistered

MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")

' Invalid Password

Case Is = SageDataObject300.ErrorCode.sdoLogonPassword

MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")

' User is Already Logged On

Case Is = SageDataObject300.ErrorCode.sdoLogonNameInUse

MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")

' Line 50 is in Exclusive Mode i.e. File Maintenance

Case Is = SageDataObject300.ErrorCode.sdoLogonExclusive

MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")

' Invalid Data Path on Connect

Case Is = SageDataObject300.ErrorCode.sdoBadDataPath

MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")

' Line 50 is not Same Version as SDO

Case Is = SageDataObject300.ErrorCode.sdoWrongVersion

MsgBox("Logon Failed Due to: " & oSDO.LastError.Text, MsgBoxStyle.OkOnly, "SDO Examples")

End Select

End Try

End Sub

Private Sub makeThePayment()

Dim AllocVal As Double ' amount to allocate in AllocatePayment() method

Dim allocate As Boolean ' defines whether to allocate payment or not

Dim PaidFlag As Boolean = False ' HEADER is not fully paid

' link the header transactions to the respective sales record

oHdrDta = oSalesRecord.Link

Do

' declare variables

Dim dCredVal As Double 'holds amount of CREDIT split

Dim dInvVal As Double 'holds amount of INVOICE split

Dim CredSpltNum As Integer 'holds record number of CREDIT split

Dim InvSpltNum As Integer 'holds record number of INVOICE split

oHdrDta.MoveFirst()

Do

'if not a fully paid Header

If oHdrDta.Fields.Item("PAID_FLAG").Value = 0 Then

allocate = False

'Find outstanding SI

If oHdrDta.Fields.Item("Type").Value = 1 Then

' move through the INVOICE splits

oSpltDta = oHdrDta.Link

oSpltDta.MoveFirst()

Do

' obtain amount for split and get record number

dInvVal = CDbl(oSpltDta.Fields.Item("NET_AMOUNT").Value + oSpltDta.Fields.Item("TAX_AMOUNT").Value - oSpltDta.Fields.Item("AMOUNT_PAID").Value)

InvSpltNum = oSpltDta.RecordNumber

' exit loop if there is an amount of 1p or more

If dInvVal > 0.009 Then

Exit Do

End If

Loop Until Not oSpltDta.MoveNext

End If

' find outstanding SC

If oHdrDta.Fields.Item("Type").Value = 2 Then

' move through the CREDIT splits

oSpltDta = oHdrDta.Link

oSpltDta.MoveFirst()

Do

' obtain amount for split and get record number

dCredVal = CDbl(oSpltDta.Fields.Item("NET_AMOUNT").Value + oSpltDta.Fields.Item("TAX_AMOUNT").Value - oSpltDta.Fields.Item("AMOUNT_PAID").Value)

CredSpltNum = oSpltDta.RecordNumber

' exit loop if there is an amount of 1p or more

If dCredVal > 0.009 Then

Exit Do

End If

Loop Until Not oSpltDta.MoveNext

End If

Else

PaidFlag = True

dInvVal = 0

dCredVal = 0

End If

' if both values are > 1p then break out of loop and perform allocation

If dInvVal > 0.009 And dCredVal > 0.009 Then

allocate = True

Exit Do

Else

PaidFlag = True

End If

Loop Until Not oHdrDta.MoveNext

' set correct amount to allocate

If dCredVal >= dInvVal Then

AllocVal = dInvVal

Else

AllocVal = dCredVal

End If

' 1st IF ensures we don't get 'failed' on last iteration

If allocate Then

' now allocate respective amount and inform user of success/failure

If oTransPost.AllocatePayment(CType(InvSpltNum, Integer), CType(CredSpltNum, Integer), _

CType(AllocVal, Double), Date.Today) Then

MsgBox("Allocation successful", MsgBoxStyle.OkOnly)

dCredVal = 0

dInvVal = 0

Else

MsgBox("Allocation failed", MsgBoxStyle.OkOnly)

Me.Close()

Exit Do

End If

End If

Loop Until PaidFlag 'loops until one of the header transactions is paid in full

MsgBox("All Complete")

oWS.Disconnect()

End Sub ' makeThePayment()

End Class
C#.NET [image] Copy C# Code

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

namespace Allocating_Multi_Split_Transactions

{

public partial class Form1 : Form

{

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

String szDataPath;

Boolean allocate;

public Form1()

{

InitializeComponent();

}

private void Form1_Load(object sender, EventArgs e)

{

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

//Leaving the username and password blank generates a login dialog

oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

// run user defined code

userDefinedMethod();

}

catch (Exception ex)

{

MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}

}

private void userDefinedMethod()

{

// Declare required objects

SageDataObject300.TransactionPost oTransactionPost;

SageDataObject300.HeaderData oHeaderData;

SageDataObject300.SplitData oSplitData = null;

SageDataObject300.SalesRecord oSalesRecord;

Double AllocVal = 0;

Boolean PaidFlag = false;

try

{

// Instantiate Objects

oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");

// Initialise Index Field with value to search

SDOHelper.Write(oSalesRecord, "ACCOUNT_REF", (String)"CUST0001");

// Read the first customer account

oSalesRecord.Find(false);

// Link the Headers

oHeaderData = (SageDataObject300.HeaderData)oSalesRecord.Link;

do

{

// declare variables

double dCredVal = 0;

//holds amount of CREDIT split

double dInvVal = 0;

//holds amount of INVOICE split

int CredSpltNum = 0;

//holds record number of CREDIT split

int InvSpltNum = 0;

//holds record number of INVOICE split

oHeaderData.MoveFirst();

do

{

//if not a fully paid Header

if (Convert.ToInt32(SDOHelper.Read(oHeaderData, "PAID_FLAG")) == 0)

{

allocate = false;

//Find outstanding SI

if (Convert.ToInt32(SDOHelper.Read(oHeaderData, "TYPE")) == 1)

{

// move through the INVOICE splits

oSplitData = (SageDataObject300.SplitData)oHeaderData.Link;

oSplitData.MoveFirst();

do

{

// obtain amount for split and get record number

dInvVal = (Double)SDOHelper.Read(oSplitData, "NET_AMOUNT") + (Double)SDOHelper.Read(oSplitData, "TAX_AMOUNT") - (Double)SDOHelper.Read(oSplitData, "AMOUNT_PAID");

InvSpltNum = oSplitData.RecordNumber;

// exit loop if there is an amount of 1p or more

if (dInvVal > 0.009)

{

break; // TODO: might not be correct. Was : Exit Do

}

} while (!(!oSplitData.MoveNext()));

}

// find outstanding SC

if (Convert.ToInt32(SDOHelper.Read(oHeaderData, "TYPE")) == 2)

{

// move through the CREDIT splits

oSplitData = (SageDataObject300.SplitData)oHeaderData.Link;

oSplitData.MoveFirst();

do

{

// obtain amount for split and get record number

dCredVal = (Double)SDOHelper.Read(oSplitData, "NET_AMOUNT") + (Double)SDOHelper.Read(oSplitData, "TAX_AMOUNT") - (Double)SDOHelper.Read(oSplitData, "AMOUNT_PAID");

CredSpltNum = oSplitData.RecordNumber;

// exit loop if there is an amount of 1p or more

if (dCredVal > 0.009)

{

break; // TODO: might not be correct. Was : Exit Do

}

} while (!(!oSplitData.MoveNext()));

}

}

else

{

PaidFlag = true;

dInvVal = 0;

dCredVal = 0;

}

// if both values are > 1p then break out of loop and perform allocation

if (dInvVal > 0.009 & dCredVal > 0.009)

{

allocate = true;

break;

}

else

{

PaidFlag = true;

}

} while (!(!oHeaderData.MoveNext()));

// set correct amount to allocate

if (dCredVal >= dInvVal)

{

AllocVal = dInvVal;

}

else

{

AllocVal = dCredVal;

}

// 1st IF ensures we don't get 'failed' on last iteration

if (allocate)

{

// Initialise TransactionPost Object

oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

// now allocate respective amount and inform user of success/failure

if (oTransactionPost.AllocatePayment(Convert.ToInt32(InvSpltNum), Convert.ToInt32(CredSpltNum), Convert.ToDouble(AllocVal), System.DateTime.Today))

{

MessageBox.Show("Allocation successful");

dCredVal = 0;

dInvVal = 0;

}

else

{

MessageBox.Show("Allocation failed");

this.Close();

break; // TODO: might not be correct. Was : Exit Do

}

}

} while (!(PaidFlag));

//loops until one of the header transactions is paid in full

MessageBox.Show("All Complete");

}

catch(Exception ex)

{

MessageBox.Show(ex.Message.ToString());

}

finally

{

oWS.Disconnect();

}

}// userDefinedMethod

}

}


Sage 50 Accounts - Example -�Allocate Stock

Example - Allocate Stock

The example code below demonstrates how to allocate stock for a product.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace

Dim oStockAllocation As SageDataObject300.StockAllocation
Dim oProduct As SageDataObject300.Product
Dim oProject As SageDataObject300.Project
Dim oCostCode As SageDataObject300.ProjectCostCode

Dim szDataPath As String

' Create the SDO Engine object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
 ' the path will be passed to the szDataPath variable.
 ' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

' Connect to Data Files
If oWS.Connect(szDataPath, "", "", "Example") Then

' Create Objects
oStockAllocation = oWS.CreateStockAllocation
oProduct = oWS.CreateProduct
oProject = oWS.CreateProject
oCostCode = oWS.CreateProjectCostCode

' Load the Product
If oProduct.Load("BOARD001") Then

' Set the product for the stock allocation
oStockAllocation.Product = oProduct

' Load the Project (optional)
If oProject.Load("PROJ1") Then

' Set the project for the stock allocation
oStockAllocation.Project = oProject

End If

' Load the CostCode (optional)
If oCostCode.Load("LAB1") Then

' Set the costcode for the stock allocation
oStockAllocation.CostCode = oCostCode

End If

' Set the allocation details
oStockAllocation.Date = CDate(Now)
oStockAllocation.Details = "Stock Allocation"
oStockAllocation.QtyAllocated = CDbl(1)
oStockAllocation.Reference = "ALLOC"

' Save the allocation
If oStockAllocation.Update Then

MsgBox("The Stock Allocation Update was successful", vbOKOnly, "SDO Examples")

Else

MsgBox("The Stock Allocation Update was unsuccessful", vbOKOnly, "SDO Examples")

End If

End If

Else

MsgBox("Could not logon to the data,", vbOKOnly, "SDO Examples")

End If

oWS.Disconnect()

End If

' Dispose of any objects
oSDO = Nothing
oWS = Nothing

oStockAllocation = Nothing
oProduct = Nothing
oProject = Nothing
oCostCode = Nothing

Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.StockAllocation oStockAllocation;

SageDataObject300.Product oProduct;

SageDataObject300.Project oProject;

SageDataObject300.ProjectCostCode oCostCode;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate Objects

  oStockAllocation = (SageDataObject300.StockAllocation)oWS.CreateStockAllocation();

  oProduct = (SageDataObject300.Product)oWS.CreateProduct();

  oProject = (SageDataObject300.Project)oWS.CreateProject();

  oCostCode = (SageDataObject300.ProjectCostCode)oWS.CreateProjectCostCode();

  //Declare Variables for load methods

  Object BOARD001 = "BOARD001";

  Object PROJ001 = "PROJ001";

  Object LAB = "LAB1";

  //Load the Product

  if (oProduct.Load(ref BOARD001))

  {

    //Set the product for the stock allocation

    oStockAllocation.Product = oProduct;

    //Load the Project (Optional)

    if (oProject.Load(ref PROJ001))

    {

      //Set the Project for the stock allocation

      oStockAllocation.Project = oProject;

    }

    //Load the Cost Code (Optional)

    if (oCostCode.Load(ref LAB))

    {

      //Set the Cost Code for the stock allocation

      oStockAllocation.CostCode = oCostCode;

    }

    //Set the allocation details

    oStockAllocation.Date = (DateTime)DateTime.Today;

    oStockAllocation.Details = (String)"Stock Allocation";

    oStockAllocation.QtyAllocated = (Double)1;

    oStockAllocation.Reference = (String)"ALLOC";

    //Save the allocation

    if (oStockAllocation.Update())

    {

      MessageBox.Show("The Stock Allocation Update was Successful");

    }

    else

    {

      MessageBox.Show("The Stock Allocation Failed");

    }

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example -�Amend an Allocation

Example - Amend an Allocation

The example code below demonstrates how to amend an allocation or remove the allocation completely for a product.To remove an allocation you would Load the allocation, set the QtyAllocated to zero and update.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oStockAllocation As SageDataObject300.StockAllocation

Dim szDataPath As String

' Create the SDO Engine object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

' Connect to Data Files
If oWS.Connect(szDataPath, "", "", "Example") Then

' Create Objects
oStockAllocation = oWS.CreateStockAllocation

' Load the Allocation to Issue, passing the AllocationID
If oStockAllocation.Load(CInt(1)) Then

' Amend the Allocation quantity
oStockAllocation.QtyAllocated = CDbl(2)

' Update the issue
If oStockAllocation.Update Then

MsgBox("The Stock Allocation Amend Update was successful", vbOKOnly, "SDO Examples")

Else

MsgBox("The Stock Allocation Amend Update was unsuccessful", vbOKOnly, "SDO Examples")

End If

Else

MsgBox("The Stock Allocation Load was unsuccessful", vbOKOnly, "SDO Examples")

End If

Else

MsgBox("Could not logon to the data,", vbOKOnly, "SDO Examples")

End If

oWS.Disconnect()

End If

' Dispose of any objects
oSDO = Nothing
oWS = Nothing

oStockAllocation = Nothing

Exit Sub
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.StockAllocation oStockAlloc;

            try
            {
                // Instantiate objects
                oStockAlloc = (SageDataObject300.StockAllocation)oWS.CreateStockAllocation();

                // Declare an Allocation object & Load it
                Object allocRef = 1;
                if (oStockAlloc.Load(ref allocRef))
                {
                    oStockAlloc.QtyAllocated = (Double)2;
                    if (oStockAlloc.Update())
                    {
                        MessageBox.Show("Allocation amended successfully", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    }
                    else
                    {
                        MessageBox.Show("Allocation could not be amended", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    }
                }
                else
                {
                    MessageBox.Show("Allocation could not be loaded", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }

                // Disconnect
                oWS.Disconnect();
            }
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Accessing Stock Transactions

Example - Accessing Stock Transactions

The example code below demonstrates how to access the transactions for a Stock Record.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code

        ' Declare Objects

        Dim oSDO As SageDataObject300.SDOEngine

        Dim oWS As SageDataObject300.WorkSpace

        Dim oStockRecord As SageDataObject300.StockRecord

        Dim oStockTran As SageDataObject300.StockTran

        ' Declare Variables

        Dim szDataPath As String

        ' Create the SDO Engine Object

        oSDO = New SageDataObject300.SDOEngine()

        ' Create the Workspace

        oWS = oSDO.Workspaces.Add("Example")

        ' Select Company. The SelectCompany method takes the program install

        ' folder as a parameter

        szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

        ' A U.I. for company selection is presented to the user. If a company is selected,

        ' the path will be passed to the szDataPath variable.

        ' If not, or the Cancel button is selected, the variable will be left empty.

        If szDataPath <> "" Then

            ' Try to Connect - Will throw an exception if it fails

            If oWS.Connect(szDataPath, "", "", "Example") Then

                ' Create Instance of Object

                oStockRecord = oWS.CreateObject("StockRecord")

                ' Read the First Stock Record

                oStockRecord.MoveFirst()

                ' Read the first Transaction

                oStockTran = oStockRecord.Link

                oStockTran.MoveFirst()

                ' Loop through the transactions

                Do

                ' You need to call read before data can be returned

                oStockTran.Read(oStockTran.RecordNumber)

                    ' Display the description

                    MsgBox("Description " & CStr(oStockTran.Fields.Item("DETAILS").Value), MsgBoxStyle.OkOnly, "SDO Examples")

                Loop Until Not oStockTran.MoveNext

                ' Disconnect

                oWS.Disconnect()

            End If

        End If

        ' Destroy Objects

        oStockTran = Nothing

        oStockRecord = Nothing

        oWS = Nothing

        oSDO = Nothing

        Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.StockRecord oStockRecord;

SageDataObject300.StockTran oStockTran;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate Stock Record Object

  oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");

  //Read the first stock record

  oStockRecord.MoveFirst();

  //Read the first transaction

  oStockTran = (SageDataObject300.StockTran)oStockRecord.Link;

  oStockTran.MoveFirst();

  //Loop through the transactions

  do

  {

    //You need to call read before you can return the data

  oStockTran.Read(oStockTran.RecordNumber);

    //Display the description

    MessageBox.Show("Description:  " + (String)SDOHelper.Read(oStockTran, "DETAILS"));

  } while (oStockTran.MoveNext());

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Creating a New Product Record

Example - Creating a New Product Record

The example code below demonstrates how to create a new Product Record.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
                                ' Declare Objects
Dim oSDO  As
                              SageDataObject300.SDOEngine
Dim oWS  As
                              SageDataObject300.WorkSpace
Dim oStockRecord  As
                              SageDataObject300.StockRecord

' Declare Variables
Dim szDataPath  As String
Dim bFlag  As Boolean

' Create the SDO Object
oSDO =  New   SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> ""  Then

' Connect to Data Files
If oWS.Connect(szDataPath, "", "", "Example")
                               Then

' Create Instance of StockRecord Object
oStockRecord = oWS.CreateObject("StockRecord")

' Add New Record
oStockRecord.AddNew()

' Populate the Fields
oStockRecord.Fields.Item("STOCK_CODE").Value = CStr("NEWSTOCK")
oStockRecord.Fields.Item("DESCRIPTION").Value =
                              CStr("New Stock Item")
oStockRecord.Fields.Item("Item_Type").Value =
                                SageDataObject300.StockItemType.sdoNonStockItem
oStockRecord.Fields.Item("NOMINAL_CODE").Value
                                = CStr("4000")
oStockRecord.Fields.Item("UNIT_OF_SALE").Value
                                = CStr("Each")

' Update the Record
If oStockRecord.Update
                               Then

' Update Successful
MsgBox("Stock Record successfully created", MsgBoxStyle.OKOnly, "SDO Examples")

Else

' Update Unsuccessful
MsgBox("Stock Record not created", MsgBoxStyle.OKOnly, "SDO Examples")

End If

'Disconnect
oWS.Disconnect()

End If

End If

oStockRecord =  Nothing
oSDO =  Nothing
oWS =  Nothing

Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.StockRecord oStockRecord;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate Stock Record Object

  oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");

  //Add a new record

  oStockRecord.AddNew();

  //Populate the fields

  SDOHelper.Write(oStockRecord, "STOCK_CODE", (String)"NEWSTOCK");

  SDOHelper.Write(oStockRecord, "DESCRIPTION", (String)"New Stock Item");

  SDOHelper.Write(oStockRecord, "ITEM_TYPE", (Byte)SageDataObject300.StockItemType.sdoNonStockItem);

  SDOHelper.Write(oStockRecord, "NOMINAL_CODE", (String)"4000");

  SDOHelper.Write(oStockRecord, "UNIT_OF_SALE", (String)"Each");

  //Update the record

  if (oStockRecord.Update())

  {

    MessageBox.Show("New Stock Record Created Successfully");

  }

  else

  {

    MessageBox.Show("Stock Record Not Created");

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Creating a New Special Price

Example - Creating a New Special Price

The example code below demonstrates how to create a new Special Price.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
                                ' Declare Objects
Dim oSDO  As
                              SageDataObject300.SDOEngine
Dim oWS  As
                              SageDataObject300.WorkSpace
Dim oPriceRecord  As
                              SageDataObject300.PriceRecord
Dim oSalesRecord  As
                              SageDataObject300.SalesRecord
Dim oStockRecord  As
                              SageDataObject300.StockRecord

' Declare Variables
Dim szDataPath  As String
Dim szAccRef  As String

' Create the SDO Engine Object
oSDO =  New   SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company.  The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> ""  Then

' Try to Connect - Will throw an exception if it fails
If oWS.Connect(szDataPath, "", "", "Example")
                               Then

' Create Instances of Objects
oPriceRecord = oWS.CreateObject("PriceRecord")
oSalesRecord = oWS.CreateObject("SalesRecord")
oStockRecord = oWS.CreateObject("StockRecord")

' Read the First Customer
oSalesRecord.MoveFirst

' Read the first Stock Record
oStockRecord.MoveFirst

' Populate New Price Record
oPriceRecord.AddNew

szAccRef = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)

' Pad with spaces up to 8 chars
szAccRef = szAccRef.PadRight(8, Chr(32))

' Discount Type ( from the enum PriceListType )
oPriceRecord.Fields.Item("DISCOUNT_TYPE").Value = CByte(SageDataObject300.PriceListType.plFixed)

' If this was a price list then use the constanst pricePriceList
oPriceRecord.Fields.Item("TYPE").Value = CByte(SageDataObject300.priceTypes.priceSpecial)
oPriceRecord.Fields.Item("STORED_PRICE").Value = CDbl(10)
oPriceRecord.Fields.Item("VALUE").Value = CDbl(10)

' Add S to denote Special Price adding Customer account reference and stock code
' NB: An P denotes a price list
oPriceRecord.Fields.Item("REFERENCE").Value = CStr("S") &
                              CStr(szAccRef) &
                              CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
oPriceRecord.Fields.Item("EXT_REF").Value = CStr(szAccRef)
oPriceRecord.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)

' Update the Record
If oPriceRecord.Update
                               Then

MsgBox "Update Successful.", vbOKOnly, "SDO Examples"

Else

MsgBox "Update Unsuccessful.", vbOKOnly, "SDO Examples"

End If

' Disconnect
oWS.Disconnect

End If

End If

' Destroy Objects
oSalesRecord =  Nothing
oStockRecord =  Nothing
oPriceRecord =  Nothing
oWS =  Nothing
oSDO =  Nothing

Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.PriceRecord oPriceRecord;

SageDataObject300.SalesRecord oSalesRecord;

SageDataObject300.StockRecord oStockRecord;

String szDataPath;

String szAccRef;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate Objects

  oPriceRecord = (SageDataObject300.PriceRecord)oWS.CreateObject("PriceRecord");

  oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");

  oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");

  //Read the first customer and first stock record

  oSalesRecord.MoveFirst();

  oStockRecord.MoveFirst();

  //Create a new price record

  oPriceRecord.AddNew();

  //Store the Customer Account Ref

  szAccRef = (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF");

  //Pad with spaces up to 8 characters

  szAccRef = szAccRef.PadRight(8,Convert.ToChar(32) );

  //Discount Type (From the enum PriceListType)

  SDOHelper.Write(oPriceRecord, "DISCOUNT_TYPE", (Byte)SageDataObject300.PriceListType.plFixed);

  //If this was a price list then use the constant pricePriceList

  SDOHelper.Write(oPriceRecord, "TYPE", (Byte)SageDataObject300.priceTypes.priceSpecial);

  SDOHelper.Write(oPriceRecord, "STORED_PRICE", (Double)10);

  SDOHelper.Write(oPriceRecord, "VALUE", (Double)10);

  //Add S to denote special price adding customer account reference and stock code

  //NB: a P denotes a price list

  SDOHelper.Write(oPriceRecord, "REFERENCE", (String)"S" + (String)szAccRef +

    (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));

  SDOHelper.Write(oPriceRecord, "EXT_REF", (String)szAccRef);

  SDOHelper.Write(oPriceRecord, "STOCK_CODE",

    (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));

  //Update the record

  if (oPriceRecord.Update())

  {

    MessageBox.Show("Update Successful");

  }

  else

  {

    MessageBox.Show("Update Failed");

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Display Stock Categories

Example - Display Stock Categories

The example code below demonstrates how to display stock categories.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oStockCategory As SageDataObject300.StockCategory

'Error Handler
Try

    ' Declare Variables
    Dim szDataPath As String

    ' Create the SDOEngine Object
    oSDO = New SageDataObject300.SDOEngine

    ' Create the Workspace
    oWS = oSDO.Workspaces.Add("Example")

    ' Select Company.  The SelectCompany method takes the program install
    ' folder as a parameter
    szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024\")

    ' A U.I. for company selection is presented to the user. If a company is selected,
    ' the path will be passed to the szDataPath variable.
    ' If not, or the Cancel button is selected, the variable will be left empty.
    If szDataPath <> "" Then

        ' Try to Connect - Will Throw an Exception if it Fails
        If oWS.Connect(szDataPath, "", "", "Example") Then

            oStockCategory = oWS.CreateObject("StockCategory")

            oStockCategory.Open(SageDataObject300.OpenMode.sdoRead)

            For i As Integer = 1 To oStockCategory.Count
                oStockCategory.Read(i)
                MsgBox(oStockCategory.Fields.Item("NAME").Value)
            Next

            oWS.Disconnect()

        End If

    End If

Catch ex As Exception

    ' Error Handling Code
    MessageBox.Show("The SDO generated the following error: " & ex.Message, "SDO Examples", _
    MessageBoxButtons.OK, MessageBoxIcon.Error)

End Try

'Destroy Objects
oStockCategory = Nothing
oWS = Nothing
oSDO = Nothing
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.StockCategory oStockCategory;

String szDataPath;

// instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

// show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

// try a connection, will throw an exception if it fails
try
{
    // leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

    // create StockCategory Object
    oStockCategory = (SageDataObject300.StockCategory)oWS.CreateObject("StockCategory");

    // open the data file in READ mode
    oStockCategory.Open(SageDataObject300.OpenMode.sdoRead);

    for (int i = 1; i <= oStockCategory.Count(); i++)
    {
        // read item at current position in loop
        oStockCategory.Read(i);

        MessageBox.Show((String)SDOHelper.Read(oStockCategory, "NAME"));
    }

}
catch (Exception ex)
{
    MessageBox.Show("Data could not be read.", "SDO Examples");
}


Sage 50 Accounts - Example - Accessing Stock Transactions

Example - Editing Stock Transactions

The example code below demonstrates how to access and edit the transactions for a Stock Record.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oStockRecord As SageDataObject300.StockRecord
Dim oStockTran As SageDataObject300.StockTran

' Declare Variables
Dim szDataPath As String

' Create the SDO Engine Object
oSDO = New SageDataObject300.SDOEngine()

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

    ' Try to Connect - Will throw an exception if it fails
    If oWS.Connect(szDataPath, "", "", "Example") Then

        ' Create Instance of Object
        oStockRecord = oWS.CreateObject("StockRecord")

        ' Read the First Stock Record
        oStockRecord.MoveFirst()

        ' Read the first Transaction
        oStockTran = oStockRecord.Link
        oStockTran.MoveFirst()

        ' Loop through the transactions
        Do
            'Set the value of the field you wish to edit
            oStockTran.Read(oStockTran.RecordNumber)
            oStockTran.Fields.Item("DETAILS").Value = CStr("SDO EDITED STOCKTRAN")

            'Write the new value back to the data
            oStockTran.Write(oStockTran.RecordNumber)

            ' Display the edited description
            MsgBox("Description " & CStr(oStockTran.Fields.Item("DETAILS").Value), MsgBoxStyle.OkOnly, "SDO Examples")

        Loop Until Not oStockTran.MoveNext

        ' Disconnect
        oWS.Disconnect()

    End If
End If

' Destroy Objects
oStockTran = Nothing
oStockRecord = Nothing
oWS = Nothing
oSDO = Nothing

Exit Sub
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.StockRecord oStockRecord;
SageDataObject300.StockTran oStockTran;

String szDataPath;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try
{
    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

    //Instantiate Stock Record Object
    oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");

    //Read the first stock record
    oStockRecord.MoveFirst();

    //Read the first transaction
    oStockTran = (SageDataObject300.StockTran)oStockRecord.Link;
    oStockTran.MoveFirst();

    //Loop through the transactions
    do
    {
        //Set the value of the field you wish to edit
        SDOHelper.Write((String)oStockTran, "DETAILS", "SDO EDITED STOCKTRAN");

        //Write the new value back to the data
        oStockTran.Write(oStockTran.RecordNumber);

        //Display the edited description
        MessageBox.Show("Description: " + (String)SDOHelper.Read(oStockTran, "DETAILS"));

    } while (oStockTran.MoveNext());

    //Disconnect
    oWS.Disconnect();

}
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}


Sage 50 Accounts - Example - Creating a New Bank Account Record

Example - Find Purchase Order Allocations

The example code below demonstrates how to find purchase order allocations for a specific stock code.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
'Declare objects
Dim oSDO As SageDataObject300.SDOEngine = New SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oPopcord As SageDataObject300.Popcord
Dim oPopItem As SageDataObject300.PopItem

Dim szDataPath As String

'Instantiate WorkSpace
oWS = oSDO.Workspaces.Add("Example")

'Show select company dialog
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

'Try a connection, will throw an exception if it fails
Try

    'Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE")

    'Create the POpcord object.
    oPopcord = oWS.CreateObject("POpCORD")

    'Move to the first Popcord
    oPopcord.MoveFirst()

    Do  'Loop through the Popcords
        ' If the Popcord Status is equal to FullAllocated or PartFullAllocated
        If oPopcord.Fields.Item("STATUS").Value = 6 Or oPopcord.Fields.Item("STATUS").Value = 2 Then

            'Use the Link method to return the Items
            oPopItem = oPopcord.Link
            'move to the first item
            oPopItem.MoveFirst()

            Do   'loop through the popItems

                'Read the POPItem
                oPopItem.Read(oPopItem.RecordNumber)

                'Pass the STOCK_CODE we wish to see the orders for
                If oPopItem.Fields.Item("STOCK_CODE").Value = CStr("CALC001") Then

                    'Check to see if there is stock allocate
                    If oPopItem.Fields.Item("QTY_ALLOCATED").Value > 0 Then

                        'Display in a control
                            MessageBox.Show("The stock is allocated on order " & oPopItem.Fields.Item("INVOICE_NUMBER").Value
                    End If

                End If

            Loop Until Not oPopItem.MoveNext

        End If

    Loop Until Not oPopcord.MoveNext

Catch ex As Exception
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!")
End Try

'Disconnect from the Database
oWS.Disconnect()

'Destroy the objects
oWS = Nothing
oSDO = Nothing
oPopcord = Nothing
oPopItem = Nothing
C#.NET [image] Copy C# Code
//Declare objects
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.Popcord oPopcord;
SageDataObject300.PopItem oPopItem;

String szDataPath;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024\\");

//Try a connection, will throw an exception if it fails
try
{
    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

    //Create the POpcord object.
    oPopcord = (SageDataObject300.Popcord)oWS.CreateObject("POpCORD");

    //iterate through the Popcords
    for (int irecNo = 1; irecNo <= oPopcord.Count; irecNo++)
    {
        //Check the Status of the POP if it is FullyAllocated(6) or PartFullAllocated(2)
        if (Convert.ToByte(SDOHelper.Read(oPopcord, "STATUS")) == 6 || Convert.ToByte(SDOHelper.Read(oPopcord, "STATUS")) == 2)
        {

            //Check the Purchase Order items for relevant stock
            //Use the Link method to return the Items
            oPopItem = (SageDataObject300.PopItem)oPopcord.Link;
            //move to the first item
            oPopItem.MoveFirst();

            do   //loop through the popItems
            {
                //Read the POPItem
                oPopItem.Read(oPopItem.RecordNumber);

                //Pass the STOCK_CODE we wish to see the orders for
                if ((string)SDOHelper.Read(oPopItem, "STOCK_CODE") == (string)"CALC001")
                {
                    //Check to see if there is stock allocate
                    if ((double)SDOHelper.Read(oPopItem, "QTY_ALLOCATED") > 0)
                    {
                        //Display in a control
                        MessageBox.Show("The stock is allocated on order " + SDOHelper.Read(oPopItem, "INVOICE_NUMBER"));
                    }
                }
            } while (!(!oPopItem.MoveNext()));
        }
    }
}
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}

//Disconnect from the Database
oWS.Disconnect();

//Destroy the objects
oWS = null;
oSDO = null;
oPopcord = null;
oPopItem = null;


Sage 50 Accounts - Example -�Issue an Allocation

Example - Issue an Allocation

The example code below demonstrates how to issue an allocation for a product.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
        ' Declare Objects
        Dim oSDO As SageDataObject300.SDOEngine
        Dim oWS As SageDataObject300.WorkSpace
        Dim oStockAllocation As SageDataObject300.StockAllocation

        Dim szDataPath As String

        ' Create the SDO Engine object
        oSDO = New SageDataObject300.SDOEngine

        ' Create the Workspace
        oWS = oSDO.Workspaces.Add("Example")

        ' Select company. The SelectCompany method takes the program install folder as a parameter
        szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

        ' A U.I. for company selection is presented to the user. If a company is selected,
        ' the path will be passed to the szDataPath variable.
        ' If not, or the Cancel button is selected, the variable will be left empty.
        If szDataPath <> "" Then

            ' Connect to Data Files
            If oWS.Connect(szDataPath, "", "", "Example") Then

                ' Create Objects
                oStockAllocation = oWS.CreateStockAllocation

                ' Load the Allocation to Issue, passing the AllocationID
                If oStockAllocation.Load(CInt(2)) Then

                    ' Set the Issue
                    If oStockAllocation.Issue(CDbl(1), CDate(Now)) Then

                        MsgBox("The Stock Allocation Issue was successful", vbOKOnly, "SDO Examples")

                    Else

                        MsgBox("The Stock Allocation Issue was unsuccessful", vbOKOnly, "SDO Examples")

                    End If

                Else

                    MsgBox("The Stock Allocation Load was unsuccessful", vbOKOnly, "SDO Examples")

                End If

            Else

                MsgBox("Could not logon to the data,", vbOKOnly, "SDO Examples")

            End If

            oWS.Disconnect()

        End If

        ' Dispose of any objects
        oSDO = Nothing
        oWS = Nothing

        oStockAllocation = Nothing

        Exit Sub
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.StockAllocation oStockAlloc;

            try
            {
                // Instantiate objects
                oStockAlloc = (SageDataObject300.StockAllocation)oWS.CreateStockAllocation();

                // Declare an Allocation object & Load it
                Object allocRef = 2;
                if (oStockAlloc.Load(ref allocRef))
                {
                    // Issue the allocation
                    if (oStockAlloc.Issue((Double)2, (DateTime)DateTime.Now))
                    {
                        MessageBox.Show("Allocation issued successfully", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    }
                    else
                    {
                        MessageBox.Show("Allocation could not be issued", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    }
                }
                else
                {
                    MessageBox.Show("Allocation could not be loaded", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }

                // Disconnect
                oWS.Disconnect();
            }
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Posting an Adjustment In

Example - Posting an Adjustment In

The example code below demonstrates how to post an Adjustment In.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
                                ' Declare Objects
Dim oSDO  As
                              SageDataObject300.SDOEngine
Dim oWS  As
                              SageDataObject300.WorkSpace
Dim oStockPost  As
                              SageDataObject300.StockPost
Dim oStockTran  As
                              SageDataObject300.StockTran
Dim oStockRecord  As
                              SageDataObject300.StockRecord

' Declare Variables
Dim szDataPath  As String

' Create the SDO Object
oSDO =  New   SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024\")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> ""  Then

' Connect to Data Files
If oWS.Connect(szDataPath, "", "", "Example")
                               Then

' Create Instances of Transaction Post
oStockPost = oWS.CreateObject("StockPost")
oStockRecord = oWS.CreateObject("StockRecord")

' Read first Stock Code
oStockRecord.MoveFirst()

' Fill in Header information required
oStockPost.Header("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)

' Add to the items collection of the StockPost object
oStockTran = oStockPost.Items.Add

' Populate Stock Transaction Fields
' This example posts a AI (Adjustment In) Transaction
oStockTran.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
oStockTran.Fields.Item("Date").Value = CDate(Today)
oStockTran.Fields.Item("Type").Value = CByte(SageDataObject300.StockTransType.sdoAI)
oStockTran.Fields.Item("Quantity").Value =
                              CDbl(2)
oStockTran.Fields.Item("COST_PRICE").Value = CDbl(15)
oStockTran.Fields.Item("Reference").Value =
                              CStr("Test AI")
oStockTran.Fields.Item("Details").Value = CStr("Adjustments")

' Update the StockPost object
If oStockPost.Update
                               Then

' Transaction Post Successfull
MsgBox("Transaction posted successfully", MsgBoxStyle.OKOnly, "SDO Examples")

Else

' Transaction Post Failed
MsgBox("Transaction Post Unsuccessful", MsgBoxStyle.OKOnly, "SDO Examples")

End If

'Disconnect
oWS.Disconnect()

End If

End If

oSDO =  Nothing
oWS =  Nothing
oStockRecord =  Nothing
oStockPost =  Nothing

Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.StockPost oStockPost;

SageDataObject300.StockTran oStockTran;

SageDataObject300.StockRecord oStockRecord;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate Objects

  oStockPost = (SageDataObject300.StockPost)oWS.CreateObject("StockPost");

  oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");

  //Read the first stock code

  oStockRecord.MoveFirst();

  //Fill in header information required

  SDOHelper.Write(oStockPost.Header, "STOCK_CODE",

    (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));

  //Add to the items collection of the stock post object

  oStockTran = (SageDataObject300.StockTran)SDOHelper.Add(oStockPost.Items);

  //Populate Stock Transaction Fields

  //This example posts an AI (Adjustment In) Transaction

  SDOHelper.Write(oStockTran, "STOCK_CODE",

    (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));

  SDOHelper.Write(oStockTran, "DATE", (DateTime)DateTime.Today);

  SDOHelper.Write(oStockTran, "TYPE", (Byte)SageDataObject300.StockTransType.sdoAI);

  SDOHelper.Write(oStockTran, "QUANTITY", (Double)2);

  SDOHelper.Write(oStockTran, "COST_PRICE", (Double)15);

  SDOHelper.Write(oStockTran, "REFERENCE", (String)"Test AI");

  SDOHelper.Write(oStockTran, "DETAILS", (String)"Adjustments");

  //Update the stock post object

  //Note: If the Stock Item is Non-Stock

  //the transaction will post but have no effect in Sage Accounts

  if (oStockPost.Update())

  {

    MessageBox.Show("Stock Transaction Posted Successfully");

  }

  else

  {

    MessageBox.Show("Stock Transaction Failed to Post");

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Posting an Adjustment Out

Example - Posting an Adjustment Out

The example code below demonstrates how to post an Adjustment Out.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
                                ' Declare Objects
Dim oSDO  As
                              SageDataObject300.SDOEngine
Dim oWS  As
                              SageDataObject300.WorkSpace
Dim oStockPost  As
                              SageDataObject300.StockPost
Dim oStockTran  As
                              SageDataObject300.StockTran
Dim oStockRecord  As
                              SageDataObject300.StockRecord

' Declare Variables
Dim szDataPath  As String

' Create the SDO Object
oSDO =  New   SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> ""  Then

' Connect to Data Files
If oWS.Connect(szDataPath, "", "", "Example")
                               Then

' Create Instances of Transaction Post
oStockPost = oWS.CreateObject("StockPost")
oStockRecord = oWS.CreateObject("StockRecord")

' Read first Stock Code
oStockRecord.MoveFirst()

' Fill in Header information required
oStockPost.Header("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)

' Add to the items collection of the StockPost object
oStockTran = oStockPost.Items.Add

' Populate Stock Transaction Fields
' This example posts a AO (Adjustment Out) Transaction
oStockTran.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
oStockTran.Fields.Item("Date").Value = CDate(Today)
oStockTran.Fields.Item("Type").Value = CByte(SageDataObject300.StockTransType.sdoAO)
oStockTran.Fields.Item("Quantity").Value =
                              CDbl(2)
oStockTran.Fields.Item("Reference").Value =
                              CStr("Test AO")
oStockTran.Fields.Item("Details").Value = CStr("Adjustments")

' Update the StockPost object
If oStockPost.Update
                               Then

' Transaction Post
                                  Successfull
MsgBox("Transaction posted successfully", MsgBoxStyle.OKOnly, "SDO Examples")

Else

' Transaction Post Failed
MsgBox("Transaction Post Unsuccessful", MsgBoxStyle.OKOnly, "SDO Examples")

End If

' Disconnect
oWS.Disconnect()

End If

End If

oStockRecord =  Nothing
oStockPost =  Nothing
oSDO =  Nothing
oWS =  Nothing

Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.StockPost oStockPost;

SageDataObject300.StockTran oStockTran;

SageDataObject300.StockRecord oStockRecord;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate Objects

  oStockPost = (SageDataObject300.StockPost)oWS.CreateObject("StockPost");

  oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");

  //Read the first stock code

  oStockRecord.MoveFirst();

  //Fill in header information required

  SDOHelper.Write(oStockPost.Header, "STOCK_CODE",

    (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));

  //Add to the items collection of the stock post object

  oStockTran = (SageDataObject300.StockTran)SDOHelper.Add(oStockPost.Items);

  //Populate Stock Transaction Fields

  //This example posts an AI (Adjustment In) Transaction

  SDOHelper.Write(oStockTran, "STOCK_CODE",

    (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));

  SDOHelper.Write(oStockTran, "DATE", (DateTime)DateTime.Today);

  SDOHelper.Write(oStockTran, "TYPE", (Byte)SageDataObject300.StockTransType.sdoAI);

  SDOHelper.Write(oStockTran, "QUANTITY", (Double)2);

  SDOHelper.Write(oStockTran, "COST_PRICE", (Double)15);

  SDOHelper.Write(oStockTran, "REFERENCE", (String)"Test AO");

  SDOHelper.Write(oStockTran, "DETAILS", (String)"Adjustments");

  //Update the stock post object

  //Note: If the Stock Item is Non-Stock

  //the transaction will post but have no effect in Sage Accounts

  if (oStockPost.Update())

  {

    MessageBox.Show("Stock Transaction Posted Successfully");

  }

  else

  {

    MessageBox.Show("Stock Transaction Failed to Post");

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Posting Damages In

Example - Posting Damages In

The example code below demonstrates how to post a Damages In.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
                                ' Declare Objects
Dim oSDO  As
                              SageDataObject300.SDOEngine
Dim oWS  As
                              SageDataObject300.WorkSpace
Dim oStockPost  As
                              SageDataObject300.StockPost
Dim oStockTran  As
                              SageDataObject300.StockTran
Dim oStockRecord  As
                              SageDataObject300.StockRecord

' Declare Variables
Dim szDataPath  As String

' Create the SDO Object
oSDO =  New   SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024\")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> ""  Then

' Connect to Data Files
If oWS.Connect(szDataPath, "", "", "Example")
                               Then

' Create Instances of Transaction Post
oStockPost = oWS.CreateObject("StockPost")
oStockRecord = oWS.CreateObject("StockRecord")

' Read first Stock Code
oStockRecord.MoveFirst()

' Fill in Header information required
oStockPost.Header("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)

' Add to the items collection of the StockPost object
oStockTran = oStockPost.Items.Add

' Populate Stock Transaction Fields
' This example posts a DI (Damages In) Transaction
oStockTran.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
oStockTran.Fields.Item("DATE").Value = CDate(Today)
oStockTran.Fields.Item("TYPE").Value = CByte(SageDataObject300.StockTransType.sdoDI)
oStockTran.Fields.Item("QUANTITY").Value =
                              CDbl(2)
oStockTran.Fields.Item("REFERENCE").Value =
                              CStr("Test DI")
oStockTran.Fields.Item("DETAILS").Value = CStr("Damages
                                In")

' Update the StockPost object
If oStockPost.Update
                               Then

' Transaction Post
                                  Successful
MsgBox("Transaction posted successfully", MsgBoxStyle.OKOnly, "SDO Examples")

Else

' Transaction Post Failed
MsgBox("Transaction Post Unsuccessful", MsgBoxStyle.OKOnly, "SDO Examples")

End If

'Disconnect
oWS.Disconnect()

End If

End If

oSDO =  Nothing
oWS =  Nothing
oStockRecord =  Nothing
oStockPost =  Nothing

Exit Sub
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.StockPost oStockPost;
            SageDataObject300.StockTran oStockTran;
            SageDataObject300.StockRecord oStockRecord;

            try
            {
                //Instantiate Objects
                oStockPost = (SageDataObject300.StockPost)oWS.CreateObject("StockPost");
                oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");

                //Read the first stock code
                oStockRecord.MoveFirst();

                //Fill in header information required
                SDOHelper.Write(oStockPost.Header, "STOCK_CODE", (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));

                //Add to the items collection of the stock post object
                oStockTran = (SageDataObject300.StockTran)SDOHelper.Add(oStockPost.Items);

                //Populate Stock Transaction Fields
                //This example posts a DI (Damages In) Transaction
                SDOHelper.Write(oStockTran, "STOCK_CODE", (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));
                SDOHelper.Write(oStockTran, "DATE", (DateTime)DateTime.Today);
                SDOHelper.Write(oStockTran, "TYPE", (Byte)SageDataObject300.StockTransType.sdoDI);
                SDOHelper.Write(oStockTran, "QUANTITY", (Double)2);
                SDOHelper.Write(oStockTran, "REFERENCE", (String)"Test DI");
                SDOHelper.Write(oStockTran, "DETAILS", (String)"Damages In");

                //Update the stock post object
                //Note: If the Stock Item is Non-Stock
                //the transaction will post but have no effect in Sage Accounts
                if (oStockPost.Update())
                {
                    MessageBox.Show("Stock 'Damages In' Posted Successfully");
                }
                else
                {
                    MessageBox.Show("Stock 'Damages In' Failed to Post");
                }

                // Disconnect
                oWS.Disconnect();
            }
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Posting Damages Out

Example - Posting Damages Out

The example code below demonstrates how to post a Damages Out.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
                                ' Declare Objects
Dim oSDO  As
                              SageDataObject300.SDOEngine
Dim oWS  As
                              SageDataObject300.WorkSpace
Dim oStockPost  As
                              SageDataObject300.StockPost
Dim oStockTran  As
                              SageDataObject300.StockTran
Dim oStockRecord  As
                              SageDataObject300.StockRecord

' Declare Variables
Dim szDataPath  As String

' Create the SDO Object
oSDO =  New   SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024\")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> ""  Then

' Connect to Data Files
If oWS.Connect(szDataPath, "", "", "Example")
                               Then

' Create Instances of Transaction Post
oStockPost = oWS.CreateObject("StockPost")
oStockRecord = oWS.CreateObject("StockRecord")

' Read first Stock Code
oStockRecord.MoveFirst()

' Fill in Header information required
oStockPost.Header("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)

' Add to the items collection of the StockPost object
oStockTran = oStockPost.Items.Add

' Populate Stock Transaction Fields
' This example posts a DI (Damages In) Transaction
oStockTran.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
oStockTran.Fields.Item("DATE").Value = CDate(Today)
oStockTran.Fields.Item("TYPE").Value = CByte(SageDataObject300.StockTransType.sdoDO)
oStockTran.Fields.Item("QUANTITY").Value =
                              CDbl(2)
oStockTran.Fields.Item("REFERENCE").Value =
                              CStr("Test DO")
oStockTran.Fields.Item("DETAILS").Value = CStr("Damages
                                Out")

' Update the StockPost object
If oStockPost.Update
                               Then

' Transaction Post
                                  Successful
MsgBox("Transaction posted successfully", MsgBoxStyle.OKOnly, "SDO Examples")

Else

' Transaction Post Failed
MsgBox("Transaction Post Unsuccessful", MsgBoxStyle.OKOnly, "SDO Examples")

End If

'Disconnect
oWS.Disconnect()

End If

End If

oSDO =  Nothing
oWS =  Nothing
oStockRecord =  Nothing
oStockPost =  Nothing

Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.StockPost oStockPost;

SageDataObject300.StockTran oStockTran;

SageDataObject300.StockRecord oStockRecord;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate Objects

  oStockPost = (SageDataObject300.StockPost)oWS.CreateObject("StockPost");

  oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");

  //Read the first stock code

  oStockRecord.MoveFirst();

  //Fill in header information required

  SDOHelper.Write(oStockPost.Header, "STOCK_CODE",

    (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));

  //Add to the items collection of the stock post object

  oStockTran = (SageDataObject300.StockTran)SDOHelper.Add(oStockPost.Items);

  //Populate Stock Transaction Fields

  //This example posts a DO (Damages Out) Transaction

  SDOHelper.Write(oStockTran, "STOCK_CODE",

    (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));

  SDOHelper.Write(oStockTran, "DATE", (DateTime)DateTime.Today);

  SDOHelper.Write(oStockTran, "TYPE", (Byte)SageDataObject300.StockTransType.sdoDO);

  SDOHelper.Write(oStockTran, "QUANTITY", (Double)2);

  SDOHelper.Write(oStockTran, "REFERENCE", (String)"Test DO");

  SDOHelper.Write(oStockTran, "DETAILS", (String)"Damages Out");

  //Update the stock post object

  //Note: If the Stock Item is Non-Stock

  //the transaction will post but have no effect in Sage Accounts

  if (oStockPost.Update())

  {

    MessageBox.Show("Stock Transaction Posted Successfully");

  }

  else

  {

    MessageBox.Show("Stock Transaction Failed to Post");

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Posting an Adjustment Out

Example - Posting a Goods Out

The example code below demonstrates how to post an Goods Out Stock Transaction.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code

                                  ' Declare Objects
Dim oSDO  As
                                SageDataObject300.SDOEngine
Dim oWS  As
                                SageDataObject300.WorkSpace
Dim oStockPost  As
                                SageDataObject300.StockPost
Dim oStockTran  As
                                SageDataObject300.StockTran
Dim oStockRecord  As
                                SageDataObject300.StockRecord

' Declare Variables
Dim szDataPath  As String

' Create the SDO Object
oSDO =  New   SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> ""  Then

' Connect to Data Files
If oWS.Connect(szDataPath, "", "", "Example")  Then

' Create Instances of Transaction Post
oStockPost = oWS.CreateObject("StockPost")
oStockRecord = oWS.CreateObject("StockRecord")

' Read first Stock Code
oStockRecord.MoveFirst()

' Fill in Header information required
oStockPost.Header("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)

' Add to the items collection of the StockPost object
oStockTran = oStockPost.Items.Add

' Populate Stock Transaction Fields
' This example posts a GO (Goods Out) Transaction
oStockTran.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
oStockTran.Fields.Item("Date").Value = CDate(Today)
oStockTran.Fields.Item("Type").Value = CByte(SageDataObject300.StockTransType.sdoGO)
oStockTran.Fields.Item("Quantity").Value = CDbl(2)
' Ensure the Reference field contains the SOP or Inv number
oStockTran.Fields.Item("Reference").Value = CStr("123")
oStockTran.Fields.Item("Details").Value = CStr("Goods Out ")
' Ensure the ISP Reference field also contains the SOP or Inv number
' If the ISP_Reference is not set the drill around function in the stock activity
' will not function
oStockTran.Fields.Item("ISP_REFERENCE").Value = CInt(123)
' Ensure the ARTEFACT_TYPE is set to 1 for an Invoice or 2 for a SOP
' If no ARTEFACT_TYPE value is set the value will be set to one as default
oStockTran.Fields.Item("ARTEFACT_TYPE").Value = CInt(1)

' Update the StockPost object
If oStockPost.Update  Then

' Transaction Post
    Successfull
MsgBox("Transaction posted successfully", MsgBoxStyle.OKOnly, "SDO Examples")

Else

' Transaction Post Failed
MsgBox("Transaction Post Unsuccessful", MsgBoxStyle.OKOnly, "SDO Examples")

End If

' Disconnect
oWS.Disconnect()

End If

End If

oStockRecord =  Nothing
oStockPost =  Nothing
oSDO =  Nothing
oWS =  Nothing

Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.StockPost oStockPost;

SageDataObject300.StockTran oStockTran;

SageDataObject300.StockRecord oStockRecord;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate Objects

  oStockPost = (SageDataObject300.StockPost)oWS.CreateObject("StockPost");

  oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");

  //Read the first stock code

  oStockRecord.MoveFirst();

  //Fill in header information required

  SDOHelper.Write(oStockPost.Header, "STOCK_CODE",

    (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));

  //Add to the items collection of the stock post object

  oStockTran = (SageDataObject300.StockTran)SDOHelper.Add(oStockPost.Items);

  //Populate Stock Transaction Fields

  //This example posts a GO (Goods Out) Transaction

  SDOHelper.Write(oStockTran, "STOCK_CODE",

    (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));

  SDOHelper.Write(oStockTran, "DATE", (DateTime)DateTime.Today);

  SDOHelper.Write(oStockTran, "TYPE", (Byte)SageDataObject300.StockTransType.sdoGO);

  SDOHelper.Write(oStockTran, "QUANTITY", (Double)2);

  SDOHelper.Write(oStockTran, "COST_PRICE", (Double)15);

  //Ensure the Reference field contains the SOP or Inv number

  SDOHelper.Write(oStockTran, "REFERENCE", (String)"123");

  SDOHelper.Write(oStockTran, "DETAILS", (String)"Goods Out");

  //Ensure the ISP Reference field also contains the SOP or Inv number

  //If the ISP_Reference is not set the drill around function in the stock activity

  //will not function

  SDOHelper.Write(oStockTran, "ISP_REFERENCE", (int)123);

  //Ensure the ARTEFACT_TYPE is set to 1 for an Invoice or 2 for a SOP

  //If no ARTEFACT_TYPE value is set the value will be set to one as default

  SDOHelper.Write(oStockTran, "ARTEFACT_TYPE", (int)1);

  //Update the stock post object

  //Note: If the Stock Item is Non-Stock

  //the transaction will post but have no effect in Sage Accounts

  if (oStockPost.Update())

  {

    MessageBox.Show("Stock Transaction Posted Successfully");

  }

  else

  {

    MessageBox.Show("Stock Transaction Failed to Post");

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Posting a Write Off

Example - Posting a Write Off

The example code below demonstrates how to post a Write Off.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
                                ' Declare Objects
Dim oSDO  As
                              SageDataObject300.SDOEngine
Dim oWS  As
                              SageDataObject300.WorkSpace
Dim oStockPost  As
                              SageDataObject300.StockPost
Dim oStockTran  As
                              SageDataObject300.StockTran
Dim oStockRecord  As
                              SageDataObject300.StockRecord

' Declare Variables
Dim szDataPath  As String

' Create the SDO Object
oSDO =  New   SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024\")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> ""  Then

' Connect to Data Files
If oWS.Connect(szDataPath, "", "", "Example")
                               Then

' Create Instances of Transaction Post
oStockPost = oWS.CreateObject("StockPost")
oStockRecord = oWS.CreateObject("StockRecord")

' Read first Stock Code
oStockRecord.MoveFirst()

' Fill in Header information required
oStockPost.Header("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)

' Add to the items collection of the StockPost object
oStockTran = oStockPost.Items.Add

' Populate Stock Transaction Fields
' This example posts a WO (Write Off) Transaction
oStockTran.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
oStockTran.Fields.Item("DATE").Value = CDate(Today)
oStockTran.Fields.Item("TYPE").Value = CByte(SageDataObject300.StockTransType.sdoWO)
oStockTran.Fields.Item("QUANTITY").Value =
                              CDbl(2)
oStockTran.Fields.Item("REFERENCE").Value =
                              CStr("Test WO")
oStockTran.Fields.Item("DETAILS").Value = CStr("Write
                                Off")

' Update the StockPost object
If oStockPost.Update
                               Then

' Transaction Post
                                  Successful
MsgBox("Transaction posted successfully", MsgBoxStyle.OKOnly, "SDO Examples")

Else

' Transaction Post Failed
MsgBox("Transaction Post Unsuccessful", MsgBoxStyle.OKOnly, "SDO Examples")

End If

'Disconnect
oWS.Disconnect()

End If

End If

oSDO =  Nothing
oWS =  Nothing
oStockRecord =  Nothing
oStockPost =  Nothing

Exit Sub
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.StockPost oStockPost;
            SageDataObject300.StockTran oStockTran;
            SageDataObject300.StockRecord oStockRecord;

            try
            {
                //Instantiate Objects
                oStockPost = (SageDataObject300.StockPost)oWS.CreateObject("StockPost");
                oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");

                //Read the first stock code
                oStockRecord.MoveFirst();

                //Fill in header information required
                SDOHelper.Write(oStockPost.Header, "STOCK_CODE", (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));

                //Add to the items collection of the stock post object
                oStockTran = (SageDataObject300.StockTran)SDOHelper.Add(oStockPost.Items);

                //Populate Stock Transaction Fields
                //This example posts a WO (Write Off) Transaction
                SDOHelper.Write(oStockTran, "STOCK_CODE", (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));
                SDOHelper.Write(oStockTran, "DATE", (DateTime)DateTime.Today);
                SDOHelper.Write(oStockTran, "TYPE", (Byte)SageDataObject300.StockTransType.sdoWO);
                SDOHelper.Write(oStockTran, "QUANTITY", (Double)2);
                SDOHelper.Write(oStockTran, "REFERENCE", (String)"Test WO");
                SDOHelper.Write(oStockTran, "DETAILS", (String)"Write Off");

                //Update the stock post object
                //Note: If the Stock Item is Non-Stock
                //the transaction will post but have no effect in Sage Accounts
                if (oStockPost.Update())
                {
                    MessageBox.Show("Stock Write Off Posted Successfully");
                }
                else
                {
                    MessageBox.Show("Stock Write Off Failed to Post");
                }

                // Disconnect
                oWS.Disconnect();
            }
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Adding an Item Line to an Invoice

Example - Adding an Item Line to an Invoice

The example code below demonstrates how to add an item line to an Invoice.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oInvoiceRecord As SageDataObject300.InvoiceRecord
Dim oInvoiceItem_Read As SageDataObject300.InvoiceItem
Dim oInvoiceItem_Write As SageDataObject300.InvoiceItem
Dim oInvoicePost As SageDataObject300.InvoicePost
Dim oStockRecord As SageDataObject300.StockRecord

' Declare Variables
Dim szDataPath As String
Dim iItemCount As Short

' Create SDO Engine Object
oSDO = New SageDataObject300.SDOEngine

' Create Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company.  The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

    ' Try to Connect - Will throw an exception if it fails
    If oWS.Connect(szDataPath, "", "", "Example") Then

        ' Create Objects
        oInvoiceRecord = oWS.CreateObject("InvoiceRecord")
        oInvoicePost = oWS.CreateObject("InvoicePost")
        oInvoiceItem_Read = oWS.CreateObject("InvoiceItem")
        oStockRecord = oWS.CreateObject("StockRecord")

        ' Read an existing invoice
        oInvoiceRecord.MoveLast()

        ' Select type of invoice to be posted.
        ' NOTE: For the purpose of this example, we assume the invoice to be a product invoice.
        oInvoicePost.Type = SageDataObject300.LedgerType.sdoLedgerInvoice

        ' Populate the invoice header, copying fields from oInvoiceRecord to oInvoicePost
        oInvoicePost.Header("INVOICE_NUMBER").Value = oInvoiceRecord.Fields.Item("INVOICE_NUMBER").Value
        oInvoicePost.Header("ACCOUNT_REF").Value = CStr(oInvoiceRecord.Fields.Item("ACCOUNT_REF").Value)
        oInvoicePost.Header("NAME").Value = CStr(oInvoiceRecord.Fields.Item("NAME").Value)
        oInvoicePost.Header("ADDRESS_1").Value = CStr(oInvoiceRecord.Fields.Item("ADDRESS_1").Value)
        oInvoicePost.Header("ADDRESS_2").Value = CStr(oInvoiceRecord.Fields.Item("ADDRESS_2").Value)
        oInvoicePost.Header("ADDRESS_3").Value = CStr(oInvoiceRecord.Fields.Item("ADDRESS_3").Value)
        oInvoicePost.Header("ADDRESS_4").Value = CStr(oInvoiceRecord.Fields.Item("ADDRESS_4").Value)
        oInvoicePost.Header("ADDRESS_5").Value = CStr(oInvoiceRecord.Fields.Item("ADDRESS_5").Value)
        oInvoicePost.Header("DEL_ADDRESS_1").Value = CStr(oInvoiceRecord.Fields.Item("DEL_ADDRESS_1").Value)
        oInvoicePost.Header("DEL_ADDRESS_2").Value = CStr(oInvoiceRecord.Fields.Item("DEL_ADDRESS_2").Value)
        oInvoicePost.Header("DEL_ADDRESS_3").Value = CStr(oInvoiceRecord.Fields.Item("DEL_ADDRESS_3").Value)
        oInvoicePost.Header("DEL_ADDRESS_4").Value = CStr(oInvoiceRecord.Fields.Item("DEL_ADDRESS_4").Value)
        oInvoicePost.Header("DEL_ADDRESS_5").Value = CStr(oInvoiceRecord.Fields.Item("DEL_ADDRESS_5").Value)
        oInvoicePost.Header("CUST_TEL_NUMBER").Value = CStr(oInvoiceRecord.Fields.Item("CUST_TEL_NUMBER").Value)
        oInvoicePost.Header("CONTACT_NAME").Value = CStr(oInvoiceRecord.Fields.Item("CONTACT_NAME").Value)
        oInvoicePost.Header("GLOBAL_TAX_CODE").Value = CShort(oInvoiceRecord.Fields.Item("GLOBAL_TAX_CODE").Value)
        oInvoicePost.Header("INVOICE_DATE").Value = CDate(oInvoiceRecord.Fields.Item("INVOICE_DATE").Value)
        oInvoicePost.Header("NOTES_1").Value = CStr(oInvoiceRecord.Fields.Item("NOTES_1").Value)
        oInvoicePost.Header("NOTES_2").Value = CStr(oInvoiceRecord.Fields.Item("NOTES_1").Value)
        oInvoicePost.Header("NOTES_3").Value = CStr(oInvoiceRecord.Fields.Item("NOTES_3").Value)
        oInvoicePost.Header("TAKEN_BY").Value = CStr(oInvoiceRecord.Fields.Item("TAKEN_BY").Value)
        oInvoicePost.Header("ORDER_NUMBER").Value = CStr(oInvoiceRecord.Fields.Item("ORDER_NUMBER").Value)
        oInvoicePost.Header("CUST_ORDER_NUMBER").Value = CStr(oInvoiceRecord.Fields.Item("CUST_ORDER_NUMBER").Value)
        oInvoicePost.Header("PAYMENT_REF").Value = CStr(oInvoiceRecord.Fields.Item("PAYMENT_REF").Value)
        oInvoicePost.Header("GLOBAL_NOM_CODE").Value = CStr(oInvoiceRecord.Fields.Item("GLOBAL_NOM_CODE").Value)
        oInvoicePost.Header("GLOBAL_DETAILS").Value = CStr(oInvoiceRecord.Fields.Item("GLOBAL_DETAILS").Value)
        oInvoicePost.Header("FOREIGN_RATE").Value = CDbl(oInvoiceRecord.Fields.Item("FOREIGN_RATE").Value)
        oInvoicePost.Header("CURRENCY").Value = oInvoiceRecord.Fields.Item("CURRENCY").Value
        oInvoicePost.Header("CURRENCY_USED").Value = oInvoiceRecord.Fields.Item("CURRENCY_USED").Value

        ' Link Items to Header
        oInvoiceItem_Read = oInvoiceRecord.Link

        ' Move to the First Record
        oInvoiceItem_Read.MoveFirst()

        Do

            ' Add the existing items to the invoice
            oInvoiceItem_Write = oInvoicePost.Items.Add

            ' Populate the Fields, copying the data from the existing records
            oInvoiceItem_Write.Fields.Item("STOCK_CODE").Value = CStr(oInvoiceItem_Read.Fields.Item("STOCK_CODE").Value)
            oInvoiceItem_Write.Fields.Item("DESCRIPTION").Value = CStr(oInvoiceItem_Read.Fields.Item("DESCRIPTION").Value)
            oInvoiceItem_Write.Fields.Item("NOMINAL_CODE").Value = CStr(oInvoiceItem_Read.Fields.Item("NOMINAL_CODE").Value)
            oInvoiceItem_Write.Fields.Item("TAX_CODE").Value = CShort(oInvoiceItem_Read.Fields.Item("TAX_CODE").Value)
            oInvoiceItem_Write.Fields.Item("QTY_ORDER").Value = CDbl(oInvoiceItem_Read.Fields.Item("QTY_ORDER").Value)
            oInvoiceItem_Write.Fields.Item("UNIT_PRICE").Value = CDbl(oInvoiceItem_Read.Fields.Item("UNIT_PRICE").Value)
            oInvoiceItem_Write.Fields.Item("NET_AMOUNT").Value = CDbl(oInvoiceItem_Read.Fields.Item("NET_AMOUNT").Value)
            oInvoiceItem_Write.Fields.Item("TAX_AMOUNT").Value = CDbl(oInvoiceItem_Read.Fields.Item("TAX_AMOUNT").Value)
            oInvoiceItem_Write.Fields.Item("COMMENT_1").Value = CStr(oInvoiceItem_Read.Fields.Item("COMMENT_1").Value)
            oInvoiceItem_Write.Fields.Item("COMMENT_2").Value = CStr(oInvoiceItem_Read.Fields.Item("COMMENT_2").Value)
            oInvoiceItem_Write.Fields.Item("UNIT_OF_SALE").Value = CStr(oInvoiceItem_Read.Fields.Item("UNIT_OF_SALE").Value)
            oInvoiceItem_Write.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(oInvoiceItem_Read.Fields.Item("FULL_NET_AMOUNT").Value)
            oInvoiceItem_Write.Fields.Item("TAX_RATE").Value = CDbl(oInvoiceItem_Read.Fields.Item("TAX_RATE").Value)
            oInvoiceItem_Write.Fields.Item("TAX_CODE").Value = CInt(oInvoiceItem_Read.Fields.Item("TAX_CODE").Value)
            'We now need to ensure that the TAX_FLAG is set the same as the item being read otherwise it will be re calculated
            oInvoiceItem_Write.Fields.Item("TAX_FLAG").Value = CInt(oInvoiceItem_Read.Fields.Item("TAX_FLAG").Value)
            ' Destroy the oInvoiceItem_Write object
            oInvoiceItem_Write = Nothing

        Loop Until oInvoiceItem_Read.MoveNext = False

        ' Write a new item
        oStockRecord.MoveLast()
        oInvoiceItem_Write = oInvoicePost.Items.Add

        ' Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
        ' regardless of the Tax_Flag being set to 1***
        oInvoiceItem_Write.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
        oInvoiceItem_Write.Fields.Item("DESCRIPTION").Value = CStr(oStockRecord.Fields.Item("DESCRIPTION").Value)
        oInvoiceItem_Write.Fields.Item("NOMINAL_CODE").Value = CStr(oStockRecord.Fields.Item("NOMINAL_CODE").Value)
        oInvoiceItem_Write.Fields.Item("TAX_CODE").Value = CShort(oStockRecord.Fields.Item("TAX_CODE").Value)
        oInvoiceItem_Write.Fields.Item("QTY_ORDER").Value = CDbl(2)
        oInvoiceItem_Write.Fields.Item("UNIT_PRICE").Value = CDbl(50)
        oInvoiceItem_Write.Fields.Item("NET_AMOUNT").Value = CDbl(100)
        oInvoiceItem_Write.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(100)
        oInvoiceItem_Write.Fields.Item("COMMENT_1").Value = CStr("")
        oInvoiceItem_Write.Fields.Item("COMMENT_2").Value = CStr("")
        oInvoiceItem_Write.Fields.Item("UNIT_OF_SALE").Value = CStr("")
        oInvoiceItem_Write.Fields.Item("TAX_RATE").Value = CDbl(20)
        oInvoiceItem_Write.Fields.Item("TAX_CODE").Value = CInt(1)

        ' Destroy the oInvoiceItem_Write object
        oInvoiceItem_Write = Nothing

        ' Post the invoice
        If oInvoicePost.Update Then

            MsgBox("Invoice Updated Successfully", MsgBoxStyle.OkOnly, "SDO Examples")

        Else

            MsgBox("Invoice Not Updated", MsgBoxStyle.OkOnly, "SDO Examples")

        End If

        ' Disconnect
        oWS.Disconnect()

    End If

End If

' Destroy the Objects
oInvoiceRecord = Nothing
oInvoiceItem_Read = Nothing
oInvoiceItem_Write = Nothing
oInvoicePost = Nothing
oStockRecord = Nothing
oWS = Nothing
oSDO = Nothing

Exit Sub
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.InvoiceRecord oInvoiceRecord;
SageDataObject300.InvoiceItem oInvoiceItem_Read;
SageDataObject300.InvoiceItem oInvoiceItem_Write;
SageDataObject300.InvoicePost oInvoicePost;
SageDataObject300.StockRecord oStockRecord;
String szDataPath;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails
try
{
    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

    //Instantiate Objects
    oInvoiceRecord = (SageDataObject300.InvoiceRecord)oWS.CreateObject("InvoiceRecord");
    oInvoicePost = (SageDataObject300.InvoicePost)oWS.CreateObject("InvoicePost");
    oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");

    //Read an existing invoice
    oInvoiceRecord.MoveLast();

    //Select the type of the invoice to be posted
    //Note: for the purpose of this example, we assume the invoice to be a product invoice.
    oInvoicePost.Type = (SageDataObject300.InvoiceType)SageDataObject300.LedgerType.sdoLedgerInvoice;

    //Populate the invoice header, copying fields from oInvoiceRecord to oInvoicePost
    SDOHelper.Write(oInvoicePost.Header, "INVOICE_NUMBER",
      (Int32)SDOHelper.Read(oInvoiceRecord, "INVOICE_NUMBER"));
    SDOHelper.Write(oInvoicePost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oInvoiceRecord, "ACCOUNT_REF"));
    SDOHelper.Write(oInvoicePost.Header, "NAME", (String)SDOHelper.Read(oInvoiceRecord, "NAME"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_1", (String)SDOHelper.Read(oInvoiceRecord, "ADDRESS_1"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_2", (String)SDOHelper.Read(oInvoiceRecord, "ADDRESS_2"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_3", (String)SDOHelper.Read(oInvoiceRecord, "ADDRESS_3"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_4", (String)SDOHelper.Read(oInvoiceRecord, "ADDRESS_4"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_5", (String)SDOHelper.Read(oInvoiceRecord, "ADDRESS_5"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_1",
      (String)SDOHelper.Read(oInvoiceRecord, "DEL_ADDRESS_1"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_2",
      (String)SDOHelper.Read(oInvoiceRecord, "DEL_ADDRESS_2"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_3",
      (String)SDOHelper.Read(oInvoiceRecord, "DEL_ADDRESS_3"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_4",
      (String)SDOHelper.Read(oInvoiceRecord, "DEL_ADDRESS_4"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_5",
      (String)SDOHelper.Read(oInvoiceRecord, "DEL_ADDRESS_5"));
    SDOHelper.Write(oInvoicePost.Header, "CUST_TEL_NUMBER",
      (String)SDOHelper.Read(oInvoiceRecord, "CUST_TEL_NUMBER"));
    SDOHelper.Write(oInvoicePost.Header, "CONTACT_NAME", (String)SDOHelper.Read(oInvoiceRecord, "CONTACT_NAME"));
    SDOHelper.Write(oInvoicePost.Header, "GLOBAL_TAX_CODE",
      (Int16)SDOHelper.Read(oInvoiceRecord, "GLOBAL_TAX_CODE"));
    SDOHelper.Write(oInvoicePost.Header, "INVOICE_DATE", (DateTime)SDOHelper.Read(oInvoiceRecord, "INVOICE_DATE"));
    SDOHelper.Write(oInvoicePost.Header, "NOTES_1", (String)SDOHelper.Read(oInvoiceRecord, "NOTES_1"));
    SDOHelper.Write(oInvoicePost.Header, "NOTES_2", (String)SDOHelper.Read(oInvoiceRecord, "NOTES_2"));
    SDOHelper.Write(oInvoicePost.Header, "NOTES_3", (String)SDOHelper.Read(oInvoiceRecord, "NOTES_3"));
    SDOHelper.Write(oInvoicePost.Header, "TAKEN_BY", (String)SDOHelper.Read(oInvoiceRecord, "TAKEN_BY"));
    SDOHelper.Write(oInvoicePost.Header, "ORDER_NUMBER", (String)SDOHelper.Read(oInvoiceRecord, "ORDER_NUMBER"));
    SDOHelper.Write(oInvoicePost.Header, "CUST_ORDER_NUMBER",
      (String)SDOHelper.Read(oInvoiceRecord, "CUST_ORDER_NUMBER"));
    SDOHelper.Write(oInvoicePost.Header, "PAYMENT_REF", (String)SDOHelper.Read(oInvoiceRecord, "PAYMENT_REF"));
    SDOHelper.Write(oInvoicePost.Header, "GLOBAL_NOM_CODE",
      (String)SDOHelper.Read(oInvoiceRecord, "GLOBAL_NOM_CODE"));
    SDOHelper.Write(oInvoicePost.Header, "GLOBAL_DETAILS",
      (String)SDOHelper.Read(oInvoiceRecord, "GLOBAL_DETAILS"));
    SDOHelper.Write(oInvoicePost.Header, "FOREIGN_RATE", (Double)SDOHelper.Read(oInvoiceRecord, "FOREIGN_RATE"));
    SDOHelper.Write(oInvoicePost.Header, "CURRENCY", SDOHelper.Read(oInvoiceRecord, "CURRENCY"));
    SDOHelper.Write(oInvoicePost.Header, "CURRENCY_USED",
    SDOHelper.Read(oInvoiceRecord, "CURRENCY_USED"));

    //Link items to the header
    oInvoiceItem_Read = (SageDataObject300.InvoiceItem)oInvoiceRecord.Link;

    //Move to the first record
    oInvoiceItem_Read.MoveFirst();

    do
    {
        //Add the existing items to the invoice
        oInvoiceItem_Write = (SageDataObject300.InvoiceItem)SDOHelper.Add(oInvoicePost.Items);

        //Populate the item fields, copying data from the existing records
        SDOHelper.Write(oInvoiceItem_Write, "STOCK_CODE",
          (String)SDOHelper.Read(oInvoiceItem_Read, "STOCK_CODE"));
        SDOHelper.Write(oInvoiceItem_Write, "DESCRIPTION",
          (String)SDOHelper.Read(oInvoiceItem_Read, "DESCRIPTION"));
        SDOHelper.Write(oInvoiceItem_Write, "NOMINAL_CODE",
          (String)SDOHelper.Read(oInvoiceItem_Read, "NOMINAL_CODE"));
        SDOHelper.Write(oInvoiceItem_Write, "TAX_CODE", (Int16)SDOHelper.Read(oInvoiceItem_Read, "TAX_CODE"));
        SDOHelper.Write(oInvoiceItem_Write, "QTY_ORDER", (Double)SDOHelper.Read(oInvoiceItem_Read, "QTY_ORDER"));
        SDOHelper.Write(oInvoiceItem_Write, "UNIT_PRICE", (Double)SDOHelper.Read(oInvoiceItem_Read, "UNIT_PRICE"));
        SDOHelper.Write(oInvoiceItem_Write, "NET_AMOUNT", (Double)SDOHelper.Read(oInvoiceItem_Read, "NET_AMOUNT"));
        SDOHelper.Write(oInvoiceItem_Write, "TAX_AMOUNT", (Double)SDOHelper.Read(oInvoiceItem_Read, "TAX_AMOUNT"));
        SDOHelper.Write(oInvoiceItem_Write, "COMMENT_1", (String)SDOHelper.Read(oInvoiceItem_Read, "COMMENT_1"));
        SDOHelper.Write(oInvoiceItem_Write, "COMMENT_2", (String)SDOHelper.Read(oInvoiceItem_Read, "COMMENT_2"));
        SDOHelper.Write(oInvoiceItem_Write, "UNIT_OF_SALE",
          (String)SDOHelper.Read(oInvoiceItem_Read, "UNIT_OF_SALE"));
        SDOHelper.Write(oInvoiceItem_Write, "FULL_NET_AMOUNT",
          (Double)SDOHelper.Read(oInvoiceItem_Read, "FULL_NET_AMOUNT"));
        SDOHelper.Write(oInvoiceItem_Write, "TAX_RATE", (Double)SDOHelper.Read(oInvoiceItem_Read, "TAX_RATE"));
        SDOHelper.Write(oInvoiceItem_Write, "TAX_CODE", (Int16)SDOHelper.Read(oInvoiceItem_Read, "TAX_CODE"));
        //We now need to ensure that the TAX_FLAG is set the same as the item being read otherwise it will be recalculated
        SDOHelper.Write(oInvoiceItem_Write, "TAX_FLAG", SDOHelper.Read(oInvoiceItem_Read, "TAX_FLAG"));
    } while (oInvoiceItem_Read.MoveNext());

    //Write the new item line
    oStockRecord.MoveLast();
    oInvoiceItem_Write = (SageDataObject300.InvoiceItem)SDOHelper.Add(oInvoicePost.Items);

    //Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
    //regardless of the Tax_Flag being set to 1***
    SDOHelper.Write(oInvoiceItem_Write, "STOCK_CODE", (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));
    SDOHelper.Write(oInvoiceItem_Write, "DESCRIPTION", (String)SDOHelper.Read(oStockRecord, "DESCRIPTION"));
    SDOHelper.Write(oInvoiceItem_Write, "NOMINAL_CODE", (String)SDOHelper.Read(oStockRecord, "NOMINAL_CODE"));
    SDOHelper.Write(oInvoiceItem_Write, "TAX_CODE", (Int16)SDOHelper.Read(oStockRecord, "TAX_CODE"));
    SDOHelper.Write(oInvoiceItem_Write, "QTY_ORDER", (Double)2);
    SDOHelper.Write(oInvoiceItem_Write, "UNIT_PRICE", (Double)50);
    SDOHelper.Write(oInvoiceItem_Write, "NET_AMOUNT", (Double)100);
    SDOHelper.Write(oInvoiceItem_Write, "FULL_NET_AMOUNT", (Double)100);
    SDOHelper.Write(oInvoiceItem_Write, "COMMENT_1", (String)"Comment 1");
    SDOHelper.Write(oInvoiceItem_Write, "COMMENT_2", (String)"Comment 2");
    SDOHelper.Write(oInvoiceItem_Write, "UNIT_OF_SALE", (String)"");
    SDOHelper.Write(oInvoiceItem_Write, "TAX_RATE", (Double)20);
    SDOHelper.Write(oInvoiceItem_Write, "TAX_CODE", (Int16)1);

    //Post the invoice
    if (oInvoicePost.Update())
    {
        MessageBox.Show("Invoice Updated Successfully");
    }
    else
    {
        MessageBox.Show("Invoice Not Updated");
    }

    //Disconnect
    oWS.Disconnect();
}
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}


Sage 50 Accounts - Example - Posting a Product Invoice

Example - Posting a Product Invoice

The example code below demonstrates how to post a Product Invoice.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
                                ' Declare Objects
Dim oSDO  As
                              SageDataObject300.SDOEngine
Dim oWS  As
                              SageDataObject300.WorkSpace
Dim oInvoicePost  As
                              SageDataObject300.InvoicePost
Dim oInvoiceItem  As
                              SageDataObject300.InvoiceItem
Dim oSalesRecord  As
                              SageDataObject300.SalesRecord
Dim oStockRecord  As
                              SageDataObject300.StockRecord

' Declare Variables
Dim szDataPath  As String
Dim iCtr  As Short

' Create the SDO Engine Object
oSDO =  New   SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' SelectCompany.  The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> ""  Then

' Connect to Data Files - Will throw
                              an exception if it fails
If oWS.Connect(szDataPath, "", "", "Example")
                               Then

' Create an instance of the Objects
oSalesRecord = oWS.CreateObject("SalesRecord")
oInvoicePost = oWS.CreateObject("InvoicePost")
oStockRecord = oWS.CreateObject("StockRecord")

' Set the type of invoice for the next available number
oInvoicePost.Type = SageDataObject300.LedgerType.sdoLedgerInvoice

' Read the First Customer & populate Invoice Fields
oSalesRecord.MoveFirst()

oInvoicePost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
oInvoicePost.Header("NAME").Value = CStr(oSalesRecord.Fields.Item("NAME").Value)
oInvoicePost.Header("ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_1").Value)
oInvoicePost.Header("ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_2").Value)
oInvoicePost.Header("ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_3").Value)
oInvoicePost.Header("ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_4").Value)
oInvoicePost.Header("ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_5").Value)
oInvoicePost.Header("DEL_ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_1").Value)
oInvoicePost.Header("DEL_ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_2").Value)
oInvoicePost.Header("DEL_ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_3").Value)
oInvoicePost.Header("DEL_ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_4").Value)
oInvoicePost.Header("DEL_ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_5").Value)
oInvoicePost.Header("CUST_TEL_NUMBER").Value = CStr(oSalesRecord.Fields.Item("TELEPHONE").Value)
oInvoicePost.Header("CONTACT_NAME").Value = CStr(oSalesRecord.Fields.Item("CONTACT_NAME").Value)
oInvoicePost.Header("GLOBAL_TAX_CODE").Value = CShort(oSalesRecord.Fields.Item("DEF_TAX_CODE").Value)

' Populate other Invoice Header Information
oInvoicePost.Header("INVOICE_DATE").Value = CDate(Today)
oInvoicePost.Header("NOTES_1").Value = CStr("")
oInvoicePost.Header("NOTES_2").Value = CStr("")
oInvoicePost.Header("NOTES_3").Value = CStr("")
oInvoicePost.Header("TAKEN_BY").Value = CStr("Mark Steel")
oInvoicePost.Header("ORDER_NUMBER").Value = CStr("")
oInvoicePost.Header("CUST_ORDER_NUMBER").Value =
                              CStr("")
oInvoicePost.Header("PAYMENT_REF").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.
oInvoicePost.Header("GLOBAL_NOM_CODE").Value = CStr("")
oInvoicePost.Header("GLOBAL_DETAILS").Value = CStr("")
oInvoicePost.Header("INVOICE_TYPE_CODE").Value =
                              CByte(SageDataObject300.InvoiceType.sdoProductInvoice)

' Create an Invoice Item
oInvoiceItem = oInvoicePost.Items.Add()

' Read the First Stock Code & populate fields from Stock Code
oStockRecord.MoveFirst()
oInvoiceItem.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
oInvoiceItem.Fields.Item("DESCRIPTION").Value =
                              CStr(oStockRecord.Fields.Item("DESCRIPTION").Value)
oInvoiceItem.Fields.Item("NOMINAL_CODE").Value =
                              CStr(oStockRecord.Fields.Item("NOMINAL_CODE").Value)
oInvoiceItem.Fields.Item("TAX_CODE").Value = CInt(oStockRecord.Fields.Item("TAX_CODE").Value)

' Populate other fields required for Invoice Item
oInvoiceItem.Fields.Item("QTY_ORDER").Value = CDbl(2)
oInvoiceItem.Fields.Item("UNIT_PRICE").Value = CDbl(50)
oInvoiceItem.Fields.Item("NET_AMOUNT").Value = CDbl(100)
oInvoiceItem.Fields.Item("TAX_AMOUNT").Value = CDbl(20)
oInvoiceItem.Fields.Item("COMMENT_1").Value = CStr("")
oInvoiceItem.Fields.Item("COMMENT_2").Value = CStr("")
oInvoiceItem.Fields.Item("UNIT_OF_SALE").Value =
                              CStr("")
oInvoiceItem.Fields.Item("FULL_NET_AMOUNT").Value =
                              CDbl(100)
oInvoiceItem.Fields.Item("TAX_RATE").Value = CDbl(20)

' Create Another Invoice Item
oInvoiceItem = oInvoicePost.Items.Add()

' Read the Next Stock Code & populate fields from Stock Code
oStockRecord.MoveNext()
oInvoiceItem.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
oInvoiceItem.Fields.Item("DESCRIPTION").Value = CStr(oStockRecord.Fields.Item("DESCRIPTION").Value)
oInvoiceItem.Fields.Item("NOMINAL_CODE").Value = CStr(oStockRecord.Fields.Item("NOMINAL_CODE").Value)
oInvoiceItem.Fields.Item("TAX_CODE").Value = CShort(oStockRecord.Fields.Item("TAX_CODE").Value)

' Populate other fields required for Invoice Item
' From 2013 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 a NVD is set the item line values will be recalculated
' regardless of the Tax_Flag being set to 1***
oInvoiceItem.Fields.Item("QTY_ORDER").Value =
                              CDbl(1)
oInvoiceItem.Fields.Item("UNIT_PRICE").Value = CDbl(200)
oInvoiceItem.Fields.Item("NET_AMOUNT").Value = CDbl(200)
oInvoiceItem.Fields.Item("COMMENT_1").Value = CStr("")
oInvoiceItem.Fields.Item("COMMENT_2").Value = CStr("")
oInvoiceItem.Fields.Item("UNIT_OF_SALE").Value =
                              CStr("")
oInvoiceItem.Fields.Item("FULL_NET_AMOUNT").Value =
                              CDbl(200)
oInvoiceItem.Fields.Item("TAX_RATE").Value = CDbl(20)

' Update the Invoice
If oInvoicePost.Update
                               Then

MsgBox("Invoice Posted Successfully", MsgBoxStyle.OKOnly, "SDO Examples")

Else

MsgBox("Failed to create Invoice", MsgBoxStyle.OKOnly, "SDO Examples")

End If

' Disconnect
oWS.Disconnect()

End If

End If

' Destroy Objects
oInvoicePost =  Nothing
oInvoiceItem =  Nothing
oSalesRecord =  Nothing
oStockRecord =  Nothing
oWS =  Nothing
oSDO =  Nothing

Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.InvoicePost oInvoicePost;

SageDataObject300.InvoiceItem oInvoiceItem;

SageDataObject300.SalesRecord oSalesRecord;

SageDataObject300.StockRecord oStockRecord;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "Example");

  //Instantiate objects

  oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");

  oInvoicePost = (SageDataObject300.InvoicePost)oWS.CreateObject("InvoicePost");

  oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");

  //Set the invoice type

  oInvoicePost.Type = (SageDataObject300.InvoiceType)SageDataObject300.LedgerType.sdoLedgerInvoice;

  //Read the first customer record and use to populate the invoice fields

  oSalesRecord.MoveFirst();

  SDOHelper.Write(oInvoicePost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));

  SDOHelper.Write(oInvoicePost.Header, "NAME", (String)SDOHelper.Read(oSalesRecord, "NAME"));

  SDOHelper.Write(oInvoicePost.Header, "ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_1"));

  SDOHelper.Write(oInvoicePost.Header, "ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_2"));

  SDOHelper.Write(oInvoicePost.Header, "ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_3"));

  SDOHelper.Write(oInvoicePost.Header, "ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_4"));

  SDOHelper.Write(oInvoicePost.Header, "ADDRESS_5", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_5"));

  SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_1"));

  SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_2"));

  SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_3"));

  SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_4"));

  SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_5", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_5"));

  SDOHelper.Write(oInvoicePost.Header, "CUST_TEL_NUMBER", (String)SDOHelper.Read(oSalesRecord, "TELEPHONE"));

  SDOHelper.Write(oInvoicePost.Header, "CONTACT_NAME", (String)SDOHelper.Read(oSalesRecord, "CONTACT_NAME"));

  SDOHelper.Write(oInvoicePost.Header, "GLOBAL_TAX_CODE", (Int16)SDOHelper.Read(oSalesRecord, "DEF_TAX_CODE"));

  //Populate other invoice header information

  SDOHelper.Write(oInvoicePost.Header, "INVOICE_DATE", (DateTime)DateTime.Today);

  SDOHelper.Write(oInvoicePost.Header, "NOTES_1", (String)"Notes 1");

  SDOHelper.Write(oInvoicePost.Header, "NOTES_2", (String)"Notes 2");

  SDOHelper.Write(oInvoicePost.Header, "NOTES_3", (String)"Notes 3");

  SDOHelper.Write(oInvoicePost.Header, "TAKEN_BY", (String)"Chris Reed");

  SDOHelper.Write(oInvoicePost.Header, "ORDER_NUMBER", (String)"");

  SDOHelper.Write(oInvoicePost.Header, "CUST_ORDER_NUMBER", (String)"");

  SDOHelper.Write(oInvoicePost.Header, "PAYMENT_REF", (String)"");

// If anything is entered in the GLOBAL_NOM_CODE, all of the updated invoice�s splits will have this nominal code and
// also this willforce anything entered in the GLOBAL_DETAILS field into the all the splits details field.

  SDOHelper.Write(oInvoicePost.Header, "GLOBAL_NOM_CODE", (String)"");

  SDOHelper.Write(oInvoicePost.Header, "GLOBAL_DETAILS", (String)"");

  SDOHelper.Write(oInvoicePost.Header, "INVOICE_TYPE_CODE",

    (Byte)SageDataObject300.InvoiceType.sdoProductInvoice);

  //Create and invoice item

  //Need to invoke the Add method

  oInvoiceItem = (SageDataObject300.InvoiceItem)SDOHelper.Add(oInvoicePost.Items);

  //Read the First Stock Code & populate fields from Stock Code

  oStockRecord.MoveFirst();

  SDOHelper.Write(oInvoiceItem, "STOCK_CODE", (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));

  SDOHelper.Write(oInvoiceItem, "DESCRIPTION", (String)SDOHelper.Read(oStockRecord, "DESCRIPTION"));

  SDOHelper.Write(oInvoiceItem, "NOMINAL_CODE", (String)SDOHelper.Read(oStockRecord, "NOMINAL_CODE"));

  SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)SDOHelper.Read(oStockRecord, "TAX_CODE"));

  //Populate other invoice item fields

  SDOHelper.Write(oInvoiceItem, "QTY_ORDER", (Int32)1);

  SDOHelper.Write(oInvoiceItem, "UNIT_PRICE", (Int32)200);

  SDOHelper.Write(oInvoiceItem, "NET_AMOUNT", (Int32)200);

  SDOHelper.Write(oInvoiceItem, "TAX_AMOUNT", (Int32)40);

  SDOHelper.Write(oInvoiceItem, "COMMENT_1", (String)"Comment 1");

  SDOHelper.Write(oInvoiceItem, "COMMENT_2", (String)"Comment 2");

  SDOHelper.Write(oInvoiceItem, "UNIT_OF_SALE", (String)"");

  SDOHelper.Write(oInvoiceItem, "FULL_NET_AMOUNT", (Int32)200);

  SDOHelper.Write(oInvoiceItem, "TAX_RATE", (Int32)20);

  //Update the invoice

  if (oInvoicePost.Update())

  {

    MessageBox.Show("Invoice Posted Successfully", "C# SDO Examples");

  }

  else

  {

    MessageBox.Show("Failed to create Invoice", "C# SDO Examples");

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Posting a Product Invoice and Receipt

Example - Posting a Product Invoice and Receipt

The example code below demonstrates how to post a Product Invoice and receipt.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oInvoicePost As SageDataObject300.InvoicePost
Dim oInvoiceItem As SageDataObject300.InvoiceItem
Dim oSalesRecord As SageDataObject300.SalesRecord
Dim oStockRecord As SageDataObject300.StockRecord

' Declare Variables
Dim szDataPath As String
Dim iCtr As Short

' Error Handler
Try

    ' Create the SDO Engine Object
    oSDO = New SageDataObject300.SDOEngine

    ' Create the Workspace
    oWS = oSDO.Workspaces.Add("Example")

    ' SelectCompany.  The SelectCompany method takes the program install
    ' folder as a parameter
    szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

    ' A U.I. for company selection is presented to the user. If a company is selected,
    ' the path will be passed to the szDataPath variable.
    ' If not, or the Cancel button is selected, the variable will be left empty.
    If szDataPath <> "" Then

        ' Connect to Data Files - Will throw an exception if it fails
        If oWS.Connect(szDataPath, "", "", "Example") Then

            ' Create an instance of the Objects
            oSalesRecord = oWS.CreateObject("SalesRecord")
            oInvoicePost = oWS.CreateObject("InvoicePost")
            oStockRecord = oWS.CreateObject("StockRecord")

            ' Set the type of invoice for the next available number
            oInvoicePost.Type = SageDataObject300.LedgerType.sdoLedgerInvoice

            ' Read the First Customer & populate Invoice Fields
            oSalesRecord.MoveFirst()

            oInvoicePost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
            oInvoicePost.Header("NAME").Value = CStr(oSalesRecord.Fields.Item("NAME").Value)
            oInvoicePost.Header("ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_1").Value)
            oInvoicePost.Header("ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_2").Value)
            oInvoicePost.Header("ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_3").Value)
            oInvoicePost.Header("ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_4").Value)
            oInvoicePost.Header("ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_5").Value)
            oInvoicePost.Header("DEL_ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_1").Value)
            oInvoicePost.Header("DEL_ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_2").Value)
            oInvoicePost.Header("DEL_ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_3").Value)
            oInvoicePost.Header("DEL_ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_4").Value)
            oInvoicePost.Header("DEL_ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_5").Value)
            oInvoicePost.Header("CUST_TEL_NUMBER").Value = CStr(oSalesRecord.Fields.Item("TELEPHONE").Value)
            oInvoicePost.Header("CONTACT_NAME").Value = CStr(oSalesRecord.Fields.Item("CONTACT_NAME").Value)
            oInvoicePost.Header("GLOBAL_TAX_CODE").Value = CShort(oSalesRecord.Fields.Item("DEF_TAX_CODE").Value)

            ' Populate Receipt information
            oInvoicePost.Header("PAYMENT_REF").Value = CStr("Cheque No")
            oInvoicePost.Header("BANK_CODE").Value = CStr("1200")
            oInvoicePost.Header("PAYMENT_TYPE").Value = CByte(SageDataObject300.TransType.sdoSR)
            oInvoicePost.Header("AMOUNT_PREPAID").Value = CDbl(100)

            ' Populate other Invoice Header Information
            oInvoicePost.Header("INVOICE_DATE").Value = CDate(Today)
            oInvoicePost.Header("NOTES_1").Value = CStr("")
            oInvoicePost.Header("NOTES_2").Value = CStr("")
            oInvoicePost.Header("NOTES_3").Value = CStr("")
            oInvoicePost.Header("TAKEN_BY").Value = CStr("Mark Steel")
            oInvoicePost.Header("ORDER_NUMBER").Value = CStr("")
            oInvoicePost.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.
            oInvoicePost.Header("GLOBAL_NOM_CODE").Value = CStr("")
            oInvoicePost.Header("GLOBAL_DETAILS").Value = CStr("")
            oInvoicePost.Header("INVOICE_TYPE_CODE").Value = CByte(SageDataObject300.InvoiceType.sdoProductInvoice)

            ' Create an Invoice Item
            oInvoiceItem = oInvoicePost.Items.Add()

            ' Read the First Stock Code & populate fields from Stock Code
            oStockRecord.MoveFirst()
            oInvoiceItem.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
            oInvoiceItem.Fields.Item("DESCRIPTION").Value = CStr(oStockRecord.Fields.Item("DESCRIPTION").Value)
            oInvoiceItem.Fields.Item("NOMINAL_CODE").Value = CStr(oStockRecord.Fields.Item("NOMINAL_CODE").Value)
            oInvoiceItem.Fields.Item("TAX_CODE").Value = CInt(oStockRecord.Fields.Item("TAX_CODE").Value)

            ' Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
            ' regardless of the Tax_Flag being set to 1***
            oInvoiceItem.Fields.Item("QTY_ORDER").Value = CDbl(2)
            oInvoiceItem.Fields.Item("UNIT_PRICE").Value = CDbl(50)
            oInvoiceItem.Fields.Item("NET_AMOUNT").Value = CDbl(100)
            oInvoiceItem.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(100)

            oInvoiceItem.Fields.Item("COMMENT_1").Value = CStr("")
            oInvoiceItem.Fields.Item("COMMENT_2").Value = CStr("")
            oInvoiceItem.Fields.Item("UNIT_OF_SALE").Value = CStr("")
            oInvoiceItem.Fields.Item("TAX_RATE").Value = CDbl(20)
            oInvoiceItem.Fields.Item("TAX_CODE").Value = CInt(1)

            ' Create Another Invoice Item
            oInvoiceItem = oInvoicePost.Items.Add()

            ' Read the Next Stock Code & populate fields from Stock Code
            oStockRecord.MoveNext()
            oInvoiceItem.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
            oInvoiceItem.Fields.Item("DESCRIPTION").Value = CStr(oStockRecord.Fields.Item("DESCRIPTION").Value)
            oInvoiceItem.Fields.Item("NOMINAL_CODE").Value = CStr(oStockRecord.Fields.Item("NOMINAL_CODE").Value)
            oInvoiceItem.Fields.Item("TAX_CODE").Value = CShort(oStockRecord.Fields.Item("TAX_CODE").Value)

            ' Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
            ' regardless of the Tax_Flag being set to 1***
            oInvoiceItem.Fields.Item("QTY_ORDER").Value = CDbl(1)
            oInvoiceItem.Fields.Item("UNIT_PRICE").Value = CDbl(200)
            oInvoiceItem.Fields.Item("NET_AMOUNT").Value = CDbl(200)
            oInvoiceItem.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(200)

            oInvoiceItem.Fields.Item("COMMENT_1").Value = CStr("")
            oInvoiceItem.Fields.Item("COMMENT_2").Value = CStr("")
            oInvoiceItem.Fields.Item("UNIT_OF_SALE").Value = CStr("")
            oInvoiceItem.Fields.Item("TAX_RATE").Value = CDbl(20)
            oInvoiceItem.Fields.Item("TAX_CODE").Value = CInt(1)

            ' Update the Invoice
            If oInvoicePost.Update Then

                MessageBox.Show("Invoice Posted Successfully", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Information)

            Else

                MessageBox.Show("Failed to create Invoice", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

            End If

            ' Disconnect
            oWS.Disconnect()

        End If

    End If

    ' Error Handling Code
Catch ex As Exception

    MessageBox.Show("The SDO generated the following error: " & ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

Finally
    ' Destroy Objects
    If Not oInvoicePost Is Nothing Then
        oInvoicePost = Nothing
    End If

    If Not oStockRecord Is Nothing Then
        oStockRecord = Nothing
    End If

    If Not oInvoiceItem Is Nothing Then
        oInvoiceItem = Nothing
    End If

    If Not oSalesRecord Is Nothing Then
        oSalesRecord = Nothing
    End If

    If Not oWS Is Nothing Then
        oWS.Disconnect()
        oWS = Nothing
        oSDO = Nothing
    End If
End Try
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
String szDataPath;

    //Instantiate WorkSpace
    oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

    //Show select company dialog
    szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

    //Try a connection, will throw an exception if it fails
    try
    {
        //Leaving the username and password blank generates a login dialog
        oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");
    }
    catch (Exception ex)
    {
        MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
    }

    // Declare required objects
    SageDataObject300.InvoicePost oInvoicePost;
    SageDataObject300.InvoiceItem oInvoiceItem;
    SageDataObject300.SalesRecord oSalesRecord;
    SageDataObject300.StockRecord oStockRecord;

    try
    {
        // Instantiate objects
        oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");
        oInvoicePost = (SageDataObject300.InvoicePost)oWS.CreateObject("InvoicePost");
        oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");

        // Set the type of the invoice so that we can find the next available number
        oInvoicePost.Type = (SageDataObject300.InvoiceType)SageDataObject300.LedgerType.sdoLedgerInvoice;

        // Read the first customer and populate invoice header fields
        oSalesRecord.MoveFirst();

        SDOHelper.Write(oInvoicePost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));
        SDOHelper.Write(oInvoicePost.Header, "NAME", (String)SDOHelper.Read(oSalesRecord, "NAME"));
        SDOHelper.Write(oInvoicePost.Header, "ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_1"));
        SDOHelper.Write(oInvoicePost.Header, "ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_2"));
        SDOHelper.Write(oInvoicePost.Header, "ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_3"));
        SDOHelper.Write(oInvoicePost.Header, "ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_4"));
        SDOHelper.Write(oInvoicePost.Header, "ADDRESS_5", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_5"));
        SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_1"));
        SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_2"));
        SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_3"));
        SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_4"));
        SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_5", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_5"));
        SDOHelper.Write(oInvoicePost.Header, "CUST_TEL_NUMBER", (String)SDOHelper.Read(oSalesRecord, "TELEPHONE"));
        SDOHelper.Write(oInvoicePost.Header, "CONTACT_NAME", (String)SDOHelper.Read(oSalesRecord, "CONTACT_NAME"));
        SDOHelper.Write(oInvoicePost.Header, "GLOBAL_TAX_CODE", (Int16)SDOHelper.Read(oSalesRecord, "DEF_TAX_CODE"));

        // Populate the Receipt information
        SDOHelper.Write(oInvoicePost.Header, "PAYMENT_REF", (String)"Cheque No");
        SDOHelper.Write(oInvoicePost.Header, "BANK_CODE", (String)"1200");
        SDOHelper.Write(oInvoicePost.Header, "PAYMENT_TYPE", (Byte)SageDataObject300.TransType.sdoSR);
        SDOHelper.Write(oInvoicePost.Header, "AMOUNT_PREPAID", (Double)100.00);

        // Populate other header information
        SDOHelper.Write(oInvoicePost.Header, "INVOICE_DATE", (DateTime)DateTime.Today);
        SDOHelper.Write(oInvoicePost.Header, "NOTES_1", (String)"Notes 1");
        SDOHelper.Write(oInvoicePost.Header, "NOTES_2", (String)"Notes 2");
        SDOHelper.Write(oInvoicePost.Header, "NOTES_3", (String)"Notes 3");
        SDOHelper.Write(oInvoicePost.Header, "TAKEN_BY", (String)"SDO");
        SDOHelper.Write(oInvoicePost.Header, "ORDER_NUMBER", (String)"");
        SDOHelper.Write(oInvoicePost.Header, "CUST_ORDER_NUMBER", (String)"");
        SDOHelper.Write(oInvoicePost.Header, "PAYMENT_REF", (String)"");
        // If anything is entered in the GLOBAL_NOM_CODE, all of the updated invoice’s splits will have this
        // nominal code and also this willforce anything entered in the GLOBAL_DETAILS field into the all
        // the splits details field.
        SDOHelper.Write(oInvoicePost.Header, "GLOBAL_NOM_CODE", (String)"");
        SDOHelper.Write(oInvoicePost.Header, "GLOBAL_DETAILS", (String)"");
        SDOHelper.Write(oInvoicePost.Header, "INVOICE_TYPE_CODE", (Byte)SageDataObject300.InvoiceType.sdoProductInvoice);
        SDOHelper.Write(oInvoicePost.Header, "ITEMS_NET", (Double)500);
        SDOHelper.Write(oInvoicePost.Header, "ITEMS_TAX", (Double)52.5);

        // Create an invoice item
        oInvoiceItem = (SageDataObject300.InvoiceItem)SDOHelper.Add(oInvoicePost.Items);

        // Read the first stock code & populate the fields
        oStockRecord.MoveFirst();

        SDOHelper.Write(oInvoiceItem, "STOCK_CODE", (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));
        SDOHelper.Write(oInvoiceItem, "DESCRIPTION", (String)SDOHelper.Read(oStockRecord, "DESCRIPTION"));
        SDOHelper.Write(oInvoiceItem, "NOMINAL_CODE", (String)SDOHelper.Read(oStockRecord, "NOMINAL_CODE"));
        SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)SDOHelper.Read(oStockRecord, "TAX_CODE"));

        //Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
        //regardless of the Tax_Flag being set to 1***
        SDOHelper.Write(oInvoiceItem, "QTY_ORDER", (Double)2);
        SDOHelper.Write(oInvoiceItem, "UNIT_PRICE", (Double)50);
        SDOHelper.Write(oInvoiceItem, "NET_AMOUNT", (Double)100);
        SDOHelper.Write(oInvoiceItem, "FULL_NET_AMOUNT", (Double)100);
        SDOHelper.Write(oInvoiceItem, "COMMENT_1", (String)"Comment 1");
        SDOHelper.Write(oInvoiceItem, "COMMENT_2", (String)"Comment 2");
        SDOHelper.Write(oInvoiceItem, "UNIT_OF_SALE", (String)"");
        SDOHelper.Write(oInvoiceItem, "TAX_RATE", (Double)20);
        SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)1);

        // Create another invoice item
        oInvoiceItem = (SageDataObject300.InvoiceItem)SDOHelper.Add(oInvoicePost.Items);

        // Read the next stock code & populate the fields
        oStockRecord.MoveNext();

        SDOHelper.Write(oInvoiceItem, "STOCK_CODE", (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));
        SDOHelper.Write(oInvoiceItem, "DESCRIPTION", (String)SDOHelper.Read(oStockRecord, "DESCRIPTION"));
        SDOHelper.Write(oInvoiceItem, "NOMINAL_CODE", (String)SDOHelper.Read(oStockRecord, "NOMINAL_CODE"));
        SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)SDOHelper.Read(oStockRecord, "TAX_CODE"));

        //Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
        //regardless of the Tax_Flag being set to 1***
        SDOHelper.Write(oInvoiceItem, "QTY_ORDER", (Double)1);
        SDOHelper.Write(oInvoiceItem, "UNIT_PRICE", (Double)200);
        SDOHelper.Write(oInvoiceItem, "NET_AMOUNT", (Double)200);
        SDOHelper.Write(oInvoiceItem, "FULL_NET_AMOUNT", (Double)200);
        SDOHelper.Write(oInvoiceItem, "COMMENT_1", (String)"Comment 1");
        SDOHelper.Write(oInvoiceItem, "COMMENT_2", (String)"Comment 2");
        SDOHelper.Write(oInvoiceItem, "UNIT_OF_SALE", (String)"");
        SDOHelper.Write(oInvoiceItem, "TAX_RATE", (Double)20);
        SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)1);

        // Update the Invoice
        if (oInvoicePost.Update())
        {
            MessageBox.Show("Invoice Posted Successfully");
        }
        else
        {
            MessageBox.Show("Invoice Post Unsuccessful");
        }

        // Disconnect
        oWS.Disconnect();
    }
    catch (Exception ex)
    {
        // Show the exception error message
        MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }


Sage 50 Accounts - Example - Posting a Product Invoice

Example - Posting a Product Invoice with Negative Item Line

The example code below demonstrates how to post a Product Invoice with a Negative item line.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
    ' Declare Objects
    Dim oSDO As SageDataObject300.SDOEngine
    Dim oWS As SageDataObject300.WorkSpace
    Dim oInvoicePost As SageDataObject300.InvoicePost
    Dim oInvoiceItem As SageDataObject300.InvoiceItem
    Dim oSalesRecord As SageDataObject300.SalesRecord
    Dim oStockRecord As SageDataObject300.StockRecord

    ' Declare Variables
    Dim szDataPath As String
    Dim iCtr As Short

    ' Create the SDO Engine Object
    oSDO = New SageDataObject300.SDOEngine

    ' Create the Workspace
    oWS = oSDO.Workspaces.Add("Example")

    ' SelectCompany.  The SelectCompany method takes the program install
    ' folder as a parameter
    szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

    ' A U.I. for company selection is presented to the user. If a company is selected,
    ' the path will be passed to the szDataPath variable.
    ' If not, or the Cancel button is selected, the variable will be left empty.
    If szDataPath <> "" Then

        ' Connect to Data Files - Will throw an exception if it fails
        If oWS.Connect(szDataPath, "", "", "Example") Then

            ' Create an instance of the Objects
            oSalesRecord = oWS.CreateObject("SalesRecord")
            oInvoicePost = oWS.CreateObject("InvoicePost")
            oStockRecord = oWS.CreateObject("StockRecord")

            ' Set the type of invoice for the next available number
            oInvoicePost.Type = SageDataObject300.LedgerType.sdoLedgerInvoice

            ' Read the First Customer & populate Invoice Fields
            oSalesRecord.MoveFirst()

            oInvoicePost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
            oInvoicePost.Header("NAME").Value = CStr(oSalesRecord.Fields.Item("NAME").Value)
            oInvoicePost.Header("ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_1").Value)
            oInvoicePost.Header("ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_2").Value)
            oInvoicePost.Header("ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_3").Value)
            oInvoicePost.Header("ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_4").Value)
            oInvoicePost.Header("ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_5").Value)
            oInvoicePost.Header("DEL_ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_1").Value)
            oInvoicePost.Header("DEL_ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_2").Value)
            oInvoicePost.Header("DEL_ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_3").Value)
            oInvoicePost.Header("DEL_ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_4").Value)
            oInvoicePost.Header("DEL_ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_5").Value)
            oInvoicePost.Header("CUST_TEL_NUMBER").Value = CStr(oSalesRecord.Fields.Item("TELEPHONE").Value)
            oInvoicePost.Header("CONTACT_NAME").Value = CStr(oSalesRecord.Fields.Item("CONTACT_NAME").Value)
            oInvoicePost.Header("GLOBAL_TAX_CODE").Value = CShort(oSalesRecord.Fields.Item("DEF_TAX_CODE").Value)

            ' Populate other Invoice Header Information
            oInvoicePost.Header("INVOICE_DATE").Value = CDate(Today)
            oInvoicePost.Header("NOTES_1").Value = CStr("")
            oInvoicePost.Header("NOTES_2").Value = CStr("")
            oInvoicePost.Header("NOTES_3").Value = CStr("")
            oInvoicePost.Header("TAKEN_BY").Value = CStr("Mark Steel")
            oInvoicePost.Header("ORDER_NUMBER").Value = CStr("")
            oInvoicePost.Header("CUST_ORDER_NUMBER").Value = CStr("")
            oInvoicePost.Header("PAYMENT_REF").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.
            oInvoicePost.Header("GLOBAL_NOM_CODE").Value = CStr("")
            oInvoicePost.Header("GLOBAL_DETAILS").Value = CStr("")
            oInvoicePost.Header("INVOICE_TYPE_CODE").Value = CByte(SageDataObject300.InvoiceType.sdoProductInvoice)

            ' Create an Invoice Item
            oInvoiceItem = oInvoicePost.Items.Add()

            ' Read the First Stock Code & populate fields from Stock Code
            oStockRecord.MoveFirst()
            oInvoiceItem.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
            oInvoiceItem.Fields.Item("DESCRIPTION").Value = CStr(oStockRecord.Fields.Item("DESCRIPTION").Value)
            oInvoiceItem.Fields.Item("NOMINAL_CODE").Value = CStr(oStockRecord.Fields.Item("NOMINAL_CODE").Value)
            oInvoiceItem.Fields.Item("TAX_CODE").Value = CInt(oStockRecord.Fields.Item("TAX_CODE").Value)

            ' Populate other fields required for Invoice Item
            oInvoiceItem.Fields.Item("QTY_ORDER").Value = CDbl(2)
            oInvoiceItem.Fields.Item("UNIT_PRICE").Value = CDbl(50)
            oInvoiceItem.Fields.Item("NET_AMOUNT").Value = CDbl(100)
            oInvoiceItem.Fields.Item("TAX_AMOUNT").Value = CDbl(20)
            oInvoiceItem.Fields.Item("COMMENT_1").Value = CStr("")
            oInvoiceItem.Fields.Item("COMMENT_2").Value = CStr("")
            oInvoiceItem.Fields.Item("UNIT_OF_SALE").Value = CStr("")
            oInvoiceItem.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(100)
            oInvoiceItem.Fields.Item("TAX_RATE").Value = CDbl(20)

            ' Create Another Invoice Item for the Negative Line
            oInvoiceItem = oInvoicePost.Items.Add()

            ' Use a Special product code

            oInvoiceItem.Fields.Item("STOCK_CODE").Value = CStr("S1")
            oInvoiceItem.Fields.Item("DESCRIPTION").Value = CStr("Negative Line")
            oInvoiceItem.Fields.Item("NOMINAL_CODE").Value = CStr(oSalesRecord.Fields.Item("DEF_NOM_CODE").Value)
            oInvoiceItem.Fields.Item("TAX_CODE").Value = CShort(oSalesRecord.Fields.Item("DEF_TAX_CODE").Value)

            ' Populate other fields required for Invoice Item
            ' From 2013 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 a NVD is set the item line values will be recalculated
            ' regardless of the Tax_Flag being set to 1***
            oInvoiceItem.Fields.Item("QTY_ORDER").Value = CDbl(1)
            oInvoiceItem.Fields.Item("UNIT_PRICE").Value = CDbl(20)
            oInvoiceItem.Fields.Item("NET_AMOUNT").Value = CDbl(20)
            oInvoiceItem.Fields.Item("COMMENT_1").Value = CStr("")
            oInvoiceItem.Fields.Item("COMMENT_2").Value = CStr("")
            oInvoiceItem.Fields.Item("UNIT_OF_SALE").Value = CStr("")
            oInvoiceItem.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(20)
            oInvoiceItem.Fields.Item("TAX_RATE").Value = CDbl(20)

            ' Specify the line is negative
            oInvoiceItem.Fields.Item("IS_NEGATIVE_LINE").Value = CDbl(1)

            ' Update the Invoice
            If oInvoicePost.Update Then

                MsgBox("Invoice Posted Successfully", MsgBoxStyle.OKOnly, "SDO Examples")

            Else

                MsgBox("Failed to create Invoice", MsgBoxStyle.OKOnly, "SDO Examples")

            End If

            ' Disconnect
            oWS.Disconnect()

        End If

    End If

    ' Destroy Objects
    oInvoicePost = Nothing
    oInvoiceItem = Nothing
    oSalesRecord = Nothing
    oStockRecord = Nothing
    oWS = Nothing
    oSDO = Nothing

    Exit Sub
End Sub
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.InvoicePost oInvoicePost;
SageDataObject300.InvoiceItem oInvoiceItem;
SageDataObject300.SalesRecord oSalesRecord;
SageDataObject300.StockRecord oStockRecord;
String szDataPath;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails
try
{
    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "Example");

    //Instantiate objects
    oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");
    oInvoicePost = (SageDataObject300.InvoicePost)oWS.CreateObject("InvoicePost");
    oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");

    //Set the invoice type
    oInvoicePost.Type = (SageDataObject300.InvoiceType)SageDataObject300.LedgerType.sdoLedgerInvoice;

    //Read the first customer record and use to populate the invoice fields
    oSalesRecord.MoveFirst();
    SDOHelper.Write(oInvoicePost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));
    SDOHelper.Write(oInvoicePost.Header, "NAME", (String)SDOHelper.Read(oSalesRecord, "NAME"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_1"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_2"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_3"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_4"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_5", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_5"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_1"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_2"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_3"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_4"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_5", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_5"));
    SDOHelper.Write(oInvoicePost.Header, "CUST_TEL_NUMBER", (String)SDOHelper.Read(oSalesRecord, "TELEPHONE"));
    SDOHelper.Write(oInvoicePost.Header, "CONTACT_NAME", (String)SDOHelper.Read(oSalesRecord, "CONTACT_NAME"));
    SDOHelper.Write(oInvoicePost.Header, "GLOBAL_TAX_CODE", (Int16)SDOHelper.Read(oSalesRecord, "DEF_TAX_CODE"));

    //Populate other invoice header information
    SDOHelper.Write(oInvoicePost.Header, "INVOICE_DATE", (DateTime)DateTime.Today);
    SDOHelper.Write(oInvoicePost.Header, "NOTES_1", (String)"Notes 1");
    SDOHelper.Write(oInvoicePost.Header, "NOTES_2", (String)"Notes 2");
    SDOHelper.Write(oInvoicePost.Header, "NOTES_3", (String)"Notes 3");
    SDOHelper.Write(oInvoicePost.Header, "TAKEN_BY", (String)"Chris Reed");
    SDOHelper.Write(oInvoicePost.Header, "ORDER_NUMBER", (String)"");
    SDOHelper.Write(oInvoicePost.Header, "CUST_ORDER_NUMBER", (String)"");
    SDOHelper.Write(oInvoicePost.Header, "PAYMENT_REF", (String)"");
    // If anything is entered in the GLOBAL_NOM_CODE, all of the updated invoice�s splits will have this nominal code and
    // also this willforce anything entered in the GLOBAL_DETAILS field into the all the splits details field.
    SDOHelper.Write(oInvoicePost.Header, "GLOBAL_NOM_CODE", (String)"");
    SDOHelper.Write(oInvoicePost.Header, "GLOBAL_DETAILS", (String)"");
    SDOHelper.Write(oInvoicePost.Header, "INVOICE_TYPE_CODE",
      (Byte)SageDataObject300.InvoiceType.sdoProductInvoice);

    //Create an invoice item
    //Need to invoke the Add method
    oInvoiceItem = (SageDataObject300.InvoiceItem)SDOHelper.Add(oInvoicePost.Items);

    //Read the First Stock Code & populate fields from Stock Code
    oStockRecord.MoveFirst();
    SDOHelper.Write(oInvoiceItem, "STOCK_CODE", (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));
    SDOHelper.Write(oInvoiceItem, "DESCRIPTION", (String)SDOHelper.Read(oStockRecord, "DESCRIPTION"));
    SDOHelper.Write(oInvoiceItem, "NOMINAL_CODE", (String)SDOHelper.Read(oStockRecord, "NOMINAL_CODE"));
    SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)SDOHelper.Read(oStockRecord, "TAX_CODE"));

    //Populate other invoice item fields
    SDOHelper.Write(oInvoiceItem, "QTY_ORDER", (Int32)1);
    SDOHelper.Write(oInvoiceItem, "UNIT_PRICE", (Int32)200);
    SDOHelper.Write(oInvoiceItem, "NET_AMOUNT", (Int32)200);
    SDOHelper.Write(oInvoiceItem, "TAX_AMOUNT", (Int32)40);
    SDOHelper.Write(oInvoiceItem, "COMMENT_1", (String)"Comment 1");
    SDOHelper.Write(oInvoiceItem, "COMMENT_2", (String)"Comment 2");
    SDOHelper.Write(oInvoiceItem, "UNIT_OF_SALE", (String)"");
    SDOHelper.Write(oInvoiceItem, "FULL_NET_AMOUNT", (Int32)200);
    SDOHelper.Write(oInvoiceItem, "TAX_RATE", (Int32)20);

    //Create a 2nd item line which is negative
    oInvoiceItem = (SageDataObject300.InvoiceItem)SDOHelper.Add(oInvoicePost.Items);

    //Use a Special product code
    SDOHelper.Write(oInvoiceItem, "STOCK_CODE", "S1");
    SDOHelper.Write(oInvoiceItem, "DESCRIPTION", "Negative Line");
    SDOHelper.Write(oInvoiceItem, "NOMINAL_CODE", (String)SDOHelper.Read(oSalesRecord, "DEF_NOM_CODE"));
    SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)SDOHelper.Read(oSalesRecord, "DEF_TAX_CODE"));

    //Populate other invoice item fields
    SDOHelper.Write(oInvoiceItem, "QTY_ORDER", (Int32)1);
    SDOHelper.Write(oInvoiceItem, "UNIT_PRICE", (Int32)20);
    SDOHelper.Write(oInvoiceItem, "NET_AMOUNT", (Int32)20);
    SDOHelper.Write(oInvoiceItem, "TAX_AMOUNT", (Int32)4);
    SDOHelper.Write(oInvoiceItem, "COMMENT_1", (String)"Comment 1");
    SDOHelper.Write(oInvoiceItem, "COMMENT_2", (String)"Comment 2");
    SDOHelper.Write(oInvoiceItem, "UNIT_OF_SALE", (String)"");
    SDOHelper.Write(oInvoiceItem, "FULL_NET_AMOUNT", (Int32)20);
    SDOHelper.Write(oInvoiceItem, "TAX_RATE", (Int32)20);

    //Specify the line is negative
    SDOHelper.Write(oInvoiceItem, "IS_NEGATIVE_LINE", 1);

    //Update the invoice
    if (oInvoicePost.Update())
    {
        MessageBox.Show("Invoice Posted Successfully", "C# SDO Examples");
    }
    else
    {
        MessageBox.Show("Failed to create Invoice", "C# SDO Examples");
    }

    //Disconnect
    oWS.Disconnect();
}
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}


Sage 50 Accounts - Example - Posting a Product Credit Note

Example - Posting a Product Credit Note

The example code below demonstrates how to post a Product Credit Note.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oInvoicePost As SageDataObject300.InvoicePost
Dim oInvoiceItem As SageDataObject300.InvoiceItem
Dim oSalesRecord As SageDataObject300.SalesRecord
Dim oStockRecord As SageDataObject300.StockRecord

' Declare Variables
Dim szDataPath As String
Dim iCtr As Short

' Create the SDO Engine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company.  The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

    ' Try to Connect - Will throw an exception if it fails
    If oWS.Connect(szDataPath, "", "", "Example") Then

        ' Create an instance of the Objects
        oSalesRecord = oWS.CreateObject("SalesRecord")
        oInvoicePost = oWS.CreateObject("InvoicePost")
        oStockRecord = oWS.CreateObject("StockRecord")

        ' Set the type of invoice for the next available number
        oInvoicePost.Type = SageDataObject300.LedgerType.sdoLedgerCredit

        ' Read the First Customer & populate Invoice Fields
        oSalesRecord.MoveFirst()

        oInvoicePost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
        oInvoicePost.Header("NAME").Value = CStr(oSalesRecord.Fields.Item("NAME").Value)
        oInvoicePost.Header("ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_1").Value)
        oInvoicePost.Header("ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_2").Value)
        oInvoicePost.Header("ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_3").Value)
        oInvoicePost.Header("ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_4").Value)
        oInvoicePost.Header("ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_5").Value)
        oInvoicePost.Header("DEL_ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_1").Value)
        oInvoicePost.Header("DEL_ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_2").Value)
        oInvoicePost.Header("DEL_ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_3").Value)
        oInvoicePost.Header("DEL_ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_4").Value)
        oInvoicePost.Header("DEL_ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_5").Value)
        oInvoicePost.Header("CUST_TEL_NUMBER").Value = CStr(oSalesRecord.Fields.Item("TELEPHONE").Value)
        oInvoicePost.Header("CONTACT_NAME").Value = CStr("Audrey Hepburn")
        oInvoicePost.Header("GLOBAL_TAX_CODE").Value = CShort(oSalesRecord.Fields.Item("DEF_TAX_CODE").Value)

        ' Populate other Invoice Header Information
        oInvoicePost.Header("INVOICE_DATE").Value = CDate(Today)
        oInvoicePost.Header("NOTES_1").Value = CStr("")
        oInvoicePost.Header("NOTES_2").Value = CStr("")
        oInvoicePost.Header("NOTES_3").Value = CStr("")
        oInvoicePost.Header("TAKEN_BY").Value = CStr("")
        oInvoicePost.Header("ORDER_NUMBER").Value = CStr("")
        oInvoicePost.Header("CUST_ORDER_NUMBER").Value = CStr("")
        oInvoicePost.Header("PAYMENT_REF").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.
        oInvoicePost.Header("GLOBAL_NOM_CODE").Value = CStr("")
        oInvoicePost.Header("GLOBAL_DETAILS").Value = CStr("")
        oInvoicePost.Header("INVOICE_TYPE_CODE").Value = CByte(SageDataObject300.InvoiceType.sdoProductCredit)

        ' Create an Invoice Item
        oInvoiceItem = oInvoicePost.Items.Add()

        ' Read the First Stock Code & populate fields from Stock Code
        oStockRecord.MoveFirst()
        oInvoiceItem.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
        oInvoiceItem.Fields.Item("DESCRIPTION").Value = CStr(oStockRecord.Fields.Item("DESCRIPTION").Value)
        oInvoiceItem.Fields.Item("NOMINAL_CODE").Value = CStr(oStockRecord.Fields.Item("NOMINAL_CODE").Value)
        oInvoiceItem.Fields.Item("TAX_CODE").Value = CShort(oStockRecord.Fields.Item("TAX_CODE").Value)

        ' Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
        ' regardless of the Tax_Flag being set to 1***
        oInvoiceItem.Fields.Item("QTY_ORDER").Value = CDbl(2)
        oInvoiceItem.Fields.Item("UNIT_PRICE").Value = CDbl(50)
        oInvoiceItem.Fields.Item("NET_AMOUNT").Value = CDbl(100)
        oInvoiceItem.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(100)
        oInvoiceItem.Fields.Item("COMMENT_1").Value = CStr("")
        oInvoiceItem.Fields.Item("COMMENT_2").Value = CStr("")
        oInvoiceItem.Fields.Item("UNIT_OF_SALE").Value = CStr("")
        oInvoiceItem.Fields.Item("TAX_RATE").Value = CDbl(20)
        oInvoiceItem.Fields.Item("TAX_CODE").Value = CInt(1)

        ' Create Another Invoice Item
        oInvoiceItem = oInvoicePost.Items.Add()

        ' Read the Next Stock Code & populate fields from Stock Code
        oStockRecord.MoveNext()
        oInvoiceItem.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
        oInvoiceItem.Fields.Item("DESCRIPTION").Value = CStr(oStockRecord.Fields.Item("DESCRIPTION").Value)
        oInvoiceItem.Fields.Item("NOMINAL_CODE").Value = CStr(oStockRecord.Fields.Item("NOMINAL_CODE").Value)
        oInvoiceItem.Fields.Item("TAX_CODE").Value = CShort(oStockRecord.Fields.Item("TAX_CODE").Value)

        ' Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
        ' regardless of the Tax_Flag being set to 1***
        oInvoiceItem.Fields.Item("QTY_ORDER").Value = CDbl(1)
        oInvoiceItem.Fields.Item("UNIT_PRICE").Value = CDbl(200)
        oInvoiceItem.Fields.Item("NET_AMOUNT").Value = CDbl(200)
        oInvoiceItem.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(200)
        oInvoiceItem.Fields.Item("COMMENT_1").Value = CStr("")
        oInvoiceItem.Fields.Item("COMMENT_2").Value = CStr("")
        oInvoiceItem.Fields.Item("UNIT_OF_SALE").Value = CStr("")
        oInvoiceItem.Fields.Item("TAX_RATE").Value = CDbl(20)
        oInvoiceItem.Fields.Item("TAX_CODE").Value = CInt(1)

        ' Update the Invoice
        If oInvoicePost.Update Then

            MsgBox("Invoice Posted Successfully", MsgBoxStyle.OkOnly, "SDO Examples")

        Else

            MsgBox("Failed to create Invoice", MsgBoxStyle.OkOnly, "SDO Examples")

        End If

        ' Disconnect
        oWS.Disconnect()

    End If

End If

' Destroy Objects
oInvoicePost = Nothing
oInvoiceItem = Nothing
oSalesRecord = Nothing
oStockRecord = Nothing
oWS = Nothing
oSDO = Nothing

Exit Sub
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
String szDataPath;

    //Instantiate WorkSpace
    oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

    //Show select company dialog
    szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

    //Try a connection, will throw an exception if it fails
    try
    {
        //Leaving the username and password blank generates a login dialog
        oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

    }
    catch (Exception ex)
    {
        MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
    }

    // Declare required objects
    SageDataObject300.InvoicePost oInvoicePost;
    SageDataObject300.InvoiceItem oInvoiceItem;
    SageDataObject300.SalesRecord oSalesRecord;
    SageDataObject300.StockRecord oStockRecord;

    try
    {
        // Instantiate objects
        oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");
        oInvoicePost = (SageDataObject300.InvoicePost)oWS.CreateObject("InvoicePost");
        oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");

        // Set the type of the invoice so that we can find the next available number
        oInvoicePost.Type = (SageDataObject300.InvoiceType)SageDataObject300.LedgerType.sdoLedgerCredit;

        // Read the first customer and populate invoice header fields
        oSalesRecord.MoveFirst();

        SDOHelper.Write(oInvoicePost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));
        SDOHelper.Write(oInvoicePost.Header, "NAME", (String)SDOHelper.Read(oSalesRecord, "NAME"));
        SDOHelper.Write(oInvoicePost.Header, "ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_1"));
        SDOHelper.Write(oInvoicePost.Header, "ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_2"));
        SDOHelper.Write(oInvoicePost.Header, "ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_3"));
        SDOHelper.Write(oInvoicePost.Header, "ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_4"));
        SDOHelper.Write(oInvoicePost.Header, "ADDRESS_5", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_5"));
        SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_1"));
        SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_2"));
        SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_3"));
        SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_4"));
        SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_5", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_5"));
        SDOHelper.Write(oInvoicePost.Header, "CUST_TEL_NUMBER", (String)SDOHelper.Read(oSalesRecord, "TELEPHONE"));
        SDOHelper.Write(oInvoicePost.Header, "CONTACT_NAME", (String)"Chris Reed");
        SDOHelper.Write(oInvoicePost.Header, "GLOBAL_TAX_CODE", (Int16)SDOHelper.Read(oSalesRecord, "DEF_TAX_CODE"));

        // Populate other header information
        SDOHelper.Write(oInvoicePost.Header, "INVOICE_DATE", (DateTime)DateTime.Today);
        SDOHelper.Write(oInvoicePost.Header, "NOTES_1", (String)"Notes 1");
        SDOHelper.Write(oInvoicePost.Header, "NOTES_2", (String)"Notes 2");
        SDOHelper.Write(oInvoicePost.Header, "NOTES_3", (String)"Notes 3");
        SDOHelper.Write(oInvoicePost.Header, "TAKEN_BY", (String)"SDO");
        SDOHelper.Write(oInvoicePost.Header, "ORDER_NUMBER", (String)"");
        SDOHelper.Write(oInvoicePost.Header, "CUST_ORDER_NUMBER", (String)"");
        SDOHelper.Write(oInvoicePost.Header, "PAYMENT_REF", (String)"");
        // If anything is entered in the GLOBAL_NOM_CODE, all of the updated invoice’s splits will have this
        // nominal code and also this willforce anything entered in the GLOBAL_DETAILS field into the all
        // the splits details field.
        SDOHelper.Write(oInvoicePost.Header, "GLOBAL_NOM_CODE", (String)"");
        SDOHelper.Write(oInvoicePost.Header, "GLOBAL_DETAILS", (String)"");
        SDOHelper.Write(oInvoicePost.Header, "INVOICE_TYPE_CODE", (Byte)SageDataObject300.InvoiceType.sdoProductCredit);
        SDOHelper.Write(oInvoicePost.Header, "ITEMS_NET", (Double)500);
        SDOHelper.Write(oInvoicePost.Header, "ITEMS_TAX", (Double)52.5);

        // Create an invoice item
        oInvoiceItem = (SageDataObject300.InvoiceItem)SDOHelper.Add(oInvoicePost.Items);

        // Read the first stock code & populate the fields
        oStockRecord.MoveFirst();

        SDOHelper.Write(oInvoiceItem, "STOCK_CODE", (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));
        SDOHelper.Write(oInvoiceItem, "DESCRIPTION", (String)SDOHelper.Read(oStockRecord, "DESCRIPTION"));
        SDOHelper.Write(oInvoiceItem, "NOMINAL_CODE", (String)SDOHelper.Read(oStockRecord, "NOMINAL_CODE"));
        SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)SDOHelper.Read(oStockRecord, "TAX_CODE"));

        //Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
        //regardless of the Tax_Flag being set to 1***
        SDOHelper.Write(oInvoiceItem, "QTY_ORDER", (Double)2);
        SDOHelper.Write(oInvoiceItem, "UNIT_PRICE", (Double)50);
        SDOHelper.Write(oInvoiceItem, "NET_AMOUNT", (Double)100);
        SDOHelper.Write(oInvoiceItem, "FULL_NET_AMOUNT", (Double)100);
        SDOHelper.Write(oInvoiceItem, "COMMENT_1", (String)"Comment 1");
        SDOHelper.Write(oInvoiceItem, "COMMENT_2", (String)"Comment 2");
        SDOHelper.Write(oInvoiceItem, "UNIT_OF_SALE", (String)"");
        SDOHelper.Write(oInvoiceItem, "TAX_RATE", (Double)20);
        SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)1);

        // Create another invoice item
        oInvoiceItem = (SageDataObject300.InvoiceItem)SDOHelper.Add(oInvoicePost.Items);

        // Read the next stock code & populate the fields
        oStockRecord.MoveNext();

        SDOHelper.Write(oInvoiceItem, "STOCK_CODE", (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));
        SDOHelper.Write(oInvoiceItem, "DESCRIPTION", (String)SDOHelper.Read(oStockRecord, "DESCRIPTION"));
        SDOHelper.Write(oInvoiceItem, "NOMINAL_CODE", (String)SDOHelper.Read(oStockRecord, "NOMINAL_CODE"));
        SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)SDOHelper.Read(oStockRecord, "TAX_CODE"));

        //Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
        //regardless of the Tax_Flag being set to 1***
        SDOHelper.Write(oInvoiceItem, "QTY_ORDER", (Double)1);
        SDOHelper.Write(oInvoiceItem, "UNIT_PRICE", (Double)200);
        SDOHelper.Write(oInvoiceItem, "NET_AMOUNT", (Double)200);
        SDOHelper.Write(oInvoiceItem, "FULL_NET_AMOUNT", (Double)200);
        SDOHelper.Write(oInvoiceItem, "COMMENT_1", (String)"Comment 1");
        SDOHelper.Write(oInvoiceItem, "COMMENT_2", (String)"Comment 2");
        SDOHelper.Write(oInvoiceItem, "UNIT_OF_SALE", (String)"");
        SDOHelper.Write(oInvoiceItem, "TAX_RATE", (Double)20);
        SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)1);

        // Update the Invoice
        if (oInvoicePost.Update())
        {
            MessageBox.Show("Product Credit Note Posted Successfully");
        }
        else
        {
            MessageBox.Show("Product Credit Note Post Unsuccessful");
        }

        // Disconnect
        oWS.Disconnect();
    }
    catch (Exception ex)
    {
        // Show the exception error message
        MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }


Sage 50 Accounts - Example - Posting a Service Invoice

Example - Posting a Service Invoice

The example code below demonstrates how to post a Service Invoice.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oInvoicePost As SageDataObject300.InvoicePost
Dim oInvoiceItem As SageDataObject300.InvoiceItem
Dim oSalesRecord As SageDataObject300.SalesRecord

' Declare Variables
Dim szDataPath As String
Dim iCtr As Short

' Create the SDO Engine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company.  The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

    ' Try to Connect - Will throw an exception if it fails
    If oWS.Connect(szDataPath, "", "", "Example") Then

        ' Create an instance of InvoicePost & Record objects
        oSalesRecord = oWS.CreateObject("SalesRecord")
        oInvoicePost = oWS.CreateObject("InvoicePost")

        ' Set the type of invoice so we can find the next available number
        oInvoicePost.Type = SageDataObject300.LedgerType.sdoLedgerService

        ' Loop for Number of Items on the Invoice
        For iCtr = 1 To 5

            oInvoiceItem = oInvoicePost.Items.Add()

            ' Populate other fields required for Invoice Item
            ' From 2013 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 a NVD is set the item line values will be recalculated
            ' regardless of the Tax_Flag being set to 1***
            oInvoiceItem.Text = CStr("Sage Uk Ltd" & System.Environment.NewLine & "North Park" & System.Environment.NewLine & "Newcastle Upon Tyne" & System.Environment.NewLine & "NE13 9AA")
            oInvoiceItem.Fields.Item("UNIT_PRICE").Value = CDbl(1)
            oInvoiceItem.Fields.Item("DESCRIPTION").Value = CStr("Transaction update description")
            oInvoiceItem.Fields.Item("UNIT_PRICE").Value = CDbl(100)
            oInvoiceItem.Fields.Item("NET_AMOUNT").Value = CDbl(100)
            oInvoiceItem.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(100)
            oInvoiceItem.Fields.Item("NOMINAL_CODE").Value = CStr(oSalesRecord.Fields.Item("DEF_NOM_CODE").Value)
            oInvoiceItem.Fields.Item("TAX_CODE").Value = CShort(oSalesRecord.Fields.Item("DEF_TAX_CODE").Value)
            oInvoiceItem.Fields.Item("TAX_RATE").Value = CDbl(20)

        Next iCtr

        ' Populate Invoice Header Information
        oInvoicePost.Header("INVOICE_DATE").Value = CDate(Today)
        oInvoicePost.Header("NOTES_1").Value = CStr("")
        oInvoicePost.Header("NOTES_2").Value = CStr("")
        oInvoicePost.Header("NOTES_3").Value = CStr("")
        oInvoicePost.Header("TAKEN_BY").Value = CStr("")
        oInvoicePost.Header("ORDER_NUMBER").Value = CStr("")
        oInvoicePost.Header("CUST_ORDER_NUMBER").Value = CStr("")
        oInvoicePost.Header("PAYMENT_REF").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.
        oInvoicePost.Header("GLOBAL_NOM_CODE").Value = CStr("")
        oInvoicePost.Header("GLOBAL_DETAILS").Value = CStr("")
        oInvoicePost.Header("INVOICE_TYPE_CODE").Value = CByte(SageDataObject300.InvoiceType.sdoServiceInvoice)

        ' Read the First Customer
        oSalesRecord.MoveFirst()
        oInvoicePost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
        oInvoicePost.Header("NAME").Value = CStr(oSalesRecord.Fields.Item("NAME").Value)
        oInvoicePost.Header("ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_1").Value)
        oInvoicePost.Header("ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_2").Value)
        oInvoicePost.Header("ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_3").Value)
        oInvoicePost.Header("ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_4").Value)
        oInvoicePost.Header("ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_5").Value)
        oInvoicePost.Header("DEL_ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_1").Value)
        oInvoicePost.Header("DEL_ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_2").Value)
        oInvoicePost.Header("DEL_ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_3").Value)
        oInvoicePost.Header("DEL_ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_4").Value)
        oInvoicePost.Header("DEL_ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_5").Value)
        oInvoicePost.Header("CUST_TEL_NUMBER").Value = CStr(oSalesRecord.Fields.Item("TELEPHONE").Value)
        oInvoicePost.Header("CONTACT_NAME").Value = CStr(oSalesRecord.Fields.Item("CONTACT_NAME").Value)
        oInvoicePost.Header("GLOBAL_TAX_CODE").Value = CShort(oSalesRecord.Fields.Item("DEF_TAX_CODE").Value)

        ' Update the Invoice
        If oInvoicePost.Update Then

            MsgBox("Invoice Created Successfully", MsgBoxStyle.OkOnly, "SDO Examples")

        Else

            MsgBox("Invoice Not Created", MsgBoxStyle.OkOnly, "SDO Examples")

        End If

        ' Disconnect
        oWS.Disconnect()

    End If

End If

' Destroy Objects
oSalesRecord = Nothing
oInvoicePost = Nothing
oInvoiceItem = Nothing
oWS = Nothing
oSDO = Nothing

Exit Sub
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
String szDataPath;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails
try
{
    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

}
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}
// Declare required objects

SageDataObject300.InvoicePost oInvoicePost;

SageDataObject300.InvoiceItem oInvoiceItem;

SageDataObject300.SalesRecord oSalesRecord;

try
{
    // Instantiate objects
    oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");
    oInvoicePost = (SageDataObject300.InvoicePost)oWS.CreateObject("InvoicePost");

    // Set the type of the invoice so that we can find the next available number
    oInvoicePost.Type = (SageDataObject300.InvoiceType)SageDataObject300.LedgerType.sdoLedgerService;

    // Read the first customer and populate invoice header fields
    oSalesRecord.MoveFirst();

    SDOHelper.Write(oInvoicePost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));
    SDOHelper.Write(oInvoicePost.Header, "NAME", (String)SDOHelper.Read(oSalesRecord, "NAME"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_1"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_2"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_3"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_4"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_5", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_5"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_1"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_2"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_3"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_4"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_5", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_5"));
    SDOHelper.Write(oInvoicePost.Header, "CUST_TEL_NUMBER", (String)SDOHelper.Read(oSalesRecord, "TELEPHONE"));
    SDOHelper.Write(oInvoicePost.Header, "CONTACT_NAME", (String)"Chris Reed");
    SDOHelper.Write(oInvoicePost.Header, "GLOBAL_TAX_CODE", (Int16)SDOHelper.Read(oSalesRecord, "DEF_TAX_CODE"));

    // Populate other header information
    SDOHelper.Write(oInvoicePost.Header, "INVOICE_DATE", (DateTime)DateTime.Today);
    SDOHelper.Write(oInvoicePost.Header, "NOTES_1", (String)"Notes 1");
    SDOHelper.Write(oInvoicePost.Header, "NOTES_2", (String)"Notes 2");
    SDOHelper.Write(oInvoicePost.Header, "NOTES_3", (String)"Notes 3");
    SDOHelper.Write(oInvoicePost.Header, "TAKEN_BY", (String)"SDO");
    SDOHelper.Write(oInvoicePost.Header, "ORDER_NUMBER", (String)"");
    SDOHelper.Write(oInvoicePost.Header, "CUST_ORDER_NUMBER", (String)"");
    SDOHelper.Write(oInvoicePost.Header, "PAYMENT_REF", (String)"");
    // If anything is entered in the GLOBAL_NOM_CODE, all of the updated invoice’s splits will have this
    // nominal code and also this willforce anything entered in the GLOBAL_DETAILS field into the all
    // the splits details field.
    SDOHelper.Write(oInvoicePost.Header, "GLOBAL_NOM_CODE", (String)"");
    SDOHelper.Write(oInvoicePost.Header, "GLOBAL_DETAILS", (String)"");
    SDOHelper.Write(oInvoicePost.Header, "INVOICE_TYPE_CODE", (Byte)SageDataObject300.InvoiceType.sdoServiceInvoice);

    //Loop for the number of items on the invoice
    for (Int16 i = 1; i <= 5; i++)
    {
        //Add a new invoice items to the Invoice Post items collection
        oInvoiceItem = (SageDataObject300.InvoiceItem)SDOHelper.Add(oInvoicePost.Items);

        //Populate other fields required for Invoice Item
        //From 2013 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 a NVD is set the item line values will be recalculated
        //regardless of the Tax_Flag being set to 1***
        oInvoiceItem.Text = (String)"This is the text for the line number" + i;
        SDOHelper.Write(oInvoiceItem, "QTY_ORDER", (Int32)1);
        SDOHelper.Write(oInvoiceItem, "DESCRIPTION", (String)"Transaction update description");
        SDOHelper.Write(oInvoiceItem, "UNIT_PRICE", (Double)100.00);
        SDOHelper.Write(oInvoiceItem, "SERVICE_ITEM_LINES", (Int32)1);
        SDOHelper.Write(oInvoiceItem, "NET_AMOUNT", (Double)100.00);
        SDOHelper.Write(oInvoiceItem, "FULL_NET_AMOUNT", (Double)100.00);
        SDOHelper.Write(oInvoiceItem, "NOMINAL_CODE", (String)SDOHelper.Read(oSalesRecord, "DEF_NOM_CODE"));
        SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)SDOHelper.Read(oSalesRecord, "DEF_TAX_CODE"));
        SDOHelper.Write(oInvoiceItem, "TAX_RATE", (Double)20);
    }

    // Update the Invoice
    if (oInvoicePost.Update())
    {
        MessageBox.Show("Service Invoice Posted Successfully");
    }
    else
    {
        MessageBox.Show("Service Invoice Post Unsuccessful");
    }

    // Disconnect
    oWS.Disconnect();
}
catch (Exception ex)
{
    // Show the exception error message
    MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
}


Sage 50 Accounts - Example - Posting a Service Invoice

Example - Posting a Service Invoice with Negative Item Line

The example code below demonstrates how to post a Service Invoice with a Negative item line.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
    ' Declare Objects
    Dim oSDO As SageDataObject300.SDOEngine
    Dim oWS As SageDataObject300.WorkSpace
    Dim oInvoicePost As SageDataObject300.InvoicePost
    Dim oInvoiceItem As SageDataObject300.InvoiceItem
    Dim oSalesRecord As SageDataObject300.SalesRecord

    ' Declare Variables
    Dim szDataPath As String
    Dim iCtr As Short

    ' Create the SDO Engine Object
    oSDO = New SageDataObject300.SDOEngine

    ' Create the Workspace
    oWS = oSDO.Workspaces.Add("Example")

    ' Select Company.  The SelectCompany method takes the program install
    ' folder as a parameter
    szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

    ' A U.I. for company selection is presented to the user. If a company is selected,
    ' the path will be passed to the szDataPath variable.
    ' If not, or the Cancel button is selected, the variable will be left empty.
    If szDataPath <> "" Then

        ' Try to Connect - Will throw an exception if it fails
        If oWS.Connect(szDataPath, "", "", "Example") Then

            ' Create an instance of InvoicePost & Record objects
            oSalesRecord = oWS.CreateObject("SalesRecord")
            oInvoicePost = oWS.CreateObject("InvoicePost")

            ' Set the type of invoice so we can find the next available number
            oInvoicePost.Type = SageDataObject300.LedgerType.sdoLedgerService

            ' Add the first item
            oInvoiceItem = oInvoicePost.Items.Add()

            ' Populate other fields required for Invoice Item
            ' From 2013 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 a NVD is set the item line values will be recalculated
            ' regardless of the Tax_Flag being set to 1***
            oInvoiceItem.Text = CStr("This is the text for the 1st line")
            oInvoiceItem.Fields.Item("QTY_ORDER").Value = CDbl(1)
            oInvoiceItem.Fields.Item("DESCRIPTION").Value = CStr("Transaction update description")
            oInvoiceItem.Fields.Item("UNIT_PRICE").Value = CDbl(100)
            oInvoiceItem.Fields.Item("NET_AMOUNT").Value = CDbl(100)
            oInvoiceItem.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(100)
            oInvoiceItem.Fields.Item("NOMINAL_CODE").Value = CStr(oSalesRecord.Fields.Item("DEF_NOM_CODE").Value)
            oInvoiceItem.Fields.Item("TAX_CODE").Value = CShort(oSalesRecord.Fields.Item("DEF_TAX_CODE").Value)
            oInvoiceItem.Fields.Item("TAX_RATE").Value = CDbl(20)

            'Add the second item which is negative
            oInvoiceItem = oInvoicePost.Items.Add()

            ' Populate other fields required for Invoice Item
            ' From 2013 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 a NVD is set the item line values will be recalculated
            ' regardless of the Tax_Flag being set to 1***

            oInvoiceItem.Text = CStr("This is the text for the negative line")
            oInvoiceItem.Fields.Item("QTY_ORDER").Value = CDbl(1)
            oInvoiceItem.Fields.Item("DESCRIPTION").Value = CStr("Transaction update description")
            oInvoiceItem.Fields.Item("UNIT_PRICE").Value = CDbl(10)
            oInvoiceItem.Fields.Item("NET_AMOUNT").Value = CDbl(10)
            oInvoiceItem.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(10)
            oInvoiceItem.Fields.Item("NOMINAL_CODE").Value = CStr(oSalesRecord.Fields.Item("DEF_NOM_CODE").Value)
            oInvoiceItem.Fields.Item("TAX_CODE").Value = CShort(oSalesRecord.Fields.Item("DEF_TAX_CODE").Value)
            oInvoiceItem.Fields.Item("TAX_RATE").Value = CDbl(20)

            'Set the item as negative
            oInvoiceItem.Fields.Item("IS_NEGATIVE_LINE").Value = CDbl(1)

            ' Populate Invoice Header Information
            oInvoicePost.Header("INVOICE_DATE").Value = CDate(Today)
            oInvoicePost.Header("NOTES_1").Value = CStr("")
            oInvoicePost.Header("NOTES_2").Value = CStr("")
            oInvoicePost.Header("NOTES_3").Value = CStr("")
            oInvoicePost.Header("TAKEN_BY").Value = CStr("")
            oInvoicePost.Header("ORDER_NUMBER").Value = CStr("")
            oInvoicePost.Header("CUST_ORDER_NUMBER").Value = CStr("")
            oInvoicePost.Header("PAYMENT_REF").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.
            oInvoicePost.Header("GLOBAL_NOM_CODE").Value = CStr("")
            oInvoicePost.Header("GLOBAL_DETAILS").Value = CStr("")
            oInvoicePost.Header("INVOICE_TYPE_CODE").Value = CByte(SageDataObject300.InvoiceType.sdoServiceInvoice)

            ' Read the First Customer
            oSalesRecord.MoveFirst()
            oInvoicePost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
            oInvoicePost.Header("NAME").Value = CStr(oSalesRecord.Fields.Item("NAME").Value)
            oInvoicePost.Header("ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_1").Value)
            oInvoicePost.Header("ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_2").Value)
            oInvoicePost.Header("ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_3").Value)
            oInvoicePost.Header("ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_4").Value)
            oInvoicePost.Header("ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_5").Value)
            oInvoicePost.Header("DEL_ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_1").Value)
            oInvoicePost.Header("DEL_ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_2").Value)
            oInvoicePost.Header("DEL_ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_3").Value)
            oInvoicePost.Header("DEL_ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_4").Value)
            oInvoicePost.Header("DEL_ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_5").Value)
            oInvoicePost.Header("CUST_TEL_NUMBER").Value = CStr(oSalesRecord.Fields.Item("TELEPHONE").Value)
            oInvoicePost.Header("CONTACT_NAME").Value = CStr(oSalesRecord.Fields.Item("CONTACT_NAME").Value)
            oInvoicePost.Header("GLOBAL_TAX_CODE").Value = CShort(oSalesRecord.Fields.Item("DEF_TAX_CODE").Value)

            ' Update the Invoice
            If oInvoicePost.Update Then

                MsgBox("Invoice Created Successfully", MsgBoxStyle.OkOnly, "SDO Examples")

            Else

                MsgBox("Invoice Not Created", MsgBoxStyle.OkOnly, "SDO Examples")

            End If

            ' Disconnect
            oWS.Disconnect()

        End If

    End If

    ' Destroy Objects
    oSalesRecord = Nothing
    oInvoicePost = Nothing
    oInvoiceItem = Nothing
    oWS = Nothing
    oSDO = Nothing

    Exit Sub

End Sub
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
String szDataPath;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails
try
{
    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

}
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}

// Declare required objects
SageDataObject300.InvoicePost oInvoicePost;
SageDataObject300.InvoiceItem oInvoiceItem;
SageDataObject300.SalesRecord oSalesRecord;

try
{
    // Instantiate objects
    oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");
    oInvoicePost = (SageDataObject300.InvoicePost)oWS.CreateObject("InvoicePost");

    // Set the type of the invoice so that we can find the next available number
    oInvoicePost.Type = (SageDataObject300.InvoiceType)SageDataObject300.LedgerType.sdoLedgerService;

    // Read the first customer and populate invoice header fields
    oSalesRecord.MoveFirst();

    SDOHelper.Write(oInvoicePost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));
    SDOHelper.Write(oInvoicePost.Header, "NAME", (String)SDOHelper.Read(oSalesRecord, "NAME"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_1"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_2"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_3"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_4"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_5", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_5"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_1"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_2"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_3"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_4"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_5", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_5"));
    SDOHelper.Write(oInvoicePost.Header, "CUST_TEL_NUMBER", (String)SDOHelper.Read(oSalesRecord, "TELEPHONE"));
    SDOHelper.Write(oInvoicePost.Header, "CONTACT_NAME", (String)"Chris Reed");
    SDOHelper.Write(oInvoicePost.Header, "GLOBAL_TAX_CODE", (Int16)SDOHelper.Read(oSalesRecord, "DEF_TAX_CODE"));

    // Populate other header information
    SDOHelper.Write(oInvoicePost.Header, "INVOICE_DATE", (DateTime)DateTime.Today);
    SDOHelper.Write(oInvoicePost.Header, "NOTES_1", (String)"Notes 1");
    SDOHelper.Write(oInvoicePost.Header, "NOTES_2", (String)"Notes 2");
    SDOHelper.Write(oInvoicePost.Header, "NOTES_3", (String)"Notes 3");
    SDOHelper.Write(oInvoicePost.Header, "TAKEN_BY", (String)"SDO");
    SDOHelper.Write(oInvoicePost.Header, "ORDER_NUMBER", (String)"");
    SDOHelper.Write(oInvoicePost.Header, "CUST_ORDER_NUMBER", (String)"");
    SDOHelper.Write(oInvoicePost.Header, "PAYMENT_REF", (String)"");
    // If anything is entered in the GLOBAL_NOM_CODE, all of the updated invoice�s splits will have this
    // nominal code and also this willforce anything entered in the GLOBAL_DETAILS field into the all
    // the splits details field.
    SDOHelper.Write(oInvoicePost.Header, "GLOBAL_NOM_CODE", (String)"");
    SDOHelper.Write(oInvoicePost.Header, "GLOBAL_DETAILS", (String)"");
    SDOHelper.Write(oInvoicePost.Header, "INVOICE_TYPE_CODE", (Byte)SageDataObject300.InvoiceType.sdoServiceInvoice);

    //Add a new invoice item to the Invoice Post items collection
    oInvoiceItem = (SageDataObject300.InvoiceItem)SDOHelper.Add(oInvoicePost.Items);

    //Populate other fields required for Invoice Item
    //From 2013 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 a NVD is set the item line values will be recalculated
    //regardless of the Tax_Flag being set to 1***
    oInvoiceItem.Text = (String)"This is the text for the 1st line";
    SDOHelper.Write(oInvoiceItem, "QTY_ORDER", (Int32)1);
    SDOHelper.Write(oInvoiceItem, "DESCRIPTION", (String)"Transaction update description");
    SDOHelper.Write(oInvoiceItem, "UNIT_PRICE", (Double)100.00);
    SDOHelper.Write(oInvoiceItem, "SERVICE_ITEM_LINES", (Int32)1);
    SDOHelper.Write(oInvoiceItem, "NET_AMOUNT", (Double)100.00);
    SDOHelper.Write(oInvoiceItem, "FULL_NET_AMOUNT", (Double)100.00);
    SDOHelper.Write(oInvoiceItem, "NOMINAL_CODE", (String)SDOHelper.Read(oSalesRecord, "DEF_NOM_CODE"));
    SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)SDOHelper.Read(oSalesRecord, "DEF_TAX_CODE"));
    SDOHelper.Write(oInvoiceItem, "TAX_RATE", (Double)20);

    //Add a second item which is negative
    oInvoiceItem = (SageDataObject300.InvoiceItem)SDOHelper.Add(oInvoicePost.Items);

    //Populate other fields required for Invoice Item
    //From 2013 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 a NVD is set the item line values will be recalculated
    //regardless of the Tax_Flag being set to 1***
    oInvoiceItem.Text = (String)"This is the text for the negative line";
    SDOHelper.Write(oInvoiceItem, "QTY_ORDER", (Int32)1);
    SDOHelper.Write(oInvoiceItem, "DESCRIPTION", (String)"Transaction update description");
    SDOHelper.Write(oInvoiceItem, "UNIT_PRICE", (Double)10.00);
    SDOHelper.Write(oInvoiceItem, "SERVICE_ITEM_LINES", (Int32)1);
    SDOHelper.Write(oInvoiceItem, "NET_AMOUNT", (Double)10.00);
    SDOHelper.Write(oInvoiceItem, "FULL_NET_AMOUNT", (Double)10.00);
    SDOHelper.Write(oInvoiceItem, "NOMINAL_CODE", (String)SDOHelper.Read(oSalesRecord, "DEF_NOM_CODE"));
    SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)SDOHelper.Read(oSalesRecord, "DEF_TAX_CODE"));
    SDOHelper.Write(oInvoiceItem, "TAX_RATE", (Double)20);

    //Specify the line is negative
    SDOHelper.Write(oInvoiceItem, "IS_NEGATIVE_LINE", 1);

    // Update the Invoice
    if (oInvoicePost.Update())
    {
        MessageBox.Show("Service Invoice Posted Successfully");
    }
    else
    {
        MessageBox.Show("Service Invoice Post Unsuccessful");
    }

    // Disconnect
    oWS.Disconnect();
}
catch (Exception ex)
{
    // Show the exception error message
    MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
}


Sage 50 Accounts - Example - Posting a Service Credit Note

Example - Posting a Service Credit Note

The example code below demonstrates how to post a Service Credit Note.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oInvoicePost As SageDataObject300.InvoicePost
  Dim oInvoiceItem As SageDataObject300.InvoiceItem
  Dim oSalesRecord As SageDataObject300.SalesRecord

  ' Declare Variables
  Dim szDataPath As String
  Dim iCtr As Short

  ' Create the SDO Engine Object
  oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  oWS = oSDO.Workspaces.Add("Example")

  ' Select Company.  The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024\")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then

      ' Try to Connect - Will throw an exception if it fails
      If oWS.Connect(szDataPath, "", "", "Example") Then

          ' Create an instance of InvoicePost & Record objects
          oSalesRecord = oWS.CreateObject("SalesRecord")
          oInvoicePost = oWS.CreateObject("InvoicePost")

          ' Set the type of invoice so we can find the next available number
          oInvoicePost.Type = SageDataObject300.LedgerType.sdoLedgerServiceCredit

          ' Populate Invoice Header Information
          oInvoicePost.Header("INVOICE_DATE").Value = CDate(Today)
          oInvoicePost.Header("NOTES_1").Value = CStr("")
          oInvoicePost.Header("NOTES_2").Value = CStr("")
          oInvoicePost.Header("NOTES_3").Value = CStr("")
          oInvoicePost.Header("TAKEN_BY").Value = CStr("")
          oInvoicePost.Header("ORDER_NUMBER").Value = CStr("")
          oInvoicePost.Header("CUST_ORDER_NUMBER").Value = CStr("")
          oInvoicePost.Header("PAYMENT_REF").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.
oInvoicePost.Header("GLOBAL_DETAILS").Value = CStr("")details.
          oInvoicePost.Header("INVOICE_TYPE_CODE").Value = CByte(SageDataObject300.InvoiceType.sdoServiceCredit)
          oInvoicePost.Header("ITEMS_NET").Value = CDbl(500)
          oInvoicePost.Header("ITEMS_TAX").Value = CDbl(87.5)

          ' Read the First Customer
          oSalesRecord.MoveFirst()
          oInvoicePost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
          oInvoicePost.Header("NAME").Value = CStr(oSalesRecord.Fields.Item("NAME").Value)
          oInvoicePost.Header("ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_1").Value)
          oInvoicePost.Header("ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_2").Value)
          oInvoicePost.Header("ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_3").Value)
          oInvoicePost.Header("ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_4").Value)
          oInvoicePost.Header("ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_5").Value)
          oInvoicePost.Header("DEL_ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_1").Value)
          oInvoicePost.Header("DEL_ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_2").Value)
          oInvoicePost.Header("DEL_ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_3").Value)
          oInvoicePost.Header("DEL_ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_4").Value)
          oInvoicePost.Header("DEL_ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_5").Value)
          oInvoicePost.Header("CUST_TEL_NUMBER").Value = CStr(oSalesRecord.Fields.Item("TELEPHONE").Value)
          oInvoicePost.Header("CONTACT_NAME").Value = CStr("Michael Kenney")
          oInvoicePost.Header("GLOBAL_TAX_CODE").Value = CShort(oSalesRecord.Fields.Item("DEF_TAX_CODE").Value)

          ' Loop for Number of Items on the Invoice
          For iCtr = 1 To 5

              oInvoiceItem = oInvoicePost.Items.Add()

              ' Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
              ' regardless of the Tax_Flag being set to 1***
              oInvoiceItem.Text = CStr("This is the text for line number " & iCtr)
              oInvoiceItem.Fields.Item("TEXT").Value = CStr("Posting Text")
              oInvoiceItem.Fields.Item("QTY_ORDER").Value = CDbl(1)
              oInvoiceItem.Fields.Item("SERVICE_ITEM_LINES").Value = CInt(1)
              oInvoiceItem.Fields.Item("NET_AMOUNT").Value = CDbl(100)
              oInvoiceItem.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(100)
              oInvoiceItem.Fields.Item("NOMINAL_CODE").Value = CStr(oSalesRecord.Fields.Item("DEF_NOM_CODE").Value)
              oInvoiceItem.Fields.Item("TAX_CODE").Value = CShort(oSalesRecord.Fields.Item("DEF_TAX_CODE").Value)
              oInvoiceItem.Fields.Item("TAX_RATE").Value = CDbl(20)

          Next iCtr

          ' Update the Invoice
          If oInvoicePost.Update Then

              MsgBox("Credit Note Created Successfully", MsgBoxStyle.OkOnly, "SDO Examples")

          Else

              MsgBox("Credit Note Not Created", MsgBoxStyle.OkOnly, "SDO Examples")

          End If

          ' Disconnect
          oWS.Disconnect()

      End If

  End If

  ' Destroy Objects
  oSalesRecord = Nothing
  oInvoicePost = Nothing
  oInvoiceItem = Nothing
  oWS = Nothing
  oSDO = Nothing

  Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.InvoicePost oInvoicePost;

SageDataObject300.InvoiceItem oInvoiceItem;

SageDataObject300.SalesRecord oSalesRecord;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate Objects

  oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");

  oInvoicePost = (SageDataObject300.InvoicePost)oWS.CreateObject("InvoicePost");

  //Set the type of invoice so we can find the next available number

  oInvoicePost.Type = (SageDataObject300.InvoiceType)SageDataObject300.LedgerType.sdoLedgerServiceCredit;

  //Populate the invoice header information

  SDOHelper.Write(oInvoicePost.Header, "INVOICE_DATE", (DateTime)DateTime.Today);

  SDOHelper.Write(oInvoicePost.Header, "NOTES_1", (String)"Notes 1");

  SDOHelper.Write(oInvoicePost.Header, "NOTES_2", (String)"Notes 2");

  SDOHelper.Write(oInvoicePost.Header, "NOTES_3", (String)"Notes 3");

  SDOHelper.Write(oInvoicePost.Header, "TAKEN_BY", (String)"SDO");

  SDOHelper.Write(oInvoicePost.Header, "ORDER_NUMBER", (String)"");

  SDOHelper.Write(oInvoicePost.Header, "CUST_ORDER_NUMBER", (String)"");

  SDOHelper.Write(oInvoicePost.Header, "PAYMENT_REF", (String)"");

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

  SDOHelper.Write(oInvoicePost.Header, "GLOBAL_NOM_CODE", (String)"");

  SDOHelper.Write(oInvoicePost.Header, "GLOBAL_DETAILS", (String)"");

  SDOHelper.Write(oInvoicePost.Header, "INVOICE_TYPE_CODE",

    (Byte)SageDataObject300.InvoiceType.sdoServiceCredit);

  //Read the first customer

  oSalesRecord.MoveFirst();

  //Populate other header fields

  SDOHelper.Write(oInvoicePost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));

  SDOHelper.Write(oInvoicePost.Header, "NAME", (String)SDOHelper.Read(oSalesRecord, "NAME"));

  SDOHelper.Write(oInvoicePost.Header, "ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_1"));

  SDOHelper.Write(oInvoicePost.Header, "ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_2"));

  SDOHelper.Write(oInvoicePost.Header, "ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_3"));

  SDOHelper.Write(oInvoicePost.Header, "ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_4"));

  SDOHelper.Write(oInvoicePost.Header, "ADDRESS_5", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_5"));

  SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_1"));

  SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_2"));

  SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_3"));

  SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_4"));

  SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_5"));

  SDOHelper.Write(oInvoicePost.Header, "CUST_TEL_NUMBER", (String)SDOHelper.Read(oSalesRecord, "TELEPHONE"));

  SDOHelper.Write(oInvoicePost.Header, "CONTACT_NAME", (String)"Chris Reed");

  SDOHelper.Write(oInvoicePost.Header, "GLOBAL_TAX_CODE", (Int16)SDOHelper.Read(oSalesRecord, "DEF_TAX_CODE"));

  //Loop for the number of items on the invoice

  for (Int16 i = 1; i <= 5; i++)

  {

    //Add a new invoice items to the Invoice Post items collection

    oInvoiceItem = (SageDataObject300.InvoiceItem)SDOHelper.Add(oInvoicePost.Items);

    //Populate the invoice item fields

    oInvoiceItem.Text = (String)"This is the text for the line number" + i;

    SDOHelper.Write(oInvoiceItem, "TEXT", (String)"Posting Text");

    SDOHelper.Write(oInvoiceItem, "QTY_ORDER", (Double)1);

    SDOHelper.Write(oInvoiceItem, "SERVICE_ITEM_LINES", (Int32)1);

    SDOHelper.Write(oInvoiceItem, "NET_AMOUNT", (Double)100.00);

    SDOHelper.Write(oInvoiceItem, "FULL_NET_AMOUNT", (Double)100.00);

    SDOHelper.Write(oInvoiceItem, "TAX_AMOUNT", (Double)17.5);

    SDOHelper.Write(oInvoiceItem, "NOMINAL_CODE", (String)SDOHelper.Read(oSalesRecord, "DEF_NOM_CODE"));

    SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)SDOHelper.Read(oSalesRecord, "DEF_TAX_CODE"));

    SDOHelper.Write(oInvoiceItem, "TAX_RATE", (Double)17.5);

  }

  //Update the invoice

  if (oInvoicePost.Update())

  {

    MessageBox.Show("Credit note created successfully");

  }

  else

  {

    MessageBox.Show("Failed to create credit note");

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Posting a 'Mix and Match' Invoice

Example - Posting a 'Mix and Match' Invoice

The example code below demonstrates how to post a 'Mix and Match' Invoice.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oInvoicePost As SageDataObject300.InvoicePost
Dim oInvoiceItem As SageDataObject300.InvoiceItem
Dim oSalesRecord As SageDataObject300.SalesRecord
Dim oStockRecord As SageDataObject300.StockRecord

' Declare Variables
Dim szDataPath As String

' Create the SDO Engine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company.  The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

    ' Try to Connect - Will throw an exception if it fails
    If oWS.Connect(szDataPath, "", "", "Example") Then

        ' Create an instance of InvoicePost & Record Objects
        oSalesRecord = oWS.CreateObject("SalesRecord")
        oInvoicePost = oWS.CreateObject("InvoicePost")
        oStockRecord = oWS.CreateObject("StockRecord")

        ' Set the type of invoice for the next available number
        oInvoicePost.Type = SageDataObject300.LedgerType.sdoLedgerInvoice

        ' Read the First Customer & populate Invoice Fields
        oSalesRecord.MoveFirst()

        oInvoicePost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
        oInvoicePost.Header("NAME").Value = CStr(oSalesRecord.Fields.Item("NAME").Value)
        oInvoicePost.Header("ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_1").Value)
        oInvoicePost.Header("ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_2").Value)
        oInvoicePost.Header("ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_3").Value)
        oInvoicePost.Header("ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_4").Value)
        oInvoicePost.Header("ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_5").Value)
        oInvoicePost.Header("DEL_ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_1").Value)
        oInvoicePost.Header("DEL_ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_2").Value)
        oInvoicePost.Header("DEL_ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_3").Value)
        oInvoicePost.Header("DEL_ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_4").Value)
        oInvoicePost.Header("DEL_ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_5").Value)
        oInvoicePost.Header("CUST_TEL_NUMBER").Value = CStr(oSalesRecord.Fields.Item("TELEPHONE").Value)
        oInvoicePost.Header("CONTACT_NAME").Value = CStr(oSalesRecord.Fields.Item("CONTACT_NAME").Value)
        oInvoicePost.Header("GLOBAL_TAX_CODE").Value = CShort(oSalesRecord.Fields.Item("DEF_TAX_CODE").Value)

        ' Populate other Invoice Header Information
        oInvoicePost.Header("INVOICE_DATE").Value = CDate(Today)
        oInvoicePost.Header("NOTES_1").Value = CStr("")
        oInvoicePost.Header("NOTES_2").Value = CStr("")
        oInvoicePost.Header("NOTES_3").Value = CStr("")
        oInvoicePost.Header("TAKEN_BY").Value = CStr("")
        oInvoicePost.Header("ORDER_NUMBER").Value = CStr("")
        oInvoicePost.Header("CUST_ORDER_NUMBER").Value = CStr("")
        oInvoicePost.Header("PAYMENT_REF").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.
        oInvoicePost.Header("GLOBAL_NOM_CODE").Value = CStr("")
        oInvoicePost.Header("GLOBAL_DETAILS").Value = CStr("")
        oInvoicePost.Header("INVOICE_TYPE_CODE").Value = CByte(SageDataObject300.InvoiceType.sdoProductInvoice)
        oInvoicePost.Header("ITEMS_NET").Value = CDbl(500)
        oInvoicePost.Header("ITEMS_TAX").Value = CDbl(52.5)

        ' Create an Invoice Item
        oInvoiceItem = oInvoicePost.Items.Add()

        ' Read the First Stock Code & populate fields from Stock Code
        oStockRecord.MoveFirst()
        oInvoiceItem.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
        oInvoiceItem.Fields.Item("DESCRIPTION").Value = CStr(oStockRecord.Fields.Item("DESCRIPTION").Value)
        oInvoiceItem.Fields.Item("NOMINAL_CODE").Value = CStr(oStockRecord.Fields.Item("NOMINAL_CODE").Value)
        oInvoiceItem.Fields.Item("TAX_CODE").Value = CShort(oStockRecord.Fields.Item("TAX_CODE").Value)

        ' Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
        ' regardless of the Tax_Flag being set to 1***
        oInvoiceItem.Fields.Item("QTY_ORDER").Value = CDbl(2)
        oInvoiceItem.Fields.Item("UNIT_PRICE").Value = CDbl(50)
        oInvoiceItem.Fields.Item("NET_AMOUNT").Value = CDbl(100)
        oInvoiceItem.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(100)
        oInvoiceItem.Fields.Item("COMMENT_1").Value = CStr("")
        oInvoiceItem.Fields.Item("COMMENT_2").Value = CStr("")
        oInvoiceItem.Fields.Item("UNIT_OF_SALE").Value = CStr("")
        oInvoiceItem.Fields.Item("TAX_RATE").Value = CDbl(20)
        oInvoiceItem.Fields.Item("TAX_CODE").Value = CInt(1)

        ' Create Another Invoice Item
        oInvoiceItem = oInvoicePost.Items.Add()

        ' Read the Next Stock Code & populate fields from Stock Code
        oStockRecord.MoveNext()
        oInvoiceItem.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
        oInvoiceItem.Fields.Item("DESCRIPTION").Value = CStr(oStockRecord.Fields.Item("DESCRIPTION").Value)
        oInvoiceItem.Fields.Item("NOMINAL_CODE").Value = CStr(oStockRecord.Fields.Item("NOMINAL_CODE").Value)
        oInvoiceItem.Fields.Item("TAX_CODE").Value = CShort(oStockRecord.Fields.Item("TAX_CODE").Value)

        ' Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
        ' regardless of the Tax_Flag being set to 1***
        oInvoiceItem.Fields.Item("QTY_ORDER").Value = CDbl(1)
        oInvoiceItem.Fields.Item("UNIT_PRICE").Value = CDbl(200)
        oInvoiceItem.Fields.Item("NET_AMOUNT").Value = CDbl(200)
        oInvoiceItem.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(200)
        oInvoiceItem.Fields.Item("COMMENT_1").Value = CStr("")
        oInvoiceItem.Fields.Item("COMMENT_2").Value = CStr("")
        oInvoiceItem.Fields.Item("UNIT_OF_SALE").Value = CStr("")
        oInvoiceItem.Fields.Item("TAX_RATE").Value = CDbl(20)
        oInvoiceItem.Fields.Item("TAX_Code").Value = CInt(1)

        ' Create a Third Invoice Item - This one is the Service Item
        oInvoiceItem = oInvoicePost.Items.Add()

        ' Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
        ' regardless of the Tax_Flag being set to 1***
        oInvoiceItem.Fields.Item("SERVICE_FLAG").Value = CByte(SageDataObject300.InvoiceItemType.sdoItemQtyService)
        oInvoiceItem.Fields.Item("STOCK_CODE").Value = CStr("S3")
        oInvoiceItem.Fields.Item("DESCRIPTION").Value = CStr("Service Item")
        oInvoiceItem.Text = CStr("Service Item on Product Invoice")
        oInvoiceItem.Fields.Item("NOMINAL_CODE").Value = CStr("4000")
        oInvoiceItem.Fields.Item("TAX_CODE").Value = CShort(1)
        oInvoiceItem.Fields.Item("QTY_ORDER").Value = CDbl(10)
        oInvoiceItem.Fields.Item("UNIT_PRICE").Value = CDbl(20)
        oInvoiceItem.Fields.Item("NET_AMOUNT").Value = CDbl(200)
        oInvoiceItem.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(200)
        oInvoiceItem.Fields.Item("COMMENT_1").Value = CStr("")
        oInvoiceItem.Fields.Item("COMMENT_2").Value = CStr("")
        oInvoiceItem.Fields.Item("UNIT_OF_SALE").Value = CStr("")
        oInvoiceItem.Fields.Item("TAX_RATE").Value = CDbl(20)
        oInvoiceItem.Fields.Item("TAX_CODE").Value = CInt(1)

        ' Update the Invoice
        If oInvoicePost.Update Then

            MsgBox("Invoice Posted Successfully", MsgBoxStyle.OkOnly, "SDO Examples")

        Else

            MsgBox("Invoice Post Unsuccessful", MsgBoxStyle.OkOnly, "SDO Examples")

        End If

        ' Disconnect
        oWS.Disconnect()

    End If

End If

' Destroy Objects
oInvoicePost = Nothing
oInvoiceItem = Nothing
oSalesRecord = Nothing
oStockRecord = Nothing
oWS = Nothing
oSDO = Nothing

Exit Sub
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.InvoicePost oInvoicePost;
SageDataObject300.InvoiceItem oInvoiceItem;
SageDataObject300.SalesRecord oSalesRecord;
SageDataObject300.StockRecord oStockRecord;
String szDataPath;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails
try
{
    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

    //Instantiate objects
    oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");
    oInvoicePost = (SageDataObject300.InvoicePost)oWS.CreateObject("InvoicePost");
    oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");

    //Set the type of the invoice so that we can find the next available number
    oInvoicePost.Type = (SageDataObject300.InvoiceType)SageDataObject300.LedgerType.sdoLedgerInvoice;

    //Read the first customer and populate invoice header fields
    oSalesRecord.MoveFirst();

    SDOHelper.Write(oInvoicePost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));
    SDOHelper.Write(oInvoicePost.Header, "NAME", (String)SDOHelper.Read(oSalesRecord, "NAME"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_1"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_2"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_3"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_4"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_5", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_5"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_1"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_2"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_3"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_4"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_5", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_5"));
    SDOHelper.Write(oInvoicePost.Header, "CUST_TEL_NUMBER", (String)SDOHelper.Read(oSalesRecord, "TELEPHONE"));
    SDOHelper.Write(oInvoicePost.Header, "CONTACT_NAME", (String)"Chris Reed");
    SDOHelper.Write(oInvoicePost.Header, "GLOBAL_TAX_CODE", (Int16)SDOHelper.Read(oSalesRecord, "DEF_TAX_CODE"));

    //Populate other header information
    SDOHelper.Write(oInvoicePost.Header, "INVOICE_DATE", (DateTime)DateTime.Today);
    SDOHelper.Write(oInvoicePost.Header, "NOTES_1", (String)"Notes 1");
    SDOHelper.Write(oInvoicePost.Header, "NOTES_2", (String)"Notes 2");
    SDOHelper.Write(oInvoicePost.Header, "NOTES_3", (String)"Notes 3");
    SDOHelper.Write(oInvoicePost.Header, "TAKEN_BY", (String)"SDO");
    SDOHelper.Write(oInvoicePost.Header, "ORDER_NUMBER", (String)"");
    SDOHelper.Write(oInvoicePost.Header, "CUST_ORDER_NUMBER", (String)"");
    SDOHelper.Write(oInvoicePost.Header, "PAYMENT_REF", (String)"");
    // If anything is entered in the GLOBAL_NOM_CODE, all of the updated invoice’s splits will have this
    // nominal code and also this willforce anything entered in the GLOBAL_DETAILS field into the all
    // the splits details field.
    SDOHelper.Write(oInvoicePost.Header, "GLOBAL_NOM_CODE", (String)"");
    SDOHelper.Write(oInvoicePost.Header, "GLOBAL_DETAILS", (String)"");
    SDOHelper.Write(oInvoicePost.Header, "INVOICE_TYPE_CODE",
      (Byte)SageDataObject300.InvoiceType.sdoProductInvoice);

    //Create an invoice item
    oInvoiceItem = (SageDataObject300.InvoiceItem)SDOHelper.Add(oInvoicePost.Items);

    //Read the first stock code & populate the fields
    oStockRecord.MoveFirst();

    SDOHelper.Write(oInvoiceItem, "STOCK_CODE", (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));
    SDOHelper.Write(oInvoiceItem, "DESCRIPTION", (String)SDOHelper.Read(oStockRecord, "DESCRIPTION"));
    SDOHelper.Write(oInvoiceItem, "NOMINAL_CODE", (String)SDOHelper.Read(oStockRecord, "NOMINAL_CODE"));
    SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)SDOHelper.Read(oStockRecord, "TAX_CODE"));

    //Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
    //regardless of the Tax_Flag being set to 1***
    SDOHelper.Write(oInvoiceItem, "QTY_ORDER", (Double)2);
    SDOHelper.Write(oInvoiceItem, "UNIT_PRICE", (Double)50);
    SDOHelper.Write(oInvoiceItem, "NET_AMOUNT", (Double)100);
    SDOHelper.Write(oInvoiceItem, "FULL_NET_AMOUNT", (Double)100);
    SDOHelper.Write(oInvoiceItem, "COMMENT_1", (String)"Comment 1");
    SDOHelper.Write(oInvoiceItem, "COMMENT_2", (String)"Comment 2");
    SDOHelper.Write(oInvoiceItem, "UNIT_OF_SALE", (String)"");
    SDOHelper.Write(oInvoiceItem, "TAX_RATE", (Double)20);
    SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)1);

    //Create another invoice item
    oInvoiceItem = (SageDataObject300.InvoiceItem)SDOHelper.Add(oInvoicePost.Items);

    //Read the next stock code & populate the fields
    oStockRecord.MoveNext();

    SDOHelper.Write(oInvoiceItem, "STOCK_CODE", (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));
    SDOHelper.Write(oInvoiceItem, "DESCRIPTION", (String)SDOHelper.Read(oStockRecord, "DESCRIPTION"));
    SDOHelper.Write(oInvoiceItem, "NOMINAL_CODE", (String)SDOHelper.Read(oStockRecord, "NOMINAL_CODE"));
    SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)SDOHelper.Read(oStockRecord, "TAX_CODE"));

    //Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
    //regardless of the Tax_Flag being set to 1***
    SDOHelper.Write(oInvoiceItem, "QTY_ORDER", (Double)1);
    SDOHelper.Write(oInvoiceItem, "UNIT_PRICE", (Double)200);
    SDOHelper.Write(oInvoiceItem, "NET_AMOUNT", (Double)200);
    SDOHelper.Write(oInvoiceItem, "FULL_NET_AMOUNT", (Double)200);
    SDOHelper.Write(oInvoiceItem, "COMMENT_1", (String)"Comment 1");
    SDOHelper.Write(oInvoiceItem, "COMMENT_2", (String)"Comment 2");
    SDOHelper.Write(oInvoiceItem, "UNIT_OF_SALE", (String)"");
    SDOHelper.Write(oInvoiceItem, "TAX_RATE", (Double)20);
    SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)1);

    //Create a third invoice item - This one is the service item
    oInvoiceItem = (SageDataObject300.InvoiceItem)SDOHelper.Add(oInvoicePost.Items);

    //Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
    //regardless of the Tax_Flag being set to 1***
    SDOHelper.Write(oInvoiceItem, "SERVICE_FLAG", (Byte)SageDataObject300.InvoiceItemType.sdoItemQtyService);
    SDOHelper.Write(oInvoiceItem, "STOCK_CODE", (String)"S3");
    SDOHelper.Write(oInvoiceItem, "DESCRIPTION", (String)"Service Item");
    oInvoiceItem.Text = (String)"Service Item on Product Invoice";
    SDOHelper.Write(oInvoiceItem, "NOMINAL_CODE", (String)"4000");
    SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)1);
    SDOHelper.Write(oInvoiceItem, "QTY_ORDER", (Double)10);
    SDOHelper.Write(oInvoiceItem, "UNIT_PRICE", (Double)20);
    SDOHelper.Write(oInvoiceItem, "NET_AMOUNT", (Double)200);
    SDOHelper.Write(oInvoiceItem, "FULL_NET_AMOUNT", (Double)200);
    SDOHelper.Write(oInvoiceItem, "COMMENT_1", (String)"Comment 1");
    SDOHelper.Write(oInvoiceItem, "COMMENT_2", (String)"Comment 2");
    SDOHelper.Write(oInvoiceItem, "UNIT_OF_SALE", (String)"");
    SDOHelper.Write(oInvoiceItem, "TAX_RATE", (Double)20);
    SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)1);

    //Update the invoice
    if (oInvoicePost.Update())
    {
        MessageBox.Show("Invoice Posted Successfully");
    }
    else
    {
        MessageBox.Show("Invoice Post Unsuccessful");
    }

    //Disconnect
    oWS.Disconnect();
}
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}

}


Sage 50 Accounts - Example - Posting a 'Mix and Match' Credit Note

Example - Posting a 'Mix and Match' Credit Note

The example code below demonstrates how to post a 'Mix and Match' Credit Note.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oInvoicePost As SageDataObject300.InvoicePost
Dim oInvoiceItem As SageDataObject300.InvoiceItem
Dim oSalesRecord As SageDataObject300.SalesRecord
Dim oStockRecord As SageDataObject300.StockRecord

' Declare Variables
Dim szDataPath As String

' Create the SDO Engine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company.  The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

    ' Try To Connect - Will throw an exception if it fails
    If oWS.Connect(szDataPath, "", "", "Example") Then

        ' Create an instance of InvoicePost & Record Objects
        oSalesRecord = oWS.CreateObject("SalesRecord")
        oInvoicePost = oWS.CreateObject("InvoicePost")
        oStockRecord = oWS.CreateObject("StockRecord")

        ' Set the type of invoice for the next available number
        oInvoicePost.Type = SageDataObject300.LedgerType.sdoLedgerCredit

        ' Read the First Customer & Populate Invoice Fields
        oSalesRecord.MoveFirst()

        oInvoicePost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
        oInvoicePost.Header("NAME").Value = CStr(oSalesRecord.Fields.Item("NAME").Value)
        oInvoicePost.Header("ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_1").Value)
        oInvoicePost.Header("ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_2").Value)
        oInvoicePost.Header("ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_3").Value)
        oInvoicePost.Header("ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_4").Value)
        oInvoicePost.Header("ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_5").Value)
        oInvoicePost.Header("DEL_ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_1").Value)
        oInvoicePost.Header("DEL_ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_2").Value)
        oInvoicePost.Header("DEL_ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_3").Value)
        oInvoicePost.Header("DEL_ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_4").Value)
        oInvoicePost.Header("DEL_ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_5").Value)
        oInvoicePost.Header("CUST_TEL_NUMBER").Value = CStr(oSalesRecord.Fields.Item("Telephone").Value)
        oInvoicePost.Header("CONTACT_NAME").Value = CStr(oSalesRecord.Fields.Item("CONTACT_NAME").Value)
        oInvoicePost.Header("GLOBAL_TAX_CODE").Value = CShort(oSalesRecord.Fields.Item("DEF_TAX_CODE").Value)

        ' Populate other Invoice Header Information
        oInvoicePost.Header("INVOICE_DATE").Value = CDate(Today)
        oInvoicePost.Header("NOTES_1").Value = CStr("")
        oInvoicePost.Header("NOTES_2").Value = CStr("")
        oInvoicePost.Header("NOTES_3").Value = CStr("")
        oInvoicePost.Header("TAKEN_BY").Value = CStr("")
        oInvoicePost.Header("ORDER_NUMBER").Value = CStr("")
        oInvoicePost.Header("CUST_ORDER_NUMBER").Value = CStr("")
        oInvoicePost.Header("PAYMENT_REF").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.
        oInvoicePost.Header("GLOBAL_NOM_CODE").Value = CStr("")
        oInvoicePost.Header("GLOBAL_DETAILS").Value = CStr("")
        oInvoicePost.Header("INVOICE_TYPE_CODE").Value = CByte(SageDataObject300.InvoiceType.sdoProductCredit)
        oInvoicePost.Header("ITEMS_NET").Value = CDbl(500)
        oInvoicePost.Header("ITEMS_TAX").Value = CDbl(52.5)

        ' Create an Invoice Item
        oInvoiceItem = oInvoicePost.Items.Add()

        ' Read the First Stock Code & populate fields from Stock Code
        oStockRecord.MoveFirst()
        oInvoiceItem.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
        oInvoiceItem.Fields.Item("DESCRIPTION").Value = CStr(oStockRecord.Fields.Item("DESCRIPTION").Value)
        oInvoiceItem.Fields.Item("NOMINAL_CODE").Value = CStr(oStockRecord.Fields.Item("NOMINAL_CODE").Value)
        oInvoiceItem.Fields.Item("TAX_CODE").Value = CShort(oStockRecord.Fields.Item("TAX_CODE").Value)

        ' Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
        ' regardless of the Tax_Flag being set to 1***
        oInvoiceItem.Fields.Item("QTY_ORDER").Value = CDbl(2)
        oInvoiceItem.Fields.Item("UNIT_PRICE").Value = CDbl(50)
        oInvoiceItem.Fields.Item("NET_AMOUNT").Value = CDbl(100)
        oInvoiceItem.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(100)
        oInvoiceItem.Fields.Item("COMMENT_1").Value = CStr("")
        oInvoiceItem.Fields.Item("COMMENT_2").Value = CStr("")
        oInvoiceItem.Fields.Item("UNIT_OF_SALE").Value = CStr("")
        oInvoiceItem.Fields.Item("TAX_RATE").Value = CDbl(20)
        oInvoiceItem.Fields.Item("TAX_CODE").Value = CInt(1)

        ' Create Another Invoice Item
        oInvoiceItem = oInvoicePost.Items.Add()

        ' Read the Next Stock Code & populate fields from Stock Code
        oStockRecord.MoveNext()
        oInvoiceItem.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
        oInvoiceItem.Fields.Item("DESCRIPTION").Value = CStr(oStockRecord.Fields.Item("DESCRIPTION").Value)
        oInvoiceItem.Fields.Item("NOMINAL_CODE").Value = CStr(oStockRecord.Fields.Item("NOMINAL_CODE").Value)
        oInvoiceItem.Fields.Item("TAX_CODE").Value = CShort(oStockRecord.Fields.Item("TAX_CODE").Value)

        ' Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
        ' regardless of the Tax_Flag being set to 1***
        oInvoiceItem.Fields.Item("QTY_ORDER").Value = CDbl(1)
        oInvoiceItem.Fields.Item("UNIT_PRICE").Value = CDbl(200)
        oInvoiceItem.Fields.Item("NET_AMOUNT").Value = CDbl(200)
        oInvoiceItem.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(200)
        oInvoiceItem.Fields.Item("COMMENT_1").Value = CStr("")
        oInvoiceItem.Fields.Item("COMMENT_2").Value = CStr("")
        oInvoiceItem.Fields.Item("UNIT_OF_SALE").Value = CStr("")
        oInvoiceItem.Fields.Item("TAX_RATE").Value = CDbl(20)
        oInvoiceItem.Fields.Item("TAX_CODE").Value = CInt(1)

        ' Create a Third Invoice Item - This one is the Service Item
        oInvoiceItem = oInvoicePost.Items.Add()

        ' Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
        ' regardless of the Tax_Flag being set to 1***
        oInvoiceItem.Fields.Item("SERVICE_FLAG").Value = CByte(SageDataObject300.InvoiceItemType.sdoItemQtyService)
        oInvoiceItem.Fields.Item("STOCK_CODE").Value = CStr("S3")
        oInvoiceItem.Fields.Item("DESCRIPTION").Value = CStr("Service Item")
        oInvoiceItem.Text = CStr("Service Item on Product Invoice")
        oInvoiceItem.Fields.Item("NOMINAL_CODE").Value = CStr("4000")
        oInvoiceItem.Fields.Item("TAX_CODE").Value = CShort(1)
        oInvoiceItem.Fields.Item("QTY_ORDER").Value = CDbl(10)
        oInvoiceItem.Fields.Item("UNIT_PRICE").Value = CDbl(20)
        oInvoiceItem.Fields.Item("NET_AMOUNT").Value = CDbl(200)
        oInvoiceItem.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(200)
        oInvoiceItem.Fields.Item("COMMENT_1").Value = CStr("")
        oInvoiceItem.Fields.Item("COMMENT_2").Value = CStr("")
        oInvoiceItem.Fields.Item("UNIT_OF_SALE").Value = CStr("")
        oInvoiceItem.Fields.Item("TAX_RATE").Value = CDbl(20)
        oInvoiceItem.Fields.Item("TAX_CODE").Value = CInt(1)

        ' Update the Invoice
        If oInvoicePost.Update Then

            MsgBox("Invoice Posted Successfully", MsgBoxStyle.OkOnly, "SDO Examples")

        Else

            MsgBox("Invoice Post Unsuccessful", MsgBoxStyle.OkOnly, "SDO Examples")

        End If

        ' Disconnect
        oWS.Disconnect()

    End If

End If

' Destroy Objects
oInvoicePost = Nothing
oInvoiceItem = Nothing
oSalesRecord = Nothing
oStockRecord = Nothing
oWS = Nothing
oSDO = Nothing

Exit Sub
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
String szDataPath;

    //Instantiate WorkSpace
    oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

    //Show select company dialog
    szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

    //Try a connection, will throw an exception if it fails
    try
    {
        //Leaving the username and password blank generates a login dialog
        oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

    }
    catch (Exception ex)
    {
        MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
    }

    // Declare required objects
    SageDataObject300.InvoicePost oInvoicePost;
    SageDataObject300.InvoiceItem oInvoiceItem;
    SageDataObject300.SalesRecord oSalesRecord;
    SageDataObject300.StockRecord oStockRecord;

    try
    {
        // Instantiate objects
        oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");
        oInvoicePost = (SageDataObject300.InvoicePost)oWS.CreateObject("InvoicePost");
        oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");

        // Set the type of the invoice so that we can find the next available number
        oInvoicePost.Type = (SageDataObject300.InvoiceType)SageDataObject300.LedgerType.sdoLedgerCredit;

        // Read the first customer and populate invoice header fields
        oSalesRecord.MoveFirst();

        SDOHelper.Write(oInvoicePost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));
        SDOHelper.Write(oInvoicePost.Header, "NAME", (String)SDOHelper.Read(oSalesRecord, "NAME"));
        SDOHelper.Write(oInvoicePost.Header, "ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_1"));
        SDOHelper.Write(oInvoicePost.Header, "ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_2"));
        SDOHelper.Write(oInvoicePost.Header, "ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_3"));
        SDOHelper.Write(oInvoicePost.Header, "ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_4"));
        SDOHelper.Write(oInvoicePost.Header, "ADDRESS_5", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_5"));
        SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_1"));
        SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_2"));
        SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_3"));
        SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_4"));
        SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_5", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_5"));
        SDOHelper.Write(oInvoicePost.Header, "CUST_TEL_NUMBER", (String)SDOHelper.Read(oSalesRecord, "TELEPHONE"));
        SDOHelper.Write(oInvoicePost.Header, "CONTACT_NAME", (String)"Chris Reed");
        SDOHelper.Write(oInvoicePost.Header, "GLOBAL_TAX_CODE", (Int16)SDOHelper.Read(oSalesRecord, "DEF_TAX_CODE"));

        // Populate other header information
        SDOHelper.Write(oInvoicePost.Header, "INVOICE_DATE", (DateTime)DateTime.Today);
        SDOHelper.Write(oInvoicePost.Header, "NOTES_1", (String)"Notes 1");
        SDOHelper.Write(oInvoicePost.Header, "NOTES_2", (String)"Notes 2");
        SDOHelper.Write(oInvoicePost.Header, "NOTES_3", (String)"Notes 3");
        SDOHelper.Write(oInvoicePost.Header, "TAKEN_BY", (String)"SDO");
        SDOHelper.Write(oInvoicePost.Header, "ORDER_NUMBER", (String)"");
        SDOHelper.Write(oInvoicePost.Header, "CUST_ORDER_NUMBER", (String)"");
        SDOHelper.Write(oInvoicePost.Header, "PAYMENT_REF", (String)"");
        // If anything is entered in the GLOBAL_NOM_CODE, all of the updated invoice’s splits will have this
        // nominal code and also this willforce anything entered in the GLOBAL_DETAILS field into the all
        // the splits details field.
        SDOHelper.Write(oInvoicePost.Header, "GLOBAL_NOM_CODE", (String)"");
        SDOHelper.Write(oInvoicePost.Header, "GLOBAL_DETAILS", (String)"");
        SDOHelper.Write(oInvoicePost.Header, "INVOICE_TYPE_CODE", (Byte)SageDataObject300.InvoiceType.sdoProductCredit);

        // Create an invoice item
        oInvoiceItem = (SageDataObject300.InvoiceItem)SDOHelper.Add(oInvoicePost.Items);

        // Read the first stock code & populate the fields
        oStockRecord.MoveFirst();

        SDOHelper.Write(oInvoiceItem, "STOCK_CODE", (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));
        SDOHelper.Write(oInvoiceItem, "DESCRIPTION", (String)SDOHelper.Read(oStockRecord, "DESCRIPTION"));
        SDOHelper.Write(oInvoiceItem, "NOMINAL_CODE", (String)SDOHelper.Read(oStockRecord, "NOMINAL_CODE"));
        SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)SDOHelper.Read(oStockRecord, "TAX_CODE"));

        //Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
        //regardless of the Tax_Flag being set to 1***
        SDOHelper.Write(oInvoiceItem, "QTY_ORDER", (Double)2);
        SDOHelper.Write(oInvoiceItem, "UNIT_PRICE", (Double)50);
        SDOHelper.Write(oInvoiceItem, "NET_AMOUNT", (Double)100);
        SDOHelper.Write(oInvoiceItem, "FULL_NET_AMOUNT", (Double)100);
        SDOHelper.Write(oInvoiceItem, "COMMENT_1", (String)"Comment 1");
        SDOHelper.Write(oInvoiceItem, "COMMENT_2", (String)"Comment 2");
        SDOHelper.Write(oInvoiceItem, "UNIT_OF_SALE", (String)"");
        SDOHelper.Write(oInvoiceItem, "TAX_RATE", (Double)20);
        SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)1);

        // Create another invoice item
        oInvoiceItem = (SageDataObject300.InvoiceItem)SDOHelper.Add(oInvoicePost.Items);

        // Read the next stock code & populate the fields
        oStockRecord.MoveNext();

        SDOHelper.Write(oInvoiceItem, "STOCK_CODE", (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));
        SDOHelper.Write(oInvoiceItem, "DESCRIPTION", (String)SDOHelper.Read(oStockRecord, "DESCRIPTION"));
        SDOHelper.Write(oInvoiceItem, "NOMINAL_CODE", (String)SDOHelper.Read(oStockRecord, "NOMINAL_CODE"));
        SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)SDOHelper.Read(oStockRecord, "TAX_CODE"));

        //Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
        //regardless of the Tax_Flag being set to 1***
        SDOHelper.Write(oInvoiceItem, "QTY_ORDER", (Double)2);
        SDOHelper.Write(oInvoiceItem, "UNIT_PRICE", (Double)50);
        SDOHelper.Write(oInvoiceItem, "NET_AMOUNT", (Double)100);
        SDOHelper.Write(oInvoiceItem, "FULL_NET_AMOUNT", (Double)100);
        SDOHelper.Write(oInvoiceItem, "COMMENT_1", (String)"Comment 1");
        SDOHelper.Write(oInvoiceItem, "COMMENT_2", (String)"Comment 2");
        SDOHelper.Write(oInvoiceItem, "UNIT_OF_SALE", (String)"");
        SDOHelper.Write(oInvoiceItem, "TAX_RATE", (Double)20);
        SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)1);

        // Create a third invoice item - This one is the service item
        oInvoiceItem = (SageDataObject300.InvoiceItem)SDOHelper.Add(oInvoicePost.Items);

        //Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
        //regardless of the Tax_Flag being set to 1***
        SDOHelper.Write(oInvoiceItem, "SERVICE_FLAG", (Byte)SageDataObject300.InvoiceItemType.sdoItemQtyService);
        SDOHelper.Write(oInvoiceItem, "STOCK_CODE", (String)"S3");
        SDOHelper.Write(oInvoiceItem, "DESCRIPTION", (String)"Service Item");
        oInvoiceItem.Text = (String)"Service Item on Product Invoice";
        SDOHelper.Write(oInvoiceItem, "NOMINAL_CODE", (String)"4000");
        SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)1);
        SDOHelper.Write(oInvoiceItem, "QTY_ORDER", (Double)10);
        SDOHelper.Write(oInvoiceItem, "UNIT_PRICE", (Double)20);
        SDOHelper.Write(oInvoiceItem, "NET_AMOUNT", (Double)200);
        SDOHelper.Write(oInvoiceItem, "FULL_NET_AMOUNT", (Double)200);
        SDOHelper.Write(oInvoiceItem, "COMMENT_1", (String)"Comment 1");
        SDOHelper.Write(oInvoiceItem, "COMMENT_2", (String)"Comment 2");
        SDOHelper.Write(oInvoiceItem, "UNIT_OF_SALE", (String)"");
        SDOHelper.Write(oInvoiceItem, "TAX_RATE", (Double)20);
        SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)1);

        // Update the credit
        if (oInvoicePost.Update())
        {
            MessageBox.Show("Invoice Posted Successfully");
        }
        else
        {
            MessageBox.Show("Invoice Post Unsuccessful");
        }

        // Disconnect
        oWS.Disconnect();
    }
    catch (Exception ex)
    {
        // Show the exception error message
        MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }


Sage 50 Accounts - Example - Posting a Foreign Currency Product Invoice

Example - Posting a Foreign Currency Product Invoice

The example code below demonstrates how to post a Foreign Currency Product Invoice.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oInvoicePost As SageDataObject300.InvoicePost
Dim oInvoiceItem As SageDataObject300.InvoiceItem
Dim oSalesRecord As SageDataObject300.SalesRecord
Dim oStockRecord As SageDataObject300.StockRecord
Dim oCurrencyData As SageDataObject300.CurrencyData

' Declare Variables
Dim szDataPath As String
Dim iCtr As Short

' Create the SDO Engine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' SelectCompany.  The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

    ' Connect to Data Files - Will throw an exception if it fails
    If oWS.Connect(szDataPath, "", "", "Example") Then

        ' Create an instance of the Objects
        oSalesRecord = oWS.CreateObject("SalesRecord")
        oInvoicePost = oWS.CreateObject("InvoicePost")
        oStockRecord = oWS.CreateObject("StockRecord")
        oCurrencyData = oWS.CreateObject("CurrencyData")

        ' Set the type of invoice for the next available number
        oInvoicePost.Type = SageDataObject300.LedgerType.sdoLedgerInvoice

        ' Read the First Customer
        oSalesRecord.MoveFirst()

        ' Read the Currency File
        oCurrencyData.Read(Convert.ToByte(oSalesRecord.Fields.Item("CURRENCY").Value) + 1)

        ' Populate Invoice Header Fields
        oInvoicePost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
        oInvoicePost.Header("NAME").Value = CStr(oSalesRecord.Fields.Item("NAME").Value)
        oInvoicePost.Header("ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_1").Value)
        oInvoicePost.Header("ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_2").Value)
        oInvoicePost.Header("ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_3").Value)
        oInvoicePost.Header("ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_4").Value)
        oInvoicePost.Header("ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_5").Value)
        oInvoicePost.Header("DEL_ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_1").Value)
        oInvoicePost.Header("DEL_ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_2").Value)
        oInvoicePost.Header("DEL_ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_3").Value)
        oInvoicePost.Header("DEL_ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_4").Value)
        oInvoicePost.Header("DEL_ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_5").Value)
        oInvoicePost.Header("CUST_TEL_NUMBER").Value = CStr(oSalesRecord.Fields.Item("TELEPHONE").Value)
        oInvoicePost.Header("CONTACT_NAME").Value = CStr(oSalesRecord.Fields.Item("CONTACT_NAME").Value)
        oInvoicePost.Header("GLOBAL_TAX_CODE").Value = CShort(oSalesRecord.Fields.Item("DEF_TAX_CODE").Value)

        ' Populate other Invoice Header Information
        oInvoicePost.Header("INVOICE_DATE").Value = CDate(Today)
        oInvoicePost.Header("NOTES_1").Value = CStr("")
        oInvoicePost.Header("NOTES_2").Value = CStr("")
        oInvoicePost.Header("NOTES_3").Value = CStr("")
        oInvoicePost.Header("TAKEN_BY").Value = CStr("Mark Steel")
        oInvoicePost.Header("ORDER_NUMBER").Value = CStr("")
        oInvoicePost.Header("CUST_ORDER_NUMBER").Value = CStr("")
        oInvoicePost.Header("PAYMENT_REF").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.
        oInvoicePost.Header("GLOBAL_NOM_CODE").Value = CStr("")
        oInvoicePost.Header("GLOBAL_DETAILS").Value = CStr("")
        oInvoicePost.Header("INVOICE_TYPE_CODE").Value = CByte(SageDataObject300.InvoiceType.sdoProductInvoice)

        ' Populate Foreign Currency Fields
        oInvoicePost.Header("FOREIGN_RATE").Value = CDbl(oCurrencyData.Fields.Item("EXCHANGE_RATE").Value)
        oInvoicePost.Header("CURRENCY").Value = oSalesRecord.Fields.Item("CURRENCY").Value
        oInvoicePost.Header("CURRENCY_USED").Value = oSalesRecord.Fields.Item("CURRENCY").Value

        ' Create an Invoice Item
        oInvoiceItem = oInvoicePost.Items.Add()

        ' Read the First Stock Code & populate fields from Stock Code
        oStockRecord.MoveFirst()
        oInvoiceItem.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
        oInvoiceItem.Fields.Item("DESCRIPTION").Value = CStr(oStockRecord.Fields.Item("DESCRIPTION").Value)
        oInvoiceItem.Fields.Item("NOMINAL_CODE").Value = CStr(oStockRecord.Fields.Item("NOMINAL_CODE").Value)
        oInvoiceItem.Fields.Item("TAX_CODE").Value = CInt(oStockRecord.Fields.Item("TAX_CODE").Value)

        ' Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
        ' regardless of the Tax_Flag being set to 1***
        oInvoiceItem.Fields.Item("QTY_ORDER").Value = CDbl(2)
        oInvoiceItem.Fields.Item("UNIT_PRICE").Value = CDbl(50)
        oInvoiceItem.Fields.Item("NET_AMOUNT").Value = CDbl(100)
        oInvoiceItem.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(100)
        oInvoiceItem.Fields.Item("COMMENT_1").Value = CStr("")
        oInvoiceItem.Fields.Item("COMMENT_2").Value = CStr("")
        oInvoiceItem.Fields.Item("UNIT_OF_SALE").Value = CStr("")
        oInvoiceItem.Fields.Item("TAX_RATE").Value = CDbl(0)
        oInvoiceItem.Fields.Item("TAX_CODE").Value = CInt(0)

        ' Create Another Invoice Item
        oInvoiceItem = oInvoicePost.Items.Add()

        ' Read the Next Stock Code & populate fields from Stock Code
        oStockRecord.MoveNext()
        oInvoiceItem.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
        oInvoiceItem.Fields.Item("DESCRIPTION").Value = CStr(oStockRecord.Fields.Item("DESCRIPTION").Value)
        oInvoiceItem.Fields.Item("NOMINAL_CODE").Value = CStr(oStockRecord.Fields.Item("NOMINAL_CODE").Value)
        oInvoiceItem.Fields.Item("TAX_CODE").Value = CShort(oStockRecord.Fields.Item("TAX_CODE").Value)

        ' Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
        ' regardless of the Tax_Flag being set to 1***
        oInvoiceItem.Fields.Item("QTY_ORDER").Value = CDbl(1)
        oInvoiceItem.Fields.Item("UNIT_PRICE").Value = CDbl(200)
        oInvoiceItem.Fields.Item("NET_AMOUNT").Value = CDbl(200)
        oInvoiceItem.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(200)
        oInvoiceItem.Fields.Item("COMMENT_1").Value = CStr("")
        oInvoiceItem.Fields.Item("COMMENT_2").Value = CStr("")
        oInvoiceItem.Fields.Item("UNIT_OF_SALE").Value = CStr("")
        oInvoiceItem.Fields.Item("TAX_RATE").Value = CDbl(0)
        oInvoiceItem.Fields.Item("TAX_CODE").Value = CInt(0)

        ' Update the Invoice
        If oInvoicePost.Update Then

            MsgBox("Invoice Posted Successfully", MsgBoxStyle.OkOnly, "SDO Examples")

        Else

            MsgBox("Failed to create Invoice", MsgBoxStyle.OkOnly, "SDO Examples")

        End If

        ' Disconnect
        oWS.Disconnect()

    End If

End If

' Destroy Objects
oCurrencyData = Nothing
oInvoicePost = Nothing
oInvoiceItem = Nothing
oSalesRecord = Nothing
oStockRecord = Nothing
oWS = Nothing
oSDO = Nothing

Exit Sub
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
String szDataPath;

    //Instantiate WorkSpace
    oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

    //Show select company dialog
    szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

    //Try a connection, will throw an exception if it fails
    try
    {
        //Leaving the username and password blank generates a login dialog
        oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

    }
    catch (Exception ex)
    {
        MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
    }

    // Declare required objects
    SageDataObject300.InvoicePost oInvoicePost;
    SageDataObject300.InvoiceItem oInvoiceItem;
    SageDataObject300.SalesRecord oSalesRecord;
    SageDataObject300.StockRecord oStockRecord;
    SageDataObject300.CurrencyData oCurrencyData;

    try
    {
        // Instantiate objects
        oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");
        oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");
        oInvoicePost = (SageDataObject300.InvoicePost)oWS.CreateObject("InvoicePost");
        oCurrencyData = (SageDataObject300.CurrencyData)oWS.CreateObject("CurrencyData");

        //Set the invoice type
        oInvoicePost.Type = (SageDataObject300.InvoiceType)SageDataObject300.LedgerType.sdoLedgerInvoice;

        // Read the first Customer record
        oSalesRecord.MoveFirst();

        // Read the currency file
        oCurrencyData.Read(Convert.ToByte(SDOHelper.Read(oSalesRecord, "CURRENCY")) + 1);

        //Populate Invoice Header Fields
        SDOHelper.Write(oInvoicePost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));
        SDOHelper.Write(oInvoicePost.Header, "NAME", (String)SDOHelper.Read(oSalesRecord, "NAME"));
        SDOHelper.Write(oInvoicePost.Header, "ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_1"));
        SDOHelper.Write(oInvoicePost.Header, "ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_2"));
        SDOHelper.Write(oInvoicePost.Header, "ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_3"));
        SDOHelper.Write(oInvoicePost.Header, "ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_4"));
        SDOHelper.Write(oInvoicePost.Header, "ADDRESS_5", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_5"));
        SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_1"));
        SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_2"));
        SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_3"));
        SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_4"));
        SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_5", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_5"));
        SDOHelper.Write(oInvoicePost.Header, "CUST_TEL_NUMBER", (String)SDOHelper.Read(oSalesRecord, "TELEPHONE"));
        SDOHelper.Write(oInvoicePost.Header, "CONTACT_NAME", (String)SDOHelper.Read(oSalesRecord, "CONTACT_NAME"));
        SDOHelper.Write(oInvoicePost.Header, "GLOBAL_TAX_CODE", (Int16)SDOHelper.Read(oSalesRecord, "DEF_TAX_CODE"));

        // Populate other header information
        SDOHelper.Write(oInvoicePost.Header, "INVOICE_DATE", (DateTime)DateTime.Today);
        SDOHelper.Write(oInvoicePost.Header, "NOTES_1", (String)"");
        SDOHelper.Write(oInvoicePost.Header, "NOTES_2", (String)"");
        SDOHelper.Write(oInvoicePost.Header, "NOTES_3", (String)"");
        SDOHelper.Write(oInvoicePost.Header, "TAKEN_BY", (String)"John Smith");
        SDOHelper.Write(oInvoicePost.Header, "CUST_ORDER_NUMBER", (String)"");
        // If anything is entered in the GLOBAL_NOM_CODE, all of the updated invoice’s splits will have this
        // nominal code and also this willforce anything entered in the GLOBAL_DETAILS field into the all
        // the splits details field.
        SDOHelper.Write(oInvoicePost.Header, "GLOBAL_NOM_CODE", (String)"");
        SDOHelper.Write(oInvoicePost.Header, "GLOBAL_DETAILS", (String)"");
        SDOHelper.Write(oInvoicePost.Header, "INVOICE_TYPE_CODE", (Byte)SageDataObject300.InvoiceType.sdoProductInvoice);

        // Populate Foreign Currency Fields
        SDOHelper.Write(oInvoicePost.Header, "FOREIGN_RATE", SDOHelper.Read(oCurrencyData, "EXCHANGE_RATE"));
        SDOHelper.Write(oInvoicePost.Header, "CURRENCY", SDOHelper.Read(oSalesRecord, "CURRENCY"));
        SDOHelper.Write(oInvoicePost.Header, "CURRENCY_USED", SDOHelper.Read(oSalesRecord, "CURRENCY"));

        // Create an Invoice Item
        oInvoiceItem = (SageDataObject300.InvoiceItem)SDOHelper.Add(oInvoicePost.Items);

        // Read the fist stock code and populate item fields
        oStockRecord.MoveFirst();

        //Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
        //regardless of the Tax_Flag being set to 1***
        SDOHelper.Write(oInvoiceItem, "STOCK_CODE", SDOHelper.Read(oStockRecord, "STOCK_CODE"));
        SDOHelper.Write(oInvoiceItem, "DESCRIPTION", SDOHelper.Read(oStockRecord, "DESCRIPTION"));
        SDOHelper.Write(oInvoiceItem, "TAX_CODE", SDOHelper.Read(oStockRecord, "TAX_CODE"));
        SDOHelper.Write(oInvoiceItem, "NOMINAL_CODE", SDOHelper.Read(oStockRecord, "NOMINAL_CODE"));
        SDOHelper.Write(oInvoiceItem, "QTY_ORDER", (Double)2);
        SDOHelper.Write(oInvoiceItem, "UNIT_PRICE", (Double)100);
        SDOHelper.Write(oInvoiceItem, "NET_AMOUNT", (Double)100);
        SDOHelper.Write(oInvoiceItem, "FULL_NET_AMOUNT", (Double)100);
        SDOHelper.Write(oInvoiceItem, "COMMENT_1", (String)"");
        SDOHelper.Write(oInvoiceItem, "COMMENT_2", (String)"");
        SDOHelper.Write(oInvoiceItem, "UNIT_OF_SALE", (String)"");
        SDOHelper.Write(oInvoiceItem, "TAX_RATE", (Double)17.5);

        // Update the Invoice
        if (oInvoicePost.Update())
        {
            MessageBox.Show("Invoice Created Successfully");
        }
        else
        {
            MessageBox.Show("Invoice Not Created");
        }

        //Disconnect
        oWS.Disconnect();
    }
    catch (Exception ex)
    {
        // Show the exception error message
        MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }


Sage 50 Accounts - Example - Item Line Discount

Example - Item Line Discount

The example code below demonstrates how to post a Product Invoice with Item Line Discount.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oInvoicePost As SageDataObject300.InvoicePost
Dim oInvoiceItem As SageDataObject300.InvoiceItem
Dim oSalesRecord As SageDataObject300.SalesRecord
Dim oStockRecord As SageDataObject300.StockRecord

' Declare Variables
Dim szDataPath As String
Dim dTotDiscPerc As Double
Dim dDiscvalue As Double

' Create the SDO Engine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' SelectCompany.  The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

    ' Connect to Data Files - Will throw an exception if it fails
    If oWS.Connect(szDataPath, "", "", "Example") Then

        ' Create an instance of the Objects
        oSalesRecord = oWS.CreateObject("SalesRecord")
        oInvoicePost = oWS.CreateObject("InvoicePost")
        oStockRecord = oWS.CreateObject("StockRecord")

        ' Set the type of invoice for the next available number
        oInvoicePost.Type = SageDataObject300.LedgerType.sdoLedgerInvoice

        ' Read the First Customer & populate Invoice Fields
        oSalesRecord.MoveFirst()

        oInvoicePost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
        oInvoicePost.Header("NAME").Value = CStr(oSalesRecord.Fields.Item("NAME").Value)
        oInvoicePost.Header("ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_1").Value)
        oInvoicePost.Header("ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_2").Value)
        oInvoicePost.Header("ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_3").Value)
        oInvoicePost.Header("ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_4").Value)
        oInvoicePost.Header("ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_5").Value)
        oInvoicePost.Header("DEL_ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_1").Value)
        oInvoicePost.Header("DEL_ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_2").Value)
        oInvoicePost.Header("DEL_ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_3").Value)
        oInvoicePost.Header("DEL_ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_4").Value)
        oInvoicePost.Header("DEL_ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_5").Value)
        oInvoicePost.Header("CUST_TEL_NUMBER").Value = CStr(oSalesRecord.Fields.Item("TELEPHONE").Value)
        oInvoicePost.Header("CONTACT_NAME").Value = CStr(oSalesRecord.Fields.Item("CONTACT_NAME").Value)
        oInvoicePost.Header("GLOBAL_TAX_CODE").Value = CShort(oSalesRecord.Fields.Item("DEF_TAX_CODE").Value)

        ' Populate other Invoice Header Information
        oInvoicePost.Header("INVOICE_DATE").Value = CDate(Today)
        oInvoicePost.Header("NOTES_1").Value = CStr("")
        oInvoicePost.Header("NOTES_2").Value = CStr("")
        oInvoicePost.Header("NOTES_3").Value = CStr("")
        oInvoicePost.Header("TAKEN_BY").Value = CStr("Mark Steel")
        oInvoicePost.Header("ORDER_NUMBER").Value = CStr("")
        oInvoicePost.Header("CUST_ORDER_NUMBER").Value = CStr("")
        oInvoicePost.Header("PAYMENT_REF").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.
        oInvoicePost.Header("GLOBAL_NOM_CODE").Value = CStr("")
        oInvoicePost.Header("GLOBAL_DETAILS").Value = CStr("")
        oInvoicePost.Header("INVOICE_TYPE_CODE").Value = CByte(SageDataObject300.InvoiceType.sdoProductInvoice)

        ' Create an Invoice Item
        oInvoiceItem = oInvoicePost.Items.Add()

        ' Read the First Stock Code & populate fields from Stock Code
        oStockRecord.MoveFirst()
        oInvoiceItem.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
        oInvoiceItem.Fields.Item("DESCRIPTION").Value = CStr(oStockRecord.Fields.Item("DESCRIPTION").Value)
        oInvoiceItem.Fields.Item("NOMINAL_CODE").Value = CStr(oStockRecord.Fields.Item("NOMINAL_CODE").Value)
        oInvoiceItem.Fields.Item("TAX_CODE").Value = CInt(oStockRecord.Fields.Item("TAX_CODE").Value)

        '2015 also sees a change in how we set item line discounts
        'Set the variable that holds the full item line discount percentage.
        dTotDiscPerc = CDbl(30)
        'We no longer need to set the Discount_Rate field as this is populated if a discount exists.
        'Additional discount rate is set using dTotDiscPerc - Discount_Rate
        'Note the Discount_Rate is taken from the SalesRecord
        oInvoiceItem.Fields.Item("ADD_DISC_RATE").Value = CDbl(dTotDiscPerc - oSalesRecord.Fields.Item("DISCOUNT_RATE").Value)
        'DISCOUNT_AMOUNT is the full percentage discount of the item line
        'DISCOUNT_RATE + ADD_DISC_RATE. DISCOUNT RATE SHOULD NO LONGER BE SET!
        oInvoiceItem.Fields.Item("DISCOUNT_AMOUNT").Value = CDbl(dTotDiscPerc)

        ' Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
        ' regardless of the Tax_Flag being set to 1***
        oInvoiceItem.Fields.Item("QTY_ORDER").Value = CDbl(1)
        oInvoiceItem.Fields.Item("UNIT_PRICE").Value = CDbl(45.687565)

        'We need to set the FULL_NET_AMOUNT and NET_AMOUNT
        oInvoiceItem.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(oInvoiceItem.Fields.Item("QTY_ORDER").Value * oInvoiceItem.Fields.Item("UNIT_PRICE").Value)
        'We need to calculate the dDiscValue so we can calculate the Net_Amount
        dDiscvalue = CDbl((oInvoiceItem.Fields.Item("FULL_NET_AMOUNT").Value / 100) * dTotDiscPerc)
        oInvoiceItem.Fields.Item("NET_AMOUNT").Value = oInvoiceItem.Fields.Item("FULL_NET_AMOUNT").Value - dDiscvalue
        oInvoiceItem.Fields.Item("TAX_RATE").Value = CDbl(20)
        oInvoiceItem.Fields.Item("TAX_CODE").Value = CInt(1)
        'We have chosen to let the new program logic calculate the TAX_AMOUNT by not setting the TAX_FLAG
        'oInvoiceItem.Fields.Item("TAX_AMOUNT").Value = CDbl((oInvoiceItem.Fields.Item("NET_AMOUNT").Value * oInvoiceItem.Fields.Item("TAX_RATE").Value) / 100)
        oInvoiceItem.Fields.Item("COMMENT_1").Value = CStr("")
        oInvoiceItem.Fields.Item("COMMENT_2").Value = CStr("")
        oInvoiceItem.Fields.Item("UNIT_OF_SALE").Value = CStr("")
        'If we were calculating the TAX_AMOUNT ourselves we would set the TAX_FLAG to 1
        'as we do not want it to be overwritten by the business logic
        'oInvoiceItem.Fields.Item("TAX_FLAG").Value = CInt(1)

        ' Update the Invoice
        If oInvoicePost.Update Then

            MsgBox("Invoice Posted Successfully", MsgBoxStyle.OkOnly, "SDO Examples")

        Else

            MsgBox("Failed to create Invoice", MsgBoxStyle.OkOnly, "SDO Examples")

        End If

        ' Disconnect
        oWS.Disconnect()

    End If

End If

' Destroy Objects
oInvoicePost = Nothing
oInvoiceItem = Nothing
oSalesRecord = Nothing
oStockRecord = Nothing
oWS = Nothing
oSDO = Nothing

Exit Sub
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.InvoicePost oInvoicePost;
SageDataObject300.InvoiceItem oInvoiceItem;
SageDataObject300.SalesRecord oSalesRecord;
SageDataObject300.StockRecord oStockRecord;
String szDataPath;
Double dTotDiscPerc;
Double dDiscvalue;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails
try
{
    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "Example");

    //Instantiate objects
    oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");
    oInvoicePost = (SageDataObject300.InvoicePost)oWS.CreateObject("InvoicePost");
    oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");

    //Set the invoice type
    oInvoicePost.Type = (SageDataObject300.InvoiceType)SageDataObject300.LedgerType.sdoLedgerInvoice;

    //Read the first customer record and use to populate the invoice fields
    oSalesRecord.MoveFirst();
    SDOHelper.Write(oInvoicePost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));
    SDOHelper.Write(oInvoicePost.Header, "NAME", (String)SDOHelper.Read(oSalesRecord, "NAME"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_1"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_2"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_3"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_4"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_5", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_5"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_1"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_2"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_3"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_4"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_5", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_5"));
    SDOHelper.Write(oInvoicePost.Header, "CUST_TEL_NUMBER", (String)SDOHelper.Read(oSalesRecord, "TELEPHONE"));
    SDOHelper.Write(oInvoicePost.Header, "CONTACT_NAME", (String)SDOHelper.Read(oSalesRecord, "CONTACT_NAME"));
    SDOHelper.Write(oInvoicePost.Header, "GLOBAL_TAX_CODE", (Int16)SDOHelper.Read(oSalesRecord, "DEF_TAX_CODE"));

    //Populate other invoice header information
    SDOHelper.Write(oInvoicePost.Header, "INVOICE_DATE", (DateTime)DateTime.Today);
    SDOHelper.Write(oInvoicePost.Header, "NOTES_1", (String)"Notes 1");
    SDOHelper.Write(oInvoicePost.Header, "NOTES_2", (String)"Notes 2");
    SDOHelper.Write(oInvoicePost.Header, "NOTES_3", (String)"Notes 3");
    SDOHelper.Write(oInvoicePost.Header, "TAKEN_BY", (String)"Chris Reed");
    SDOHelper.Write(oInvoicePost.Header, "ORDER_NUMBER", (String)"");
    SDOHelper.Write(oInvoicePost.Header, "CUST_ORDER_NUMBER", (String)"");
    SDOHelper.Write(oInvoicePost.Header, "PAYMENT_REF", (String)"");
    // If anything is entered in the GLOBAL_NOM_CODE, all of the updated invoice’s splits will have this nominal code and
    // also this willforce anything entered in the GLOBAL_DETAILS field into the all the splits details field.
    SDOHelper.Write(oInvoicePost.Header, "GLOBAL_NOM_CODE", (String)"");
    SDOHelper.Write(oInvoicePost.Header, "GLOBAL_DETAILS", (String)"");
    SDOHelper.Write(oInvoicePost.Header, "INVOICE_TYPE_CODE",
      (Byte)SageDataObject300.InvoiceType.sdoProductInvoice);

    //Create and invoice item
    //Need to invoke the Add method
    oInvoiceItem = (SageDataObject300.InvoiceItem)SDOHelper.Add(oInvoicePost.Items);

    //Read the First Stock Code & populate fields from Stock Code
    oStockRecord.MoveFirst();
    SDOHelper.Write(oInvoiceItem, "STOCK_CODE", (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));
    SDOHelper.Write(oInvoiceItem, "DESCRIPTION", (String)SDOHelper.Read(oStockRecord, "DESCRIPTION"));
    SDOHelper.Write(oInvoiceItem, "NOMINAL_CODE", (String)SDOHelper.Read(oStockRecord, "NOMINAL_CODE"));
    SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)SDOHelper.Read(oStockRecord, "TAX_CODE"));

    //2015 also sees a change in how we set item line discounts
    //Set the variable that holds the full item line discount percentage.
    dTotDiscPerc = (Double)30;
    //We no longer need to set the Discount_Rate field as this is populated if a discount exists.
    //Additional discount rate is set using dTotDiscPerc - Discount_Rate
    //Note the Discount_Rate is taken from the SalesRecord
    SDOHelper.Write(oInvoiceItem, "ADD_DISC_RATE", dTotDiscPerc - (Double)(SDOHelper.Read(oSalesRecord, "DISCOUNT_RATE")));
    //DISCOUNT_AMOUNT is the full percentage discount of the item line
    //DISCOUNT_RATE + ADD_DISC_RATE. DISCOUNT RATE SHOULD NO LONGER BE SET!
    SDOHelper.Write(oInvoiceItem, "DISCOUNT_AMOUNT", (Double)(dTotDiscPerc));

    //Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
    //regardless of the Tax_Flag being set to 1***
    SDOHelper.Write(oInvoiceItem, "QTY_ORDER", (Int32)1);
    SDOHelper.Write(oInvoiceItem, "UNIT_PRICE", (Double)45.687565);
    SDOHelper.Write(oInvoiceItem, "FULL_NET_AMOUNT", (Double)SDOHelper.Read(oInvoiceItem, "QTY_ORDER")* (Double)SDOHelper.Read(oInvoiceItem, "UNIT_PRICE"));
    //We need to calculate the dDiscValue so we can calculate the Net_Amount
    dDiscvalue = (Double)SDOHelper.Read(oInvoiceItem, "FULL_NET_AMOUNT") / 100 * dTotDiscPerc;
    SDOHelper.Write(oInvoiceItem, "NET_AMOUNT", (Double)SDOHelper.Read(oInvoiceItem, "FULL_NET_AMOUNT") - dDiscvalue);
    //We have chosen to let the new program logic calculate the TAX_AMOUNT by not setting the TAX_FLAG
    //SDOHelper.Write(oInvoiceItem, "TAX_FLAG", (Double)20)= (Double)(oInvoiceItem.Fields.Item("NET_AMOUNT").Value * (oInvoiceItem.Fields.Item("TAX_RATE").Value) / 100);
    SDOHelper.Write(oInvoiceItem, "COMMENT_1", (String)"Comment 1");
    SDOHelper.Write(oInvoiceItem, "COMMENT_2", (String)"Comment 2");
    SDOHelper.Write(oInvoiceItem, "UNIT_OF_SALE", (String)"");
    SDOHelper.Write(oInvoiceItem, "TAX_RATE", (Double)20);
    SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int32)1);
    //If we were calculating the TAX_AMOUNT ourselves we would set the TAX_FLAG to 1
    //as we do not want it to be overwritten by the business logic
    //SDOHelper.Write(oInvoiceItem, "TAX_FLAG", (Byte)1);

    //Update the invoice
    if (oInvoicePost.Update())
    {
        MessageBox.Show("Invoice Posted Successfully", "C# SDO Examples");
    }
    else
    {
        MessageBox.Show("Failed to create Invoice", "C# SDO Examples");
    }

    //Disconnect
    oWS.Disconnect();
}
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}


Sage 50 Accounts - Example - Post Invoice with an item that is VAT ammendable

Example - Post Invoice with an item that is VAT ammendable

The example code below demonstrates how to post an Invoice that is item VAT ammendable.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code

                                  ' Declare Objects
Dim oSDO  As
                                SageDataObject300.SDOEngine
Dim oWS  As
                                SageDataObject300.WorkSpace
Dim oInvoicePost  As
                                SageDataObject300.InvoicePost
Dim oInvoiceItem  As
                                SageDataObject300.InvoiceItem
Dim oSalesRecord  As
                                SageDataObject300.SalesRecord
Dim oStockRecord  As
                                SageDataObject300.StockRecord

' Declare Variables
Dim szDataPath  As String
Dim iCtr  As Short

' Create the SDO Engine Object
oSDO =  New   SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' SelectCompany.  The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> ""  Then

' Connect to Data Files - Will throw
                                    an exception if it fails
If oWS.Connect(szDataPath, "", "", "Example")  Then

' Create an instance of the Objects
oSalesRecord = oWS.CreateObject("SalesRecord")
oInvoicePost = oWS.CreateObject("InvoicePost")
oStockRecord = oWS.CreateObject("StockRecord")

' Set the type of invoice for the next available number
oInvoicePost.Type = SageDataObject300.LedgerType.sdoLedgerInvoice

' Read the First Customer & populate Invoice Fields
oSalesRecord.MoveFirst()

oInvoicePost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
oInvoicePost.Header("NAME").Value = CStr(oSalesRecord.Fields.Item("NAME").Value)
oInvoicePost.Header("ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_1").Value)
oInvoicePost.Header("ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_2").Value)
oInvoicePost.Header("ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_3").Value)
oInvoicePost.Header("ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_4").Value)
oInvoicePost.Header("ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_5").Value)
oInvoicePost.Header("DEL_ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_1").Value)
oInvoicePost.Header("DEL_ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_2").Value)
oInvoicePost.Header("DEL_ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_3").Value)
oInvoicePost.Header("DEL_ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_4").Value)
oInvoicePost.Header("DEL_ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_5").Value)
oInvoicePost.Header("CUST_TEL_NUMBER").Value = CStr(oSalesRecord.Fields.Item("TELEPHONE").Value)
oInvoicePost.Header("CONTACT_NAME").Value = CStr(oSalesRecord.Fields.Item("CONTACT_NAME").Value)
oInvoicePost.Header("GLOBAL_TAX_CODE").Value = CShort(oSalesRecord.Fields.Item("DEF_TAX_CODE").Value)

' Populate other Invoice Header Information
oInvoicePost.Header("INVOICE_DATE").Value = CDate(Today)
oInvoicePost.Header("NOTES_1").Value = CStr("")
oInvoicePost.Header("NOTES_2").Value = CStr("")
oInvoicePost.Header("NOTES_3").Value = CStr("")
oInvoicePost.Header("TAKEN_BY").Value = CStr("Mark Steel")
oInvoicePost.Header("ORDER_NUMBER").Value = CStr("")
oInvoicePost.Header("CUST_ORDER_NUMBER").Value = CStr("")
oInvoicePost.Header("PAYMENT_REF").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.
oInvoicePost.Header("GLOBAL_NOM_CODE").Value = CStr("")
oInvoicePost.Header("GLOBAL_DETAILS").Value = CStr("")
oInvoicePost.Header("INVOICE_TYPE_CODE").Value = CByte(SageDataObject300.InvoiceType.sdoProductInvoice)

' Create an Invoice Item
oInvoiceItem = oInvoicePost.Items.Add()

' Read the First Stock Code & populate fields from Stock Code
oStockRecord.MoveFirst()
oInvoiceItem.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
oInvoiceItem.Fields.Item("DESCRIPTION").Value = CStr(oStockRecord.Fields.Item("DESCRIPTION").Value)
oInvoiceItem.Fields.Item("NOMINAL_CODE").Value = CStr(oStockRecord.Fields.Item("NOMINAL_CODE").Value)
oInvoiceItem.Fields.Item("TAX_CODE").Value = CInt(oStockRecord.Fields.Item("TAX_CODE").Value)

' Populate other fields required for Invoice Item
oInvoiceItem.Fields.Item("QTY_ORDER").Value = CDbl(1)
oInvoiceItem.Fields.Item("UNIT_PRICE").Value = CDbl(133.33)
oInvoiceItem.Fields.Item("NET_AMOUNT").Value = CDbl(133.33)
oInvoiceItem.Fields.Item("TAX_AMOUNT").Value = CDbl(26.66)
oInvoiceItem.Fields.Item("COMMENT_1").Value = CStr("")
oInvoiceItem.Fields.Item("COMMENT_2").Value = CStr("")
oInvoiceItem.Fields.Item("UNIT_OF_SALE").Value = CStr("")
oInvoiceItem.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(100)
oInvoiceItem.Fields.Item("TAX_RATE").Value = CDbl(20)
' Ensure the Tax Flag is set if calculating own Tax_Amount value
oInvoiceItem.Fields.Item("TAX_FLAG").Value = CByte(1)

' Create Another Invoice Item
oInvoiceItem = oInvoicePost.Items.Add()

' Read the Next Stock Code & populate fields from Stock Code
oStockRecord.MoveNext()
oInvoiceItem.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
oInvoiceItem.Fields.Item("DESCRIPTION").Value = CStr(oStockRecord.Fields.Item("DESCRIPTION").Value)
oInvoiceItem.Fields.Item("NOMINAL_CODE").Value = CStr(oStockRecord.Fields.Item("NOMINAL_CODE").Value)
oInvoiceItem.Fields.Item("TAX_CODE").Value = CShort(oStockRecord.Fields.Item("TAX_CODE").Value)

' Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
' regardless of the Tax_Flag being set to 1***
oInvoiceItem.Fields.Item("QTY_ORDER").Value = CDbl(1)
oInvoiceItem.Fields.Item("UNIT_PRICE").Value = CDbl(200)
oInvoiceItem.Fields.Item("NET_AMOUNT").Value = CDbl(200)
oInvoiceItem.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(200)
oInvoiceItem.Fields.Item("COMMENT_1").Value = CStr("")
oInvoiceItem.Fields.Item("COMMENT_2").Value = CStr("")
oInvoiceItem.Fields.Item("UNIT_OF_SALE").Value = CStr("")
oInvoiceItem.Fields.Item("TAX_RATE").Value = CDbl(20)

' Update the Invoice
If oInvoicePost.Update  Then

MsgBox("Invoice Posted Successfully", MsgBoxStyle.OKOnly, "SDO Examples")

Else

MsgBox("Failed to create Invoice", MsgBoxStyle.OKOnly, "SDO Examples")

End If

' Disconnect
oWS.Disconnect()

End If

End If

' Destroy Objects
oInvoicePost =  Nothing
oInvoiceItem =  Nothing
oSalesRecord =  Nothing
oStockRecord =  Nothing
oWS =  Nothing
oSDO =  Nothing

Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.InvoicePost oInvoicePost;

SageDataObject300.InvoiceItem oInvoiceItem;

SageDataObject300.SalesRecord oSalesRecord;

SageDataObject300.StockRecord oStockRecord;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

//Leaving the username and password blank generates a login dialog

oWS.Connect(szDataPath, "", "", "Example");

//Instantiate objects

oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");

oInvoicePost = (SageDataObject300.InvoicePost)oWS.CreateObject("InvoicePost");

oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");

//Set the invoice type

oInvoicePost.Type = (SageDataObject300.InvoiceType)SageDataObject300.LedgerType.sdoLedgerInvoice;

//Read the first customer record and use to populate the invoice fields

oSalesRecord.MoveFirst();

SDOHelper.Write(oInvoicePost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));

SDOHelper.Write(oInvoicePost.Header, "NAME", (String)SDOHelper.Read(oSalesRecord, "NAME"));

SDOHelper.Write(oInvoicePost.Header, "ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_1"));

SDOHelper.Write(oInvoicePost.Header, "ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_2"));

SDOHelper.Write(oInvoicePost.Header, "ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_3"));

SDOHelper.Write(oInvoicePost.Header, "ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_4"));

SDOHelper.Write(oInvoicePost.Header, "ADDRESS_5", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_5"));

SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_1"));

SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_2"));

SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_3"));

SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_4"));

SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_5", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_5"));

SDOHelper.Write(oInvoicePost.Header, "CUST_TEL_NUMBER", (String)SDOHelper.Read(oSalesRecord, "TELEPHONE"));

SDOHelper.Write(oInvoicePost.Header, "CONTACT_NAME", (String)SDOHelper.Read(oSalesRecord, "CONTACT_NAME"));

SDOHelper.Write(oInvoicePost.Header, "GLOBAL_TAX_CODE", (Int16)SDOHelper.Read(oSalesRecord, "DEF_TAX_CODE"));

//Populate other invoice header information

SDOHelper.Write(oInvoicePost.Header, "INVOICE_DATE", (DateTime)DateTime.Today);

SDOHelper.Write(oInvoicePost.Header, "NOTES_1", (String)"Notes 1");

SDOHelper.Write(oInvoicePost.Header, "NOTES_2", (String)"Notes 2");

SDOHelper.Write(oInvoicePost.Header, "NOTES_3", (String)"Notes 3");

SDOHelper.Write(oInvoicePost.Header, "TAKEN_BY", (String)"Chris Reed");

SDOHelper.Write(oInvoicePost.Header, "ORDER_NUMBER", (String)"");

SDOHelper.Write(oInvoicePost.Header, "CUST_ORDER_NUMBER", (String)"");

SDOHelper.Write(oInvoicePost.Header, "PAYMENT_REF", (String)"");

// If anything is entered in the GLOBAL_NOM_CODE, all of the updated invoice’s splits will have this nominal code and

// also this willforce anything entered in the GLOBAL_DETAILS field into the all the splits details field.

SDOHelper.Write(oInvoicePost.Header, "GLOBAL_NOM_CODE", (String)"");

SDOHelper.Write(oInvoicePost.Header, "GLOBAL_DETAILS", (String)"");

SDOHelper.Write(oInvoicePost.Header, "INVOICE_TYPE_CODE",

(Byte)SageDataObject300.InvoiceType.sdoProductInvoice);

//Create and invoice item

//Need to invoke the Add method

oInvoiceItem = (SageDataObject300.InvoiceItem)SDOHelper.Add(oInvoicePost.Items);

//Read the First Stock Code & populate fields from Stock Code

oStockRecord.MoveFirst();

SDOHelper.Write(oInvoiceItem, "STOCK_CODE", (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));

SDOHelper.Write(oInvoiceItem, "DESCRIPTION", (String)SDOHelper.Read(oStockRecord, "DESCRIPTION"));

SDOHelper.Write(oInvoiceItem, "NOMINAL_CODE", (String)SDOHelper.Read(oStockRecord, "NOMINAL_CODE"));

SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)SDOHelper.Read(oStockRecord, "TAX_CODE"));

//Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated

//regardless of the Tax_Flag being set to 1***

SDOHelper.Write(oInvoiceItem, "QTY_ORDER", (Int32)1);

SDOHelper.Write(oInvoiceItem, "UNIT_PRICE", (Int32)133.33);

SDOHelper.Write(oInvoiceItem, "NET_AMOUNT", (Int32)133.33);

SDOHelper.Write(oInvoiceItem, "TAX_AMOUNT", (Int32)26.66);

SDOHelper.Write(oInvoiceItem, "COMMENT_1", (String)"Comment 1");

SDOHelper.Write(oInvoiceItem, "COMMENT_2", (String)"Comment 2");

SDOHelper.Write(oInvoiceItem, "UNIT_OF_SALE", (String)"");

SDOHelper.Write(oInvoiceItem, "FULL_NET_AMOUNT", (Int32)133.33);

SDOHelper.Write(oInvoiceItem, "TAX_RATE", (Int32)20);

// Ensure the Tax Flag is set if calculating own Tax_Amount value

SDOHelper.Write(oInvoiceItem, "TAX_FLAG", (Byte)1);

//Update the invoice

if (oInvoicePost.Update())

{

MessageBox.Show("Invoice Posted Successfully", "C# SDO Examples");

}

else

{

MessageBox.Show("Failed to create Invoice", "C# SDO Examples");

}

//Disconnect

oWS.Disconnect();

}

catch (Exception ex)

{

MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Posting a Product Invoice with a Net Value Discount

Example - Posting a Product Invoice with a Net Value Discount

The example code below demonstrates how Posting a Product Invoice with a Net Value Discount .

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
        ' Declare Objects
        Dim oSDO As SageDataObject300.SDOEngine
        Dim oWS As SageDataObject300.WorkSpace
        Dim oInvoicePost As SageDataObject300.InvoicePost
        Dim oInvoiceItem As SageDataObject300.InvoiceItem
        Dim oSalesRecord As SageDataObject300.SalesRecord
        Dim oStockRecord As SageDataObject300.StockRecord

        ' Declare Variables
        Dim szDataPath As String
        Dim iCtr As Short

        ' Create the SDO Engine Object
        oSDO = New SageDataObject300.SDOEngine

        ' Create the Workspace
        oWS = oSDO.Workspaces.Add("Example")

        ' SelectCompany.  The SelectCompany method takes the program install
        ' folder as a parameter
        szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

        ' A U.I. for company selection is presented to the user. If a company is selected,
        ' the path will be passed to the szDataPath variable.
        ' If not, or the Cancel button is selected, the variable will be left empty.
        If szDataPath <> "" Then

            ' Connect to Data Files - Will throw an exception if it fails
            If oWS.Connect(szDataPath, "", "", "Example") Then

                ' Create an instance of the Objects
                oSalesRecord = oWS.CreateObject("SalesRecord")
                oInvoicePost = oWS.CreateObject("InvoicePost")
                oStockRecord = oWS.CreateObject("StockRecord")

                ' Set the type of invoice for the next available number
                oInvoicePost.Type = SageDataObject300.LedgerType.sdoLedgerInvoice

                ' Read the First Customer & populate Invoice Fields
                oSalesRecord.MoveFirst()

                oInvoicePost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
                oInvoicePost.Header("NAME").Value = CStr(oSalesRecord.Fields.Item("NAME").Value)
                oInvoicePost.Header("ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_1").Value)
                oInvoicePost.Header("ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_2").Value)
                oInvoicePost.Header("ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_3").Value)
                oInvoicePost.Header("ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_4").Value)
                oInvoicePost.Header("ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_5").Value)
                oInvoicePost.Header("DEL_ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_1").Value)
                oInvoicePost.Header("DEL_ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_2").Value)
                oInvoicePost.Header("DEL_ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_3").Value)
                oInvoicePost.Header("DEL_ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_4").Value)
                oInvoicePost.Header("DEL_ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_5").Value)
                oInvoicePost.Header("CUST_TEL_NUMBER").Value = CStr(oSalesRecord.Fields.Item("TELEPHONE").Value)
                oInvoicePost.Header("CONTACT_NAME").Value = CStr(oSalesRecord.Fields.Item("CONTACT_NAME").Value)
                oInvoicePost.Header("GLOBAL_TAX_CODE").Value = CShort(oSalesRecord.Fields.Item("DEF_TAX_CODE").Value)

                ' Populate other Invoice Header Information
                oInvoicePost.Header("INVOICE_DATE").Value = CDate(Today)
                oInvoicePost.Header("NOTES_1").Value = CStr("")
                oInvoicePost.Header("NOTES_2").Value = CStr("")
                oInvoicePost.Header("NOTES_3").Value = CStr("")
                oInvoicePost.Header("TAKEN_BY").Value = CStr("Mark Steel")
                oInvoicePost.Header("ORDER_NUMBER").Value = CStr("")
                oInvoicePost.Header("CUST_ORDER_NUMBER").Value = CStr("")
                oInvoicePost.Header("PAYMENT_REF").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.
                oInvoicePost.Header("GLOBAL_NOM_CODE").Value = CStr("")
                oInvoicePost.Header("GLOBAL_DETAILS").Value = CStr("")
                oInvoicePost.Header("INVOICE_TYPE_CODE").Value = CByte(SageDataObject300.InvoiceType.sdoProductInvoice)

                ' Set the Net Value Discount values. If setting NVD the program logic will now recalculate
                ' the invoice Item values regardless of whether the TAX_FLAG is set on the item.
                oInvoicePost.Header("NETVALUE_DISCOUNT").Value = CDbl(10)
                oInvoicePost.Header("NETVALUE_DESCRIPTION").Value = CStr("Discount offered")

                ' Create an Invoice Item
                oInvoiceItem = oInvoicePost.Items.Add()

                ' Read the First Stock Code & populate fields from Stock Code
                oStockRecord.MoveFirst()
                oInvoiceItem.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
                oInvoiceItem.Fields.Item("DESCRIPTION").Value = CStr(oStockRecord.Fields.Item("DESCRIPTION").Value)
                oInvoiceItem.Fields.Item("NOMINAL_CODE").Value = CStr(oStockRecord.Fields.Item("NOMINAL_CODE").Value)
                oInvoiceItem.Fields.Item("TAX_CODE").Value = CInt(oStockRecord.Fields.Item("TAX_CODE").Value)

                ' Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
                ' regardless of the Tax_Flag being set to 1***
                oInvoiceItem.Fields.Item("QTY_ORDER").Value = CDbl(2)
                oInvoiceItem.Fields.Item("UNIT_PRICE").Value = CDbl(50)
                oInvoiceItem.Fields.Item("NET_AMOUNT").Value = CDbl(100)
                oInvoiceItem.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(100)
                oInvoiceItem.Fields.Item("TAX_AMOUNT").Value = CDbl(20)
                oInvoiceItem.Fields.Item("COMMENT_1").Value = CStr("")
                oInvoiceItem.Fields.Item("COMMENT_2").Value = CStr("")
                oInvoiceItem.Fields.Item("UNIT_OF_SALE").Value = CStr("")
                oInvoiceItem.Fields.Item("TAX_RATE").Value = CDbl(20)

                ' Create Another Invoice Item
                oInvoiceItem = oInvoicePost.Items.Add()

                ' Read the Next Stock Code & populate fields from Stock Code
                oStockRecord.MoveNext()
                oInvoiceItem.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
                oInvoiceItem.Fields.Item("DESCRIPTION").Value = CStr(oStockRecord.Fields.Item("DESCRIPTION").Value)
                oInvoiceItem.Fields.Item("NOMINAL_CODE").Value = CStr(oStockRecord.Fields.Item("NOMINAL_CODE").Value)
                oInvoiceItem.Fields.Item("TAX_CODE").Value = CShort(oStockRecord.Fields.Item("TAX_CODE").Value)

                ' Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
                ' regardless of the Tax_Flag being set to 1***
                oInvoiceItem.Fields.Item("QTY_ORDER").Value = CDbl(1)
                oInvoiceItem.Fields.Item("UNIT_PRICE").Value = CDbl(133.33)
                oInvoiceItem.Fields.Item("NET_AMOUNT").Value = CDbl(133.33)
                oInvoiceItem.Fields.Item("TAX_AMOUNT").Value = CDbl(26.66)
                oInvoiceItem.Fields.Item("COMMENT_1").Value = CStr("")
                oInvoiceItem.Fields.Item("COMMENT_2").Value = CStr("")
                oInvoiceItem.Fields.Item("UNIT_OF_SALE").Value = CStr("")
                oInvoiceItem.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(133.33)
                oInvoiceItem.Fields.Item("TAX_RATE").Value = CDbl(20)

                ' Update the Invoice
                If oInvoicePost.Update Then

                    MsgBox("Invoice Posted Successfully", MsgBoxStyle.OkOnly, "SDO Examples")

                Else

                    MsgBox("Failed to create Invoice", MsgBoxStyle.OkOnly, "SDO Examples")

                End If

                ' Disconnect
                oWS.Disconnect()

            End If

        End If

        ' Destroy Objects
        oInvoicePost = Nothing
        oInvoiceItem = Nothing
        oSalesRecord = Nothing
        oStockRecord = Nothing
        oWS = Nothing
        oSDO = Nothing

        Exit Sub
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.InvoicePost oInvoicePost;
SageDataObject300.InvoiceItem oInvoiceItem;
SageDataObject300.SalesRecord oSalesRecord;
SageDataObject300.StockRecord oStockRecord;
String szDataPath;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails
try
{
    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "Example");

    //Instantiate objects
    oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");
    oInvoicePost = (SageDataObject300.InvoicePost)oWS.CreateObject("InvoicePost");
    oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");

    //Set the invoice type
    oInvoicePost.Type = (SageDataObject300.InvoiceType)SageDataObject300.LedgerType.sdoLedgerInvoice;

    //Read the first customer record and use to populate the invoice fields
    oSalesRecord.MoveFirst();
    SDOHelper.Write(oInvoicePost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));
    SDOHelper.Write(oInvoicePost.Header, "NAME", (String)SDOHelper.Read(oSalesRecord, "NAME"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_1"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_2"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_3"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_4"));
    SDOHelper.Write(oInvoicePost.Header, "ADDRESS_5", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_5"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_1"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_2"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_3"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_4"));
    SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_5", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_5"));
    SDOHelper.Write(oInvoicePost.Header, "CUST_TEL_NUMBER", (String)SDOHelper.Read(oSalesRecord, "TELEPHONE"));
    SDOHelper.Write(oInvoicePost.Header, "CONTACT_NAME", (String)SDOHelper.Read(oSalesRecord, "CONTACT_NAME"));
    SDOHelper.Write(oInvoicePost.Header, "GLOBAL_TAX_CODE", (Int16)SDOHelper.Read(oSalesRecord, "DEF_TAX_CODE"));

    //Populate other invoice header information
    SDOHelper.Write(oInvoicePost.Header, "INVOICE_DATE", (DateTime)DateTime.Today);
    SDOHelper.Write(oInvoicePost.Header, "NOTES_1", (String)"Notes 1");
    SDOHelper.Write(oInvoicePost.Header, "NOTES_2", (String)"Notes 2");
    SDOHelper.Write(oInvoicePost.Header, "NOTES_3", (String)"Notes 3");
    SDOHelper.Write(oInvoicePost.Header, "TAKEN_BY", (String)"Chris Reed");
    SDOHelper.Write(oInvoicePost.Header, "ORDER_NUMBER", (String)"");
    SDOHelper.Write(oInvoicePost.Header, "CUST_ORDER_NUMBER", (String)"");
    SDOHelper.Write(oInvoicePost.Header, "PAYMENT_REF", (String)"");
    // If anything is entered in the GLOBAL_NOM_CODE, all of the updated invoice’s splits will have this nominal code and
    // also this willforce anything entered in the GLOBAL_DETAILS field into the all the splits details field.
    SDOHelper.Write(oInvoicePost.Header, "GLOBAL_NOM_CODE", (String)"");
    SDOHelper.Write(oInvoicePost.Header, "GLOBAL_DETAILS", (String)"");
    SDOHelper.Write(oInvoicePost.Header, "INVOICE_TYPE_CODE",
      (Byte)SageDataObject300.InvoiceType.sdoProductInvoice);

    // Set the Net Value Discount values. If setting NVD the program logic will now recalculate
    // the invoice Item values regardless of whether the TAX_FLAG is set on the item.
    SDOHelper.Write(oInvoicePost.Header,"NETVALUE_DISCOUNT", (Double)10);
    SDOHelper.Write(oInvoicePost.Header,"NETVALUE_DESCRIPTION", (String)"Discount offered");

    //Create and invoice item
    //Need to invoke the Add method
    oInvoiceItem = (SageDataObject300.InvoiceItem)SDOHelper.Add(oInvoicePost.Items);

    //Read the First Stock Code & populate fields from Stock Code
    oStockRecord.MoveFirst();
    SDOHelper.Write(oInvoiceItem, "STOCK_CODE", (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));
    SDOHelper.Write(oInvoiceItem, "DESCRIPTION", (String)SDOHelper.Read(oStockRecord, "DESCRIPTION"));
    SDOHelper.Write(oInvoiceItem, "NOMINAL_CODE", (String)SDOHelper.Read(oStockRecord, "NOMINAL_CODE"));
    SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)SDOHelper.Read(oStockRecord, "TAX_CODE"));

    //Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
    //regardless of the Tax_Flag being set to 1***
    SDOHelper.Write(oInvoiceItem, "QTY_ORDER", (Int32)1);
    SDOHelper.Write(oInvoiceItem, "UNIT_PRICE", (Int32)200);
    SDOHelper.Write(oInvoiceItem, "NET_AMOUNT", (Int32)200);
    SDOHelper.Write(oInvoiceItem, "FULL_NET_AMOUNT", (Int32)200);
    SDOHelper.Write(oInvoiceItem, "COMMENT_1", (String)"Comment 1");
    SDOHelper.Write(oInvoiceItem, "COMMENT_2", (String)"Comment 2");
    SDOHelper.Write(oInvoiceItem, "UNIT_OF_SALE", (String)"");
    SDOHelper.Write(oInvoiceItem, "FULL_NET_AMOUNT", (Int32)200);
    SDOHelper.Write(oInvoiceItem, "TAX_RATE", (Int32)20);

    //Update the invoice
    if (oInvoicePost.Update())
    {
        MessageBox.Show("Invoice Posted Successfully", "C# SDO Examples");
    }
    else
    {
        MessageBox.Show("Failed to create Invoice", "C# SDO Examples");
    }

    //Disconnect
    oWS.Disconnect();
}
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}


Sage 50 Accounts - Example - Reading the Item Lines of an Existing Invoice

Example - Reading the Item Lines of an Existing Invoice

The example code below demonstrates how to read the Item Lines of an Existing Invoice.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
                                ' Declare Objects
Dim oSDO  As
                              SageDataObject300.SDOEngine
Dim oWS  As
                              SageDataObject300.WorkSpace
Dim oInvoiceRecord  As
                              SageDataObject300.InvoiceRecord
Dim oInvoiceItem  As
                              SageDataObject300.InvoiceItem

' Declare Variables
Dim szDataPath  As
                               String

' Create the SDO Engine Object
oSDO =  New   SageDataObject300.SDOEngine()

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company.  The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> ""  Then

' Try to Connect - Will throw an exception if it fails
If oWS.Connect(szDataPath, "", "", "Example")
                               Then

' Create an Instance of Objects
oInvoiceRecord = oWS.CreateObject("InvoiceRecord")
oInvoiceItem = oWS.CreateObject("InvoiceItem")

' Read an Existing
                                  Invoice
oInvoiceRecord.MoveLast()

' Link Items to Record
oInvoiceItem = oInvoiceRecord.Link

' Move to the First Item
oInvoiceItem.MoveFirst()

' Loop through Invoice items
Do

' Display the
                                  Item Product Code
MsgBox("Item " & CStr(oInvoiceItem.Fields.Item("ITEM_NUMBER").Value) & " has product code " &
                              CStr(oInvoiceItem.Fields.Item("STOCK_CODE").Value), MsgBoxStyle.OKOnly, "SDO Examples")

Loop Until Not oInvoiceItem.MoveNext

End If

' Disconnect
oWS.Disconnect()

End If

' Destroy Objects
oInvoiceRecord =  Nothing
oInvoiceItem =  Nothing
oWS =  Nothing
oSDO =  Nothing

Exit Sub
C#.NET [image] Copy C# Code
No C# example


Sage 50 Accounts - Example - Manual Invoice Discount

Example - Manual Invoice Discount

The following code example demonstrates how to apply a manual discount to an invoice in Sage 50 Accounts when using the Sage Data Objects. The code will calculate the values based on a discount percentage entered and the quantity of items. Examples are available in VB.NET and C#.NET.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code

' Declare Objects

Dim oSDO As SageDataObject300.SDOEngine

Dim oWS As SageDataObject300.WorkSpace

Dim oControlData As SageDataObject300.ControlData

Dim oInvoicePost As SageDataObject300.InvoicePost

Dim oInvoiceItem As SageDataObject300.InvoiceItem

Dim oSalesRecord As SageDataObject300.SalesRecord

Dim oStockRecord As SageDataObject300.StockRecord

' Declare Variables

Dim szDataPath As String

Dim taxcoderef As Integer

Dim szFieldName As String

' Create the SDO Engine Object

oSDO = New SageDataObject300.SDOEngine

' Create the Workspace

oWS = oSDO.Workspaces.Add("Example")

' SelectCompany. The SelectCompany method takes the program install

' folder as a parameter

szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

Try

' A U.I. for company selection is presented to the user. If a company is selected,

' the path will be passed to the szDataPath variable.

' If not, or the Cancel button is selected, the variable will be left empty.

If szDataPath <> "" Then

' Connect to Data Files - Will throw an exception if it fails

If oWS.Connect(szDataPath, "", "", "Example") Then

' Create an instance of the Objects

oSalesRecord = oWS.CreateObject("SalesRecord")

oInvoicePost = oWS.CreateObject("InvoicePost")

oStockRecord = oWS.CreateObject("StockRecord")

' Create an Instance of and Read the record for the ControlData object

' ControlData has only one record, this will be used

'for Tax Codes later

oControlData = oWS.CreateObject("ControlData")

oControlData.Read(1)

' Set the type of invoice for the next available number

oInvoicePost.Type = SageDataObject300.LedgerType.sdoLedgerInvoice

' Read the First Customer & populate Invoice Fields

oSalesRecord.MoveFirst()

oInvoicePost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)

oInvoicePost.Header("NAME").Value = CStr(oSalesRecord.Fields.Item("NAME").Value)

oInvoicePost.Header("ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_1").Value)

oInvoicePost.Header("ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_2").Value)

oInvoicePost.Header("ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_3").Value)

oInvoicePost.Header("ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_4").Value)

oInvoicePost.Header("ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_5").Value)

oInvoicePost.Header("DEL_ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_1").Value)

oInvoicePost.Header("DEL_ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_2").Value)

oInvoicePost.Header("DEL_ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_3").Value)

oInvoicePost.Header("DEL_ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_4").Value)

oInvoicePost.Header("DEL_ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_5").Value)

oInvoicePost.Header("CUST_TEL_NUMBER").Value = CStr(oSalesRecord.Fields.Item("TELEPHONE").Value)

oInvoicePost.Header("CONTACT_NAME").Value = CStr(oSalesRecord.Fields.Item("CONTACT_NAME").Value)

oInvoicePost.Header("GLOBAL_TAX_CODE").Value = CShort(oSalesRecord.Fields.Item("DEF_TAX_CODE").Value)

' Populate other Invoice Header Information

oInvoicePost.Header("INVOICE_DATE").Value = CDate(Today)

oInvoicePost.Header("NOTES_1").Value = CStr("")

oInvoicePost.Header("NOTES_2").Value = CStr("")

oInvoicePost.Header("NOTES_3").Value = CStr("")

oInvoicePost.Header("TAKEN_BY").Value = CStr("Mark Steel")

oInvoicePost.Header("ORDER_NUMBER").Value = CStr("")

oInvoicePost.Header("CUST_ORDER_NUMBER").Value = CStr("")

oInvoicePost.Header("PAYMENT_REF").Value = CStr("")

oInvoicePost.Header("GLOBAL_NOM_CODE").Value = CStr("")

oInvoicePost.Header("GLOBAL_DETAILS").Value = CStr("")

oInvoicePost.Header("INVOICE_TYPE_CODE").Value = CByte(SageDataObject300.InvoiceType.sdoProductInvoice)

' Create an Invoice Item

oInvoiceItem = oInvoicePost.Items.Add()

' Read the First Stock Code & populate fields from Stock Code

oStockRecord.MoveFirst()

oInvoiceItem.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)

oInvoiceItem.Fields.Item("DESCRIPTION").Value = CStr(oStockRecord.Fields.Item("DESCRIPTION").Value)

oInvoiceItem.Fields.Item("NOMINAL_CODE").Value = CStr(oStockRecord.Fields.Item("NOMINAL_CODE").Value)

oInvoiceItem.Fields.Item("TAX_CODE").Value = CInt(oStockRecord.Fields.Item("TAX_CODE").Value)

'Store the tax code to be used later to calculate tax rate

taxcoderef = oInvoiceItem.Fields.Item("TAX_CODE").Value

' Populate values of other fields required for Invoice Item

oInvoiceItem.Fields.Item("QTY_ORDER").Value = CDbl(2)

oInvoiceItem.Fields.Item("UNIT_PRICE").Value = oStockRecord.Fields.Item("SALES_PRICE").Value

oInvoiceItem.Fields.Item("FULL_NET_AMOUNT").Value = oInvoiceItem.Fields.Item("QTY_ORDER").Value * oInvoiceItem.Fields.Item("UNIT_PRICE").Value

'Set discount rate as a percentage and calculate the discount amount

oInvoiceItem.Fields.Item("DISCOUNT_RATE").Value = CDbl(5)

oInvoiceItem.Fields.Item("DISCOUNT_AMOUNT").Value = oInvoiceItem.Fields.Item("FULL_NET_AMOUNT").Value / 100 * oInvoiceItem.Fields.Item("DISCOUNT_RATE").Value

'Calculate the net amount after the discount

oInvoiceItem.Fields.Item("NET_AMOUNT").Value = oInvoiceItem.Fields.Item("FULL_NET_AMOUNT").Value - oInvoiceItem.Fields.Item("DISCOUNT_AMOUNT").Value

'We need to form a string that will be used to read a field in control data.

'This will allow us to read the tax rate based on the tax code

szFieldName = "T" & taxcoderef & "_RATE"

oInvoiceItem.Fields.Item("TAX_RATE").Value = Format(oControlData.Fields.Item(szFieldName).Value, "##,##0.00")

oInvoiceItem.Fields.Item("TAX_AMOUNT").Value = oInvoiceItem.Fields.Item("NET_AMOUNT").Value / 100 * oInvoiceItem.Fields.Item("TAX_RATE").Value

'Add any comments

oInvoiceItem.Fields.Item("COMMENT_1").Value = CStr("")

oInvoiceItem.Fields.Item("COMMENT_2").Value = CStr("")

oInvoiceItem.Fields.Item("UNIT_OF_SALE").Value = CStr("")

' Update the Invoice

If oInvoicePost.Update Then

MsgBox("Invoice Posted Successfully", MsgBoxStyle.OkOnly, "SDO Examples")

Else

MsgBox("Failed to create Invoice", MsgBoxStyle.OkOnly, "SDO Examples")

End If

End If

End If

Catch ex As Exception

MessageBox.Show(ex.Message.ToString)

Finally

' Disconnect

oWS.Disconnect()

' Destroy Objects

oInvoicePost = Nothing

oInvoiceItem = Nothing

oSalesRecord = Nothing

oStockRecord = Nothing

oWS = Nothing

oSDO = Nothing

End Try

Exit Sub
C#.NET [image] Copy C# Code

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.ControlData oControlData;

SageDataObject300.InvoicePost oInvoicePost;

SageDataObject300.InvoiceItem oInvoiceItem;

SageDataObject300.SalesRecord oSalesRecord;

SageDataObject300.StockRecord oStockRecord;

// Declare Variables

String szDataPath = null;

Int32 taxcoderef = 0;

String szFieldName = null;

// Create the Workspace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

// SelectCompany. The SelectCompany method takes the program install

// folder as a parameter

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

try

{

oWS.Connect(szDataPath, "", "", "Example");

//Instantiate objects

oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");

oInvoicePost = (SageDataObject300.InvoicePost)oWS.CreateObject("InvoicePost");

oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");

// Create an Instance of and Read the record for the ControlData object

// ControlData has only one record, this will be used

//for Tax Codes later

oControlData = (SageDataObject300.ControlData)oWS.CreateObject("ControlData");

oControlData.Read(1);

// Set the type of invoice for the next available number

oInvoicePost.Type = (SageDataObject300.InvoiceType)SageDataObject300.LedgerType.sdoLedgerInvoice;

// Read the First Customer & populate Invoice Fields

oSalesRecord.MoveFirst();

SDOHelper.Write(oInvoicePost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));

SDOHelper.Write(oInvoicePost.Header, "NAME", (String)SDOHelper.Read(oSalesRecord, "NAME"));

SDOHelper.Write(oInvoicePost.Header, "ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_1"));

SDOHelper.Write(oInvoicePost.Header, "ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_2"));

SDOHelper.Write(oInvoicePost.Header, "ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_3"));

SDOHelper.Write(oInvoicePost.Header, "ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_4"));

SDOHelper.Write(oInvoicePost.Header, "ADDRESS_5", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_5"));

SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_1"));

SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_2"));

SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_3"));

SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_4"));

SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_5", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_5"));

SDOHelper.Write(oInvoicePost.Header, "CUST_TEL_NUMBER", (String)SDOHelper.Read(oSalesRecord, "TELEPHONE"));

SDOHelper.Write(oInvoicePost.Header, "CONTACT_NAME", (String)SDOHelper.Read(oSalesRecord, "CONTACT_NAME"));

SDOHelper.Write(oInvoicePost.Header, "GLOBAL_TAX_CODE", (Int16)SDOHelper.Read(oSalesRecord, "DEF_TAX_CODE"));

//Populate other invoice header information

SDOHelper.Write(oInvoicePost.Header, "INVOICE_DATE", (DateTime)DateTime.Today);

SDOHelper.Write(oInvoicePost.Header, "NOTES_1", (String)"Notes 1");

SDOHelper.Write(oInvoicePost.Header, "NOTES_2", (String)"Notes 2");

SDOHelper.Write(oInvoicePost.Header, "NOTES_3", (String)"Notes 3");

SDOHelper.Write(oInvoicePost.Header, "TAKEN_BY", (String)"Chris Reed");

SDOHelper.Write(oInvoicePost.Header, "ORDER_NUMBER", (String)"");

SDOHelper.Write(oInvoicePost.Header, "CUST_ORDER_NUMBER", (String)"");

SDOHelper.Write(oInvoicePost.Header, "PAYMENT_REF", (String)"");

SDOHelper.Write(oInvoicePost.Header, "GLOBAL_NOM_CODE", (String)"");

SDOHelper.Write(oInvoicePost.Header, "GLOBAL_DETAILS", (String)"");

SDOHelper.Write(oInvoicePost.Header, "INVOICE_TYPE_CODE", (Byte)SageDataObject300.InvoiceType.sdoProductInvoice);

//Create and invoice item

//Need to invoke the Add method

oInvoiceItem = (SageDataObject300.InvoiceItem)SDOHelper.Add(oInvoicePost.Items);

// Read the First Stock Code & populate fields from Stock Code

oStockRecord.MoveFirst();

SDOHelper.Write(oInvoiceItem, "STOCK_CODE", (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));

SDOHelper.Write(oInvoiceItem, "DESCRIPTION", (String)SDOHelper.Read(oStockRecord, "DESCRIPTION"));

SDOHelper.Write(oInvoiceItem, "NOMINAL_CODE", (String)SDOHelper.Read(oStockRecord, "NOMINAL_CODE"));

SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)SDOHelper.Read(oStockRecord, "TAX_CODE"));

//Store the tax code to be used later to calculate tax rate

taxcoderef = (Int16)SDOHelper.Read(oInvoiceItem, "TAX_CODE");

// Populate values of other fields required for Invoice Item

SDOHelper.Write(oInvoiceItem, "QTY_ORDER", (Int32)2);

SDOHelper.Write(oInvoiceItem, "UNIT_PRICE", (Double)SDOHelper.Read(oStockRecord, "SALES_PRICE"));

SDOHelper.Write(oInvoiceItem, "FULL_NET_AMOUNT", (((Double)SDOHelper.Read(oInvoiceItem, "QTY_ORDER"))

* ((Double)SDOHelper.Read(oInvoiceItem, "UNIT_PRICE"))));

//Set discount rate as a percentage and calculate the discount amount

SDOHelper.Write(oInvoiceItem, "DISCOUNT_RATE", (Double)25);

SDOHelper.Write(oInvoiceItem, "DISCOUNT_AMOUNT", (((Double)SDOHelper.Read(oInvoiceItem, "FULL_NET_AMOUNT"))

/ 100 * ((Double)SDOHelper.Read(oInvoiceItem, "DISCOUNT_RATE"))));

//Calcualte the net amount after the discount

SDOHelper.Write(oInvoiceItem, "NET_AMOUNT", (((Double)SDOHelper.Read(oInvoiceItem, "FULL_NET_AMOUNT"))

- ((Double)SDOHelper.Read(oInvoiceItem, "DISCOUNT_AMOUNT"))));

//We need to form a string that will be used to read a field in control data.

//This will allow us to read the tax rate based on the tax code

szFieldName = "T" + taxcoderef + "_RATE";

SDOHelper.Write(oInvoiceItem, "TAX_RATE", SDOHelper.Read(oControlData, szFieldName));

SDOHelper.Write(oInvoiceItem, "TAX_AMOUNT", (((Double)SDOHelper.Read(oInvoiceItem, "NET_AMOUNT"))

/ 100) * ((Double)SDOHelper.Read(oInvoiceItem, "TAX_RATE")));

//Add any comments

SDOHelper.Write(oInvoiceItem, "COMMENT_1", (String)"");

SDOHelper.Write(oInvoiceItem, "COMMENT_2", (String)"");

SDOHelper.Write(oInvoiceItem, "UNIT_OF_SALE", (String)"");

//Update the invoice

if (oInvoicePost.Update())

{

MessageBox.Show("Invoice Posted Successfully", "C# SDO Examples");

}

else

{

MessageBox.Show("Failed to create Invoice", "C# SDO Examples");

}

}

catch (Exception ex)

{

MessageBox.Show(ex.Message.ToString());

}

finally

{

// Disconnect

oWS.Disconnect();

// Destroy Objects

oInvoicePost = null;

oInvoiceItem = null;

oSalesRecord = null;

oStockRecord = null;

oWS = null;

oSDO = null;

}


Sage 50 Accounts - Example - Adding an Item Line to a Sales Order

Example - Adding an Item Line to a Sales Order

The example code below demonstrates how to add an item line to a Sales Order.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
'Declare objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oSOPRecord As SageDataObject300.SopRecord
Dim oSOPItem_Read As SageDataObject300.SopItem
Dim oSOPItem_Write As SageDataObject300.SopItem
Dim oSOPPost As SageDataObject300.SopPost
Dim oStockRecord As SageDataObject300.StockRecord

'Declare Variables
Dim szDataPath As String

'Create SDO Engine Object
oSDO = New SageDataObject300.SDOEngine

' Select company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

'Create Workspace
oWS = oSDO.Workspaces.Add("Example")

'Try to connect
If oWS.Connect(szDataPath, "", "", "Example") Then

    'Create objects
    oSOPRecord = oWS.CreateObject("SOPRecord")
    oSOPPost = oWS.CreateObject("SOPPost")
    oSOPItem_Read = oWS.CreateObject("SOPItem")
    oStockRecord = oWS.CreateObject("StockRecord")

    'Read an existing Sales Order
    oSOPRecord.MoveLast()

    'Populate the order header, copying fields from oSOPRecord to oSOPPost
    oSOPPost.Header("INVOICE_NUMBER").Value = oSOPRecord.Fields.Item("INVOICE_NUMBER").Value
    oSOPPost.Header("ACCOUNT_REF").Value = CStr(oSOPRecord.Fields.Item("ACCOUNT_REF").Value)
    oSOPPost.Header("NAME").Value = CStr(oSOPRecord.Fields.Item("NAME").Value)
    oSOPPost.Header("ADDRESS_1").Value = CStr(oSOPRecord.Fields.Item("ADDRESS_1").Value)
    oSOPPost.Header("ADDRESS_2").Value = CStr(oSOPRecord.Fields.Item("ADDRESS_2").Value)
    oSOPPost.Header("ADDRESS_3").Value = CStr(oSOPRecord.Fields.Item("ADDRESS_3").Value)
    oSOPPost.Header("ADDRESS_4").Value = CStr(oSOPRecord.Fields.Item("ADDRESS_4").Value)
    oSOPPost.Header("ADDRESS_5").Value = CStr(oSOPRecord.Fields.Item("ADDRESS_5").Value)
    oSOPPost.Header("DEL_ADDRESS_1").Value = CStr(oSOPRecord.Fields.Item("DEL_ADDRESS_1").Value)
    oSOPPost.Header("DEL_ADDRESS_2").Value = CStr(oSOPRecord.Fields.Item("DEL_ADDRESS_2").Value)
    oSOPPost.Header("DEL_ADDRESS_3").Value = CStr(oSOPRecord.Fields.Item("DEL_ADDRESS_3").Value)
    oSOPPost.Header("DEL_ADDRESS_4").Value = CStr(oSOPRecord.Fields.Item("DEL_ADDRESS_4").Value)
    oSOPPost.Header("DEL_ADDRESS_5").Value = CStr(oSOPRecord.Fields.Item("DEL_ADDRESS_5").Value)
    oSOPPost.Header("CUST_TEL_NUMBER").Value = CStr(oSOPRecord.Fields.Item("CUST_TEL_NUMBER").Value)
    oSOPPost.Header("CONTACT_NAME").Value = CStr(oSOPRecord.Fields.Item("CONTACT_NAME").Value)
    oSOPPost.Header("GLOBAL_TAX_CODE").Value = CShort(oSOPRecord.Fields.Item("GLOBAL_TAX_CODE").Value)
    oSOPPost.Header("ORDER_DATE").Value = CDate(oSOPRecord.Fields.Item("ORDER_DATE").Value)
    oSOPPost.Header("NOTES_1").Value = CStr(oSOPRecord.Fields.Item("NOTES_1").Value)
    oSOPPost.Header("NOTES_2").Value = CStr(oSOPRecord.Fields.Item("NOTES_1").Value)
    oSOPPost.Header("NOTES_3").Value = CStr(oSOPRecord.Fields.Item("NOTES_3").Value)
    oSOPPost.Header("TAKEN_BY").Value = CStr(oSOPRecord.Fields.Item("TAKEN_BY").Value)
    oSOPPost.Header("ORDER_NUMBER").Value = CStr(oSOPRecord.Fields.Item("ORDER_NUMBER").Value)
    oSOPPost.Header("CUST_ORDER_NUMBER").Value = CStr(oSOPRecord.Fields.Item("CUST_ORDER_NUMBER").Value)
    oSOPPost.Header("PAYMENT_REF").Value = CStr(oSOPRecord.Fields.Item("PAYMENT_REF").Value)
    oSOPPost.Header("GLOBAL_NOM_CODE").Value = CStr(oSOPRecord.Fields.Item("GLOBAL_NOM_CODE").Value)
    oSOPPost.Header("GLOBAL_DETAILS").Value = CStr(oSOPRecord.Fields.Item("GLOBAL_DETAILS").Value)
    oSOPPost.Header("ORDER_TYPE").Value = oSOPRecord.Fields.Item("ORDER_TYPE").Value
    oSOPPost.Header("FOREIGN_RATE").Value = CDbl(oSOPRecord.Fields.Item("FOREIGN_RATE").Value)
    oSOPPost.Header("CURRENCY").Value = oSOPRecord.Fields.Item("CURRENCY").Value
    oSOPPost.Header("CURRENCY_USED").Value = oSOPRecord.Fields.Item("CURRENCY_USED").Value

    ' Link header to items
    oSOPItem_Read = oSOPRecord.Link

    'Find the First Record
    oSOPItem_Read.MoveFirst()

    Do

        'Add the existing items to the order
        oSOPItem_Write = oSOPPost.Items.Add

        'Populate the Fields, copying the data from the existing records
        oSOPItem_Write.Fields.Item("STOCK_CODE").Value = CStr(oSOPItem_Read.Fields.Item("STOCK_CODE").Value)
        oSOPItem_Write.Fields.Item("DESCRIPTION").Value = CStr(oSOPItem_Read.Fields.Item("DESCRIPTION").Value)
        oSOPItem_Write.Fields.Item("NOMINAL_CODE").Value = CStr(oSOPItem_Read.Fields.Item("NOMINAL_CODE").Value)
        oSOPItem_Write.Fields.Item("TAX_CODE").Value = CShort(oSOPItem_Read.Fields.Item("TAX_CODE").Value)
        oSOPItem_Write.Fields.Item("QTY_ORDER").Value = CDbl(oSOPItem_Read.Fields.Item("QTY_ORDER").Value)
        oSOPItem_Write.Fields.Item("UNIT_PRICE").Value = CDbl(oSOPItem_Read.Fields.Item("UNIT_PRICE").Value)
        oSOPItem_Write.Fields.Item("NET_AMOUNT").Value = CDbl(oSOPItem_Read.Fields.Item("NET_AMOUNT").Value)
        oSOPItem_Write.Fields.Item("TAX_AMOUNT").Value = CDbl(oSOPItem_Read.Fields.Item("TAX_AMOUNT").Value)
        oSOPItem_Write.Fields.Item("COMMENT_1").Value = CStr(oSOPItem_Read.Fields.Item("COMMENT_1").Value)
        oSOPItem_Write.Fields.Item("COMMENT_2").Value = CStr(oSOPItem_Read.Fields.Item("COMMENT_2").Value)
        oSOPItem_Write.Fields.Item("UNIT_OF_SALE").Value = CStr(oSOPItem_Read.Fields.Item("UNIT_OF_SALE").Value)
        oSOPItem_Write.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(oSOPItem_Read.Fields.Item("FULL_NET_AMOUNT").Value)
        oSOPItem_Write.Fields.Item("TAX_RATE").Value = CDbl(oSOPItem_Read.Fields.Item("TAX_RATE").Value)
        'We now need to ensure that the TAX_FLAG is set the same as the item being read otherwise it will be re calculated
        oSOPItem_Write.Fields.Item("TAX_FLAG").Value = CInt(oSOPItem_Read.Fields.Item("TAX_FLAG").Value)

        'Loop until there are no more existing items
    Loop Until oSOPItem_Read.MoveNext = False

    'destroy the oSOPItem_Write object
    oSOPItem_Write = Nothing

    'write a new item
    oStockRecord.MoveLast()
    oSOPItem_Write = oSOPPost.Items.Add

    ' Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
    ' regardless of the Tax_Flag being set to 1***
    oSOPItem_Write.Fields.Item("STOCK_CODE").Value = oStockRecord.Fields.Item("STOCK_CODE").Value
    oSOPItem_Write.Fields.Item("DESCRIPTION").Value = CStr(oStockRecord.Fields.Item("DESCRIPTION").Value)
    oSOPItem_Write.Fields.Item("NOMINAL_CODE").Value = CStr(oStockRecord.Fields.Item("NOMINAL_CODE").Value)
    oSOPItem_Write.Fields.Item("TAX_CODE").Value = CShort(oStockRecord.Fields.Item("TAX_CODE").Value)
    oSOPItem_Write.Fields.Item("QTY_ORDER").Value = CDbl(2)
    oSOPItem_Write.Fields.Item("UNIT_PRICE").Value = CDbl(50)
    oSOPItem_Write.Fields.Item("NET_AMOUNT").Value = CDbl(100)
    oSOPItem_Write.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(100)
    oSOPItem_Write.Fields.Item("COMMENT_1").Value = CStr("")
    oSOPItem_Write.Fields.Item("COMMENT_2").Value = CStr("")
    oSOPItem_Write.Fields.Item("UNIT_OF_SALE").Value = CStr("")
    oSOPItem_Write.Fields.Item("TAX_RATE").Value = CDbl(20)

    'Destroy the oSOPItem_Write object
    oSOPItem_Write = Nothing

    'Post the order
    If oSOPPost.Update() Then

        MsgBox("Order Updated Successfully")

    Else

        MsgBox("Order Update Failed")

    End If

    'Disconnect and destroy the objects
    oWS.Disconnect()
    oSDO = Nothing
    oWS = Nothing
    oSOPRecord = Nothing
    oSOPItem_Read = Nothing
    oSOPItem_Write = Nothing
    oSOPPost = Nothing
    oStockRecord = Nothing

End If

Exit Sub
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.SopRecord oSopRecord;
SageDataObject300.SopItem oSopItem_Read;
SageDataObject300.SopItem oSopItem_Write;
SageDataObject300.SopPost oSopPost;
SageDataObject300.StockRecord oStockRecord;
String szDataPath;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails
try
{
    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

    //Instantiate Objects
    oSopRecord = (SageDataObject300.SopRecord)oWS.CreateObject("SopRecord");
    oSopPost = (SageDataObject300.SopPost)oWS.CreateObject("SopPost");
    oSopItem_Read = (SageDataObject300.SopItem)oWS.CreateObject("SopItem");
    oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");

    //Read an existing Sales Order
    oSopRecord.MoveLast();

    //Populate the order header, copying fields from oSopRecord to oSopPost
    SDOHelper.Write(oSopPost.Header, "INVOICE_NUMBER", SDOHelper.Read(oSopRecord, "INVOICE_NUMBER"));
    SDOHelper.Write(oSopPost.Header, "ACCOUNT_REF", SDOHelper.Read(oSopRecord, "ACCOUNT_REF"));
    SDOHelper.Write(oSopPost.Header, "NAME", SDOHelper.Read(oSopRecord, "NAME"));
    SDOHelper.Write(oSopPost.Header, "ADDRESS_1", SDOHelper.Read(oSopRecord, "ADDRESS_1"));
    SDOHelper.Write(oSopPost.Header, "ADDRESS_2", SDOHelper.Read(oSopRecord, "ADDRESS_2"));
    SDOHelper.Write(oSopPost.Header, "ADDRESS_3", SDOHelper.Read(oSopRecord, "ADDRESS_3"));
    SDOHelper.Write(oSopPost.Header, "ADDRESS_4", SDOHelper.Read(oSopRecord, "ADDRESS_4"));
    SDOHelper.Write(oSopPost.Header, "ADDRESS_5", SDOHelper.Read(oSopRecord, "ADDRESS_5"));
    SDOHelper.Write(oSopPost.Header, "DEL_ADDRESS_1", SDOHelper.Read(oSopRecord, "DEL_ADDRESS_1"));
    SDOHelper.Write(oSopPost.Header, "DEL_ADDRESS_2", SDOHelper.Read(oSopRecord, "DEL_ADDRESS_2"));
    SDOHelper.Write(oSopPost.Header, "DEL_ADDRESS_3", SDOHelper.Read(oSopRecord, "DEL_ADDRESS_3"));
    SDOHelper.Write(oSopPost.Header, "DEL_ADDRESS_4", SDOHelper.Read(oSopRecord, "DEL_ADDRESS_4"));
    SDOHelper.Write(oSopPost.Header, "DEL_ADDRESS_5", SDOHelper.Read(oSopRecord, "DEL_ADDRESS_5"));
    SDOHelper.Write(oSopPost.Header, "CUST_TEL_NUMBER", SDOHelper.Read(oSopRecord, "CUST_TEL_NUMBER"));
    SDOHelper.Write(oSopPost.Header, "CONTACT_NAME", SDOHelper.Read(oSopRecord, "CONTACT_NAME"));
    SDOHelper.Write(oSopPost.Header, "GLOBAL_TAX_CODE", SDOHelper.Read(oSopRecord, "GLOBAL_TAX_CODE"));
    SDOHelper.Write(oSopPost.Header, "ORDER_DATE", SDOHelper.Read(oSopRecord, "ORDER_DATE"));
    SDOHelper.Write(oSopPost.Header, "NOTES_1", SDOHelper.Read(oSopRecord, "NOTES_1"));
    SDOHelper.Write(oSopPost.Header, "NOTES_2", SDOHelper.Read(oSopRecord, "NOTES_2"));
    SDOHelper.Write(oSopPost.Header, "NOTES_3", SDOHelper.Read(oSopRecord, "NOTES_3"));
    SDOHelper.Write(oSopPost.Header, "TAKEN_BY", SDOHelper.Read(oSopRecord, "TAKEN_BY"));
    SDOHelper.Write(oSopPost.Header, "ORDER_NUMBER", SDOHelper.Read(oSopRecord, "ORDER_NUMBER"));
    SDOHelper.Write(oSopPost.Header, "CUST_ORDER_NUMBER", SDOHelper.Read(oSopRecord, "CUST_ORDER_NUMBER"));
    SDOHelper.Write(oSopPost.Header, "PAYMENT_REF", SDOHelper.Read(oSopRecord, "PAYMENT_REF"));
    SDOHelper.Write(oSopPost.Header, "GLOBAL_NOM_CODE", SDOHelper.Read(oSopRecord, "GLOBAL_NOM_CODE"));
    SDOHelper.Write(oSopPost.Header, "GLOBAL_DETAILS", SDOHelper.Read(oSopRecord, "GLOBAL_DETAILS"));
    SDOHelper.Write(oSopPost.Header, "ORDER_TYPE", SDOHelper.Read(oSopRecord, "ORDER_TYPE"));
    SDOHelper.Write(oSopPost.Header, "FOREIGN_RATE", SDOHelper.Read(oSopRecord, "FOREIGN_RATE"));
    SDOHelper.Write(oSopPost.Header, "CURRENCY", SDOHelper.Read(oSopRecord, "CURRENCY"));
    SDOHelper.Write(oSopPost.Header, "CURRENCY_USED", SDOHelper.Read(oSopRecord, "CURRENCY_USED"));

    //Link header to items
    oSopItem_Read = (SageDataObject300.SopItem)oSopRecord.Link;

    //Find the first record
    oSopItem_Read.MoveFirst();

    do
    {
        //Add the existing items to the order
        oSopItem_Write = (SageDataObject300.SopItem)SDOHelper.Add(oSopPost.Items);

        //Populate the fields copying from the existing records
        SDOHelper.Write(oSopItem_Write, "STOCK_CODE", SDOHelper.Read(oSopItem_Read, "STOCK_CODE"));
        SDOHelper.Write(oSopItem_Write, "DESCRIPTION", SDOHelper.Read(oSopItem_Read, "DESCRIPTION"));
        SDOHelper.Write(oSopItem_Write, "NOMINAL_CODE", SDOHelper.Read(oSopItem_Read, "NOMINAL_CODE"));
        SDOHelper.Write(oSopItem_Write, "TAX_CODE", SDOHelper.Read(oSopItem_Read, "TAX_CODE"));
        SDOHelper.Write(oSopItem_Write, "QTY_ORDER", SDOHelper.Read(oSopItem_Read, "QTY_ORDER"));
        SDOHelper.Write(oSopItem_Write, "UNIT_PRICE", SDOHelper.Read(oSopItem_Read, "UNIT_PRICE"));
        SDOHelper.Write(oSopItem_Write, "NET_AMOUNT", SDOHelper.Read(oSopItem_Read, "NET_AMOUNT"));
        SDOHelper.Write(oSopItem_Write, "TAX_AMOUNT", SDOHelper.Read(oSopItem_Read, "TAX_AMOUNT"));
        SDOHelper.Write(oSopItem_Write, "COMMENT_1", SDOHelper.Read(oSopItem_Read, "COMMENT_1"));
        SDOHelper.Write(oSopItem_Write, "COMMENT_2", SDOHelper.Read(oSopItem_Read, "COMMENT_2"));
        SDOHelper.Write(oSopItem_Write, "UNIT_OF_SALE", SDOHelper.Read(oSopItem_Read, "UNIT_OF_SALE"));
        SDOHelper.Write(oSopItem_Write, "FULL_NET_AMOUNT", SDOHelper.Read(oSopItem_Read, "FULL_NET_AMOUNT"));
        SDOHelper.Write(oSopItem_Write, "TAX_RATE", SDOHelper.Read(oSopItem_Read, "TAX_RATE"));

    } while (oSopItem_Read.MoveNext());

    //Destroy the oSopItem_Write object
    oSopItem_Write = null;

    //Write a new item
    oStockRecord.MoveLast();
    oSopItem_Write = (SageDataObject300.SopItem)SDOHelper.Add(oSopPost.Items);

    //Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
    //regardless of the Tax_Flag being set to 1***
    SDOHelper.Write(oSopItem_Write, "STOCK_CODE", SDOHelper.Read(oStockRecord, "STOCK_CODE"));
    SDOHelper.Write(oSopItem_Write, "DESCRIPTION", SDOHelper.Read(oStockRecord, "DESCRIPTION"));
    SDOHelper.Write(oSopItem_Write, "NOMINAL_CODE", SDOHelper.Read(oStockRecord, "NOMINAL_CODE"));
    SDOHelper.Write(oSopItem_Write, "TAX_CODE", SDOHelper.Read(oStockRecord, "TAX_CODE"));
    SDOHelper.Write(oSopItem_Write, "QTY_ORDER", (Double)2);
    SDOHelper.Write(oSopItem_Write, "UNIT_PRICE", (Double)50);
    SDOHelper.Write(oSopItem_Write, "NET_AMOUNT", (Double)100);
    SDOHelper.Write(oSopItem_Write, "FULL_NET_AMOUNT", (Double)100);
    SDOHelper.Write(oSopItem_Write, "COMMENT_1", (String)"");
    SDOHelper.Write(oSopItem_Write, "COMMENT_2", (String)"");
    SDOHelper.Write(oSopItem_Write, "UNIT_OF_SALE", (String)"");
    SDOHelper.Write(oSopItem_Write, "TAX_RATE", (Double)20);

    //Post the order
    if (oSopPost.Update())
    {
        MessageBox.Show("Order Updated Successfully");
    }
    else
    {
        MessageBox.Show("Order Update Failed");
    }

    //Disconnect
    oWS.Disconnect();
}
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}


Sage 50 Accounts - Example - Posting a Sales Order

Example - Posting a Sales Order

The example code below demonstrates how to post a Sales Order.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oSOPPost As SageDataObject300.SopPost
Dim oSOPItem As SageDataObject300.SopItem
Dim oSalesRecord As SageDataObject300.SalesRecord
Dim oStockRecord As SageDataObject300.StockRecord

Dim szDataPath As String

' Create Instance of SDO Engine
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install
' directory as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024\")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

    ' 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("Mark Steel")
        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("Audrey Hepburn")
        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 a 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

End If

oSOPPost = Nothing
oSOPItem = Nothing
oSalesRecord = Nothing
oStockRecord = Nothing
oSDO = Nothing
oWS = Nothing

Exit Sub
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.SopPost oSopPost;
SageDataObject300.SopItem oSopItem;
SageDataObject300.SalesRecord oSalesRecord;
SageDataObject300.StockRecord oStockRecord;
String szDataPath;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails
try
{
    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

    //Instantiate objects
    oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");
    oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");
    oSopPost = (SageDataObject300.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)"Chris Reed");
    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)"Mark Steel");
    // If anything is entered in the GLOBAL_NOM_CODE, all of the updated invoice’s splits will have this
    // nominal code and also this willforce 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 = (SageDataObject300.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 a 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();
}
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}


Sage 50 Accounts - Example - Posting a Sales Order Quotation

Example - Posting a Sales Order Quotation

The example code below demonstrates how to post a Sales Order Quotation.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oSOPPost As SageDataObject300.SopPost
Dim oSOPItem As SageDataObject300.SopItem
Dim oSalesRecord As SageDataObject300.SalesRecord
Dim oStockRecord As SageDataObject300.StockRecord

Dim szDataPath As String

' Create Instance of SDO Engine
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install
' directory as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024\")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

    ' 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("Mark Steel")
        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("Audrey Hepburn")
        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("")

        ' Populate details to generate quote
        oSOPPost.Header("ORDER_TYPE").Value = CByte(9)
        oSOPPost.Header("QUOTE_EXPIRY").Value = CDate(Today)
        oSOPPost.Header("QUOTE_STATUS").Value = CByte(1)

        ' 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 Invoice 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 a 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(100)
        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 Quotation Created Successfully", MsgBoxStyle.OkOnly, "SDO Examples")

        Else

            MsgBox("Sales Order Quotation Not Created", MsgBoxStyle.OkOnly, "SDO Examples")

        End If

        ' Disconnect
        oWS.Disconnect()

    End If

End If

oSOPPost = Nothing
oSOPItem = Nothing
oSalesRecord = Nothing
oStockRecord = Nothing
oSDO = Nothing
oWS = Nothing

Exit Sub
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
String szDataPath;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails
try
{
    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

}
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}

// Declare required objects
SageDataObject300.SopPost oSopPost;
SageDataObject300.SopItem oSopItem;
SageDataObject300.SalesRecord oSalesRecord;
SageDataObject300.StockRecord oStockRecord;

try
{
    // Create objects
    oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");
    oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");
    oSopPost = (SageDataObject300.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)SDOHelper.Read(oSalesRecord, "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)"John Smith");
    SDOHelper.Write(oSopPost.Header, "CUST_ORDER_NUMBER", (String)"");
    // If anything is entered in the GLOBAL_NOM_CODE, all of the updated invoice’s splits will have this
    // nominal code and also this willforce 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)"");

    // Populate details to generate quote
    SDOHelper.Write(oSopPost.Header, "ORDER_TYPE", (Byte)SageDataObject300.InvoiceType.sdoSopQuote);
    SDOHelper.Write(oSopPost.Header, "QUOTE_EXPIRY", (DateTime)DateTime.Today);
    SDOHelper.Write(oSopPost.Header, "QUOTE_STATUS", (Byte)SageDataObject300.QuoteStatus.sdoOpen);

    // Create and order item
    oSopItem = (SageDataObject300.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 Invoice 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 a 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)100);
    SDOHelper.Write(oSopItem, "FULL_NET_AMOUNT", (Double)100);
    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);

    // Update the SO
    if (oSopPost.Update())
    {
        MessageBox.Show("Sales Order Quotation Created Successfully");
    }
    else
    {
        MessageBox.Show("Sales Order Quotation Not Created");
    }

    // Disconnect
    oWS.Disconnect();
}
catch (Exception ex)
{
    // Show the exception error message
    MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
}


Sage 50 Accounts - Example - Posting a Foreign Currency Sales Order

Example - Posting a Foreign Currency Sales Order

The example code below demonstrates how to post a Sales Order.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code

' Declare Objects

Dim oSDO As SageDataObject300.SDOEngine

Dim oWS As SageDataObject300.WorkSpace

Dim oSOPPost As SageDataObject300.SopPost

Dim oSOPItem As SageDataObject300.SopItem

Dim oSalesRecord As SageDataObject300.SalesRecord

Dim oStockRecord As SageDataObject300.StockRecord

Dim oCurrencyData As SageDataObject300.CurrencyData

Dim szDataPath As String

' Create Instance of SDO Engine

oSDO = New SageDataObject300.SDOEngine

' Create the Workspace

oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install

' directory as a parameter

szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024\")

' A U.I. for company selection is presented to the user. If a company is selected,

' the path will be passed to the szDataPath variable.

' If not, or the Cancel button is selected, the variable will be left empty.

If szDataPath <> "" Then

' 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")

oCurrencyData = oWS.CreateObject("CurrencyData")

' Read the first customer

oSalesRecord.MoveFirst()

' Read the Currency File

oCurrencyData.Read(Convert.ToByte(oSalesRecord.Fields.Item("CURRENCY").Value) + 1)

' 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("Mark Steel")

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")

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("")

' Populate Foreign Currency Fields

oSOPPost.Header("FOREIGN_RATE").Value = CDbl(oCurrencyData.Fields.Item("EXCHANGE_RATE").Value)

oSOPPost.Header("CURRENCY").Value = oSalesRecord.Fields.Item("CURRENCY").Value

oSOPPost.Header("CURRENCY_USED").Value = oSalesRecord.Fields.Item("CURRENCY").Value

' 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 Order Item fields

' 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 a 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(100)

oSOPItem.Fields.Item("TAX_AMOUNT").Value = CDbl(17.5)

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(17.5)

' Ensure the Tax Flag is set if calculating own Tax_Amount value

oSOPItem.Fields.Item("TAX_FLAG").Value = CByte(1)

' 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

End If

oSOPPost = Nothing

oSOPItem = Nothing

oSalesRecord = Nothing

oStockRecord = Nothing

oCurrencyData = Nothing

oSDO = Nothing

oWS = Nothing
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.SopPost oSopPost;
SageDataObject300.SopItem oSopItem;
SageDataObject300.SalesRecord oSalesRecord;
SageDataObject300.StockRecord oStockRecord;
SageDataObject300.CurrencyData oCurrencyData;
String szDataPath;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails
try
{
    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

    //Instantiate objects
    oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");
    oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");
    oSopPost = (SageDataObject300.SopPost)oWS.CreateObject("SopPost");
    oCurrencyData = (SageDataObject300.CurrencyData)oWS.CreateObject("CurrencyData");

    //Read the first Customer record
    oSalesRecord.MoveFirst();

    //Read the currency file
    oCurrencyData.Read(Convert.ToByte(SDOHelper.Read(oSalesRecord, "CURRENCY")) + 1);

    //Populate 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)"Chris Reed");
    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)"Mark Steel");
    SDOHelper.Write(oSopPost.Header, "CUST_ORDER_NUMBER", (String)"");
    // If anything is entered in the GLOBAL_NOM_CODE, all of the updated invoice’s splits will have this
    // nominal code and also this willforce 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)"");

    //Populate Foreign Currency Fields
    SDOHelper.Write(oSopPost.Header, "FOREIGN_RATE", SDOHelper.Read(oCurrencyData, "EXCHANGE_RATE"));
    SDOHelper.Write(oSopPost.Header, "CURRENCY", SDOHelper.Read(oSalesRecord, "CURRENCY"));
    SDOHelper.Write(oSopPost.Header, "CURRENCY_USED", SDOHelper.Read(oSalesRecord, "CURRENCY"));

    //Create an order item
    oSopItem = (SageDataObject300.SopItem)SDOHelper.Add(oSopPost.Items);

    //Read the fist stock code and populate item fields
    oStockRecord.MoveFirst();

    //Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
    //regardless of the Tax_Flag being set to 1***
    SDOHelper.Write(oSopItem, "STOCK_CODE", SDOHelper.Read(oStockRecord, "STOCK_CODE"));
    SDOHelper.Write(oSopItem, "DESCRIPTION", SDOHelper.Read(oStockRecord, "DESCRIPTION"));
    SDOHelper.Write(oSopItem, "TAX_CODE", SDOHelper.Read(oStockRecord, "TAX_CODE"));
    SDOHelper.Write(oSopItem, "QTY_ORDER", (Double)2);
    SDOHelper.Write(oSopItem, "UNIT_PRICE", (Double)100);
    SDOHelper.Write(oSopItem, "NET_AMOUNT", (Double)100);
    SDOHelper.Write(oSopItem, "FULL_NET_AMOUNT", (Double)100);
    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);

    //Update the invoice
    if (oSopPost.Update())
    {
        MessageBox.Show("Sales Order Created Successfully");
    }
    else
    {
        MessageBox.Show("Sales Order Not Created");
    }

    //Disconnect
    oWS.Disconnect();
}
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}


Sage 50 Accounts - Example - Posting a Sales Order with Item Vat ammendable

Example - Posting a Sales Order with Item Vat ammendable

The example code below demonstrates Posting a Sales Order with Item Vat ammendable .

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oSOPPost As SageDataObject300.SopPost
Dim oSOPItem As SageDataObject300.SopItem
Dim oSalesRecord As SageDataObject300.SalesRecord
Dim oStockRecord As SageDataObject300.StockRecord

Dim szDataPath As String

' Create Instance of SDO Engine
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install
' directory as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024\")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

    ' 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("Mark Steel")
        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("Audrey Hepburn")
        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 a 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(1)
        oSOPItem.Fields.Item("UNIT_PRICE").Value = CDbl(133.33)
        oSOPItem.Fields.Item("NET_AMOUNT").Value = CDbl(133.33)
        oSOPItem.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(133.33)
        oSOPItem.Fields.Item("TAX_AMOUNT").Value = CDbl(26.66)
        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)
        ' Ensure the Tax Flag is set if calculating own Tax_Amount value
        oSOPItem.Fields.Item("TAX_FLAG").Value = CByte(1)

        ' 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

End If

oSOPPost = Nothing
oSOPItem = Nothing
oSalesRecord = Nothing
oStockRecord = Nothing
oSDO = Nothing
oWS = Nothing

Exit Sub
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.SopPost oSopPost;
SageDataObject300.SopItem oSopItem;
SageDataObject300.SalesRecord oSalesRecord;
SageDataObject300.StockRecord oStockRecord;
String szDataPath;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails
try
{
    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

    //Instantiate objects
    oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");
    oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");
    oSopPost = (SageDataObject300.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)"Chris Reed");
    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)"Mark Steel");
    // If anything is entered in the GLOBAL_NOM_CODE, all of the updated invoice’s splits will have this
    // nominal code and also this willforce 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 = (SageDataObject300.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 a 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)133.33);
    SDOHelper.Write(oSopItem, "NET_AMOUNT", (Double)133.33);
    SDOHelper.Write(oSopItem, "FULL_NET_AMOUNT", (Double)133.33);
    SDOHelper.Write(oSopItem, "TAX_AMOUNT", (Double)26.66);
    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);
    // Ensure the Tax Flag is set if calculating own Tax_Amount value
    SDOHelper.Write(oSopItem, "TAX_FLAG", (Byte)1);

    //Update the SO
    if (oSopPost.Update())
    {
        MessageBox.Show("Sales Order Created Successfully");
    }
    else
    {
        MessageBox.Show("Sales Order Not Created");
    }

    //Disconnect
    oWS.Disconnect();
}
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}


Sage 50 Accounts - Example - Posting a Sales Order with a Net Value Discount

Example - Posting a Sales Order with a Net Value Discount

The example code below demonstrates Posting a Sales Order with a Net Value Discount.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oSOPPost As SageDataObject300.SopPost
Dim oSOPItem As SageDataObject300.SopItem
Dim oSalesRecord As SageDataObject300.SalesRecord
Dim oStockRecord As SageDataObject300.StockRecord

Dim szDataPath As String

' Create Instance of SDO Engine
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install
' directory as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024\")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

    ' 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("Mark Steel")
        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("Audrey Hepburn")
        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("")

        ' Set the Net Value Discount values. If setting NVD the program logic will now recalculate
        ' the SOP Item values regardless of whether the TAX_FLAG is set on the item.
        oSOPPost.Header("NETVALUE_DISCOUNT").Value = CDbl(10)
        oSOPPost.Header("NETVALUE_DESCRIPTION").Value = CStr("Discount offered")

        ' 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 a 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(100)
        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

End If

oSOPPost = Nothing
oSOPItem = Nothing
oSalesRecord = Nothing
oStockRecord = Nothing
oSDO = Nothing
oWS = Nothing

Exit Sub
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.SopPost oSopPost;
SageDataObject300.SopItem oSopItem;
SageDataObject300.SalesRecord oSalesRecord;
SageDataObject300.StockRecord oStockRecord;
String szDataPath;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails
try
{
    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

    //Instantiate objects
    oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");
    oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");
    oSopPost = (SageDataObject300.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)"Chris Reed");
    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)"Mark Steel");
    // If anything is entered in the GLOBAL_NOM_CODE, all of the updated invoice’s splits will have this
    // nominal code and also this willforce 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)"");

    // Set the Net Value Discount values. If setting NVD the program logic will now recalculate
    // the invoice Item values regardless of whether the TAX_FLAG is set on the item.
    SDOHelper.Write(oSopPost.Header, "NETVALUE_DISCOUNT", (Double)10);
    SDOHelper.Write(oSopPost.Header, "NETVALUE_DESCRIPTION", (String)"Discount offered");

    //Create and order item
    oSopItem = (SageDataObject300.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 a 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);

    //Update the SO
    if (oSopPost.Update())
    {
        MessageBox.Show("Sales Order Created Successfully");
    }
    else
    {
        MessageBox.Show("Sales Order Not Created");
    }

    //Disconnect
    oWS.Disconnect();
}
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}


Sage 50 Accounts - Example - Reading the Item Lines of an Existing Sales Order

Example - Reading the Item Lines of an Existing Sales Order

The example code below demonstrates how to read the Item Lines of an Existing Sales Order.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
                                ' Declare Objects
Dim oSDO  As
                              SageDataObject300.SDOEngine
Dim oWS  As
                              SageDataObject300.WorkSpace
Dim  oSOPRecord  As
                              SageDataObject300.SOPRecord
Dim  oSOPItem  As
                              SageDataObject300.SOPItem

' Declare Variables
Dim szDataPath  As
                               String

' Create the SDO Engine Object
oSDO =  New   SageDataObject300.SDOEngine()

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company.  The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> ""  Then

' Try to Connect - Will throw an exception if it fails
If oWS.Connect(szDataPath, "", "", "Example")
                               Then

' Create an Instance of Objects
oSOPRecord = oWS.CreateObject("SOPRecord")
oSOPItem = oWS.CreateObject("SOPItem")

' Read an Existing SOP
oSOPRecord.MoveLast()

' Link Items to Record
oSOPItem = oSOPRecord.Link

' Move to the First Item
oSOPItem.MoveFirst()

' Loop through SOP items
Do

' Display the
                                  Item Product Code
MsgBox("Item " & CStr(oSOPItem.Fields.Item("ITEM_NUMBER").Value) & " has product code " &
                              CStr(oSOPItem.Fields.Item("STOCK_CODE").Value), MsgBoxStyle.OKOnly, "SDO Examples")

Loop Until Not  oSOPItem.MoveNext

End If

' Disconnect
oWS.Disconnect()

End If

' Destroy Objects
oSOPRecord =  Nothing
oSOPItem =  Nothing
oWS =  Nothing
oSDO =  Nothing

Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.SopRecord oSopRecord;

SageDataObject300.SopItem oSopItem;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate SopRecord Object

  oSopRecord = (SageDataObject300.SopRecord)oWS.CreateObject("SopRecord");

  //Read an existing SO

  oSopRecord.MoveFirst();

  //Link items to the current record

  oSopItem = (SageDataObject300.SopItem)oSopRecord.Link;

  //Move to the first item

  oSopItem.MoveFirst();

  //Loop through SO Items

  do

  {

    //Display the item product code

    MessageBox.Show("Item " + Convert.ToString(SDOHelper.Read(oSopItem, "ITEM_NUMBER"))

      + " has product code " + (String)SDOHelper.Read(oSopItem, "STOCK_CODE"));

  } while (oSopItem.MoveNext());

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Adding an Item Line to a Purchase Order

Example - Adding an Item Line to a Purchase Order

The example code below demonstrates how to add an item line to a Purchase Order.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. This example is very granuler representation of adding an item line to an existing Purchase Order. This example is based on the existing Purchase Order being fully allocated. Therefore, this example may not work as expected when the Purchase Order is set to a certain status.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oPOPRecord As SageDataObject300.PopRecord
Dim oPOPItem_Read As SageDataObject300.PopItem
Dim oPOPItem_Write As SageDataObject300.PopItem
Dim oPOPPost As SageDataObject300.PopPost
Dim oStockRecord As SageDataObject300.StockRecord

' Declare Variables
Dim szDataPath As String
Dim iItemCount As Short

' Create SDO Engine Object
oSDO = New SageDataObject300.SDOEngine

' Select Company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' Create Workspace
oWS = oSDO.Workspaces.Add("Example")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

    ' Try to Connect - Will throw an exception if it fails
    If oWS.Connect(szDataPath, "", "", "Example") Then

        ' Create Objects
        oPOPRecord = oWS.CreateObject("POPRecord")
        oPOPPost = oWS.CreateObject("POPPost")
        oPOPItem_Read = oWS.CreateObject("POPItem")
        oStockRecord = oWS.CreateObject("StockRecord")

        ' Read an existing Purchase Order
        oPOPRecord.MoveLast()

        ' Populate the Order header, copying fields from oPOPRecord to oPOPPost
        oPOPPost.Header("INVOICE_NUMBER").Value = CStr(oPOPRecord.Fields.Item("INVOICE_NUMBER").Value)
        oPOPPost.Header("ACCOUNT_REF").Value = CStr(oPOPRecord.Fields.Item("ACCOUNT_REF").Value)
        oPOPPost.Header("NAME").Value = CStr(oPOPRecord.Fields.Item("NAME").Value)
        oPOPPost.Header("ADDRESS_1").Value = CStr(oPOPRecord.Fields.Item("ADDRESS_1").Value)
        oPOPPost.Header("ADDRESS_2").Value = CStr(oPOPRecord.Fields.Item("ADDRESS_2").Value)
        oPOPPost.Header("ADDRESS_3").Value = CStr(oPOPRecord.Fields.Item("ADDRESS_3").Value)
        oPOPPost.Header("ADDRESS_4").Value = CStr(oPOPRecord.Fields.Item("ADDRESS_4").Value)
        oPOPPost.Header("ADDRESS_5").Value = CStr(oPOPRecord.Fields.Item("ADDRESS_5").Value)
        oPOPPost.Header("DEL_ADDRESS_1").Value = CStr(oPOPRecord.Fields.Item("DEL_ADDRESS_1").Value)
        oPOPPost.Header("DEL_ADDRESS_2").Value = CStr(oPOPRecord.Fields.Item("DEL_ADDRESS_2").Value)
        oPOPPost.Header("DEL_ADDRESS_3").Value = CStr(oPOPRecord.Fields.Item("DEL_ADDRESS_3").Value)
        oPOPPost.Header("DEL_ADDRESS_4").Value = CStr(oPOPRecord.Fields.Item("DEL_ADDRESS_4").Value)
        oPOPPost.Header("DEL_ADDRESS_5").Value = CStr(oPOPRecord.Fields.Item("DEL_ADDRESS_5").Value)
        oPOPPost.Header("SUPP_TEL_NUMBER").Value = CStr(oPOPRecord.Fields.Item("SUPP_TEL_NUMBER").Value)
        oPOPPost.Header("CONTACT_NAME").Value = CStr(oPOPRecord.Fields.Item("CONTACT_NAME").Value)
        oPOPPost.Header("ORDER_DATE").Value = CDate(oPOPRecord.Fields.Item("ORDER_DATE").Value)
        oPOPPost.Header("NOTES_1").Value = CStr(oPOPRecord.Fields.Item("NOTES_1").Value)
        oPOPPost.Header("NOTES_2").Value = CStr(oPOPRecord.Fields.Item("NOTES_1").Value)
        oPOPPost.Header("NOTES_3").Value = CStr(oPOPRecord.Fields.Item("NOTES_3").Value)
        oPOPPost.Header("TAKEN_BY").Value = CStr(oPOPRecord.Fields.Item("TAKEN_BY").Value)
        oPOPPost.Header("ORDER_NUMBER").Value = CStr(oPOPRecord.Fields.Item("ORDER_NUMBER").Value)
        oPOPPost.Header("SUPP_ORDER_NUMBER").Value = CStr(oPOPRecord.Fields.Item("SUPP_ORDER_NUMBER").Value)
        oPOPPost.Header("PAYMENT_REF").Value = CStr(oPOPRecord.Fields.Item("PAYMENT_REF").Value)
        oPOPPost.Header("FOREIGN_RATE").Value = CDbl(oPOPRecord.Fields.Item("FOREIGN_RATE").Value)
        oPOPPost.Header("CURRENCY").Value = oPOPRecord.Fields.Item("CURRENCY").Value
        oPOPPost.Header("CURRENCY_USED").Value = oPOPRecord.Fields.Item("CURRENCY_USED").Value

        ' Link Items to Header
        oPOPItem_Read = oPOPRecord.Link

        ' Find the First Record
        oPOPItem_Read.MoveFirst()

        Do

            ' Add the existing items to the order
            oPOPItem_Write = oPOPPost.Items.Add

            ' Populate the Fields, copying the data from the existing records
            oPOPItem_Write.Fields.Item("STOCK_CODE").Value = CStr(oPOPItem_Read.Fields.Item("STOCK_CODE").Value)
            oPOPItem_Write.Fields.Item("DESCRIPTION").Value = CStr(oPOPItem_Read.Fields.Item("DESCRIPTION").Value)
            oPOPItem_Write.Fields.Item("NOMINAL_CODE").Value = CStr(oPOPItem_Read.Fields.Item("NOMINAL_CODE").Value)
            oPOPItem_Write.Fields.Item("TAX_CODE").Value = CShort(oPOPItem_Read.Fields.Item("TAX_CODE").Value)
            oPOPItem_Write.Fields.Item("QTY_ORDER").Value = CDbl(oPOPItem_Read.Fields.Item("QTY_ORDER").Value)
            oPOPItem_Write.Fields.Item("UNIT_PRICE").Value = CDbl(oPOPItem_Read.Fields.Item("UNIT_PRICE").Value)
            oPOPItem_Write.Fields.Item("NET_AMOUNT").Value = CDbl(oPOPItem_Read.Fields.Item("NET_AMOUNT").Value)
            oPOPItem_Write.Fields.Item("TAX_AMOUNT").Value = CDbl(oPOPItem_Read.Fields.Item("TAX_AMOUNT").Value)
            oPOPItem_Write.Fields.Item("COMMENT_1").Value = CStr(oPOPItem_Read.Fields.Item("COMMENT_1").Value)
            oPOPItem_Write.Fields.Item("COMMENT_2").Value = CStr(oPOPItem_Read.Fields.Item("COMMENT_2").Value)
            oPOPItem_Write.Fields.Item("UNIT_OF_SALE").Value = CStr(oPOPItem_Read.Fields.Item("UNIT_OF_SALE").Value)
            oPOPItem_Write.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(oPOPItem_Read.Fields.Item("FULL_NET_AMOUNT").Value)
            oPOPItem_Write.Fields.Item("TAX_RATE").Value = CDbl(oPOPItem_Read.Fields.Item("TAX_RATE").Value)
            oPOPItem_Write.Fields.Item("TAX_CODE").Value = CDbl(oPOPItem_Read.Fields.Item("TAX_CODE").Value)
            'We now need to ensure that the TAX_FLAG is set the same as the item being read otherwise it will be recalculated
            oPOPItem_Write.Fields.Item("TAX_FLAG").Value = CDbl(oPOPItem_Read.Fields.Item("TAX_FLAG").Value)
            ' Destroy the oPOPItem_Write object
            oPOPItem_Write = Nothing

            ' Loop until there are no more existing items
        Loop Until oPOPItem_Read.MoveNext = False

        ' Write a New Item
        oStockRecord.MoveLast()
        oPOPItem_Write = oPOPPost.Items.Add

        ' Populate other fields required for POP 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 a NVD is set the item line values will be recalculated
        ' regardless of the Tax_Flag being set to 1***
        oPOPItem_Write.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
        oPOPItem_Write.Fields.Item("DESCRIPTION").Value = CStr(oStockRecord.Fields.Item("DESCRIPTION").Value)
        oPOPItem_Write.Fields.Item("NOMINAL_CODE").Value = CStr(oStockRecord.Fields.Item("NOMINAL_CODE").Value)
        oPOPItem_Write.Fields.Item("TAX_CODE").Value = CShort(oStockRecord.Fields.Item("TAX_CODE").Value)
        oPOPItem_Write.Fields.Item("QTY_ORDER").Value = CDbl(2)
        oPOPItem_Write.Fields.Item("UNIT_PRICE").Value = CDbl(50)
        oPOPItem_Write.Fields.Item("NET_AMOUNT").Value = CDbl(100)
        oPOPItem_Write.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(100)
        oPOPItem_Write.Fields.Item("COMMENT_1").Value = CStr("")
        oPOPItem_Write.Fields.Item("COMMENT_2").Value = CStr("")
        oPOPItem_Write.Fields.Item("UNIT_OF_SALE").Value = CStr("")
        oPOPItem_Write.Fields.Item("TAX_RATE").Value = CDbl(20)

        ' Destroy the oPOPItem_Write object
        oPOPItem_Write = Nothing

        ' Post the order
        If oPOPPost.Update() Then

            MsgBox("Order Updated Successfully")

        Else

            MsgBox("Order Update Failed")

        End If

        ' Disconnect
        oWS.Disconnect()

    End If

End If

' Destroy Objects
oPOPRecord = Nothing
oPOPItem_Read = Nothing
oPOPItem_Write = Nothing
oPOPPost = Nothing
oStockRecord = Nothing
oWS = Nothing
oSDO = Nothing

Exit Sub
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.PopRecord oPopRecord;
SageDataObject300.PopItem oPopItem_Read;
SageDataObject300.PopItem oPopItem_Write;
SageDataObject300.PopPost oPopPost;
SageDataObject300.StockRecord oStockRecord;
String szDataPath;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails
try
{
    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

    //Instantiate Objects
    oPopRecord = (SageDataObject300.PopRecord)oWS.CreateObject("PopRecord");
    oPopPost = (SageDataObject300.PopPost)oWS.CreateObject("PopPost");
    oPopItem_Read = (SageDataObject300.PopItem)oWS.CreateObject("PopItem");
    oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");

    //Read an existing Purchase Order
    oPopRecord.MoveLast();

    //Populate the order header, copying fields from oPopRecord to oPopPost
    SDOHelper.Write(oPopPost.Header, "INVOICE_NUMBER", SDOHelper.Read(oPopRecord, "INVOICE_NUMBER"));
    SDOHelper.Write(oPopPost.Header, "ACCOUNT_REF", SDOHelper.Read(oPopRecord, "ACCOUNT_REF"));
    SDOHelper.Write(oPopPost.Header, "NAME", SDOHelper.Read(oPopRecord, "NAME"));
    SDOHelper.Write(oPopPost.Header, "ADDRESS_1", SDOHelper.Read(oPopRecord, "ADDRESS_1"));
    SDOHelper.Write(oPopPost.Header, "ADDRESS_2", SDOHelper.Read(oPopRecord, "ADDRESS_2"));
    SDOHelper.Write(oPopPost.Header, "ADDRESS_3", SDOHelper.Read(oPopRecord, "ADDRESS_3"));
    SDOHelper.Write(oPopPost.Header, "ADDRESS_4", SDOHelper.Read(oPopRecord, "ADDRESS_4"));
    SDOHelper.Write(oPopPost.Header, "ADDRESS_5", SDOHelper.Read(oPopRecord, "ADDRESS_5"));
    SDOHelper.Write(oPopPost.Header, "DEL_ADDRESS_1", SDOHelper.Read(oPopRecord, "DEL_ADDRESS_1"));
    SDOHelper.Write(oPopPost.Header, "DEL_ADDRESS_2", SDOHelper.Read(oPopRecord, "DEL_ADDRESS_2"));
    SDOHelper.Write(oPopPost.Header, "DEL_ADDRESS_3", SDOHelper.Read(oPopRecord, "DEL_ADDRESS_3"));
    SDOHelper.Write(oPopPost.Header, "DEL_ADDRESS_4", SDOHelper.Read(oPopRecord, "DEL_ADDRESS_4"));
    SDOHelper.Write(oPopPost.Header, "DEL_ADDRESS_5", SDOHelper.Read(oPopRecord, "DEL_ADDRESS_5"));
    SDOHelper.Write(oPopPost.Header, "SUPP_TEL_NUMBER", SDOHelper.Read(oPopRecord, "SUPP_TEL_NUMBER"));
    SDOHelper.Write(oPopPost.Header, "CONTACT_NAME", SDOHelper.Read(oPopRecord, "CONTACT_NAME"));
    SDOHelper.Write(oPopPost.Header, "ORDER_DATE", SDOHelper.Read(oPopRecord, "ORDER_DATE"));
    SDOHelper.Write(oPopPost.Header, "NOTES_1", SDOHelper.Read(oPopRecord, "NOTES_1"));
    SDOHelper.Write(oPopPost.Header, "NOTES_2", SDOHelper.Read(oPopRecord, "NOTES_2"));
    SDOHelper.Write(oPopPost.Header, "NOTES_3", SDOHelper.Read(oPopRecord, "NOTES_3"));
    SDOHelper.Write(oPopPost.Header, "TAKEN_BY", SDOHelper.Read(oPopRecord, "TAKEN_BY"));
    SDOHelper.Write(oPopPost.Header, "ORDER_NUMBER", SDOHelper.Read(oPopRecord, "ORDER_NUMBER"));
    SDOHelper.Write(oPopPost.Header, "SUPP_ORDER_NUMBER", SDOHelper.Read(oPopRecord, "SUPP_ORDER_NUMBER"));
    SDOHelper.Write(oPopPost.Header, "PAYMENT_REF", SDOHelper.Read(oPopRecord, "PAYMENT_REF"));
    SDOHelper.Write(oPopPost.Header, "ORDER_TYPE", SDOHelper.Read(oPopRecord, "ORDER_TYPE"));
    SDOHelper.Write(oPopPost.Header, "FOREIGN_RATE", SDOHelper.Read(oPopRecord, "FOREIGN_RATE"));
    SDOHelper.Write(oPopPost.Header, "CURRENCY", SDOHelper.Read(oPopRecord, "CURRENCY"));
    SDOHelper.Write(oPopPost.Header, "CURRENCY_USED", SDOHelper.Read(oPopRecord, "CURRENCY_USED"));

    //Link header to items
    oPopItem_Read = (SageDataObject300.PopItem)oPopRecord.Link;

    //Find the first record
    oPopItem_Read.MoveFirst();

    do
    {
        //Add the existing items to the order
        oPopItem_Write = (SageDataObject300.PopItem)SDOHelper.Add(oPopPost.Items);

        //Populate the fields copying from the existing records
        SDOHelper.Write(oPopItem_Write, "STOCK_CODE", SDOHelper.Read(oPopItem_Read, "STOCK_CODE"));
        SDOHelper.Write(oPopItem_Write, "DESCRIPTION", SDOHelper.Read(oPopItem_Read, "DESCRIPTION"));
        SDOHelper.Write(oPopItem_Write, "NOMINAL_CODE", SDOHelper.Read(oPopItem_Read, "NOMINAL_CODE"));
        SDOHelper.Write(oPopItem_Write, "TAX_CODE", SDOHelper.Read(oPopItem_Read, "TAX_CODE"));
        SDOHelper.Write(oPopItem_Write, "QTY_ORDER", SDOHelper.Read(oPopItem_Read, "QTY_ORDER"));
        SDOHelper.Write(oPopItem_Write, "UNIT_PRICE", SDOHelper.Read(oPopItem_Read, "UNIT_PRICE"));
        SDOHelper.Write(oPopItem_Write, "NET_AMOUNT", SDOHelper.Read(oPopItem_Read, "NET_AMOUNT"));
        SDOHelper.Write(oPopItem_Write, "TAX_AMOUNT", SDOHelper.Read(oPopItem_Read, "TAX_AMOUNT"));
        SDOHelper.Write(oPopItem_Write, "COMMENT_1", SDOHelper.Read(oPopItem_Read, "COMMENT_1"));
        SDOHelper.Write(oPopItem_Write, "COMMENT_2", SDOHelper.Read(oPopItem_Read, "COMMENT_2"));
        SDOHelper.Write(oPopItem_Write, "UNIT_OF_SALE", SDOHelper.Read(oPopItem_Read, "UNIT_OF_SALE"));
        SDOHelper.Write(oPopItem_Write, "FULL_NET_AMOUNT", SDOHelper.Read(oPopItem_Read, "FULL_NET_AMOUNT"));
        SDOHelper.Write(oPopItem_Write, "TAX_RATE", SDOHelper.Read(oPopItem_Read, "TAX_RATE"));
        //We now need to ensure that the TAX_FLAG is set the same as the item being read otherwise it will be recalculated
        SDOHelper.Write(oPopItem_Write, "TAX_FLAG", SDOHelper.Read(oPopItem_Read, "TAX_FLAG"));
    } while (oPopItem_Read.MoveNext());

    //Destroy the oPopItem_Write object
    oPopItem_Write = null;

    //Write a new item
    oStockRecord.MoveLast();
    oPopItem_Write = (SageDataObject300.PopItem)SDOHelper.Add(oPopPost.Items);

    //Populate other fields required for Invoice 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 a NVD is set the item line values will be recalculated
    //regardless of the Tax_Flag being set to 1***
    SDOHelper.Write(oPopItem_Write, "STOCK_CODE", SDOHelper.Read(oStockRecord, "STOCK_CODE"));
    SDOHelper.Write(oPopItem_Write, "DESCRIPTION", SDOHelper.Read(oStockRecord, "DESCRIPTION"));
    SDOHelper.Write(oPopItem_Write, "NOMINAL_CODE", SDOHelper.Read(oStockRecord, "NOMINAL_CODE"));
    SDOHelper.Write(oPopItem_Write, "TAX_CODE", SDOHelper.Read(oStockRecord, "TAX_CODE"));
    SDOHelper.Write(oPopItem_Write, "QTY_ORDER", (Double)2);
    SDOHelper.Write(oPopItem_Write, "UNIT_PRICE", (Double)50);
    SDOHelper.Write(oPopItem_Write, "NET_AMOUNT", (Double)100);
    SDOHelper.Write(oPopItem_Write, "FULL_NET_AMOUNT", (Double)100);
    SDOHelper.Write(oPopItem_Write, "COMMENT_1", (String)"");
    SDOHelper.Write(oPopItem_Write, "COMMENT_2", (String)"");
    SDOHelper.Write(oPopItem_Write, "UNIT_OF_SALE", (String)"");
    SDOHelper.Write(oPopItem_Write, "TAX_RATE", (Double)20);

    //Post the order
    if (oPopPost.Update())
    {
        MessageBox.Show("Order Updated Successfully");
    }
    else
    {
        MessageBox.Show("Order Update Failed");
    }

    //Disconnect
    oWS.Disconnect();
}
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}


Sage 50 Accounts - Example - Posting a Purchase Order

Example - Posting a Purchase Order

The example code below demonstrates how to post a Purchase Order.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oPOPPost As SageDataObject300.PopPost
Dim oPOPItem As SageDataObject300.PopItem
Dim oPurchaseRecord As SageDataObject300.PurchaseRecord
Dim oStockRecord As SageDataObject300.StockRecord

' Declare Variables
Dim szDataPath As String

' Create Instance of SDO Engine
oSDO = New SageDataObject300.SDOEngine

' Create Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company.  The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

    ' Try to Connect - Will throw an exception if it fails
    If oWS.Connect(szDataPath, "", "", "Example") Then

        ' Create an Instance of POPPost & Record Objects
        oPurchaseRecord = oWS.CreateObject("PurchaseRecord")
        oStockRecord = oWS.CreateObject("StockRecord")
        oPOPPost = oWS.CreateObject("POPPost")

        ' Read the First Supplier
        oPurchaseRecord.MoveFirst()
        oPOPPost.Header("ACCOUNT_REF").Value = CStr(oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value)
        oPOPPost.Header("NAME").Value = CStr(oPurchaseRecord.Fields.Item("Name").Value)
        oPOPPost.Header("ADDRESS_1").Value = CStr(oPurchaseRecord.Fields.Item("ADDRESS_1").Value)
        oPOPPost.Header("ADDRESS_2").Value = CStr(oPurchaseRecord.Fields.Item("ADDRESS_2").Value)
        oPOPPost.Header("ADDRESS_3").Value = CStr(oPurchaseRecord.Fields.Item("ADDRESS_3").Value)
        oPOPPost.Header("ADDRESS_4").Value = CStr(oPurchaseRecord.Fields.Item("ADDRESS_4").Value)
        oPOPPost.Header("ADDRESS_5").Value = CStr(oPurchaseRecord.Fields.Item("ADDRESS_5").Value)
        oPOPPost.Header("DEL_ADDRESS_1").Value = CStr(oPurchaseRecord.Fields.Item("DEL_ADDRESS_1").Value)
        oPOPPost.Header("DEL_ADDRESS_2").Value = CStr(oPurchaseRecord.Fields.Item("DEL_ADDRESS_2").Value)
        oPOPPost.Header("DEL_ADDRESS_3").Value = CStr(oPurchaseRecord.Fields.Item("DEL_ADDRESS_3").Value)
        oPOPPost.Header("DEL_ADDRESS_4").Value = CStr(oPurchaseRecord.Fields.Item("DEL_ADDRESS_4").Value)
        oPOPPost.Header("DEL_ADDRESS_5").Value = CStr(oPurchaseRecord.Fields.Item("DEL_ADDRESS_5").Value)
        oPOPPost.Header("SUPP_TEL_NUMBER").Value = CStr(oPurchaseRecord.Fields.Item("TELEPHONE").Value)
        oPOPPost.Header("CONTACT_NAME").Value = CStr("Mark Steel")

        ' Populate other Order Header Information
        oPOPPost.Header("ORDER_DATE").Value = CDate(Today)
        oPOPPost.Header("NOTES_1").Value = CStr("")
        oPOPPost.Header("NOTES_2").Value = CStr("")
        oPOPPost.Header("NOTES_3").Value = CStr("")
        oPOPPost.Header("TAKEN_BY").Value = CStr("")
        oPOPPost.Header("SUPP_ORDER_NUMBER").Value = CStr("")

        ' Create an Order Item
        oPOPItem = oPOPPost.Items.Add()

        ' Read the first Stock Code and populate Item fields
        oStockRecord.MoveFirst()

        ' Populate other fields required for POP 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
        oPOPItem.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
        oPOPItem.Fields.Item("DESCRIPTION").Value = CStr(oStockRecord.Fields.Item("DESCRIPTION").Value)
        oPOPItem.Fields.Item("NOMINAL_CODE").Value = CStr(oPurchaseRecord.Fields.Item("DEF_NOM_CODE").Value)
        oPOPItem.Fields.Item("TAX_CODE").Value = CShort(oStockRecord.Fields.Item("TAX_CODE").Value)
        oPOPItem.Fields.Item("QTY_ORDER").Value = CDbl(2)
        oPOPItem.Fields.Item("UNIT_PRICE").Value = CDbl(100)
        oPOPItem.Fields.Item("NET_AMOUNT").Value = CDbl(200)
        oPOPItem.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(200)
        oPOPItem.Fields.Item("COMMENT_1").Value = CStr("")
        oPOPItem.Fields.Item("COMMENT_2").Value = CStr("")
        oPOPItem.Fields.Item("UNIT_OF_SALE").Value = CStr("")
        oPOPItem.Fields.Item("TAX_RATE").Value = CDbl(20)

        ' Update the Invoice
        If oPOPPost.Update Then

            MsgBox("Purchase Order Created Successfully.", MsgBoxStyle.OkOnly, "SDO Examples")

        Else

            MsgBox("Purchase Order Not Created.", MsgBoxStyle.OkOnly, "SDO Examples")

        End If

        ' Disconnect
        oWS.Disconnect()

    End If

End If

' Destroy Objects
oPOPPost = Nothing
oPOPItem = Nothing
oPurchaseRecord = Nothing
oStockRecord = Nothing
oWS = Nothing
oSDO = Nothing

Exit Sub
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.PopPost oPopPost;
SageDataObject300.PopItem oPopItem;
SageDataObject300.PurchaseRecord oPurchaseRecord;
SageDataObject300.StockRecord oStockRecord;
String szDataPath;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails
try
{
    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

    //Instantiate objects
    oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");
    oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");
    oPopPost = (SageDataObject300.PopPost)oWS.CreateObject("PopPost");

    //Read the first supplier
    oPurchaseRecord.MoveFirst();

    //Populate the order Header Fields
    SDOHelper.Write(oPopPost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"));
    SDOHelper.Write(oPopPost.Header, "NAME", (String)SDOHelper.Read(oPurchaseRecord, "NAME"));
    SDOHelper.Write(oPopPost.Header, "ADDRESS_1", (String)SDOHelper.Read(oPurchaseRecord, "ADDRESS_1"));
    SDOHelper.Write(oPopPost.Header, "ADDRESS_2", (String)SDOHelper.Read(oPurchaseRecord, "ADDRESS_2"));
    SDOHelper.Write(oPopPost.Header, "ADDRESS_3", (String)SDOHelper.Read(oPurchaseRecord, "ADDRESS_3"));
    SDOHelper.Write(oPopPost.Header, "ADDRESS_4", (String)SDOHelper.Read(oPurchaseRecord, "ADDRESS_4"));
    SDOHelper.Write(oPopPost.Header, "ADDRESS_5", (String)SDOHelper.Read(oPurchaseRecord, "ADDRESS_5"));
    SDOHelper.Write(oPopPost.Header, "DEL_ADDRESS_1", (String)SDOHelper.Read(oPurchaseRecord, "DEL_ADDRESS_1"));
    SDOHelper.Write(oPopPost.Header, "DEL_ADDRESS_2", (String)SDOHelper.Read(oPurchaseRecord, "DEL_ADDRESS_2"));
    SDOHelper.Write(oPopPost.Header, "DEL_ADDRESS_3", (String)SDOHelper.Read(oPurchaseRecord, "DEL_ADDRESS_3"));
    SDOHelper.Write(oPopPost.Header, "DEL_ADDRESS_4", (String)SDOHelper.Read(oPurchaseRecord, "DEL_ADDRESS_4"));
    SDOHelper.Write(oPopPost.Header, "DEL_ADDRESS_5", (String)SDOHelper.Read(oPurchaseRecord, "DEL_ADDRESS_5"));
    SDOHelper.Write(oPopPost.Header, "SUPP_TEL_NUMBER", (String)SDOHelper.Read(oPurchaseRecord, "TELEPHONE"));
    SDOHelper.Write(oPopPost.Header, "CONTACT_NAME", (String)"Chris Reed");

    //Populate other header information
    SDOHelper.Write(oPopPost.Header, "ORDER_DATE", (DateTime)DateTime.Today);
    SDOHelper.Write(oPopPost.Header, "NOTES_1", (String)"");
    SDOHelper.Write(oPopPost.Header, "NOTES_2", (String)"");
    SDOHelper.Write(oPopPost.Header, "NOTES_3", (String)"");
    SDOHelper.Write(oPopPost.Header, "TAKEN_BY", (String)"Mark Steel");
    SDOHelper.Write(oPopPost.Header, "SUPP_ORDER_NUMBER", (String)"");

    //Create and order item
    oPopItem = (SageDataObject300.PopItem)SDOHelper.Add(oPopPost.Items);

    //Read the first stock code
    oStockRecord.MoveFirst();
    SDOHelper.Write(oPopItem, "STOCK_CODE", (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));
    SDOHelper.Write(oPopItem, "DESCRIPTION", (String)SDOHelper.Read(oStockRecord, "DESCRIPTION"));
    SDOHelper.Write(oPopItem, "NOMINAL_CODE", (String)SDOHelper.Read(oStockRecord, "NOMINAL_CODE"));
    SDOHelper.Write(oPopItem, "TAX_CODE", (Int16)SDOHelper.Read(oStockRecord, "TAX_CODE"));

    //Populate other fields required for POP 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 a NVD is set the item line values will be recalculated
    //regardless of the Tax_Flag being set to 1***
    SDOHelper.Write(oPopItem, "QTY_ORDER", (Double)2);
    SDOHelper.Write(oPopItem, "UNIT_PRICE", (Double)100);
    SDOHelper.Write(oPopItem, "NET_AMOUNT", (Double)200);
    SDOHelper.Write(oPopItem, "FULL_NET_AMOUNT", (Double)200);
    SDOHelper.Write(oPopItem, "COMMENT_1", (String)"");
    SDOHelper.Write(oPopItem, "COMMENT_2", (String)"");
    SDOHelper.Write(oPopItem, "UNIT_OF_SALE", (String)"");
    SDOHelper.Write(oPopItem, "TAX_RATE", (Double)20);

    //Update the PO
    if (oPopPost.Update())
    {
        MessageBox.Show("Purchase Order Created Successfully");
    }
    else
    {
        MessageBox.Show("Purchase Order Not Created");
    }

    //Disconnect
    oWS.Disconnect();
}
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}


Sage 50 Accounts - Example - Posting a Foreign Currency Purchase Order

Example - Posting a Foreign Currency Purchase Order

The example code below demonstrates how to post a Foreign Currency Purchase Order.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oPOPPost As SageDataObject300.PopPost
Dim oPOPItem As SageDataObject300.PopItem
Dim oPurchaseRecord As SageDataObject300.PurchaseRecord
Dim oStockRecord As SageDataObject300.StockRecord
Dim oCurrencyData As SageDataObject300.CurrencyData

' Declare Variables
Dim szDataPath As String

' Create Instance of SDO Engine
oSDO = New SageDataObject300.SDOEngine

' Create Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company.  The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

    ' Try to Connect - Will throw an exception if it fails
    If oWS.Connect(szDataPath, "", "", "Example") Then

        ' Create an Instance of POPPost & Record Objects
        oPurchaseRecord = oWS.CreateObject("PurchaseRecord")
        oStockRecord = oWS.CreateObject("StockRecord")
        oPOPPost = oWS.CreateObject("POPPost")
        oCurrencyData = oWS.CreateObject("CurrencyData")

        ' Read the First Supplier
        oPurchaseRecord.MoveFirst()

        ' Read the Currency File
        oCurrencyData.Read(Convert.ToByte(oPurchaseRecord.Fields.Item("CURRENCY").Value) + 1)

        ' Populate Order Header Fields
        oPOPPost.Header("ACCOUNT_REF").Value = CStr(oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value)
        oPOPPost.Header("NAME").Value = CStr(oPurchaseRecord.Fields.Item("Name").Value)
        oPOPPost.Header("ADDRESS_1").Value = CStr(oPurchaseRecord.Fields.Item("ADDRESS_1").Value)
        oPOPPost.Header("ADDRESS_2").Value = CStr(oPurchaseRecord.Fields.Item("ADDRESS_2").Value)
        oPOPPost.Header("ADDRESS_3").Value = CStr(oPurchaseRecord.Fields.Item("ADDRESS_3").Value)
        oPOPPost.Header("ADDRESS_4").Value = CStr(oPurchaseRecord.Fields.Item("ADDRESS_4").Value)
        oPOPPost.Header("ADDRESS_5").Value = CStr(oPurchaseRecord.Fields.Item("ADDRESS_5").Value)
        oPOPPost.Header("DEL_ADDRESS_1").Value = CStr(oPurchaseRecord.Fields.Item("DEL_ADDRESS_1").Value)
        oPOPPost.Header("DEL_ADDRESS_2").Value = CStr(oPurchaseRecord.Fields.Item("DEL_ADDRESS_2").Value)
        oPOPPost.Header("DEL_ADDRESS_3").Value = CStr(oPurchaseRecord.Fields.Item("DEL_ADDRESS_3").Value)
        oPOPPost.Header("DEL_ADDRESS_4").Value = CStr(oPurchaseRecord.Fields.Item("DEL_ADDRESS_4").Value)
        oPOPPost.Header("DEL_ADDRESS_5").Value = CStr(oPurchaseRecord.Fields.Item("DEL_ADDRESS_5").Value)
        oPOPPost.Header("SUPP_TEL_NUMBER").Value = CStr(oPurchaseRecord.Fields.Item("TELEPHONE").Value)
        oPOPPost.Header("CONTACT_NAME").Value = CStr("Mark Steel")

        ' Populate other Order Header Information
        oPOPPost.Header("ORDER_DATE").Value = CDate(Today)
        oPOPPost.Header("NOTES_1").Value = CStr("")
        oPOPPost.Header("NOTES_2").Value = CStr("")
        oPOPPost.Header("NOTES_3").Value = CStr("")
        oPOPPost.Header("TAKEN_BY").Value = CStr("Chris Burke")
        oPOPPost.Header("SUPP_ORDER_NUMBER").Value = CStr("")

        ' Populate Foreign Currency Fields
        oPOPPost.Header("FOREIGN_RATE").Value = CDbl(oCurrencyData.Fields.Item("EXCHANGE_RATE").Value)
        oPOPPost.Header("CURRENCY").Value = oPurchaseRecord.Fields.Item("CURRENCY").Value
        oPOPPost.Header("CURRENCY_USED").Value = oPurchaseRecord.Fields.Item("CURRENCY").Value

        ' Create an Order Item
        oPOPItem = oPOPPost.Items.Add()

        ' Read the first Stock Code and populate Item fields
        oStockRecord.MoveFirst()

        ' Populate other fields required for POP 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 a NVD is set the item line values will be recalculated
        ' regardless of the Tax_Flag being set to 1***
        oPOPItem.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
        oPOPItem.Fields.Item("DESCRIPTION").Value = CStr(oStockRecord.Fields.Item("DESCRIPTION").Value)
        oPOPItem.Fields.Item("TAX_CODE").Value = CShort(oStockRecord.Fields.Item("TAX_CODE").Value)
        oPOPItem.Fields.Item("QTY_ORDER").Value = CDbl(2)
        oPOPItem.Fields.Item("UNIT_PRICE").Value = CDbl(100)
        oPOPItem.Fields.Item("NET_AMOUNT").Value = CDbl(100)
        oPOPItem.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(100)
        oPOPItem.Fields.Item("COMMENT_1").Value = CStr("")
        oPOPItem.Fields.Item("COMMENT_2").Value = CStr("")
        oPOPItem.Fields.Item("UNIT_OF_SALE").Value = CStr("")
        oPOPItem.Fields.Item("TAX_RATE").Value = CDbl(20)

        ' Update the Invoice
        If oPOPPost.Update Then

            MsgBox("Purchase Order Created Successfully.", MsgBoxStyle.OkOnly, "SDO Examples")

        Else

            MsgBox("Purchase Order Not Created.", MsgBoxStyle.OkOnly, "SDO Examples")

        End If

        ' Disconnect
        oWS.Disconnect()

    End If

End If

' Destroy Objects
oPOPPost = Nothing
oPOPItem = Nothing
oPurchaseRecord = Nothing
oStockRecord = Nothing
oCurrencyData = Nothing
oWS = Nothing
oSDO = Nothing

Exit Sub
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.PopPost oPopPost;
SageDataObject300.PopItem oPopItem;
SageDataObject300.PurchaseRecord oPurchaseRecord;
SageDataObject300.StockRecord oStockRecord;
SageDataObject300.CurrencyData oCurrencyData;
String szDataPath;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails
try
{
    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

    //Instantiate objects
    oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");
    oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");
    oPopPost = (SageDataObject300.PopPost)oWS.CreateObject("PopPost");
    oCurrencyData = (SageDataObject300.CurrencyData)oWS.CreateObject("CurrencyData");

    //Read the first supplier record
    oPurchaseRecord.MoveFirst();

    //Read the currency file
    oCurrencyData.Read(Convert.ToByte(SDOHelper.Read(oPurchaseRecord, "CURRENCY")) + 1);

    //Populate Order Header Fields
    SDOHelper.Write(oPopPost.Header, "ACCOUNT_REF",
      (String)SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"));
    SDOHelper.Write(oPopPost.Header, "NAME", (String)SDOHelper.Read(oPurchaseRecord, "NAME"));
    SDOHelper.Write(oPopPost.Header, "ADDRESS_1", (String)SDOHelper.Read(oPurchaseRecord, "ADDRESS_1"));
    SDOHelper.Write(oPopPost.Header, "ADDRESS_2", (String)SDOHelper.Read(oPurchaseRecord, "ADDRESS_2"));
    SDOHelper.Write(oPopPost.Header, "ADDRESS_3", (String)SDOHelper.Read(oPurchaseRecord, "ADDRESS_3"));
    SDOHelper.Write(oPopPost.Header, "ADDRESS_4", (String)SDOHelper.Read(oPurchaseRecord, "ADDRESS_4"));
    SDOHelper.Write(oPopPost.Header, "ADDRESS_5", (String)SDOHelper.Read(oPurchaseRecord, "ADDRESS_5"));
    SDOHelper.Write(oPopPost.Header, "DEL_ADDRESS_1", (String)SDOHelper.Read(oPurchaseRecord, "DEL_ADDRESS_1"));
    SDOHelper.Write(oPopPost.Header, "DEL_ADDRESS_2", (String)SDOHelper.Read(oPurchaseRecord, "DEL_ADDRESS_2"));
    SDOHelper.Write(oPopPost.Header, "DEL_ADDRESS_3", (String)SDOHelper.Read(oPurchaseRecord, "DEL_ADDRESS_3"));
    SDOHelper.Write(oPopPost.Header, "DEL_ADDRESS_4", (String)SDOHelper.Read(oPurchaseRecord, "DEL_ADDRESS_4"));
    SDOHelper.Write(oPopPost.Header, "DEL_ADDRESS_5", (String)SDOHelper.Read(oPurchaseRecord, "DEL_ADDRESS_5"));
    SDOHelper.Write(oPopPost.Header, "SUPP_TEL_NUMBER", (String)SDOHelper.Read(oPurchaseRecord, "TELEPHONE"));
    SDOHelper.Write(oPopPost.Header, "CONTACT_NAME", (String)"Chris Reed");

    //Populate other header information
    SDOHelper.Write(oPopPost.Header, "ORDER_DATE", (DateTime)DateTime.Today);
    SDOHelper.Write(oPopPost.Header, "NOTES_1", (String)"");
    SDOHelper.Write(oPopPost.Header, "NOTES_2", (String)"");
    SDOHelper.Write(oPopPost.Header, "NOTES_3", (String)"");
    SDOHelper.Write(oPopPost.Header, "TAKEN_BY", (String)"Mark Steel");
    SDOHelper.Write(oPopPost.Header, "SUPP_ORDER_NUMBER", (String)"");

    //Populate Foreign Currency Fields
    SDOHelper.Write(oPopPost.Header, "FOREIGN_RATE", SDOHelper.Read(oCurrencyData, "EXCHANGE_RATE"));
    SDOHelper.Write(oPopPost.Header, "CURRENCY", SDOHelper.Read(oPurchaseRecord, "CURRENCY"));
    SDOHelper.Write(oPopPost.Header, "CURRENCY_USED", SDOHelper.Read(oPurchaseRecord, "CURRENCY"));

    //Create an order item
    oPopItem = (SageDataObject300.PopItem)SDOHelper.Add(oPopPost.Items);

    //Read the fist stock code and populate item fields
    oStockRecord.MoveFirst();

    //Populate other fields required for POP 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 a NVD is set the item line values will be recalculated
    //regardless of the Tax_Flag being set to 1***
    SDOHelper.Write(oPopItem, "STOCK_CODE", (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));
    SDOHelper.Write(oPopItem, "DESCRIPTION", (String)SDOHelper.Read(oStockRecord, "DESCRIPTION"));
    SDOHelper.Write(oPopItem, "TAX_CODE", (Int16)SDOHelper.Read(oStockRecord, "TAX_CODE"));
    SDOHelper.Write(oPopItem, "QTY_ORDER", (Double)2);
    SDOHelper.Write(oPopItem, "UNIT_PRICE", (Double)100);
    SDOHelper.Write(oPopItem, "NET_AMOUNT", (Double)100);
    SDOHelper.Write(oPopItem, "FULL_NET_AMOUNT", (Double)100);
    SDOHelper.Write(oPopItem, "COMMENT_1", (String)"");
    SDOHelper.Write(oPopItem, "COMMENT_2", (String)"");
    SDOHelper.Write(oPopItem, "UNIT_OF_SALE", (String)"");
    SDOHelper.Write(oPopItem, "TAX_RATE", (Double)20);

    //Update the invoice
    if (oPopPost.Update())
    {
        MessageBox.Show("Purchase Order Created Successfully");
    }
    else
    {
        MessageBox.Show("Purchase Order Not Created");
    }

    //Disconnect
    oWS.Disconnect();
}
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}


Sage 50 Accounts - Example - Posting a Purchase Order with item VAT ammendable

Example - Posting a Purchase Order with item VAT ammendable

The example code below demonstrates Posting a Purchase Order with item VAT ammendable.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oPOPPost As SageDataObject300.PopPost
Dim oPOPItem As SageDataObject300.PopItem
Dim oPurchaseRecord As SageDataObject300.PurchaseRecord
Dim oStockRecord As SageDataObject300.StockRecord

' Declare Variables
Dim szDataPath As String

' Create Instance of SDO Engine
oSDO = New SageDataObject300.SDOEngine

' Create Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company.  The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

    ' Try to Connect - Will throw an exception if it fails
    If oWS.Connect(szDataPath, "", "", "Example") Then

        ' Create an Instance of POPPost & Record Objects
        oPurchaseRecord = oWS.CreateObject("PurchaseRecord")
        oStockRecord = oWS.CreateObject("StockRecord")
        oPOPPost = oWS.CreateObject("POPPost")

        ' Read the First Supplier
        oPurchaseRecord.MoveFirst()
        oPOPPost.Header("ACCOUNT_REF").Value = CStr(oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value)
        oPOPPost.Header("NAME").Value = CStr(oPurchaseRecord.Fields.Item("Name").Value)
        oPOPPost.Header("ADDRESS_1").Value = CStr(oPurchaseRecord.Fields.Item("ADDRESS_1").Value)
        oPOPPost.Header("ADDRESS_2").Value = CStr(oPurchaseRecord.Fields.Item("ADDRESS_2").Value)
        oPOPPost.Header("ADDRESS_3").Value = CStr(oPurchaseRecord.Fields.Item("ADDRESS_3").Value)
        oPOPPost.Header("ADDRESS_4").Value = CStr(oPurchaseRecord.Fields.Item("ADDRESS_4").Value)
        oPOPPost.Header("ADDRESS_5").Value = CStr(oPurchaseRecord.Fields.Item("ADDRESS_5").Value)
        oPOPPost.Header("DEL_ADDRESS_1").Value = CStr(oPurchaseRecord.Fields.Item("DEL_ADDRESS_1").Value)
        oPOPPost.Header("DEL_ADDRESS_2").Value = CStr(oPurchaseRecord.Fields.Item("DEL_ADDRESS_2").Value)
        oPOPPost.Header("DEL_ADDRESS_3").Value = CStr(oPurchaseRecord.Fields.Item("DEL_ADDRESS_3").Value)
        oPOPPost.Header("DEL_ADDRESS_4").Value = CStr(oPurchaseRecord.Fields.Item("DEL_ADDRESS_4").Value)
        oPOPPost.Header("DEL_ADDRESS_5").Value = CStr(oPurchaseRecord.Fields.Item("DEL_ADDRESS_5").Value)
        oPOPPost.Header("SUPP_TEL_NUMBER").Value = CStr(oPurchaseRecord.Fields.Item("TELEPHONE").Value)
        oPOPPost.Header("CONTACT_NAME").Value = CStr("Mark Steel")

        ' Populate other Order Header Information
        oPOPPost.Header("ORDER_DATE").Value = CDate(Today)
        oPOPPost.Header("NOTES_1").Value = CStr("")
        oPOPPost.Header("NOTES_2").Value = CStr("")
        oPOPPost.Header("NOTES_3").Value = CStr("")
        oPOPPost.Header("TAKEN_BY").Value = CStr("")
        oPOPPost.Header("SUPP_ORDER_NUMBER").Value = CStr("")

        ' Create an Order Item
        oPOPItem = oPOPPost.Items.Add()

        ' Read the first Stock Code and populate Item fields
        oStockRecord.MoveFirst()

        ' Populate other fields required for Invoice 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
        oPOPItem.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
        oPOPItem.Fields.Item("DESCRIPTION").Value = CStr(oStockRecord.Fields.Item("DESCRIPTION").Value)
        oPOPItem.Fields.Item("NOMINAL_CODE").Value = CStr(oPurchaseRecord.Fields.Item("DEF_NOM_CODE").Value)
        oPOPItem.Fields.Item("TAX_CODE").Value = CShort(oStockRecord.Fields.Item("TAX_CODE").Value)
        oPOPItem.Fields.Item("QTY_ORDER").Value = CDbl(1)
        oPOPItem.Fields.Item("UNIT_PRICE").Value = CDbl(133.33)
        oPOPItem.Fields.Item("NET_AMOUNT").Value = CDbl(133.33)
        oPOPItem.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(133.33)
        oPOPItem.Fields.Item("TAX_AMOUNT").Value = CDbl(26.66)
        oPOPItem.Fields.Item("COMMENT_1").Value = CStr("")
        oPOPItem.Fields.Item("COMMENT_2").Value = CStr("")
        oPOPItem.Fields.Item("UNIT_OF_SALE").Value = CStr("")
        oPOPItem.Fields.Item("TAX_RATE").Value = CDbl(20)
        ' Ensure the Tax Flag is set if calculating own Tax_Amount value
        oPOPItem.Fields.Item("TAX_FLAG").Value = CByte(1)

        ' Update the Invoice
        If oPOPPost.Update Then

            MsgBox("Purchase Order Created Successfully.", MsgBoxStyle.OkOnly, "SDO Examples")

        Else

            MsgBox("Purchase Order Not Created.", MsgBoxStyle.OkOnly, "SDO Examples")

        End If

        ' Disconnect
        oWS.Disconnect()

    End If

End If

' Destroy Objects
oPOPPost = Nothing
oPOPItem = Nothing
oPurchaseRecord = Nothing
oStockRecord = Nothing
oWS = Nothing
oSDO = Nothing

Exit Sub
C#.NET [image] Copy C# Code
//Declare Variables
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.PopPost oPopPost;
SageDataObject300.PopItem oPopItem;
SageDataObject300.PurchaseRecord oPurchaseRecord;
SageDataObject300.StockRecord oStockRecord;
String szDataPath;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails
try
{
    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

    //Instantiate objects
    oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");
    oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");
    oPopPost = (SageDataObject300.PopPost)oWS.CreateObject("PopPost");

    //Read the first supplier
    oPurchaseRecord.MoveFirst();

    //Populate the order Header Fields
    SDOHelper.Write(oPopPost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"));
    SDOHelper.Write(oPopPost.Header, "NAME", (String)SDOHelper.Read(oPurchaseRecord, "NAME"));
    SDOHelper.Write(oPopPost.Header, "ADDRESS_1", (String)SDOHelper.Read(oPurchaseRecord, "ADDRESS_1"));
    SDOHelper.Write(oPopPost.Header, "ADDRESS_2", (String)SDOHelper.Read(oPurchaseRecord, "ADDRESS_2"));
    SDOHelper.Write(oPopPost.Header, "ADDRESS_3", (String)SDOHelper.Read(oPurchaseRecord, "ADDRESS_3"));
    SDOHelper.Write(oPopPost.Header, "ADDRESS_4", (String)SDOHelper.Read(oPurchaseRecord, "ADDRESS_4"));
    SDOHelper.Write(oPopPost.Header, "ADDRESS_5", (String)SDOHelper.Read(oPurchaseRecord, "ADDRESS_5"));
    SDOHelper.Write(oPopPost.Header, "DEL_ADDRESS_1", (String)SDOHelper.Read(oPurchaseRecord, "DEL_ADDRESS_1"));
    SDOHelper.Write(oPopPost.Header, "DEL_ADDRESS_2", (String)SDOHelper.Read(oPurchaseRecord, "DEL_ADDRESS_2"));
    SDOHelper.Write(oPopPost.Header, "DEL_ADDRESS_3", (String)SDOHelper.Read(oPurchaseRecord, "DEL_ADDRESS_3"));
    SDOHelper.Write(oPopPost.Header, "DEL_ADDRESS_4", (String)SDOHelper.Read(oPurchaseRecord, "DEL_ADDRESS_4"));
    SDOHelper.Write(oPopPost.Header, "DEL_ADDRESS_5", (String)SDOHelper.Read(oPurchaseRecord, "DEL_ADDRESS_5"));
    SDOHelper.Write(oPopPost.Header, "SUPP_TEL_NUMBER", (String)SDOHelper.Read(oPurchaseRecord, "TELEPHONE"));
    SDOHelper.Write(oPopPost.Header, "CONTACT_NAME", (String)"Chris Reed");

    //Populate other header information
    SDOHelper.Write(oPopPost.Header, "ORDER_DATE", (DateTime)DateTime.Today);
    SDOHelper.Write(oPopPost.Header, "NOTES_1", (String)"");
    SDOHelper.Write(oPopPost.Header, "NOTES_2", (String)"");
    SDOHelper.Write(oPopPost.Header, "NOTES_3", (String)"");
    SDOHelper.Write(oPopPost.Header, "TAKEN_BY", (String)"Mark Steel");
    SDOHelper.Write(oPopPost.Header, "SUPP_ORDER_NUMBER", (String)"");

    //Create and order item
    oPopItem = (SageDataObject300.PopItem)SDOHelper.Add(oPopPost.Items);

    //Read the first stock code
    oStockRecord.MoveFirst();
    SDOHelper.Write(oPopItem, "STOCK_CODE", (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));
    SDOHelper.Write(oPopItem, "DESCRIPTION", (String)SDOHelper.Read(oStockRecord, "DESCRIPTION"));
    SDOHelper.Write(oPopItem, "NOMINAL_CODE", (String)SDOHelper.Read(oStockRecord, "NOMINAL_CODE"));
    SDOHelper.Write(oPopItem, "TAX_CODE", (Int16)SDOHelper.Read(oStockRecord, "TAX_CODE"));

    //Populate other fields required for POP 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 a NVD is set the item line values will be recalculated
    //regardless of the Tax_Flag being set to 1***
    SDOHelper.Write(oPopItem, "QTY_ORDER", (Double)2);
    SDOHelper.Write(oPopItem, "UNIT_PRICE", (Double)133.33);
    SDOHelper.Write(oPopItem, "NET_AMOUNT", (Double)133.33);
    SDOHelper.Write(oPopItem, "FULL_NET_AMOUNT", (Double)133.33);
    SDOHelper.Write(oPopItem, "TAX_AMOUNT", (Double)26.66);
    SDOHelper.Write(oPopItem, "COMMENT_1", (String)"");
    SDOHelper.Write(oPopItem, "COMMENT_2", (String)"");
    SDOHelper.Write(oPopItem, "UNIT_OF_SALE", (String)"");
    SDOHelper.Write(oPopItem, "TAX_RATE", (Double)20);
    // Ensure the Tax Flag is set if calculating own Tax_Amount value
    SDOHelper.Write(oPopItem, "TAX_FLAG", (Byte)1);

    //Update the PO
    if (oPopPost.Update())
    {
        MessageBox.Show("Purchase Order Created Successfully");
    }
    else
    {
        MessageBox.Show("Purchase Order Not Created");
    }

    //Disconnect
    oWS.Disconnect();
}
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}


Sage 50 Accounts - Example - Reading the Item Lines of an Existing Purchase Order

Example - Reading the Item Lines of an Existing Purchase Order

The example code below demonstrates how to read the Item Lines of an Existing Purchase Order.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
                                ' Declare Objects
Dim oSDO  As
                              SageDataObject300.SDOEngine
Dim oWS  As
                              SageDataObject300.WorkSpace
Dim  oPOPRecord  As
                              SageDataObject300.POPRecord
Dim  oPOPItem  As
                              SageDataObject300.POPItem

' Declare Variables
Dim szDataPath  As
                               String

' Create the SDO Engine Object
oSDO =  New   SageDataObject300.SDOEngine()

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company.  The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> ""  Then

' Try to Connect - Will throw an exception if it fails
If oWS.Connect(szDataPath, "", "", "Example")
                               Then

' Create an Instance of Objects
oPOPRecord = oWS.CreateObject("POPRecord")
oPOPItem = oWS.CreateObject("POPItem")

' Read an Existing POP
oPOPRecord.MoveLast()

' Link Items to Record
oPOPItem = oPOPRecord.Link

' Move to the First Item
oPOPItem.MoveFirst()

' Loop through POP items
Do

' Display the
                                  Item Product Code
MsgBox("Item " & CStr(oPOPItem.Fields.Item("ITEM_NUMBER").Value) & " has product code " &
                              CStr(oPOPItem.Fields.Item("STOCK_CODE").Value), MsgBoxStyle.OKOnly, "SDO Examples")

Loop Until Not  oPOPItem.MoveNext

End If

' Disconnect
oWS.Disconnect()

End If

' Destroy Objects
oPOPRecord =  Nothing
oPOPItem =  Nothing
oWS =  Nothing
oSDO =  Nothing

Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.PopRecord oPopRecord;

SageDataObject300.PopItem oPopItem;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate PopRecord Object

  oPopRecord = (SageDataObject300.PopRecord)oWS.CreateObject("PopRecord");

  //Read an existing POP

  oPopRecord.MoveFirst();

  //Link items to the current record

  oPopItem = (SageDataObject300.PopItem)oPopRecord.Link;

  //Move to the first item

  oPopItem.MoveFirst();

  //Loop through POP Items

  do

  {

    //Display the item product code

    MessageBox.Show("Item " + Convert.ToString(SDOHelper.Read(oPopItem, "ITEM_NUMBER"))

      + " has product code " +(String)SDOHelper.Read(oPopItem, "STOCK_CODE"));

  } while (oPopItem.MoveNext());

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Editing a Transaction Split

Example - Editing a Transaction Split

The example code below demonstrates how to edit a Transaction Split. You should only use this method to edit fields that, in Sage 50 Accounts, would not result in the original transaction being deleted and a new one posted. For example, you cannot use this method to change amounts on a transaction - if you need to do this, you should post a reversing transaction and then a new transaction with the new details.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
                                ' Declare Objects
Dim oSDO  As
                              SageDataObject300.SDOEngine
Dim oWS  As
                              SageDataObject300.WorkSpace
Dim oSalesRecord  As
                              SageDataObject300.SalesRecord
Dim oHeaderData  As
                              SageDataObject300.HeaderData
Dim oSplitData  As
                              SageDataObject300.SplitData

' Declare Variables
Dim szDataPath  As
                               String
Dim iSplitCount  As
                               Short

' Create the SDO Engine Object
oSDO =  New   SageDataObject300.SDOEngine()

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company.  The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> ""  Then

' Try to Connect - Will throw an exception if it fails
If oWS.Connect(szDataPath, "", "", "Example")
                               Then

' Create Instance of Object
oSalesRecord = oWS.CreateObject("SalesRecord")

' Read the First Customer
oSalesRecord.MoveFirst()

' Read the first Header
oHeaderData = oSalesRecord.Link
oHeaderData.MoveFirst()

' Read the first split on the header
oSplitData = oHeaderData.Link
oSplitData.MoveFirst()
oSplitData.Read(CInt(oSplitData.RecordNumber))

' Amend the split details
oSplitData.Fields.Item("DETAILS").Value = CStr("Amended by the SDO")

' Write the split data
If
                              oSplitData.Write(CInt(oSplitData.RecordNumber))  Then

' Amend Successful
MsgBox("Split successfully amended.")

Else

' Amend Unsuccessful
MsgBox("Failed to amend split.")

End If

' Disconnect
oWS.Disconnect()

End If

End If

' Destroy Objects
oHeaderData =  Nothing
oSplitData =  Nothing
oSalesRecord =  Nothing
oWS =  Nothing
oSDO =  Nothing

Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.SalesRecord oSalesRecord;

SageDataObject300.HeaderData oHeaderData;

SageDataObject300.SplitData oSplitData;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate the Sales Record object

  oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");

  //Read the first customer

  oSalesRecord.MoveFirst();

  //Link the header object and read the first record

  oHeaderData = (SageDataObject300.HeaderData)oSalesRecord.Link;

  oHeaderData.MoveFirst();

  //Link the split object and read the first record

  oSplitData = (SageDataObject300.SplitData)oHeaderData.Link;

  oSplitData.MoveFirst();

  //Amend the split details

  SDOHelper.Write(oSplitData, "DETAILS", (String)"Amended by SDO");

  //Write the split data

  if (oSplitData.Write((Int32)oSplitData.RecordNumber))

  {

    MessageBox.Show("Split successfully amended");

  }

  else

  {

    MessageBox.Show("Failed to amend split");

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Flag Disputed Transactions

Example - Flag Disputed Transactions

The example code below demonstrates how to flag transactions as disputed.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code

' Declare Objects

Dim oSDO As SageDataObject300.SDOEngine

Dim oWS As SageDataObject300.WorkSpace

Dim oSalesRecord As SageDataObject300.SalesRecord

Dim oHeaderData As SageDataObject300.HeaderData

Dim oSplitData As SageDataObject300.SplitData

' Declare Variables

Dim szDataPath As String

' Create the SDO Engine Object

oSDO = New SageDataObject300.SDOEngine

' Create the Workspace

oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install

' folder as a parameter

szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,

' the path will be passed to the szDataPath variable.

' If not, or the Cancel button is selected, the variable will be left empty.

If szDataPath <> "" Then

' Try to Connect - Will throw an exception if it fails

If oWS.Connect(szDataPath, "", "", "Example") Then

' Create Instances of Objects

oSalesRecord = oWS.CreateObject("SalesRecord")

oSplitData = oWS.CreateObject("SplitData")

oHeaderData = oWS.CreateObject("HeaderData")

' Read the First Customer

oSalesRecord.MoveFirst()

' link the headerData for this customer record

oHeaderData = oSalesRecord.Link

oHeaderData.MoveFirst()

' display number of splits

MsgBox("This Transaction contains " & CType(oHeaderData.Fields.Item("NO_OF_SPLIT").Value, Integer) & " splits")

' link the splitData for this Header

oSplitData = oHeaderData.Link

oSplitData.MoveFirst()

Do

' open the split for reading and writing

oSplitData.Open(SageDataObject300.OpenMode.sdoReadWrite)

' set the values

oSplitData.Fields.Item("DISPUTE_TYPE").Value = CShort(1) ' this number can be up to 1000

oSplitData.Fields.Item("STATUS").Value = CShort(1)

' write the data back to the data set

oSplitData.Write(oSplitData.RecordNumber)

' you must set the No. of disputed items, for the header, yourself

oHeaderData.Fields.Item("NO_DISPUTED").Value += 1

' write the data back to the data set

oHeaderData.Write(oHeaderData.RecordNumber)

Loop Until Not oSplitData.MoveNext

' Close Data Objects

oSplitData.Close()

oHeaderData.Close()

' Disconnect

oWS.Disconnect()

End If

End If

' Destroy Objects

oSplitData = Nothing

oHeaderData = Nothing

oSalesRecord = Nothing

oWS = Nothing

oSDO = Nothing

End Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.SalesRecord oSalesRecord;

SageDataObject300.HeaderData oHeaderData;

SageDataObject300.SplitData oSplitData;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

//Leaving the username and password blank generates a login dialog

oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

// Create Instances of Objects

oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");

oSplitData = (SageDataObject300.SplitData)oWS.CreateObject("SplitData");

oHeaderData = (SageDataObject300.HeaderData)oWS.CreateObject("HeaderData");

// Read the First Customer

oSalesRecord.MoveFirst();

// Link the headerdata for this customer record

oHeaderData = (SageDataObject300.HeaderData)oSalesRecord.Link;

oHeaderData.MoveFirst();

// Display number of splits]

MessageBox.Show("This transaction contains " + Convert.ToString(SDOHelper.Read(oHeaderData, "NO_OF_SPLIT")) + " splits");

// Link the split data fot this Header

oSplitData = (SageDataObject300.SplitData)oHeaderData.Link;

oSplitData.MoveFirst();

do

{

//set the values

SDOHelper.Write(oSplitData, "DISPUTE_TYPE", (Int16)1);

SDOHelper.Write(oSplitData, "STATUS", (Int16)1);

//write the data back to the data set

oSplitData.Write((Int32)oSplitData.RecordNumber);

MessageBox.Show("Tran No " + Convert.ToString(SDOHelper.Read(oSplitData, "TRAN_NUMBER") + " Dispute Type " + Convert.ToString(SDOHelper.Read(oSplitData, "DISPUTE_TYPE") + " Status " + Convert.ToString(SDOHelper.Read(oSplitData, "STATUS")))));

// you must set the number of disputed items, for the header, yourself

SDOHelper.Write(oHeaderData, "NO_DISPUTED", (Int16)2);

//write the data back to the data set

oHeaderData.Write((Int32)oHeaderData.RecordNumber);

} while (!(!oSplitData.MoveNext()));

//Disconnect

oWS.Disconnect();

// Destroy objects

oSplitData = null;

oHeaderData = null;

oSalesRecord = null;

oWS = null;

oSDO = null;

}

catch (Exception ex)

{

MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}

}

}


Sage 50 Accounts - Example - Finding Invoice Payments

Example - Find Invoice Payments

The following code example demonstrates how to find payments relating to specific invoices in Sage 50 Accounts. The code will find all invoices that have a payment against them for a particular customer then drill down through the audit trail to find any payments made. Examples are available in VB.NET and C#.NET.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code

'Declare Objects

Dim oSDO As SageDataObject300.SDOEngine

Dim oWS As SageDataObject300.WorkSpace

Dim oSalesRecord As SageDataObject300.SalesRecord

Dim oHeaderData As SageDataObject300.HeaderData

Dim oSplitData As SageDataObject300.SplitData

Dim oUsageData As SageDataObject300.UsageData

'Declare Variables

Dim szDataPath As String

Dim bFlag As Boolean

'Create the SDOEngine Object

oSDO = New SageDataObject300.SDOEngine

'Create the Workspace

oWS = oSDO.Workspaces.Add("Example")

'Select Company. The SelectCompany method takes the program install

'folder as a parameter

szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

'A U.I. for company selection is presented to the user. If a company is selected,

'the path will be passed to the szDataPath variable.

'If not, or the Cancel button is selected, the variable will be left empty.

Try

If szDataPath <> "" Then

'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")

' Populate index field with value to search for

oSalesRecord.Fields.Item("ACCOUNT_REF").Value = CStr("AAAA")

' Perform Exact match find

bFlag = oSalesRecord.Find(False)

If bFlag Then

'Use the Link Method to get the Headers for the Customer Account

oHeaderData = oSalesRecord.Link

'Move to the First Header - This gives access to the transaction information

oHeaderData.MoveFirst()

Do

'Check to see if header is a sales invoice has had a payment made against it. If partially

'paid will still have a flag against it

If oHeaderData.Fields.Item("TYPE").Value = CByte(SageDataObject300.TransType.sdoSI) Then

'Check that a payment has been made against the account

If oHeaderData.Fields.Item("AMOUNT_PAID").Value > 0 Then

'Use the Link method to get the Splits for the Header

oSplitData = oHeaderData.Link

'At the Split level we now have access to the transaction information

'Now loop through the Splits as there may be more than one

oSplitData.MoveFirst()

Do

'Check the splits to see if a payment has been made

If oSplitData.Fields.Item("AMOUNT_PAID").Value > 0 Then

'Use the Link method again to get the Usages for the Split

oUsageData = oSplitData.Link

'Now Loop through the Usages as there may be more than one

oUsageData.MoveFirst()

Do

'Return data from the payment made against the Invoice

MessageBox.Show("Invoice Ref: " & oHeaderData.Fields.Item("INV_REF").Value & ControlChars.NewLine & _

"Split Number: " & oUsageData.Fields.Item("SPLIT_NUMBER").Value.ToString() & " Payment Amount " & _

oUsageData.Fields.Item("AMOUNT").Value.ToString() & ControlChars.NewLine & _

"Paid By Sales Reciept: " & oUsageData.Fields.Item("SPLIT_CROSSREF").Value.ToString())

Loop Until Not oUsageData.MoveNext

End If

Loop Until Not oSplitData.MoveNext

End If

End If

Loop Until Not oHeaderData.MoveNext

Else

MsgBox("The find has not found a match to your criteria", vbOKOnly Or vbInformation, "SDO")

End If

End If

End If

Catch ex As Exception

MessageBox.Show(ex.Message.ToString)

Finally

'Disconnect

oWS.Disconnect()

'Destroy Objects

oSalesRecord = Nothing

oHeaderData = Nothing

oSplitData = Nothing

oUsageData = Nothing

oWS = Nothing

oSDO = Nothing

End Try
C#.NET [image] Copy C# Code

//Declare Objects

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.SalesRecord oSalesRecord;

SageDataObject300.HeaderData oHeaderData;

SageDataObject300.SplitData oSplitData;

SageDataObject300.UsageData oUsageData;

//Declare Variables

string szDataPath;

bool bFlag = false;

//Create the SDOEngine Object

oSDO = new SageDataObject300.SDOEngine();

//Create the Workspace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Select Company. The SelectCompany method takes the program install

//folder as a parameter

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

try

{

//A U.I. for company selection is presented to the user. If a company is selected,

//the path will be passed to the szDataPath variable.

//If not, or the Cancel button is selected, the variable will be left empty.

if (!string.IsNullOrEmpty(szDataPath))

{

//Try to Connect - Will Throw an Exception if it Fails

oWS.Connect(szDataPath, "", "", "Example");

//Create an Instance of the SalesRecord Object

oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");

// Populate index field with value to search for

SDOHelper.Write(oSalesRecord,"ACCOUNT_REF",(String)"AAAA");

// Perform Exact match find

bFlag = oSalesRecord.Find(false);

if (bFlag)

{

//Use the Link Method to get the Headers for the Customer Account

oHeaderData = (SageDataObject300.HeaderData)oSalesRecord.Link;

//Move to the First Header - This gives access to the transaction information

oHeaderData.MoveFirst();

do

{

//Check to see if header is a sales invoice has had a payment made against it. If partially

//paid will still have a flag against it

if (Convert.ToByte(SDOHelper.Read(oHeaderData, "TYPE")) == (byte)SageDataObject300.TransType.sdoSI)

{

//Check that a payment has been made against the account

if (Convert.ToInt32(SDOHelper.Read(oHeaderData, "AMOUNT_PAID")) > 0)

{

//Use the Link method to get the Splits for the Header

oSplitData = (SageDataObject300.SplitData)oHeaderData.Link;

//At the Split level we now have access to the transaction information

//Now loop through the Splits as there may be more than one

oSplitData.MoveFirst();

do

{

//Check the splits to see if a payment has been made

if (Convert.ToInt32(SDOHelper.Read(oSplitData, "AMOUNT_PAID")) > 0)

{

//Use the Link method again to get the Usages for the Split

oUsageData = (SageDataObject300.UsageData)oSplitData.Link;

//Now Loop through the Usages as there may be more than one

oUsageData.MoveFirst();

do

{

//Return data from the payment made against the Invoice

MessageBox.Show("Invoice Ref: " + SDOHelper.Read(oHeaderData, "INV_REF") +

Environment.NewLine + "Split Number: " + SDOHelper.Read(oUsageData, "SPLIT_NUMBER") +

" Payment Amount " + SDOHelper.Read(oUsageData, "AMOUNT") + Environment.NewLine +

"Paid By Sales Reciept: " + SDOHelper.Read(oUsageData, "SPLIT_CROSSREF"));

}

while (!(!oUsageData.MoveNext()));

}

}

while (!(!oSplitData.MoveNext()));

}

}

}

while (!(!oHeaderData.MoveNext()));

}

else

{

MessageBox.Show("The find has not found a match to your criteria");

}

}

}

catch (Exception ex)

{

MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}

finally

{

//Disconnect

oWS.Disconnect();

//Destroy Objects

oSalesRecord = null;

oHeaderData = null;

oSplitData = null;

oUsageData = null;

oWS = null;

oSDO = null;

}


Sage 50 Accounts - Example - Creating a New Fixed Asset Record

Example - Creating a New Fixed Asset Record

The example code below demonstrates how to create a new Fixed Asset Record.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oAssetRecord As SageDataObject300.AssetRecord
Dim oPurchaseRecord As SageDataObject300.PurchaseRecord

' Declare Variables
Dim szDataPath As String

' Create the SDOEngine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

' Try to Connect - Will Throw an Exception if it Fails
If oWS.Connect(szDataPath, "", "", "Example") Then

' Create Instances of the Asset and Purchase Objects
oAssetRecord = oWS.CreateObject("AssetRecord")
oPurchaseRecord = oWS.CreateObject("PurchaseRecord")

' Move to First Supplier
oPurchaseRecord.MoveFirst()

' Try to Add a New Record
If oAssetRecord.AddNew Then

oAssetRecord.Fields.Item("ASSET_CAT").Value = CShort(1)
oAssetRecord.Fields.Item("ASSET_REF").Value = CStr("SDOAsset")
oAssetRecord.Fields.Item("BAL_SHEET_NOM_CODE").Value = CStr("0030")
oAssetRecord.Fields.Item("COST_PRICE").Value = CDbl(1000#)
oAssetRecord.Fields.Item("DEP_LAST").Value = CDbl(0#)
oAssetRecord.Fields.Item("DEP_METHOD_CODE").Value = CShort(SageDataObject300.DepreciationType.sdoSDP)
oAssetRecord.Fields.Item("DEP_RATE").Value = CDbl(10#)
oAssetRecord.Fields.Item("DEP_TO_DATE").Value = CDbl(0#)
oAssetRecord.Fields.Item("DEPT_NUMBER").Value = CShort(0)
oAssetRecord.Fields.Item("DETAILS_1").Value = CStr("SDO Generate Fixed Asset Details 1")
oAssetRecord.Fields.Item("DETAILS_2").Value = CStr("Details Line 2")
oAssetRecord.Fields.Item("DETAILS_3").Value = CStr("Details Line 3")
oAssetRecord.Fields.Item("EMPLOYEE").Value = CStr("SDO Employee")
oAssetRecord.Fields.Item("NET_BOOK").Value = CDbl(1000#)
oAssetRecord.Fields.Item("POST_DATE").Value = CDate(Today)
oAssetRecord.Fields.Item("PROFIT_LOSS_NOM_CODE").Value = CStr("8004")
oAssetRecord.Fields.Item("PURCHASE_DATE").Value = CDate(Today)
oAssetRecord.Fields.Item("PURCHASE_REF").Value = oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value
oAssetRecord.Fields.Item("SERIAL_NUMBER").Value = CStr("SDO Serial Number")

' Update the Record
If oAssetRecord.Update Then

' The Update was Successful
MsgBox("Asset '" & oAssetRecord.Fields.Item("ASSET_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

End If

' Destroy Objects
oPurchaseRecord = Nothing
oAssetRecord = Nothing
oSDO = Nothing
oWS = Nothing

Exit Sub
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.AssetRecord oAssetRecord;

SageDataObject300.PurchaseRecord oPurchaseRecord;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate Purchase and Asset record objects

  oAssetRecord = (SageDataObject300.AssetRecord)oWS.CreateObject("AssetRecord");

  oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");

  //Move to the first supplier

  oPurchaseRecord.MoveFirst();

  //Try and add a new record

  if (oAssetRecord.AddNew())

  {

    //Populate Fields

    SDOHelper.Write(oAssetRecord, "ASSET_CAT", (Int16)1);

    SDOHelper.Write(oAssetRecord, "ASSET_REF", (String)"SDOAsset");

    SDOHelper.Write(oAssetRecord, "BAL_SHEET_NOM_CODE", (String)"0030");

    SDOHelper.Write(oAssetRecord, "COST_PRICE", (Double)1000);

    SDOHelper.Write(oAssetRecord, "DEP_LAST", (Double)0);

    SDOHelper.Write(oAssetRecord, "DEP_METHOD_CODE", (Int16)SageDataObject300.DepreciationType.sdoSDP);

    SDOHelper.Write(oAssetRecord, "DEP_RATE", (Double)10);

    SDOHelper.Write(oAssetRecord, "DEP_TO_DATE", (Double)0);

    SDOHelper.Write(oAssetRecord, "DEPT_NUMBER", (Int16)0);

    SDOHelper.Write(oAssetRecord, "DETAILS_1", (String)"SDO Generated Fixed Asset Details 1");

    SDOHelper.Write(oAssetRecord, "DETAILS_2", (String)"Details 2");

    SDOHelper.Write(oAssetRecord, "DETAILS_3", (String)"Details 3");

    SDOHelper.Write(oAssetRecord, "EMPLOYEE", (String)"SDO Employee");

    SDOHelper.Write(oAssetRecord, "NET_BOOK", (Double)1000);

    SDOHelper.Write(oAssetRecord, "POST_DATE", (DateTime)DateTime.Today);

    SDOHelper.Write(oAssetRecord, "PROFIT_LOSS_NOM_CODE", (String)"8004");

    SDOHelper.Write(oAssetRecord, "PURCHASE_DATE", (DateTime)DateTime.Today);

    SDOHelper.Write(oAssetRecord, "PURCHASE_REF", (String)SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"));

    SDOHelper.Write(oAssetRecord, "SERIAL_NUMBER", (String)"SDO Serial Number");

    //Update the record

    if (oAssetRecord.Update())

    {

      MessageBox.Show("Asset '" + SDOHelper.Read(oAssetRecord, "ASSET_REF") + "' Was Created Successfully");

    }

    else

    {

      MessageBox.Show("The account could not be created");

    }

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Amending a Project Cost Code

Example - Amending a Project Cost Code

The example code below demonstrates how to amend a Project Costing CostCode.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oCostCode As SageDataObject300.ProjectCostCode

Dim szDataPath As String

Try
' Create the SDO Engine object
 oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
 oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install folder as a parameter
 szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
 If szDataPath <> "" Then

' Connect to Data Files
 If oWS.Connect(szDataPath, "", "", "Example") Then
' Create Objects
oCostCode = oWS.CreateProjectCostCode

If oCostCode.Load("LAB1") Then
' Change the Cost Code Description details
oCostCode.Description = "New Labour Charge"

' Save the cost code
If oCostCode.Update() Then

MessageBox.Show("The Cost Code Save was successful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)

Else
MessageBox.Show("The Cost Code Save was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

End If

Else

 MessageBox.Show("The Cost Code Load was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

End If

Else

 MessageBox.Show("Could not logon to the data.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

End If

End If

Catch ex As Exception
' Show the exception error message
MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

Finally

 If Not oWs Is Nothing Then
 oWS.Disconnect()
 oWs = Nothing
 End If
' Dispose of any objects
 If Not oSDO Is Nothing Then oSDO = Nothing
If Not oCostCode Is Nothing Then oCostCode = Nothing
End Try
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            SageDataObject300.ProjectCostCode oCostCode;

            // Create Objects
            oCostCode = (SageDataObject300.ProjectCostCode)oWS.CreateProjectCostCode();

            try
            {
                // Declare a CostCode object
                Object ccode = "SDO_CODE";

                if (oCostCode.Load(ref ccode))
                {
                    // Make required changes
                    oCostCode.Description = (String)"New SDO_CODE description";

                    // Delee the CostCode
                    if (oCostCode.Update())
                    {
                        MessageBox.Show("The CostCode Update was successful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    }

                    else
                    {
                        MessageBox.Show("The CostCode Update was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                else
                {
                    MessageBox.Show("The CostCode Load was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                if ((oWS != null))
                {
                    oWS.Disconnect();
                    oWS = null;
                }
                // Dispose of any objects
                if (oSDO != null) oSDO = null;
                if (oCostCode != null) oCostCode = null;
            }
        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Amending a Project Record

Example - Amending a Project Record

The example code below demonstrates how to amend a Project Costing Record.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
 Dim oSDO As SageDataObject300.SDOEngine
 Dim oWS As SageDataObject300.WorkSpace
 Dim oProject As SageDataObject300.Project

 Dim szDataPath As String

 Try
   ' Create the SDO Engine object
    oSDO = New SageDataObject300.SDOEngine

   ' Create the Workspace
    oWS = oSDO.Workspaces.Add("Example")

   ' Select company. The SelectCompany method takes the program install folder as a parameter
    szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

   ' A U.I. for company selection is presented to the user. If a company is selected,
   ' the path will be passed to the szDataPath variable.
   ' If not, or the Cancel button is selected, the variable will be left empty.
    If szDataPath <> "" Then

     ' Connect to Data Files
      If oWS.Connect(szDataPath, "", "", "Example") Then
       ' Create Objects
       oProject = oWS.CreateProject

       If oProject.Load("PROJ1") Then

        ' Change the Name
         oProject.Name = "Amended Project Name"

         ' Save the project
         If oProject.Update() Then
           MessageBox.Show("The Project Save was successful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)

         Else
           MessageBox.Show("The Project Save was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

         End If

       Else

         MessageBox.Show("The Project Load was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

       End If

     Else

       MessageBox.Show("Could not logon to the data.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

     End If

   End If

 Catch ex As Exception
   ' Show the exception error message
   MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

 Finally

   If Not oWs Is Nothing Then
      oWS.Disconnect()
     oWs = Nothing
   End If
   ' Dispose of any objects
   If Not oSDO Is Nothing Then oSDO = Nothing
   If Not oProject Is Nothing Then oProject = Nothing
 End Try
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            SageDataObject300.Project oProject;

            // Create Objects
            oProject = (SageDataObject300.Project)oWS.CreateProject();

            try
            {
                // Declare a Project object
                Object proj = "PROJ1";

                if (oProject.Load(ref proj))
                {
                    // Change the Name
                    oProject.Name = "Amended Project Name";

                    // Save the project
                    if (oProject.Update())
                    {
                        MessageBox.Show("The Project Save was successful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    }

                    else
                    {
                        MessageBox.Show("The Project Save was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                else
                {
                    MessageBox.Show("The Project Load was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                if ((oWS != null))
                {
                    oWS.Disconnect();
                    oWS = null;
                }
                // Dispose of any objects
                if (oSDO != null) oSDO = null;
                if (oProject != null) oProject = null;
            }
        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Amending a Project Resource

Example - Amending a Project Resource

The example code below demonstrates how to amend a Project Costing Resource.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
 Dim oSDO As SageDataObject300.SDOEngine
 Dim oWS As SageDataObject300.WorkSpace
 Dim oResource As SageDataObject300.ProjectResource

 Dim szDataPath As String

 Try
   ' Create the SDO Engine object
    oSDO = New SageDataObject300.SDOEngine

   ' Create the Workspace
    oWS = oSDO.Workspaces.Add("Example")

   ' Select company. The SelectCompany method takes the program install folder as a parameter
    szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

   ' A U.I. for company selection is presented to the user. If a company is selected,
   ' the path will be passed to the szDataPath variable.
   ' If not, or the Cancel button is selected, the variable will be left empty.
    If szDataPath <> "" Then

     ' Connect to Data Files
      If oWS.Connect(szDataPath, "", "", "Example") Then
       ' Create Objects
       oResource = oWS.CreateProjectResource

       If oResource.Load("RES1") Then

         ' Change the Resource Description details
         oResource.Name = "New Resource One"

         ' Save the resource
         If oResource.Update() Then
           MessageBox.Show("The Resource Save was successful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)

         Else
           MessageBox.Show("The Resource Save was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

         End If

       Else

         MessageBox.Show("The Resource Load was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

       End If

     Else

       MessageBox.Show("Could not logon to the data.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

     End If

   End If

 Catch ex As Exception
   ' Show the exception error message
   MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

 Finally

   If Not oWs Is Nothing Then
      oWS.Disconnect()
     oWs = Nothing
   End If
   ' Dispose of any objects
   If Not oSDO Is Nothing Then oSDO = Nothing
   If Not oResource Is Nothing Then oResource = Nothing
 End Try
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.ProjectResource oResource;

            try
            {
               // Create Objects
               oResource = (SageDataObject300.ProjectResource)oWS.CreateProjectResource();

               Object resName = "RES1";
               if (oResource.Load(ref resName))
               {
                   // Change the resource Name
                   oResource.Name = (String)"New Resource One";

                   // Update/Save the resource
                   if (oResource.Update())
                   {
                       MessageBox.Show("The Resource Save was successful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                   }
                   else
                   {
                       MessageBox.Show("The Resource Save was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                   }
               }
               else
               {
                   MessageBox.Show("The Resource Load was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
               }

            }
            // Error Handling Code
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Example", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            oWS.Disconnect();

        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Amending a Project Status

Example - Amending a Project Status

The example code below demonstrates how to amend a Project Costing Status.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
 Dim oSDO As SageDataObject300.SDOEngine
 Dim oWS As SageDataObject300.WorkSpace
 Dim oStatus As SageDataObject300.ProjectStatus

 Dim szDataPath As String

 Try
   ' Create the SDO Engine object
    oSDO = New SageDataObject300.SDOEngine

   ' Create the Workspace
    oWS = oSDO.Workspaces.Add("Example")

   ' Select company. The SelectCompany method takes the program install folder as a parameter
    szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

   ' A U.I. for company selection is presented to the user. If a company is selected,
   ' the path will be passed to the szDataPath variable.
   ' If not, or the Cancel button is selected, the variable will be left empty.
    If szDataPath <> "" Then

     ' Connect to Data Files
      If oWS.Connect(szDataPath, "", "", "Example") Then
       ' Create Objects
       oStatus = oWS.CreateProjectStatus

       If oStatus.Load("NEWACTIVE") Then

         ' Change the Status Name details
         oStatus.Name = "New Active Status"

         ' Save the status
         If oStatus.Update() Then
           MessageBox.Show("The Status Save was successful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)

         Else
           MessageBox.Show("The Status Save was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

         End If

       Else

         MessageBox.Show("The Status Load was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

       End If

     Else

       MessageBox.Show("Could not logon to the data.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

     End If

   End If

 Catch ex As Exception
   ' Show the exception error message
   MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

 Finally

   If Not oWs Is Nothing Then
      oWS.Disconnect()
     oWs = Nothing
   End If
   ' Dispose of any objects
   If Not oSDO Is Nothing Then oSDO = Nothing
   If Not oStatus Is Nothing Then oStatus = Nothing
 End Try
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.ProjectStatus oStatus;

            try
            {
               // Create Objects
               oStatus = (SageDataObject300.ProjectStatus)oWS.CreateProjectStatus();

               Object statusName = "NEWACTIVE";
               if (oStatus.Load(ref statusName))
               {

                   // Change the Status details
                   oStatus.Name = (String)"New Active Status (Amended)";

                   // Save the status
                   if (oStatus.Update())
                   {
                       MessageBox.Show("The Status Save was successful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                   }
                   else
                   {
                       MessageBox.Show("The Status Save was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                   }
               }
               else
               {
                   MessageBox.Show("The Status Load was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
               }

            }
            // Error Handling Code
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Example", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            oWS.Disconnect();

        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Creating a New Project Record

Example - Creating a New Project Record

The example code below demonstrates how to create a new Project Costing Project.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
 Dim oSDO As SageDataObject300.SDOEngine
 Dim oWS As SageDataObject300.WorkSpace
 Dim oProject As SageDataObject300.Project
 Dim oSalesRecord As SageDataObject300.SalesRecord
 Dim oCustomer As SageDataObject300.Customer
 Dim oStatus As SageDataObject300.ProjectStatus
 Dim oCountry As SageDataObject300.Country

 Dim szDataPath As String

 Try
   ' Create the SDO Engine object
    oSDO = New SageDataObject300.SDOEngine

   ' Create the Workspace
    oWS = oSDO.Workspaces.Add("Example")

   ' Select company. The SelectCompany method takes the program install folder as a parameter
    szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

   ' A U.I. for company selection is presented to the user. If a company is selected,
   ' the path will be passed to the szDataPath variable.
   ' If not, or the Cancel button is selected, the variable will be left empty.
    If szDataPath <> "" Then

     ' Connect to Data Files
      If oWS.Connect(szDataPath, "", "", "Example") Then
       ' Create Objects
       oProject = oWS.CreateProject
       oCustomer = oWS.CreateCustomer
       oCountry = oWS.CreateCountry
       oStatus = oWS.CreateProjectStatus
       oSalesRecord = oWS.CreateObject("SalesRecord")

       ' Set the Project main titles
       oProject.Reference = "PROJECT1"
       oProject.Name = "Project One"
       oProject.Description = "Project for A1 Design Services"

       ' Set the Price, Budget and Order Number
       oProject.PriceQuoted = CDbl(10000)
       oProject.TotalBudget = CDbl(5000)
       oProject.OrderNumber = "0001"

       ' Load the Project Status with a StatusID of '1'
       If oStatus.Load(1) Then

         ' Set the .Status object on the project
         oProject.Status = oStatus

       End If
       ' Populate index field with value to search for
       oSalesRecord.Fields.Item("ACCOUNT_REF").Value = CStr("A1D001")

       ' Perform Exact match find
       If oSalesRecord.Find(False) Then
         'Store the Sales Ledger Account Reference
         Dim strSalesRef As String = oSalesRecord.Fields.Item("ACCOUNT_REF").Value

         'Load the Customer object using the oSalesRecord ACCOUNT_REF value
         If oCustomer.Load(strSalesRef) Then
           ' Set the .Customer object on the project
           oProject.Customer = oCustomer

         End If
         ' Populate contact/address details
         oProject.Contact = oSalesRecord.Fields.Item("CONTACT_NAME").Value
         oProject.Address1 = oSalesRecord.Fields.Item("ADDRESS_1").Value
         oProject.Address2 = oSalesRecord.Fields.Item("ADDRESS_2").Value
         oProject.Address3 = oSalesRecord.Fields.Item("ADDRESS_3").Value
         oProject.Address4 = oSalesRecord.Fields.Item("ADDRESS_4").Value
         oProject.Address5 = oSalesRecord.Fields.Item("ADDRESS_5").Value
         oProject.EMail = oSalesRecord.Fields.Item("E_MAIL").Value
         oProject.Fax = oSalesRecord.Fields.Item("FAX").Value
         oProject.Telephone = oSalesRecord.Fields.Item("TELEPHONE").Value

         ' Store the Sales Ledger Country Code
         Dim strCountryCode As String = oSalesRecord.Fields.Item("COUNTRY_CODE").Value

         ' Load the Country object using the oSalesRecord COUNTRY_CODE value
         If oCountry.Load(strCountryCode) Then
           ' Set the Country object on the project
           oProject.Country = oCountry

         End If
       End If
       ' Set the Start and End Dates of the project
       oProject.StartDate = Today
       oProject.EndDate = System.DateTime.Today.AddMonths(12)

       ' Save the project
       If oProject.Update Then
         MessageBox.Show("The Project Save was successful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)

       Else
         MessageBox.Show("The Project Save was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

       End If

     Else

       MessageBox.Show("Could not logon to the data.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

     End If

   End If

 Catch ex As Exception
   ' Show the exception error message
   MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

 Finally

   If Not oWs Is Nothing Then
      oWS.Disconnect()
     oWs = Nothing
   End If
   ' Dispose of any objects
   If Not oSDO Is Nothing Then oSDO = Nothing
   If Not oProject Is Nothing Then oProject = Nothing
   If Not oSalesRecord Is Nothing Then oSalesRecord = Nothing
   If Not oCustomer Is Nothing Then oCustomer = Nothing
   If Not oStatus Is Nothing Then oStatus = Nothing
   If Not oCountry Is Nothing Then oCountry = Nothing
 End Try
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.Project oProject;

SageDataObject300.SalesRecord oSalesRecord;

SageDataObject300.Customer oCustomer;

SageDataObject300.ProjectStatus oStatus;

SageDataObject300.Country oCountry;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate Objects

  oProject = (SageDataObject300.Project)oWS.CreateProject();

  oCustomer = (SageDataObject300.Customer)oWS.CreateCustomer();

  oCountry = (SageDataObject300.Country)oWS.CreateCountry();

  oStatus = (SageDataObject300.ProjectStatus)oWS.CreateProjectStatus();

  oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");

  //Set the project main titles

  oProject.Reference = (String)"PROJECT1";

  oProject.Name = (String)"Project One";

  oProject.Description = (String)"Project for A1 Design Services";

  //Set the price, budget and order number

  oProject.PriceQuoted = (Double)10000;

  oProject.TotalBudget = (Double)5000;

  oProject.OrderNumber = (String)"0001";

  //Load the project status with as StatusID of '1'

  //Note: In C# you need to pass an object reference

  Object status = 1;

  if (oStatus.Load(ref status))

  {

    //Set the .Status object on the project

    oProject.Status = oStatus;

  }

  //Populate index field with a value to search for

  SDOHelper.Write(oSalesRecord, "ACCOUNT_REF", (String)"A1D001");

  //Perform an exact match find

  if (oSalesRecord.Find(false))

  {

    //Load the Customer object using the oSalesRecord ACCOUNT_REF value

    Object CustAccRef = (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF");;

    if (oCustomer.Load(ref CustAccRef))

    {

      //Set the customer object on the project

      oProject.Customer = oCustomer;

    }

    //Populate Contact / Address Details

    oProject.Contact = (String)SDOHelper.Read(oSalesRecord, "CONTACT_NAME");

    oProject.Address1 = (String)SDOHelper.Read(oSalesRecord, "ADDRESS_1");

    oProject.Address2 = (String)SDOHelper.Read(oSalesRecord, "ADDRESS_2");

    oProject.Address3 = (String)SDOHelper.Read(oSalesRecord, "ADDRESS_3");

    oProject.Address4 = (String)SDOHelper.Read(oSalesRecord, "ADDRESS_4");

    oProject.Address5 = (String)SDOHelper.Read(oSalesRecord, "ADDRESS_5");

    oProject.EMail = (String)SDOHelper.Read(oSalesRecord, "E_MAIL");

    oProject.Fax = (String)SDOHelper.Read(oSalesRecord, "FAX");

    oProject.Telehpone = (String)SDOHelper.Read(oSalesRecord, "TELEPHONE");

    //Load the Country object using the oSalesRecord COUNTRY_CODE Value

    //Note: In C# you need to pass an object reference

    Object CustCountry = (String)SDOHelper.Read(oSalesRecord, "COUNTRY_CODE");;

    if (oCountry.Load(ref CustCountry))

    {

      //Set the Country object on the project

      oProject.Country = oCountry;

    }

  }

  //Set the Start and End Dates of the project

  oProject.StartDate = (DateTime)DateTime.Today;

  oProject.EndDate = (DateTime)DateTime.Today.AddMonths(12);

  //Save the Project

  if (oProject.Update())

  {

    MessageBox.Show("The Project Was Created Successfully");

  }

  else

  {

    MessageBox.Show("The Project Was Not Created");

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Creating a New Project Resource

Example - Creating a New Project Resource

The example code below demonstrates how to create a new Project Costing Resource.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
 Dim oSDO As SageDataObject300.SDOEngine
 Dim oWS As SageDataObject300.WorkSpace
 Dim oResource As SageDataObject300.ProjectResource

 Dim szDataPath As String

 Try
   ' Create the SDO Engine object
    oSDO = New SageDataObject300.SDOEngine

   ' Create the Workspace
    oWS = oSDO.Workspaces.Add("Example")

   ' Select company. The SelectCompany method takes the program install folder as a parameter
    szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

   ' A U.I. for company selection is presented to the user. If a company is selected,
   ' the path will be passed to the szDataPath variable.
   ' If not, or the Cancel button is selected, the variable will be left empty.
    If szDataPath <> "" Then

     ' Connect to Data Files
      If oWS.Connect(szDataPath, "", "", "Example") Then
       ' Create Objects
       oResource = oWS.CreateProjectResource

       ' Set the Resource details
       oResource.Reference = "RES1"
       oResource.Name = "Resource 1"
       oResource.Unit = "Hour"
       oResource.Rate = CDbl(10)

       ' Save the resource
       If oResource.Update() Then
         MessageBox.Show("The Resource Save was successful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)

       Else
         MessageBox.Show("The Resource Save was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

       End If

     Else

       MessageBox.Show("Could not logon to the data.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

     End If

   End If

 Catch ex As Exception
   ' Show the exception error message
   MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

 Finally

   If Not oWs Is Nothing Then
      oWS.Disconnect()
     oWs = Nothing
   End If
   ' Dispose of any objects
   If Not oSDO Is Nothing Then oSDO = Nothing
   If Not oResource Is Nothing Then oResource = Nothing
 End Try
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.ProjectResource oResource;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate Project Resource Object

  oResource = (SageDataObject300.ProjectResource)oWS.CreateProjectResource();

  //Set the Resource details

  oResource.Reference = (String)"RES1";

  oResource.Name = (String)"Resource 1";

  oResource.Unit = (String)"Hour";

  oResource.Rate = (Double)10;

  //Save the Resource

  if (oResource.Update())

  {

    MessageBox.Show("Resource Created Successfully");

  }

  else

  {

    MessageBox.Show("Resource Not Created");

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Creating a New Project Cost Code

Example - Creating a New Project Cost Code

The example code below demonstrates how to create a new Project Costing CostCode.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
 Dim oSDO As SageDataObject300.SDOEngine
 Dim oWS As SageDataObject300.WorkSpace
 Dim oCostCode As SageDataObject300.ProjectCostCode

 Dim szDataPath As String

 Try
   ' Create the SDO Engine object
    oSDO = New SageDataObject300.SDOEngine

   ' Create the Workspace
    oWS = oSDO.Workspaces.Add("Example")

   ' Select company. The SelectCompany method takes the program install folder as a parameter
    szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

   ' A U.I. for company selection is presented to the user. If a company is selected,
   ' the path will be passed to the szDataPath variable.
   ' If not, or the Cancel button is selected, the variable will be left empty.
    If szDataPath <> "" Then

     ' Connect to Data Files
      If oWS.Connect(szDataPath, "", "", "Example") Then
       ' Create Objects
       oCostCode = oWS.CreateProjectCostCode

       ' Set the Cost Code details
       oCostCode.Reference = "SRV"
       oCostCode.Description = "Service Charges"

       ' Save the cost code
       If oCostCode.Update Then
         MessageBox.Show("The Cost Code Save was successful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)

       Else
         MessageBox.Show("The Cost Code Save was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

       End If

     Else

       MessageBox.Show("Could not logon to the data.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

     End If

   End If

 Catch ex As Exception
   ' Show the exception error message
   MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

 Finally

   If Not oWs Is Nothing Then
      oWS.Disconnect()
     oWs = Nothing
   End If
   ' Dispose of any objects
   If Not oSDO Is Nothing Then oSDO = Nothing
   If Not oCostCode Is Nothing Then oCostCode = Nothing
 End Try
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.ProjectCostCode oCostCode;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate Project Cost Code Object

  oCostCode =(SageDataObject300.ProjectCostCode) oWS.CreateProjectCostCode();

  //Set the Cost Code details

  oCostCode.Reference = (String)"SRV";

  oCostCode.Description = (String)"Service Charges";

  //Save the Cost Code

  if (oCostCode.Update())

  {

    MessageBox.Show("Cost Code Created Successfully");

  }

  else

  {

    MessageBox.Show("Cost Code Not Created");

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Creating a New Project Status

Example - Creating a New Project Status

The example code below demonstrates how to create a new Project Costing Status.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
 Dim oSDO As SageDataObject300.SDOEngine
 Dim oWS As SageDataObject300.WorkSpace
 Dim oStatus As SageDataObject300.ProjectStatus

 Dim szDataPath As String

 Try
   ' Create the SDO Engine object
    oSDO = New SageDataObject300.SDOEngine

   ' Create the Workspace
    oWS = oSDO.Workspaces.Add("Example")

   ' Select company. The SelectCompany method takes the program install folder as a parameter
    szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

   ' A U.I. for company selection is presented to the user. If a company is selected,
   ' the path will be passed to the szDataPath variable.
   ' If not, or the Cancel button is selected, the variable will be left empty.
    If szDataPath <> "" Then

     ' Connect to Data Files
      If oWS.Connect(szDataPath, "", "", "Example") Then
       ' Create Objects
       oStatus = oWS.CreateProjectStatus

       ' Set the Status details
       oStatus.Reference = "NEWACTIVE"
       oStatus.Name = "New Active Status"
       oStatus.Postings = True
       oStatus.Deletion = False
       oStatus.Default = False

       ' Save the status
       If oStatus.Update() Then
         MessageBox.Show("The Status Save was successful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)

       Else
         MessageBox.Show("The Status Save was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

       End If

     Else

       MessageBox.Show("Could not logon to the data.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

     End If

   End If

 Catch ex As Exception
   ' Show the exception error message
   MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

 Finally

   If Not oWs Is Nothing Then
      oWS.Disconnect()
     oWs = Nothing
   End If
   ' Dispose of any objects
   If Not oSDO Is Nothing Then oSDO = Nothing
   If Not oStatus Is Nothing Then oStatus = Nothing
 End Try
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.ProjectStatus oStatus;

            try
            {
               // Create Objects
               oStatus = (SageDataObject300.ProjectStatus)oWS.CreateProjectStatus();

               // Set the Status details
               oStatus.Reference = (String)"NEWACTIVE";
               oStatus.Name = (String)"New Active Status";
               oStatus.Postings = true;
               oStatus.Deletion = false;
               oStatus.Default = false;

               // Save the status
               if(oStatus.Update())
               {
                 MessageBox.Show("The Status Save was successful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
               }
               else
               {
                 MessageBox.Show("The Status Save was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
               }

            }
            // Error Handling Code
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Example", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            oWS.Disconnect();

        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Deleting a Project Record

Example - Deleting a Project Record

The example code below demonstrates how to delete a Project Costing Record. Note: you can only delete a Project Record if its Status is set to allow deletion.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
 Dim oSDO As SageDataObject300.SDOEngine
 Dim oWS As SageDataObject300.WorkSpace
 Dim oProject As SageDataObject300.Project

 Dim szDataPath As String

 Try
   ' Create the SDO Engine object
    oSDO = New SageDataObject300.SDOEngine

   ' Create the Workspace
    oWS = oSDO.Workspaces.Add("Example")

   ' Select company. The SelectCompany method takes the program install folder as a parameter
    szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

   ' A U.I. for company selection is presented to the user. If a company is selected,
   ' the path will be passed to the szDataPath variable.
   ' If not, or the Cancel button is selected, the variable will be left empty.
    If szDataPath <> "" Then

     ' Connect to Data Files
      If oWS.Connect(szDataPath, "", "", "Example") Then
       ' Create Objects
       oProject = oWS.CreateProject

       If oProject.Load("PROJ1") Then

         ' Delete the project
         If oProject.Delete() Then
           MessageBox.Show("The Project Delete was successful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)

         Else
           MessageBox.Show("The Project Delete was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

         End If

       Else

         MessageBox.Show("The Project Load was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

       End If

     Else

       MessageBox.Show("Could not logon to the data.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

     End If

   End If

 Catch ex As Exception
   ' Show the exception error message
   MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

 Finally

   If Not oWs Is Nothing Then
      oWS.Disconnect()
     oWs = Nothing
   End If
   ' Dispose of any objects
   If Not oSDO Is Nothing Then oSDO = Nothing
   If Not oProject Is Nothing Then oProject = Nothing
 End Try
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            SageDataObject300.Project oProject;

            // Create Objects
            oProject = (SageDataObject300.Project)oWS.CreateProject();

            try
            {
                // Declare a Project object
                Object proj = "PROJ002";

                if (oProject.Load(ref proj))
                {
                    // Delee the project
                    if (oProject.Delete())
                    {
                        MessageBox.Show("The Project Delete was successful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    }

                    else
                    {
                        MessageBox.Show("The Project Delete was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                else
                {
                    MessageBox.Show("The Project Load was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                if ((oWS != null))
                {
                    oWS.Disconnect();
                    oWS = null;
                }
                // Dispose of any objects
                if (oSDO != null) oSDO = null;
                if (oProject != null) oProject = null;
            }
        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Deleting a Project Cost Code

Example - Deleting a Project Cost Code

The example code below demonstrates how to delete a Project Costing CostCode.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
 Dim oSDO As SageDataObject300.SDOEngine
 Dim oWS As SageDataObject300.WorkSpace
 Dim oCostCode As SageDataObject300.ProjectCostCode

 Dim szDataPath As String

 Try
   ' Create the SDO Engine object
    oSDO = New SageDataObject300.SDOEngine

   ' Create the Workspace
    oWS = oSDO.Workspaces.Add("Example")

   ' Select company. The SelectCompany method takes the program install folder as a parameter
    szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

   ' A U.I. for company selection is presented to the user. If a company is selected,
   ' the path will be passed to the szDataPath variable.
   ' If not, or the Cancel button is selected, the variable will be left empty.
    If szDataPath <> "" Then

     ' Connect to Data Files
      If oWS.Connect(szDataPath, "", "", "Example") Then
       ' Create Objects
       oCostCode = oWS.CreateProjectCostCode

       If oCostCode.Load("LAB1") Then

         ' Delete the cost code
         If oCostCode.Delete() Then
           MessageBox.Show("The Cost Code Delete was successful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)

         Else
           MessageBox.Show("The Cost Code Delete was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

         End If

       Else

         MessageBox.Show("The Cost Code Load was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

       End If

     Else

       MessageBox.Show("Could not logon to the data.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

     End If

   End If

 Catch ex As Exception
   ' Show the exception error message
   MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

 Finally

   If Not oWs Is Nothing Then
      oWS.Disconnect()
     oWs = Nothing
   End If
   ' Dispose of any objects
   If Not oSDO Is Nothing Then oSDO = Nothing
   If Not oCostCode Is Nothing Then oCostCode = Nothing
 End Try
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            SageDataObject300.ProjectCostCode oCostCode;

            // Create Objects
            oCostCode = (SageDataObject300.ProjectCostCode)oWS.CreateProjectCostCode();

            try
            {
                // Declare a CostCode object
                Object ccode = "SDO_CODE";

                // Load the Cost Code
                if (oCostCode.Load(ref ccode))
                {
                    // Delete the CostCode
                    if (oCostCode.Delete())
                    {
                        MessageBox.Show("The CostCode Delete was successful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    }
                    else
                    {
                        MessageBox.Show("The CostCode Delete was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                else
                {
                    MessageBox.Show("The CostCode Load was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                if ((oWS != null))
                {
                    oWS.Disconnect();
                    oWS = null;
                }
                // Dispose of any objects
                if (oSDO != null) oSDO = null;
                if (oCostCode != null) oCostCode = null;
            }
        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Deleting a Project Resource

Example - Deleting a Project Resource

The example code below demonstrates how to delete a Project Costing Resource.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
 Dim oSDO As SageDataObject300.SDOEngine
 Dim oWS As SageDataObject300.WorkSpace
 Dim oResource As SageDataObject300.ProjectResource

 Dim szDataPath As String

 Try
   ' Create the SDO Engine object
    oSDO = New SageDataObject300.SDOEngine

   ' Create the Workspace
    oWS = oSDO.Workspaces.Add("Example")

   ' Select company. The SelectCompany method takes the program install folder as a parameter
    szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

   ' A U.I. for company selection is presented to the user. If a company is selected,
   ' the path will be passed to the szDataPath variable.
   ' If not, or the Cancel button is selected, the variable will be left empty.
    If szDataPath <> "" Then

     ' Connect to Data Files
      If oWS.Connect(szDataPath, "", "", "Example") Then
       ' Create Objects
       oResource = oWS.CreateProjectResource

       If oResource.Load("RES1") Then

         ' Delete the resource
         If oResource.Delete() Then
           MessageBox.Show("The Resource Delete was successful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)

         Else
           MessageBox.Show("The Resource Delete was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

         End If

       Else

         MessageBox.Show("The Resource Load was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

       End If

     Else

       MessageBox.Show("Could not logon to the data.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

     End If

   End If

 Catch ex As Exception
   ' Show the exception error message
   MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

 Finally

   If Not oWs Is Nothing Then
      oWS.Disconnect()
     oWs = Nothing
   End If
   ' Dispose of any objects
   If Not oSDO Is Nothing Then oSDO = Nothing
   If Not oResource Is Nothing Then oResource = Nothing
 End Try

C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.ProjectResource oResource;

            try
            {
               // Create Objects
               oResource = (SageDataObject300.ProjectResource)oWS.CreateProjectResource();

               Object resName = "RES1";
               if (oResource.Load(ref resName))
               {
                   // Delete the resource
                   if (oResource.Delete())
                   {
                       MessageBox.Show("The Resource Delete was successful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                   }
                   else
                   {
                       MessageBox.Show("The Resource Delete was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                   }
               }
               else
               {
                   MessageBox.Show("The Resource Load was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
               }

            }
            // Error Handling Code
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Example", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            oWS.Disconnect();

        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Deleting a Project Status

Example - Deleting a Project Status

The example code below demonstrates how to delete a Project Costing Status. Note: you cannot delete the status if it set as default (.Default property set to True).

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
 Dim oSDO As SageDataObject300.SDOEngine
 Dim oWS As SageDataObject300.WorkSpace
 Dim oStatus As SageDataObject300.ProjectStatus

 Dim szDataPath As String

 Try
   ' Create the SDO Engine object
    oSDO = New SageDataObject300.SDOEngine

   ' Create the Workspace
    oWS = oSDO.Workspaces.Add("Example")

   ' Select company. The SelectCompany method takes the program install folder as a parameter
    szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

   ' A U.I. for company selection is presented to the user. If a company is selected,
   ' the path will be passed to the szDataPath variable.
   ' If not, or the Cancel button is selected, the variable will be left empty.
    If szDataPath <> "" Then

     ' Connect to Data Files
      If oWS.Connect(szDataPath, "", "", "Example") Then
       ' Create Objects
       oStatus = oWS.CreateProjectStatus

       If oStatus.Load("COMPLETED") Then

         ' Delete the status
         If oStatus.Delete() Then
           MessageBox.Show("The Status Delete was successful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)

         Else
           MessageBox.Show("The Status Delete was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

         End If

       Else

         MessageBox.Show("The Status Load was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

       End If

     Else

       MessageBox.Show("Could not logon to the data.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

     End If

   End If

 Catch ex As Exception
   ' Show the exception error message
   MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

 Finally

   If Not oWs Is Nothing Then
      oWS.Disconnect()
     oWs = Nothing
   End If
   ' Dispose of any objects
   If Not oSDO Is Nothing Then oSDO = Nothing
   If Not oStatus Is Nothing Then oStatus = Nothing
 End Try
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.ProjectStatus oStatus;

            try
            {
               // Create Objects
               oStatus = (SageDataObject300.ProjectStatus)oWS.CreateProjectStatus();

               Object statusName = "NEWACTIVE";
               if (oStatus.Load(ref statusName))
               {
                   // Delete the status
                   if (oStatus.Delete())
                   {
                       MessageBox.Show("The Status Delete was successful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                   }
                   else
                   {
                       MessageBox.Show("The Status Delete was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                   }
               }
               else
               {
                   MessageBox.Show("The Status Load was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
               }

            }
            // Error Handling Code
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Example", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            oWS.Disconnect();

        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Display Project Details In A Combobox

Example - Display Project Details In A Combobox

The example code below demonstrates how to display project details in a combobox Visual Basic .NET.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
Public Class Form1

    ' Declare Objects
    Private oSDO As SageDataObject300.SDOEngine
    Private oWS As SageDataObject300.WorkSpace

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        ' Declare Variables
        Dim szDataPath As String

        ' Create the SDOEngine Object
        oSDO = New SageDataObject300.SDOEngine

        ' Create the Workspace
        oWS = oSDO.Workspaces.Add("Example")

        ' Select Company.  The SelectCompany method takes the program install
        ' folder as a parameter
        szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

        ' A U.I. for company selection is presented to the user. If a company is selected,
        ' the path will be passed to the szDataPath variable.
        ' If not, or the Cancel button is selected, the variable will be left empty.
        If szDataPath <> "" Then

            ' Try to Connect - Will Throw an Exception if it Fails
            If oWS.Connect(szDataPath, "", "", "Example") Then

                'User defined Code
                projectcombo()

                ' Disconnect
                oWS.Disconnect()

            End If

        End If

        ' Destroy the Objects
        oWS = Nothing
        oSDO = Nothing

        Exit Sub

    End Sub

    Private Sub projectcombo()

        'Declare Objects
        Dim oProject As SageDataObject300.Project
        Dim oProjects As SageDataObject300.Projects

        ' Instantiate the Projects Buiness objec. collection
        oProjects = oWS.CreateProjects
        oProject = oWS.CreateProject

        ' Loop through each project in the oProject collection
        For Each oProject In oProjects

            ' Add the project to the projectStatusComboBox control
            Me.ComboBox1.Items.Add(oProject.Reference & " " & oProject.Name & " " & oProject.ProjectID)

        Next

    End Sub

End Class
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Project_Combobox_cSharp
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        private SageDataObject300.WorkSpace oWS;
        private void Form1_Load(object sender, EventArgs e)
        {
            //Declare Variables

            String szDataPath;

            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                ///User Method here
                fillcombo();

                //Disconnect
                oWS.Disconnect();
            }

            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void fillcombo()
        {
            //Declare Objects
            SageDataObject300.Project oProject;
            SageDataObject300.Projects oProjects;

            //Instantiate the projects business object collection
            oProject = (SageDataObject300.Project)oWS.CreateProject();
            oProjects = (SageDataObject300.Projects)oWS.CreateProjects();

            for (int i = 1; i < oProjects.Count + 1; i++)
            {
                Object currProj = i;
                oProject.Load(ref currProj);
                this.comboBox1.Items.Add(oProject.Reference + " " + oProject.Name + " " + oProject.ProjectID);
            }

        }
    }
}


Sage 50 Accounts - Example - Display Project Statuses In A Combobox

Example - Display Project Statuses In A Combobox

The example code below demonstrates how to display project statuses in a combobox Visual Basic .NET.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
Public Class Form1

    ' Declare Objects
    Private oSDO As SageDataObject300.SDOEngine
    Private oWS As SageDataObject300.WorkSpace

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        ' Declare Variables
        Dim szDataPath As String

        ' Create the SDOEngine Object
        oSDO = New SageDataObject300.SDOEngine

        ' Create the Workspace
        oWS = oSDO.Workspaces.Add("Example")

        ' Select Company.  The SelectCompany method takes the program install
        ' folder as a parameter
        szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

        ' A U.I. for company selection is presented to the user. If a company is selected,
        ' the path will be passed to the szDataPath variable.
        ' If not, or the Cancel button is selected, the variable will be left empty.
        If szDataPath <> "" Then

            ' Try to Connect - Will Throw an Exception if it Fails
            If oWS.Connect(szDataPath, "", "", "Example") Then

                'User defined Code
                projectcombo()

                ' Disconnect
                oWS.Disconnect()

            End If

        End If

        ' Destroy the Objects
        oWS = Nothing
        oSDO = Nothing

        Exit Sub

    End Sub

    Private Sub projectcombo()

        'Declare Objects
        Dim oProjectStatus As SageDataObject300.ProjectStatus
        Dim oProjectStatuses As SageDataObject300.ProjectStatuses

        ' Instantiate the Projects Buiness objec. collection
        oProjectStatus = oWS.CreateProjectStatus
        oProjectStatuses = oWS.CreateProjectStatuses

        ' Loop through each project in the oProject collection
        For Each oProjectStatus In oProjectStatuses

            ' Add the project to the projectStatusComboBox control
            Me.ComboBox1.Items.Add(oProjectStatus.StatusID & " " & oProjectStatus.Name & " " & oProjectStatus.Reference)

        Next

    End Sub

End Class
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Project_Status_ComboBox
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        private SageDataObject300.WorkSpace oWS;

        private void Form1_Load(object sender, EventArgs e)
        {
            //Declare Variables

            String szDataPath;

            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                ///User Method here
                fillcombo();

                //Disconnect
                oWS.Disconnect();
            }

            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }

        }

        private void fillcombo()
        {
            //Declare Objects
            SageDataObject300.ProjectStatus oProjectStatus;
            SageDataObject300.ProjectStatuses oProjectStatuses;

            //Instantiate the projects business object collection
            oProjectStatus = (SageDataObject300.ProjectStatus)oWS.CreateProjectStatus();
            oProjectStatuses = (SageDataObject300.ProjectStatuses)oWS.CreateProjectStatuses();

            for (int i = 1; i < oProjectStatuses.Count + 1; i++)
            {
                Object currProj = i;
                oProjectStatus.Load(ref currProj);
                this.comboBox1.Items.Add(oProjectStatus.Reference + " " + oProjectStatus.Name + " " + oProjectStatus.StatusID);
            }

        }

    }
}


Sage 50 Accounts - Example - Marking a Project Record as Complete

Example - Marking a Project Record as Complete

The example code below demonstrates how to mark a Project Costing Project as Complete. This involves changing the Status on a Project to one that is marked as Complete. This example requires a Status exists with a code 'COMPLETED'.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

The code also includes a generic error handler. Clearly, you would respond differently depending on the actual exception thrown.

VB.NET [image] Copy VB Code
 ' Declare Objects
 Dim oSDO As SageDataObject300.SDOEngine
 Dim oWS As SageDataObject300.WorkSpace
 Dim oProject As SageDataObject300.Project
 Dim oStatus As SageDataObject300.ProjectStatus
 Dim szDataPath As String
 Try
   ' Create the SDO Engine object
   oSDO = New SageDataObject300.SDOEngine

   ' Create the Workspace
   oWS = oSDO.Workspaces.Add("Example")

   ' Select company. The SelectCompany method takes the program install folder as a parameter
   szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

   ' A U.I. for company selection is presented to the user. If a company is selected,
   ' the path will be passed to the szDataPath variable.
   ' If not, or the Cancel button is selected, the variable will be left empty.
   If szDataPath <> "" Then
     ' Connect to Data Files
     If oWS.Connect(szDataPath, "", "", "Example") Then
       ' Create Objects
       oProject = oWS.CreateProject
       oStatus = oWS.CreateProjectStatus

       ' Load the Project we wish tomark as Complete
       If oProject.Load("PROJ8") Then
         ' Load the Project Status with a Reference of 'COMPLETED'
         If oStatus.Load("COMPLETED") Then
           ' Set the .Status object on the project
           oProject.Status = oStatus

           ' Save the project
           If oProject.Update Then
             MessageBox.Show("The Project Save was successful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)

           Else
             MessageBox.Show("The Project Save was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

           End If
         Else
           MessageBox.Show("Could not load the status", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

         End If
       Else
         MessageBox.Show("Could not load the project", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

       End If
     Else
       MessageBox.Show("Could not logon to the data.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

     End If
   End If

 Catch ex As Exception

   ' Show the exception error message
   MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

 Finally
   If Not oWS Is Nothing Then
     oWS.Disconnect()
     oWS = Nothing
   End If
   ' Dispose of any objects
   If Not oSDO Is Nothing Then oSDO = Nothing
   If Not oProject Is Nothing Then oProject = Nothing
   If Not oStatus Is Nothing Then oStatus = Nothing
 End Try
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.Project oProject;

SageDataObject300.ProjectStatus oStatus;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate Objects

  oProject = (SageDataObject300.Project)oWS.CreateProject();

  oStatus = (SageDataObject300.ProjectStatus)oWS.CreateProjectStatus();

  //Load the project that we wish to mark as complete

  //Note: In C# you need to pass a reference to an object

  Object ProjRef = "PROJECT1";

  if (oProject.Load(ref ProjRef))

  {

    //Load the project status with a reference of 'COMPLETED'

    //Note: In C# you need to pass a reference to an object

    Object Status = "COMPLETED";

    if (oStatus.Load(ref Status))

    {

      //Set the Status on the Project

      oProject.Status = oStatus;

      //Save the Project

      if (oProject.Update())

      {

        MessageBox.Show("Project Status Was Changed Successfully");

      }

      else

      {

        MessageBox.Show("The Project Status Was Not Changed");

      }

    }

    else

    {

      MessageBox.Show("Could Not Load The Status");

    }

  }

  else

  {

    MessageBox.Show("Could Not Load The Project");

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Posting a Project Charge

Example - Posting a Project Charge

The example code below demonstrates how to post a Project Costing charge. This will be using the ProjectOnlyTransaction object. For further information on Product Charges click here.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

Note: If you attempt to Post a Project Charge to a project that has a Status that is set to not allow postings then an error is thrown (sdoInvalidProjectStatus - Code 37).

VB.NET [image] Copy VB Code
 ' Declare Objects
 Dim oSDO As SageDataObject300.SDOEngine
 Dim oWS As SageDataObject300.WorkSpace
 Dim oProjectOnlyTransaction As SageDataObject300.ProjectOnlyTransaction
 Dim oProject As SageDataObject300.Project
 Dim oCostCode As SageDataObject300.ProjectCostCode
 Dim oResource As SageDataObject300.ProjectResource
 Dim szDataPath As String
 Try
   ' Create the SDO Engine object
   oSDO = New SageDataObject300.SDOEngine

   ' Create the Workspace
   oWS = oSDO.Workspaces.Add("Example")

   ' Select company. The SelectCompany method takes the program install folder as a parameter
   szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

   ' A U.I. for company selection is presented to the user. If a company is selected,
   ' the path will be passed to the szDataPath variable.
   ' If not, or the Cancel button is selected, the variable will be left empty.
   If szDataPath <> "" Then
     ' Connect to Data Files
     If oWS.Connect(szDataPath, "", "", "Example") Then
       ' Create Objects
       oProjectOnlyTransaction = oWS.CreateProjectOnlyTransaction
       oProject = oWS.CreateProject
       oCostCode = oWS.CreateProjectCostCode
       oResource = oWS.CreateProjectResource

       ' Load the Project we wish to post the charge on
       If oProject.Load("PROJ8") Then
         oProjectOnlyTransaction.Project = oProject

         ' Load and set the Cost Code
         If oCostCode.Load("LAB1") Then
           oProjectOnlyTransaction.CostCode = oCostCode

           ' Load the Resource. This is optional
           If oResource.Load("RES1") Then
             oProjectOnlyTransaction.Resource = oResource

           End If
           ' Set the other Charge details
           oProjectOnlyTransaction.Date = Today
           oProjectOnlyTransaction.Details = "Project Only Charge"
           oProjectOnlyTransaction.Quantity = CDbl(2)
           oProjectOnlyTransaction.Rate = CDbl(20)
           oProjectOnlyTransaction.Reference = "CHRG"

           ' Set the Charge transaction type sdoCD
           oProjectOnlyTransaction.Type = SageDataObject300.TransType.sdoCD

           ' Post the transaction
           If oProjectOnlyTransaction.Post Then
             MessageBox.Show("The Project Only Transaction Post was successful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)

           Else
             MessageBox.Show("The Project Only Transaction Post was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

           End If
         Else
           MessageBox.Show("Could not load the cost code", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

         End If
       Else
         MessageBox.Show("Could not load the project", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

       End If
     Else
       MessageBox.Show("Could not logon to the data.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

     End If
   End If

 Catch ex As Exception

   ' Show the exception error message
   MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

 Finally
   If Not oWS Is Nothing Then
     oWS.Disconnect()
     oWS = Nothing
   End If
   ' Dispose of any objects
   If Not oSDO Is Nothing Then oSDO = Nothing
   If Not oProject Is Nothing Then oProject = Nothing
   If Not oProjectOnlyTransaction Is Nothing Then oProjectOnlyTransaction = Nothing
   If Not oCostCode Is Nothing Then oCostCode = Nothing
   If Not oResource Is Nothing Then oResource = Nothing
 End Try
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.ProjectOnlyTransaction oProjectOnlyTransaction;

SageDataObject300.Project oProject;

SageDataObject300.ProjectCostCode oCostCode;

SageDataObject300.ProjectResource oResource;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate Objects

  oProjectOnlyTransaction = (SageDataObject300.ProjectOnlyTransaction)oWS.CreateProjectOnlyTransaction();

  oProject = (SageDataObject300.Project)oWS.CreateProject();

  oCostCode = (SageDataObject300.ProjectCostCode)oWS.CreateProjectCostCode();

  oResource = (SageDataObject300.ProjectResource)oWS.CreateProjectResource();

  //Load the Project we wish to post the charge on

  //Note: In C# you need to pass an object reference

  Object ProjRef = "PROJECT1";

  if (oProject.Load(ref ProjRef))

  {

    oProjectOnlyTransaction.Project = oProject;

    //Load and set the Cost Code

    //Note: In C# you need to pass an object reference

    Object CostCodeRef = "MISC";

    if (oCostCode.Load(ref CostCodeRef))

    {

      oProjectOnlyTransaction.CostCode = oCostCode;

      //Load the Resource. This is optional

      //Note: In C# you need to pass an object reference

      Object ResourceRef = "RES1";

      if (oResource.Load(ref ResourceRef))

      {

        oProjectOnlyTransaction.Resource = oResource;

      }

      //Set the other charge details

      oProjectOnlyTransaction.Date = (DateTime)DateTime.Today;

      oProjectOnlyTransaction.Details = (String)"Project Only Charge";

      oProjectOnlyTransaction.Quantity = (Double)2;

      oProjectOnlyTransaction.Rate = (Double)20;

      oProjectOnlyTransaction.Reference = (String)"CHRG";

      //Set the charge transaction type sdoCD

      oProjectOnlyTransaction.Type = (Int32)SageDataObject300.TransType.sdoCD;

      //Post the transaction

      if (oProjectOnlyTransaction.Post())

      {

        MessageBox.Show("The Project Only Transaction Posted Successfully");

      }

      else

      {

        MessageBox.Show("The Project Only Transaction Failed To Post");

      }

    }

    else

    {

      MessageBox.Show("Could Not Load The Cost Code");

    }

  }

  else

  {

    MessageBox.Show("Could Not Load The Project");

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Posting a Project Credit

Example - Posting a Project Credit

The example code below demonstrates how to post a Project Costing credit. This will be using the ProjectOnlyTransaction object. For further information on Product Credits click here.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

Note: If you attempt to Post a Project Credit to a project that has a Status that is set to not allow postings then an error is thrown (sdoInvalidProjectStatus - Code 37).

VB.NET [image] Copy VB Code
 ' Declare Objects
 Dim oSDO As SageDataObject300.SDOEngine
 Dim oWS As SageDataObject300.WorkSpace
 Dim oProjectOnlyTransaction As SageDataObject300.ProjectOnlyTransaction
 Dim oProject As SageDataObject300.Project
 Dim oCostCode As SageDataObject300.ProjectCostCode
 Dim oResource As SageDataObject300.ProjectResource
 Dim szDataPath As String
 Try
   ' Create the SDO Engine object
   oSDO = New SageDataObject300.SDOEngine

   ' Create the Workspace
   oWS = oSDO.Workspaces.Add("Example")

   ' Select company. The SelectCompany method takes the program install folder as a parameter
   szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

   ' A U.I. for company selection is presented to the user. If a company is selected,
   ' the path will be passed to the szDataPath variable.
   ' If not, or the Cancel button is selected, the variable will be left empty.
   If szDataPath <> "" Then
     ' Connect to Data Files
     If oWS.Connect(szDataPath, "", "", "Example") Then
       ' Create Objects
       oProjectOnlyTransaction = oWS.CreateProjectOnlyTransaction
       oProject = oWS.CreateProject
       oCostCode = oWS.CreateProjectCostCode
       oResource = oWS.CreateProjectResource

       ' Load the Project we wish to post the credit on
       If oProject.Load("PROJ8") Then
         oProjectOnlyTransaction.Project = oProject

         ' Load and set the Cost Code
         If oCostCode.Load("LAB1") Then
           oProjectOnlyTransaction.CostCode = oCostCode

           ' Load the Resource. This is optional
           If oResource.Load("RES1") Then
             oProjectOnlyTransaction.Resource = oResource

           End If
           ' Set the other Credit details
           oProjectOnlyTransaction.Date = Today
           oProjectOnlyTransaction.Details = "Project Only Credit"
           oProjectOnlyTransaction.Quantity = CDbl(2)
           oProjectOnlyTransaction.Rate = CDbl(20)
           oProjectOnlyTransaction.Reference = "CHRG"

           ' Set the Credit transaction type sdoCC
           oProjectOnlyTransaction.Type = SageDataObject300.TransType.sdoCC

           ' Post the transaction
           If oProjectOnlyTransaction.Post Then
             MessageBox.Show("The Project Only Transaction Post was successful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)

           Else
             MessageBox.Show("The Project Only Transaction Post was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

           End If
         Else
           MessageBox.Show("Could not load the cost code", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

         End If
       Else
         MessageBox.Show("Could not load the project", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

       End If
     Else
       MessageBox.Show("Could not logon to the data.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

     End If
   End If

 Catch ex As Exception

   ' Show the exception error message
   MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

 Finally
   If Not oWS Is Nothing Then
     oWS.Disconnect()
     oWS = Nothing
   End If
   ' Dispose of any objects
   If Not oSDO Is Nothing Then oSDO = Nothing
   If Not oProject Is Nothing Then oProject = Nothing
   If Not oProjectOnlyTransaction Is Nothing Then oProjectOnlyTransaction = Nothing
   If Not oCostCode Is Nothing Then oCostCode = Nothing
   If Not oResource Is Nothing Then oResource = Nothing
 End Try
C#.NET [image] Copy C# Code
//Declare Objects
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.ProjectOnlyTransaction oProjectOnlyTransaction;
SageDataObject300.Project oProject;
SageDataObject300.ProjectCostCode oCostCode;
SageDataObject300.ProjectResource oResource;

//Declare Variables
String szDataPath;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails
try
{
    //Leaving the username and password blank generates a login dialog
    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

    //Create Objects
    oProjectOnlyTransaction = (SageDataObject300.ProjectOnlyTransaction)oWS.CreateProjectOnlyTransaction();
    oProject = (SageDataObject300.Project)oWS.CreateProject();
    oCostCode = (SageDataObject300.ProjectCostCode)oWS.CreateProjectCostCode();
    oResource = (SageDataObject300.ProjectResource)oWS.CreateProjectResource();

    Object projRef = "TEST";
    if (oProject.Load(ref projRef))
    {
        oProjectOnlyTransaction.Project = oProject;

        Object costRef = "LAB1";
        if (oCostCode.Load(ref costRef))
        {
            oProjectOnlyTransaction.CostCode = oCostCode;

            Object resRef = "RES1";
            if (oResource.Load(ref resRef))
            {
                oProjectOnlyTransaction.Resource = oResource;

                //Set the other Credit Details
                oProjectOnlyTransaction.Date = DateTime.Today;
                oProjectOnlyTransaction.Details = (String)"Project Only Credit";
                oProjectOnlyTransaction.Quantity = (Double)2;
                oProjectOnlyTransaction.Rate = (Double)20;
                oProjectOnlyTransaction.Reference = (String)"CHRG";

                //Set the Credit Transaction type sdoCC
                oProjectOnlyTransaction.Type = (Int32)SageDataObject300.TransType.sdoCC;

                //Post the transaction
                if (oProjectOnlyTransaction.Post())
                {
                    MessageBox.Show("The Project Only Transaction Post was successful");
                }
                else
                {
                    MessageBox.Show("The Project Only Transaction Post was unsuccessful");
                }
            }
            else
            {
                MessageBox.Show("Could not load the resource");
            }

        }
        else
        {
            MessageBox.Show("Could not load the cost code");
        }
    }
    else
    {
        MessageBox.Show("Could not load the project");
    }
}
catch (Exception ex)
{
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
}
finally
{
    //Disconnect
    oWS.Disconnect();
}


Sage 50 Accounts - Example - Posting an Adjustment Out to a Project

Example - Posting an Adjustment Out to a Project

The example code below demonstrates how to post a stock adjustment out to a project. This will be using the StockTran object. For further information on Stock Postings click here.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

Note: If you attempt to Post an Adjustment Out to a project that has a Status that is set to not allow postings then an error is thrown (sdoInvalidProjectStatus - Code 37).

VB.NET [image] Copy VB Code
 ' Declare Objects
 Dim oSDO As SageDataObject300.SDOEngine
 Dim oWS As SageDataObject300.WorkSpace
 Dim oStockPost As SageDataObject300.StockPost
 Dim oStockTran As SageDataObject300.StockTran
 Dim oStockRecord As SageDataObject300.StockRecord
 Dim oProject As SageDataObject300.Project
 Dim oCostCode As SageDataObject300.ProjectCostCode

 Dim szDataPath As String
 Try
   ' Create the SDO Engine object
   oSDO = New SageDataObject300.SDOEngine

   ' Create the Workspace
   oWS = oSDO.Workspaces.Add("Example")

   ' Select company. The SelectCompany method takes the program install folder as a parameter
   szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

   ' A U.I. for company selection is presented to the user. If a company is selected,
   ' the path will be passed to the szDataPath variable.
   ' If not, or the Cancel button is selected, the variable will be left empty.
   If szDataPath <> "" Then
     ' Connect to Data Files
     If oWS.Connect(szDataPath, "", "", "Example") Then
       ' Create Objects
       oProject = oWS.CreateProject
       oCostCode = oWS.CreateProjectCostCode
       oStockPost = oWS.CreateObject("StockPost")
       oStockRecord = oWS.CreateObject("StockRecord")

       ' Find the Stock Record we wish to post the Adjustment for
       oStockRecord.Fields.Item("STOCK_CODE").Value = "BOARD001"
       If oStockRecord.Find(False) Then
         ' Load the Project we wish to associate the stock adjustment with
         If oProject.Load("PROJ8") Then
           ' Load the Cost Code
           If oCostCode.Load("LAB1") Then
             ' Fill in Header information required
             oStockPost.Header("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)

             ' Add to the items collection of the StockPost object
             oStockTran = oStockPost.Items.Add

             ' Set the Project and CostCode
             oStockTran.Project = oProject
             oStockTran.CostCode = oCostCode

             ' Populate Stock Transaction Fields
             ' This example posts a AO (Adjustment Out) Transaction
             oStockTran.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
             oStockTran.Fields.Item("Date").Value = CDate(Today)
             oStockTran.Fields.Item("Type").Value = CByte(SageDataObject300.StockTransType.sdoAO)
             oStockTran.Fields.Item("Quantity").Value = CDbl(2)
             oStockTran.Fields.Item("Reference").Value = CStr("Test AO")
             oStockTran.Fields.Item("Details").Value = CStr("Adjustments")

             ' Update the transaction
             If oStockPost.Update Then
               MessageBox.Show("The Stock Transaction Update was successful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)

             Else
               MessageBox.Show("The Stock Transaction Update was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

             End If
           Else
             MessageBox.Show("Could not load the cost code", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

           End If
         Else
           MessageBox.Show("Could not load the project", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

         End If
       Else
         MessageBox.Show("Could not find the stock code.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

       End If
     Else
       MessageBox.Show("Could not logon to the data.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

     End If
   End If
 Catch ex As Exception

   ' Show the exception error message
   MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

 Finally
   If Not oWS Is Nothing Then
     oWS.Disconnect()
     oWS = Nothing
   End If
   ' Dispose of any objects
   If Not oSDO Is Nothing Then oSDO = Nothing
   If Not oProject Is Nothing Then oProject = Nothing
   If Not oStockRecord Is Nothing Then oStockRecord = Nothing
   If Not oStockPost Is Nothing Then oStockPost = Nothing
   If Not oStockTran Is Nothing Then oStockTran = Nothing
   If Not oCostCode Is Nothing Then oCostCode = Nothing
 End Try
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.StockPost oStockPost;
            SageDataObject300.StockTran oStockTran;
            SageDataObject300.StockRecord oStockRecord;
            SageDataObject300.Project oProject;
            SageDataObject300.ProjectCostCode oCostCode;

            try
            {
                // Create Instances of Objects
                oStockPost = (SageDataObject300.StockPost)oWS.CreateObject("StockPost");
                oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");
                oCostCode = (SageDataObject300.ProjectCostCode)oWS.CreateProjectCostCode();
                oProject = (SageDataObject300.Project)oWS.CreateProject();

                // Find the required Stock Record
                SDOHelper.Write(oStockRecord, "STOCK_CODE", (String)"PC001");
                if (oStockRecord.Find(false))
                {
                    // Load the Project & Cost Code we wish to associate the AO with
                    Object projRef = "PROJ001";
                    Object costCode = "TRAV";

                    if (oProject.Load(ref projRef))
                    {
                        // Load the Cost Code
                        if (oCostCode.Load(ref costCode))
                        {
                            //Fill in header information required
                            SDOHelper.Write(oStockPost.Header, "STOCK_CODE", (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));

                            //Add to the items collection of the stock post object
                            oStockTran = (SageDataObject300.StockTran)SDOHelper.Add(oStockPost.Items);

                            //Populate Stock Transaction Fields
                            SDOHelper.Write(oStockTran, "STOCK_CODE", (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));
                            SDOHelper.Write(oStockTran, "DATE", (DateTime)DateTime.Today);
                            SDOHelper.Write(oStockTran, "TYPE", (Byte)SageDataObject300.StockTransType.sdoAO);
                            SDOHelper.Write(oStockTran, "QUANTITY", (Double)2);
                            SDOHelper.Write(oStockTran, "REFERENCE", (String)"Test AO");
                            SDOHelper.Write(oStockTran, "DETAILS", (String)"Adjustments");
                            oStockTran.CostCode = oCostCode;
                            oStockTran.Project = oProject;

                            // Update the StockPost object
                            if (oStockPost.Update())
                            {
                                MessageBox.Show("AO Transaction Posted successfully", "SDO Example", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            }
                            else
                            {
                                MessageBox.Show("AO Transaction Post failed", "SDO Example", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            }
                        }
                        else
                        {
                            MessageBox.Show("Could not load the cost code", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                    }
                    else
                    {
                        MessageBox.Show("Could not load the project", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                else
                {
                    MessageBox.Show("Could not find the Stock Record.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            // Error Handling Code
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Example", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            oWS.Disconnect();

        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Posting an Adjustment In to a Project

Example - Posting an Adjustment In to a Project

The example code below demonstrates how to post a stock adjustment in to a project. This will be using the StockTran object. For further information on Stock Postings click here.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

Note: If you attempt to Post an Adjustment In to a project that has a Status that is set to not allow postings then an error is thrown (sdoInvalidProjectStatus - Code 37).

VB.NET [image] Copy VB Code
 ' Declare Objects
 Dim oSDO As SageDataObject300.SDOEngine
 Dim oWS As SageDataObject300.WorkSpace
 Dim oStockPost As SageDataObject300.StockPost
 Dim oStockTran As SageDataObject300.StockTran
 Dim oStockRecord As SageDataObject300.StockRecord
 Dim oProject As SageDataObject300.Project
 Dim oCostCode As SageDataObject300.ProjectCostCode

 Dim szDataPath As String
 Try
   ' Create the SDO Engine object
   oSDO = New SageDataObject300.SDOEngine

   ' Create the Workspace
   oWS = oSDO.Workspaces.Add("Example")

   ' Select company. The SelectCompany method takes the program install folder as a parameter
   szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

   ' A U.I. for company selection is presented to the user. If a company is selected,
   ' the path will be passed to the szDataPath variable.
   ' If not, or the Cancel button is selected, the variable will be left empty.
   If szDataPath <> "" Then
     ' Connect to Data Files
     If oWS.Connect(szDataPath, "", "", "Example") Then
       ' Create Objects
       oProject = oWS.CreateProject
       oCostCode = oWS.CreateProjectCostCode
       oStockPost = oWS.CreateObject("StockPost")
       oStockRecord = oWS.CreateObject("StockRecord")

       ' Find the Stock Record we wish to post the Adjustment for
       oStockRecord.Fields.Item("STOCK_CODE").Value = "BOARD001"
       If oStockRecord.Find(False) Then
         ' Load the Project we wish to associate the stock adjustment with
         If oProject.Load("PROJ8") Then
           ' Load the Cost Code
           If oCostCode.Load("LAB1") Then
             ' Fill in Header information required
             oStockPost.Header("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)

             ' Add to the items collection of the StockPost object
             oStockTran = oStockPost.Items.Add

             ' Set the Project and CostCode
             oStockTran.Project = oProject
             oStockTran.CostCode = oCostCode

             ' Populate Stock Transaction Fields
             ' This example posts a AI (Adjustment In) Transaction
             oStockTran.Fields.Item("STOCK_CODE").Value = CStr(oStockRecord.Fields.Item("STOCK_CODE").Value)
             oStockTran.Fields.Item("Date").Value = CDate(Today)
             oStockTran.Fields.Item("Type").Value = CByte(SageDataObject300.StockTransType.sdoAI)
             oStockTran.Fields.Item("Quantity").Value = CDbl(2)
             oStockTran.Fields.Item("Reference").Value = CStr("Test AI")
             oStockTran.Fields.Item("Details").Value = CStr("Adjustments")
             oStockTran.Fields.Item("COST_PRICE").Value = CDbl(15)

             ' Update the transaction
             If oStockPost.Update Then
               MessageBox.Show("The Stock Transaction Update was successful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)

             Else
               MessageBox.Show("The Stock Transaction Update was unsuccessful", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

             End If
           Else
             MessageBox.Show("Could not load the cost code", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

           End If
         Else
           MessageBox.Show("Could not load the project", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

         End If
       Else
         MessageBox.Show("Could not find the stock code.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

       End If
     Else
       MessageBox.Show("Could not logon to the data.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

     End If
   End If
 Catch ex As Exception

   ' Show the exception error message
   MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

 Finally
   If Not oWS Is Nothing Then
     oWS.Disconnect()
     oWS = Nothing
   End If
   ' Dispose of any objects
   If Not oSDO Is Nothing Then oSDO = Nothing
   If Not oProject Is Nothing Then oProject = Nothing
   If Not oStockRecord Is Nothing Then oStockRecord = Nothing
   If Not oStockPost Is Nothing Then oStockPost = Nothing
   If Not oStockTran Is Nothing Then oStockTran = Nothing
   If Not oCostCode Is Nothing Then oCostCode = Nothing
 End Try
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.StockPost oStockPost;
            SageDataObject300.StockTran oStockTran;
            SageDataObject300.StockRecord oStockRecord;
            SageDataObject300.Project oProject;
            SageDataObject300.ProjectCostCode oCostCode;

            try
            {
                // Create Instances of Objects
                oStockPost = (SageDataObject300.StockPost)oWS.CreateObject("StockPost");
                oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");
                oCostCode = (SageDataObject300.ProjectCostCode)oWS.CreateProjectCostCode();
                oProject = (SageDataObject300.Project)oWS.CreateProject();

                // Find the required Stock Record
                SDOHelper.Write(oStockRecord, "STOCK_CODE", (String)"PC001");
                if (oStockRecord.Find(false))
                {
                    // Load the Project & Cost Code we wish to associate the AI with
                    Object projRef = "PROJ001";
                    Object costCode = "TRAV";

                    if (oProject.Load(ref projRef))
                    {
                        // Load the Cost Code
                        if (oCostCode.Load(ref costCode))
                        {
                            //Fill in header information required
                            SDOHelper.Write(oStockPost.Header, "STOCK_CODE", (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));

                            //Add to the items collection of the stock post object
                            oStockTran = (SageDataObject300.StockTran)SDOHelper.Add(oStockPost.Items);

                            //Populate Stock Transaction Fields
                            SDOHelper.Write(oStockTran, "STOCK_CODE", (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));
                            SDOHelper.Write(oStockTran, "DATE", (DateTime)DateTime.Today);
                            SDOHelper.Write(oStockTran, "TYPE", (Byte)SageDataObject300.StockTransType.sdoAI);
                            SDOHelper.Write(oStockTran, "QUANTITY", (Double)2);
                            SDOHelper.Write(oStockTran, "COST_PRICE", (Double)15);
                            SDOHelper.Write(oStockTran, "REFERENCE", (String)"Test AI");
                            SDOHelper.Write(oStockTran, "DETAILS", (String)"Adjustments");
                            oStockTran.CostCode = oCostCode;
                            oStockTran.Project = oProject;

                            // Update the StockPost object
                            if (oStockPost.Update())
                            {
                                MessageBox.Show("AI Transaction Posted successfully", "SDO Example", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            }
                            else
                            {
                                MessageBox.Show("AI Transaction Post failed", "SDO Example", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            }
                        }
                        else
                        {
                            MessageBox.Show("Could not load the cost code", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                    }
                    else
                    {
                        MessageBox.Show("Could not load the project", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                else
                {
                    MessageBox.Show("Could not find the Stock Record.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            // Error Handling Code
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Example", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            oWS.Disconnect();

        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Posting a Supplier Invoice to a Project

Example - Posting a Supplier Invoice to a Project

The example code below demonstrates how to post a supplier invoice to a project. This will be using the SplitData object. For further information on Cost Postings click here.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

Note: If you attempt to Post a Supplier Invoice to a project that has a Status that is set to not allow postings then an error is thrown (sdoInvalidProjectStatus - Code 37).

VB.NET [image] Copy VB Code
 ' Declare Objects
 Dim oSDO As SageDataObject300.SDOEngine
 Dim oWS As SageDataObject300.WorkSpace
 Dim oPurchaseRecord As SageDataObject300.PurchaseRecord
 Dim oTransactionPost As SageDataObject300.TransactionPost
 Dim oSplitData As SageDataObject300.SplitData
 Dim oProject As SageDataObject300.Project
 Dim oCostCode As SageDataObject300.ProjectCostCode

 ' Declare Variables
 Dim iCtr As Short
 Dim szDataPath As String
 Try
   ' Create the SDO Engine object
   oSDO = New SageDataObject300.SDOEngine

   ' Create the Workspace
   oWS = oSDO.Workspaces.Add("Example")

   ' Select company. The SelectCompany method takes the program install folder as a parameter
   szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

   ' A U.I. for company selection is presented to the user. If a company is selected,
   ' the path will be passed to the szDataPath variable.
   ' If not, or the Cancel button is selected, the variable will be left empty.
   If szDataPath <> "" Then
     ' Connect to Data Files
     If oWS.Connect(szDataPath, "", "", "Example") Then
       ' Create Instances of Objects
       oTransactionPost = oWS.CreateObject("TransactionPost")
       oPurchaseRecord = oWS.CreateObject("PurchaseRecord")
       oCostCode = oWS.CreateProjectCostCode
       oProject = oWS.CreateProject

       ' Find the Supplier we wish to post the invoice for
       oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value = "CON001"

       If oPurchaseRecord.Find(False) Then
         ' Load the Project we wish to associate the stock adjustment with
         If oProject.Load("PROJ8") Then
           ' Load the Cost Code
           If oCostCode.Load("LAB1") Then
             ' Populate Header fields
             ' Note:
             ' The ACCOUNT_REF field must be populated with a valid Supplier Account Reference
             oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value)
             oTransactionPost.Header("DATE").Value = CDate(Today)
             oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
             oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoPI)
             oTransactionPost.Header("DETAILS").Value = CStr("Test Purchase Invoice")
             oTransactionPost.Header("INV_REF").Value = CStr("INV001")
             oTransactionPost.Header("USER_NAME").Value = CStr("SDO")

             ' Loop for the Number of Splits
             ' Note:
             ' The Transaction can have 1 or many splits
             For iCtr = 1 To 2

               ' Add a split to the Header Item's collection
               oSplitData = oTransactionPost.Items.Add

               ' Populate Split Fields
               oSplitData.Fields.Item("TYPE").Value = oTransactionPost.Header("TYPE").Value
               oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("5000")
               oSplitData.Fields.Item("DETAILS").Value = oTransactionPost.Header("DETAILS").Value
               oSplitData.Fields.Item("TAX_CODE").Value = CShort(1)
               oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(100)
               oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(17.5)
               oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)
               oSplitData.Fields.Item("USER_NAME").Value = CStr("SDO")
               oSplitData.CostCode = oCostCode
               oSplitData.Project = oProject

             Next iCtr

             ' Update the TransactionPost object
             If oTransactionPost.Update Then
               MessageBox.Show("Transaction Posted successfully", "SDO Example", MessageBoxButtons.OK, MessageBoxIcon.Information)

             Else
               MessageBox.Show("Transaction Post failed", "SDO Example", MessageBoxButtons.OK, MessageBoxIcon.Error)

             End If
           Else
             MessageBox.Show("Could not load the cost code", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

           End If
         Else
           MessageBox.Show("Could not load the project", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

         End If
       Else
         MessageBox.Show("Could not find the supplier.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

       End If
     Else
       MessageBox.Show("Could not logon to the data.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

     End If
   End If
 ' Error Handling Code
 Catch ex As Exception

   ' Show the exception error message
   MessageBox.Show(ex.Message, "SDO Example", MessageBoxButtons.OK, MessageBoxIcon.Error)

 Finally
   If Not oWS Is Nothing Then
     oWS.Disconnect()
     oWS = Nothing
   End If
   ' Dispose of any objects
   If Not oSDO Is Nothing Then oSDO = Nothing
   If Not oProject Is Nothing Then oProject = Nothing
   If Not oCostCode Is Nothing Then oCostCode = Nothing
   If Not oTransactionPost Is Nothing Then oTransactionPost = Nothing
   If Not oPurchaseRecord Is Nothing Then oPurchaseRecord = Nothing
   If Not oSplitData Is Nothing Then oSplitData = Nothing
End Try
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.PurchaseRecord oPurchaseRecord;
            SageDataObject300.TransactionPost oTransactionPost;
            SageDataObject300.SplitData oSplitData;
            SageDataObject300.Project oProject;
            SageDataObject300.ProjectCostCode oCostCode;

            try
            {
                // Create Instances of Objects
                oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");
                oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");
                oCostCode = (SageDataObject300.ProjectCostCode)oWS.CreateProjectCostCode();
                oProject = (SageDataObject300.Project)oWS.CreateProject();

                // Find the Supplier Record we wish to post the Invoice to
                SDOHelper.Write(oPurchaseRecord, "ACCOUNT_REF", (String)"WIS002");
                if (oPurchaseRecord.Find(false))
                {
                    // Load the Project & Cost Code we wish to associate the PI with
                    Object projRef = "PROJ001";
                    Object costCode = "TRAV";

                    if (oProject.Load(ref projRef))
                    {
                        // Load the Cost Code
                        if (oCostCode.Load(ref costCode))
                        {
                            // Populate Header fields
                            SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"));
                            SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);
                            SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);
                            SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoPI);
                            SDOHelper.Write(oTransactionPost.Header, "DETAILS", (String)"Test Purchase Invoice");
                            SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"INV001");

                            //Loop for the number of splits
                            //Note: The transaction can have 1 or many splits
                            for (Int16 i = 1; i <= 2; i++)
                            {
                                //Add a split to the header items collection
                                oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                                //Populate the split fields
                                SDOHelper.Write(oSplitData, "TYPE", SDOHelper.Read(oTransactionPost.Header, "TYPE"));
                                SDOHelper.Write(oSplitData, "DETAILS", SDOHelper.Read(oTransactionPost.Header, "DETAILS"));
                                SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"5000");
                                SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)1);
                                SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)100);
                                SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)17.5);
                                SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));
                                SDOHelper.Write(oSplitData, "USER_NAME", (String)"SDO User");
                                oSplitData.CostCode = oCostCode;
                                oSplitData.Project = oProject;
                            }

                            // Update the TransactionPost object
                            if (oTransactionPost.Update())
                            {
                                MessageBox.Show("PI Transaction Posted successfully", "SDO Example", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            }
                            else
                            {
                                MessageBox.Show("PI Transaction Post failed", "SDO Example", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            }
                        }
                        else
                        {
                            MessageBox.Show("Could not load the cost code", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                    }
                    else
                    {
                        MessageBox.Show("Could not load the project", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                else
                {
                    MessageBox.Show("Could not find the Supplier Account.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            // Error Handling Code
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Example", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            oWS.Disconnect();

        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Posting a Supplier Credit to a Project

Example - Posting a Supplier Credit to a Project

The example code below demonstrates how to post a supplier credit to a project. This will be using the SplitData object. For further information on Cost Postings click here.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

Note: If you attempt to Post a Supplier Credit to a project that has a Status that is set to not allow postings then an error is thrown (sdoInvalidProjectStatus - Code 37).

VB.NET [image] Copy VB Code
 ' Declare Objects
 Dim oSDO As SageDataObject300.SDOEngine
 Dim oWS As SageDataObject300.WorkSpace
 Dim oPurchaseRecord As SageDataObject300.PurchaseRecord
 Dim oTransactionPost As SageDataObject300.TransactionPost
 Dim oSplitData As SageDataObject300.SplitData
 Dim oProject As SageDataObject300.Project
 Dim oCostCode As SageDataObject300.ProjectCostCode

 ' Declare Variables
 Dim iCtr As Short
 Dim szDataPath As String
 Try
   ' Create the SDO Engine object
   oSDO = New SageDataObject300.SDOEngine

   ' Create the Workspace
   oWS = oSDO.Workspaces.Add("Example")

   ' Select company. The SelectCompany method takes the program install folder as a parameter
   szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

   ' A U.I. for company selection is presented to the user. If a company is selected,
   ' the path will be passed to the szDataPath variable.
   ' If not, or the Cancel button is selected, the variable will be left empty.
   If szDataPath <> "" Then
     ' Connect to Data Files
     If oWS.Connect(szDataPath, "", "", "Example") Then
       ' Create Instances of Objects
       oTransactionPost = oWS.CreateObject("TransactionPost")
       oPurchaseRecord = oWS.CreateObject("PurchaseRecord")
       oCostCode = oWS.CreateProjectCostCode
       oProject = oWS.CreateProject

       ' Find the Supplier we wish to post the credit for
       oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value = "CON001"

       If oPurchaseRecord.Find(False) Then
         ' Load the Project we wish to associate the stock adjustment with
         If oProject.Load("PROJ8") Then
           ' Load the Cost Code
           If oCostCode.Load("LAB1") Then
             ' Populate Header fields
             ' Note:
             ' The ACCOUNT_REF field must be populated with a valid Supplier Account Reference
             oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value)
             oTransactionPost.Header("DATE").Value = CDate(Today)
             oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
             oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoPC)
             oTransactionPost.Header("DETAILS").Value = CStr("Test Purchase Credit")
             oTransactionPost.Header("INV_REF").Value = CStr("CRD001")
             oTransactionPost.Header("USER_NAME").Value = CStr("SDO")

             ' Loop for the Number of Splits
             ' Note:
             ' The Transaction can have 1 or many splits
             For iCtr = 1 To 2

               ' Add a split to the Header Item's collection
               oSplitData = oTransactionPost.Items.Add

               ' Populate Split Fields
               oSplitData.Fields.Item("TYPE").Value = oTransactionPost.Header("TYPE").Value
               oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("5000")
               oSplitData.Fields.Item("DETAILS").Value = oTransactionPost.Header("DETAILS").Value
               oSplitData.Fields.Item("TAX_CODE").Value = CShort(1)
               oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(100)
               oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(17.5)
               oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)
               oSplitData.Fields.Item("USER_NAME").Value = CStr("SDO")
               oSplitData.CostCode = oCostCode
               oSplitData.Project = oProject

             Next iCtr

             ' Update the TransactionPost object
             If oTransactionPost.Update Then
               MessageBox.Show("Transaction Posted successfully", "SDO Example", MessageBoxButtons.OK, MessageBoxIcon.Information)

             Else
               MessageBox.Show("Transaction Post failed", "SDO Example", MessageBoxButtons.OK, MessageBoxIcon.Error)

             End If
           Else
             MessageBox.Show("Could not load the cost code", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

           End If
         Else
           MessageBox.Show("Could not load the project", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

         End If
       Else
         MessageBox.Show("Could not find the supplier.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

       End If
     Else
       MessageBox.Show("Could not logon to the data.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

     End If
   End If
 ' Error Handling Code
 Catch ex As Exception

   ' Show the exception error message
   MessageBox.Show(ex.Message, "SDO Example", MessageBoxButtons.OK, MessageBoxIcon.Error)

 Finally
   If Not oWS Is Nothing Then
     oWS.Disconnect()
     oWS = Nothing
   End If
   ' Dispose of any objects
   If Not oSDO Is Nothing Then oSDO = Nothing
   If Not oProject Is Nothing Then oProject = Nothing
   If Not oCostCode Is Nothing Then oCostCode = Nothing
   If Not oTransactionPost Is Nothing Then oTransactionPost = Nothing
   If Not oPurchaseRecord Is Nothing Then oPurchaseRecord = Nothing
   If Not oSplitData Is Nothing Then oSplitData = Nothing
End Try
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.PurchaseRecord oPurchaseRecord;

SageDataObject300.TransactionPost oTransactionPost;

SageDataObject300.SplitData oSplitData;

SageDataObject300.Project oProject;

SageDataObject300.ProjectCostCode oCostCode;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate Objects

  oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

  oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");

  oCostCode = (SageDataObject300.ProjectCostCode)oWS.CreateProjectCostCode();

  oProject = (SageDataObject300.Project)oWS.CreateProject();

  //Find the supplier we wish to post the credit for

  SDOHelper.Write(oPurchaseRecord, "ACCOUNT_REF", (String)"CON001");

  if (oPurchaseRecord.Find(false))

  {

    //Load the Project we wish to associate the credit with

    //Note: In C# you need to pass a reference to an object

    Object ProjRef = "PROJECT1";

    if (oProject.Load(ref ProjRef))

    {

      //Load the Cost Code

      //Note: In C# you need to pass a reference to an object

      Object CostCodeRef = "MISC";

      if (oCostCode.Load(ref CostCodeRef))

      {

        //Populate the header fields

        SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF",

          (String)SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"));

        SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);

        SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);

        SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoPC);

        SDOHelper.Write(oTransactionPost.Header, "DETAILS", (String)"Test Purchase Credit");

        SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"CRD001");

        SDOHelper.Write(oTransactionPost.Header, "USER_NAME", (String)"SDO");

        //Loop for the number of splits

        //Note: The transaction can have one or many splits

        for (Int16 i = 1; i < 2; i++)

        {

          //Add a split to the Headers items collection

          oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

          //Populate the split fields

          SDOHelper.Write(oSplitData, "TYPE", SDOHelper.Read(oTransactionPost.Header, "TYPE"));

          SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"5000");

          SDOHelper.Write(oSplitData, "DETAILS",

            (String)SDOHelper.Read(oTransactionPost.Header, "DETAILS"));

          SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)1);

          SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)100);

          SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)17.5);

          SDOHelper.Write(oSplitData, "DATE",

            (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));

          SDOHelper.Write(oSplitData, "USER_NAME", (String)"SDO");

          oSplitData.CostCode = oCostCode;

          oSplitData.Project = oProject;

        }

        //Update the TransactionPost object

        if (oTransactionPost.Update())

        {

          MessageBox.Show("Transaction Posted Successfully");

        }

        else

        {

          MessageBox.Show("Transaction Post Failed");

        }

      }

      else

      {

        MessageBox.Show("Could Not Load The Cost Code");

      }

    }

    else

    {

      MessageBox.Show("Could Not Load The Project");

    }

  }

  else

  {

    MessageBox.Show("Could Not Find The Supplier");

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Posting a Bank Payment to a Project

Example - Posting a Bank Payment to a Project

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

Note: If you attempt to Post a Bank Payment to a project that has a Status that is set to not allow postings then an error is thrown (sdoInvalidProjectStatus - Code 37).

VB.NET [image] Copy VB Code
 ' Declare Objects
 Dim oSDO As SageDataObject300.SDOEngine
 Dim oWS As SageDataObject300.WorkSpace
 Dim oBankRecord As SageDataObject300.BankRecord
 Dim oTransactionPost As SageDataObject300.TransactionPost
 Dim oSplitData As SageDataObject300.SplitData
 Dim oProject As SageDataObject300.Project
 Dim oCostCode As SageDataObject300.ProjectCostCode

 ' Declare Variables
 Dim iCtr As Short
 Dim szDataPath As String
 Try
   ' Create the SDO Engine object
   oSDO = New SageDataObject300.SDOEngine

   ' Create the Workspace
   oWS = oSDO.Workspaces.Add("Example")

   ' Select company. The SelectCompany method takes the program install folder as a parameter
   szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

   ' A U.I. for company selection is presented to the user. If a company is selected,
   ' the path will be passed to the szDataPath variable.
   ' If not, or the Cancel button is selected, the variable will be left empty.
   If szDataPath <> "" Then
     ' Connect to Data Files
     If oWS.Connect(szDataPath, "", "", "Example") Then
       ' Create Instances of Objects
       oTransactionPost = oWS.CreateObject("TransactionPost")
       oBankRecord = oWS.CreateObject("BankRecord")
       oCostCode = oWS.CreateProjectCostCode
       oProject = oWS.CreateProject

       ' Find the Bank Record we wish to post the payment to
       oBankRecord.Fields.Item("ACCOUNT_REF").Value = "1200"

       If oBankRecord.Find(False) Then
         ' Load the Project we wish to associate the bank payment with
         If oProject.Load("PROJ8") Then
           ' Load the Cost Code
           If oCostCode.Load("LAB1") Then
             ' Populate Header fields
             ' Note:
             ' The ACCOUNT_REF field must be populated with a valid Bank Account Reference
             oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oBankRecord.Fields.Item("ACCOUNT_REF").Value)
             oTransactionPost.Header("DATE").Value = CDate(Today)
             oTransactionPost.Header("POSTED_DATE").Value = CDate(Today)
             oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoBP)
             oTransactionPost.Header("DETAILS").Value = CStr("Test Bank Payment")
             oTransactionPost.Header("INV_REF").Value = CStr("BP001")
             oTransactionPost.Header("BANK_CODE").Value = CStr("1200")

             ' Add a split to the Header Item's collection
             oSplitData = oTransactionPost.Items.Add

             ' Populate Split Fields
             oSplitData.Fields.Item("TYPE").Value = oTransactionPost.Header("TYPE").Value
             oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("5000")
             oSplitData.Fields.Item("DETAILS").Value = oTransactionPost.Header("DETAILS").Value
             oSplitData.Fields.Item("TAX_CODE").Value = CShort(1)
             oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(100)
             oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(17.5)
             oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)
             oSplitData.CostCode = oCostCode
             oSplitData.Project = oProject

             ' Update the TransactionPost object
             If oTransactionPost.Update Then
               MessageBox.Show("Transaction Posted successfully", "SDO Example", MessageBoxButtons.OK, MessageBoxIcon.Information)

             Else
               MessageBox.Show("Transaction Post failed", "SDO Example", MessageBoxButtons.OK, MessageBoxIcon.Error)

             End If
           Else
             MessageBox.Show("Could not load the cost code", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

           End If
         Else
           MessageBox.Show("Could not load the project", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

         End If
       Else
         MessageBox.Show("Could not find the bank account.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

       End If
     Else
       MessageBox.Show("Could not logon to the data.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

     End If
   End If
 ' Error Handling Code
 Catch ex As Exception

   ' Show the exception error message
   MessageBox.Show(ex.Message, "SDO Example", MessageBoxButtons.OK, MessageBoxIcon.Error)

 Finally
   If Not oWS Is Nothing Then
     oWS.Disconnect()
     oWS = Nothing
   End If
   ' Dispose of any objects
   If Not oSDO Is Nothing Then oSDO = Nothing
   If Not oProject Is Nothing Then oProject = Nothing
   If Not oCostCode Is Nothing Then oCostCode = Nothing
   If Not oTransactionPost Is Nothing Then oTransactionPost = Nothing
   If Not oBankRecord Is Nothing Then oBankRecord = Nothing
   If Not oSplitData Is Nothing Then oSplitData = Nothing
End Try
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.BankRecord oBankRecord;
            SageDataObject300.TransactionPost oTransactionPost;
            SageDataObject300.SplitData oSplitData;
            SageDataObject300.Project oProject;
            SageDataObject300.ProjectCostCode oCostCode;

            try
            {
                // Create Instances of Objects
                oBankRecord = (SageDataObject300.BankRecord)oWS.CreateObject("BankRecord");
                oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");
                oCostCode = (SageDataObject300.ProjectCostCode)oWS.CreateProjectCostCode();
                oProject = (SageDataObject300.Project)oWS.CreateProject();

                // Find the Bank Record we wish to post the payment to
                SDOHelper.Write(oBankRecord, "ACCOUNT_REF", (String)"1200");
                if (oBankRecord.Find(false))
                {
                    // Load the Project & Cost Code we wish to associate the BP with
                    Object projRef = "PROJ001";
                    Object costCode = "TRAV";

                    if (oProject.Load(ref projRef))
                    {
                        // Load the Cost Code
                        if (oCostCode.Load(ref costCode))
                        {
                            // Populate Header fields
                            // Note:
                            // The ACCOUNT_REF field must be populated with a valid Bank Account Reference
                            SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oBankRecord, "ACCOUNT_REF"));
                            SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Today);
                            SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Today);
                            SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoBP);
                            SDOHelper.Write(oTransactionPost.Header, "DETAILS", (String)"Test Bank Payment");
                            SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"BP001");
                            SDOHelper.Write(oTransactionPost.Header, "BANK_CODE", (String)"1200");

                            // Add a split to the Header Item's collection
                            oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                            // Populate Split Fields
                            SDOHelper.Write(oSplitData, "TYPE", SDOHelper.Read(oTransactionPost.Header, "TYPE"));
                            SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"5000");
                            SDOHelper.Write(oSplitData, "TAX_CODE", (Int16)1);
                            SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)100);
                            SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)17.5);
                            SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));
                            SDOHelper.Write(oSplitData, "DETAILS", (String)SDOHelper.Read(oTransactionPost.Header, "DETAILS"));
                            oSplitData.CostCode = oCostCode;
                            oSplitData.Project = oProject;

                            // Update the TransactionPost object
                            if (oTransactionPost.Update())
                            {
                                MessageBox.Show("BP Transaction Posted successfully", "SDO Example", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            }
                            else
                            {
                                MessageBox.Show("BP Transaction Post failed", "SDO Example", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            }
                        }
                        else
                        {
                            MessageBox.Show("Could not load the cost code", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                    }
                    else
                    {
                        MessageBox.Show("Could not load the project", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                else
                {
                    MessageBox.Show("Could not find the bank account.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            // Error Handling Code
            catch (Exception ex)
            {
                // Show the exception error message
                MessageBox.Show(ex.Message, "SDO Example", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            oWS.Disconnect();

        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Posting a Product Invoice for a Project

Example - Posting a Product Invoice for a Project

The example code below demonstrates how to post a product invoice for a project. This will be using the InvoiceItem object.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

Note: If you attempt to Post a Customer Invoice to a project that has a Status that is set to not allow postings then an error is thrown (sdoInvalidProjectStatus - Code 37).

VB.NET [image] Copy VB Code
 ' Declare Objects
 Dim oSDO As SageDataObject300.SDOEngine
 Dim oWS As SageDataObject300.WorkSpace
 Dim oInvoicePost As SageDataObject300.InvoicePost
 Dim oInvoiceItem As SageDataObject300.InvoiceItem
 Dim oSalesRecord As SageDataObject300.SalesRecord
 Dim oProject As SageDataObject300.Project

 ' Declare Variables
 Dim szDataPath As String
 Try
   ' Create the SDO Engine Object
   oSDO = New SageDataObject300.SDOEngine

   ' Create the Workspace
   oWS = oSDO.Workspaces.Add("Example")

   ' SelectCompany. The SelectCompany method takes the program install
   ' folder as a parameter
   szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

   ' A U.I. for company selection is presented to the user. If a company is selected,
   ' the path will be passed to the szDataPath variable.
   ' If not, or the Cancel button is selected, the variable will be left empty.
   If szDataPath <> "" Then
     ' Connect to Data Files - Will throw an exception if it fails
     If oWS.Connect(szDataPath, "", "", "Example") Then
       ' Create an instance of the Objects
       oSalesRecord = oWS.CreateObject("SalesRecord")
       oInvoicePost = oWS.CreateObject("InvoicePost")
       oProject = oWS.CreateProject

       ' Find the Customer we wish to post the invoice for
       oSalesRecord.Fields.Item("ACCOUNT_REF").Value = "A1D001"
       If oSalesRecord.Find(False) Then
         ' Load the Project we wish to associate the invoice with
         If oProject.Load("PROJ8") Then
           ' Set the type of invoice for the next available number
           oInvoicePost.Type = SageDataObject300.LedgerType.sdoLedgerInvoice

           oInvoicePost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
           oInvoicePost.Header("NAME").Value = CStr(oSalesRecord.Fields.Item("NAME").Value)
           oInvoicePost.Header("ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_1").Value)
           oInvoicePost.Header("ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_2").Value)
           oInvoicePost.Header("ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_3").Value)
           oInvoicePost.Header("ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_4").Value)
           oInvoicePost.Header("ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_5").Value)
           oInvoicePost.Header("DEL_ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_1").Value)
           oInvoicePost.Header("DEL_ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_2").Value)
           oInvoicePost.Header("DEL_ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_3").Value)
           oInvoicePost.Header("DEL_ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_4").Value)
           oInvoicePost.Header("DEL_ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_5").Value)
           oInvoicePost.Header("CUST_TEL_NUMBER").Value = CStr(oSalesRecord.Fields.Item("TELEPHONE").Value)
           oInvoicePost.Header("CONTACT_NAME").Value = CStr(oSalesRecord.Fields.Item("CONTACT_NAME").Value)
           oInvoicePost.Header("GLOBAL_TAX_CODE").Value = CShort(oSalesRecord.Fields.Item("DEF_TAX_CODE").Value)

           ' Populate other Invoice Header Information
           oInvoicePost.Header("INVOICE_DATE").Value = CDate(Today)
           oInvoicePost.Header("NOTES_1").Value = CStr("")
           oInvoicePost.Header("NOTES_2").Value = CStr("")
           oInvoicePost.Header("NOTES_3").Value = CStr("")
           oInvoicePost.Header("TAKEN_BY").Value = CStr("Mark Steel")
           oInvoicePost.Header("ORDER_NUMBER").Value = CStr("")
           oInvoicePost.Header("CUST_ORDER_NUMBER").Value = CStr("")
           oInvoicePost.Header("PAYMENT_REF").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.
           oInvoicePost.Header("GLOBAL_NOM_CODE").Value = CStr("")
           oInvoicePost.Header("GLOBAL_DETAILS").Value = CStr("")
           oInvoicePost.Header("INVOICE_TYPE_CODE").Value = CByte(SageDataObject300.InvoiceType.sdoProductInvoice)

           ' Create an Invoice Item
           oInvoiceItem = oInvoicePost.Items.Add()

           ' Set the Project
           oInvoiceItem.Project = oProject

           ' Populate the text, nominal and tax code fields
           oInvoiceItem.Fields.Item("STOCK_CODE").Value = "S3"
           oInvoiceItem.Fields.Item("TEXT").Value = CStr("Invoice for project")
           oInvoiceItem.Text = "Details of the project"
           oInvoiceItem.Fields.Item("NOMINAL_CODE").Value = CStr(oSalesRecord.Fields.Item("DEF_NOM_CODE").Value)
           oInvoiceItem.Fields.Item("TAX_CODE").Value = CInt(oSalesRecord.Fields.Item("DEF_TAX_CODE").Value)

           ' Populate other fields required for Invoice Item
           oInvoiceItem.Fields.Item("QTY_ORDER").Value = CDbl(1)
           oInvoiceItem.Fields.Item("UNIT_PRICE").Value = CDbl(100)
           oInvoiceItem.Fields.Item("NET_AMOUNT").Value = CDbl(100)
           oInvoiceItem.Fields.Item("TAX_AMOUNT").Value = CDbl(17.5)
           oInvoiceItem.Fields.Item("COMMENT_1").Value = CStr("")
           oInvoiceItem.Fields.Item("COMMENT_2").Value = CStr("")
           oInvoiceItem.Fields.Item("UNIT_OF_SALE").Value = CStr("")
           oInvoiceItem.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(100)
           oInvoiceItem.Fields.Item("TAX_RATE").Value = CDbl(17.5)

           ' Update the Invoice
           If oInvoicePost.Update Then
             MessageBox.Show("Invoice Posted Successfully", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Information)

           Else
             MessageBox.Show("Failed to create Invoice", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

           End If
         Else
           MessageBox.Show("Could not load the project", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

         End If
       Else
         MessageBox.Show("Could not find the customer.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

       End If
     Else
       MessageBox.Show("Could not logon to the data.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

     End If
   End If

 Catch ex As Exception

   MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

 Finally
   If Not oWS Is Nothing Then
     ' Disconnect
     oWS.Disconnect()
     oWS = Nothing
   End If
   ' Destroy(Objects)
   If Not oSDO Is Nothing Then oSDO = Nothing
   If Not oProject Is Nothing Then oProject = Nothing
   If Not oInvoicePost Is Nothing Then oInvoicePost = Nothing
   If Not oInvoiceItem Is Nothing Then oInvoiceItem = Nothing
   If Not oSalesRecord Is Nothing Then oSalesRecord = Nothing
 End Try
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.InvoicePost oInvoicePost;
            SageDataObject300.InvoiceItem oInvoiceItem;
            SageDataObject300.SalesRecord oSalesRecord;
            SageDataObject300.StockRecord oStockRecord;
            SageDataObject300.Project oProject;

            try
            {
                // Create an instance of the Objects
                oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");
                oInvoicePost = (SageDataObject300.InvoicePost)oWS.CreateObject("InvoicePost");
                oStockRecord = (SageDataObject300.StockRecord)oWS.CreateObject("StockRecord");
                oProject = (SageDataObject300.Project)oWS.CreateProject();

                // Find the Customer we wish to post the invoice for
                SDOHelper.Write(oSalesRecord, "ACCOUNT_REF", (String)"A1D001");
                if (oSalesRecord.Find(false))
                {
                    // Load the Project we wish to associate the invoice with
                    Object projRef = "PROJ001";

                    if (oProject.Load(ref projRef))
                    {
                        // Set the type of invoice for the next available number
                        oInvoicePost.Type = (SageDataObject300.InvoiceType)SageDataObject300.LedgerType.sdoLedgerInvoice;

                        SDOHelper.Write(oInvoicePost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));
                        SDOHelper.Write(oInvoicePost.Header, "NAME", (String)SDOHelper.Read(oSalesRecord, "NAME"));
                        SDOHelper.Write(oInvoicePost.Header, "ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_1"));
                        SDOHelper.Write(oInvoicePost.Header, "ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_2"));
                        SDOHelper.Write(oInvoicePost.Header, "ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_3"));
                        SDOHelper.Write(oInvoicePost.Header, "ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_4"));
                        SDOHelper.Write(oInvoicePost.Header, "ADDRESS_5", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_5"));
                        SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_1"));
                        SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_2"));
                        SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_3"));
                        SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_4"));
                        SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_5"));
                        SDOHelper.Write(oInvoicePost.Header, "CUST_TEL_NUMBER", (String)SDOHelper.Read(oSalesRecord, "TELEPHONE"));
                        SDOHelper.Write(oInvoicePost.Header, "CONTACT_NAME", (String)SDOHelper.Read(oSalesRecord, "CONTACT_NAME"));
                        SDOHelper.Write(oInvoicePost.Header, "GLOBAL_TAX_CODE", (Int16)SDOHelper.Read(oSalesRecord, "DEF_TAX_CODE"));

                        // Populate other Invoice Header Information
                        SDOHelper.Write(oInvoicePost.Header, "INVOICE_DATE", (DateTime)DateTime.Today);
                        SDOHelper.Write(oInvoicePost.Header, "NOTES_1", (String)"Notes 1");
                        SDOHelper.Write(oInvoicePost.Header, "NOTES_2", (String)"Notes 2");
                        SDOHelper.Write(oInvoicePost.Header, "NOTES_3", (String)"Notes 3");
                        SDOHelper.Write(oInvoicePost.Header, "TAKEN_BY", (String)"SDO User");
                        SDOHelper.Write(oInvoicePost.Header, "ORDER_NUMBER", (String)"");
                        SDOHelper.Write(oInvoicePost.Header, "CUST_ORDER_NUMBER", (String)"");
                        SDOHelper.Write(oInvoicePost.Header, "PAYMENT_REF", (String)"");
                        // If anything is entered in the GLOBAL_NOM_CODE, all of the updated invoice�s splits will have this
                        // nominal code and also this willforce anything entered in the GLOBAL_DETAILS field into the all
                        // the splits details field.
                        SDOHelper.Write(oInvoicePost.Header, "GLOBAL_NOM_CODE", (String)"");
                        SDOHelper.Write(oInvoicePost.Header, "GLOBAL_DETAILS", (String)"");
                        SDOHelper.Write(oInvoicePost.Header, "INVOICE_TYPE_CODE", (Byte)SageDataObject300.InvoiceType.sdoProductInvoice);

                        // Create an Invoice Item
                        oInvoiceItem = (SageDataObject300.InvoiceItem)SDOHelper.Add(oInvoicePost.Items);

                        // Set the Project
                        oInvoiceItem.Project = oProject;

                        // Move to First Stock Record & populate Invoice Item fields from Stock Record
                        oStockRecord.MoveFirst();
                        SDOHelper.Write(oInvoiceItem, "STOCK_CODE", (String)SDOHelper.Read(oStockRecord, "STOCK_CODE"));
                        SDOHelper.Write(oInvoiceItem, "DESCRIPTION", (String)SDOHelper.Read(oStockRecord, "DESCRIPTION"));
                        SDOHelper.Write(oInvoiceItem, "NOMINAL_CODE", (String)SDOHelper.Read(oStockRecord, "NOMINAL_CODE"));
                        SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)SDOHelper.Read(oStockRecord, "TAX_CODE"));

                        //Populate other invoice item fields
                        SDOHelper.Write(oInvoiceItem, "QTY_ORDER", (Int32)1);
                        SDOHelper.Write(oInvoiceItem, "UNIT_PRICE", (Int32)200);
                        SDOHelper.Write(oInvoiceItem, "NET_AMOUNT", (Int32)200);
                        SDOHelper.Write(oInvoiceItem, "TAX_AMOUNT", (Int32)0);
                        SDOHelper.Write(oInvoiceItem, "COMMENT_1", (String)"Comment 1");
                        SDOHelper.Write(oInvoiceItem, "COMMENT_2", (String)"Comment 2");
                        SDOHelper.Write(oInvoiceItem, "UNIT_OF_SALE", (String)"");
                        SDOHelper.Write(oInvoiceItem, "FULL_NET_AMOUNT", (Int32)200);
                        SDOHelper.Write(oInvoiceItem, "TAX_RATE", (Int32)17.5);

                        // Update the Invoice
                        if (oInvoicePost.Update())
                        {
                            MessageBox.Show("Invoice Posted Successfully", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        }
                        else
                        {
                            MessageBox.Show("Failed to create Invoice", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                    }
                    else
                    {
                        MessageBox.Show("Could not load the project", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                else
                {
                    MessageBox.Show("Could not find the customer.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Posting a Service Invoice for a Project

Example - Posting a Service Invoice for a Project

The example code below demonstrates how to post a service invoice for a project. This will be using the InvoiceItem object.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

Note: If you attempt to Post a Service Invoice to a project that has a Status that is set to not allow postings then an error is thrown (sdoInvalidProjectStatus - Code 37).

VB.NET [image] Copy VB Code
 ' Declare Objects
 Dim oSDO As SageDataObject300.SDOEngine
 Dim oWS As SageDataObject300.WorkSpace
 Dim oInvoicePost As SageDataObject300.InvoicePost
 Dim oInvoiceItem As SageDataObject300.InvoiceItem
 Dim oSalesRecord As SageDataObject300.SalesRecord
 Dim oProject As SageDataObject300.Project

 ' Declare Variables
 Dim szDataPath As String
 Try
   ' Create the SDO Engine Object
   oSDO = New SageDataObject300.SDOEngine

   ' Create the Workspace
   oWS = oSDO.Workspaces.Add("Example")

   ' SelectCompany. The SelectCompany method takes the program install
   ' folder as a parameter
   szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

   ' A U.I. for company selection is presented to the user. If a company is selected,
   ' the path will be passed to the szDataPath variable.
   ' If not, or the Cancel button is selected, the variable will be left empty.
   If szDataPath <> "" Then
     ' Connect to Data Files - Will throw an exception if it fails
     If oWS.Connect(szDataPath, "", "", "Example") Then
       ' Create an instance of the Objects
       oSalesRecord = oWS.CreateObject("SalesRecord")
       oInvoicePost = oWS.CreateObject("InvoicePost")
       oProject = oWS.CreateProject

       ' Find the Customer we wish to post the invoice for
       oSalesRecord.Fields.Item("ACCOUNT_REF").Value = "A1D001"
       If oSalesRecord.Find(False) Then
         ' Load the Project we wish to associate the invoice with
         If oProject.Load("PROJ8") Then
           ' Set the type of invoice for the next available number
           oInvoicePost.Type = SageDataObject300.LedgerType.sdoLedgerService

           oInvoicePost.Header("ACCOUNT_REF").Value = CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)
           oInvoicePost.Header("NAME").Value = CStr(oSalesRecord.Fields.Item("NAME").Value)
           oInvoicePost.Header("ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_1").Value)
           oInvoicePost.Header("ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_2").Value)
           oInvoicePost.Header("ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_3").Value)
           oInvoicePost.Header("ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_4").Value)
           oInvoicePost.Header("ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("ADDRESS_5").Value)
           oInvoicePost.Header("DEL_ADDRESS_1").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_1").Value)
           oInvoicePost.Header("DEL_ADDRESS_2").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_2").Value)
           oInvoicePost.Header("DEL_ADDRESS_3").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_3").Value)
           oInvoicePost.Header("DEL_ADDRESS_4").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_4").Value)
           oInvoicePost.Header("DEL_ADDRESS_5").Value = CStr(oSalesRecord.Fields.Item("DEL_ADDRESS_5").Value)
           oInvoicePost.Header("CUST_TEL_NUMBER").Value = CStr(oSalesRecord.Fields.Item("TELEPHONE").Value)
           oInvoicePost.Header("CONTACT_NAME").Value = CStr(oSalesRecord.Fields.Item("CONTACT_NAME").Value)
           oInvoicePost.Header("GLOBAL_TAX_CODE").Value = CShort(oSalesRecord.Fields.Item("DEF_TAX_CODE").Value)

           ' Populate other Invoice Header Information
           oInvoicePost.Header("INVOICE_DATE").Value = CDate(Today)
           oInvoicePost.Header("NOTES_1").Value = CStr("")
           oInvoicePost.Header("NOTES_2").Value = CStr("")
           oInvoicePost.Header("NOTES_3").Value = CStr("")
           oInvoicePost.Header("TAKEN_BY").Value = CStr("Mark Steel")
           oInvoicePost.Header("ORDER_NUMBER").Value = CStr("")
           oInvoicePost.Header("CUST_ORDER_NUMBER").Value = CStr("")
           oInvoicePost.Header("PAYMENT_REF").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.
           oInvoicePost.Header("GLOBAL_NOM_CODE").Value = CStr("")
           oInvoicePost.Header("GLOBAL_DETAILS").Value = CStr("")
           oInvoicePost.Header("INVOICE_TYPE_CODE").Value = CByte(SageDataObject300.InvoiceType.sdoServiceInvoice)

           ' Create an Invoice Item
           oInvoiceItem = oInvoicePost.Items.Add()

           ' Set the Project
           oInvoiceItem.Project = oProject

           ' Populate the text for the line
           oInvoiceItem.Fields.Item("TEXT").Value = CStr("Invoice for project")
           oInvoiceItem.Text = "Details of the project"
           oInvoiceItem.Fields.Item("NOMINAL_CODE").Value = CStr(oSalesRecord.Fields.Item("DEF_NOM_CODE").Value)
           oInvoiceItem.Fields.Item("TAX_CODE").Value = CInt(oSalesRecord.Fields.Item("DEF_TAX_CODE").Value)

           ' Populate other fields required for Invoice Item
           oInvoiceItem.Fields.Item("QTY_ORDER").Value = CDbl(1)
           oInvoiceItem.Fields.Item("UNIT_PRICE").Value = CDbl(100)
           oInvoiceItem.Fields.Item("NET_AMOUNT").Value = CDbl(100)
           oInvoiceItem.Fields.Item("TAX_AMOUNT").Value = CDbl(17.5)
           oInvoiceItem.Fields.Item("COMMENT_1").Value = CStr("")
           oInvoiceItem.Fields.Item("COMMENT_2").Value = CStr("")
           oInvoiceItem.Fields.Item("UNIT_OF_SALE").Value = CStr("")
           oInvoiceItem.Fields.Item("FULL_NET_AMOUNT").Value = CDbl(100)
           oInvoiceItem.Fields.Item("TAX_RATE").Value = CDbl(17.5)

           ' Update the Invoice
           If oInvoicePost.Update Then
             MessageBox.Show("Invoice Posted Successfully", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Information)

           Else
             MessageBox.Show("Failed to create Invoice", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

           End If
         Else
           MessageBox.Show("Could not load the project", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

         End If
       Else
         MessageBox.Show("Could not find the customer.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

       End If
     Else
       MessageBox.Show("Could not logon to the data.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

     End If
   End If

 Catch ex As Exception

   MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

 Finally
   If Not oWS Is Nothing Then
     ' Disconnect
     oWS.Disconnect()
     oWS = Nothing
   End If
   ' Destroy(Objects)
   If Not oSDO Is Nothing Then oSDO = Nothing
   If Not oProject Is Nothing Then oProject = Nothing
   If Not oInvoicePost Is Nothing Then oInvoicePost = Nothing
   If Not oInvoiceItem Is Nothing Then oInvoiceItem = Nothing
   If Not oSalesRecord Is Nothing Then oSalesRecord = Nothing
 End Try
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.InvoicePost oInvoicePost;
            SageDataObject300.InvoiceItem oInvoiceItem;
            SageDataObject300.SalesRecord oSalesRecord;
            SageDataObject300.Project oProject;

            try
            {
                // Create an instance of the Objects
                oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");
                oInvoicePost = (SageDataObject300.InvoicePost)oWS.CreateObject("InvoicePost");
                oProject = (SageDataObject300.Project)oWS.CreateProject();

                // Find the Customer we wish to post the invoice for
                SDOHelper.Write(oSalesRecord, "ACCOUNT_REF", (String)"A1D001");
                if (oSalesRecord.Find(false))
                {
                    // Load the Project we wish to associate the invoice with
                    Object projRef = "PROJ001";

                    if (oProject.Load(ref projRef))
                    {

                        // Set the type of invoice for the next available number
                        oInvoicePost.Type = (SageDataObject300.InvoiceType)SageDataObject300.LedgerType.sdoLedgerService;

                        SDOHelper.Write(oInvoicePost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF"));
                        SDOHelper.Write(oInvoicePost.Header, "NAME", (String)SDOHelper.Read(oSalesRecord, "NAME"));
                        SDOHelper.Write(oInvoicePost.Header, "ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_1"));
                        SDOHelper.Write(oInvoicePost.Header, "ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_2"));
                        SDOHelper.Write(oInvoicePost.Header, "ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_3"));
                        SDOHelper.Write(oInvoicePost.Header, "ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_4"));
                        SDOHelper.Write(oInvoicePost.Header, "ADDRESS_5", (String)SDOHelper.Read(oSalesRecord, "ADDRESS_5"));
                        SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_1", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_1"));
                        SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_2", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_2"));
                        SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_3", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_3"));
                        SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_4"));
                        SDOHelper.Write(oInvoicePost.Header, "DEL_ADDRESS_4", (String)SDOHelper.Read(oSalesRecord, "DEL_ADDRESS_5"));
                        SDOHelper.Write(oInvoicePost.Header, "CUST_TEL_NUMBER", (String)SDOHelper.Read(oSalesRecord, "TELEPHONE"));
                        SDOHelper.Write(oInvoicePost.Header, "CONTACT_NAME", (String)SDOHelper.Read(oSalesRecord, "CONTACT_NAME"));
                        SDOHelper.Write(oInvoicePost.Header, "GLOBAL_TAX_CODE", (Int16)SDOHelper.Read(oSalesRecord, "DEF_TAX_CODE"));

                        // Populate other Invoice Header Information
                        SDOHelper.Write(oInvoicePost.Header, "INVOICE_DATE", (DateTime)DateTime.Today);
                        SDOHelper.Write(oInvoicePost.Header, "NOTES_1", (String)"Notes 1");
                        SDOHelper.Write(oInvoicePost.Header, "NOTES_2", (String)"Notes 2");
                        SDOHelper.Write(oInvoicePost.Header, "NOTES_3", (String)"Notes 3");
                        SDOHelper.Write(oInvoicePost.Header, "TAKEN_BY", (String)"SDO");
                        SDOHelper.Write(oInvoicePost.Header, "ORDER_NUMBER", (String)"");
                        SDOHelper.Write(oInvoicePost.Header, "CUST_ORDER_NUMBER", (String)"");
                        SDOHelper.Write(oInvoicePost.Header, "PAYMENT_REF", (String)"");
                        // If anything is entered in the GLOBAL_NOM_CODE, all of the updated invoice�s splits will have this
                        // nominal code and also this willforce anything entered in the GLOBAL_DETAILS field into the all
                        // the splits details field.
                        SDOHelper.Write(oInvoicePost.Header, "GLOBAL_NOM_CODE", (String)"");
                        SDOHelper.Write(oInvoicePost.Header, "GLOBAL_DETAILS", (String)"");
                        SDOHelper.Write(oInvoicePost.Header, "INVOICE_TYPE_CODE", (Byte)SageDataObject300.InvoiceType.sdoServiceInvoice);

                        // Create an Invoice Item
                        oInvoiceItem = (SageDataObject300.InvoiceItem)SDOHelper.Add(oInvoicePost.Items);

                        // Set the Project
                        oInvoiceItem.Project = oProject;

                        // Populate the text for the line
                        oInvoiceItem.Text = (String)"Details of the project";

                        // Populate other fields required for Invoice Item
                        SDOHelper.Write(oInvoiceItem, "TEXT", (String)"Posting Text");
                        SDOHelper.Write(oInvoiceItem, "QTY_ORDER", (Double)1);
                        SDOHelper.Write(oInvoiceItem, "SERVICE_ITEM_LINES", (Int32)1);
                        SDOHelper.Write(oInvoiceItem, "NET_AMOUNT", (Double)100.00);
                        SDOHelper.Write(oInvoiceItem, "FULL_NET_AMOUNT", (Double)100.00);
                        SDOHelper.Write(oInvoiceItem, "TAX_AMOUNT", (Double)17.5);
                        SDOHelper.Write(oInvoiceItem, "NOMINAL_CODE", (String)SDOHelper.Read(oSalesRecord, "DEF_NOM_CODE"));
                        SDOHelper.Write(oInvoiceItem, "TAX_CODE", (Int16)SDOHelper.Read(oSalesRecord, "DEF_TAX_CODE"));
                        SDOHelper.Write(oInvoiceItem, "TAX_RATE", (Double)17.5);

                        // Update the Invoice
                        if (oInvoicePost.Update())
                        {
                            MessageBox.Show("Invoice Posted Successfully", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        }
                        else
                        {
                            MessageBox.Show("Failed to create Invoice", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                    }
                    else
                    {
                        MessageBox.Show("Could not load the project", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                else
                {
                    MessageBox.Show("Could not find the customer.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Posting a Sales Order for a Project

Example - Posting a Sales Order for a Project

The example code below demonstrates how to post a sales order for a project. This will be using the SOPItem object.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

Note: If you attempt to Post a Sales Order to a project that has a Status that is set to not allow postings then an error is thrown (sdoInvalidProjectStatus - Code 37).

VB.NET [image] Copy VB Code
 ' Declare Objects
 Dim oSDO As SageDataObject300.SDOEngine
 Dim oWS As SageDataObject300.WorkSpace
 Dim oSOPPost As SageDataObject300.SOPPost
 Dim oSOPItem As SageDataObject300.SOPItem
 Dim oSalesRecord As SageDataObject300.SalesRecord
 Dim oProject As SageDataObject300.Project

 ' Declare Variables
 Dim szDataPath As String
 Try
   ' Create the SDO Engine Object
   oSDO = New SageDataObject300.SDOEngine

   ' Create the Workspace
   oWS = oSDO.Workspaces.Add("Example")

   ' SelectCompany. The SelectCompany method takes the program install
   ' folder as a parameter
   szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

   ' A U.I. for company selection is presented to the user. If a company is selected,
   ' the path will be passed to the szDataPath variable.
   ' If not, or the Cancel button is selected, the variable will be left empty.
   If szDataPath <> "" Then
     ' Connect to Data Files - Will throw an exception if it fails
     If oWS.Connect(szDataPath, "", "", "Example") Then
       ' Create an instance of the Objects
       oSalesRecord = oWS.CreateObject("SalesRecord")
       oSOPPost = oWS.CreateObject("SOPPost")
       oProject = oWS.CreateProject

       ' Find the Customer we wish to post the Sales Order for
       oSalesRecord.Fields.Item("ACCOUNT_REF").Value = "A1D001"
       If oSalesRecord.Find(False) Then
         ' Load the Project we wish to associate the Sales Order with
         If oProject.Load("PROJ8") Then

           ' Populate the SOP Header information
           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(oSalesRecord.Fields.Item("CONTACT_NAME").Value)
           oSOPPost.Header("GLOBAL_TAX_CODE").Value = CShort(oSalesRecord.Fields.Item("DEF_TAX_CODE").Value)

           ' Populate other SOP Header Information
           oSOPPost.Header("ORDER_DATE").Value = CDate(Today)
           oSOPPost.Header("NOTES_1").Value = CStr("")
           oSOPPost.Header("NOTES_2").Value = CStr("")
           oSOPPost.Header("NOTES_3").Value = CStr("")
           oSOPPost.Header("TAKEN_BY").Value = CStr("Will Hearn")
           oSOPPost.Header("ORDER_NUMBER").Value = CStr("")
           oSOPPost.Header("CUST_ORDER_NUMBER").Value = CStr("")
           oSOPPost.Header("PAYMENT_REF").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 a SOP Item
           oSOPItem = oSOPPost.Items.Add()

           ' Set the Project
           oSOPItem.Project = oProject

           ' Populate the text for the line
           oSOPItem.Fields.Item("STOCK_CODE").Value = "S3"
           oSOPItem.Fields.Item("TEXT").Value = CStr("SOP for project")
           oSOPItem.Text = "Details of the project"
           oSOPItem.Fields.Item("NOMINAL_CODE").Value = CStr(oSalesRecord.Fields.Item("DEF_NOM_CODE").Value)
           oSOPItem.Fields.Item("TAX_CODE").Value = CInt(oSalesRecord.Fields.Item("DEF_TAX_CODE").Value)

           ' Populate other fields required for Invoice Item
           oSOPItem.Fields.Item("QTY_ORDER").Value = CDbl(1)
           oSOPItem.Fields.Item("UNIT_PRICE").Value = CDbl(100)
           oSOPItem.Fields.Item("NET_AMOUNT").Value = CDbl(100)
           oSOPItem.Fields.Item("TAX_AMOUNT").Value = CDbl(17.5)
           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("FULL_NET_AMOUNT").Value = CDbl(100)
           oSOPItem.Fields.Item("TAX_RATE").Value = CDbl(17.5)

           ' Update the Sales Order
           If oSOPPost.Update Then
             MessageBox.Show("The Sales Order Posted Successfully", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Information)

           Else
             MessageBox.Show("Failed to create Sales Order", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

           End If
         Else
           MessageBox.Show("Could not load the project", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

         End If
       Else
         MessageBox.Show("Could not find the customer.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

       End If
     Else
       MessageBox.Show("Could not logon to the data.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

     End If
   End If

 Catch ex As Exception

   MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

 Finally
   If Not oWS Is Nothing Then
     ' Disconnect
     oWS.Disconnect()
     oWS = Nothing
   End If
   ' Destroy(Objects)
   If Not oSDO Is Nothing Then oSDO = Nothing
   If Not oProject Is Nothing Then oProject = Nothing
   If Not oSOPPost Is Nothing Then oSOPPost = Nothing
   If Not oSOPItem Is Nothing Then oSOPItem = Nothing
   If Not oSalesRecord Is Nothing Then oSalesRecord = Nothing
 End Try
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {

            // Declare Objects
            SageDataObject300.SopPost oSopPost;
            SageDataObject300.SopItem oSopItem;
            SageDataObject300.SalesRecord oSalesRecord;
            SageDataObject300.Project oProject;

            try
            {
                // Create an instance of the Objects
                oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");
                oSopPost = (SageDataObject300.SopPost)oWS.CreateObject("SopPost");
                oProject = (SageDataObject300.Project)oWS.CreateProject();

                // Find the Customer we wish to post the Sales Order for
                SDOHelper.Write(oSalesRecord, "ACCOUNT_REF", (String)"A1D001");
                if (oSalesRecord.Find(false))
                {
                    // Create a Project Reference object
                    Object projRef = "PROJ001";

                    // Load the Project we wish to associate the Sales Order with
                    if (oProject.Load(ref projRef))
                    {

                        // Populate the SOP Header information
                        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)SDOHelper.Read(oSalesRecord, "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)"John Smith");
                        // If anything is entered in the GLOBAL_NOM_CODE, all of the updated invoice�s splits will have this
                        // nominal code and also this willforce 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)"");
                        SDOHelper.Write(oSopPost.Header, "ORDER_NUMBER", (String)"");
                        SDOHelper.Write(oSopPost.Header, "CUST_ORDER_NUMBER", (String)"");
                        SDOHelper.Write(oSopPost.Header, "PAYMENT_REF", (String)"");

                        // Create a SOP Item
                        oSopItem = (SageDataObject300.SopItem)SDOHelper.Add(oSopPost.Items);

                        // Set the Project
                        oSopItem.Project = oProject;

                        // Populate the text for the line
                        SDOHelper.Write(oSopItem, "STOCK_CODE", (String)"S3");
                        SDOHelper.Write(oSopItem, "TEXT", (String)"SOP for project");
                        oSopItem.Text = (String)"Details of the project";
                        SDOHelper.Write(oSopItem, "NOMINAL_CODE", (String)SDOHelper.Read(oSalesRecord, "DEF_NOM_CODE"));
                        SDOHelper.Write(oSopItem, "TAX_CODE", (Int16)SDOHelper.Read(oSalesRecord, "DEF_TAX_CODE"));

                        // Populate other fields required for Invoice Item
                        SDOHelper.Write(oSopItem, "QTY_ORDER", (Double)1);
                        SDOHelper.Write(oSopItem, "UNIT_PRICE", (Double)100);
                        SDOHelper.Write(oSopItem, "NET_AMOUNT", (Double)100);
                        SDOHelper.Write(oSopItem, "FULL_NET_AMOUNT", (Double)100);
                        SDOHelper.Write(oSopItem, "TAX_AMOUNT", (Double)17.5);
                        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)17.5);

                        // Update the Sales Order
                        if (oSopPost.Update())
                        {
                            MessageBox.Show("The Sales Order Posted Successfully", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        }
                        else
                        {
                            MessageBox.Show("Failed to create Sales Order", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                    }
                    else
                    {
                        MessageBox.Show("Could not load the project", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                else
                {
                    MessageBox.Show("Could not find the customer.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - View Transactions on a Project

Example - View Transactions on a Project

The example code below demonstrates how to view the transactions for a project. This will be using the ProjectTransactions object. This example assumes that a project exists ('PROJ8') and that transactions exist on it.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
 ' Declare Objects
 Dim oSDO As SageDataObject300.SDOEngine
 Dim oWS As SageDataObject300.WorkSpace
 Dim oProject As SageDataObject300.Project
 Dim oTransactions As SageDataObject300.ProjectTransactions
 Dim oTransaction As SageDataObject300.ProjectTransaction
 Dim oListItem As ListViewItem

 Dim szDataPath As String
 Try
   ' Create the SDO Engine object
   oSDO = New SageDataObject300.SDOEngine

   ' Create the Workspace
   oWS = oSDO.Workspaces.Add("Example")

   ' Select company. The SelectCompany method takes the program install folder as a parameter
   szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

   ' A U.I. for company selection is presented to the user. If a company is selected,
   ' the path will be passed to the szDataPath variable.
   ' If not, or the Cancel button is selected, the variable will be left empty.
   If szDataPath <> "" Then
     ' Connect to Data Files
     If oWS.Connect(szDataPath, "", "", "Example") Then
       ' Create Objects
       oProject = oWS.CreateProject

       ' Load the Project we wish to post the charge on
       If oProject.Load("PROJ8") Then
         ' Get the transactions from the project
         oTransactions = oProject.Transactions

         ' If there is more than 1 transaction
         If oTransactions.Count > 0 Then
           ' Add the columns to the ListView
           Me.lstView.Columns.Clear()
           Me.lstView.Columns.Add("No", 40, HorizontalAlignment.Left)
           Me.lstView.Columns.Add("Audit No", 70, HorizontalAlignment.Left)
           Me.lstView.Columns.Add("Type", 50, HorizontalAlignment.Left)
           Me.lstView.Columns.Add("Date", 80, HorizontalAlignment.Left)
           Me.lstView.Columns.Add("Reference", 70, HorizontalAlignment.Left)
           Me.lstView.Columns.Add("Quantity", 40, HorizontalAlignment.Left)
           Me.lstView.Columns.Add("Cost Code", 70, HorizontalAlignment.Left)
           Me.lstView.Columns.Add("Details", 100, HorizontalAlignment.Left)
           Me.lstView.Columns.Add("Amount", 70, HorizontalAlignment.Left)
           Me.lstView.Items.Clear()

           ' For each transaction add the details to the ListView
           For Each oTransaction In oTransactions

             oListItem = Me.lstView.Items.Add(oTransaction.TransactionID)
             oListItem.SubItems.Add(oTransaction.AuditTrailID)
             oListItem.SubItems.Add(oTransaction.Type)
             oListItem.SubItems.Add(oTransaction.Date.ToShortDateString)
             oListItem.SubItems.Add(oTransaction.Reference)
             oListItem.SubItems.Add(oTransaction.Quantity)
             oListItem.SubItems.Add(oTransaction.CostCode.Reference)
             oListItem.SubItems.Add(oTransaction.Details)
             oListItem.SubItems.Add(oTransaction.Amount)

           Next
         Else
           MessageBox.Show("There are no transactions for the project", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Information)

         End If
       Else
         MessageBox.Show("Could not load the project", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

       End If
     Else
       MessageBox.Show("Could not logon to the data.", "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

     End If
   End If
 Catch ex As Exception

   ' Show the exception error message
   MessageBox.Show(ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

 Finally
   If Not oWS Is Nothing Then
     oWS.Disconnect()
     oWS = Nothing
   End If
   ' Dispose of any objects
   If Not oSDO Is Nothing Then oSDO = Nothing
   If Not oProject Is Nothing Then oProject = Nothing
   If Not oTransactions Is Nothing Then oTransactions = Nothing
   If Not oTransaction Is Nothing Then oTransaction = Nothing
 End Try
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.Project oProject;

SageDataObject300.ProjectTransactions oTransactions;

ListViewItem oListItem;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

  //Leaving the username and password blank generates a login dialog

  oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

  //Instantiate Project Object

  oProject = (SageDataObject300.Project)oWS.CreateProject();

  //Load the project

  //Note: In C# you need to pass a reference to an object

  Object ProjRef = "PROJECT1";

  if (oProject.Load(ref ProjRef))

  {

    //Get the transactions collection from the project

    oTransactions = (SageDataObject300.ProjectTransactions)oProject.Transactions;

    //If there are some transactions

    if (oTransactions.Count > 0)

    {

      //Add the columns to the listview

      this.listView1.Columns.Clear();

      this.listView1.Columns.Add("No.", 40, HorizontalAlignment.Left);

      this.listView1.Columns.Add("Audit No.", 40, HorizontalAlignment.Left);

      this.listView1.Columns.Add("Type", 40, HorizontalAlignment.Left);

      this.listView1.Columns.Add("Date", 40, HorizontalAlignment.Left);

      this.listView1.Columns.Add("Reference", 40, HorizontalAlignment.Left);

      this.listView1.Columns.Add("Quantity", 40, HorizontalAlignment.Left);

      this.listView1.Columns.Add("Cost Code", 40, HorizontalAlignment.Left);

      this.listView1.Columns.Add("Details", 40, HorizontalAlignment.Left);

      this.listView1.Columns.Add("Amount", 40, HorizontalAlignment.Left);

      this.listView1.Items.Clear();

      //For each transaction add the details to the listview

      foreach ( SageDataObject300.ProjectTransaction oTransaction in oTransactions)

      {

        oListItem = this.listView1.Items.Add(oTransaction.TransactionID.ToString());

        oListItem.SubItems.Add(oTransaction.AuditTrailID.ToString());

        oListItem.SubItems.Add(oTransaction.Type.ToString());

        oListItem.SubItems.Add(oTransaction.Date.ToShortDateString().ToString());

        oListItem.SubItems.Add(oTransaction.Reference.ToString());

        oListItem.SubItems.Add(oTransaction.Quantity.ToString());

        oListItem.SubItems.Add(

          ((SageDataObject300.ProjectCostCode)oTransaction.CostCode).Reference.ToString());

        oListItem.SubItems.Add(oTransaction.Details.ToString());

        oListItem.SubItems.Add(oTransaction.Amount.ToString());

      }

    }

    else

    {

      MessageBox.Show("There Are No Transactions For The Project");

    }

  }

  else

  {

    MessageBox.Show("Could Not Load The Project");

  }

  //Disconnect

  oWS.Disconnect();

}

catch (Exception ex)

{

  MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}


Sage 50 Accounts - Example - Amending CIS and ESubmission Settings

Example - Amending CIS and ESubmission Settings

The example code below demonstrates how to amend CIS and ESubmission settings.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code

' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oCISSettings As SageDataObject300.CISSetting
Dim oESubmissionSetting As SageDataObject300.ESubmissionSetting
Dim oCISControlReference As SageDataObject300.Nominal
Dim oCISLabourNominal As SageDataObject300.Nominal
Dim oCISMaterialsNominal As SageDataObject300.Nominal
Dim oCISOtherNonTaxableNominal As SageDataObject300.Nominal
Dim oCISOtherTaxableNominal As SageDataObject300.Nominal
Dim oCISTaxLiabilityNominal As SageDataObject300.Nominal

' Declare Variables
Dim szDataPath As String

' Create the SDOEngine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

' Try to Connect - Will Throw an Exception if it Fails
If oWS.Connect(szDataPath, "", "", "Example") Then

'Create CIS Setting object and load
 oCISSettings = oWS.CreateCISSetting
oESubmissionSetting = oWS.CreateESubmissionSetting
oCISSettings.Load()
oESubmissionSetting.Load()

'Create Nominal Objects
 oCISControlReference = oWS.CreateNominal
oCISLabourNominal = oWS.CreateNominal
oCISMaterialsNominal = oWS.CreateNominal
oCISOtherNonTaxableNominal = oWS.CreateNominal
oCISOtherTaxableNominal = oWS.CreateNominal
oCISTaxLiabilityNominal = oWS.CreateNominal

'Set Nominal Codes
 oCISControlReference.Load("2101")
oCISLabourNominal.Load("6000")
oCISMaterialsNominal.Load("6001")
oCISOtherNonTaxableNominal.Load("6100")
oCISOtherTaxableNominal.Load("6002")
oCISTaxLiabilityNominal.Load("2102")

'Set Nominal Objects equal to CIS Setting Nominal Objects
 oCISSettings.CISControlReference = oCISControlReference
oCISSettings.CISLabourNominal = oCISLabourNominal
oCISSettings.CISMaterialsNominal = oCISMaterialsNominal
oCISSettings.CISOtherNonTaxableNominal = oCISOtherNonTaxableNominal
oCISSettings.CISOtherTaxableNominal = oCISOtherTaxableNominal
oCISSettings.CISTaxLiabilityNominal = oCISTaxLiabilityNominal

'Edit CIS and ESubmission Settings
 oCISSettings.CompanyRegistrationNo = CStr("1234567890")
oCISSettings.UniqueTaxReference = CStr("ABC123456")
oESubmissionSetting.Forenames = CStr("Mark")
oESubmissionSetting.Surname = CStr("Steel")
oESubmissionSetting.SenderType = CByte(SageDataObject300.ESubmissionSenderType.sdoCompany)

If oCISSettings.Update() Then

If oESubmissionSetting.Update() Then

MessageBox.Show("CIS and ESubmission Settings Updated Sucessfully")

Else

MessageBox.Show("ESubmission Update Failed")

End if

Else

MessageBox.Show("CISSetting Update Failed")

End If

' Disconnect
oWS.Disconnect()

End If

End If

' Destroy Objects
oSDO = Nothing
oWS = Nothing
oCISSettings = Nothing
oESubmissionSetting = Nothing
oCISControlReference = Nothing
oCISLabourNominal = Nothing
oCISMaterialsNominal = Nothing
oCISOtherNonTaxableNominal = Nothing
oCISOtherTaxableNominal = Nothing
oCISTaxLiabilityNominal = Nothing

Exit Sub

C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare objects
            SageDataObject300.CISSetting oCISSettings;
            SageDataObject300.ESubmissionSetting oESubmissionSetting;
            SageDataObject300.Nominal oCISControlReference;
            SageDataObject300.Nominal oCISLabourNominal;
            SageDataObject300.Nominal oCISMaterialsNominal;
            SageDataObject300.Nominal oCISOtherNonTaxableNominal;
            SageDataObject300.Nominal oCISOtherTaxableNominal;
            SageDataObject300.Nominal oCISTaxLiabilityNominal;

            // Create CIS Setting object and load
            oCISSettings = (SageDataObject300.CISSetting)oWS.CreateCISSetting();
            oESubmissionSetting = (SageDataObject300.ESubmissionSetting)oWS.CreateESubmissionSetting();
            oCISSettings.Load();
            oESubmissionSetting.Load();

            // Create Nominal Objects
            oCISControlReference = (SageDataObject300.Nominal)oWS.CreateNominal();
            oCISLabourNominal = (SageDataObject300.Nominal)oWS.CreateNominal();
            oCISMaterialsNominal = (SageDataObject300.Nominal)oWS.CreateNominal();
            oCISOtherNonTaxableNominal = (SageDataObject300.Nominal)oWS.CreateNominal();
            oCISOtherTaxableNominal = (SageDataObject300.Nominal)oWS.CreateNominal();
            oCISTaxLiabilityNominal = (SageDataObject300.Nominal)oWS.CreateNominal();

            object oCntrlRef = "2101";
            object oLabNom = "6000";
            object oMatNom = "6001";
            object oOthNonTaxNom = "6100";
            object oOthTaxNom = "6002";
            object oTaxLiabNom = "2102";

            // Set Nominal Codes
            oCISControlReference.Load(ref oCntrlRef);
            oCISLabourNominal.Load(ref oLabNom);
            oCISMaterialsNominal.Load(ref oMatNom);
            oCISOtherNonTaxableNominal.Load(ref oOthNonTaxNom);
            oCISOtherTaxableNominal.Load(ref oOthTaxNom);
            oCISTaxLiabilityNominal.Load(ref oTaxLiabNom);

            // Set Nominal Objects equal to CIS Setting Nominal Objects
            oCISSettings.CISControlReference = oCISControlReference;
            oCISSettings.CISLabourNominal = oCISLabourNominal;
            oCISSettings.CISMaterialsNominal = oCISMaterialsNominal;
            oCISSettings.CISOtherNonTaxableNominal = oCISOtherNonTaxableNominal;
            oCISSettings.CISOtherTaxableNominal = oCISOtherTaxableNominal;
            oCISSettings.CISTaxLiabilityNominal = oCISTaxLiabilityNominal;

            // Edit CIS and ESubmission Settings
            oCISSettings.CompanyRegistrationNo = (string)"1234567890";
            oCISSettings.UniqueTaxReference = (string)"ABC123456";
            oESubmissionSetting.Forenames = (string)"John";
            oESubmissionSetting.Surname = (string)"Smith";
            oESubmissionSetting.SenderType = SageDataObject300.ESubmissionSenderType.sdoCompany;

            if (oCISSettings.Update())
            {
                if (oESubmissionSetting.Update())
                {
                    MessageBox.Show("CIS and ESubmission Settings Updated Sucessfully");
                }
                else
                {
                    MessageBox.Show("ESubmission Update Failed");
                }
            }
            else
            {
                MessageBox.Show("CISSetting Update Failed");
            }

            // Disconnect
            oWS.Disconnect();

        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Creating a New Subcontractor Record

Example - Creating a New Subcontractor Record

The example code below demonstrates how to create a new Subcontractor Record.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oPurchaseRecord As SageDataObject300.PurchaseRecord
Dim oCISSubContractor As SageDataObject300.CISSubcontrator
Dim oCISLegacy As SageDataObject300.CisSubcontractorLegacy
Dim oCISTaxHistory As SageDataObject300.CisSubcontractorTaxHistory
Dim oSupplier As SageDataObject300.Supplier

' Declare Variables
Dim szDataPath As String

' Create the SDOEngine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

' Try to Connect - Will Throw an Exception if it Fails
If oWS.Connect(szDataPath, "", "", "Example") Then

' Create an Instance of the PurchaseRecord Object
 oPurchaseRecord = oWS.CreateObject("PurchaseRecord")

' Try to Add a New Record
If oPurchaseRecord.AddNew Then

 oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value = CStr("SAGEGRP")
oPurchaseRecord.Fields.Item("NAME").Value = CStr("The Sage Group plc")
oPurchaseRecord.Fields.Item("ADDRESS_1").Value = CStr("Building 5")
oPurchaseRecord.Fields.Item("ADDRESS_2").Value = CStr("North Park")
oPurchaseRecord.Fields.Item("ADDRESS_3").Value = CStr("Newcastle Upon Tyne")
oPurchaseRecord.Fields.Item("ADDRESS_4").Value = CStr("Tyne and Wear")
oPurchaseRecord.Fields.Item("ADDRESS_5").Value = CStr("NE13 9AA")
oPurchaseRecord.Fields.Item("CONTACT_NAME").Value = CStr("Mark Steel")
oPurchaseRecord.Fields.Item("TELEPHONE").Value = CStr("0845 1117733")
oPurchaseRecord.Fields.Item("FAX").Value = CStr("0845 2450294")
oPurchaseRecord.Fields.Item("TERMS").Value = CStr("30 Days")
oPurchaseRecord.Fields.Item("DEF_NOM_CODE").Value = CStr("5000")
oPurchaseRecord.Fields.Item("VAT_REG_NUMBER").Value = CStr("")
oPurchaseRecord.Fields.Item("COUNTRY_CODE").Value = CStr("GB")

' Update the Record
If oPurchaseRecord.Update Then

'Once Supplier record has been created the CIS details can be added

'Create and load supplier business object
oSupplier = oWS.CreateSupplier

If oSupplier.Load(oPurchaseRecord.Fields.It em("Account_Ref").V alue) Then

' Create Subcontractor object
 oCISSubContractor = oWS.CreateCISSubcontractor
oCISLegacy = oWS.CreateCISSubcontractorLegacy
oCISTaxHistory = oWS.CreateCISSubcontractorTaxHistory

' Populate Basic Subcontractor fields
 oCISSubContractor.Supplier = oSupplier
oCISSubContractor.CompanyType = CBtye(SageDataObject300.CISCompanyType.sdoCompanyType)
oCISSubContractor.FirstName = CStr("Dan")
oCISSubContractor.LastName = CStr("Minnick")

' Populate CIS Legacy field
 oCISLegacy.Supplier = oSupplier
oCISLegacy.CardType = CByte(SageDataObject300.CISCardType.CIS4_Permanent)
oCISLegacy.CISNumber = CStr("123456")
oCISLegacy.CISType = CByte(SageDataObject300.CISType.sdoCIS4)
oCISLegacy.ValidFr om = CDate(#1/1/2006#)
oCISLegacy.ValidTo = CDate(#12/31/2049#)

' Populate CIS Tax History Details
 oCISTaxHistory.Supplier = oSupplier
oCISTaxHistory.TaxTreatment = CByte(SageDataObject300.CISTaxTreatment.sdoStandardRate)
oCISTaxHistory.StartDate = CDate(#4/6/2007#)

If oCISSubContractor.Update() Then

Else

 MessageBox.Show("Subcontractor Details not updated")

If oCISLegacy.Update Then

Else

MessageBox.Show("Tax History not updated")

If oCISTaxHistory.Update Then

' The updates were successful
MessageBox.Show("New Subcontractor Record has been successfully created.", _
"New Subcontractor Record", MessageBoxButtons.OK, MessageBoxIcon.Information)

Else

MessageBox.Show("Tax History not updated")

End If

End If

End If

End If

End If

Else
' The Update was Unsuccessful
 MessageBox.Show("The account could not be created.")

End If

End If

' Disconnect
oWS.Disconnect()

End If

' Destroy Objects
 oSDO = Nothing
oWS = Nothing
oPurchaseRecord = Nothing
oCISSubContractor = Nothing
oSupplier = Nothing
oCISLegacy = Nothing
oCISTaxHistory = Nothing

Exit Sub
C#.NET [image] Copy C# Code
//Declare Objects
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.PurchaseRecord oPurchaseRecord;
SageDataObject300.CISSubcontrator oCISSubcontractor;
SageDataObject300.CisSubcontractorLegacy oCISLegacy;
SageDataObject300.CisSubcontractorTaxHistory oCISTaxHistory;
SageDataObject300.Supplier oSupplier;

//Declare Variables
String szDataPath;

//Create the Workspace Object
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Select Company. The SelectCompany method takes the program install
//folder as parameter
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

try
{
 //Try to connect - Will throw exception if it fails
  if (oWS.Connect(szDataPath, "", "", "Example"))
  {
      //Create an instance of the PurchaseRecord Object
      oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");

      //Try to add a new record
      if (oPurchaseRecord.AddNew())
      {
          SDOHelper.Write(oPurchaseRecord, "ACCOUNT_REF", (String)"SAGEGRP");
          SDOHelper.Write(oPurchaseRecord, "NAME", (String)"The Sage Group PLC");
          SDOHelper.Write(oPurchaseRecord, "ADDRESS_1", (String)"Sage 3:3");
          SDOHelper.Write(oPurchaseRecord, "ADDRESS_2", (String)"North Park");
          SDOHelper.Write(oPurchaseRecord, "ADDRESS_3", (String)"Newcastle Upon Tyne");
          SDOHelper.Write(oPurchaseRecord, "ADDRESS_4", (String)"Tyne and Wear");
          SDOHelper.Write(oPurchaseRecord, "ADDRESS_5", (String)"NE13 9AA");
          SDOHelper.Write(oPurchaseRecord, "CONTACT_NAME", (String)"Pete Brown");
          SDOHelper.Write(oPurchaseRecord, "TELEPHONE", (String)"0845 111 77 33");
          SDOHelper.Write(oPurchaseRecord, "FAX", (String)"0845 245 0294");
          SDOHelper.Write(oPurchaseRecord, "TERMS", (String)"30 Days");
          SDOHelper.Write(oPurchaseRecord, "DEF_NOM_CODE", (String)"5000");
          SDOHelper.Write(oPurchaseRecord, "VAT_REG_NUMBER", (String)"");
          SDOHelper.Write(oPurchaseRecord, "COUNTRY_CODE", (String)"GB");

          if (oPurchaseRecord.Update())
          {
              //Once Supplier record has been created the CIS details can be added

              //Create and load supplier business object
              oSupplier = (SageDataObject300.Supplier)oWS.CreateSupplier();

              Object suppRef = SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF");
              if (oSupplier.Load(ref suppRef))

              {
                  //Create Subcontractor Object
                  oCISSubcontractor = (SageDataObject300.CISSubcontrator)oWS.CreateCISSubcontractor();
                  oCISLegacy = (SageDataObject300.CisSubcontractorLegacy)oWS.CreateCISSubcontractorLegacy();
                  oCISTaxHistory = (SageDataObject300.CisSubcontractorTaxHistory)oWS.CreateCISSubcontractorTaxHistory();

                  //Populate Basic Subcontractor fields
                  oCISSubcontractor.Supplier = oSupplier;
                  oCISSubcontractor.CompanyType = SageDataObject300.CISCompanyType.sdoCompanyType;
                  oCISSubcontractor.FirstName = (String)"Danny";
                  oCISSubcontractor.LastName = (String)"Patter";

                  //Populate CIS Legacy field
                  oCISLegacy.Supplier = oSupplier;
                  oCISLegacy.CardType = SageDataObject300.CISCardType.CIS4_Permanent;
                  oCISLegacy.CISNumber = (String)"123456";
                  oCISLegacy.CISType = SageDataObject300.CISType.sdoCIS4;
                  oCISLegacy.ValidFrom = DateTime.Parse("1 1 2006");
                  oCISLegacy.ValidTo = DateTime.Parse("31 12 2049");

                  //Populate CIS Tax History details
                  oCISTaxHistory.Supplier = oSupplier;
                  oCISTaxHistory.TaxTreatment = SageDataObject300.CISTaxTreatment.sdoStandardRate;
                  oCISTaxHistory.StartDate = DateTime.Parse("4 6 2010");

                  if (oCISSubcontractor.Update())
                  {
                      if(oCISLegacy.Update())
                      {
                          if(oCISTaxHistory.Update())
                          {
                              MessageBox.Show("New Subcontractor Record has been successfully created.");
                          }
                          else
                          {
                              MessageBox.Show("Tax History not updated");
                          }

                      }
                      else
                      {
                          MessageBox.Show("Legacy not updated");
                      }
                  }
                  else
                  {
                      MessageBox.Show("Subcontractor Details not updated");
                  }
              }
          }
      }
  }
}
    //Error Handling code
catch (Exception ex)
  {
    MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
  }

finally
{
    //Disconnect
    oWS.Disconnect();
}


Sage 50 Accounts - Example - Creating a Subcontractor Record From An Existing Supplier Record

Example - Creating a Subcontractor Record From An Existing Supplier Record

The example code below demonstrates how to create a Subcontractor Record from an existing Supplier Record.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oPurchaseRecord As SageDataObject300.PurchaseRecord
Dim oCISSubContractor As SageDataObject300.CISSubcontrator
Dim oSupplier As SageDataObject300.Supplier

' Declare Variables
Dim szDataPath As String

' Create the SDOEngine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
 oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install
' folder as a parameter
 szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

' Try to Connect - Will Throw an Exception if it Fails
If oWS.Connec t(szDataPath, "", "", "Example") Then

' Create an Instance of the PurchaseRecord Object
oPurchaseRecord = oWS.CreateObject("PurchaseRecord")

' Move to last Supplier Record
If oPurchaseRecord.MoveLast Then

'Create and load supplier business object
 oSupplier = oWS.CreateSupplier

If oSupplier.Load(oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value) Then

'Create Subcontractor object
oCISSubContractor = oWS.CreateCISSubcontractor

'Populate Basic Subcontractor infomation
 oCISSubContractor.Supplier = oSupplier
oCISSubContractor.CompanyType = CByte(SageDataObject300.CISCompanyType.sdoCompanyType)
oCISSubContractor.FirstName = "Dave"
oCISSubContractor.LastName = "Clark"

If oCISSubContractor.Update() Then

 MessageBox.Show("Subcontractor Details added to " & oSupplier.Reference)

End If

End If

End If

' Disconnect
oWS.Disconnect()

End If

End If

' Destroy Objects
 oSDO = Nothing
oWS = Nothing
oPurchaseRecord = Nothing
oCISSubContractor = Nothing
oSupplier = Nothing

Exit Sub
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare required objects
            SageDataObject300.CISSubcontrator oCISSubContractor;
            SageDataObject300.Supplier oSupplier;
            SageDataObject300.PurchaseRecord oPurchaseRecord;

            // Create an Instance of the PurchaseRecord Object
            oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");

            //Create supplier placeholder object
            oSupplier = (SageDataObject300.Supplier)oWS.CreateObject("Supplier");

            // Move to last Supplier Record
            if (oPurchaseRecord.MoveLast())
            {
                // Create and load supplier business object
                Object supplier = (String)SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF");
                if (oSupplier.Load(ref supplier))
                {
                    //Create Subcontractor object
                    oCISSubContractor = (SageDataObject300.CISSubcontrator)oWS.CreateCISSubcontractor();

                    //Populate Basic Subcontractor infomation
                    oCISSubContractor.Supplier = oSupplier;
                    oCISSubContractor.CompanyType = (SageDataObject300.CISCompanyType)SageDataObject300.CISCompanyType.sdoCompanyType;
                    oCISSubContractor.FirstName = (String)"John";
                    oCISSubContractor.LastName = (String)"Smith";

                    if (oCISSubContractor.Update())
                    {
                        MessageBox.Show("Subcontractor Details added to " + oSupplier.Reference);
                    }
                }
            }

            // Disconnect
            oWS.Disconnect();

        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Edit CIS Details

Example - Edit CIS Details

The example code below demonstrates how to edit CIS details.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code

' declare objects

Dim oSDO As SageDataObject300.SDOEngine

Dim oWS As SageDataObject300.WorkSpace

Dim oPurchaseRecord As SageDataObject300.PurchaseRecord

Dim oSupplier As SageDataObject300.Supplier

Dim oCISSubContractor As SageDataObject300.CISSubcontrator

Dim oCISLegacy As SageDataObject300.CisSubcontractorLegacy

Dim oCISTaxHistory As SageDataObject300.CisSubcontractorTaxHistory

' Declare Variables

Dim szDataPath As String

' Create the SDOEngine Object

oSDO = New SageDataObject300.SDOEngine

' Create the Workspace

oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install

' folder as a parameter

szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,

' the path will be passed to the szDataPath variable.

' If not, or the Cancel button is selected, the variable will be left empty.

If szDataPath <> "" Then

' Try to Connect - Will Throw an Exception if it Fails

If oWS.Connect(szDataPath, "", "", "Example") Then

' create instance of purchase record

oPurchaseRecord = oWS.CreateObject("PURCHASERECORD")

' find required supplier, example uses a supplier with reference SUPP1

oPurchaseRecord.Fields.Item("Account_Ref").Value = "SUPP1"

oPurchaseRecord.Find(False)

' create supplier placeholder object

oSupplier = oWS.CreateSupplier

' get first and last name of the main contact for this record

Dim fullName As String = CStr(oPurchaseRecord.Fields.Item("CONTACT_NAME").Value)

Dim txtArray() As String

txtArray = fullName.Split(" ")

Dim firstName As String = txtArray(0)

Dim lastName As String = txtArray(1)

' load the Supplier

If oSupplier.Load(oPurchaseRecord.Fields.Item("Account_Ref").Value) Then

' we can now pass the Supplier (placeholder) to our other Business Objects' properties

' create Subcontractor object

oCISSubContractor = oWS.CreateCISSubcontractor

oCISLegacy = oWS.CreateCISSubcontractorLegacy

oCISTaxHistory = oWS.CreateCISSubcontractorTaxHistory

oCISSubContractor.Load(CStr(oPurchaseRecord.Fields.Item("Account_Ref").Value))

' populate Basic Subcontractor fields

oCISSubContractor.Supplier = oSupplier

oCISSubContractor.CompanyType = CByte(SageDataObject300.CISCompanyType.sdoCompanyType)

oCISSubContractor.FirstName = CStr(firstName)

oCISSubContractor.LastName = CStr(lastName)

' Populate CIS Legacy field

oCISLegacy.Load(CStr(oPurchaseRecord.Fields.Item("Account_Ref").Value))

oCISLegacy.Supplier = oSupplier

oCISLegacy.CardType = CByte(SageDataObject300.CISCardType.CIS4_Permanent)

oCISLegacy.CISNumber = CStr("123456")

oCISLegacy.CISType = CByte(SageDataObject300.CISType.sdoCIS4)

oCISLegacy.ValidFrom = CDate(#1/1/2006#)

oCISLegacy.ValidTo = CDate(#12/31/2049#)

' Populate CIS Tax History Details

oCISTaxHistory.Load(CStr(oPurchaseRecord.Fields.Item("Account_Ref").Value), Date.Now)

oCISTaxHistory.Supplier = oSupplier

oCISTaxHistory.TaxTreatment = CByte(SageDataObject300.CISTaxTreatment.sdoStandardRate)

' this date must be different to any previous value

oCISTaxHistory.StartDate = CDate(#4/6/2010#)

If oCISSubContractor.Update() Then

If oCISLegacy.Update Then

If oCISTaxHistory.Update Then

MsgBox("All Subcontractor Details updated")

Else

MsgBox("Tax History not updated")

End If

Else

MsgBox("Legacy Details not updated")

End If

Else

MsgBox("Subcontractor Details not updated")

End If

End If

End If

End If

oWS.Disconnect()
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.PurchaseRecord oPurchaseRecord;

SageDataObject300.Supplier oSupplier;

SageDataObject300.CISSubcontrator oCISSubContractor;

SageDataObject300.CisSubcontractorLegacy oCISLegacy;

SageDataObject300.CisSubcontractorTaxHistory oCISTaxHistory;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//Try a connection, will throw an exception if it fails

try

{

//Leaving the username and password blank generates a login dialog

oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

//Create instance of purchase record

oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");

//Find required supplier, example uses a supplier with reference "SUPPLIER"

SDOHelper.Write(oPurchaseRecord, "ACCOUNT_REF", (String)"SUPP1");

oPurchaseRecord.Find(false);

//Create supplier placeholder object

oSupplier = (SageDataObject300.Supplier)oWS.CreateObject("Supplier");

//Get first and last name of the main contact for this record

String fullName = (String)(SDOHelper.Read(oPurchaseRecord, "CONTACT_NAME"));

MessageBox.Show(fullName);

String[] txtArray = fullName.Split(' ');

String firstName = txtArray[0];

String lastName = txtArray[1];

MessageBox.Show(firstName + Environment.NewLine + lastName);

//Load the supplier

Object supplier = (String)SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF");

if ( oSupplier.Load(ref supplier))

{

//We can now pass the supplier (placeholder) to our other busiess objects' properties

//Create Subcontractor object

oCISSubContractor = (SageDataObject300.CISSubcontrator)oWS.CreateCISSubcontractor();

MessageBox.Show("sub contactor!");

oCISLegacy = (SageDataObject300.CisSubcontractorLegacy)oWS.CreateCISSubcontractorLegacy();

MessageBox.Show("CIS LEGACY!");

oCISTaxHistory = (SageDataObject300.CisSubcontractorTaxHistory)oWS.CreateCISSubcontractorTaxHistory();

MessageBox.Show("CIS HIstory!");

//Populate the basic subcontractor fields

Object subcontractor = (String)SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF");

oCISSubContractor.Load(ref subcontractor);

oCISSubContractor.Supplier = oSupplier;

oCISSubContractor.CompanyType = SageDataObject300.CISCompanyType.sdoCompanyType;

oCISSubContractor.FirstName = (String)firstName;

oCISSubContractor.LastName = (String)lastName;

//Populate the CIS Legacy field

Object legacy = (String)SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF");

oCISLegacy.Load(ref legacy);

oCISLegacy.Supplier = oSupplier;

oCISLegacy.CardType = SageDataObject300.CISCardType.CIS4_Permanent;

oCISLegacy.CISType = SageDataObject300.CISType.sdoCIS4;

oCISLegacy.ValidFrom = DateTime.Parse("1 1 2006");

oCISLegacy.ValidTo = DateTime.Parse("31 12 2049");

//Populate CIS Tax History Details

Object daytoday = System.DateTime.Now;

Object history = (String)SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF");

oCISTaxHistory.Load(ref history, ref daytoday);

oCISTaxHistory.Supplier = oSupplier;

oCISTaxHistory.TaxTreatment = SageDataObject300.CISTaxTreatment.sdoStandardRate;

oCISTaxHistory.StartDate = DateTime.Parse ("4 6 2010");

{

if (oCISSubContractor.Update())

{

if (oCISLegacy.Update())

{

if (oCISTaxHistory.Update())

{

MessageBox.Show("All Subcontractor Details updated");

}

else

{

MessageBox.Show("Tax History not updated");

}

}

else

{

MessageBox.Show("Legacy Details not updated");

}

}

else

{

MessageBox.Show("Subcontractor Details not updated");

}

}

}

}

catch (Exception ex)

{

MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

}

//Disconnect

oWS.Disconnect();


Sage 50 Accounts - Example - Posting a Subcontractor Invoice

Example - Posting a Subcontractor Invoice

The example code below demonstrates how to post a Subcontractor Invoice.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oPurchaseRecord As SageDataObject300.PurchaseRecord
Dim oTransactionPost As SageDataObject300.TransactionPost
Dim oSplitData As SageDataObject300.SplitData

' Declare Variables
Dim szDataPath As String
Dim iCtr As Short

' Create the SDO Engine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is 'selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left 'empty.
If szDataPath <> "" Then

' Connect to Data Files
If oWS.Connect(szDataPath, "", "", "Example") Then

' Create Instances of Objects
oTransactionPost = oWS.CreateObject("TransactionPost")
oPurchaseRecord = oWS.CreateObject("PurchaseRecord")

 ' Find Supplier Record "CON001"
oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value = CStr("CON001")

If oPurchaseRecord.Find(False) Then

' Populate Header fields
' Note:
' The ACCOUNT_REF field must be populated with a valid Supplier Account Reference
oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value = CDate(#4/30/2007#)
oTransactionPost.Header("POSTED_DATE").Value = CDate(#4/30/2007#)
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoPI)
oTransactionPost.Header("INV_REF").Value = CStr("INV001")

 ' Populate the foreign currency fields
 oTransactionPost.Header("CURRENCY").Value = oPurchaseRecord.Fields.Item("CURRENCY").Value

' Loop for the Number of Splits
' Note:
' The Transaction can have 1 or many splits
For iCtr = 1 To 2

' Add a split to the Header Item's collection
oSplitData = oTransactionPost.Items.Add

' Populate Split Fields
' Note:
' Nominal Code must be populated with a valid CIS Nominal Code
' otherwise a supplier batch invoice is posted
 oSplitData.Fields.Item("TYPE").Value = CByte(oTransactionPost.Header("TYPE").Value)
oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("6000")
oSplitData.Fields.Item("TAX_CODE").Value = CShort(1)
oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(100)
oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(17.5)
oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)

Next iCtr

' Update the TransactionPost object
If oTransactionPost.Update Then

 MessageBox.Show("Transaction Posted successfully")

Else

 MessageBox.Show("Transaction Post Failed")

 End If

Else

 MessageBox.Show("Subcontractor Account can not be found")

 End If

 ' Disconnect
oWS.Disconnect()

End If

End If

'Destroy Objects
oTransactionPost = Nothing
oSplitData = Nothing
oPurchaseRecord = Nothing
oSDO = Nothing
oWS = Nothing

Exit Sub
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // Declare Objects
            SageDataObject300.PurchaseRecord oPurchaseRecord;
            SageDataObject300.TransactionPost oTransactionPost;
            SageDataObject300.SplitData oSplitData;
            short iCtr;

            // Create Instances of Objects
            oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");
            oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");

            // Find Supplier Record "CON001"
            SDOHelper.Write(oPurchaseRecord, "ACCOUNT_REF", (String)"CON001");

            if (oPurchaseRecord.Find(false))
            {
                // Populate Header fields
                // Note:
                // The ACCOUNT_REF field must be populated with a valid Supplier Account Reference
                SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"));
                SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)DateTime.Parse("30/04/2007"));
                SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)DateTime.Parse("30/04/2007"));
                SDOHelper.Write(oTransactionPost.Header, "TYPE", (byte)SageDataObject300.TransType.sdoPI);
                SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"INV001");

                // Populate the foreign currency fields
                SDOHelper.Write(oTransactionPost.Header, "CURRENCY", SDOHelper.Read(oPurchaseRecord, "CURRENCY"));

                // Loop for the Number of Splits
                // Note:
                // The Transaction can have 1 or many splits
                for (iCtr = 1; iCtr <= 2; iCtr++)
                {
                    // Add a split to the Header Item's collection
                    oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                    // Populate Split Fields
                    // Note:
                    // Nominal Code must be populated with a valid CIS Nominal Code
                    // otherwise a supplier batch invoice is posted
                    SDOHelper.Write(oSplitData, "TYPE", SDOHelper.Read(oTransactionPost.Header, "TYPE"));
                    SDOHelper.Write(oSplitData, "NOMINAL_CODE", (string)"6000");
                    SDOHelper.Write(oSplitData, "TAX_CODE", (Int32)1);
                    SDOHelper.Write(oSplitData, "NET_AMOUNT", (double)100);
                    SDOHelper.Write(oSplitData, "TAX_AMOUNT", (double)17.5);
                    SDOHelper.Write(oSplitData, "DATE", SDOHelper.Read(oTransactionPost.Header, "DATE"));
                }

                // Update the TransactionPost object
                if (oTransactionPost.Update())
                {
                    MessageBox.Show("Transaction Posted successfully");
                }
                else
                {
                    MessageBox.Show("Transaction Post Failed");
                }
            }
            else
            {
                MessageBox.Show("Subcontractor Account can not be found");
            }
            // Disconnect
            oWS.Disconnect();

        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - Posting a Subcontractor Payment

Example - Posting a Subcontractor Payment

The example code below demonstrates how to post a subcontractor payment. The code also includes a calculation for the CIS Tax, which is posted as Purchase Credit to the appropriate Nominal Code.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code

' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oCISSubcontractor As SageDataObject300.CISSubcontrator
Dim oCISTaxHistory As SageDataObject300.CisSubcontractorTaxHistory
Dim oCISTaxHistorys As SageDataObject300.CisSubcontractorTaxHistorys
Dim oCISSetting As SageDataObject300.CISSetting
Dim oNominalCode As SageDataObject300.Nominal
Dim oPurchaseRecord As SageDataObject300.PurchaseRecord
Dim oTransactionPost As SageDataObject300.TransactionPost
Dim oSplitData As SageDataObject300.SplitData
Dim oHeaderData As SageDataObject300.HeaderData

' Declare Variables
Dim szDataPath As String
Dim bRecordFound, bTransactionFound, bPosted, bAllocated As Boolean
Dim dPaymentValue As Double
Dim dCISTaxValue As Double
Dim dTaxTreatment As Double
Dim lPaymentSplit, lInvoiceSplit As Long

' Note: Date must be after 6th April 2007
Dim dPostDate As Date = "4/30/2007"

' Create the SDO Engine object
oSDO = New SageDataObject300.SDOEngine()

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select company. The SelectCompany method takes the program install folder as a parameter
 szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

' Connect to Data Files
 oWS.Connect(szDataPath, "", "", "Example")

' Create an instance of the PurchaseRecord object
 oPurchaseRecord = oWS.CreateObject("PurchaseRecord")

' Initialise Index Field with value to search
 oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value = CStr("CON001")

' Perform Find for an exact match
 bRecordFound = oPurch aseRecord.Find(False)

If bRecordFound Then

' Link to Headers
 oHeaderData = oPurchaseRecord.Link

' Move to the first Header on the Purchase Ledger account
oHeaderData.MoveFirst()

' Attempt to find an Invoice.
' Loop through the Headers until the Invoice Reference is found
Do

If oHeaderData.Fields.Item("INV_REF").Value = CStr("INV001") Then

' Set the invoice transaction found flag
bTransactionFound = True

' Exit the loop
Exit Do

End If

Loop Until Not oHeaderData.MoveNext

If bTransactionFound Then

' Link to Splits
 oSplitData = oHeaderData.Link

' Move to first Split
oSplitData.MoveFirst()

' Calculate Purchase Payment Value
 dPaymentValue = CDbl(oSplitData.Fields.Item("NET_AMOUNT").Value) + CDbl(oSplitData.Fields.Item("TAX_AMOUNT").Value) - CDbl(oSplitData.Fields.Item("AMOUNT_PAID").Value)

' Store Split Number for Invoice
 lInvoiceSplit = oSplitData.RecordNumber

If dPaymentValue > 0 Then

'Create and Load CIS Business Objects
 oCISSubcontractor = oWS.CreateCISSubcontractor
oCISSubcontractor.Load(oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value)

oCISTaxHistorys = oWS.CreateCISSubcontractorTaxHistorys
oCISTaxHistorys = oCISSubcontractor.TaxHistorys

oCISSetting = oWS.CreateCISSetting
oCISSetting.Load()

For Each oCISTaxHistory In oCISTaxHistorys

'Find correct tax history for posted date
If (dPostDate > oCISTaxHistory.StartDate) And (dPostDate < oCISTaxHistory.EndDate) Then

Select Case oCISTaxHistory.TaxTreatment

Case SageDataObject300.CISTaxTreatment.sdoGross
dTaxTreatment = 0

Case SageDataObject300.CISTaxTreatment.sdoHigherRate
dTaxTreatment = (oCISSetting.HigherRate) / 100

Case SageDataObject300.CISTaxTreatment.sdoStandardRate
 dTaxTreatment = (oCISSetting.StandardRate) / 100

End Select

' Calculate Payment and CIS Tax Value
 dCISTaxValue = Decimal.Round((CDec(oSplitData.Fields.Item("NET_AMOUNT").Value) * CDec(dTaxTreatment), 2, MidpointRounding.AwayFromZero)
dPaymentValue = dPaymentValue - dCISTaxValue

Exit For

End If

Next

' Create an instance of TransactionPost for the Purchase Payment
 oTransactionPost = oWS.CreateObject("TransactionPost")

' Fill in the Header fields
 oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value = CDate(dPostDate)
oTransactionPost.Header("POSTED_DATE").Value = CDate(dPostDate)
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoPP)
oTransactionPost.Header("DETAILS").Value = CStr("Purchase Payment")
oTransactionPost.Header("INV_REF").Value = CStr("BACS")
oTransactionPost.Header("BANK_CODE").Value = CStr("1200")

' Destroy Existing Split Object
 oSplitData = Nothing

' Create a split item by adding an empty split to the Items
' collection of the TransactionPost Object.
 oSplitData = oTransactionPost.Items.Add()

' Fill in the Split fields - note a Purchase Payment only has one split
 oSplitData.Fields.Item("TYPE").Value = CByte(SageDataObject300.TransType.sdoPP)
oSplitData.Fields.Item("NOMINAL_CODE").Value = CStr("1200")
oSplitData.Fields.Item("TAX_CODE").Value = CInt(9)
oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(dPaymentValue)
oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(0)
oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)
oSplitData.Fields.Item("DETAILS").Value = CStr(oTransactionPost.Header("DETAILS").Value)

' Update the TransactionPost object
bPosted = oTransactionPost.Update

If bPosted Then

' Read HeaderData for Payment
oHeaderData.Read(oTransactionPost.PostingNumber)

' Store Split Number for Payment
 lPaymentSplit = oHeaderData.Fields.Item("FIRST_SPLIT").Value

' Allocate Payment Against Invoice
bAllocated = oTransactionPost.AllocatePayment(CLng(lInvoiceSplit), CLng(lPaymentSplit), CDbl(dPaymentValue), CDate(dPostDate))

If bAllocated Then

 MessageBox.Show("Purchase Payment posted, and allocated successfully.")

End If

' Post PC transaction for CIS Tax Withheld
' Destroy and Create a new instance of TransactionPost for the Purchase Credit (CIS Tax)
 oTransactionPost = Nothing
oTransactionPost = oWS.CreateObject("TransactionPost")

' Fill in the Header fields
 oTransactionPost.Header("ACCOUNT_REF").Value = CStr(oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value = CDate(dPostDate)
oTransactionPost.Header("POSTED_DATE").Value = CDate(dPostDate)
oTransactionPost.Header("TYPE").Value = CByte(SageDataObject300.TransType.sdoPC)
oTransactionPost.Header("INV_REF").Value = CStr("CIS Tax")

' Destroy Existing Split Object
 oSplitData = Nothing

' Create a split item by adding an empty split to the Items
' collection of the TransactionPost Object.
 oSplitData = oTransactionPost.Items.Add()

' Fill in the Split fields - note a Purchase Payment only has one split
 oSplitData.Fields.Item("TYPE").Valu e = CByte(SageDataObject300.TransType.sdoPC)

' Set Nominal Business Object to CIS Control Reference Nominal Code for CIS
oNominalCode = oCISSetting.CISControlReference
 oSplitData.Fields.Item("NOMINAL_CODE").V alue = oNominalCode.Reference

oSplitData.Fields.Item("TAX_CODE").Value = CInt(9)

' Subtract Tax amount from dPaymentValue
 oSplitData.Fields.Item("NET_AMOUNT").Value = CDbl(dCISTaxValue)
oSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl(0)
oSplitData.Fields.Item("DATE").Value = CDate(oTransactionPost.Header("DATE").Value)
oSplitData.Fields.Item("DETAILS").Value = CStr(oTransactionPost.Header("DETAILS").Value)

' Update the TransactionPost object
 bPosted = oTransactionPost.Update

If bPosted Then

' Read HeaderData for Payment
oHeaderData.Read(oTransactionPost.PostingNumber)

' Store Split Number for Payment
 lPaymentSplit = oHeaderData.Fields.Item("FIRST_SPLIT").Value

' Allocate Payment Against Invoice
 bAllocated = oTransactionPost.AllocatePayment(CLng(lInvoiceSplit), CLng(lPaymentSplit), CDbl(dCISTaxValue), CDate(dPostDate))

If bAllocated Then

 MessageBox.Show("Purchase Credit (CIS Tax) posted, and allocated successfully.")

End If

End If

End If

End If

End If

End If

' Disconnect
oWS.Disconnect()

End If

' Destroy Objects
 oPurchaseRecord = Nothing
oHeaderData = Nothing
oSplitData = Nothing
oTransactionPost = Nothing
oNominalCode = Nothing
oCISSubcontractor = Nothing
oCISTaxHistory = Nothing
oCISTaxHistorys = Nothing
oCISSetting = Nothing
oSDO = Nothing
oWS = Nothing

Exit Sub

C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace cSharpDefaultL50
{
    public partial class Form1 : Form
    {
        //Declare Variables
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        String szDataPath;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code
                userDefinedMethod();
            }
            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void userDefinedMethod()
        {
            // declare required objects
            SageDataObject300.CISSubcontrator oCISSubContractor;
            SageDataObject300.CisSubcontractorTaxHistorys oCISTaxHistorys;
            SageDataObject300.CISSetting oCISSetting;
            SageDataObject300.PurchaseRecord oPurchaseRecord;
            SageDataObject300.Nominal oNominalCode;
            SageDataObject300.SplitData oSplitData;
            SageDataObject300.HeaderData oHeaderData;
            SageDataObject300.TransactionPost oTransactionPost;
            Boolean bRecordFound = false;
            Boolean bTransactionFound = false;
            Boolean bPosted, bAllocated;
            Double dPaymentValue = 0.0;
            Double dCISTaxValue = 0.0;
            Double dTaxTreatment = 0.0;
            Int32 lPaymentSplit, lInvoiceSplit;
            DateTime dPostDate = (DateTime)DateTime.Now;

            // Create an instance of the PurchaseRecord object
            oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");

            // Initialise Index Field with value to search
            SDOHelper.Write(oPurchaseRecord, "ACCOUNT_REF", (String)"CON001");

            // Perform Find for an exact match
            bRecordFound = oPurchaseRecord.Find(false);

            if (bRecordFound)
            {
                // Link to Headers
                oHeaderData = (SageDataObject300.HeaderData)oPurchaseRecord.Link;

                // Move to the first Header on the Purchase Ledger account
                oHeaderData.MoveFirst();

                // Attempt to find an Invoice.
                // Loop through the Headers until the Invoice Reference is found
                do
                {
                    if ((String)SDOHelper.Read(oHeaderData, "INV_REF") == (String)"INV0001")
                    {
                        // Set the invoice transaction found flag
                        bTransactionFound = true;

                        // Exit the loop
                        break;
                    }
                }
                while (!(!oHeaderData.MoveNext()));

                if (bTransactionFound)
                {
                    // Link to Splits
                    oSplitData = (SageDataObject300.SplitData)oHeaderData.Link;

                    // Move to first Split
                    oSplitData.MoveFirst();

                    // Calculate Purchase Payment Value
                    dPaymentValue = (double)SDOHelper.Read(oSplitData, "NET_AMOUNT") +
                                    (double)SDOHelper.Read(oSplitData, "TAX_AMOUNT") -
                                    (double)SDOHelper.Read(oSplitData, "AMOUNT_PAID");

                    // Store Split Number for Invoice
                    lInvoiceSplit = oSplitData.RecordNumber;

                    if (dPaymentValue > 0)
                    {
                        // Create and Load CIS Business Objects
                        Object subContractor = (String)SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF");
                        oCISSubContractor = (SageDataObject300.CISSubcontrator)oWS.CreateCISSubcontractor();
                        oCISSubContractor.Load(ref subContractor);

                        oCISTaxHistorys = (SageDataObject300.CisSubcontractorTaxHistorys)oWS.CreateCISSubcontractorTaxHistorys();
                        oCISTaxHistorys = (SageDataObject300.CisSubcontractorTaxHistorys)oCISSubContractor.TaxHistorys;

                        oCISSetting = (SageDataObject300.CISSetting)oWS.CreateCISSetting();
                        oCISSetting.Load();

                        foreach (SageDataObject300.CisSubcontractorTaxHistory oCISTaxHistory in oCISTaxHistorys)
                        {
                            // Find correct tax history for posted date
                            if ((dPostDate > oCISTaxHistory.StartDate) & (dPostDate < oCISTaxHistory.EndDate))
                            {
                                switch (oCISTaxHistory.TaxTreatment)
                                {
                                    case SageDataObject300.CISTaxTreatment.sdoGross:
                                        dTaxTreatment = 0;
                                        break;

                                    case SageDataObject300.CISTaxTreatment.sdoHigherRate:
                                        dTaxTreatment = (oCISSetting.HigherRate) / 100;
                                        break;

                                    case SageDataObject300.CISTaxTreatment.sdoStandardRate:
                                        dTaxTreatment = (oCISSetting.StandardRate) / 100;
                                        break;
                                }

                                // Calculate Payment and CIS Tax Value
                                dCISTaxValue = (Double)Math.Round((Decimal)SDOHelper.Read(oSplitData, "NET_AMOUNT") * dTaxTreatment, (int)2, MidpointRounding.AwayFromZero);
                                dPaymentValue = dPaymentValue - dCISTaxValue;

                                // We have our values so exit loop
                                break;
                            }
                        }

                        // Create an instance of TransactionPost for the Purchase Payment
                        oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

                        // Fill in the Header fields
                        SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"));
                        SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)dPostDate);
                        SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)dPostDate);
                        SDOHelper.Write(oTransactionPost.Header, "TYPE", (Byte)SageDataObject300.TransType.sdoPP);
                        SDOHelper.Write(oTransactionPost.Header, "INV_REF", (String)"BACS");
                        SDOHelper.Write(oTransactionPost.Header, "BANK_CODE", (String)"1200");

                        // Destroy Existing Split Object
                        oSplitData = null;

                        // Create a split item by adding an empty split to the items
                        //   collection of the TransactionPost object
                        oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                        //Fill in the split fields - note a purchase payment only has one split
                        SDOHelper.Write(oSplitData, "TYPE", (Byte)SageDataObject300.TransType.sdoPP);
                        SDOHelper.Write(oSplitData, "NOMINAL_CODE", (String)"1200");
                        SDOHelper.Write(oSplitData, "TAX_CODE", (Int32)9);
                        SDOHelper.Write(oSplitData, "NET_AMOUNT", (Double)dPaymentValue);
                        SDOHelper.Write(oSplitData, "TAX_AMOUNT", (Double)0);
                        SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));
                        SDOHelper.Write(oSplitData, "DETAILS", (String)SDOHelper.Read(oTransactionPost.Header, "DETAILS"));

                        // Update the TransactionPost object
                        bPosted = oTransactionPost.Update();
                        if (bPosted)
                        {

                            // Read HeaderData for Payment
                            oHeaderData.Read(oTransactionPost.PostingNumber);

                            // Store Split Number for Payment
                            lPaymentSplit = (Int32)SDOHelper.Read(oHeaderData, "FIRST_SPLIT");

                            // Allocate Payment Against Invoice
                            bAllocated = oTransactionPost.AllocatePayment((Int32)lInvoiceSplit, (Int32)lPaymentSplit, (Double)dPaymentValue, (DateTime)dPostDate);

                            if (bAllocated)
                            {

                                MessageBox.Show("Purchase Payment posted, and allocated successfully.");

                            }

                            // Post PC transaction for CIS Tax Withheld
                            // Destroy and Create a new instance of TransactionPost for the Purchase Credit (CIS Tax)
                            oTransactionPost = null;
                            oTransactionPost = (SageDataObject300.TransactionPost)oWS.CreateObject("TransactionPost");

                            // Fill in the Header fields
                            SDOHelper.Write(oTransactionPost.Header, "ACCOUNT_REF", (String)SDOHelper.Read(oPurchaseRecord, "ACCOUNT_REF"));
                            SDOHelper.Write(oTransactionPost.Header, "DATE", (DateTime)dPostDate);
                            SDOHelper.Write(oTransactionPost.Header, "POSTED_DATE", (DateTime)dPostDate);
                            SDOHelper.Write(oTransactionPost.Header, "TYPE", (byte)SageDataObject300.TransType.sdoPC);
                            SDOHelper.Write(oTransactionPost.Header, "DETAILS", (string)"Purchase Credit - CIS Tax");
                            SDOHelper.Write(oTransactionPost.Header, "INV_REF", (string)"CIS Tax");

                            // Destroy Existing Split Object
                            oSplitData = null;

                            // Create a split item by adding an empty split to the Items
                            //   collection of the TransactionPost Object.
                            oSplitData = (SageDataObject300.SplitData)SDOHelper.Add(oTransactionPost.Items);

                            // Fill in the Split fields - note a Purchase Payment only has one split
                            SDOHelper.Write(oSplitData,"TYPE", (byte)SageDataObject300.TransType.sdoPC);

                            // Set Nominal Business Object to CIS Control Reference Nominal Code for CIS
                            oNominalCode = (SageDataObject300.Nominal)oCISSetting.CISControlReference;
                            SDOHelper.Write(oSplitData, "NOMINAL_CODE", oNominalCode.Reference);
                            SDOHelper.Write(oSplitData, "TAX_CODE", (Int32)9);

                            // Subtract Tax amount from dPaymentValue
                            SDOHelper.Write(oSplitData, "NET_AMOUNT", (double)dCISTaxValue);
                            SDOHelper.Write(oSplitData, "TAX_AMOUNT", (double)0);
                            SDOHelper.Write(oSplitData, "DATE", (DateTime)SDOHelper.Read(oTransactionPost.Header, "DATE"));
                            SDOHelper.Write(oSplitData, "DETAILS", (String)SDOHelper.Read(oTransactionPost.Header, "DETAILS"));

                            // Update the TransactionPost object
                            bPosted = oTransactionPost.Update();

                            if (bPosted)
                            {

                                // Read HeaderData for Payment
                                oHeaderData.Read(oTransactionPost.PostingNumber);

                                // Store Split Number for Payment
                                lPaymentSplit = (Int32)SDOHelper.Read(oHeaderData, "FIRST_SPLIT");

                                // Allocate Payment Against Invoice
                                bAllocated = oTransactionPost.AllocatePayment((Int32)lInvoiceSplit, (Int32)lPaymentSplit, (double)dCISTaxValue, (DateTime)dPostDate);

                                if (bAllocated)
                                {
                                    MessageBox.Show("Purchase Credit (CIS Tax) posted, and allocated successfully.");
                                }
                            }
                        }
                    }
                }
            }
        }// userDefinedMethod
    }// class
}// namespace


Sage 50 Accounts - Example - How To Use CIS Collection Objects

Example - How To Use CIS Collection Objects

The example code below demonstrates how to use the CIS Collection objects.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

Note: This example relies on a ListView ('listview1') being available on the form

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oCISSubContractor As SageDataObject300.CISSubcontrator
Dim oCISSubContractors As SageDataObject300.CisSubcontractors
Dim oCISTaxHistory As SageDataObject300.CisSubcontractorTaxHistory
Dim oCISTaxHistorys As SageDataObject300.CisSubcontractorTaxHistorys
Dim oSupplier As SageDataObject300.Supplier
Dim oPurchaseRecord As SageDataObject300.PurchaseRecord
Dim lvItem As ListViewItem

' Declare Variables
Dim szDataPath As String

' Create the SDOEngine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

' Try to Connect - Will Throw an Exception if it Fails
If oWS.Connect(szDataPath, "", "", "Example") Then

 ' Create CIS Collection Object
oCISSubContractors = oWS.CreateCISSubcontractors
oSupplier = oWS.CreateSupplier
oPurchaseRecord = oWS.CreateObject("PurchaseRecord")

' Add the columns to the ListView
Me.ListView.Columns.Clear()
Me.ListView.Columns.Add("Supp Ref", 60, HorizontalAlignment.Left)
Me.ListView.Columns.Add("Supplier Name", 100, HorizontalAlignment.Left)
Me.ListView.Columns.Add("Tax History Start", 80, HorizontalAlignment.Left)
Me.ListView.Columns.Add("Tax History End", 80, HorizontalAlignment.Lef t)
Me.ListView.Columns.Add("Tax Treat", 80, HorizontalAlignment.Left)
Me.ListView.Items.Clear()

' If there is more than 1 transaction
If oCISSubContractors.Count > 0 Then

 ' Iterate through CIS Subcontractor using For Each Loop
For Each oCISSubContractor In oCISSubContractors

' Set Supplier Business Object to CISSubcontractor Supplier property
 oSupplier = oCISSubContractor.Supplier
oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value = oSupplier.Reference
oPurchaseRecord.Find(False)
oCISTaxHistorys = oCISSubContractor.TaxHistorys

' Check if Tax History Exists for this subcontractor
If oCISTaxHistorys.Count > 0 Then

For Each oCISTaxHistory In oCISTaxHistorys

lvItem = New ListViewItem
lvItem.Text = oSupplier.Reference
lvItem.SubItems.Add(oPurchaseRecord.Fields.Item("NAME").Value)
lvItem.SubItems.Add(oCISTaxHistory.StartDate)
lvItem.SubItems.Add(oCISTaxHistory.EndDate)
lvItem.SubItems.Add(oCISTaxHistory.TaxTreatment)
Me.ListView.Items.Add(lvItem)

Next

End If

Next

End If

' Disconnect
oWS.Disconnect()

End If

End If

' Destroy Objects
oSupplier = Nothing
oPurchaseRecord = Nothing
oSDO = Nothing
oWS = Nothing
oCISSubContractor = Nothing
oCISSubContractors = Nothing
oCISTaxHistory = Nothing
oCISTaxHistorys = Nothing
lvItem = Nothing

 Exit Sub
C#.NET [image] Copy C# Code

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

namespace cSharpDefaultL50

{

    public partial class Form1 : Form

    {

        //Declare Variables

        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

        SageDataObject300.WorkSpace oWS;

        String szDataPath;

        public Form1()

        {

            InitializeComponent();

        }

        private void Form1_Load(object sender, EventArgs e)

        {

            //Instantiate WorkSpace

            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog

            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails

            try

            {

                //Leaving the username and password blank generates a login dialog

                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                // run user defined code

                userDefinedMethod();

            }

            catch (Exception ex)

            {

                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

            }

        }

        private void userDefinedMethod()

        {

            // Declare Objects

            SageDataObject300.CisSubcontractors oCISSubContractors;

            SageDataObject300.CisSubcontractorTaxHistorys oCISTaxHistorys;

            SageDataObject300.Supplier oSupplier;

            SageDataObject300.PurchaseRecord oPurchaseRecord;

            ListViewItem lvItem;

            // Create CIS Collection Object

            oCISSubContractors = (SageDataObject300.CisSubcontractors)oWS.CreateCISSubcontractors();

            oSupplier = (SageDataObject300.Supplier)oWS.CreateSupplier();

            oPurchaseRecord = (SageDataObject300.PurchaseRecord)oWS.CreateObject("PurchaseRecord");

            // Add the columns to the ListView

            this.listView.Columns.Clear();

            this.listView.Columns.Add("Supp Ref", 60, HorizontalAlignment.Left);

            this.listView.Columns.Add("Supplier Name", 100, HorizontalAlignment.Left);

            this.listView.Columns.Add("Tax History Start", 80, HorizontalAlignment.Left);

            this.listView.Columns.Add("Tax History End", 80, HorizontalAlignment.Left);

            this.listView.Columns.Add("Tax Treat", 80, HorizontalAlignment.Left);

            this.listView.Items.Clear();

            // If there is more than 1 transaction

            if (oCISSubContractors.Count > 0)

            {

                // Iterate through CIS Subcontractor using For Each Loop

                foreach (SageDataObject300.CISSubcontrator oCISSubContractor in oCISSubContractors)

                {

                    // Set Supplier Business Object to CISSubcontractor Supplier property

                    oSupplier = (SageDataObject300.Supplier)oCISSubContractor.Supplier;

                    SDOHelper.Write(oPurchaseRecord, "ACCOUNT_REF", (String)oSupplier.Reference);

                    oPurchaseRecord.Find(false);

                    oCISTaxHistorys = (SageDataObject300.CisSubcontractorTaxHistorys)oCISSubContractor.TaxHistorys;

                    // Check if Tax History Exists for this subcontractor

                    if (oCISTaxHistorys.Count > 0)

                    {

                        foreach (SageDataObject300.CisSubcontractorTaxHistory oCISTaxHistory in oCISTaxHistorys)

                        {

                            lvItem = new ListViewItem();

                            lvItem.Text = oSupplier.Reference;

                            lvItem.SubItems.Add(SDOHelper.Read(oPurchaseRecord, "NAME").ToString());

                            lvItem.SubItems.Add(oCISTaxHistory.StartDate.ToString());

                            lvItem.SubItems.Add(oCISTaxHistory.EndDate.ToString());

                            lvItem.SubItems.Add(oCISTaxHistory.TaxTreatment.ToString());

                            this.listView.Items.Add(lvItem);

                        }

                    }

                }

            }

        }// userDefinedMethod

    }// class

}// namespace


Examples - Microsoft Office Integration

These examples demonstrate how you can use the SDO with the applications from Microsoft's Office suite. The examples are as follows:

  • Excel 2000

Creating a Profit and Loss Report

  • Outlook 2000

Creating an email with details taken from a Customer's Account

  • Word 2000

Creating a letter with details taken from a Customer's Account


Example - Creating a Letter in Microsoft Word 2000

Description

The example code below demonstrates how to create a letter in Microsoft Word 2000 based on information from a Customer record. The code is written in Visual Basic v6.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

The code also includes a generic error handler. Clearly, you would respond differently depending on the actual exception thrown.

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oSalesRecord As SageDataObject300.SalesRecord
  Dim oSetupData As SageDataObject300.SetupData
  Dim oWord As Word.Application
  Dim oDocument As Word.Document

  ' Declare Variables
  Dim szDataPath As String

  ' Create SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company.  The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then

    ' Try to Connect - Will throw an exception if it fails
    If oWS.Connect(szDataPath, "", "", "Example") Then

      ' Create Instances of the Objects
      Set oSalesRecord = oWS.CreateObject("SalesRecord")
      Set oSetupData = oWS.CreateObject("SetupData")

      Set oWord = CreateObject("Word.Application")
      oWord.Visible = True
      oWord.Application.WindowState = wdWindowStateMaximize
      Set oDocument = oWord.Documents.Add

      oSalesRecord.MoveFirst
      oWord.Selection.TypeText Text:=oSalesRecord.Fields.Item("NAME").Value
      oWord.Selection.TypeParagraph

      If oSalesRecord.Fields.Item("ADDRESS_1").Value <> "" Then

        oWord.Selection.TypeText Text:=oSalesRecord.Fields.Item("ADDRESS_1").Value
        oWord.Selection.TypeParagraph

      End If

      If oSalesRecord.Fields.Item("ADDRESS_2").Value <> "" Then

        oWord.Selection.TypeText Text:=oSalesRecord.Fields.Item("ADDRESS_2").Value
        oWord.Selection.TypeParagraph

      End If

      If oSalesRecord.Fields.Item("ADDRESS_3").Value <> "" Then

        oWord.Selection.TypeText Text:=oSalesRecord.Fields.Item("ADDRESS_3").Value
        oWord.Selection.TypeParagraph

      End If

      If oSalesRecord.Fields.Item("ADDRESS_4").Value <> "" Then

        oWord.Selection.TypeText Text:=oSalesRecord.Fields.Item("ADDRESS_4").Value
        oWord.Selection.TypeParagraph

      End If

      If oSalesRecord.Fields.Item("ADDRESS_5").Value <> "" Then

        oWord.Selection.TypeText Text:=oSalesRecord.Fields.Item("ADDRESS_5").Value
        oWord.Selection.TypeParagraph

      End If

      If oSalesRecord.Fields.Item("CONTACT_NAME").Value <> "" Then

        oWord.Selection.TypeParagraph
        oWord.Selection.TypeParagraph
        oWord.Selection.TypeText Text = "Dear " & oSalesRecord.Fields.Item("CONTACT_NAME").Value
        oWord.Selection.TypeParagraph
        oWord.Selection.TypeParagraph

      Else

        oWord.Selection.TypeParagraph
        oWord.Selection.TypeParagraph
        oWord.Selection.TypeText Text:="Dear Sir / Madam"
        oWord.Selection.TypeParagraph
        oWord.Selection.TypeParagraph

      End If

      oWord.Selection.TypeParagraph
      oWord.Selection.TypeParagraph
      oWord.Selection.TypeText Text:=CDate(Date)
      oWord.Selection.TypeParagraph
      oWord.Selection.TypeParagraph

      oWord.Selection.TypeText Text:="Our business address has recently changed, and we would like to take this opportunity to inform you of our new location."
      oWord.Selection.TypeParagraph
      oWord.Selection.TypeParagraph

      oSetupData.Read 1
      If oSetupData.Fields.Item("ADDRESS_1").Value <> "" Then

        oWord.Selection.TypeText Text:=oSetupData.Fields.Item("ADDRESS_1").Value
        oWord.Selection.TypeParagraph

      End If

      If oSetupData.Fields.Item("ADDRESS_2").Value <> "" Then

        oWord.Selection.TypeText Text:=oSetupData.Fields.Item("ADDRESS_2").Value
        oWord.Selection.TypeParagraph

      End If

      If oSetupData.Fields.Item("ADDRESS_3").Value <> "" Then

        oWord.Selection.TypeText Text:=oSetupData.Fields.Item("ADDRESS_3").Value
        oWord.Selection.TypeParagraph

      End If

      If oSetupData.Fields.Item("ADDRESS_4").Value <> "" Then

        oWord.Selection.TypeText Text:=oSetupData.Fields.Item("ADDRESS_4").Value
        oWord.Selection.TypeParagraph

      End If

      If oSetupData.Fields.Item("ADDRESS_5").Value <> "" Then

        oWord.Selection.TypeText Text:=oSetupData.Fields.Item("ADDRESS_5").Value
        oWord.Selection.TypeParagraph

      End If

      oWord.Selection.TypeParagraph
      oWord.Selection.TypeText Text:="Your co-operation is appreciated."
      oWord.Selection.TypeParagraph
      oWord.Selection.TypeParagraph
      oWord.Selection.TypeParagraph
      oWord.Selection.TypeParagraph
      oWord.Selection.TypeText Text:="Paul Smith"

    End If

    ' Disconnect
    oWS.Disconnect

  End If

  ' Destroy Objects
  oDocument = Nothing
  oWord = Nothing
  oSalesRecord = Nothing
  oSetupData = Nothing
  oWS = Nothing
  oSDO = Nothing

  Exit Sub

 ' Error Handling Code
Error_Handler:

  MsgBox "The SDO generated the following error: " & oSDO.LastError.Text, vbOKOnly, "SDO Examples"


Example - Creating a Profit and Loss Report in Excel 2000

Description

The example code below demonstrates how to create a Profit and Loss report in Microsoft Excel 2000 based on information from the Nominal Ledger. The code is written in Visual Basic v6.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

The code also includes a generic error handler. Clearly, you would respond differently depending on the actual exception thrown.

Note: This example relies on a combobox control (lstMonths) showing a list of months, being available on a form.

  ' Error Handler
On Error GoTo Error_Handler

' Declare Sage Objects
Dim oSDO  As
  SageDataObject300.SDOEngine
Dim oWS  As
  SageDataObject300.WorkSpace
Dim oChartData  As
  SageDataObject300.ChartData
Dim oCategory  As
  SageDataObject300.Category
Dim oNominalRecord  As
  SageDataObject300.NominalRecord
Dim oSetupData  As
  SageDataObject300.SetupData

' Declare Microsoft Excel Objects
Dim xlApp  As Excel.Application
Dim xlBook  As Excel.Workbook
Dim xlSheet  As Excel.Worksheet

' Declare Variables
Dim szDataPath  As String
Dim iCategoryCounter  As Integer
Dim iXLRow  As Integer
Dim iXLColumn  As Integer
Dim dCategoryBalance  As Double
Dim dSalesCategoryTotal  As Double
Dim dPurchaseCategoryTotal  As Double
Dim dDirectExpenseCategoryTotal  As Double
Dim dOverheadCategoryTotal As Double
Dim sSelectedMonth  As String
Dim iSelectedMonth  As Integer
Dim iFirstMonthOfYear  As Integer
Dim  iMonthToRun  As Integer
Dim sMonthToRead  As String

' Create Instances of Excel Objects
Set xlApp =  New Excel.Application
Set xlBook = xlApp.Workbooks.Add
Set xlSheet = xlBook.Worksheets.Add

' Create SDO Engine Object
Set oSDO =  New
  SageDataObject300.SDOEngine

' Create SDO Workspace
Set oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> ""  Then

' Try to Connect - Will throw an
  exception if it fails
If oWS.Connect(szDataPath, "", "", "Example")
   Then

' Create Instances of Sage Objects
Set oChartData = oWS.CreateObject("ChartData")
Set oCategory = oWS.CreateObject("Category")
Set oNominalRecord = oWS.CreateObject("NominalRecord")
Set oSetupData = oWS.CreateObject("SetupData")

' Calculate Month
oSetupData.Read 1

' Get Financial Year Start date.
iFirstMonthOfYear =
  oSetupData.Fields.Item("FINYEAR_MONTH").Value

' Get selected month from user selection and add 1 as the list is zero based.
iSelectedMonth = lstMonth.ListIndex + 1

iMonthToRun = iSelectedMonth +
  iFirstMonthOfYear

If iMonthToRun > 12 Then

iMonthToRun = iMonthToRun - 12

End If

sMonthToRead = "BALANCE_MTH" &
  iMonthToRun

'Populate sSelectedMonth with the name of the selected month
Select Case iSelectedMonth

Case  1
sSelectedMonth = "January"

Case 2
sSelectedMonth = "February"

Case 3
sSelectedMonth = "March"

Case 4
sSelectedMonth = "April"

Case 5
sSelectedMonth = "May"

Case 6
sSelectedMonth = "June"

Case 7
sSelectedMonth = "July"

Case 8
sSelectedMonth = "August"

Case 9
sSelectedMonth = "September"

Case 10
sSelectedMonth = "October"

Case 11
sSelectedMonth = "November"

Case 12
sSelectedMonth = "December"

End Select

'Add a header to the P&L
iXLRow = 1
oChartData.Read 1
xlSheet.Cells(iXLRow, 1).Value = "Profit & Loss for " & sSelectedMonth
xlSheet.Cells(iXLRow, 1).Font.Bold = True
xlSheet.Cells(iXLRow, 1).Font.Size = 12
xlSheet.Cells(iXLRow, 1).Font.Underline = xlUnderlineStyleSingle

' Add Sales Categories *************************************************************************

'Get the category title for Sales
iXLRow = iXLRow + 2
xlSheet.Cells(iXLRow, 1).Value = oChartData.Fields.Item("NAME_SALES").Value
xlSheet.Cells(iXLRow, 1).Font.Bold = True
xlSheet.Cells(iXLRow, 1).Font.Underline = xlUnderlineStyleSingle

' Read Sales Headings
iXLRow = iXLRow + 2

' Loop through the first 80 categories - first 80 categories are for Sales Ledger
For iCategoryCounter = 0
   To 80

oCategory.Read(iCategoryCounter)
If oCategory.Fields.Item("NAME").Value <> ""
   Then

xlSheet.Cells(iXLRow, 1).Value = oCategory.Fields.Item("NAME").Value
oNominalRecord.MoveFirst

Do

If Int(oNominalRecord.Fields.Item("ACCOUNT_REF").Value) >= oCategory.Fields.Item("LOW").Value
   And _
Int(oNominalRecord.Fields.Item("ACCOUNT_REF").Value) <=
  oCategory.Fields.Item("HIGH").Value  Then

dCategoryBalance = dCategoryBalance + (0 - 1 * oNominalRecord.Fields.Item(sMonthToRead).Value)
dSalesCategoryTotal = dSalesCategoryTotal + (0 - 1 * oNominalRecord.Fields.Item(sMonthToRead).Value)
xlSheet.Cells(iXLRow, 4).Value = dCategoryBalance

End If

Loop Until oNominalRecord.MoveNext = False

dCategoryBalance = 0
iXLRow = iXLRow + 1

End If

Next iCategoryCounter

iXLRow = iXLRow + 1
xlSheet.Cells(iXLRow, 1).Value = "TOTAL SALES"
xlSheet.Cells(iXLRow, 4).Value = dSalesCategoryTotal
xlSheet.Cells(iXLRow, 4).Font.Underline = True
xlSheet.Cells(iXLRow, 1).Font.Bold = True
xlSheet.Cells(iXLRow, 4).Font.Bold = True

dPurchaseCategoryTotal = 0
xlSheet.Columns("A:A").ColumnWidth = 36
xlSheet.Columns("D:D").NumberFormat = "#,##0.00"

' Add Purchase Categories *************************************************************************
iXLRow = iXLRow + 2
xlSheet.Cells(iXLRow, 1).Value = oChartData.Fields.Item("NAME_PURCHASE").Value
xlSheet.Cells(iXLRow, 1).Font.Bold = True
xlSheet.Cells(iXLRow, 1).Font.Underline = xlUnderlineStyleSingle

' Read Purchase Headings
iXLRow = iXLRow + 2

For iCategoryCounter = 81
   To 160

oCategory.Read iCategoryCounter
If oCategory.Fields.Item("NAME").Value <> ""
   Then

xlSheet.Cells(iXLRow, 1).Value = oCategory.Fields.Item("NAME").Value
oNominalRecord.MoveFirst

Do

If Int(oNominalRecord.Fields.Item("ACCOUNT_REF").Value) >= Int(oCategory.Fields.Item("LOW").Value)
   And _
Int(oNominalRecord.Fields.Item("ACCOUNT_REF").Value) <= Int(oCategory.Fields.Item("HIGH").Value)
   Then

dCategoryBalance = dCategoryBalance + oNominalRecord.Fields.Item(sMonthToRead).Value
dPurchaseCategoryTotal = dPurchaseCategoryTotal + oNominalRecord.Fields.Item(sMonthToRead).Value
xlSheet.Cells(iXLRow, 4).Value = dCategoryBalance

End If

Loop Until oNominalRecord.MoveNext = False

dCategoryBalance = 0
iXLRow = iXLRow + 1

End If

Next  iCategoryCounter

iXLRow = iXLRow + 1
xlSheet.Cells(iXLRow, 1).Value = "TOTAL PURCHASES"
xlSheet.Cells(iXLRow, 4).Value = dPurchaseCategoryTotal
xlSheet.Cells(iXLRow, 4).Font.Underline = True
xlSheet.Cells(iXLRow, 1).Font.Bold = True
xlSheet.Cells(iXLRow, 4).Font.Bold = True
xlSheet.Columns("A:A").ColumnWidth = 36
xlSheet.Columns("D:D").NumberFormat = "#,##0.00"

' Calculate Gross Profit
iXLRow = iXLRow + 3
xlSheet.Cells(iXLRow, 1).Value = "GROSS PROFIT/LOSS"
xlSheet.Cells(iXLRow, 1).Font.Underline = True
xlSheet.Cells(iXLRow, 1).Font.Bold = True

xlSheet.Cells(iXLRow, 4).Value = dSalesCategoryTotal - dPurchaseCategoryTotal
xlSheet.Cells(iXLRow, 4).Font.Underline = True
xlSheet.Cells(iXLRow, 4).Font.Bold = True

' Add Direct Expenses Categories *************************************************************************

iXLRow = iXLRow + 2
xlSheet.Cells(iXLRow, 1).Value = oChartData.Fields.Item("NAME_EXPENSE").Value
xlSheet.Cells(iXLRow, 1).Font.Bold = True
xlSheet.Cells(iXLRow, 1).Font.Underline = xlUnderlineStyleSingle

' Read Direct Expense Headings
iXLRow = iXLRow + 2

For iCategoryCounter = 161
   To 240

oCategory.Read iCategoryCounter
If oCategory.Fields.Item("NAME").Value <> ""
   Then

xlSheet.Cells(iXLRow, 1).Value = oCategory.Fields.Item("NAME").Value
oNominalRecord.MoveFirst

Do

If Int(oNominalRecord.Fields.Item("ACCOUNT_REF").Value) >= Int(oCategory.Fields.Item("LOW").Value)
   And _
Int(oNominalRecord.Fields.Item("ACCOUNT_REF").Value) <= Int(oCategory.Fields.Item("HIGH").Value) Then

dCategoryBalance = dCategoryBalance + oNominalRecord.Fields.Item(sMonthToRead).Value
dDirectExpenseCategoryTotal = dDirectExpenseCategoryTotal + oNominalRecord.Fields.Item(sMonthToRead).Value
xlSheet.Cells(iXLRow, 4).Value = dCategoryBalance

End If

Loop Until oNominalRecord.MoveNext = False

dCategoryBalance = 0
iXLRow = iXLRow + 1

End If

Next iCategoryCounter

iXLRow = iXLRow + 1
xlSheet.Cells(iXLRow, 1).Value = "TOTAL DIRECT EXPENSES"
xlSheet.Cells(iXLRow, 4).Value = dDirectExpenseCategoryTotal
xlSheet.Cells(iXLRow, 4).Font.Underline = True
xlSheet.Cells(iXLRow, 1).Font.Bold = True
xlSheet.Cells(iXLRow, 4).Font.Bold = True

' Add Overheads Categories *************************************************************************
iXLRow = iXLRow + 2
xlSheet.Cells(iXLRow, 1).Value = oChartData.Fields.Item("NAME_OVERHEADS").Value
xlSheet.Cells(iXLRow, 1).Font.Bold = True
xlSheet.Cells(iXLRow, 1).Font.Underline = xlUnderlineStyleSingle

' Read Direct Expense Headings
iXLRow = iXLRow + 2

For iCategoryCounter = 241
   To 320

oCategory.Read iCategoryCounter
If oCategory.Fields.Item("NAME").Value <> ""
   Then

xlSheet.Cells(iXLRow, 1).Value = oCategory.Fields.Item("NAME").Value
oNominalRecord.MoveFirst

Do

If Int(oNominalRecord.Fields.Item("ACCOUNT_REF").Value) >= Int(oCategory.Fields.Item("LOW").Value)
   And _
Int(oNominalRecord.Fields.Item("ACCOUNT_REF").Value) <= Int(oCategory.Fields.Item("HIGH").Value)
   Then

dCategoryBalance =
  dCategoryBalance + oNominalRecord.Fields.Item(sMonthToRead).Value
dOverheadCategoryTotal = dOverheadCategoryTotal + oNominalRecord.Fields.Item(sMonthToRead).Value
xlSheet.Cells(iXLRow, 4).Value = dCategoryBalance

End If

Loop Until oNominalRecord.MoveNext = False

dCategoryBalance = 0
iXLRow = iXLRow + 1

End If

Next iCategoryCounter

iXLRow = iXLRow + 1
xlSheet.Cells(iXLRow, 1).Value = "TOTAL OVERHEADS"
xlSheet.Cells(iXLRow, 4).Value = dOverheadCategoryTotal
xlSheet.Cells(iXLRow, 4).Font.Underline = True
xlSheet.Cells(iXLRow, 1).Font.Bold = True
xlSheet.Cells(iXLRow, 4).Font.Bold = True
xlSheet.Columns("A:A").ColumnWidth = 36
xlSheet.Columns("D:D").ColumnWidth = 18
xlSheet.Columns("D:D").NumberFormat = "#,##0.00"

' Calculate Net Profit
iXLRow = iXLRow + 3
xlSheet.Cells(iXLRow, 1).Value = "NET PROFIT/LOSS"
xlSheet.Cells(iXLRow, 1).Font.Underline = True
xlSheet.Cells(iXLRow, 1).Font.Bold = True
xlSheet.Cells(iXLRow, 4).Value = (dSalesCategoryTotal - dPurchaseCategoryTotal) - (dDirectExpenseCategoryTotal + dOverheadCategoryTotal)
xlSheet.Cells(iXLRow, 4).Font.Underline = True
xlSheet.Cells(iXLRow, 4).Font.Bold = True

' Disconnect
oWS.Disconnect

End If

End If

' Save the Worksheet
xlSheet.SaveAs "c:\Temp.xls"
xlApp.Visible = True

' Destroy Objects
Set xlApp =  Nothing
Set xlBook =  Nothing
Set xlSheet =  Nothing
Set oChartData = Nothing
Set oCategory = Nothing
Set oNominalRecord = Nothing
Set oSetupData = Nothing
Set oWS = Nothing
Set oSDO = Nothing

Exit Sub

' Error Handling Code
Error_Handler:

MsgBox "The SDO generated the following error: " & oSDO.LastError.Text, vbOKOnly, "SDO Examples"


Example - Creating a Profit and Loss Report in Excel 2000

Example - Creating a Profit and Loss Report in Excel 2003

Description

The example code below demonstrates how to create a Profit and Loss report in Microsoft Excel 2003 based on information from the Nominal Ledger.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

The code also includes a generic error handler. Clearly, you would respond differently depending on the actual exception thrown.

Note: This example relies on a combobox control (lstMonths) showing a list of months, being available on a form.

VB.NET [image] Copy VB Code
        ' Declare Sage Objects
        Dim oSDO As SageDataObject300.SDOEngine
        Dim oWS As SageDataObject300.WorkSpace
        Dim oChartData As SageDataObject300.ChartData
        Dim oCategory As SageDataObject300.Category
        Dim oNominalRecord As SageDataObject300.NominalRecord
        Dim oSetupData As SageDataObject300.SetupData

        ' Declare Microsoft Excel Objects
        Dim xlApp As Excel.Application
        Dim xlBook As Excel.Workbook
        Dim xlSheet As Excel.Worksheet

        ' Declare Variables
        Dim szDataPath As String
        Dim iCategoryCounter As Integer
        Dim iXLRow As Integer
        Dim dCategoryBalance As Double
        Dim dSalesCategoryTotal As Double
        Dim dPurchaseCategoryTotal As Double
        Dim dDirectExpenseCategoryTotal As Double
        Dim dOverheadCategoryTotal As Double
        Dim sSelectedMonth As String
        Dim iSelectedMonth As Integer
        Dim iFirstMonthOfYear As Integer
        Dim iMonthToRun As Integer
        Dim sMonthToRead As String

        Try

            ' Create Instances of Excel Objects
            xlApp = New Excel.Application
            xlBook = xlApp.Workbooks.Add
            xlSheet = xlBook.Worksheets.Add

            ' Create SDO Engine Object
            oSDO = New SageDataObject300.SDOEngine

            ' Create SDO Workspace
            oWS = oSDO.Workspaces.Add("Example")

            ' Select Company. The SelectCompany method takes the program install
            ' folder as a parameter
            szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

            ' A U.I. for company selection is presented to the user. If a company is selected,
            ' the path will be passed to the szDataPath variable.
            ' If not, or the Cancel button is selected, the variable will be left empty.
            If szDataPath <> "" Then

                ' Try to Connect - Will throw an exception if it fails
                If oWS.Connect(szDataPath, "", "", "Example") Then

                    ' Create Instances of Sage Objects
                    oChartData = oWS.CreateObject("ChartData")
                    oCategory = oWS.CreateObject("Category")
                    oNominalRecord = oWS.CreateObject("NominalRecord")
                    oSetupData = oWS.CreateObject("SetupData")

                    ' Calculate Month
                    oSetupData.Read(1)

                    ' Get Financial Year Start date.
                    iFirstMonthOfYear = oSetupData.Fields.Item("FINYEAR_MONTH").Value

                    ' Get selected month from user selection and add 1 as the list is zero based.
                    iSelectedMonth = lstMonth.SelectedIndex + 1

                    iMonthToRun = iSelectedMonth + iFirstMonthOfYear

                    If iMonthToRun > 12 Then

                        iMonthToRun = iMonthToRun - 12

                    End If

                    sMonthToRead = "BALANCE_MTH" & iMonthToRun

                    'Populate sSelectedMonth with the name of the selected month
                    Select Case iSelectedMonth

                        Case 1
                            sSelectedMonth = "January"

                        Case 2
                            sSelectedMonth = "February"

                        Case 3
                            sSelectedMonth = "March"

                        Case 4
                            sSelectedMonth = "April"

                        Case 5
                            sSelectedMonth = "May"

                        Case 6
                            sSelectedMonth = "June"

                        Case 7
                            sSelectedMonth = "July"

                        Case 8
                            sSelectedMonth = "August"

                        Case 9
                            sSelectedMonth = "September"

                        Case 10
                            sSelectedMonth = "October"

                        Case 11
                            sSelectedMonth = "November"

                        Case 12
                            sSelectedMonth = "December"

                    End Select

                    'Add a header to the P&L
                    iXLRow = 1
                    oChartData.Read(1)
                    xlSheet.Cells(iXLRow, 1).Value = "Profit & Loss for " & sSelectedMonth
                    xlSheet.Cells(iXLRow, 1).Font.Bold = True
                    xlSheet.Cells(iXLRow, 1).Font.Size = 12
                    xlSheet.Cells(iXLRow, 1).Font.Underline = Excel.XlUnderlineStyle.xlUnderlineStyleSingle

                    ' Add Sales Categories *************************************************************************

                    'Get the category title for Sales
                    iXLRow = iXLRow + 2
                    xlSheet.Cells(iXLRow, 1).Value = oChartData.Fields.Item("NAME_SALES").Value
                    xlSheet.Cells(iXLRow, 1).Font.Bold = True
                    xlSheet.Cells(iXLRow, 1).Font.Underline = Excel.XlUnderlineStyle.xlUnderlineStyleSingle

                    ' Read Sales Headings
                    iXLRow = iXLRow + 2

                    ' Loop through the first 80 categories - first 80 categories are for Sales Ledger
                    For iCategoryCounter = 0 To 80

                        oCategory.Read(iCategoryCounter)
                        If oCategory.Fields.Item("NAME").Value <> "" Then

                            xlSheet.Cells(iXLRow, 1).Value = oCategory.Fields.Item("NAME").Value
                            oNominalRecord.MoveFirst()

                            Do

                                If Int(oNominalRecord.Fields.Item("ACCOUNT_REF").Value) >= oCategory.Fields.Item("LOW").Value And _
                                  Int(oNominalRecord.Fields.Item("ACCOUNT_REF").Value) <= oCategory.Fields.Item("HIGH").Value Then

                                    dCategoryBalance = dCategoryBalance + (0 - 1 * oNominalRecord.Fields.Item(sMonthToRead).Value)
                                    dSalesCategoryTotal = dSalesCategoryTotal + (0 - 1 * oNominalRecord.Fields.Item(sMonthToRead).Value)
                                    xlSheet.Cells(iXLRow, 4).Value = dCategoryBalance

                                End If

                            Loop Until oNominalRecord.MoveNext = False

                            dCategoryBalance = 0
                            iXLRow = iXLRow + 1

                        End If

                    Next iCategoryCounter

                    iXLRow = iXLRow + 1
                    xlSheet.Cells(iXLRow, 1).Value = "TOTAL SALES"
                    xlSheet.Cells(iXLRow, 4).Value = dSalesCategoryTotal
                    xlSheet.Cells(iXLRow, 4).Font.Underline = True
                    xlSheet.Cells(iXLRow, 1).Font.Bold = True
                    xlSheet.Cells(iXLRow, 4).Font.Bold = True

                    dPurchaseCategoryTotal = 0
                    xlSheet.Columns("A:A").ColumnWidth = 36
                    xlSheet.Columns("D:D").NumberFormat = "#,##0.00"

                    ' Add Purchase Categories *************************************************************************
                    iXLRow = iXLRow + 2
                    xlSheet.Cells(iXLRow, 1).Value = oChartData.Fields.Item("NAME_PURCHASE").Value
                    xlSheet.Cells(iXLRow, 1).Font.Bold = True
                    xlSheet.Cells(iXLRow, 1).Font.Underline = Excel.XlUnderlineStyle.xlUnderlineStyleSingle

                    ' Read Purchase Headings
                    iXLRow = iXLRow + 2

                    For iCategoryCounter = 81 To 160

                        oCategory.Read(iCategoryCounter)
                        If oCategory.Fields.Item("NAME").Value <> "" Then

                            xlSheet.Cells(iXLRow, 1).Value = oCategory.Fields.Item("NAME").Value
                            oNominalRecord.MoveFirst()

                            Do

                                If Int(oNominalRecord.Fields.Item("ACCOUNT_REF").Value) >= Int(oCategory.Fields.Item("LOW").Value) And _
                                  Int(oNominalRecord.Fields.Item("ACCOUNT_REF").Value) <= Int(oCategory.Fields.Item("HIGH").Value) Then

                                    dCategoryBalance = dCategoryBalance + oNominalRecord.Fields.Item(sMonthToRead).Value
                                    dPurchaseCategoryTotal = dPurchaseCategoryTotal + oNominalRecord.Fields.Item(sMonthToRead).Value
                                    xlSheet.Cells(iXLRow, 4).Value = dCategoryBalance

                                End If

                            Loop Until oNominalRecord.MoveNext = False

                            dCategoryBalance = 0
                            iXLRow = iXLRow + 1

                        End If

                    Next iCategoryCounter

                    iXLRow = iXLRow + 1
                    xlSheet.Cells(iXLRow, 1).Value = "TOTAL PURCHASES"
                    xlSheet.Cells(iXLRow, 4).Value = dPurchaseCategoryTotal
                    xlSheet.Cells(iXLRow, 4).Font.Underline = True
                    xlSheet.Cells(iXLRow, 1).Font.Bold = True
                    xlSheet.Cells(iXLRow, 4).Font.Bold = True
                    xlSheet.Columns("A:A").ColumnWidth = 36
                    xlSheet.Columns("D:D").NumberFormat = "#,##0.00"

                    ' Calculate Gross Profit
                    iXLRow = iXLRow + 3
                    xlSheet.Cells(iXLRow, 1).Value = "GROSS PROFIT/LOSS"
                    xlSheet.Cells(iXLRow, 1).Font.Underline = True
                    xlSheet.Cells(iXLRow, 1).Font.Bold = True

                    xlSheet.Cells(iXLRow, 4).Value = dSalesCategoryTotal - dPurchaseCategoryTotal
                    xlSheet.Cells(iXLRow, 4).Font.Underline = True
                    xlSheet.Cells(iXLRow, 4).Font.Bold = True

                    ' Add Direct Expenses Categories *************************************************************************

                    iXLRow = iXLRow + 2
                    xlSheet.Cells(iXLRow, 1).Value = oChartData.Fields.Item("NAME_EXPENSE").Value
                    xlSheet.Cells(iXLRow, 1).Font.Bold = True
                    xlSheet.Cells(iXLRow, 1).Font.Underline = Excel.XlUnderlineStyle.xlUnderlineStyleSingle

                    ' Read Direct Expense Headings
                    iXLRow = iXLRow + 2

                    For iCategoryCounter = 161 To 240

                        oCategory.Read(iCategoryCounter)
                        If oCategory.Fields.Item("NAME").Value <> "" Then

                            xlSheet.Cells(iXLRow, 1).Value = oCategory.Fields.Item("NAME").Value
                            oNominalRecord.MoveFirst()

                            Do

                                If Int(oNominalRecord.Fields.Item("ACCOUNT_REF").Value) >= Int(oCategory.Fields.Item("LOW").Value) And _
                                  Int(oNominalRecord.Fields.Item("ACCOUNT_REF").Value) <= Int(oCategory.Fields.Item("HIGH").Value) Then

                                    dCategoryBalance = dCategoryBalance + oNominalRecord.Fields.Item(sMonthToRead).Value
                                    dDirectExpenseCategoryTotal = dDirectExpenseCategoryTotal + oNominalRecord.Fields.Item(sMonthToRead).Value
                                    xlSheet.Cells(iXLRow, 4).Value = dCategoryBalance

                                End If

                            Loop Until oNominalRecord.MoveNext = False

                            dCategoryBalance = 0
                            iXLRow = iXLRow + 1

                        End If

                    Next iCategoryCounter

                    iXLRow = iXLRow + 1
                    xlSheet.Cells(iXLRow, 1).Value = "TOTAL DIRECT EXPENSES"
                    xlSheet.Cells(iXLRow, 4).Value = dDirectExpenseCategoryTotal
                    xlSheet.Cells(iXLRow, 4).Font.Underline = True
                    xlSheet.Cells(iXLRow, 1).Font.Bold = True
                    xlSheet.Cells(iXLRow, 4).Font.Bold = True

                    ' Add Overheads Categories *************************************************************************
                    iXLRow = iXLRow + 2
                    xlSheet.Cells(iXLRow, 1).Value = oChartData.Fields.Item("NAME_OVERHEADS").Value
                    xlSheet.Cells(iXLRow, 1).Font.Bold = True
                    xlSheet.Cells(iXLRow, 1).Font.Underline = Excel.XlUnderlineStyle.xlUnderlineStyleSingle

                    ' Read Direct Expense Headings
                    iXLRow = iXLRow + 2

                    For iCategoryCounter = 241 To 320

                        oCategory.Read(iCategoryCounter)
                        If oCategory.Fields.Item("NAME").Value <> "" Then

                            xlSheet.Cells(iXLRow, 1).Value = oCategory.Fields.Item("NAME").Value
                            oNominalRecord.MoveFirst()

                            Do

                                If Int(oNominalRecord.Fields.Item("ACCOUNT_REF").Value) >= Int(oCategory.Fields.Item("LOW").Value) And _
                                  Int(oNominalRecord.Fields.Item("ACCOUNT_REF").Value) <= Int(oCategory.Fields.Item("HIGH").Value) Then

                                    dCategoryBalance = dCategoryBalance + oNominalRecord.Fields.Item(sMonthToRead).Value
                                    dOverheadCategoryTotal = dOverheadCategoryTotal + oNominalRecord.Fields.Item(sMonthToRead).Value
                                    xlSheet.Cells(iXLRow, 4).Value = dCategoryBalance

                                End If

                            Loop Until oNominalRecord.MoveNext = False

                            dCategoryBalance = 0
                            iXLRow = iXLRow + 1

                        End If

                    Next iCategoryCounter

                    iXLRow = iXLRow + 1
                    xlSheet.Cells(iXLRow, 1).Value = "TOTAL OVERHEADS"
                    xlSheet.Cells(iXLRow, 4).Value = dOverheadCategoryTotal
                    xlSheet.Cells(iXLRow, 4).Font.Underline = True
                    xlSheet.Cells(iXLRow, 1).Font.Bold = True
                    xlSheet.Cells(iXLRow, 4).Font.Bold = True
                    xlSheet.Columns("A:A").ColumnWidth = 36
                    xlSheet.Columns("D:D").ColumnWidth = 18
                    xlSheet.Columns("D:D").NumberFormat = "#,##0.00"

                    ' Calculate Net Profit
                    iXLRow = iXLRow + 3
                    xlSheet.Cells(iXLRow, 1).Value = "NET PROFIT/LOSS"
                    xlSheet.Cells(iXLRow, 1).Font.Underline = True
                    xlSheet.Cells(iXLRow, 1).Font.Bold = True
                    xlSheet.Cells(iXLRow, 4).Value = (dSalesCategoryTotal - dPurchaseCategoryTotal) - (dDirectExpenseCategoryTotal + dOverheadCategoryTotal)
                    xlSheet.Cells(iXLRow, 4).Font.Underline = True
                    xlSheet.Cells(iXLRow, 4).Font.Bold = True

                    ' Disconnect
                    oWS.Disconnect()

                End If

            End If

            ' Save the Worksheet
            xlSheet.SaveAs("c:\Temp.xls")
            xlApp.Visible = True

        Catch ex As Exception
            MessageBox.Show("The SDO generated the following error: " & oSDO.LastError.Text, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try

        ' Destroy Objects
        xlApp = Nothing
        xlBook = Nothing
        xlSheet = Nothing
        oChartData = Nothing
        oCategory = Nothing
        oNominalRecord = Nothing
        oSetupData = Nothing
        oWS = Nothing
        oSDO = Nothing

C# Copy C# Code Copy C# Code

            // Declare Sage Objects
            SageDataObject300.SDOEngine oSDO;
            SageDataObject300.WorkSpace oWS;
            SageDataObject300.ChartData oChartData;
            SageDataObject300.Category oCategory;
            SageDataObject300.NominalRecord oNominalRecord;
            SageDataObject300.SetupData oSetupData;

            // Declare Microsoft Excel Objects
            Microsoft.Office.Interop.Excel.Application xlApp;
            Microsoft.Office.Interop.Excel.Workbook xlBook;
            Microsoft.Office.Interop.Excel.Worksheet xlSheet;

            // Declare variables
            string szDataPath;
            int iCategoryCounter;
            int iXLRow;
            double dCategoryBalance = 0;
            double dSalesCategoryTotal = 0;
            double dPurchaseCategoryTotal = 0;
            double dDirectExpenseCategoryTotal = 0;
            double dOverheadCategoryTotal = 0;
            string sSelectedMonth;
            int iSelectedMonth;
            int iFirstMonthOfYear;
            int iMonthToRun;
            string sMonthToRead;
            Microsoft.Office.Interop.Excel.Range Range;

            // Create instances of Excel objects
            object misValue = System.Reflection.Missing.Value;
            xlApp = new Microsoft.Office.Interop.Excel.Application();
            xlBook = xlApp.Workbooks.Add(misValue);
            xlSheet = (Microsoft.Office.Interop.Excel.Worksheet)xlBook.Worksheets.Add(misValue, misValue, misValue, misValue);

            // Create SDOEngine Object
            oSDO = new SageDataObject300.SDOEngine();
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            // Select Company. The SelectCompany method takes the program installation folder as a parameter
            szDataPath = oSDO.SelectCompany("C:\\Documents and Settings\\All Users\\Application Data\\Sage\\Accounts\\2024");

            // A U.I. for company selection is presented to the user. If a company is selected, the path
            // will be passed to the szDataPath variable.
            // If not, or the Cancel button is selected, the variable will be left empty.
            if (szDataPath != "")
            {
                // Try to connect - will throw an exception if it fails
                if (oWS.Connect(szDataPath, "", "", "Example"))
                {
                    // Create instances of Sage Objects
                    oChartData = (SageDataObject300.ChartData)oWS.CreateObject("ChartData");
                    oCategory = (SageDataObject300.Category)oWS.CreateObject("Category");
                    oNominalRecord = (SageDataObject300.NominalRecord)oWS.CreateObject("NominalRecord");
                    oSetupData = (SageDataObject300.SetupData)oWS.CreateObject("SetupData");

                    // Calculate Month
                    oSetupData.Read(1);

                    // Get Financial Year Start Date
                    iFirstMonthOfYear = int.Parse(SDOHelper.Read(oSetupData, "FINYEAR_MONTH").ToString());

                    // Get selected month from user selection and add 1 as the list is zero based.
                    iSelectedMonth = lstMonth.SelectedIndex + 1;

                    iMonthToRun = iSelectedMonth + iFirstMonthOfYear;

                    if (iMonthToRun > 12)
                    {
                        iMonthToRun = iMonthToRun - 12;
                    }

                    sMonthToRead = "BALANCE_MTH" + iMonthToRun;

                    // Populate sSelectedMonth with the name of the selected month
                    switch (iSelectedMonth)
                    {
                        case 1:
                            sSelectedMonth = "January";
                            break;
                        case 2:
                            sSelectedMonth = "February";
                            break;
                        case 3:
                            sSelectedMonth = "March";
                            break;
                        case 4:
                            sSelectedMonth = "April";
                            break;
                        case 5:
                            sSelectedMonth = "May";
                            break;
                        case 6:
                            sSelectedMonth = "June";
                            break;
                        case 7:
                            sSelectedMonth = "July";
                            break;
                        case 8:
                            sSelectedMonth = "August";
                            break;
                        case 9:
                            sSelectedMonth = "September";
                            break;
                        case 10:
                            sSelectedMonth = "October";
                            break;
                        case 11:
                            sSelectedMonth = "November";
                            break;
                        case 12:
                            sSelectedMonth = "December";
                            break;
                        default:
                            sSelectedMonth = "January";
                            break;
                    }
                    // Add a header to the P&L
                    iXLRow = 1;
                    oChartData.Read(1);
                    xlSheet.Cells[iXLRow, 1] = "Profit & Loss for " + sSelectedMonth;
                    Range = xlSheet.get_Range("A" + iXLRow.ToString(), misValue);
                    Range.Font.Bold = true;
                    Range.Font.Size = 12;
                    Range.Font.Underline = Microsoft.Office.Interop.Excel.XlUnderlineStyle.xlUnderlineStyleSingle;

                    // Add Sales Categories *************************************************************************

                    // Get the category title for Sales
                    iXLRow = iXLRow + 2;
                    xlSheet.Cells[iXLRow, 1] = (string)SDOHelper.Read(oChartData, "NAME_SALES");
                    Range = xlSheet.get_Range("A" + iXLRow.ToString(), misValue);
                    Range.Font.Bold = true;
                    Range.Font.Underline = Microsoft.Office.Interop.Excel.XlUnderlineStyle.xlUnderlineStyleSingle;

                    // Read Sales Headings
                    iXLRow = iXLRow + 2;

                    // Loop through the first 80 categories - first 80 categories are for Sales Ledger
                    for (iCategoryCounter = 0; iCategoryCounter <= 80; iCategoryCounter++)
                    {
                        oCategory.Read(iCategoryCounter);
                        if ((string)SDOHelper.Read(oCategory, "NAME") != "")
                        {
                            xlSheet.Cells[iXLRow, 1] = (string)SDOHelper.Read(oCategory, "NAME");
                            oNominalRecord.MoveFirst();

                            do
                            {
                                if (double.Parse(SDOHelper.Read(oNominalRecord, "ACCOUNT_REF").ToString()) >= double.Parse(SDOHelper.Read(oCategory, "LOW").ToString())
                                    && double.Parse(SDOHelper.Read(oNominalRecord, "ACCOUNT_REF").ToString()) <= double.Parse(SDOHelper.Read(oCategory, "HIGH").ToString()))
                                {
                                    dCategoryBalance = dCategoryBalance + (0 - 1 * double.Parse(SDOHelper.Read(oNominalRecord, sMonthToRead).ToString()));
                                    dSalesCategoryTotal = dSalesCategoryTotal + (0 - 1 * double.Parse(SDOHelper.Read(oNominalRecord, sMonthToRead).ToString()));
                                    xlSheet.Cells[iXLRow, 4] = dCategoryBalance.ToString();
                                }
                            } while (oNominalRecord.MoveNext());

                            dCategoryBalance = 0;
                            iXLRow++;
                        }
                    }

                    iXLRow++;
                    xlSheet.Cells[iXLRow, 1] = "TOTAL SALES";
                    xlSheet.Cells[iXLRow, 4] = dSalesCategoryTotal.ToString();
                    Range = xlSheet.get_Range("D" + iXLRow.ToString(), misValue);
                    Range.Font.Underline = true;
                    Range.Font.Bold = true;
                    Range = xlSheet.get_Range("A" + iXLRow.ToString(), misValue);
                    Range.Font.Bold = true;

                    dPurchaseCategoryTotal = 0;
                    Range = xlSheet.get_Range("A1", misValue);
                    Range.ColumnWidth = 36;
                    Range = xlSheet.get_Range("D4", misValue);
                    Range.NumberFormat = "#,##0.00";

                    // Add Purchase Categories *************************************************************************
                    iXLRow = iXLRow + 2;
                    xlSheet.Cells[iXLRow, 1] = SDOHelper.Read(oChartData, "NAME_PURCHASE");
                    Range = xlSheet.get_Range("A" + iXLRow.ToString(), misValue);
                    Range.Font.Bold = true;
                    Range.Font.Underline = Microsoft.Office.Interop.Excel.XlUnderlineStyle.xlUnderlineStyleSingle;

                    // Read Purchase Headings
                    iXLRow = iXLRow + 2;

                    for (iCategoryCounter = 81; iCategoryCounter <= 160; iCategoryCounter++)
                    {
                        oCategory.Read(iCategoryCounter);
                        if ((string)SDOHelper.Read(oCategory, "NAME") != "")
                        {
                            xlSheet.Cells[iXLRow, 1] = SDOHelper.Read(oCategory, "NAME");
                            oNominalRecord.MoveFirst();

                            do
                            {
                                if (double.Parse(SDOHelper.Read(oNominalRecord, "ACCOUNT_REF").ToString()) >= double.Parse(SDOHelper.Read(oCategory, "LOW").ToString())
                                    && double.Parse(SDOHelper.Read(oNominalRecord, "ACCOUNT_REF").ToString()) <= double.Parse(SDOHelper.Read(oCategory, "HIGH").ToString()))
                                {
                                    dCategoryBalance = dCategoryBalance + (double)SDOHelper.Read(oNominalRecord, sMonthToRead);
                                    dPurchaseCategoryTotal = dPurchaseCategoryTotal + (double)SDOHelper.Read(oNominalRecord, sMonthToRead);
                                    xlSheet.Cells[iXLRow, 4] = dCategoryBalance.ToString();
                                }
                            } while (oNominalRecord.MoveNext());

                            dCategoryBalance = 0;
                            iXLRow++;
                        }
                    }
                    iXLRow++;
                    xlSheet.Cells[iXLRow, 1] = "TOTAL PURCHASES";
                    xlSheet.Cells[iXLRow, 4] = dPurchaseCategoryTotal;
                    Range = xlSheet.get_Range("D" + iXLRow.ToString(), misValue);
                    Range.Font.Underline = true;
                    Range.Font.Bold = true;
                    Range.NumberFormat = "#,##0.00";
                    Range = xlSheet.get_Range("A" + iXLRow.ToString(), misValue);
                    Range.Font.Bold = true;
                    Range.ColumnWidth = 36;

                    // Calculate Gross Profit
                    iXLRow = iXLRow + 3;
                    xlSheet.Cells[iXLRow, 1] = "GROSS PROFIT/LOSS";
                    Range = xlSheet.get_Range("A" + iXLRow.ToString(), misValue);
                    Range.Font.Underline = true;
                    Range.Font.Bold = true;

                    xlSheet.Cells[iXLRow, 4] = dSalesCategoryTotal - dPurchaseCategoryTotal;
                    Range = xlSheet.get_Range("D" + iXLRow.ToString(), misValue);
                    Range.Font.Underline = true;
                    Range.Font.Bold = true;

                    // Add Direct Expenses Categories *************************************************************************

                    iXLRow = iXLRow + 2;
                    xlSheet.Cells[iXLRow, 1] = SDOHelper.Read(oChartData, "NAME_EXPENSE");
                    Range = xlSheet.get_Range("A" + iXLRow.ToString(), misValue);
                    Range.Font.Underline = true;
                    Range.Font.Bold = true;

                    // Read Direct Expense Headings
                    iXLRow = iXLRow + 2;

                    for (iCategoryCounter = 161; iCategoryCounter <= 240; iCategoryCounter++)
                    {
                        oCategory.Read(iCategoryCounter);
                        if ((string)SDOHelper.Read(oCategory, "NAME") != "")
                        {
                            xlSheet.Cells[iXLRow, 1] = (string)SDOHelper.Read(oCategory, "NAME");
                            oNominalRecord.MoveFirst();

                            do
                            {
                                if (double.Parse(SDOHelper.Read(oNominalRecord, "ACCOUNT_REF").ToString()) >= double.Parse(SDOHelper.Read(oCategory, "LOW").ToString())
                                    && double.Parse(SDOHelper.Read(oNominalRecord, "ACCOUNT_REF").ToString()) <= double.Parse(SDOHelper.Read(oCategory, "HIGH").ToString()))
                                {
                                    dCategoryBalance = dCategoryBalance + (double)SDOHelper.Read(oNominalRecord, sMonthToRead);
                                    dDirectExpenseCategoryTotal = dDirectExpenseCategoryTotal + (double)SDOHelper.Read(oNominalRecord, sMonthToRead);
                                    xlSheet.Cells[iXLRow, 4] = dCategoryBalance.ToString();
                                }
                            } while (oNominalRecord.MoveNext());

                            dCategoryBalance = 0;
                            iXLRow++;
                        }
                    }
                    iXLRow++ ;
                    xlSheet.Cells[iXLRow, 1] = "TOTAL DIRECT EXPENSES";
                    xlSheet.Cells[iXLRow, 4] = dDirectExpenseCategoryTotal;
                    Range = xlSheet.get_Range("D" + iXLRow.ToString(), misValue);
                    Range.Font.Underline = true;
                    Range.Font.Bold = true;
                    Range = xlSheet.get_Range("A" + iXLRow.ToString(), misValue);
                    Range.Font.Bold = true;

                    // Add Overheads Categories *************************************************************************
                    iXLRow = iXLRow + 2;
                    xlSheet.Cells[iXLRow, 1] = (string)SDOHelper.Read(oChartData, "NAME_OVERHEADS");
                    Range = xlSheet.get_Range("A" + iXLRow.ToString(), misValue);
                    Range.Font.Underline = true;
                    Range.Font.Bold = true;

                    // Read Direct Expense Headings
                    iXLRow = iXLRow + 2;

                    for (iCategoryCounter = 241; iCategoryCounter <= 320; iCategoryCounter++)
                    {
                        oCategory.Read(iCategoryCounter);
                        if ((string)SDOHelper.Read(oCategory, "NAME") != "")
                        {
                            xlSheet.Cells[iXLRow, 1] = (string)SDOHelper.Read(oCategory, "NAME");
                            oNominalRecord.MoveFirst();

                            do
                            {
                                if (double.Parse(SDOHelper.Read(oNominalRecord, "ACCOUNT_REF").ToString()) >= double.Parse(SDOHelper.Read(oCategory, "LOW").ToString())
                                    && double.Parse(SDOHelper.Read(oNominalRecord, "ACCOUNT_REF").ToString()) <= double.Parse(SDOHelper.Read(oCategory, "HIGH").ToString()))
                                {
                                    dCategoryBalance = dCategoryBalance + (double)SDOHelper.Read(oNominalRecord, sMonthToRead);
                                    dOverheadCategoryTotal = dOverheadCategoryTotal + (double)SDOHelper.Read(oNominalRecord, sMonthToRead);
                                    xlSheet.Cells[iXLRow, 4] = dCategoryBalance.ToString();
                                }
                            } while (oNominalRecord.MoveNext());

                            dCategoryBalance = 0;
                            iXLRow++;
                        }
                    }

                    iXLRow++;
                    xlSheet.Cells[iXLRow, 1] = "TOTAL OVERHEADS";
                    xlSheet.Cells[iXLRow, 4] = dOverheadCategoryTotal;
                    Range = xlSheet.get_Range("D" + iXLRow.ToString(), misValue);
                    Range.Font.Underline = true;
                    Range.Font.Bold = true;
                    Range.ColumnWidth = 18;
                    Range.NumberFormat = "#,##0.00";
                    Range = xlSheet.get_Range("A" + iXLRow.ToString(), misValue);
                    Range.Font.Underline = true;
                    Range.Font.Bold = true;
                    Range.ColumnWidth = 36;

                    // Calculate Net Profit
                    iXLRow = iXLRow + 3;
                    xlSheet.Cells[iXLRow, 1] = "NET PROFIT/LOSS";
                    Range = xlSheet.get_Range("A" + iXLRow.ToString(), misValue);
                    Range.Font.Underline = true;
                    Range.Font.Bold = true;
                    xlSheet.Cells[iXLRow, 4] = (dSalesCategoryTotal - dPurchaseCategoryTotal) - (dDirectExpenseCategoryTotal + dOverheadCategoryTotal);
                    Range = xlSheet.get_Range("D" + iXLRow.ToString(), misValue);
                    Range.Font.Underline = true;
                    Range.Font.Bold = true;

                    // Disconnect
                    oWS.Disconnect();
                }
            }
            // Save the Worksheet
            xlSheet.SaveAs("c:\\Temp.xls",misValue, misValue, misValue, misValue, misValue, misValue, misValue, misValue, misValue);
            xlApp.Visible = true;


Example - Creating an E-Mail in Microsoft Outlook 2000

Description

The example code below demonstrates how to create emails in Outlook 2000 based on information from Customer records. The code is written in Visual Basic v6.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

The code also includes a generic error handler. Clearly, you would respond differently depending on the actual exception thrown.

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare SDO Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oSalesRecord As SageDataObject300.SalesRecord
  Dim oSetupData As SageDataObject300.SetupData

  ' Declare Outlook Objects
  Dim oOutlookApp As New Outlook.Application
  Dim oMessage As Outlook.MailItem

  ' Declare Variables
  Dim intNotSent As Integer
  Dim szMessageContent, szDataPath As String

  ' Create an Instance of the SDOEngine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create an Instance of the Workspace Object
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then

    ' Try to Connect - Will throw an exception if it fails
    If oWS.Connect(szDataPath, "", "", "Example") Then

      ' Create an Instance of the SalesRecord Object
      Set oSalesRecord = oWS.CreateObject("SalesRecord")

      ' Create an Instance of the Setup Object
      Set oSetupData = oWS.CreateObject("SetupData")

      ' Create an Instance of the Outlook MailItem Object
      Set oMessage = oOutlookApp.CreateItem(olMailItem)

      ' Move to the First Sales Account
      oSalesRecord.MoveFirst

      Do

        ' Check Credit Limit
        If (oSalesRecord.Fields.Item("BALANCE").Value > oSalesRecord.Fields.Item("CREDIT_LIMIT").Value) And _
          oSalesRecord.Fields.Item("CREDIT_LIMIT").Value > 0 Then

          ' Build up content string
          szMessageContent = vbCrLf & vbCrLf & "RE Your Reference: " & CStr(oSalesRecord.Fields.Item("ACCOUNT_REF").Value) & vbCrLf _
            & vbCrLf & "Your Credit Limit Is: �" & CStr(Format(oSalesRecord.Fields.Item("CREDIT_LIMIT").Value, "##,##0.00")) & vbCrLf _
              & "Your Current Balance Is: �" & CStr(Format(oSalesRecord.Fields.Item("BALANCE").Value, "##,##0.00")) & vbCrLf & vbCrLf _
                & "Could you please address the situation ASAP." & vbCrLf & vbCrLf & "Regards" & vbCrLf & vbCrLf _
                  & "Michael Kenney" & vbCrLf & "Credit Control" & vbCrLf & CStr(oSetupData.Fields.Item("NAME").Value)

          ' Check to see if E-Mail is Populated and if so Create Message and Populate
          If oSalesRecord.Fields.Item("E_MAIL").Value <> "" Then

            oMessage.To = oSalesRecord.Fields.Item("E_MAIL").Value
            oMessage.Subject = "Message From " & oSetupData.Fields.Item("NAME").Value

            ' Validate Contact Name
            If oSalesRecord.Fields.Item("CONTACT_NAME").Value <> "" Then

              ' Populate Header of Message
              oMessage.Body = "Dear " & oSalesRecord.Fields.Item("CONTACT_NAME").Value & "," & szMessageContent

            Else

              ' Populate With Dear/Sir Madam
              oMessage.Body = "Dear Sir/Madam" & "," & szMessageContent

            End If

            ' Send the Message
            oMessage.Send

          Else

            ' Add to count of emails not sent
            intNotSent = intNotSent + 1

          End If

        End If

      Loop Until Not oSalesRecord.MoveNext

    End If

    MsgBox CStr(intNotSent) + " Accounts Not Sent Because of No Email Address", vbOKOnly, "SDO"

    ' Disconnect
    oWS.Disconnect

  End If

  ' Destroy Objects
  Set oMessage = Nothing
  Set oOutlookApp = Nothing
  Set oSetupData = Nothing
  Set oSalesRecord = Nothing
  Set oWS = Nothing
  Set oSDO = Nothing

  Exit Sub

' Error Handling Code
Error_Handler:

  MsgBox "The SDO generated the following error: " & oSDO.LastError.Text, vbOKOnly, "SDO Examples"


Launching Applications from the Sage 50 Toolbars

Launching Other Applications from the Sage 50 Accounts Toolbars

Launching an Application from a Sage 50 Accounts Module Toolbar

You can launch an application from the toolbars of individual modules, all you need to do is:

  1. Design a 16 colour bitmap, 25 * 23 pixels - the icon should be 33 * 33 for the 'XP look and feel' in v2010
  2. Save it in the same directory as your application.
  3. Add an entry to the SAGE.INI file (This file can be found in the Default Data location, C:\Documents and Settings\All Users\Application Data\Sage\Accounts or C:\Program Data\Sage\Accounts on Windows Vista, Windows 7 or Windows 8.1) which conforms to the following format:

    ICON NAME, PATH TO EXE, BITMAP FILENAME, EXE FILENAME,, Optional Parameter (See below), SMALL BITMAP FILENAME

    E.g.:

    [SFWAddIns]
    Addin1=Test Prog,c:\test,test.bmp,test.exe,,CUSTOMER, SMALL BITMAP FILENAME

The last variable (CUSTOMER) is the program argument.

You can choose from:

    CUSTOMER, SUPPLIER, BANK. PRODUCT, INVOICE, SOP, POP, VAT

The next time you start Sage 50 Accounts, the new icon will appear in the specified module's toolbar.

Note:
  • There must be no spaces in the SAGE.INI entry, except for the first parameter (ICON NAME).
  • A maximum of 10 applications in total can be added.
  • Your application will not appear as an MDI child of Sage 50 Accounts.
  • You will need to code your application to prevent multiple copies from being launched.
  • Your application will need to logon to Sage 50 Accounts with a different name to that being used by the current instance of Sage 50 Accounts so this method of launching applications is not applicable to the single user versions of Accounts and Accounts Plus.
  • Should you require transparency in your bitmap image, Sage 50 Accounts' default transparency colour is RGB value 255, 0, 255.


Technical Support

Troubleshooting Tips

Installation Issues

Use the installer

If you have not already, try running the SDO installer utility on your developer edition CD.
Browse the content of your CD for Sage50Accounts_SDO.msi and double click to run.
(May be named differently dependent on version, only available since version 13)

Register files

See this article for help with copying the required files manually and registering them if the installer fails.

64 bit Operating system

64 bit operating systems are supported from version 2010, however applications should be compiled targeted to x86 CPUs to avoid runtime errors. Sage 50 Accounts v30:It is now possible to build 64-bit applications

Permissions

Log directly onto the PC as a local Admin , do not use a remote desktop connection

Version incompatibility

Make sure the version matches between Help > About in the UI and the version of the Sg50SdoEngine.dll properties.

Registration Issues

Running on a machine where the U.I is not installed

Use the register method within your applications code to register the SDO and create the file. (See Register Method)

Running on a Vista machine (v13 or previous)

Vista uses virtual store, so SDOeng.usr will not be placed in C:\Windows, you need to manually copy the file to C:\Windows.

Prompted to register

Are you definitely being prompted for SDO key and not for an Application key? If you are prompted for the Application key then the Sage registration file (Sage.usr) is not present in the parent directory.

Have you definitely registered previously? The SDO and Application can run for 30 days or 30 uses before registration is required to enable trials.

SDOeng.usr file needs to be present in C:\ProgramData\Sage\Accounts\2024

For earlier versions the file needs to be present in C:\Windows.

Note:
In versions 13 and earlier the file is stored in the same directory, with the same name, regardless of version. This can cause problems when more than one version is installed at the same time.

A workaround for this problem is to rename the SDOEng.usr file when switching between versions. For example:

Register v11 SDO, as a result a file called SDOEng.usr is created in C:\Windows.
Before using v12, rename the file SDOEng.usrv11
Register v12 SDO, as a result a file called SDOEng.usr is created in C:\Windows.

When you want to return to using v11 SDO:
Rename the file SDOEng.usr to SDOEng.usrv12
Rename the file SDOEng.usrv11. back to SDOEng.usr

Problems connecting

Check username, password, and data path

This is by far the most common resolution to connection problems. Are you absolutely sure that you are pointing to the right data path, you have permissions to that directory and that the username and password are correct for that particular database?

Note:
When using the SelectCompany method, the data path you pass is to the COMPANY file, by default in version 24:

C:\ProgramData\Sage\Accounts\2024

When using the Connect Method alone the path you are passing is to the actual data folder, for example:

C:\ProgramData\Sage\Accounts\2024\Company.000\ACCDATA

Select Company Dialog Blank

Make sure the COMPANY file you are pointing to is local on the machine and the path in the file is valid.

Try demo database connection

A simple way to troubleshoot if it is a code issue or an environmental issue is to test your connection code with the demo database. The default path is:

C:\ProgramData\Sage\Accounts\2024\Demodata\Accdata

Username: MANAGER
Password: <Blank>

Try local copy of data

Copy the data you are trying to access locally onto your machine to eliminate network issues.

Update

An update is available for version 15 that addresses a particular connection issue. (Sage 50 Accounts 2009 SDO Hotfix)

Sage Developer Services are available to answer any queries you may have, and may be contacted between 9am and 5pm, Monday to Friday.

Contact details:

  • email: developers.programme@sage.com

Produced by: Developer Services, Sage (UK) Limited.


Report Designer API

Introduction

Sage 50 Report Designer was introduced in Sage 50 Accounts 2007 and is an enhanced version of the original Sage Report Designer.
Sage 50 Report Designer has a .Net and COM API that allows integration with 3rd party applications, providing functionality such as getting report layout information, launching report preview windows and exporting reports to different file formats.

Getting started

The Sage Report Designer API is available via a .Net assembly and contains objects and interfaces necessary to launch the reporting engine from within your own code. The assembly is also COM registered and therefore can be accessed in non-.Net development environments.
In order to communicate with the Reporting Engine your application will need to implement the IReportingEngineHost interface and the ReportDesignerResolver class. The Reporting Engine can then provide various Report Designer Services such as Preview, Export and ReportInformation.

Where the Reporting Engine requires a user interface, integrated applications may provide a Windows Form handle to contain the Reporting UI.

Sage 50 Accounts v28 onwards

The Sage 50 Accounts v28 update included a new version of the Report Design program that Sage 50 Accounts uses for its reporting. As a result developers who use the above reporting engine dll to run Sage reports, will need to reference a new Sage.Reporting.Engine.integration.dll file. This is located in the Sage 50 Accounts program install folder.

In Visual Studio you need to locate the new Sage.Reporting.Engine.Integration.dll file, click the Project menu > Add Reference > Browse tab > Browse (C:\Program Files (x86)\Sage\Accounts\Sage.Reporting.Engine.Integration.dll) and select the Sage.Reporting.Engine.Integration.dll file and press Ok.

**Note** Projects need to be compiled against .Net version 4.7.2 or above. Also we would recommend setting the Copy Local reference property for the Sage.Reporting.Engine.Integration.dll to false.

Examples Using this Object

Implementing the ReportDesignerResolver class

Implementing the IReportingEngineHost

Getting Report Information

Previewing A Report

Exporting A Report

Opening The Report Browser


Examples

Examples - Report Designer Code Examples

This help file contains code examples for the following development environments:

Microsoft .NET (VB & C#)


Implementing the ReportDesignerResolver class

Introduction

With v28 you will be required to use the new ReportDesignerResolver class in order to use the Report Designer API. Instead of just providing examples we have created the following solutions which demonstrate how to impliment the new Report Designer Resolver class.
These solutions have been created for the sole purpose of demonstrating the new implmentation of this class. Therefore, we wont offer support for troubleshooting any specifc issues with these solutions but will continue to offer support for any questions or issues regarding the report designer API.

**Note** szReportPath, szOutputPath, data directory and user credentials need to be entered before running either application.

Download Links


Sage 50 Accounts - Example - Implementing the IReportingEngineHost

Example - Implementing the IReportingEngineHost

In each of the examples in this article, we create a new instance of the class MyHost, which is a class that we need to create ourselves that implements the Reporting Engine’s IReportingEngineHost interface. Before running the examples, make sure that the implementation exists somewhere in your Visual Studio project.

VB.NET [image] Copy VB Code

Public Class MyHost

Implements Sage.Reporting.Engine.Integration.IReportingEngineHost

Private _oSite As Sage.Reporting.Engine.Integration.IReportingEngineSite

Public Function GetService(ByVal identifier As System.Guid) As Object _

Implements Sage.Reporting.Engine.Integration.IReportingEngineHost.GetService

Return Nothing

End Function

Public Property Site() As Sage.Reporting.Engine.Integration.IReportingEngineSite _

Implements Sage.Reporting.Engine.Integration.IReportingEngineHost.Site

Get

Return _oSite

End Get

Set(ByVal value As Sage.Reporting.Engine.Integration.IReportingEngineSite)

_oSite = value

End Set

End Property

End Class

C#.NET [image] Copy C# Code

/// <summary>

/// Reporting Host Class

/// </summary>

public class MyHost : Sage.Reporting.Engine.Integration.IReportingEngineHost

{

private Sage.Reporting.Engine.Integration.IReportingEngineSite _oSite;

public object GetService(Guid identifier)

{

return null;

}

public Sage.Reporting.Engine.Integration.IReportingEngineSite Site

{

get { return _oSite; }

set { _oSite = value; }

}

}


Sage 50 Accounts - Example - Getting report information

Example - Getting Report Information

Each report layout in Sage Report Designer has meta-information which may be useful and is used for instance to display the report Description and Last Run Date. To access the Report Information, we implement and create an instance of the IReportingEngineHost interface and create a ReportingEngine. We also create a ReportingEngineSite that represents the Report Designer aspect of the Reporting Engine. The next step is to create an object that implements IReportInformationService and this provides information about the report. Each example assumes that a listbox called listBox1 has been added to a Windows Form.

VB.NET [image] Copy VB Code

' Declare variables and objects

Dim szReportsPath As String = "C:\Documents and Settings\All Users\Application " & _

"Data\Sage\Accounts\2023\Demodata\Reports"

Dim oHost As Sage.Reporting.Engine.Integration.IReportingEngineHost

Dim oEngine As Sage.Reporting.Engine.Integration.ReportingEngine

Dim oSite As Sage.Reporting.Engine.Integration.IReportingEngineSite

Dim oInformationService As Sage.Reporting.Engine.Integration.IReportInformationService

' Instantiate Reporting objects

oHost = New MyHost()

oEngine = New Sage.Reporting.Engine.Integration.ReportingEngine()

oSite = oEngine.CreateInstance(oHost)

oInformationService = oSite.GetService _

(Sage.Reporting.Engine.Integration.ServiceIdentifiers.ReportInformation)

' Cycle through all report files and display their details

For Each szReportFilePath As String In _

System.IO.Directory.GetFiles(szReportsPath, "*.report", _

System.IO.SearchOption.AllDirectories)

' Create Report Information Service and return report details

Dim oInformation As Sage.Reporting.Engine.Integration.IReportInformation = _

oInformationService.GetInformation(szReportFilePath)

Dim szReportName As String = oInformation.GetAttribute("Name").ToString()

Dim szReportDescription As String = _

oInformation.GetAttribute("Description").ToString()

Dim szReportLastRun As String = _

oInformation.GetAttribute("LastRunDate").ToString()

' This example assumes that a listbox called listbox1 exists on the form

listBox1.Items.Add(String.Format( _

"Report name: {0}, Description: {1}, Last Run Date: {2}", _

szReportName, szReportDescription, szReportLastRun))

Next
C#.NET [image] Copy C# Code

// Declare variables and objects

string szReportsPath = @"C:\Documents and Settings\All Users\Application"

+ "Data\Sage\Accounts\2023\Demodata\Reports";

Sage.Reporting.Engine.Integration.IReportingEngineHost oHost;

Sage.Reporting.Engine.Integration.ReportingEngine oEngine;

Sage.Reporting.Engine.Integration.IReportingEngineSite oSite;

Sage.Reporting.Engine.Integration.IReportInformationService oInformationService;

// Instantiate Reporting objects

oHost = new MyHost();

oEngine = new Sage.Reporting.Engine.Integration.ReportingEngine();

oSite = oEngine.CreateInstance(oHost);

oInformationService = (Sage.Reporting.Engine.Integration.IReportInformationService)oSite.GetService

(Sage.Reporting.Engine.Integration.ServiceIdentifiers.ReportInformation);

// Cycle through all report files and display their details

foreach (string szReportFilePath in System.IO.Directory.

GetFiles(szReportsPath, "*.report", System.IO.SearchOption.AllDirectories))

{

// Create Report Information Service and return report details

Sage.Reporting.Engine.Integration.IReportInformation oInformation =

oInformationService.GetInformation(szReportFilePath);

string szReportName = oInformation.GetAttribute("Name").ToString();

string szReportDescription =

oInformation.GetAttribute("Description").ToString();

string szReportLastRun = oInformation.GetAttribute("LastRunDate").ToString();

// This example assumes that a listbox control named listBox1

// has been added to the form

listBox1.Items.Add(string.Format

("Report name: {0}, Description: {1}, Last Run Date: {2}",

szReportName, szReportDescription, szReportLastRun));

}


Sage 50 Accounts - Example - Previewing A Report

Example - Previewing a Report

We can preview any report by providing its full file path. We can also set the path to the data, any username and password, and also some criteria for the report.

With the example below, we create an object that implements the IPreviewService interface and set the username, password, directory and data source name. We also set the criteria for the report automatically � if we didn�t do this then the criteria dialog would appear for the user to select their own criteria.

We then attach a new Windows form to the preview service, load the report and display it.

To find what criteria string you should use, Edit the report you wish to run and check the Report Header section. The criteria will usually appear here on standard reports, so to find out the string, simply click on the variable and check the Expression�s property. For instance on the screenshot below, the selected variable�s Expression property is �CRITERIA.TRAN_DATE_BFCF_FROM�, so our criteria string when using the API is �TRAN_DATE_BFCF_FROM�.

VB.NET [image] Copy VB Code

' Declare variables and objects

Dim szReportPath As String = _

"C:\ProgramData\Sage\Accounts\2024\" _

& "Demodata\Reports\Customer\Customer Details Reports\CSTLIST.Report"

Dim oHost As Sage.Reporting.Engine.Integration.IReportingEngineHost

Dim oEngine As Sage.Reporting.Engine.Integration.ReportingEngine

Dim oSite As Sage.Reporting.Engine.Integration.IReportingEngineSite

' Instantiate Reporting objects

oHost = New MyHost()

oEngine = New Sage.Reporting.Engine.Integration.ReportingEngine()

oSite = oEngine.CreateInstance(oHost)

' Create a Report Preview and set some of it's attributes

Dim oPreview As Sage.Reporting.Engine.Integration.IPreviewService = _

oSite.GetService(Sage.Reporting.Engine.Integration.ServiceIdentifiers.Preview)

oPreview.SetAttribute("DIR", "C:\ProgramData\Sage\Accounts\2023\COMPANY.000\ACCDATA")

oPreview.SetAttribute("DSN", "SageLine50v30")

oPreview.SetAttribute("UID", "MANAGER")

oPreview.SetAttribute("PWD", "")

' Set some criteria automatically

oPreview.Criteria.Add("CUSTOMER_REF_FROM", "")

oPreview.Criteria.Add("CUSTOMER_REF_TO", "ZZZZZZZZ")

' Create a form to hold the report

Dim oPreviewForm As New Form()

oPreviewForm.Size = New Size(400, 400)

oPreviewForm.Location = New Point(300, 300)

oPreviewForm.Text = "Report Preview"

' Attach the Report Preview to this form

oPreview.Attach(oPreviewForm.Handle)

Try

' Load the Report file

oPreview.Load(szReportPath)

' Run the Report Preview

If oPreview.Run(True) Then

' Make the Report Preview and form visible

oPreview.Visible = True

oPreviewForm.Visible = True

Else

MessageBox.Show("Report failed to run.")

End If

Catch ex As Exception

MessageBox.Show(ex.Message)

End Try
C#.NET [image] Copy C# Code

// Declare variables and objects

string szReportPath = @"C:\ProgramData\Sage\Accounts\2024" +

@"Demodata\Reports\Customer\Customer Details Reports\" +

@"CSTLIST.Report";

Sage.Reporting.Engine.Integration.IReportingEngineHost oHost;

Sage.Reporting.Engine.Integration.ReportingEngine oEngine;

Sage.Reporting.Engine.Integration.IReportingEngineSite oSite;

// Instantiate Reporting objects

oHost = new MyHost();

oEngine = new Sage.Reporting.Engine.Integration.ReportingEngine();

oSite = oEngine.CreateInstance(oHost);

// Create a Report Preview and set some of it's attributes

Sage.Reporting.Engine.Integration.IPreviewService oPreview =

(Sage.Reporting.Engine.Integration.IPreviewService)oSite.GetService

(Sage.Reporting.Engine.Integration.ServiceIdentifiers.Preview);

oPreview.SetAttribute("UID", "MANAGER");

oPreview.SetAttribute("PWD", "");

oPreview.SetAttribute("DIR", @"C:\ProgramData\Sage\Accounts\2024\COMPANY.000\ACCDATA");

oPreview.SetAttribute("DSN", "SageLine50v30");

// Set some criteria automatically

oPreview.Criteria.Add("CUSTOMER_REF_FROM", "");

oPreview.Criteria.Add("CUSTOMER_REF_TO", "ZZZZZZZZ");

// Create a form to hold the report

Form oPreviewForm = new Form();

oPreviewForm.Size = new Size(400, 400);

oPreviewForm.Location = new Point(300, 300);

oPreviewForm.Text = "Report Preview";

// Attach the Report Preview to this form

oPreview.Attach(oPreviewForm.Handle);

try

{

// Load the Report file

oPreview.Load(szReportPath);

// Run the Report Preview

if (oPreview.Run(true))

{

// Make the Report Preview and form visible

oPreview.Visible = true;

oPreviewForm.Visible = true;

}

else

{

MessageBox.Show("Report failed to run.");

}

}

catch (Exception ex)

{

MessageBox.Show(ex.Message);

}


Sage 50 Accounts - Example - Exporting A Report

Example - Exporting A Report

We can export a report into many formats such as bitmap (.bmp), Comma Separated Values (.csv), email (.eml), web page (.html), Adobe Acrobat (.pdf), text (.txt) and XML (.xml). This may be useful in situations where batch reports need to be run overnight and saved to disk, or perhaps even to allow remote users to access data remotely using CSV or XML.

With the example below, we create an object that implements the IExportService interface and set the username, password, directory and data source name.

We then load the report and run it with the desired format and other arguments and launch Excel to display it in a separate process.
VB.NET [image] Copy VB Code

' Declare variables and objects

Dim szReportPath As String = _

"C:\ProgramData\Sage\Accounts\2024\" _

& "Demodata\Reports\Transactions\Audit Trail Reports\AuditSP.Report"

Dim szOutputPath As String = "C:\temp.csv"

Dim oHost As Sage.Reporting.Engine.Integration.IReportingEngineHost

Dim oEngine As Sage.Reporting.Engine.Integration.ReportingEngine

Dim oSite As Sage.Reporting.Engine.Integration.IReportingEngineSite

' Instantiate Reporting objects

oHost = New MyHost()

oEngine = New Sage.Reporting.Engine.Integration.ReportingEngine()

oSite = oEngine.CreateInstance(oHost)

' Create a Report Export object and set some of it's attributes

Dim oExport As Sage.Reporting.Engine.Integration.IExportService = _

oSite.GetService(Sage.Reporting.Engine.Integration.ServiceIdentifiers.Export)

oExport.SetAttribute("DIR", "C:\ProgramData\Sage\Accounts\2023\COMPANY.000\ACCDATA")

oExport.SetAttribute("DSN", "SageLine50v30")

oExport.SetAttribute("UID", "")

oExport.SetAttribute("PWD", "")

Try

' Load the report file

oExport.Load(szReportPath)

' Run the Report Export, output to a Comma Separated Values file

If oExport.Run(Sage.Reporting.Engine.Integration.ExportType.csv, _

szOutputPath, Sage.Reporting.Engine.Integration.ExportFlags.None) Then

' Open the file in Excel

System.Diagnostics.Process.Start("Excel.exe", szOutputPath)

Else

MessageBox.Show("Report failed to run.")

End If

Catch ex As Exception

MessageBox.Show(ex.Message)

End Try
C#.NET [image] Copy C# Code

// Declare variables and objects

string szReportPath = @"C:\ProgramData\Sage\Accounts\2023\Demodata\Reports\Transactions\Audit Trail Reports\AuditSP.Report";

string szOutputPath = @"C:\temp.csv";

Sage.Reporting.Engine.Integration.IReportingEngineHost oHost;

Sage.Reporting.Engine.Integration.ReportingEngine oEngine;

Sage.Reporting.Engine.Integration.IReportingEngineSite oSite;

// Instantiate Reporting objects

oHost = new MyHost();

oEngine = new Sage.Reporting.Engine.Integration.ReportingEngine();

oSite = oEngine.CreateInstance(oHost);

// Create a Report Export object and set some of it's attributes

Sage.Reporting.Engine.Integration.IExportService oExport =

(Sage.Reporting.Engine.Integration.IExportService)oSite.GetService

(Sage.Reporting.Engine.Integration.ServiceIdentifiers.Export);

oExport.SetAttribute("DIR", @"C:\ProgramData\Sage\Accounts\2023\COMPANY.000\ACCDATA");

oExport.SetAttribute("DSN", "SageLine50v30");

oExport.SetAttribute("UID", "");

oExport.SetAttribute("PWD", "");

try

{

// Load the report file

oExport.Load(szReportPath);

// Run the Report Export, output to a Comma Separated Values file

if (oExport.Run(Sage.Reporting.Engine.Integration.ExportType.csv,

szOutputPath, Sage.Reporting.Engine.Integration.ExportFlags.None))

{

// Open the file in Excel

System.Diagnostics.Process.Start("Excel.exe", szOutputPath);

}

else

{

MessageBox.Show("Report failed to run.");

}

}

catch (Exception ex)

{

MessageBox.Show(ex.Message);

}


Sage 50 Accounts - Example - Opening the Report Browser

Example - Opening the Report Browser

You may wish to open the Report Browser window that appears within Sage applications that use the new Report Designer. From here, users can run reports to preview, export and so on as if they were inside the application.

VB.NET [image] Copy VB Code

' Declare variables and objects

Dim szReportsPath As String = "C:\ProgramData\Sage\Accounts\2023\Demodata\Reports\"

Dim szDSN As String = "SageLine50v30"

Dim szDataProvider As String = _

"Sage.Query.Engine.DataProvider.Line50.Line50DataProvider"

Dim szDataProviderPath As String = _

"C:\Program Files\Sage\Accounts\Sage.Query.Engine.DataProvider.Line50.dll"

Dim szConfig As String = "DSN=SageLine50v30;" _

& "DIR=C:\ProgramData\Sage\Accounts\2023\demodata\ACCDATA;" _

& "Root Path=C:\Program Files\Sage\Accounts\;" _

& "Report Types=C:\Program Files\Sage\Accounts\Line50.reporttypes"

Dim oHost As Sage.Reporting.Engine.Integration.IReportingEngineHost

Dim oEngine As Sage.Reporting.Engine.Integration.ReportingEngine

Dim oSite As Sage.Reporting.Engine.Integration.IReportingEngineSite

' Instantiate Reporting objects

oHost = New MyHost()

oEngine = New Sage.Reporting.Engine.Integration.ReportingEngine()

oSite = oEngine.CreateInstance(oHost)

' Create a service

Dim oService As Sage.Reporting.Engine.Integration.IDataSourceRegistrationService = _

oSite.GetService _

(Sage.Reporting.Engine.Integration.ServiceIdentifiers.DataSourceRegistration)

oService.Register(szDSN, szDataProvider, szDataProviderPath, szConfig)

' Create the Browser object

Dim oBrowser As Sage.Reporting.Engine.Integration.IReportBrowserService = _

oSite.GetService _

(Sage.Reporting.Engine.Integration.ServiceIdentifiers.ReportBrowserService)

' Set the attributes and DSN

oBrowser.DataSourceName = szDSN

oBrowser.SetAttribute("DSN", szDSN)

oBrowser.SetAttribute("UID", "MANAGER")

oBrowser.SetAttribute("PWD", "")

oBrowser.SetAttribute("DIR", "C:\ProgramData\Sage\Accounts\2023\DEMODATA\ACCDATA\")

' Add the root folder for reports

oBrowser.RootFolders.Add(szReportsPath, True)

' Create a form to hold the report

Dim oBrowserForm As New Form()

oBrowserForm.Size = New Size(400, 400)

oBrowserForm.Location = New Point(300, 300)

oBrowserForm.Text = "Report Preview"

oBrowser.Show(oBrowserForm.Handle)
C#.NET [image] Copy C# Code

// Declare variables and objects

string szReportsPath = @"C:\ProgramData\Sage\Accounts\2023\Demodata\Reports\";

string szDSN = "SageLine50v30";

string szDataProvider = "Sage.Query.Engine.DataProvider.Line50.Line50DataProvider";

string szDataProviderPath =

+@"C:\Program Files\Sage\Accounts\Sage.Query.Engine.DataProvider.Line50.dll";

string szConfig = @"DSN=SageLine50v30;DIR=C:\ProgramData\Sage\Accounts\2023\demodata\ACCDATA;"

+ @"Root Path=C:\Program Files\Sage\Accounts\;"

+ @"Report Types=C:\Program Files\Sage\Accounts\Line50.reporttypes";

Sage.Reporting.Engine.Integration.IReportingEngineHost oHost;

Sage.Reporting.Engine.Integration.ReportingEngine oEngine;

Sage.Reporting.Engine.Integration.IReportingEngineSite oSite;

// Instantiate Reporting objects

oHost = new MyHost();

oEngine = new Sage.Reporting.Engine.Integration.ReportingEngine();

oSite = oEngine.CreateInstance(oHost);

// Create a service

Sage.Reporting.Engine.Integration.IDataSourceRegistrationService oService =

(Sage.Reporting.Engine.Integration.IDataSourceRegistrationService)oSite.GetService

(Sage.Reporting.Engine.Integration.ServiceIdentifiers.DataSourceRegistration);

oService.Register(szDSN, szDataProvider, szDataProviderPath, szConfig);

// Create the Browser object

Sage.Reporting.Engine.Integration.IReportBrowserService oBrowser =

(Sage.Reporting.Engine.Integration.IReportBrowserService)oSite.GetService

(Sage.Reporting.Engine.Integration.ServiceIdentifiers.ReportBrowserService);

// Set the attributes and DSN

oBrowser.DataSourceName = szDSN;

oBrowser.SetAttribute("DSN", szDSN);

oBrowser.SetAttribute("UID", "MANAGER");

oBrowser.SetAttribute("PWD", "");

oBrowser.SetAttribute("DIR", @"C:\ProgramData\Sage\Accounts\2023\Demodata\ACCDATA\");

// Add the root folder for reports

oBrowser.RootFolders.Add(szReportsPath, true);

// Create a form to hold the report

Form oBrowserForm = new Form();

oBrowserForm.Size = new Size(400, 400);

oBrowserForm.Location = new Point(300, 300);

oBrowserForm.Text = "Report Preview";

oBrowser.Show(oBrowserForm.Handle);


Technical Support

 Updated articles, hints, tips and more:

Please visit the Sage 50 Accounts Developer Centre on a regular basis.

Downloads - updates and full versions

Please visit the Sage 50 Accounts Downloads page to download latest copies of the SDK and Sage 50 Accounts Developer Edition licences.

Contact our Developer Support Team

Sage Developer Services are available to answer any queries you may have, and may be contacted via email between 9am and 5pm, Monday to Friday.

  • email: developers.programme@sage.com

Use the Sage Developers Forum

You can visit the Sage Developers Forum, available to members of the Developers Programme and moderated by Sage staff, to exchange development information, tips and techniques. Please click here and choose 'visit the forum'.
Produced by: Developer Services, Sage (UK) Limited.


AccountStatusData - ON_HOLD Field Values

Values

The following table lists the possible values for the ON_HOLD field of the AccountStatusData object:

Value | Description
0 | On Hold flag not set
1 | On Hold flag set

Applies To

These constants are used in conjunction with the following objects:

Object | Field
AccountStatusData | ON_HOLD


AccountStatusData - STATUS Field Values

AccountStatusData - STATUS Values

Values

The following table lists the possible values for the STATUS field of the AccountStatusData object:

Value | Description
Alpha Numeric characters | Narrative for the status up to the length of the STATUS field.

Applies To

These constants are used in conjunction with the following objects:

Object | Field
AccountStatusData | STATUS


Installing and Running SDO Applications on PCs with no Sage 50 Installation

Architectural changes

Background

An ongoing internal project within Sage R&D has been undertaken to modify the existing file SDK with the creation of a new server process to manage the data files through a client/server framework. The changes introduced for the 2015 release of Sage 50 Accounts mean sage can now be used by upto 20 consecutive users in a network environment with additional robustness to data integrity and opens the door to addtional scalabilty.

Legacy File SDK

Prior to Sage 50 Accounts 2015, the data files were accessed through a shared folder in a peer to peer network environment with Microsoft Windows controling the data I/O and caching.

Remote File SDK

The Remote File SDK is of a client/server architecture which removes the reliance on a shared folder and offers a single point in which the data is written with the benefit of greater robustness and architectural opportunities for the future. As the client-side caching offered by Windows has been eliminated and client/server network trips introduced, performance was a particular challenge. Although TCP is very fast in a Local Area Network, Sage 50 Accounts makes large numbers of small requests which creates the challenge of winning back performance through an on going effort involving caching and optimisation.

Service Calls

Service Calls Core File SDK functions and indexing functions have been remoted and are now delegated to the server process. These are as follows

File SDK

  • Open File
  • Close File
  • Read Record
  • Write Record
  • Lock Record
  • Unlock Record
  • Get File Size
  • Set End of File
  • Set File Times

    • File Indexing

  • Search Key
  • Find Key
  • Next Key
  • Previous Key
  • Add Key
  • Delete Key

            •


Fixed Asset Depreciation Code Constants

Fixed Asset Depreciation Codes

Enumeration name

DepreciationType

Values

The following table lists the constants for the Fixed Asset Depreciation Codes.

Constant | Value | Description
sdoSDP | 1 | Straight Line
sdoRDP | 2 | Reducing
sdoWDP | 3 | Write Off

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.DepreciationType

Applies To

These constants are used in conjunction with the following objects:

Object | Field
AssetData | DEP_METHOD_CODE
AssetRecord | DEP_METHOD_CODE


Price Type Constants

BudgetingType

Enumeration name

BudgetingType

Values

The following table lists the constants for the Budgeting Types:

Constant | Value | Description | Budgeting Type Selection
sdoNominalStandard 0

Nominal Monthly Buckets

 Standard
sdoNominalAdvanced | 1 | Nominal Monthly Buckets with Additional Options | Advanced / Nominal Code
sdoDepartment | 2 | Budgets by Dept/Nominal Category | Advanced / Department Overview
sdoDepartmentAndNominal | 3 | Budgets by Dept/Nominal Category and Nominal Code | Advanced / Department In-Depth

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.BudgetingType

Applies To

These constants are used in conjunction with the following objects:

Object | Field
SetupData | BUDGETING_TYPE


CIS Card Type Constants

CIS Card Types

Enumeration name

CISCardType

Values

The following table lists the constants for CIS Card Types:

Constant | Value | Description
CIS4_Permanent | 0 | CIS4 Permanent Registration Card.
CIS4_Temporary | 1 | CIS4 Temporary Registration Card.
CIS5 | 2 | CIS5 Registration Card
CIS5_Partner | 3 | CIS5 Partner Registration Card
CIS6 | 4 | CIS6 Registration Card

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.CISCardType

Applies To

These constants are used in conjunction with the following objects:

Object | Property
CISSubcontractorLegacy | CardType


CIS Company Type Constants

CIS Company Types

Enumeration name

CISCompanyType

Values

The following table lists the constants for CIS Company Types:

Constant | Value | Description
sdoSoleTraderType | 0 | Sole Trader
sdoPartnershipType | 1 | Partnership
sdoCompanyType | 2 | Company
sdoTrustType | 3 | Trust Company

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.CISCCompanyType.

Applies To

These constants are used in conjunction with the following objects:

Object | Property
CISSubcontractor | CompanyType


CIS Payment Frequency Constants

CIS Payment Frequency

Enumeration name

CISPaymentFrequency

Values

The following table lists the constants for CIS Payment Frequency :

Constant | Value | Description
sdoWekly | 0 | Weekly payment frequency
sdoMonthly | 1 | Monthly payment frequency.

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.CISPaymentFrequency

Applies To

These constants are used in conjunction with the following objects:

Object | Property
CISSubcontractor | All fields except NAME and PASSWORD.


CIS Tax Treatment Constants

CIS Tax Treatment

Enumeration name

CISTaxTreatment

Values

The following table lists the constants for CIS Tax Treatment :

Constant | Value | Description
sdoGross | 0 | Gross tax treatment.
sdoStandardRate | 1 | Net (Standard Rate).
sdoHigherRate | 2 | Net (Higher Rate).

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.CISTaxTreatment

Applies To

These constants are used in conjunction with the following objects:

Object | Property
CISSubcontractorTaxHistory | All fields except NAME and PASSWORD.


CIS Type Constants

CIS Type

Enumeration name

CISType

Values

The following table lists the constants for CIS Types:

Constant | Value | Description
sdoCIS4 | 0 | CIS4 Registration Card.
sdoCIS5 | 1 | CIS5 Registration Card.
sdoCIS6 | 2 | CIS6 Registration Card.
sdoCIS6Exempt | 3 | CIS6 Exempt Registration Card.

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.CISType

Applies To

These constants are used in conjunction with the following objects:

Object | Property
CISSubcontractorLegacy | CISType


CIS Verification Status Constants

CIS Verification Status

Enumeration name

CISVerificationStatus

Values

The following table lists the constants for CIS Verification Status:

Constant | Value | Description
sdoToBeDetermined | 0 | CIS status to be verified.
sdoVerified | 1 | CIS status verified.
sdoNotRequired | 2 | CIS verification not required.

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.CISVerificationStatus

Applies To

These constants are used in conjunction with the following objects:

Object | Property
CISSubcontractor | VerificationStatus


Contact Type Constants

Contact Types

Enumeration name

ContactType

Values

The following table lists the constants for the Contact Types:

Constant | Value | Description
sdoCustomerContact | 67 | Contact is a Customer
sdoSupplierContact | 83 | Contact is a Supplier

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.ContactType

Applies To

These constants are used in conjunction with the following objects:

Object | Field
ContactAccountIdxRecord | TYPE
ContactDateIdxRecord | TYPE
ContactData | TYPE


Discount Type Constants

Discount Types

Enumeration name

DiscountType

Values

The following table lists the constants for the Discount Types:

Constant | Value | Description
sdoNoDiscount | 0 | No Discount Applied
sdoValueDiscount | 1 | Discount Applied by Invoice Value
sdoQtyDiscountA | 2 | Discount Applied by Banding A
sdoQtyDiscountB | 3 | Discount Applied by Banding B
sdoQtyDiscountC | 4 | Discount Applied by Banding C
sdoQtyDiscountD | 5 | Discount Applied by Banding D
sdoQtyDiscountE | 6 | Discount Applied by Banding E

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.DiscountType

Applies To

These constants are used in conjunction with the following objects:

Object | Field
SalesData | DISCOUNT_TYPE
SalesRecord | DISCOUNT_TYPE


Non Stock Product Code Constants

Non-Stock Product Codes

Values

The following table lists the constants for the Non-Stock Product Codes:

Constant | Description
S1 | Standard Service Line Vatable (T1)
S2 | Standard Service Line Non-Vatable (T0)
S3 | Service Line for Stock/Service Invoices (Allows the use of the memo field for extended text)
M | Message Line no pricing or Vat information

Remarks

These values are not actually constants; they are string values that may be entered into the stock code field and are recognised by Sage 50 Accounts as being non-stock items.

Applies To

These constants are used in conjunction with the following objects:

Object | Field
InvoiceItem | STOCK_CODE
SOPItem | STOCK_CODE
POPItem | STOCK_CODE


Price Type Constants

Payment Type

Field name

Payment_Type

Values

The following table lists the constants for the Payment Type:

Constant | Value | Description
0 | 0 | Payment already received
3 | 3 | Allocate Payment To Invoice (SR)
4 | 4 | Post as Payment on Accounts (SA)

Note: These values are set against the Payment_Type field name and also correspond to the TransactionTypes enumerator.

Applies To

These constants are used in conjunction with the following objects:

Object | Method
InvoiceData | TYPE
InvoicePost | TYPE
InvoiceRecord | TYPE
SopData | TYPE
SopPost | TYPE
SopRecord | TYPE


Price List Type Constants

Price List Calculation Types

Enumeration name

PriceListType

Values

The following table lists the constants for the Price List Types:

Constant | Value | Description
plFixed | 0 | Fixed discounted price i.e. List=100.00 Fixed=60.00
plStandard | 1 | Uses standard stock record sales price
plDecreasePercent | 2 | Decrease product sales price by a percentage
plDecreaseValue | 3 | Decrease product sales price by a specified amount
plMarkupCost | 4 | Increase cost price by a percentage
plMarkupValue | 5 | Increase cost price by a specified amount
plMarkupSales | 6 | Increase sales price by a percentage

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.PriceListType

Applies To

These constants are used in conjunction with the following objects:

Object | Method
PriceData | DISCOUNT_TYPE
PriceRecord | DISCOUNT_TYPE


Price Type Constants

Price List Types

Enumeration name

priceTypes

Values

The following table lists the constants for the Price Types:

Constant | Value | Description
pricePriceList | 80 | Price List
priceSpecial | 83 | Special
priceSupplier | 85 | Supplier

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.priceTypes

Applies To

These constants are used in conjunction with the following objects:

Object | Method
PriceListData | TYPE
PriceListRecord | TYPE


Purchase Order Status Constants

Purchase Order Status

Enumeration name

OrderStatusType

Values

The following table lists the constants for the Purchase Order Status:

Constant | Value | On Order | Delivered
sdoZeroAlloc | 0 | Blank | Blank
sdoFullAlloc | 2 | Full | Blank
sdoCancelled | 3 | Cancelled | Blank
sdoPartFullAlloc | 6 | Full | Part
sdoPartCancelled | 7 | Cancel | Part
sdoComplete | 8 | Blank | Complete

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.OrderStatusType

Remarks

The On-Order and Delivered columns represent the same named columns in Sage 50 Accounts Purchase Order Processing. When nothing appears in a column, it is assumed to be blank. E.g. A new Purchase Order has no Stock On-Order or Delivered, therefore both columns are listed here as Blank. (See sdoZeroAlloc)

Applies To

These constants are used in conjunction with the following objects:

Object | Field
POPData | STATUS
POPPost | STATUS
POPRecord | STATUS


Quotation Status Constants

Quotation Status

Enumeration name

QuoteStatus

Values

The following table lists the constants for the Invoice/SOPOrder Quotation status:

Constant | Value | Description
sdoNotAQuote | 0 | The Invoice/SOP is not a Quote so it has no status
sdoOpen | 1 | The quote is waiting for further processing
sdoWon | 2 | The quote has been won and is marked as such when converted to an invoice/sop
sdoLost | 3 | The quote has been lost i.e. not taken up by the customer
sdoInvalid | 4 | The quote is beyond its expiry date

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.QuoteStatus

Remarks

For a new quotation the 'QUOTE_STATUS' field should be set to sdoOpen, and the 'QUOTE_EXPIRY' field should be set.

Applies To

These constants are used in conjunction with the following objects:

Object | Field
InvoiceData | QUOTE_STATUS
InvoicePost | QUOTE_STATUS
InvoiceRecord | QUOTE_STATUS
SOPData | QUOTE_STATUS
SOPPost | QUOTE_STATUS
SOPRecord | QUOTE_STATUS


Recurring Entry Type Constants

Recurring Entry Types

Values

The following table lists the constants for the Recurring Entry Types:

Constant | Value | Description
sdoBankPayment | 0 | Bank Payment
sdoBankReceipt | 1 | Bank Receipt
sdoBankTransfer | 2 | Bank Transfer
sdoCustomerPaymentOnAccount | 3 | Sales Receipt On Account
sdoJournalDebit | 4 | Journal Debit
sdoJournalCredit | 5 | Journal Credit
sdoSupplierPaymentOnAccount | 6 | Purchase Payment On Account

Applies To

These constants are used in conjunction with the following objects:

Object | Field
RecurringData | TYPE


Recurring Frequency Type Constants

Recurring Frequency Types

Values

The following table lists the constants for the Recurring Frequency Types:

Constant | Value | Description
sdoDays | 0 | Posting made Daily
sdoWeeks | 1 | Posting made Weekly
sdoMonths | 2 | Posting made Monthly

Applies To

These constants are used in conjunction with the following objects:

Object | Field
RecurringData | FREQUENCY_TYPE


To Do Ledger Type Constants

ToDo Ledger Types

Enumeration name

LedgerType

Values

The following table lists the constants for the ToDo Ledger Types:

Constant | Value | Description
sdoLedgerSales | 256 | Sales Ledger (Customers)
sdoLedgerPurchase | 257 | Purchase Ledger (Suppliers)

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.LedgerType

Applies To

These constants are used in conjunction with the following objects:

Object | Field
ToDoData | LEDGER
ToDoRecord | LEDGER


Ledger Constants

Trader Type

Enumeration name

TraderType

Values

The following table lists the constants for the Trader Types:

Constant | Value | Description
sdoCustomer | 0 | Customer
sdoSupplier | 1 | Supplier

Note: To use these constants in Visual Basic .NET, prefix the constant name with SageDataObject300.TraderType

Remarks

These constants are used to return the type of Trader.

Applies To

These constants are used in conjunction with the following objects:

Object | Property
DiaryEvent | Type
DocumentAddress | Type


Cost_Postings

Cost postings allow you to post transactions that affect both the Project.Transactions and the financial accounts. For example, if a purchase is made of stock for a project and the supplier invoices for the goods, you need to post a purchase invoice that shows both on the supplier activity and on the project record.

You can post purchase invoices, purchase credits and bank payments to a project. Cost postings show on the project’s activity as a PI, PC or BP transaction type.

Note: You cannot make a Cost Posting for a specific quantity, as there is no Quantity column available on the Supplier Invoice, Supplier Credit or Bank Payment window. This means that if you post a purchase invoice or credit or a bank payment using the SplitData object's Project property to link the transaction to a particular project, the Project.Transaction does not display a Quantity on the project’s Transactions. If you need a transaction involving a quantity to affect both your project and your accounts, you should post your purchase invoice or credit, or your bank payment, without a project reference. You then need to create a Project Only Cost to post the cost to the project, including the quantity.

Related Topics

To Record Invoices Received from your Suppliers
 To Record Credit Notes you have Received from your Suppliers
 To Record Bank Payments


Examples - Accessing Fields in C# .NET

If you want to access a field on a record using C# you need to pass it a reference to an object containing the Field name rather than a string as you would in Visual Basic.

E.g.

VISUAL BASIC / .NET

oSalesRecord.Fields.Item("ACCOUNT_REF").Value = "ABC"
oSalesRecord.Fields.Item("NAME").Value = "The Sage Group plc";
oSalesRecord.Fields.Item("CONTACT_NAME").Value = "Chris Reed";
oSalesRecord.Fields.Item("TELEPHONE").Value = "0845 1117733";

C#

object AccountRef = "ACCOUNT_REF";
object AccountName = "NAME";
object Contact_Name = "CONTACT_NAME";
object Telephone = "TELEPHONE";

oSalesRecord.Fields.Item(ref AccountRef).value = "ABC";
oSalesRecord.Fields.Item(ref AccountName).Value = "The Sage Group plc";
oSalesRecord.Fields.Item(ref Contact_Name).Value = "Chris Reed";
oSalesRecord.Fields.Item(ref Telephone).Value = "0845 1117733";


Sage 50 Accounts - Example - Display Project Details In A Combobox

Example - Display Project Details In A Combobox

The example code below demonstrates how to display project details in a combobox Visual Basic .NET.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
Public Class Form1

    ' Declare Objects
    Private oSDO As SageDataObject300.SDOEngine
    Private oWS As SageDataObject300.WorkSpace

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        ' Declare Variables
        Dim szDataPath As String

        ' Create the SDOEngine Object
        oSDO = New SageDataObject300.SDOEngine

        ' Create the Workspace
        oWS = oSDO.Workspaces.Add("Example")

        ' Select Company.  The SelectCompany method takes the program install
        ' folder as a parameter
        szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024\")

        ' A U.I. for company selection is presented to the user. If a company is selected,
        ' the path will be passed to the szDataPath variable.
        ' If not, or the Cancel button is selected, the variable will be left empty.
        If szDataPath <> "" Then

            ' Try to Connect - Will Throw an Exception if it Fails
            If oWS.Connect(szDataPath, "", "", "Example") Then

                'User defined Code
                projectcombo()

                ' Disconnect
                oWS.Disconnect()

            End If

        End If

        ' Destroy the Objects
        oWS = Nothing
        oSDO = Nothing

        Exit Sub

    End Sub

    Private Sub projectcombo()

        'Declare Objects
        Dim oProject As SageDataObject300.Project
        Dim oProjects As SageDataObject300.Projects

        ' Instantiate the Projects Buiness objec. collection
        oProjects = oWS.CreateProjects
        oProject = oWS.CreateProject

        ' Loop through each project in the oProject collection
        For Each oProject In oProjects

            ' Add the project to the projectStatusComboBox control
            Me.ComboBox1.Items.Add(oProject.Reference & " " & oProject.Name & " " & oProject.ProjectID)

        Next

    End Sub

End Class
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Project_Combobox_cSharp
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        private SageDataObject300.WorkSpace oWS;
        private void Form1_Load(object sender, EventArgs e)
        {
            //Declare Variables

            String szDataPath;

            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

                ///User Method here
                fillcombo();

                //Disconnect
                oWS.Disconnect();
            }

            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
            }
        }

        private void fillcombo()
        {
            //Declare Objects
            SageDataObject300.Project oProject;
            SageDataObject300.Projects oProjects;

            //Instantiate the projects business object collection
            oProject = (SageDataObject300.Project)oWS.CreateProject();
            oProjects = (SageDataObject300.Projects)oWS.CreateProjects();

            for (int i = 1; i < oProjects.Count + 1; i++)
            {
                Object currProj = i;
                oProject.Load(ref currProj);
                this.comboBox1.Items.Add(oProject.Reference + " " + oProject.Name + " " + oProject.ProjectID);
            }

        }
    }
}


Sage 50 Accounts - Example - Posting a Purchase Credit Note and Allocating it to Outstanding Invoices

Example - Posting a Purchase Credit Note and Allocating it to Outstanding Invoices

The example code below demonstrates how to post a purchase credit note and then allocate it against existing purchase invoices.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code
' Declare Objects
Dim oSDO As SageDataObject300.SDOEngine
Dim oWS As SageDataObject300.WorkSpace
Dim oPurchaseRecord As SageDataObject300.PurchaseRecord
Dim oTransactionPost As SageDataObject300.TransactionPost
Dim oInvoiceSplitData As SageDataObject300.SplitData
Dim oCreditSplitData As SageDataObject300.SplitData
Dim oInvoiceHeaderData As SageDataObject300.HeaderData
Dim oCreditHeaderData As SageDataObject300.HeaderData

' Declare Variables
Dim szDataPath As String
Dim bRecordFound, bAllocated As Boolean
Dim dInvoiceValue, dCreditValue, dAllocateValue, dCreditTotalOutstanding As Double
Dim iSplitCount, iInvoiceTotalOutstanding As Integer

 ' Create the SDO Engine Object
oSDO = New SageDataObject300.SDOEngine

' Create the Workspace
oWS = oSDO.Workspaces.Add("Example")

' Select Company The SelectCompany method takes the program install
' folder as a parameter
szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,
' the path will be passed to the szDataPath variable.
' If not, or the Cancel button is selected, the variable will be left empty.
If szDataPath <> "" Then

' Try to Connect - Will throw an exception if it fails
If oWS.Connect(szDataPath, "", "", "Example") Then

' Create Instance Objects to Post the Credit Note
oPurchaseRecord = oWS.CreateObject("PurchaseRecord")
oTransactionPost = oWS.CreateObject("TransactionPost")
oCreditHeaderData = oWS.CreateObject("HeaderData")

' Initialise Index Field with value to search
oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value = CStr ("CON001")

' Perform Find for an exact match
If oPurchaseRecord.Find(False) Then
' Populate Header fields
' Note:
' The ACCOUNT_REF field must be populated with a valid
' Supplier Account Reference

oTransactionPost.Header("ACCOUNT_REF").Value = CStr (oPurchaseRecord.Fields.Item("ACCOUNT_REF").Value)
oTransactionPost.Header("DATE").Value = CDate(Now)
oTransactionPost.Header("POSTED_DATE").Value = CDate(Now)
oTransactionPost.Header("TYPE").Value = CByte (SageDataObject300.TransType.sdoPC)
oTransactionPost.Header("DETAILS").Value = CStr ("Test Purchase Credit Note")
oTransactionPost.Header("INV_REF").Value = CStr ("CRD001")

' Loop for the Number of Splits
' Note:
' The Transaction can have 1 or many splits

For iSplitCount = 1 To 2

' Add a split to the Header Item's collection
oInvoiceSplitData = oTransactionPost.Items.Add

' Populate Split Fields
oInvoiceSplitData.Fields.Item("TYPE").Value = oTransactionPost.Header("TYPE").Value
oInvoiceSplitData.Fields.Item("NOMINAL_CODE").Value = CStr ("5000")
oInvoiceSplitData.Fields.Item("TAX_CODE").Value = CShort (1)
oInvoiceSplitData.Fields.Item("NET_AMOUNT").Value = CDbl (100)
oInvoiceSplitData.Fields.Item("TAX_AMOUNT").Value = CDbl (17.5)
oInvoiceSplitData.Fields.Item("DATE").Value = CDate (oTransactionPost.Header("DATE").Value)

Next iSplitCount

' Update the TransactionPost Object
If oTransactionPost.Update Then

' Transaction Post Successful
MsgBox("Credit Note transaction Posted successfully.", MsgBoxStyle.OKOnly, "SDO Examples")

' Read the HeaderData for Credit
oCreditHeaderData.Read(oTransactionPost.PostingNumber)

' Create a new Transaction post object
oTransactionPost = Nothing
oTransactionPost = oWS.CreateObject("TransactionPost")

'Calculate the total outstanding on the Credit Note
dCreditTotalOutstanding = CDbl(oCreditHeaderData.Fields.Item("NET_AMOUNT").Value) + CDbl(oCreditHeaderData.Fields.Item("TAX_AMOUNT").Value) - CDbl(oCreditHeaderData.Fields.Item("AMOUNT_PAID").Value)

'Link to the Credit Splits
oCreditSplitData = oCreditHeaderData.Link
oCreditSplitData.MoveFirst()

'Calculate the Credit Split amount outstanding
dCreditValue = CDbl(oCreditSplitData.Fields.Item("NET_AMOUNT").Value) + CDbl(oCreditSplitData.Fields.Item("TAX_AMOUNT").Value) - CDbl(oCreditSplitData.Fields.Item("AMOUNT_PAID").Value)

' Link to Invoice Headers
oInvoiceHeaderData = oPurchaseRecord.Link

' Move to the first Header on the Supplier account
oInvoiceHeaderData.MoveFirst()

' Loop through the Headers until an Invoice that has an outstanding amount is found
Do
iInvoiceTotalOutstanding = CDbl(oInvoiceHeaderData.Fields.Item("NET_AMOUNT").Value) + CDbl(oInvoiceHeaderData.Fields.Item("TAX_AMOUNT").Value) - CDbl(oInvoiceHeaderData.Fields.Item("AMOUNT_PAID").Value)

If Convert.ToByte(oInvoiceHeaderData.Fields.Item("TYPE").Value) = Convert.ToByte(SageDataObject300.TransType.sdoPI) And iInvoiceTotalOutstanding > 0 Then

'Link to Splits
oInvoiceSplitData = oInvoiceHeaderData.Link
oInvoiceSplitData.MoveFirst()

' Calculate the Invoice Split amount outstanding
dInvoiceValue = CDbl(oInvoiceSplitData.Fields.Item("NET_AMOUNT").Value) + CDbl(oInvoiceSplitData.Fields.Item("TAX_AMOUNT").Value) - CDbl(oInvoiceSplitData.Fields.Item("AMOUNT_PAID").Value)

Do

If Math.Round(dInvoiceValue, 2) > 0 Then

' Calculate the amount to allocate
If dInvoiceValue > dCreditValue Then
dAllocateValue = dCreditValue

' Allocate Credit Against Invoice
bAllocated = oTransactionPost.AllocatePayment(CInt(oInvoiceSplitData.RecordNumber), CInt(oCreditSplitData.RecordNumber), CDbl(dAllocateValue), CDate(Now))
dCreditTotalOutstanding - = dAllocateValue
dInvoiceValue - = dAllocateValue
If Not oCreditSplitData.MoveNext() Then

Exit Do
Else
dCreditValue = CDbl(oCreditSplitData.Fields.Item("NET_AMOUNT").Value) + CDbl(oCreditSplitData.Fields.Item("TAX_AMOUNT").Value) - CDbl(oCreditSplitData.Fields.Item("AMOUNT_PAID").Value)

End If
Else
If dInvoiceValue < dCreditValue Then
dAllocateValue = dInvoiceValue

' Allocate Credit Against Invoice
bAllocated = oTransactionPost.AllocatePayment(CInt(oInvoiceSplitData.RecordNumber), CInt(oCreditSplitData.RecordNumber), CDbl(dAllocateValue), CDate(Now))
dCreditTotalOutstanding - = dAllocateValue
dCreditValue - = dAllocateValue
If Not oInvoiceSplitData.MoveNext() Then
Exit Do
Else
dInvoiceValue = CDbl(oInvoiceSplitData.Fields.Item("NET_AMOUNT").Value) + CDbl(oInvoiceSplitData.Fields.Item("TAX_AMOUNT").Value) - CDbl(oInvoiceSplitData.Fields.Item("AMOUNT_PAID").Value)
End If
Else
dAllocateValue = dInvoiceValue

' Allocate Credit Against Invoice
bAllocated = oTransactionPost.AllocatePayment(CInt(oInvoiceSplitData.RecordNumber), CInt(oCreditSplitData.RecordNumber), CDbl(dAllocateValue), CDate(Now))
If Not oCreditSplitData.MoveNext() Then
Exit Do
Else
dCreditValue = CDbl(oCreditSplitData.Fields.Item("NET_AMOUNT").Value) + CDbl(oCreditSplitData.Fields.Item("TAX_AMOUNT").Value) - CDbl(oCreditSplitData.Fields.Item("AMOUNT_PAID").Value)
If Not oInvoiceSplitData.MoveNext() Then
Exit Do
Else
dInvoiceValue = CDbl(oInvoiceSplitData.Fields.Item("NET_AMOUNT").Value) + CDbl(oInvoiceSplitData.Fields.Item("TAX_AMOUNT").Value) - CDbl(oInvoiceSplitData.Fields.Item("AMOUNT_PAID").Value)

End If

End If

End If

End If
Else
 oInvoiceSplitData.MoveNext
dInvoiceValue = CDbl(oInvoiceSplitData.Fields.Item("NET_AMOUNT").Value) + CDbl(oInvoiceSplitData.Fields.Item("TAX_AMOUNT").Value) - CDbl(oInvoiceSplitData.Fields.Item("AMOUNT_PAID").Value)

End If

Loop Until dCreditTotalOutstanding = 0

End If

Loop Until Not oInvoiceHeaderData.MoveNext Or dCreditTotalOutstanding = 0

Else

' Transaction Post Failed
MsgBox("Credit Note transaction Post Failed.", MsgBoxStyle.OKOnly, "SDO Examples")
Exit Sub
End If
End If

' Disconnect
oWS.Disconnect()

End If

End If

' Destroy Objects
oPurchaseRecord = Nothing
oInvoiceHeaderData = Nothing
oInvoiceSplitData = Nothing
oCreditHeaderData = Nothing
oCreditSplitData = Nothing
oTransactionPost = Nothing
oSDO = Nothing
oWS = Nothing

Exit Sub
C#.NET [image] Copy C# Code
No C# example


Sage 50 Accounts - Example - Posting Journal Entries

Example - Posting Journal Entries

The example code below demonstrates how to post Journal Entries using the JournalPost object. The object has been available since the release of Sage 50 Accounts 2015 and is specifically for posting journal transactions. The reason for its creation is to prevent one sided or unbalanced journal entries from being posted. The journal post eradicates the need to create a header for each Journal split that is required and allows an unlimited number of splits to be posted if both the debit and the credit entries balance. The business logic behind the update method then creates the header for each of the splits.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications. The examples are written based on the company data using the standard VAT scheme. If the company you are posting to uses the Vat Cash Accounting scheme please read the following article. If you are posting to a company that uses neither of the above please contact the Developer Services team for further guidance.

VB.NET [image] Copy VB Code

' Declare Objects

Dim oSDO As SageDataObject300.SDOEngine = New SageDataObject300.SDOEngine

Dim oWS As SageDataObject300.WorkSpace

Dim journalPost As SageDataObject300.JournalPost

Dim JCsplit As SageDataObject300.SplitData

Dim JDsplit As SageDataObject300.SplitData

' Declare Variables

Dim szDataPath As String

' Create the Workspace

oWS = oSDO.Workspaces.Add("Example")

' Select Company. The SelectCompany method takes the program install

' folder as a parameter

szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

' A U.I. for company selection is presented to the user. If a company is selected,

' the path will be passed to the szDataPath variable.

' If not, or the Cancel button is selected, the variable will be left empty.

If szDataPath <> "" Then

' Try to Connect - Will Throw an Exception if it Fails

If oWS.Connect(szDataPath, "", "", "Example") Then

'Create an intstance of the JournalPost object

journalPost = oWS.CreateObject("JOURNALPOST")

'Set the Header Values

journalPost.Header("DATE").Value = Date.Today

journalPost.Header("INV_REF").Value = "JournlaPost Posting"

'add as many splits as you require, they need to balance though!

JCsplit = journalPost.Items.Add

JCsplit.Fields.Item("TYPE").Value = SageDataObject300.TransType.sdoJC

'Set the other values

JCsplit.Fields.Item("NOMINAL_CODE").Value = CStr("4000")

JCsplit.Fields.Item("Details").Value = CStr("JournalPostJC")

JCsplit.Fields.Item("TAX_CODE").Value = CInt(9)

JCsplit.Fields.Item("TAX_AMOUNT").Value = CDbl(0)

JCsplit.Fields.Item("NET_AMOUNT").Value = CDbl(100)

'add as many splits as you require, they need to balance though!

JCsplit = journalPost.Items.Add

JCsplit.Fields.Item("TYPE").Value = SageDataObject300.TransType.sdoJC

'Set the other values

JCsplit.Fields.Item("NOMINAL_CODE").Value = CStr("4001")

JCsplit.Fields.Item("Details").Value = CStr("JournalPostJC")

JCsplit.Fields.Item("TAX_CODE").Value = CInt(9)

JCsplit.Fields.Item("TAX_AMOUNT").Value = CDbl(0)

JCsplit.Fields.Item("NET_AMOUNT").Value = CDbl(100)

'add as many splits as you require, they need to balance though!

JDsplit = journalPost.Items.Add

JDsplit.Fields.Item("TYPE").Value = SageDataObject300.TransType.sdoJD

'Set the other values

JDsplit.Fields.Item("NOMINAL_CODE").Value = CStr("4000")

JDsplit.Fields.Item("Details").Value = CStr("JournalPostJD")

JDsplit.Fields.Item("TAX_CODE").Value = CInt(9)

JDsplit.Fields.Item("TAX_AMOUNT").Value = CDbl(0)

JDsplit.Fields.Item("NET_AMOUNT").Value = CDbl(100)

'add as many splits as you require, they need to balance though!

JDsplit = journalPost.Items.Add

JDsplit.Fields.Item("TYPE").Value = SageDataObject300.TransType.sdoJD

'Set the other values

JDsplit.Fields.Item("NOMINAL_CODE").Value = CStr("4001")

JDsplit.Fields.Item("Details").Value = CStr("JournalPostJD")

JDsplit.Fields.Item("TAX_CODE").Value = CInt(9)

JDsplit.Fields.Item("TAX_AMOUNT").Value = CDbl(0)

JDsplit.Fields.Item("NET_AMOUNT").Value = CDbl(100)

If journalPost.Update() Then

Console.WriteLine("Journal Posted")

Console.ReadLine()

Else

Console.WriteLine("Unable to Post")

Console.ReadLine()

End If

End If

End If

'Marshal objects to be released ensuring they are picked up by the GC

System.Runtime.InteropServices.Marshal.FinalReleaseComObject(oSDO)

oSDO = Nothing

System.Runtime.InteropServices.Marshal.FinalReleaseComObject(oWS)

oWS = Nothing

System.Runtime.InteropServices.Marshal.FinalReleaseComObject(JCsplit)

JCsplit = Nothing

System.Runtime.InteropServices.Marshal.FinalReleaseComObject(JDsplit)

JDsplit = Nothing

System.Runtime.InteropServices.Marshal.FinalReleaseComObject(journalPost)

journalPost = Nothing
C#.NET [image] Copy C# Code

//Declare Variables

SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();

SageDataObject300.WorkSpace oWS;

SageDataObject300.SplitData jcSplit;

SageDataObject300.SplitData jdSplit;

SageDataObject300.JournalPost journalPost;

String szDataPath;

//Instantiate WorkSpace

oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog

szDataPath = oSDO.SelectCompany(@"C:\ProgramData\Sage\Accounts\2024");

//Try a connection, will throw an exception if it fails

try

{

    //Leaving the username and password blank generates a login dialog

    oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");

    Console.WriteLine("Connected");

    journalPost = oWS.CreateObject("JournalPost") as SageDataObject300.JournalPost;

    //Populate Header information

    SDOHelper.Write(journalPost.Header, "DATE", DateTime.Today);

    SDOHelper.Write(journalPost.Header, "INV_REF", "JournalPost Test");

    //Add as many splits as required as the header for each is auto generated and the

    //journal will only post if it balances unlike a Journal posted through transaction post

    //The Split must be added as a JournalPost Item

    jcSplit = journalPost.Items.Add;

    //Set the transaction type

    SDOHelper.Write(jcSplit, "TYPE", SageDataObject300.TransType.sdoJC);

    // Set the other values

    SDOHelper.Write(jcSplit, "NOMINAL_CODE", (String)"4000");

    SDOHelper.Write(jcSplit, "DETAILS", (String)"JOURNALPOST JC");

    SDOHelper.Write(jcSplit, "TAX_CODE", (Int32)9);

    SDOHelper.Write(jcSplit, "NET_AMOUNT", (Double)100);

    SDOHelper.Write(jcSplit, "TAX_AMOUNT", (Double)0);

    //Add as many splits as required as the header for each is auto generated and the

    //journal will only post if it balances unlike a Journal posted through transaction post

    //The Split must be added as a JournalPost Item

    jcSplit = journalPost.Items.Add;

    //Set the transaction type

    SDOHelper.Write(jcSplit, "TYPE", SageDataObject300.TransType.sdoJC);

    // Set the other values

    SDOHelper.Write(jcSplit, "NOMINAL_CODE", (String)"4001");

    SDOHelper.Write(jcSplit, "DETAILS", (String)"JOURNALPOST JC");

    SDOHelper.Write(jcSplit, "TAX_CODE", (Int32)9);

    SDOHelper.Write(jcSplit, "NET_AMOUNT", (Double)100);

    SDOHelper.Write(jcSplit, "TAX_AMOUNT", (Double)0);

    //Add as many splits as required as the header for each is auto generated and the

    //journal will only post if it balances unlike a Journal posted through transaction post

    //The Split must be added as a JournalPost Item

    jdSplit = journalPost.Items.Add;

    //Set the transaction type

    SDOHelper.Write(jdSplit, "TYPE", SageDataObject300.TransType.sdoJD);

    // Set the other values

    SDOHelper.Write(jdSplit, "NOMINAL_CODE", (String)"4001");

    SDOHelper.Write(jdSplit, "DETAILS", (String)"JOURNALPOST JD");

    SDOHelper.Write(jdSplit, "TAX_CODE", (Int32)9);

    SDOHelper.Write(jdSplit, "NET_AMOUNT", (Double)100);

    SDOHelper.Write(jdSplit, "TAX_AMOUNT", (Double)0);

    //Add as many splits as required as the header for each is auto generated and the

    //journal will only post if it balances unlike a Journal posted through transaction post

    //The Split must be added as a JournalPost Item

    jdSplit = journalPost.Items.Add;

    //Set the transaction type

    SDOHelper.Write(jdSplit, "TYPE", SageDataObject300.TransType.sdoJD);

    // Set the other values

    SDOHelper.Write(jdSplit, "NOMINAL_CODE", (String)"4000");

    SDOHelper.Write(jdSplit, "DETAILS", (String)"JOURNALPOST JD");

    SDOHelper.Write(jdSplit, "TAX_CODE", (Int32)9);

    SDOHelper.Write(jdSplit, "NET_AMOUNT", (Double)100);

    SDOHelper.Write(jdSplit, "TAX_AMOUNT", (Double)0);

    /*Post the Journal transaction

if the Update method returns false, ensure the Nominal Codes Exist

 * and the Debits and credits balance*/

    if (journalPost.Update())

    {

        Console.WriteLine("Journal Posted");

        Console.ReadLine();

    }

    else

    {

        Console.WriteLine("Failed to post");

        Console.ReadLine();

    }

    oWS.Disconnect();

}

catch (Exception ex)

{

    Console.WriteLine("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

    Console.ReadLine();

}

//Marshal objects to be released ensuring they are picked up by the GC

System.Runtime.InteropServices.Marshal.FinalReleaseComObject(oSDO);

oSDO = null;

System.Runtime.InteropServices.Marshal.FinalReleaseComObject(oWS);

oWS = null;

System.Runtime.InteropServices.Marshal.FinalReleaseComObject(jcSplit);

jcSplit = null;

System.Runtime.InteropServices.Marshal.FinalReleaseComObject(jdSplit);

jdSplit = null;

System.Runtime.InteropServices.Marshal.FinalReleaseComObject(journalPost);

journalPost = null;


Sage 50 Accounts - Example - Reading The Last Diary Event

Example - Reading The Last Diary Event

The example code below demonstrates how to read the last New DiaryEvent. The output is written to a listView (listView1) which would need to be added to your form prior to running this code.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. The code is also assuming the use of a Helper Class, if you have not already done so we would advise reading Considerations When Using C# before continuing. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
     'declare objects
     Dim oSDO As SageDataObject300.SDOEngine
     Dim oWS As SageDataObject300.WorkSpace
     Dim oCustomer As SageDataObject300.Customer
     Dim oDiaryEvent As SageDataObject300.DiaryEvent
     Dim oDiaryEvents As SageDataObject300.DiaryEvents
     Dim oDiaryEventLabel As SageDataObject300.DiaryEventLabel
     Dim oDiaryRecurrencePattern As SageDataObject300.DiaryRecurrencePattern
     Dim oSalesRecord As SageDataObject300.SalesRecord

     ' Declare Variables
     Dim szDataPath As String
     Dim lvitem As ListViewItem

     ' Create the SDO Engine object
     oSDO = New SageDataObject300.SDOEngine

     ' Create the workspace
     oWS = oSDO.Workspaces.Add("SageExample")

     ' Select company. The SelectCompany method takes the program install
     ' folder as a parameter
     szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

     ' A U.I. for company selection is presented to the user. If a company 'is selected,
     ' the path will be passed to the szDataPath variable.
     ' If not, or the Cancel button is selected, the variable will be left 'empty.
     If szDataPath <> "" Then

         Try

             ' Connect to Data Files
             If oWS.Connect(szDataPath, "", "", "Sage Example") Then

                 'Instantiate the Objects
                 oCustomer = oWS.CreateCustomer
                 oDiaryEvent = oWS.CreateDiaryEvent
                 oDiaryEvents = oWS.CreateDiaryEvents
                 oDiaryEventLabel = oWS.CreateDiaryEventLabel
                 oDiaryRecurrencePattern = oWS.CreateDiaryRecurrencePattern
                 oSalesRecord = oWS.CreateObject("SALESRECORD")

                 'Locate the SalesRecord to set the Customer object to
                 oSalesRecord.Fields.Item("ACCOUNT_REF").Value = "AAAA"

                 If oSalesRecord.Find(False) Then

                     'Load the Customer place holder object by passing the SalesRecord Account Reference
                     oCustomer.Load(oSalesRecord.Fields.Item("ACCOUNT_REF").Value)

                     MessageBox.Show("Customer has been located")

                     'Load the Diary Event Label(The Appointment Label Type has been selected for this example)
                     oDiaryEventLabel.Load(2)

                     'Read the last diary properties
                     oDiaryEvent.Load(oDiaryEvents.Count - 1)

                     lvitem = New ListViewItem

                     lvitem.Text = oDiaryEvent.AccountContact
                     lvitem.SubItems.Add(Convert.ToString(oDiaryEvent.AccountType))
                     lvitem.SubItems.Add((oDiaryEvent.Customer).Reference)
                     lvitem.SubItems.Add(Convert.ToString(oDiaryEvent.EndTime))
                     lvitem.SubItems.Add(Convert.ToString(oDiaryEvent.HasReminder))
                     lvitem.SubItems.Add(Convert.ToString(oDiaryEvent.IsAllDayEvent))
                     lvitem.SubItems.Add(Convert.ToString(oDiaryEvent.IsDeletedOccurrence))
                     lvitem.SubItems.Add((oDiaryEvent.Label).Name)
                     lvitem.SubItems.Add(Convert.ToString(oDiaryEvent.Location))
                     lvitem.SubItems.Add(Convert.ToString(oDiaryEvent.NextReminderTime))
                     lvitem.SubItems.Add(Convert.ToString(oDiaryEvent.OccurrenceType))
                     lvitem.SubItems.Add(Convert.ToString(oDiaryEvent.OriginalEndTime))
                     lvitem.SubItems.Add(Convert.ToString(oDiaryEvent.OriginalStartTime))
                     lvitem.SubItems.Add(Convert.ToString(((oDiaryEvent.RecurrencePattern).UniqueID)))
                     lvitem.SubItems.Add(Convert.ToString(oDiaryEvent.ReminderMinutesBeforeStart))
                     lvitem.SubItems.Add(Convert.ToString(oDiaryEvent.StartTime))
                     lvitem.SubItems.Add(Convert.ToString(oDiaryEvent.Subject))
                     lvitem.SubItems.Add(Convert.ToString(oDiaryEvent.Supplier))
                     lvitem.SubItems.Add(Convert.ToString(oDiaryEvent.UniqueID))
                     lvitem.SubItems.Add(Convert.ToString(oDiaryEvent.UserName))

                     ListView1.Items.Add(lvitem)

                 Else

                     MessageBox.Show("Could not find SalesRecord")

                 End If

             End If

         Catch ex As Exception
             MessageBox.Show("The SDO generated the following error: " & ex.Message, "SDO Examples", MessageBoxButtons.OK, MessageBoxIcon.Error)

         Finally
             'Disconnect
             oWS.Disconnect()

         End Try
     End If
C#.NET [image] Copy C# Code
//Declare Objects
SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
SageDataObject300.WorkSpace oWS;
SageDataObject300.Customer oCustomer;
SageDataObject300.DiaryEvent oDiaryEvent;
SageDataObject300.DiaryEvents oDiaryEvents;
SageDataObject300.DiaryEventLabel oDiaryEventLabel;
SageDataObject300.DiaryRecurrencePattern oDiaryRecurrencePattern;
SageDataObject300.SalesRecord oSalesRecord;

//Declare variables
String szDataPath;

//Instantiate WorkSpace
oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

//Show select company dialog, taking the path to the company file as a parameter
szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");

//If the select company screen is cancelled a blank string is returned to szDataPath
if (szDataPath != string.Empty)
{

    //Try a connection, will throw an exception if it fails
    try
    {
        //Leaving the username and password blank generates a login dialog
        oWS.Connect(szDataPath, "", "", "Example");

        //Instantiate Sales Record Object
        oCustomer = (SageDataObject300.Customer)oWS.CreateCustomer();
        oDiaryEvent = (SageDataObject300.DiaryEvent)oWS.CreateDiaryEvent();
        oDiaryEvents = (SageDataObject300.DiaryEvents)oWS.CreateDiaryEvents();
        oDiaryEventLabel = (SageDataObject300.DiaryEventLabel)oWS.CreateDiaryEventLabel();
        oDiaryRecurrencePattern = (SageDataObject300.DiaryRecurrencePattern)oWS.CreateDiaryRecurrencePattern();
        oSalesRecord = (SageDataObject300.SalesRecord)oWS.CreateObject("SalesRecord");

        //Locate the SalesRecord to set the Customer object to.
        SDOHelper.Write(oSalesRecord, "ACCOUNT_REF", (String)"AAAA");

        //If the SalesRecord is found

        if (oSalesRecord.Find(false))
        {
            //Load the Customer place holder object by passing in the SalesRecord Account Ref
            Object customer = (String)SDOHelper.Read(oSalesRecord, "ACCOUNT_REF");

            oCustomer.Load(ref customer);

            MessageBox.Show("Customer has been located");

            //Load the Diary Event Label(The Appointment Label Type has been selected for this example)
            Object oType;
            oType = 2;
            oDiaryEventLabel.Load(ref oType);

            //Read the last Diary Properties
            Object oLastEvent;
            oLastEvent = oDiaryEvents.Count;
            oDiaryEvent.Load(ref oLastEvent);

            ListViewItem lvitem = new ListViewItem();

            lvitem.Text = oDiaryEvent.AccountContact;
            lvitem.SubItems.Add(Convert.ToString(oDiaryEvent.AccountType));
            lvitem.SubItems.Add(((SageDataObject300.Customer)oDiaryEvent.Customer).Reference);
            lvitem.SubItems.Add(Convert.ToString(oDiaryEvent.EndTime));
            lvitem.SubItems.Add(Convert.ToString(oDiaryEvent.HasReminder));
            lvitem.SubItems.Add(Convert.ToString(oDiaryEvent.IsAllDayEvent));
            lvitem.SubItems.Add(Convert.ToString(oDiaryEvent.IsDeletedOccurrence));
            lvitem.SubItems.Add(((SageDataObject300.DiaryEventLabel)oDiaryEvent.Label).Name);
            lvitem.SubItems.Add(Convert.ToString(oDiaryEvent.Location));
            lvitem.SubItems.Add(Convert.ToString(oDiaryEvent.NextReminderTime));
            lvitem.SubItems.Add(Convert.ToString(oDiaryEvent.OccurrenceType));
            lvitem.SubItems.Add(Convert.ToString(oDiaryEvent.OriginalEndTime));
            lvitem.SubItems.Add(Convert.ToString(oDiaryEvent.OriginalStartTime));
            lvitem.SubItems.Add(Convert.ToString((((SageDataObject300.DiaryRecurrencePattern)oDiaryEvent.RecurrencePattern).UniqueID)));
            lvitem.SubItems.Add(Convert.ToString(oDiaryEvent.ReminderMinutesBeforeStart));
            lvitem.SubItems.Add(Convert.ToString(oDiaryEvent.StartTime));
            lvitem.SubItems.Add(Convert.ToString(oDiaryEvent.Subject));
            lvitem.SubItems.Add(Convert.ToString(oDiaryEvent.Supplier));
            lvitem.SubItems.Add(Convert.ToString(oDiaryEvent.UniqueID));
            lvitem.SubItems.Add(Convert.ToString(oDiaryEvent.UserName));

            listView1.Items.Add(lvitem);

        }

        else
        {
            MessageBox.Show("Could not find SalesRecord");
        }

        //Disconnect
        oWS.Disconnect();

    }
    catch (Exception ex)
    {

        MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");

    }
    finally
    {
        //Disconnect
        oWS.Disconnect();
    }
}


Sage 50 Accounts - Example - Using Document Link

Example - Using Document Link

The example code below demonstrates how to use the DocumentLink object. It demonstrates setting the values on the IDocumentLink object. Then looping through the SplitData to enable the link to be visible on the Transactions List area of the Sage 50 Accounts program UI.

As with all the examples in this help file, the code below uses the SelectCompany method of the SDOEngine object to allow the user to select a data set. You should also note that although values are hard coded in the example, we always typecast any value passed to an SDO field - we recommend that you follow this practice in your own applications.

VB.NET [image] Copy VB Code
Public Class Form1

    'Declare Class level objects
    Dim oSDO As New SageDataObject300.SDOEngine()
    Dim oWS As SageDataObject300.WorkSpace
    Dim oHeaderData As SageDataObject300.HeaderData
    Dim oSplitData As SageDataObject300.SplitData
    Dim oDocumentLink As SageDataObject300.IDocumentLink

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        connectToData()
        userDefinedMethod()

    End Sub

    Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing

        oWS.Disconnect()
        'Destroy Objects
        oDocumentLink = Nothing
        oHeaderData = Nothing
        oSplitData = Nothing
        oWS = Nothing
        oSDO = Nothing

    End Sub

    Private Function connectToData() As [Boolean]

        Dim szDataPath As String

        'Instantiate WorkSpace
        oWS = DirectCast(oSDO.Workspaces.Add("Example"), SageDataObject300.WorkSpace)

        'Show select company dialog
        szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2023")
        'Try a connection, will throw an exception if it fails
        Try
            'Leaving the username and password blank generates a login dialog
            oWS.Connect(szDataPath, "", "", "SDO EXAMPLE")
            Return True

        Catch ex As Exception
            MessageBox.Show("SDO Generated the Following Error: " & ex.Message, "Error!")
            Return False
        End Try

    End Function

    Private Sub userDefinedMethod()
        'Instantiate the required objects
        oDocumentLink = DirectCast(oWS.CreateObject("DocumentLink"), SageDataObject300.IDocumentLink)
        oHeaderData = DirectCast(oWS.CreateObject("HeaderData"), SageDataObject300.HeaderData)
        oSplitData = DirectCast(oWS.CreateObject("SplitData"), SageDataObject300.SplitData)

        'Load the required transaction
        oDocumentLink.Load(3)

        'Set the DocumentLink property as required
        oDocumentLink.DocumentLink = "C:\sdo list.txt"

        'Update the object
        Try
            oDocumentLink.Update()
        Catch ex As Exception
            MessageBox.Show(ex.Message)
            Return
        End Try

        'Iterate HeaderData
        oHeaderData.MoveFirst()
        oHeaderData.Fields.Item("HAS_EXTERNAL_LINK").Value = 1
        oSplitData = oHeaderData.Link

        'Iterate SplitData
        oSplitData.MoveFirst()

        Do
            'Check to find the required transaction
            If CInt(oSplitData.Fields.Item("TRAN_NUMBER").Value) = oDocumentLink.TransactionID Then
                'Set the "HAS_EXTERNAL_LINK" property to make the Ext Link available on the Transactions List
                oSplitData.Fields.Item("HAS_EXTERNAL_LINK").Value = 1
                oSplitData.Write(oSplitData.RecordNumber)
            End If

        Loop While oSplitData.MoveNext()

    End Sub

End Class
C#.NET [image] Copy C# Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ExampleDocumentLink
{
    public partial class Form1 : Form
    {

        //Declare Class level objects
        SageDataObject300.SDOEngine oSDO = new SageDataObject300.SDOEngine();
        SageDataObject300.WorkSpace oWS;
        SageDataObject300.HeaderData oHeaderData;
        SageDataObject300.SplitData oSplitData;
        SageDataObject300.IDocumentLink oDocumentLink;
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            connectToData();
            userDefinedMethod();
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            oWS.Disconnect();
        }

        Boolean connectToData()
        {
            string szDataPath;

            //Instantiate WorkSpace
            oWS = (SageDataObject300.WorkSpace)oSDO.Workspaces.Add("Example");

            //Show select company dialog
            szDataPath = oSDO.SelectCompany("C:\\ProgramData\\Sage\\Accounts\\2024");
            //Try a connection, will throw an exception if it fails
            try
            {
                //Leaving the username and password blank generates a login dialog
                oWS.Connect(szDataPath, "", "", "SDO EXAMPLE");
                return true;
            }

            catch (Exception ex)
            {
                MessageBox.Show("SDO Generated the Following Error: \n\n" + ex.Message, "Error!");
                return false;
            }
        }

        private void userDefinedMethod()
        {
            //Instantiate the required objects
            oDocumentLink = (SageDataObject300.IDocumentLink)oWS.CreateObject("DocumentLink");
            oSplitData = (SageDataObject300.SplitData)oWS.CreateObject("SplitData");
            oHeaderData = (SageDataObject300.HeaderData)oWS.CreateObject("HeaderData");

            //Load the required transaction
            oDocumentLink.Load(3);

            //Set the DocumentLink property as required
            oDocumentLink.DocumentLink = @"C:\sdo list.txt";

            //Update the object
            try
            {
                oDocumentLink.Update();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return;
            }

            //Iterate HeaderData
            oHeaderData.MoveFirst();

            oHeaderData.Fields.Item("HAS_EXTERNAL_LINK").Value = 1;

            oSplitData = oHeaderData.Link;

            //Iterate SplitData
            oSplitData.MoveFirst();

            do
            {
                //Check to find the required transaction
                if ((int)(oSplitData.Fields.Item("TRAN_NUMBER").Value) == oDocumentLink.TransactionID)
                {
                    //Set the "HAS_EXTERNAL_LINK" property to make the Ext Link available on the Transactions List
                    oSplitData.Fields.Item("HAS_EXTERNAL_LINK").Value = 1;
                    oSplitData.Write(oSplitData.RecordNumber);
                }
            }

            while (oSplitData.MoveNext());

        }

    }
}


Examples - Visual Basic .NET

These examples demonstrate how to use the Report Desgner API.

  • General

Implementing The IReportingEngineHost

Getting Report Information

Example_Previewing_A_Report.htm

Example_Exporting_A_Report.htm

Example_Opening_The_Report_Browser.htm


Add Method

Description

The Add method allows a new item to be added to a collection.

Syntax

The AddNew method has the following syntax:

object.Add

with the following parts:

Part | Description
Object | Applies to one of the following types: SDOIndex and Workspace

Return Value(s)

The Add method returns the following values:

Value | Description
True | The method was successful and a new item added to the collection.
False | The method was unsuccessful, a new item cannot be added.

Examples

This example uses the Add method in conjunction with Workspaces collection.

    ' Error Handler
On Error GoTo Error_Handler

' Declare Objects
Dim oSDO As
  SageDataObject300.SDOEngine
Dim oWS As
  SageDataObject300.WorkSpace

' Create the SDO Engine Object
Set oSDO =  New
  SageDataObject300.SDOEngine

' Create the Workspace
Set oWS = oSDO.Workspaces.Add("Example")

' Destroy Objects
Set oWS =  Nothing
Set oSDO =  Nothing

Exit Sub

' Error Handling Code
Error_Handler:
MsgBox "The SDO generated the following error: " &
    oSDO.LastError.Text


CreateCustomerAddress Method

CreateContactHistory Method

Description

The CreateContactHistory method is used to create an object of the type Contacthistory.

Syntax

The CreateContactHistory method has the following syntax:

Object.CreateContactHistory

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Value

The CreateContactHistory method returns the following value:

Return Value | Description
ContactHistory | An object of type SageDataObjectN.ContactHistory (N denotes SDO version e.g. 180)

Remarks

You should always destroy any objects you create by setting them to Nothing.

Examples Using this Object

View Contact History Properties
Edit a Contact History Item
Create New Contact History Item


CreateCustomer Method

CreateContactHistorys Method

Description

The CreateContactHistorys method is used to create an object of the type ContactHistorys.

Syntax

The CreateContactHistorys method has the following syntax:

Object.CreateContactHistorys

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Value

The CreateContactHistorys method returns the following value:

Return Value | Description
ContactHistorys | An object of type SageDataObjectN.ContactHistorys (N denotes SDO version e.g. 180)

Remarks

You should always destroy any objects you create by setting them to Nothing.

Examples Using this Object

View Contact History Properties
Edit a Contact History Item
Create New Contact History Item


CreateDiaryRecurrencePattern Method

Description

The CreateDiaryRecurrencePattern method is used to create an object of the type DiaryRecurrencePattern.

Syntax

The CreateDiaryRecurrencePattern method has the following syntax:

Object.Create DiaryRecurrencePattern

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Value

The CreateCustomer method returns the following value:

Return Value | Description
DiaryRecurrencePattern | An object of type SageDataObjectN.DiaryRecurrencePattern (N denotes SDO version e.g. 180)

Remarks

You should always destroy any objects you create by setting them to Nothing.

Examples Using This Object

There are currently no examples using this method.


CustomerUnitPrice Method

Description

The CustomerUnitPrice method calculates the price of a product for a given customer, taking into account any customer special prices or price list prices where applicable

Syntax

The CustomerUnitPrice method has the following syntax:

object.CustomerUnitPrice CustomerAccountReference, StockCode

with the following parts:

Part | Description
Object | Applies to the Pricing Object
CustomerAccountReference | The account reference for the customer the calculation is for
StockCode | The stock code for the product price to be calculated

Return Value

The CustomerUnitPrice method returns the following value:

Value | Description
Unit Price | Returns a double giving the unit price in the base currency without any quantity or value discount being applied

Examples

This example uses the CustomerUnitPrice method.

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oPricing As SageDataObject300.Pricing

  ' Declare Variables
  Dim szDataPath As String
  Dim dPrice As Double

  ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then
    ' Connect to Data Files
    oWS.Connect szDataPath, "", "", "Example"

    ' Create instance of the Pricing Object
    oWS.CreateObject("Pricing")

    ' Get the Price
    dPrice = oPricing.CustomerUnitPrice("ABB001", "ENV001")

  End If

  ' Destroy Objects
  Set oWS = Nothing
   Set oSDO = Nothing
   Set oPricing = Nothing

  Exit Sub

' Error Handling Code
 Error_Handler:
  MsgBox "The SDO generated the following error: " & oSDO.LastError.Text


ProgramType Method

Description

The ProgramType method enables you to determine which Sage 50 Accounts product is installed, i.e. Accounts, Accounts Plus or Professional.

Syntax

The ProgramType method has the following syntax:

object.ProgramType

with the following parts:

Part | Description
Object | Applies to the Workspace object.

Return Value(s)

The ProgramType method returns the following values:

Return Value | Description
1 | Professional
4 | Standard
64 | Essentials

Remarks

Prior to calling the ProgramType method, you must have a valid connection in place.

Example

The following example demonstrates the use of the ProgramType method:

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace

  ' Declare Variables
  Dim szDataPath As String
  ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

    ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
   If szDataPath <> "" Then

    ' Connect to Data Files
    If oWS.Connect(szDataPath, "", "", "Example") Then

      ' Show the Program Type
      Select Case oWS.ProgramType

        Case Is = sdoProgramFinCon
          MsgBox "Professional"

        Case Is = sdoProgramAccount
          MsgBox "Standard"

        Case Is = sdoProgramInstplus
          MsgBox "Essentials"

      End Select

      ' Disconnect
      oWS.Disconnect

    End If

  End If

  ' Destroy Objects
  Set oWS = Nothing
  Set oSDO = Nothing

  Exit Sub

 ' Error Handling Code
Error_Handler:

  MsgBox "The SDO generated the following error: " & oSDO.LastError.Text


SupplierUnitPrice Method

Description

The SupplierUnitPrice method calculates the price of a product for a given Supplier, taking into account any Supplier price list prices where applicable

Syntax

The SupplierUnitPrice method has the following syntax:

object.SupplierUnitPrice SupplierAccountReference, StockCode

with the following parts:

Part | Description
Object | Applies to the Pricing Object
SupplierAccountReference | The account reference for the Supplier the calculation is for
StockCode | The stock code for the product price to be calculated

Return Value

The SupplierUnitPrice method returns the following value:

Value | Description
Unit Price | Returns a double giving the unit price in the Supplier's currency without any quantity or value discount being applied

Examples

This example uses the SupplierUnitPrice method.

  ' Error Handler
  On Error GoTo Error_Handler

  ' Declare Objects
  Dim oSDO As SageDataObject300.SDOEngine
  Dim oWS As SageDataObject300.WorkSpace
  Dim oPricing As SageDataObject300.Pricing

  ' Declare Variables
  Dim szDataPath As String
  Dim dPrice As Double

  ' Create the SDO Engine Object
  Set oSDO = New SageDataObject300.SDOEngine

  ' Create the Workspace
  Set oWS = oSDO.Workspaces.Add("Example")

  ' Select Company. The SelectCompany method takes the program install
  ' folder as a parameter
  szDataPath = oSDO.SelectCompany("C:\ProgramData\Sage\Accounts\2024")

  ' A U.I. for company selection is presented to the user. If a company is selected,
  ' the path will be passed to the szDataPath variable.
  ' If not, or the Cancel button is selected, the variable will be left empty.
  If szDataPath <> "" Then
    ' Connect to Data Files
    oWS.Connect szDataPath, "", "", "Example"

    ' Create instance of the Pricing Object
    oWS.CreateObject("Pricing")

    ' Get the Price
    dPrice = oPricing.SupplierUnitPrice("ABB001", "ENV001")

  End If

  ' Destroy Objects
  Set oWS = Nothing
   Set oSDO = Nothing
  Set oPricing = Nothing

  Exit Sub

' Error Handling Code
 Error_Handler:
  MsgBox "The SDO generated the following error: " & oSDO.LastError.Text


Objects Applicable to Programs

Objects Applicable to Program Versions

The table below list the objects that are applicable to the various versions of Sage 50 Accounts:

Object

Essentials

Standard

Professional
AccessData | Y | Y | Y
AccountStatusData | Y | Y | Y
AccrualData | Y | Y
AgedBalances

Y

 Y Y
AssetCategory | Y | Y | Y
AssetData | Y | Y | Y
AssetIndex | Y | Y | Y
AssetRecord | Y | Y | Y
BankData | Y | Y | Y
BankHeaderData | Y | Y | Y
BankIndex | Y | Y | Y
BankRecord | Y | Y | Y
BankRemittanceData | Y | Y | Y
BankRemittanceIndex | Y | Y | Y
BankRemittanceRecord | Y | Y | Y
BankWWWData | Y | Y | Y
BillData | Y | Y | Y
Category | Y | Y | Y
ChartData | Y | Y | Y
CharityFund | Y | Y | Y
CharityFundType | Y | Y | Y
CompanyDeliveryData | Y | Y
CompanyDeliveryIndex | Y | Y
CompanyDeliveryRecord | Y | Y
ContactAccountIdxRecord | Y | Y | Y
ContactAccountIndex | Y | Y | Y
ContactData | Y | Y | Y
ContactDateIdxRecord | Y | Y | Y
ContactDateIndex | Y | Y | Y
ControlData | Y | Y | Y
CountryCodeData | Y | Y | Y
CountryCodeIndex | Y | Y | Y
CountryCodeRecord | Y | Y | Y
CourierWWWData | Y | Y | Y
CreditChargeData | Y | Y | Y
CreditWWWData | Y | Y | Y
CurrencyData | Y | Y | Y
Customer | Y | Y
Department | Y | Y
DepartmentData | Y | Y | Y
GDNData | Y
GDNIndex | Y
GDNRecord | Y
HeaderData | Y | Y | Y
InvoiceData | Y | Y
InvoiceIndex | Y | Y
InvoiceItem | Y | Y
InvoicePost | Y | Y
InvoiceRecord | Y | Y
MiscWWWData | Y | Y | Y
Nominal | Y | Y
NominalData | Y | Y | Y
NominalIndex | Y | Y | Y
NominalRecord | Y | Y | Y
POPData | Y
POPIndex | Y
POPItem | Y
POPPost | Y
POPRecord | Y
PrepayData | Y | Y
PriceData | Y | Y
PriceIndex | Y | Y
PriceRecord | Y | Y
PriceListData | Y | Y
PriceListIndex | Y | Y
PriceListRecord | Y | Y
PurchaseDeliveryData | Y | Y
PurchaseDeliveryIndex | Y | Y
PurchaseDeliveryRecord | Y | Y
PurchaseData | Y | Y | Y
PurchaseIndex | Y | Y | Y
PurchaseRecord | Y | Y | Y
QueueData | Y | Y | Y
RecurringData | Y | Y | Y
RemittanceData | Y | Y | Y
RemittanceIndex | Y | Y | Y
RemittanceRecord | Y | Y | Y
SalesDeliveryData | Y | Y
SalesDeliveryIndex | Y | Y
SalesDeliveryRecord | Y | Y
SalesData | Y | Y | Y
SalesIndex | Y | Y | Y
SalesRecord | Y | Y | Y
SetupData | Y | Y | Y
SOPData | Y
SOPIndex | Y
SOPItem | Y
SOPPost | Y
SOPRecord | Y
SplitData | Y | Y | Y
StockCategory | Y | Y
StockData | Y | Y
StockIndex | Y | Y
StockPost | Y | Y
StockRecord | Y | Y
StockTran | Y | Y
Supplier | Y | Y
ToDoData | Y | Y | Y
ToDoIndex | Y | Y | Y
ToDoRecord | Y | Y | Y
TransactionPost | Y | Y | Y
UsageData | Y | Y | Y


Field Object

Description

The Field object represents a single piece of data within a single record of a Sage 50 Accounts file object. You use the Field object to access or change the data held within a record.

Field objects are not creatable but you can declare a variable as a Field object to allow you to store a reference to a Field object.

Properties

The Field object has the following properties:

Property | Description
DecimalPlaces | Returns the number of decimal places the field has.
Description | Returns the Description for the field.
Length | Returns the length of the field in bytes.
Name | Returns the name of the field.
State | Returns the state of the field (Optional, Required etc.)
Type | Returns the type of the field.
Value | Returns the value of the field.


Known Issues

Introduction

There are no known issues at present.


Project_Only_Costs

Project Only Costs enable you to record costs incurred when work is carried out on a project. For example, you might post a Project Only Cost for labour costs, using the number of hours’ work and the hourly rate shown on timesheets submitted by a contractor.

You can also use Project Only Costs to enter costs that do not affect the accounts or stock, such as costs involving non-stock or service items. Alternatively, you can use Project Only Costs to record adjustments or corrections to other costs for the project.

Project Only Costs appear on the project activity (Project.Transactions) as CD transactions, and do not update the financial audit trail or stock history.

Alternatively, if you need to reverse a Project Only Cost, for example if you post an invoice to the wrong project but do not need to reverse the invoice to correct the accounts, use the Project Credits option. These reversals appear as CC transactions on the project activity, and do not affect the financials audit trail or stock.

Note: To be able to post a Project Only Cost, the project must be set up with a status that allows postings.

Related Topics

To Post a Project Charge
To Post a Project Credit


Country Property

CISLevyNominal

Description

The CISLevyNominal property returns an object of type Nominal for CIS within Sage 50.

Syntax

The CISLevyNominal property has the following syntax:

Object.CISLevyNominal

with the following parts:

Part | Description
Object | Applies to the following object: CISSetting.
CISLevyNominal | Returns the Nominal object of the current record.

Examples Using This Method

Example - Amending CIS Settings


FileType Property

Description

The FileType property returns the SDO file type constant of the SDO object.

Syntax

The FileType property has the following syntax:

object.FileType

with the following parts:

Part | Description
Object | Applies to one of the following types: SDOFile, SDOIndexFile, SDOLinkedFile and SDOLinkedSubFile.

Values

The following table lists the constants for the Ledger Types.

Constant | Value | Description
sdoAccessData | 31 | Access Data
sdoAccrualData | 23 | Accrual Data
sdoAccStatusData | 49 | Account Status Data
sdoAssetCategory | 35 | Asset Category
sdoAssetData | 34 | Asset Data
sdoAssetIndex | 33 | Asset Index
sdoBankData | 11 | Bank Data
sdoBankIndex | 16 | Bank Index
sdoBankRemitData | 68 | Bank Remittance Data
sdoBankRemitIndex | 69 | Bank Remittance Index
sdoBankWWWData | 51 | Bank WWW Data
sdoBillsData | 46 | Bank Bills Data
sdoCharityFund | 157 | Charity Fund Data
sdoCharityFundType | 158 | Charity Fund Type Data
sdoChartData | 17 | Chart Data
sdoCISSettings | 185 | CIS Settings
sdoCISSubcontractor | 168 | CIS Subcontractor Data
sdoCISSubcontractorLegacy | 186 | CIS Subcontractor Legacy Data
sdoCISSubcontractorTaxHistory | 182 | CIS Subcontractor Tax History Data
sdoCompanyDeliveryData | 64 | Company Delivery Data
sdoCompanyDeliveryIndex | 65 | Company Delivery Index
sdoContactAccountIndex | 40 | Contact Account Index
sdoContactData | 38 | Contact Data
sdoContactDataIndex | 39 | Contact Data Index
sdoContactMemo | 41 | Contact Memo
sdoControlData | 18 | Control Data
sdoCountryCodeData | 70 | Country Code Data
sdoCountryCodeIndex | 71 | Country Code Index
sdoCourierWWWData | 50 | Courier WWW Data
sdoCreditChargeData | 48 | Credit Charge Data
sdoCreditMemo | 42 | Credit Memo
sdoCreditWWWData | 52 | Credit WWW Data
sdoCurrencyData | 20 | Currency Data
sdoDepartmentData | 19 | Department Data
sdoDepreciationData | 24 | Depreciation Data
sdoDisputedReasonData | 82 | Disputed Reason
sdoDocumentLinkData | 267 | Document Link Data
sdoDocumentLinkIndex | 268 | Document Link Index
sdoESubmissionSettings | 184 | ESubmission Settings
sdoFinancialBudget | 174 | Financial Budget Data
sdoGDNData | 104 | Goods Delivered Note Data
sdoGDNIndex | 105 | Goods Delivered Index
sdoGoodsNotesData | 66 | Goods Notes Data
sdoGoodsNotesIndex | 67 | Goods Notes Index
sdoHeaderData | 12 | Header Data
sdoInvoiceData | 1 | Invoice Data
sdoInvoiceIndex | 2 | Invoice Index
sdoInvoiceItem | 3 | Invoice Item
sdoMiscWWWData | 53 | Misc WWW Data
sdoNominalData | 10 | Nominal Data
sdoNominalIndex | 15 | Nominal Index
sdoPOPData | 28 | POP Data
sdoPOPIndex | 29 | POP Index
sdoPOPItem | 30 | POP Item
sdoPrepaymentData | 22 | Prepayment Data
sdoPriceData | 58 | Price Data
sdoPriceIndex | 59 | Price Index
sdoPriceListsData | 56 | Price Lists Data
sdoPriceListsIndex | 57 | Price Lists Index
sdoProjectCostCodeData | 92 | Project Cost Code Data
sdoProjectCostCodeIndex | 93 | Project Cost Code Index
sdoProjectCostCodeUniqueIndex | 94 | Project Cost Code Unique Index
sdoProjectData | 83 | Project Data
sdoProjectIndex | 84 | Project Index
sdoProjectOnlyTransactionData | 100 | Project Only Transaction Data
sdoProjectOnlyTransactionIndex | 101 | Project Only Transaction Index
sdoProjectResourceTypeUniqueIndex | 103 | Project Resource type Unique Index
sdoProjectResourceData | 89 | Project Resource Data
sdoProjectResourceIndex | 90 | Project Resource Index
sdoProjectResourceTypeData | 102 | Project Resource Type Data
sdoProjectResourceUniqueIndex | 91 | Project Resource Unique Index
sdoProjectRevenueCodeData | 95 | Project Revenue Code Data
sdoProjectRevenueCodeIndex | 96 | Project Revenue Code Index
sdoProjectRevenueCodeUniqueIndex | 97 | Project Revenue Code Unique Index
sdoProjectStatusData | 86 | Project Status Data
sdoProjectStatusIndex | 87 | Project Status Index
sdoProjectStatusUniqueIndex | 88 | Project Status Unique Index
sdoProjectTransactionData | 98 | Project Transaction Data
sdoProjectTransactionUniqueIndex | 99 | Project Transaction Unique Index
sdoProjectUniqueIndex | 85 | Project Unique Index
sdoPurchaseData | 9 | Purchase Data
sdoPurchaseDeliveryData | 62 | Purchase Delivery Data
sdoPurchaseDeliveryIndex | 63 | Purchase Delivery Index
sdoPurchaseIndex | 14 | Purchase Index
sdoQueueData | 32 | Queue Data
sdoRecurringData | 21 | Recurring Data
sdoRemittanceData | 54 | Remittance Data
sdoRemittanceIndex | 55 | Remittance Index
sdoSalesData | 8 | Sales Data
sdoSalesDeliveryData | 60 | Sales Delivery Data
sdoSalesDeliveryIndex | 61 | Sales Delivery Index
sdoSalesIndex | 13 | Sales Index
sdoServiceData | 47 | Service Data
sdoSetupData | 0 | Setup Data
sdoSOPData | 25 | SOP Data
sdoSOPIndex | 26 | SOP Index
sdoSOPItem | 27 | SOP Item
sdoSplitData | 36 | Split Data
sdoStockCategory | 7 | Stock Category
sdoStockData | 4 | Stock Data
sdoStockIndex | 5 | Stock Index
sdoStockTrans | 6 | Stock Trans
sdoToDoData | 43 | ToDo Data
sdoToDoIndex | 44 | ToDo Index
sdoToDoMemo | 45 | ToDo Memo
sdoUndefinedFile | -1 | Undefined File
sdoUsageData | 37 | Usage Data


Path Property

Description

The Path property returns a string containing the datapath for the company.

Syntax

The Path property has the following syntax:

object.Path

with the following parts:

Part | Description
Object | Applies to the Company Object


System Requirements

Sage Data Objects for Sage 50 Accounts

A collection of ActiveX Dynamic Link Libraries (.DLLs), the Software Development Kit (SDK) is compatible with many popular development environments. Sage Data Objects (SDO) for Sage 50 is fully documented with hints, tips and code samples for Microsoft .Net developers.

Supported Development Environments

  • Microsoft Visual Basic .Net
  • Microsoft C# .Net

Supported .Net Framewroks

  • Microsoft .Net Framework V2.0 and above

For a list of requirements to use these development environments, see Microsoft's System Requirements.
Produced by: Developer Services, Sage (UK) Limited.


Installing and Running SDO Applications on PCs with no Line 50 Installation

Installing and Running SDO Applications on PCs with no Sage 50 Installation

Considerations

If you are going to run your application in this way, you need to consider the following:

  • Installing the SDO
  • Registering the SDO
  • Connecting to the Data

Installing the SDO

We have provided an installer that will install and register all of the DLLs and dependencies required for third party applications to run on a computer without Sage 50 Accounts installed. This file (Sage50Accounts_SDO.msi) can be obtained from the root of the CD.

If the development of the third party software is to be done on such a machine, you will also need to copy the SDO Type Library (SDOENG.tlb ) file to your computer; This is located in 32-bit: C:\Program Files (x86)\Sage\Accounts\SDO\2024 or 64-bit: C:\Program Files\Sage\Accounts\SDO\2024. You also need to register this file; this can be done by running REGTLIBv12.EXE passing SDOENG.tlb as a parameter. Please Note: regtlibv12.exe is a Microsoft file and is not supplied by Sage Developer Services.

To register the file you will need to locate the Regtlibv12.exe file in C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 or C:\Windows\Microsoft.NET\Framework\v4.0.30319. From Start and run you can use the following to register the tlb (changing the paths accordingly for regtlibv12.exe and SDOENG.tlb locations):

  • C:\Windows\Microsoft.NET\Framework\v2.0.50727\regtlibv12.exe "C:\Program Files\Sage\Accounts\SDO\2024\SDOENG.tlb"
  • C:\Windows\Microsoft.NET\Framework\v4.0.303197\regtlibv12.exe "C:\Program Files (x86)\Sage\Accounts\SDO\2024\SDOENG.tlb"

On machines where UAC control is given we recommend that you run cmd.exe as administrator and register the TLB with the following command: C:\Windows\Microsoft.NET\Framework\v4.0.303197\regtlibv12.exe "C:\Program Files (x86)\Sage\Accounts\SDO\2024\SDOENG.tlb". Please Note: Windows 10 machines do not have the regtlibv12.exe in these locations, it is necessary to copy this across from another machine before following the steps in this answer.

Under normal circumstances, this file is only needed on your development PC; it does not need to be installed on your clients' sites. It does appear, however, that development with some .NET languages requires this file to be present on client PCs. If the file is not present, you may get a message "Query Interface for ISDOEngine Failed Error" when trying to instantiate the SDOEngine object.

Registering the SDO

You will need to register the SDO within your own application by using the Register method of the SDOEngine object. Each version of the SDO requires a different Serial Number and Activation, so a key for Sage 50 Acounts v23 SDO will not activate Sage 50 Acounts v24.0 SDO.
Connecting to the Data

Using the Connect Method:

If you are calling the Connect method directly, you need to ensure that the path to the data points to the machine that has the Sage 50 installation.

Using the SelectCompany Method:

If you are using the SelectCompany method then there are further complications due to the fact that this method looks for the COMPANY file to get a list of data paths.

The problem here is that if you try to use the COMPANY file in the Sage 50 installation, the paths will relate to the C drive of the machine with the Sage 50 installation and this will cause problems as your application will then try to connect to a dataset on the C drive of the machine your application is on.

To overcome this, you need to create a COMPANY file on each machine that has your application installed on it and the pass the path to that file to the SelectCompany method. So, for example, if the COMPANY file on the machine that has the Sage 50 installation had the following paths in it:

C:\ProgramData\Sage\Accounts\2024\COMPANY.000
C:\ProgramData\Sage\Accounts\2024\COMPANY.001

you would create a COMPANY file on the machine that has the SDO application installed in C:\ProgramData\Sage\Accounts\2024 that would hold the following data paths(where X is mapped to the shared Sage Directory on the file server):

X:\ACCOUNTS\2024\COMPANY.000
X:\ACCOUNTS\2024\COMPANY.001

The only problem with this method is that if a company is added or deleted in Sage 50 then the COMPANY files on the machines that have the SDO application would have to be manually amended.


Stock Postings

Stock postings enable you to record stock issued to projects, or to put returned or unused products from a project back into stock. These postings appear on the project activity (Project.Transactions) as an AI or AO transaction type, and also update the stock history.

Note: If the Clear Stock option is used as part of a Month End or Year End routine, Sage 50 removes transactions prior to a specified date from the Product Activity. However, if stock transactions link to a project that is still active, Clear Stock does not remove these transactions from the data completely. Instead, the details of these transactions remain on your project’s activity so that the history for that project is complete.

When using stock for a project, you should remember that Sage 50 uses the FIFO (first in, first out) method of stock control. When you issue stock to a project, Sage 50 uses the oldest stock first. This means that if stock is purchased specifically for a project, for example at a special price, Sage 50 will only use this stock if it is the oldest for that product, otherwise it will use whatever stock already existed on the product record. If you want to use the stock purchased especially for the project, you must post a Project Only Cost adjustment for the difference between the standard stock price and the project’s stock price.

You can only post stock issues or returns for products that are set up as Stock items. For Non-Stock and Service items, you should post a Project Only Cost.

Remember! In Project Costing, stock issues are a COST to a project. This differs to transactions that issue stock in other areas of Sage 50, such as Invoicing, which result in income for the company.

Related Topics

To Enter a Product Adjustment In - Stock Return
To Enter a Product Adjustment Out - Stock Issue