Access Type Constants

Name Value(hex) description
sdoAccessNone 0x1 No Access
sdoAccessPart 0x2 Partial Access
sdoAccessFull 0x4 Full Access

Bank Reconciliation Type Constants

Bank Reconciliation Type Constants

Name Value Description
sdoBankNotApplicable '-' Will not appear in the bank reconciliation
sdoBankReconciled 'R' Will appear as already bank reconciled.
sdoBankUnReconciled 'N' Will appear as unreconciled in the bank

Bank Account Type Constants

Bank Account Type Constants

Constant Value
sdoTypeCheque 1
sdoTypeCash 2
sdoTypeCredit 4

Boolean Constants

Boolean Constants

Value Description
0 False
1 True

Note that these values are often stored as Byte (ASCII) values.
Depending on the programming language used you may have to typecast the value to a byte in order to read or write to it. Contact Type Constants

Contact Type Constants

Name Value Description
sdoCustomerContact C Contact is a customer
sdoSupplierContact S Contact is a supplier

Asset Depreciation Code Constants

Asset Depreciation Code Constants

Constant Value Description
sdoSDP 1 Straight Line
sdoRDP 2 Reducing Balance
sdoWDP 3 Write off

Discount Type Constants

Discount Type Constants

These relate to the Discount Matrix that can be applied in Sage Line 50 for Windows Sales Orders and Invoices.

Name 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

SDOError Code Constants

SDOError Code Constants

Constant Value
sdoNone 0
sdoInvalidArg 1
sdoArchiveException 2
sdoException 3
sdoDaoException 4
sdoDBException 5
sdoFileException 6
sdoMemoryException 7
sdoNotSupportedException 8
sdoOleException 9
sdoOleDispatchException 10
sdoResourceException 11
sdoUserException 12
sdoUnknownException 13
sdoInvalidOpenMode 14
sdoInvalidName 15
sdoNotConnected 16
sdoInvalidKey 17
sdoInvalidValue 18
sdoInvalidUse 19
sdoInvalidType 20
sdoLogonFail 21
sdoLogonPassword 22
sdoLogonNameInUse 23
sdoLogonExclusive 24
sdoBadDataPath 25
sdoWrongVersion 26
sdoBadUpdateMode 27

ToDo Ledger Type Constants

ToDo Ledger Type Constants

Name Value Description
sdoLedgerSales 256 Sales Ledger (Customer)
sdoLedgerPurchase 257 Purchase Ledger (Supplier)

Invoice Type Constants

Invoice Type Constants

Constant Value Description
sdoProductInvoice 0 Product Invoice originating from Invoicing module. i.e. Stock will be removed upon posting of this invoice.
sdoSopInvoice 1 Product Invoice originating from a Sales Order. i.e. It is assumed that stock has already been removed by the Sales Order.
sdoServiceInvoice 2 Service Invoice no stock involved
sdoProductCredit 3 Product Credit. i.e. Stock would be replaced upon posting.
sdoServiceCredit 4 Service Credit no stock involved.
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: These constants apply only to Invoices and Sales Orders, which in Sage Line 50 for Windows may be of several types. Purchase Orders have only one type and thus do not need these constants. Ledger Type Constants

Ledger Type Constants

The following list shows the Ledger Type constants. These are properties of the InvoicePost object which allow us to determine whether it is to represent an Invoice, Sales Order or Purchase Order.

e.g. InvoicePost.Type = sdoLedgerInvoice

Name Value Description
sdoLedgerInvoice 261 Invoice.
sdoLedgerCredit 265 Credit Note
sdoLedgerSop 267 Sales Order.
sdoLedgerPop 268 Purchase Order

Note: Although there are many more Ledger Type Constants exposed through the object model. These three are the only ones that are needed for SDO development. Logon Error Constants

Logon Error Constants

Constant Value Description
sdoLogonFail 21 Failed for unknown reason
sdoLogonPassword 22 Invalid password
sdoLogonNameInUse 23 User already logged on
sdoLogonExclusive 24 Attempting a second logon on a single user program. (only one person may be logged on at any time)

Note: Refer to SDOError Constants for a comprehensive list of error codes. Nominal Type Constants

Nominal Type Constants

Name Value
sdoTypeNormal 1
sdoTypeBank 2
sdoTypeControl 4

Open Mode Constants

Open Mode Constants

The following list shows the Open Mode constants for how a SDOFile, SDOLinkedFile or SDOLinkedSubFile may open a Sage Line 50 for Windows V5 data file.

Constant Value (in hex)
sdoRead 0x00000000
sdoReadWrite 0x00000001
sdoWrite 0x00000002
sdoShareCompat 0x00000000
sdoShareExclusive 0x00000010
sdoShareDenyWrite 0x00000020
sdoShareDenyRead 0x00000030
sdoShareDenyNone 0x00000040
sdoDelete 0x00000200
sdoCreate 0x00001000
sdoExist 0x0000400

Purchase Order Status Constants

Purchase Order Status Constants

Constant Value On-Order Delivered
sdoZeroAlloc 0 Blank Blank NB. This is the status of a new order
sdoFullAlloc 2 Full Blank
sdoCancelled 3 Cancelled Blank
sdoPartFullAlloc 6 Full Part
sdoPartCancelled 7 Cancel Part
sdoComplete 8 Blank Complete NB. Order is fully delivered

Note: The On-Order and Delivered columns represent the same named columns in Sage Line 50 for Windows V5 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) Request Type Constants

Request Type Constants

The following list shows the request constants for the QueueData object.

sdoRequestCompPref = 0x0019, // Asks if company preferences can be done. sdoRequestSalDefaults = 0x001A, // Asks if sales defaults can be done. sdoRequestPurDefaults = 0x001B, // Asks if purchase defaults can be done. sdoRequestStkDefaults = 0x001C, // Asks if stock defaults can be done. sdoRequestAccessRights = 0x001D, // Asks if access rights can be done. sdoRequestFinYear = 0x001E, // Asks if financial year can be done. sdoRequestTaxCodes = 0x001F, // Asks if tax codes can be done. sdoRequestCurrency = 0x0020, // Asks if currency can be done. sdoRequestDepartments = 0x0021, // Asks if departments can be done. sdoRequestProdcat = 0x0022, // Asks if product categories can be done. sdoRequestConsol = 0x0023, // Asks if consolidation can be done. sdoRequestLayout = 0x0024, // Asks if layout of accounts can be done. sdoRequestClearCompany = 0x0025, // Asks if clear company file can be done. sdoRequestInvPrn = 0x0026, // Asks if invoice print can be done. sdoRequestSopPrn = 0x0027, // Asks if SOP print can be done. sdoRequestPopPrn = 0x0028, // Asks if POP print can be done. sdoRequestNewCompany = 0x0029, // Asks if New Company can be done sdoRequestDeleteCompany = 0x002A, // Asks if Delete Company can be done sdoRequestGlobalChange = 0x002B, // Asks if Global Changes can be done sdoRequestDeleteRecords = 0x002C, // Asks if Global Changes can be done sdoRequestClearStock = 0x002D, // Asks if Clear Stock can be done sdoRequestClearAudit = 0x002E, // Asks if Clear Audit Trail can be done sdoRequestWriteoff = 0x002F, // Asks if Write Off can be done sdoRequestContra = 0x0030, // Asks if Contra can be done sdoRequestUpgradeProgram = 0x0031, // Asks if Upgrade Program can be done sdoRequestUpgradeData = 0x0032, // Asks if Upgrade Data can be done sdoRequestDefInv = 0x0033, // Defaults: Invoice Defaults sdoRequestDefAss = 0x0034, // Defaults: Asset categories sdoRequestReports = 0x0035, // General Reports sdoRequestSalReceipts = 0x0036, // Customer Receipts sdoRequestPurPayments = 0x0037, // Supplier payments sdoRequestVatReturn = 0x0038, // VAT Return sdoRequestEis = 0x0039, // EIS sdoRequestSdk = 0x003A, // SDK App sdoRequestPay = 0x003B, // Payroll (future) sdoRequestJob = 0x003C // Job costing (future)
Name Value (hex) Description
sdoRequestActionEnd 0x8000 Asks if doctor can be run.
sdoRequestDoctor 0x0001 Asks if doctor can be run.
sdoRequestBackup 0x0002 Asks if a backup can be run.
sdoRequestRestore 0x0003 Asks if a restore can be done.
sdoRequestEdit 0x0004 Asks if an edit can be done.
sdoRequestDelete 0x0005 Asks if a delete can be done.
sdoRequestPost 0x0006 Asks if a post can be done.
sdoRequestLogon 0x0007 Asks if a user can logon.
sdoRequestImport 0x0008 Asks if a import can be done.
sdoRequestDepreciation 0x0009 Asks if depreciation can be done
sdoRequestPrepayments 0x000A Asks if prepayments can be done.
sdoRequestAccruals 0x000B Asks if accruals can be done.
sdoRequestRecurring 0x000C Asks if recurring entries can be done.
sdoRequestUpdateledger 0x000D Asks if update ledgers can be done.
sdoRequestMonthEnd 0x000E Asks if month end can be done.
sdoRequestYearEnd 0x000F Asks if year end can be done.
sdoRequestControlAcc 0x0010 Asks if control accounts can be done.
sdoRequestInvDel 0x0011 Asks if invoice delete can be done.
sdoRequestSopDel 0x0012 Asks if sop delete can be done.
sdoRequestPopDel 0x0013 Asks if pop delete can be done.
sdoRequestBankRec 0x0014 Asks if bank rec can be done.
sdoRequestGUpdate 0x0015 Asks if global update can be done.
sdoRequestInvAccess 0x0016 Asks if credit note create can be done.
sdoRequestSopAccess 0x0017 Asks if sop create can be done.
sdoRequestPopAccess 0x0018 Asks if pop create can be done.

Sales Order Status Constants

Sales Order Status Constants

Constant Value Allocated Dispatched
sdoZeroAlloc 0 Blank Blank NB. This is the status of a new order
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 NB. Order is fully dispatched
sdoHeldPart 9 Held Part
sdoHeld 10 Held Blank

Note: The Allocated and Dispatched columns represent the same named columns in Sage Line 50 for Windows V5 Sales Order Processing. When nothing appears in a column it is assumed to be blank. E.g. A new Sales Order has no stock allocated or despatched, therefore both columns are listed here as Blank. ( See sdoZeroAlloc) Stock Transaction Type Constants

Stock Transaction Type Constants

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 transfers)
sdoMO 6 Movement Out (from stock transfers)
sdoGR 7 Goods Returned

Audit Trail Transaction Type Constants

Audit Trail Transaction Type Constants

Constants used for posting a transaction that will appear on the Audit Trail.

Constant Value Description
sdoSI 1 Sales Invoice
sdoSC 2 Sales Credit
sdoSR 3 Sales Receipt
sdoSA 4 Sales Payment 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

VAT Type Constants

VAT Reconciliation Type Constants

Name Value Description
sdoVATNotApplicable '-' Will not appear in the VAT reconciliation
sdoVATReconciled 'R' Will appear as already VAT reconciled.
sdoVATUnReconciled 'N' Will appear as unreconciled in the VAT return

Tax Code Conventions

Tax Code Conventions

Line 50 stores tax codes as numbers 0 through to 99.
Although within the program they are always displayed with the 'T' prefix, the SDO will only expect you to refer to the tax code by it's relevant number

Note: You can access the list of fields storing the details for tax codes from the ControlData object. How to delete records - Example

How to Delete Records

The following code example essentially deletes a customer record from the sales ledger. However it also contains a few more useful snippets of code.

The first is an example illustrating a search on a specified account number. The account number is passed to a string variable which is then used to perform a Find. The find will return either a true or false depending on the results.

The second shows how to link a sales record to its corresponding header transaction records. This is necessary since as a developer you should not allow a user to delete an account that has transaction records. The example returns the number of transaction records as an integer which can then be evaluated.

var
   SDO ,WS : Variant;
   objHeaderData, objSalesRec : Variant;
   bFlag : Bool;
   lLinkedRecs : LongInt;
   szAccountNo : Variant;

const
     DataPath = 'c:\sfw\accdata\';

begin
     //Create the SDO Object
     SDO := CreateOleObject('SDOEngine.5');

     //Add a Workspace
     WS := SDO.WorkSpaces.Add('Company1');

try
     //Connect to the Datafiles
     WS.Connect(Datapath,'Manager','','Company1')

except
      on E: EOleException do
      begin
           MessageDlg('Login Falied due to' + chr(10) +
              E.Message,mtError,[mbOK],0);
           Exit;
      end;
end;

     //Create Instance of Sales Record Object
     objSalesRec := WS.CreateObject('SalesRecord');

     //Assign a Value to szAccountNo
     szAccountNo := '0123';

     //Perform a Search on the Account Number
     objSalesRec.Fields['Account_Ref'].Value := string(szAccountNo);
     bFlag := objSalesRec.Find(FALSE);
     if not bFlag then
        begin
             MessageDlg('Account ' + szAccountNo + ' could not be found',
             mtInformation,[mbOK],0);
             exit;
        end;

     //Link Sales Record to Header Transactions
     objHeaderData := objSalesRec.Link;

     //Return the Number of Header Transactions
     lLinkedRecs := objHeaderData.Count;

     //Check to see if there are any transactions
     if lLinkedRecs = 0 then
        begin
             //Ok - delete Account
             objSalesRec.Remove;
             MessageDlg('Account ' + szAccountNo + ' has been removed',
             mtInformation,[mbOK],0);
        end
     else
         begin
              //Cannot delete account as there are transactions
              MessageDlg('You cannot delete an account that has transactions',
              mtWarning,[mbOK],0);
         end;

     //Disconnect
     WS.Disconnect;
end;

How to Access the Fields Collection - Example

How to Access the Fields Collection

This example reads each field in turn from the field collection and displays each field and its description.

procedure TfrmMain.ViewingFieldCollectionClick(Sender: TObject);

var
   SDO ,WS : Variant;
   objControlData : Variant;
   bFlag : Bool;
   lCtr : LongInt;
   lFieldCount : LongInt;

const
     DataPath = 'c:\sfw\accdata\';

begin
     //Create the SDO Object
     SDO := CreateOleObject('SDOEngine.5');

     //Add a Workspace
     WS := SDO.WorkSpaces.Add('Company1');

try
     //Connect to the Datafiles
     WS.Connect(Datapath,'Manager','','Company1')

except
      on E: EOleException do
      begin
           MessageDlg('Login Falied due to' + chr(10) +
              E.Message,mtError,[mbOK],0);
           Exit;
      end;
end;

     //Create Instances of ControlData
     objControlData := WS.CreateObject('ControlData');

     lFieldCount := objControlData.Fields.Count;
     lCtr:=1;
     Repeat
           MessageDlg('Name : ' +
              VarToStr(objControlData.Fields.Item(lCtr).Name)+chr(10)+chr(10)+
              'Description : ' +
              VarToStr(objControlData.Fields.Item(lCtr).Description),
           mtInformation,[mbOK],0);
           lCtr:=lCtr+1;
     Until lCtr > lFieldCount;

     //Disconnect
     WS.Disconnect;

end;

Viewing Header and Split Information - Example

Viewing Header & Split Information

This program highlights the use of the link method to return the splits for a specific header. The program simply moves through the header file displaying a header transaction and the corresponding splits for that transaction in a message box. The loop continues until you select 'No' on the message box prompt.

var
   SDO ,WS : Variant;
   objHeaderData, objSplitData : Variant;
   bFlag : Bool;
   iCtr : Integer;
   szMessage : String;

const
     DataPath = 'c:\sfw\accdata\';

begin
     //Create the SDO Object
     SDO := CreateOleObject('SDOEngine.5');

     //Add a Workspace
     WS := SDO.WorkSpaces.Add('Company1');

try
     //Connect to the Datafiles
     WS.Connect(Datapath,'Manager','','Company1')

except
      on E: EOleException do
      begin
           MessageDlg('Login Falied due to' + chr(10) +
              E.Message,mtError,[mbOK],0);
           Exit;
      end;
end;

     //Create Instance of Header Data Object
     objHeaderData := WS.CreateObject('HeaderData');

     //Read First Header Record
     objHeaderData.MoveFirst;

     //Loop through Headers until it is EOF, or you choose to stop
     Repeat
           //Use Link Method to return Split's for the Header
           objSplitData := objHeaderData.Link;

           //Create Header Info for MessageBox
           szMessage := 'Header Number ' +
           VarToStr(objHeaderData.RecordNumber) +
           ' has ' + VarToStr(objSplitData.Count) + ' Split';

           if objSplitData.Count > 1 then
              begin
                   szMessage := szMessage + 's';
              end;

           szMessage := szMessage + Chr(10);

           //Read the First Split of the Header
           objSplitData.MoveFirst;

           //Loop Through Split's
           iCtr := 1;
           Repeat
                 //Add Split Info to Message
                 szMessage := szMessage + Chr(10) +
                 'Transaction Number ' + VarToStr(objSplitData.RecordNumber);

                 //Read the Next Split
                 objSplitData.MoveNext;
                 iCtr := iCtr +1;
           Until iCtr > objSplitData.Count;

           //Complete the Message
           szMessage := szMessage + Chr(10) + Chr(10) + Chr(10) +
           'Do you want to see the next Header ?';

           //Read next Header
           objHeaderData.MoveNext;

     Until MessageDlg(szMessage, mtConfirmation, [mbYes, mbNO],0) = mrNO;

     WS.Disconnect;

end;

How to use the Memo Property

How to use the Memo Property

This example show's how to use the Memo property on the Sales Ledger.
It can also be used in the Purchase Ledger, Products, Nominal or Bank.

  // Connect to the Data

  SDO := CreateOLEObject('SDOEngine.5');
  WS := SDO.Workspaces.Add('Test');
  WS.Connect('c:\line50\v5\accdata\', 'MANAGER', '', 'Test');
  SalesRecord := WS.CreateObject('SalesRecord');

  // Get the First Sales Record & Show It's Memo

  SalesRecord.MoveFirst;
  ShowMessage(SalesRecord.Memo);

  // Get the Next Sales Record and Add a Memo to it

  SalesRecord.MoveNext;
  SalesRecord.Edit;
  SalesRecord.Memo := 'SDO Test Memo';
  SalesRecord.Update;

  // Disconnect

  WS.Disconnect;

How to Create a New Customer - Example

How to Create a New Customer

var
   SDO ,WS : Variant;
   objSalesRec : Variant;
   bFlag : Bool;

const
     DataPath = 'c:\sfw\accdata\';

begin
     //Create the SDO Object
     SDO := CreateOleObject('SDOEngine.5');

     //Add a Workspace
     WS := SDO.WorkSpaces.Add('Company1');

try
     //Connect to the Datafiles
     WS.Connect(Datapath,'Manager','','Company1')

except
      on E: EOleException do
      begin
           MessageDlg('Login Falied due to' + chr(10) +
              E.Message,mtError,[mbOK],0);
           Exit;
      end;
end;

     //Create Instances of Object's
     objSalesRec := WS.CreateObject('SalesRecord');

     //Add new Record to the Sales Ledger
     objSalesRec.AddNew;

     //Populate Fields
     objSalesRec.Fields['Account_Ref'].Value := '0123';
     objSalesRec.Fields['Name'].Value := 'New SDO Account';
     objSalesRec.Fields['Address_1'].Value := 'Sage House';
     objSalesRec.Fields['Address_2'].Value := 'Benton Park Road';
     objSalesRec.Fields['Address_3'].Value := 'Newcastle Upon Tyne';
     objSalesRec.Fields['Address_4'].Value := 'Tyne & Wear';
     objSalesRec.Fields['Address_5'].Value := 'NE7 7LZ';
     objSalesRec.Fields['Address_5'].Value := 'NE7 7LZ';
     objSalesRec.Fields['Contact_Name'].Value := 'My Contact';
     objSalesRec.Fields['Telephone'].Value := '0191 2553000';
     objSalesRec.Fields['Fax'].Value := '0191 2553001';
     objSalesRec.Fields['Analysis_1'].Value := '';
     objSalesRec.Fields['Analysis_2'].Value := '';
     objSalesRec.Fields['Analysis_3'].Value := '';
     objSalesRec.Fields['Terms'].Value := '30 days';
     objSalesRec.Fields['Def_Nom_Code'].Value := '4000';
     objSalesRec.Fields['Vat_Reg_Number'].Value := '';

     //Update the Record
     bFlag := objSalesRec.Update;

     if (bFlag) then
        begin
             MessageDlg('Account ' +
             VarToStr(objSalesRec.Fields['Account_Ref'].Value) +
             ' Successfully Created',mtInformation,[mbOK],0);
        end
     else
        begin
             MessageDlg('Failed to Create Record',mtError,[mbOK],0);
        end;

     //Disconnect
     WS.Disconnect;

end;

How to Open and Close Files- Example

How to Open and Close Files

This example amends the Company Name in Setup.Dta.
It uses the Methods Open, Close, Read & Write of an SDOFile Object.
This example uses the Open Method using sdoReadWrite, it then Reads the Setup.DTA file using record 1, alters the company name and them Write's back record 1 and finally closes the datafile.

var
   SDO ,WS : Variant;
   objSetupData : Variant;
   bFlag : Bool;

const
     DataPath = 'c:\sfw\accdata\';

begin
     //Create the SDO Object
     SDO := CreateOleObject('SDOEngine.5');

     //Add a Workspace
     WS := SDO.WorkSpaces.Add('Company1');

try
     //Connect to the Datafiles
     WS.Connect(Datapath,'Manager','','Company1')

except
      on E: EOleException do
      begin
           MessageDlg('Login Falied due to' + chr(10) +
              E.Message,mtError,[mbOK],0);
           Exit;
      end;
end;

     //Create Instances of Object
     objSetupData := WS.CreateObject('SetupData');

     //Open the SalesData file
     bFlag := objSetupData.Open(sdoReadWrite);
     if not bFlag then
        begin
             MessageDlg('Error Opening SETUP.DTA',mtError,[mbOK],0);
             WS.Disconnect;
             Exit;
        end;

     //Read the First Record in the File
     objSetupData.Read(1);

     MessageDlg('Your Company Name was ' +
     VarToStr(objSetupData.Fields['Name'].Value),mtInformation,[mbOK],0);

     //Set New Company Name
     objSetupData.Fields['Name'].Value := 'Test Company Name';

     //Write Back
     bFlag := objSetupData.Write(1);
     if not bFlag then
        begin
             MessageDlg('Error Writing to SETUP.DTA',mtError,[mbOK],0);
             WS.Disconnect;
             Exit;
        end;

     MessageDlg('Your Company Name Now is ' +
     VarToStr(objSetupData.Fields['Name'].Value),mtInformation,[mbOK],0);

     //Close the SalesData File
     objSetupData.Close;

     //Disconnect
     WS.Disconnect;

end;

How to Create a Service Invoice

How to Create a Service Invoice

This example creates a service invoice for the first customer in the sales ledger.

It also shows's the use of the Text Property for the Item Lines

The program illustrates how to use GetNextNumber to return the next available invoice number. The invoice is then updated to the InvPost file. This example also introduces a SDO constant : sdoServiceInvoice

var
  SDO ,WS : Variant;
  InvoicePost, InvoiceItem, SalesRecord : Variant;
  bFlag : Bool;   iCtr : Integer;
  szItemString, szSrvString : string;
begin
  // Connect to the Data

  SDO := CreateOleObject('SDOEngine.5');
  WS := SDO.WorkSpaces.Add('Test');
  WS.Connect('c:\line50\v5\accdata\', 'MANAGER', '', 'Test');
  SalesRecord := WS.CreateObject('SalesRecord');
  InvoicePost := WS.CreateObject('InvoicePost');

  // Read the first Customer
  SalesRecord.MoveFirst;

  //Set the type of invoice for the next available number
  InvoicePost.Type := sdoLedgerService;

  //Use the GetNextNumber method

  InvoicePost.Header.Fields['Invoice_Number'].Value := InvoicePost.GetNextNumber;

  //Loop for Number of items on the invoice

  iCtr := 1;
  Repeat
    szsrvstring := '';

    // Create Instance of Invoice Item

    InvoiceItem := InvoicePost.Items.Add;

    //Add to output string
    szItemString := 'This is Item Line Number ' + IntToStr(iCtr);
    szSrvString := szSrvString + szItemString + chr(0);
    //Populate Item Line fields
    InvoiceItem.Fields['Text'].Value:= 'Posting Text';
    InvoiceItem.Text := szsrvstring;
    InvoiceItem.Fields['Service_Item_Lines'].Value:= 1;
    InvoiceItem.Fields['Net_Amount'].Value:= StrToFloat('100');
    InvoiceItem.Fields['Full_Net_Amount'].Value:= StrToFloat('100');
    InvoiceItem.Fields['Tax_Amount'].Value:= StrToFloat('17.50');
    InvoiceItem.Fields['Nominal_Code'].Value:=
      SalesRecord.Fields['Def_Nom_Code'].Value;
    InvoiceItem.Fields['Tax_Code'].Value:=
      SalesRecord.Fields['Def_Tax_Code'].Value;
    InvoiceItem.Fields['Full_Net_Amount'].Value := StrToFloat('100');
    iCtr:= iCtr + 1;
    InvoiceItem := Null;
  Until iCtr > 2;

  //Populate other Header information
  InvoicePost.Header.Fields['Invoice_Date'].Value := Date;
  InvoicePost.Header.Fields['Notes_1'].Value := '';
  InvoicePost.Header.Fields['Notes_2'].Value := '';
  InvoicePost.Header.Fields['Notes_3'].Value := '';
  InvoicePost.Header.Fields['Taken_By'].Value := '';
  InvoicePost.Header.Fields['Order_Number'].Value := '';
  InvoicePost.Header.Fields['Cust_Order_Number'].Value := '';
  InvoicePost.Header.Fields['Payment_Ref'].Value := '';
  InvoicePost.Header.Fields['Global_Nom_Code'].Value := '';
  InvoicePost.Header.Fields['Global_Details'].Value := '';
  InvoicePost.Header.Fields['Invoice_Type_Code'].Value := sdoServiceInvoice;
  InvoicePost.Header.Fields['Items_Net'].Value := StrToFloat('200');
  InvoicePost.Header.Fields['Items_Tax'].Value := StrToFloat('35');

  //Populate fields from Customer Record
  InvoicePost.Header.Fields['Account_Ref'].Value := SalesRecord.Fields['Account_Ref'].Value;
  InvoicePost.Header.Fields['Name'].Value := SalesRecord.Fields['Name'].Value;
  InvoicePost.Header.Fields['Address_1'].Value := SalesRecord.Fields['Address_1'].Value;
  InvoicePost.Header.Fields['Address_2'].Value := SalesRecord.Fields['Address_2'].Value;
  InvoicePost.Header.Fields['Address_3'].Value := SalesRecord.Fields['Address_3'].Value;
  InvoicePost.Header.Fields['Address_4'].Value := SalesRecord.Fields['Address_4'].Value;
  InvoicePost.Header.Fields['Address_5'].Value := SalesRecord.Fields['Address_5'].Value;
  InvoicePost.Header.Fields['Del_Address_1'].Value := SalesRecord.Fields['Del_Address_1'].Value;
  InvoicePost.Header.Fields['Del_Address_2'].Value := SalesRecord.Fields['Del_Address_2'].Value;
  InvoicePost.Header.Fields['Del_Address_3'].Value := SalesRecord.Fields['Del_Address_3'].Value;
  InvoicePost.Header.Fields['Del_Address_4'].Value := SalesRecord.Fields['Del_Address_4'].Value;
  InvoicePost.Header.Fields['Del_Address_5'].Value := SalesRecord.Fields['Del_Address_5'].Value;
  InvoicePost.Header.Fields['Cust_Tel_Number'].Value := SalesRecord.Fields['Telephone'].Value;
  InvoicePost.Header.Fields['Contact_Name'].Value := SalesRecord.Fields['Contact_Name'].Value;
  InvoicePost.Header.Fields['Global_Tax_Code'].Value := SalesRecord.Fields['Def_Tax_Code'].Value;

  //Update the Invoice
  bFlag := InvoicePost.Update;
  if (bFlag) then
  begin
    MessageDlg('Invoice Number ' +
      VarToStr(InvoicePost.Header.Fields['Invoice_Number'].Value) +
        ' Successfully Created',mtInformation,[mbOK],0);
  end
  else
  begin
    MessageDlg('Failed to Create Invoice',mtError,[mbOK],0);
  end;

  // Disconnect

  WS.Disconnect;
end;

How to Create a Stock Invoice - Example

How To Create A Stock Invoice

This example creates a stock invoice for the first customer in the sale ledger.

The program reads the first record in the sales ledger and then moves the customer details into the invoice header. It then reads the stock file sequentially creating two invoice items.

The program illustrates how to use GetNextNumber to return the next available invoice number. The invoice is then updated to the InvPost file. This example also introduces a SDO constant: sdoLedgerInvoice

var
   SDO ,WS : Variant;
   objInvPost, objInvItem, objSalesRec, objStockRec : Variant;
   bFlag : Bool;

const
     DataPath = 'c:\sfw\accdata\';

begin

     //Create the SDO Object
     SDO := CreateOleObject('SDOEngine.5');

     //Add a Workspace
     WS := SDO.WorkSpaces.Add('Company1');

try
     //Connect to the Datafiles
     WS.Connect(Datapath,'Manager','','Company1')

except
      on E: EOleException do
      begin
           MessageDlg('Login Falied due to' + chr(10) +
              E.Message,mtError,[mbOK],0);
           Exit;
      end;
end;

     //Create Instances of Object's
     objSalesRec := WS.CreateObject('SalesRecord');
     objStockRec := WS.CreateObject('StockRecord');
     objInvPost := WS.CreateObject('InvoicePost');

     //Set the type of invoice for the next available number
     objInvPost.Type := sdoLedgerInvoice;

     //Use the GetNextNumber method
     objInvPost.Header.Fields['Invoice_Number'].Value := objInvPost.GetNextNumber;

     //Read the First Customer & populate Invoice Fields
     objSalesRec.MoveFirst;
     objInvPost.Header.Fields['Account_Ref'].Value := objSalesRec.Fields['Account_Ref'].Value;
     objInvPost.Header.Fields['Name'].Value := objSalesRec.Fields['Name'].Value;
     objInvPost.Header.Fields['Address_1'].Value := objSalesRec.Fields['Address_1'].Value;
     objInvPost.Header.Fields['Address_2'].Value := objSalesRec.Fields['Address_2'].Value;
     objInvPost.Header.Fields['Address_3'].Value := objSalesRec.Fields['Address_3'].Value;
     objInvPost.Header.Fields['Address_4'].Value := objSalesRec.Fields['Address_4'].Value;
     objInvPost.Header.Fields['Address_5'].Value := objSalesRec.Fields['Address_5'].Value;
     objInvPost.Header.Fields['Del_Address_1'].Value := objSalesRec.Fields['Del_Address_1'].Value;
     objInvPost.Header.Fields['Del_Address_2'].Value := objSalesRec.Fields['Del_Address_2'].Value;
     objInvPost.Header.Fields['Del_Address_3'].Value := objSalesRec.Fields['Del_Address_3'].Value;
     objInvPost.Header.Fields['Del_Address_4'].Value := objSalesRec.Fields['Del_Address_4'].Value;
     objInvPost.Header.Fields['Del_Address_5'].Value := objSalesRec.Fields['Del_Address_5'].Value;
     objInvPost.Header.Fields['Cust_Tel_Number'].Value := objSalesRec.Fields['Telephone'].Value;
     objInvPost.Header.Fields['Contact_Name'].Value := objSalesRec.Fields['Contact_Name'].Value;
     objInvPost.Header.Fields['Global_Tax_Code'].Value := objSalesRec.Fields['Def_Tax_Code'].Value;

     //Populate other Invoice Header Information
     objInvPost.Header.Fields['Invoice_Date'].Value := Date;
     objInvPost.Header.Fields['Notes_1'].Value := '';
     objInvPost.Header.Fields['Notes_2'].Value := '';
     objInvPost.Header.Fields['Notes_3'].Value := '';
     objInvPost.Header.Fields['Taken_By'].Value := '';
     objInvPost.Header.Fields['Order_Number'].Value := '';
     objInvPost.Header.Fields['Cust_Order_Number'].Value := '';
     objInvPost.Header.Fields['Payment_Ref'].Value := '';
     objInvPost.Header.Fields['Global_Nom_Code'].Value := '';
     objInvPost.Header.Fields['Global_Details'].Value := '';
     objInvPost.Header.Fields['Invoice_Type_Code'].Value := sdoProductInvoice;
     objInvPost.Header.Fields['Items_Net'].Value := StrToFloat('300');
     objInvPost.Header.Fields['Items_Tax'].Value := StrToFloat('17.5');

     //Create an Inovoice Item
     objInvItem := objInvPost.Items.Add();

     //Read the First Stock Code & populate fields from Stock Code
     objStockRec.MoveFirst;
     objInvItem.Fields['Stock_Code'].Value := objStockRec.Fields['Stock_Code'].Value;
     objInvItem.Fields['Description'].Value := objStockRec.Fields['Description'].Value;
     objInvItem.Fields['Nominal_Code'].Value := objStockRec.Fields['Nominal_Code'].Value;
     objInvItem.Fields['Tax_Code'].Value := objStockRec.Fields['Tax_Code'].Value;

     //Populate other fields required for Invoice Item
     objInvItem.Fields['Qty_Order'].Value := StrToFloat('2');
     objInvItem.Fields['Unit_Price'].Value := StrToFLoat('50');
     objInvItem.Fields['Net_Amount'].Value := StrToFloat('100');
     objInvItem.Fields['Tax_Amount'].Value := StrToFloat('17.5');
     objInvItem.Fields['Comment_1'].Value := '';
     objInvItem.Fields['Comment_2'].Value := '';
     objInvItem.Fields['Unit_Of_Sale'].Value := '';
     objInvItem.Fields['Full_Net_Amount'].Value := StrToFloat('100');

     //Create Another Inovoice Item
     objInvItem := objInvPost.Items.Add();

     //Read the Next Stock Code & populate fields from Stock Code
     objStockRec.MoveNext;
     objInvItem.Fields['Stock_Code'].Value := objStockRec.Fields['Stock_Code'].Value;
     objInvItem.Fields['Description'].Value := objStockRec.Fields['Description'].Value;
     objInvItem.Fields['Nominal_Code'].Value := objStockRec.Fields['Nominal_Code'].Value;
     objInvItem.Fields['Tax_Code'].Value := objStockRec.Fields['Tax_Code'].Value;

     //Populate other fields required for Invoice Item
     objInvItem.Fields['Qty_Order'].Value := StrToFloat('1');
     objInvItem.Fields['Unit_Price'].Value := StrToFLoat('200');
     objInvItem.Fields['Net_Amount'].Value := StrToFloat('200');
     objInvItem.Fields['Tax_Amount'].Value := StrToFloat('0');
     objInvItem.Fields['Comment_1'].Value := '';
     objInvItem.Fields['Comment_2'].Value := '';
     objInvItem.Fields['Unit_Of_Sale'].Value := '';
     objInvItem.Fields['Full_Net_Amount'].Value := StrToFloat('200');

     //Update the Invoice
     bFlag := objInvPost.Update;

     if (bFlag) then
        begin
             MessageDlg('Invoice Number ' +
             VarToStr(objInvPost.Header.Fields['Invoice_Number'].Value) +
             ' Successfully Created',mtInformation,[mbOK],0);
        end
     else
        begin
             MessageDlg('Failed to Create Invoice',mtError,[mbOK],0);
        end;

      //Disconnect
      WS.Disconnect;

end;

Posting a Stock Transaction - Example

Posting a Stock Transaction

This example creates an Adjustment In transaction for the first Stock Code in the index.

var
   SDO ,WS : Variant;
   objStockPost, objStockRec, objStockTran : Variant;
   bFlag : Bool;

const
     DataPath = 'c:\sfw\accdata\';

begin
     //Create the SDO Object
     SDO := CreateOleObject('SDOEngine.5');

     //Add a Workspace
     WS := SDO.WorkSpaces.Add('Company1');

try
     //Connect to the Datafiles
     WS.Connect(Datapath,'Manager','','Company1')

except
      on E: EOleException do
      begin
           MessageDlg('Login Falied due to' + chr(10) +
              E.Message,mtError,[mbOK],0);
           Exit;
      end;
end;

     //Create Instances of Transaction Post
     objStockPost := WS.CreateObject('StockPost');
     objStockRec := WS.CreateObject('StockRecord');

     //Read first Stock Code
     objStockRec.MoveFirst;

     //Fill in Header information required
     objStockPost.Header.Fields['Stock_Code'].Value :=
        objStockRec.Fields['Stock_Code'].Value;

     //Add to the items collection of the StockPost object
     objStockTran := objStockPost.Items.Add;

     //Populate Stock Transaction Fields
     objStockTran.Fields['Stock_Code'].Value :=
        objStockRec.Fields['Stock_Code'].Value;
     objStockTran.Fields['Date'].Value := Date;
     objStockTran.Fields['Type'].Value := sdoAI;
     objStockTran.Fields['Quantity'].Value := StrToFloat('2');
     objStockTran.Fields['Cost_Price'].Value := StrToFloat('1');
     objStockTran.Fields['Reference'].Value := 'Test Ref';
     objStockTran.Fields['Details'].Value := 'Test Transaction';

     //Update the StockPost object
     bFlag := objStockPost.Update;

     if (bFlag) then
        begin
             MessageDlg('Successfully Created Stock Transaction to' + chr(10) +
             'Stock Code ' + VarToStr(objStockRec.Fields['Stock_Code'].Value)
             ,mtInformation,[mbOK],0);
        end
     else
        begin
             MessageDlg('Failed to Create Stock Transaction',mtError,[mbOK],0);
        end;

     // Disconnect
     WS.Disconnect;
     
end;

Posting a transaction - Example 2

Posting a Transaction

This example creates a Sales Invoice transaction consisting of one header and two splits. The example creates an instance of a TransactionPost object and a SplitData Object. These are then used to create one Sales Invoice transaction.

var
   SDO ,WS : Variant;
   objTranPost, objSplitData, objSalesRec : Variant;
   bFlag : Bool;
   iCtr : Integer;

const
     DataPath = 'c:\sfw\accdata\';

begin
     //Create the SDO Object
     SDO := CreateOleObject('SDOEngine.5');

     //Add a Workspace
     WS := SDO.WorkSpaces.Add('Company1');

try
     //Connect to the Datafiles
     WS.Connect(Datapath,'Manager','','Company1')

except
      on E: EOleException do
      begin
           MessageDlg('Login Falied due to' + chr(10) +
              E.Message,mtError,[mbOK],0);
           Exit;
      end;
end;

     //Create Instances of Objects
     objTranPost := WS.CreateObject('TransactionPost');
     objSalesRec := WS.CreateObject('SalesRecord');

     //Read the first Customer
     objSalesRec.MoveFirst;

     //Populate Header fields
     objTranPost.Header.Fields['Account_Ref'].Value :=
        objSalesRec.Fields['Account_Ref'].Value;
     objTranPost.Header.Fields['Date'].Value := Date;
     objTranPost.Header.Fields['Posted_Date'].Value := Date;
     objTranPost.Header.Fields['Type'].Value := sdoSI;
     objTranPost.Header.Fields['Details'].Value := 'Test Transaction';
     objTranPost.Header.Fields['Inv_Ref'].Value := 'INV001';

     //Loop for the Number of Splits
     iCtr:= 1;
     Repeat
           //Add a split to the Header Item's collection
           objSplitdata:= objTranPost.Items.Add;

           //Populate Split Fields;
           objSplitData.Fields['Type'].Value := sdoSI;
           objSplitData.Fields['Nominal_Code'].Value := '4000';
           objSplitData.Fields['Tax_Code'].Value := 1;
           objSplitData.Fields['Net_Amount'].Value := StrToFloat('100');
           objSplitData.Fields['Tax_Amount'].Value := StrToFloat('17.50');
           objSplitData.Fields['Date'].Value :=
              objTranPost.Header.Fields['Date'].Value;

           iCtr:= iCtr + 1;
     Until iCtr > 2;

     //Update the TransactionPost object
     bFlag := objTranPost.Update;

     if (bFlag) then
        begin
             MessageDlg('Successfully Created Transaction to' + chr(10) +
             'Customer ' +
             VarToStr(objTranPost.Header.Fields['Account_Ref'].Value)
             ,mtInformation,[mbOK],0);
        end
     else
        begin
             MessageDlg('Failed to Create Transaction',mtError,[mbOK],0);
        end;

      //Disconnect
      WS.Disconnect;
end;

Allocating Transactions - Example

Allocating Transactions

To use the new SDO in Visual Basic you must add it to the list of References so that Visual Basic knows what the Line 50 Data Objects are when you refer to them.

Follow these steps:

In Visual Basic 4 (32-bit)

Choose the Tools menu followed by References.

Find the 'Sage Data Objects 5.0' item, check it and click OK.

In Visual Basic 5/6

Choose the Project menu followed by References.

Find the 'Sage Data Objects 5.0' item, check it and click OK.

If you cannot see the 'Sage Data Objects 5.0' item in the References list, choose Browse and locate the directory where the SDOENG50.DLL and SDOENG50.TLB files are located. Select the SDOENG50.TLB file and click OK. This will add the "Sage Data Objects" to the Reference list in Visual Basic and at the same time register the objects in the Windows registry.

Visual Basic Code Example

This example show's how to allocate a Sales Receipt against a Sales Invoice using the AllocatePayment method. The example first of all post's a Sales Invoice with two splits and then a Sales Receipt. It then allocates the Sales Receipt against each split on the Sales Invoice.

'Set DataPath
Const szConnect = "c:\line50\accdata\"

'Declare Objects
Dim SDO               As SageDataObject50.SDOEngine
Dim WS                As SageDataObject50.WorkSpace
Dim objTranPost       As SageDataObject50.TransactionPost
Dim objHeader         As SageDataObject50.HeaderData
Dim objSplit          As SageDataObject50.SplitData

'Declare program variables
Dim iCtr              As Integer
Dim bFlag             As Boolean
Dim lInvoiceHeader    As Long
Dim lReceiptHeader    As Long
Dim lReceiptSplit     As Long

'Create Instance of Engine and Workspace
Set SDO = New SageDataObject50.SDOEngine
Set WS = SDO.Workspaces.Add("Myconnection")

'Connect to data files
WS.Connect szConnect, "manager", "", "ThisIsUnique"

'Create an instance of TransactionPost
Set objTranPost = WS.CreateObject("TransactionPost")
   
'Fill in the Header fields - note that the Net and Vat are not
'filled in as this is calculated from the splits.
objTranPost.Header("Account_Ref") = CStr("TEST")
objTranPost.Header("Date") = CDate(Date)
objTranPost.Header("Posted_Date") = CDate(Date)
objTranPost.Header("Type") = CByte(sdoSI)
objTranPost.Header("Details") = CStr("Test Transaction")
objTranPost.Header("Inv_Ref") = CStr("BACS")
   
' 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.
  Set objSplit = objTranPost.Items.Add()

  'Fill in the Split fields
  objSplit("Type") = CByte(sdoSI)
  objSplit("Nominal_Code") = CStr("4000")
  objSplit("Tax_Code") = CInt(1)
  objSplit("Net_Amount") = CDbl(100)
  objSplit("Tax_Amount") = CDbl(17.5)
  objSplit("Date") = CDate(objTranPost.Header("Date"))
  objSplit("Details") = CStr(objTranPost.Header("Details"))
Next iCtr

'Update the TransactionPost object
bFlag = objTranPost.Update

' If successfull
If (bFlag) Then

  ' Store Header record number of invoice just posted
  lInvoiceHeader = objTranPost.PostingNumber

  ' Destroy Objects
  Set objTranPost = Nothing
  Set objSplit = Nothing

  ' Create an instance of TransactionPost for the Sales Receipt
  Set objTranPost = WS.CreateObject("TransactionPost")
   
  ' Fill in the Header fields
  objTranPost.Header("Account_Ref") = CStr("TEST")
  objTranPost.Header("Date") = CDate(Date)
  objTranPost.Header("Posted_Date") = CDate(Date)
  objTranPost.Header("Type") = CByte(sdoSR)
  objTranPost.Header("Details") = CStr("Sales Receipt")
  objTranPost.Header("Inv_Ref") = CStr("BACS")
  objTranPost.Header("Bank_Code") = CStr("1200")
   
  'Create a split item by adding an empty split to the Items
  'collection of the TransactionPost Object.
  Set objSplit = objTranPost.Items.Add()

  'Fill in the Split fields - note a Sales Receipt only has one split
  objSplit("Type") = CByte(sdoSR)
  objSplit("Nominal_Code") = CStr("1200")
  objSplit("Tax_Code") = CInt(9)
  objSplit("Net_Amount") = CDbl(235)
  objSplit("Tax_Amount") = CDbl(0)
  objSplit("Date") = CDate(objTranPost.Header("Date"))
  objSplit("Details") = CStr(objTranPost.Header("Details"))

  'Update the TransactionPost object
  bFlag = objTranPost.Update

End If

' If successfull
If (bFlag) Then
      
   ' Destroy SplitData as it will be recreated later
   Set objSplit = Nothing
      
  ' Store Header record number of receipt just posted
  lReceiptHeader = objTranPost.PostingNumber
  
  ' The AllocatePayment function needs the split record number
  ' so we will need to read the header first and then obtain the split's from their
  
  ' Create an instance of HeaderData
  Set objHeader = WS.CreateObject("HeaderData")
   
  ' Read HeaderData for Receipt
  objHeader.Read (lReceiptHeader)
  
  ' Store split number
  lReceiptSplit = objHeader("First_Split")

  ' Read HeaderData for Invoice
  objHeader.Read (lInvoiceHeader)

  ' Link to Split's
  Set objSplit = objHeader.Link

  ' Loop through splits
  objSplit.MoveFirst
  Do
    ' Allocate
    bFlag = objTranPost.AllocatePayment(CLng(objSplit.RecordNumber), _
                                        CLng(lReceiptSplit), _
                                        CDbl(objSplit("Net_Amount") + objSplit("Tax_Amount")), _
                                        CDate(Date))
    
  Loop Until Not objSplit.MoveNext

End If

If (bFlag) Then
  MsgBox "Posting and Allocation has been successfull"
Else
  MsgBox "Routine Failed"
End If


'Disconnect
WS.Disconnect

End
How to use the new memo property - Example

How to use the new Memo Property

To use the new SDO in Visual Basic you must add it to the list of References so that Visual Basic knows what the Sage Line 50 Data Objects are when you refer to them.

Follow these steps:

In Visual Basic 4 (32-bit)

Choose the Tools menu followed by References.

Find the 'Sage Data Objects 5.0' item, check it and click OK.

In Visual Basic 5/6

Choose the Project menu followed by References.

Find the 'Sage Data Objects 5.0' item, check it and click OK.

If you cannot see the 'Sage Data Objects 5.0' item in the References list, choose Browse and locate the directory where the SDOENG50.DLL and SDOENG50.TLB files are located. Select the SDOENG50.TLB file and click OK. This will add the "Sage Data Objects" to the Reference list in Visual Basic and at the same time register the objects in the Windows registry.

Visual Basic Code Example

This example demonstrates the new Memo property on a customer record in the sale ledger.
Note that this could have been on the purchase ledger, nominal ledger or stock

Dim Engine As SageDataObject50.SDOEngine            'Engine
Dim WS As SageDataObject50.WorkSpace                'Workspace
Dim CustomerObj As SageDataObject50.SalesRecord     'Sales record object

'Init the objects
Set Engine = New SageDataObject50.SDOEngine
Set WS = Engine.Workspaces.Add("AC_Connection")

'Set connect path - note should finish ACCDATA\
WS.Connect "D:\L50\SAGEWIN\V5\ACCDATA\", "manager", "", "XYZ123"

'Init the sales record object
Set CustomerObj = WS.CreateObject("SalesRecord")

'For this example we will find the first customer
CustomerObj.MoveFirst

'*****************************************************************************************
'First we will write a new memo to an existing customer
'*****************************************************************************************

'We must use Edit if we are going to use Update later and the customer already exists
'Note we could be using AddNew to create a new customer
If CustomerObj.Edit() Then
    'Now we can add the text for the memo
    CustomerObj.memo = "Memo text for first customer"
    'Finally for the memo to be saved to the customer we need to call update
    If CustomerObj.Update() Then
        MsgBox "done memo"
    End If
End If

'******************************************************************************************
'Now we will read an existing memo
'We will now assume that there is a second customer in Line50 and that they have
'already got memo text entered against them
'******************************************************************************************

'Move to the next customer
CustomerObj.MoveNext
'return the text of their memo back to a message box
MsgBox CustomerObj.memo

'And last we destroy the objects and disconnect from Line50
Set CustomerObj = Nothing
WS.Disconnect
Set WS = Nothing
Set Engine = Nothing

How to Post a Service Invoice - Example

How to Post a Service Invoice

To use the new SDO in Visual Basic you must add it to the list of References so that Visual Basic knows what the Sage Line 50 Data Objects are when you refer to them.

Follow these steps:

In Visual Basic 4 (32-bit)

Choose the Tools menu followed by References.

Find the 'Sage Data Objects 5.0' item, check it and click OK.

In Visual Basic 5/6

Choose the Project menu followed by References.

Find the 'Sage Data Objects 5.0' item, check it and click OK.

If you cannot see the 'Sage Data Objects 5.0' item in the References list, choose Browse and locate the directory where the SDOENG50.DLL and SDOENG50.TLB files are located. Select the SDOENG50.TLB file and click OK. This will add the "Sage Data Objects" to the Reference list in Visual Basic and at the same time register the objects in the Windows registry.

Visual Basic Code Example

This example demonstrates the new Text property when adding the text to a Service Invoice.

Const szConnect = "c:\line50\accdata\"

Dim SDO                 As SageDataObject50.SDOEngine
Dim WS                  As SageDataObject50.WorkSpace
Dim InvPost             As SageDataObject50.InvoicePost
Dim InvItem             As SageDataObject50.InvoiceItem
Dim SalesRec            As SageDataObject50.SalesRecord

'Declare program variables
Dim iCtr                As Integer

'Create instance of Engine and Workspace
Set SDO = New SageDataObject50.SDOEngine
Set WS = SDO.Workspaces.Add("Myconnection")

'Connect to data files
WS.Connect szConnect, "manager", "", "ThisIsUnique"

'Create an instance of InvoicePost & Record object's
Set SalesRec = WS.CreateObject("SalesRecord")
Set InvPost = WS.CreateObject("InvoicePost")

'Set the type of invoice so we can find the next available number
InvPost.Type = sdoLedgerService

'Use the GetNextNumber Method to generate the next available number
InvPost.Header("Invoice_Number") = CLng(InvPost.GetNextNumber)

'Loop for Number of Items on the Invoice
For iCtr = 1 To 5
  Set InvItem = InvPost.Items.Add()
    
  ' This is the text for the line
  InvItem.Text = CStr("This is the text for line number " & iCtr)
  
  InvItem("Text") = CStr("Posting Text")
  InvItem("Service_Item_Lines") = CLng(1)
  InvItem("Net_Amount") = CDbl(100)
  InvItem("Full_Net_Amount") = CDbl(100)
  InvItem("Tax_Amount") = CDbl(17.5)
  InvItem("Nominal_Code") = CStr(SalesRec("Def_Nom_Code"))
  InvItem("Tax_Code") = CInt(SalesRec("Def_Tax_Code"))
  InvItem("Tax_Rate") = CDbl(17.5)
  
Next iCtr

'Populate Invoice Header Information
InvPost.Header("Invoice_Date") = Date
InvPost.Header("Notes_1") = ""
InvPost.Header("Notes_2") = ""
InvPost.Header("Notes_3") = ""
InvPost.Header("Taken_By") = ""
InvPost.Header("Order_Number") = ""
InvPost.Header("Cust_Order_Number") = ""
InvPost.Header("Payment_Ref") = ""
InvPost.Header("Global_Nom_Code") = ""
InvPost.Header("Global_Details") = ""
InvPost.Header("Invoice_Type_Code") = sdoServiceInvoice
InvPost.Header("Items_Net") = CDbl(500)
InvPost.Header("Items_Tax") = CDbl(87.5)

'Read the first customer
SalesRec.MoveFirst
InvPost.Header("Account_Ref") = CStr(SalesRec("Account_Ref"))
InvPost.Header("Name") = CStr(SalesRec("Name"))
InvPost.Header("Address_1") = CStr(SalesRec("Address_1"))
InvPost.Header("Address_2") = CStr(SalesRec("Address_2"))
InvPost.Header("Address_3") = CStr(SalesRec("Address_3"))
InvPost.Header("Address_4") = CStr(SalesRec("Address_4"))
InvPost.Header("Address_5") = CStr(SalesRec("Address_5"))
InvPost.Header("Del_Address_1") = CStr(SalesRec("Del_Address_1"))
InvPost.Header("Del_Address_2") = CStr(SalesRec("Del_Address_2"))
InvPost.Header("Del_Address_3") = CStr(SalesRec("Del_Address_3"))
InvPost.Header("Del_Address_4") = CStr(SalesRec("Del_Address_4"))
InvPost.Header("Del_Address_5") = CStr(SalesRec("Del_Address_5"))
InvPost.Header("Cust_Tel_Number") = CStr(SalesRec("Telephone"))
InvPost.Header("Contact_Name") = CStr(SalesRec("Contact_Name"))
InvPost.Header("Global_Tax_Code") = CInt(SalesRec("Def_Tax_Code"))

'Update the Invoice
If InvPost.Update Then
  MsgBox "Invoice Created Successfully"
Else
  MsgBox "Invoice Not Created"
End If

' Disconnect
WS.Disconnect
Distribution and Registration

Distribution & Registration

Distribution

Sage Data Objects ('SDO') for Line 50 V5 requires that the following files are installed, in order that it may function.

File Description
SDOENG50.DLL Sage SDO Engine Control
SDOENG50.TLB Sage SDO Type Library
SGDT32.DLL Sage Common Date Functions
SGCOM32.DLL Sage Common Functions
MFC42.DLL Microsoft Foundation Class Library
MSVCRT.DLL Visual C++ Runtime Library

 

 

 

 


Registration

SDO V5 needs to be registered manually. You'll find a file called REGSVR32.EXE (Registry Server) in either the \Windows or \Windows\System directory. REGSVR32.EXE needs to be run with the SDOENG50.DLL ('SDO') as it's argument.

For example:

REGSVR32 SDOENG50.DLL

Tip: Should you wish to register SDO V5 from an application, the messagebox returned by regsvr32 can be switched off by using the /S parameter.

For example:

REGSVR32 SDOENG50.DLL/S

Note: If SDO V5 is not registered correctly, errors such as 'cannot create object', will be reported in SDO V5 dependent applications.

AllocatePayment Method

AllocatePayment Method

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

object.AllocatePayment(nInvoice as Long, nCredit as Long, dfAmount as Double, dDate as Date)

The AllocatePayment Method syntax has these parts;

Part Description
object An expression that evaluates to a TransactionPost object derived from a SDOPosting core object
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
The function returns a Boolean value indicating whether the AllocatePayment has been succesful or not

Note: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) CreditMemo Property

CreditMemo Property

Allows access to the credit memo data for Customers and Suppliers. This data is new to Line 50 version 5

Syntax

object.CreditMemo

The CreditMemo Property syntax has these parts;

Part Description
object An expression that evaluates to a Purchase or Sales record object derived from a SDORecordLinked core object

For Example please refer to the Memo property. Syntax is the same Text Property

Text Property

Allows access to the service invoice item's text.

Syntax

object.Text

The Item Property syntax has these parts;

Part Description
object An expression that evaluates to a InvoiceItem object derived from a SDOLinkedFile core object

Example Memo Property

Memo Property

Allows access to the memo data for Customers and Suppliers. This data is stored separately by Line 50 in the memo directory with a file name that corresponds to .slm or plm for Suppliers.

Syntax

object.Memo

The Memo Property syntax has these parts;

Part Description
object An expression that evaluates to a Purchase or Sales record object derived from a SDORecordLinked core object

Example PostingNumber Property

PostingNumber Property

After a successfull call to Update of a TransactionPost this property holds the record number in Header.Dta of the transaction just posted into Line 50.

Syntax

object.PostingNumber

The PostingNumber Property syntax has these parts;

Part Description
object An expression that evaluates to a TransactionPost object derived from a SDOPosting core object

Return
A long value that is the record number of the new transaction in Line 50 Add Method

Add Method

The Add method adds a new entry to the index file.

Syntax

object.Add

The Add method syntax has these parts;

Part Description
object An expression that evaluates to a SDOIndexFile object.

Return Values

Value Description
-1 (TRUE) Item was successfully added to index.
0 (FALSE) Item could not be added to index.

Collection Properties and Methods

Collection Properties and Methods

Properties
Count
Methods
Add
Clear
Remove

SDOError object Properties

SDOError object Properties

Properties
Code
Text

File Properties and Methods

File Properties and Methods

Properties
Count
Fields
FileType
Methods
Close
Lock
Open
Read
Unlock
Write

IndexFile Properties and Methods

IndexFile Properties and Methods

Properties
Count
Fields
FileType
DataRecordNumber
IndexRecordNumber
Key
Methods
Add
Find
FindFirst
FindNext
IsBOF
IsEOF
Move
MoveFirst
MoveLast
MoveNext
MovePrev
Remove
Close
Lock
Open
Read
Unlock
Write

ISPPost Properties and Methods

ISPPost Properties and Methods

Properties
Header
Items
Methods
Update
GetNextNumber
Type

LinkedFile Properties and Methods

LinkedFile Properties and Methods

Properties
Count
Fields
RecordNumber
FileType
Text ( Applies only to InvoiceItem object)
Methods
Close
Lock
Open
Read
Unlock
Write
Link
MoveFirst
MoveLast
MoveNext
MovePrev

LinkedSubFile Properties and Methods

LinkedSubFile Properties and Methods

Properties
Count
Fields
RecordNumber
FileType
Methods
Close
Lock
Open
Read
Unlock
Write
Link
MoveFirst
MoveLast
MoveNext
MovePrev

Posting Object Properties and Methods

Posting Object Properties and Methods

Properties
Header
Items
PostingNumber
Methods
Update
AllocatePayment

Record Properties and Methods

Record Properties and Methods

Properties
Count
Fields
RecordNumber
Methods
AddNew
CancelUpdate
Edit
Find
FindFirst
FindNext
IsBOF
IsEOF
Move
MoveFirst
MoveLast
MoveNext
MovePrev
Remove
Update
GetNextNumber

RecordLinked Properties and Methods

RecordLinked Properties and Methods

Properties
Count
Fields
Memo(Applies to Sales, Purchase, Nominal and Stock record objects)
CreditMemo(Applies to Sales and Purchase record objects)
Methods
AddNew
CanRemove
Find
FindFirst
FindNext
IsBOF
IsEOF
Link
Move
MoveFirst
MoveLast
MoveNext
MovePrev
Remove
Update
GetNextNumber

SDOEngine Properties

SDOEngine Properties

Properties
LastError
Workspaces Collection

Workspace Properties

Workspace Properties

Properties
Name
Version
Methods
Connect
CreateObject
Disconnect

SDOWorkspaces Collection Properties

SDOWorkspaces Collection Properties

Properties
Count
Methods
Add
Clear
Remove

Add Method Example (Workspaces Collection)

Add Method Example (Workspaces Collection)

The following example demonstrates how to add a new Workspace object to the Workspaces collection.

Dim SDO as New SageDataObject50.SDOEngine
Dim WS as SageDataObject50.Workspace

Set WS = SDO.Workspaces.Add("MyConnection")
Fields Collection Example

Fields Collection Example

The following example demonstrates how to access the Fields collection (the data) of an object. It demonstrates the use of a For..Each loop to output the names and descriptions of the fields within an object to a text file name FIELDS.TXT.

'Declare required variables
Dim SDO as New SageDataObject50.SDOEngine
Dim WS as SageDataObject50.Workspace
Dim MySalesRecord as SageDataObject50.SalesRecord
Dim MyField as Field
Dim Freef as Integer


'Create a Workspace object and store the reference to it.
Set WS = SDO.Workspaces.Add("MyConnection")

'Connect to the data using Manager and no password.
'Note that the last \ on the path is required.
WS.Connect "C:\SFW\ACCDATA\", "Manager", "", "XYZ123"

Set MySalesRecord = WS.CreateObject("SalesRecord")

'Get the next free file handle
Freef = Freefile()

'Open the file to output to
Open "FIELDS.TXT" for Output as #Freef

'Start looping through fields
For Each MyField in MySalesRecord.Fields
Print #Freef, MyField.Name, MyField.Description
Next MyField

'Close the File
Close #Freef

'Disconnect and destroy the objects
WS.Disconnect
Set MySalesRecord = Nothing
Set WS = Nothing
Set SDO = Nothing

SDOEngine Object Example

SDOEngine Object Example

This example demonstrates two ways to create the SDOEngine object.

In Visual Basic using early binding;
Public SDO as New SageDataObject50.SDOEngine
In Visual Basic for Applications (VBA) using late binding;
Public SDO as Object
Set SDO = CreateObject ("SageDataObject50.SDOEngine")
Viewing Header and Split Information - Example

Viewing Header & Split Information

To use the new SDO in Visual Basic you must add it to the list of References so that Visual Basic knows what the Sage Line 50 Data Objects are when you refer to them.

Follow these steps:

In Visual Basic 4 (32-bit)

Choose the Tools menu followed by References.

Find the 'Sage Data Objects 5.0' item, check it and click OK.

In Visual Basic 5/6

Choose the Project menu followed by References.

Find the 'Sage Data Objects 5.0' item, check it and click OK.

If you cannot see the 'Sage Data Objects' item in the References list, choose Browse and locate the directory where the SDOENG50.DLL and SDOENG50.TLB files are located. Select the SDOENG50.TLB file and click OK. This will add the "Sage Data Objects" to the Reference list in Visual Basic and at the same time register the objects in the Windows registry.

Visual Basic Code Example

This program highlights the use of the link method to return the splits for a specific header. The program simply moves through the header file displaying a header transaction and the corresponding splits for that transaction in a message box. The loop continues until you select 'No' on the message box prompt.

Dim SDO As New SageDataObject50.SDOEngine
Dim WS As SageDataObject50.WorkSpace
Dim Header As SageDataObject50.HeaderData
Dim Split As SageDataObject50.SplitData

'Declare program variables
Dim szConnect As String
Dim lRecordNum As Long
Dim iCtr As Long
Dim szMessage As String

'Add Workspace
Set WS = SDO.Workspaces.Add("Myconnection")

'Set connect path - note last \ is required.
szConnect = "C:\SFW\ACCDATA\"

'Attempt connection to data files
If WS.Connect(szConnect, "manager", "", "ThisIsUnique") = False Then
  MsgBox "Could not connect to Sage Line 50", vbCritical
  Exit Sub
End If

'Create an instance of HeaderData
Set Header = WS.CreateObject("HeaderData")

'Move to the First Header & set lRecordNum to 1
Header.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 Split's for this Header
  Set Split = Header.Link

  'Create standard message
  szMessage = "Header Number " & Header("Unique_Ref") & " has " _
            & Split.Count & " Split"
  If Split.Count > 1 Then szMessage = szMessage + "s"
  szMessage = szMessage & Chr(10)
        
  'Move to the First Split of the originating object
  'In this case the first split of the header
  Split.MoveFirst
  
  'We can use the Count Method to determine how many Split's
  'the Header has
  For iCtr = 1 To Split.Count
    
    'Add a transaction detail to the message
    szMessage = szMessage & Chr(10) & "Transaction Number " _
                & Split.RecordNumber
    
    'Move to the Next Split of the Header
    Split.MoveNext
  Next iCtr

  'Complete the Message
  szMessage = szMessage & Chr(10) & Chr(10) & Chr(10) & "Do you want " _
            	 & "to see the next Header Transcation ?"  

  'Move to the next Header & increment lRecordNum
  Header.MoveNext
  lRecordNum = lRecordNum + 1
Loop Until MsgBox(szMessage, vbYesNo) = vbNo Or lRecordNum > Header.Count

'Disconnect and destroy the objects
WS.Disconnect
Set Split = Nothing
Set Header = Nothing
Set WS = Nothing
Set SDO = Nothing

End
Using and SDORecord Object - Example

Using a SDORecord Object

A SDORecord object represents records in one of Sage Line 50's Ledgers. It wraps the functionality of the data file and the index file into a single object. This gives you a more abstract way of manipulating the Line 50 records.

Const szDataPath = "c:\sfw\accdata\"
Private Sub Command1_Click()
        
    'Declare SDO objects
    Dim DBEngine    As SageDataObject50.SDOEngine
    Dim WS          As SageDataObject50.WorkSpace
    Dim SalRec      As SageDataObject50.SalesRecord

    'Declare general varaibles
    Dim bFlag       As Boolean
    Dim szListItem  As String
    
    'Create instances of both Engine and Workspace
    Set DBEngine = New SageDataObject.SDOEngine
    Set WS = DBEngine.Workspaces.Add("My Workspace")
    
    'Connect to data source
    bFlag = WS.Connect(szDataPath, "manager", "", "sdoExample")
    If Not bFlag Then
        MsgBox "Program could not connect to Sage Line 50 Data Source", _ 
  vbCritical
        Exit Sub
    End If
    
    'Create instance of sales record
    Set SalRec = WS.CreateObject("SalesRecord")
    
    'Fill the list box
    SalRec.MoveFirst
    Do While Not SalRec.IsEOF
         szListItem = SalRec("Account_Ref") & vbTab & _
                      SalRec("Name")
        
        SGOList1.Items.Add szListItem
        
        SalRec.MoveNext
    Loop

'Disconnect and destroy the objects
WS.Disconnect
Set SalRec = Nothing
Set WS = Nothing
Set DBEngine = Nothing

    

End Sub

Opening and Closing Files - Example

Opening And Closing Files

To use the new SDO in Visual Basic you must add it to the list of References so that Visual Basic knows what the Sage Line 50 Data Objects are when you refer to them.

Follow these steps:

In Visual Basic 4 (32-bit)

Choose the Tools menu followed by References.

Find the 'Sage Data Objects 5.0' item, check it and click OK.

In Visual Basic 5/6

Choose the Project menu followed by References.

Find the 'Sage Data Objects 5.0' item, check it and click OK.

If you cannot see the 'Sage Data Objects 5.0' item in the References list, choose Browse and locate the directory where the SDOENG50.DLL and SDOENG50.TLB files are located. Select the SDOENG50.TLB file and click OK. This will add the "Sage Data Objects" to the Reference list in Visual Basic and at the same time register the objects in the Windows registry.

Visual Basic Code Example

The following code fills a Sage list box with the account number and customer name. Obviously any list box control could be used. The example uses an index file to move through the data file reading each record sequentially.

It uses the SDOFile object, which represents the lowest level of access by allowing direct access to the Line 50 data files. The following example also uses the SDOIndexFile object represents a Line 50 index file. When a SDOIndexFile is opened it is immediately positioned to the first record in the file.

'It is advisable to declare this constant in a module to avoid
'simple typing errors
Const szDataPath = "c:\sfw\accdata\"

Private Sub Command1_Click()
    'Declare SDO objects
    Dim DBEngine    As SageDataObject50.SDOEngine
    Dim WS          As SageDataObject50.WorkSpace
    Dim SDOFile     As SageDataObject50.SalesData
    Dim SDOIndex    As SageDataObject50.SalesIndex
    
    'Declare general varaibles
    Dim bFlag       As Boolean
    Dim szListItem  As String
    
    'Create instances of both Engine and Workspace
    Set DBEngine = New SageDataObject50.SDOEngine
    Set WS = DBEngine.Workspaces.Add("My Workspace")
    
    'Connect to data source
    bFlag = WS.Connect(szDataPath, "manager", "", "sdoExample")
    If Not bFlag Then
        MsgBox "Program could not connect to Sage Line 50 Data Source", _ 
  vbCritical
        Exit Sub
    End If
    
    'Create instances of SalesData and Index
    Set SDOFile = WS.CreateObject("SalesData")
    Set SDOIndex = WS.CreateObject("SalesIndex")
    
    'Open the SalesData file
    bFlag = SDOFile.Open(sdoRead)
    If Not bFlag Then
        MsgBox "Error Opening File - Operation Cancelled", vbCritical
        Exit Sub
    End If
    
    'Read the first record in the file
    SDOIndex.MoveFirst
    SDOFile.Read (SDOIndex.DataRecordNumber)
    
    'Fill SAGE list box with account details
    Do While Not SDOIndex.IsEOF
        szListItem = SDOFile("Account_Ref") & vbTab & _
                     SDOFile("Name")
        
        SGOList1.Items.Add szListItem
        
        SDOIndex.MoveNext
        SDOFile.Read (SDOIndex.DataRecordNumber)
    Loop
    
    'Close the sales file
    SDOFile.Close
 
'Disconnect and destroy the objects
WS.Disconnect
Set SDOIndex = Nothing
Set SDOFile = Nothing
Set WS = Nothing
Set DBEngine = Nothing
  
End Sub
Link Method Example

Link Method Example

This example demonstrates how to use the Link method to access the transactions of a specific customer and simply displays the number of transactions.

'Declare required variables
Dim SDO as New SageDataObject50.SDOEngine
Dim WS as SageDataObject50.Workspace
Dim MySalesRecord as SageDataObject50.SalesRecord
Dim Trans as SageDataObject50.HeaderData
Dim MyField as Field
Dim Freef as Integer


'Create a Workspace object and store the reference to it.
Set WS = SDO.Workspaces.Add("MyConnection")

'Connect to the data using Manager and no password.
WS.Connect "C:\SFW\ACCDATA\", "Manager", "", "XYZ123"

'Create a SalesRecord object  First record will be 
'automatically selected
Set MySalesRecord = WS.CreateObject("SalesRecord")

'Make the first record the current record
MySalesRecord.MoveFirst

'Get a reference to the transactions for the first record
'A reference to an instance of a SDOLinkedSubFile will be returned
Set Trans = MySalesRecord.Link

'Make the first record the current record
Trans.MoveFirst

'Display the number of transaction in link object
MsgBox Trans.Count

'Disconnect and destroy the objects
WS.Disconnect
Set Trans = Nothing
Set MySalesRecord = Nothing
Set WS = Nothing
Set SDO = Nothing

How to create a stock invoice - Example

How to Create a Stock Invoice

To use the new SDO in Visual Basic you must add it to the list of References so that Visual Basic knows what the Sage Line 50 Data Objects are when you refer to them.

Follow these steps:

In Visual Basic 4 (32-bit)

Choose the Tools menu followed by References.

Find the 'Sage Data Objects 5.0' item, check it and click OK.

In Visual Basic 5/6

Choose the Project menu followed by References.

Find the 'Sage Data Objects 5.0' item, check it and click OK.

If you cannot see the 'Sage Data Objects 5.0' item in the References list, choose Browse and locate the directory where the SDOENG50.DLL and SDOENG50.TLB files are located. Select the SDOENG50.TLB file and click OK. This will add the "Sage Data Objects" to the Reference list in Visual Basic and at the same time register the objects in the Windows registry.

Visual Basic Code Example

This example creates a stock invoice for the first customer in the sale ledger.

The program reads the first record in the sales ledger and then moves the customer details into the invoice header. It then reads the stock file sequentially creating two invoice items.

The program illustrates how to use GetNextNumber to return the next available invoice number. The invoice is then updated to the InvPost file. This example also introduces a SDO constant: sdoLedgerInvoice

Dim SDO As New SageDataObject50.SDOEngine
Dim WS As SageDataObject50.WorkSpace
Dim InvPost As SageDataObject50.InvoicePost
Dim InvItem As SageDataObject50.InvoiceItem
Dim SalesRec As SageDataObject50.SalesRecord
Dim StockRec As SageDataObject50.StockRecord
Dim szConnect As String

'Add Workspace
Set WS = SDO.Workspaces.Add("Myconnection")

'Set connect path - note last \ is required.
szConnect = "C:\SFW\ACCDATA\"

'Attempt connection to data files
If WS.Connect(szConnect, "manager", "", "ThisIsUnique") Then

  'Create an instance of InvoicePost & Record object's
  Set SalesRec = WS.CreateObject("SalesRecord")
  Set StockRec = WS.CreateObject("StockRecord")
  Set InvPost = WS.CreateObject("InvoicePost")
  
  'Set the type of invoice so we can find the next available number
  InvPost.Type = sdoLedgerInvoice
  
  'Use the GetNextNumber Method
  InvPost.Header("Invoice_Number") = InvPost.GetNextNumber
  
  'Read the first customer
  'Note use of the CStr & CInt Function
  SalesRec.MoveFirst
  InvPost.Header("Account_Ref") = CStr(SalesRec("Account_Ref"))
  InvPost.Header("Name") = CStr(SalesRec("Name"))
  InvPost.Header("Address_1") = CStr(SalesRec("Address_1"))
  InvPost.Header("Address_2") = CStr(SalesRec("Address_2"))
  InvPost.Header("Address_3") = CStr(SalesRec("Address_3"))
  InvPost.Header("Address_4") = CStr(SalesRec("Address_4"))
  InvPost.Header("Address_5") = CStr(SalesRec("Address_5"))
  InvPost.Header("Del_Address_1") = CStr(SalesRec("Del_Address_1"))
  InvPost.Header("Del_Address_2") = CStr(SalesRec("Del_Address_2"))
  InvPost.Header("Del_Address_3") = CStr(SalesRec("Del_Address_3"))
  InvPost.Header("Del_Address_4") = CStr(SalesRec("Del_Address_4"))
  InvPost.Header("Del_Address_5") = CStr(SalesRec("Del_Address_5"))
  InvPost.Header("Cust_Tel_Number") = CStr(SalesRec("Telephone"))
  InvPost.Header("Contact_Name") = CStr(SalesRec("Contact_Name"))
  InvPost.Header("Global_Tax_Code") = CInt(SalesRec("Def_Tax_Code"))
  
  'Populate other Invoice Header Information
  InvPost.Header("Invoice_Date") = Date
  InvPost.Header("Notes_1") = ""
  InvPost.Header("Notes_2") = ""
  InvPost.Header("Notes_3") = ""
  InvPost.Header("Taken_By") = ""
  InvPost.Header("Order_Number") = ""
  InvPost.Header("Cust_Order_Number") = ""
  InvPost.Header("Payment_Ref") = ""
  InvPost.Header("Global_Nom_Code") = ""
  InvPost.Header("Global_Details") = ""
  InvPost.Header("Invoice_Type_Code") = sdoProductInvoice
  InvPost.Header("Items_Net") = 300#
  InvPost.Header("Items_Tax") = 17.5

  'Create an Invoice Item
  Set InvItem = InvPost.Items.Add()
  
  'Read the first Stock Code
  StockRec.MoveFirst
  InvItem("Stock_Code") = CStr(StockRec("Stock_Code"))
  InvItem("Description") = CStr(StockRec("Description"))
  InvItem("Nominal_Code") = CStr(StockRec("Nominal_Code"))
  InvItem("Tax_Code") = CInt(StockRec("Tax_Code"))
    
  'Populate other Invoice Item fields
  InvItem("Qty_Order") = 2#
  InvItem("Unit_Price") = 50#
  InvItem("Net_Amount") = 100#
  InvItem("Tax_Amount") = 17.5
  InvItem("Comment_1") = ""
  InvItem("Comment_2") = ""
  InvItem("Unit_Of_Sale") = ""
  
  'Create another Invoice Item
  Set InvItem = InvPost.Items.Add()
  
  'Read the Next Stock Code
  StockRec.MoveNext
  InvItem("Stock_Code") = CStr(StockRec("Stock_Code"))
  InvItem("Description") = CStr(StockRec("Description"))
  InvItem("Nominal_Code") = CStr(StockRec("Nominal_Code"))
  InvItem("Tax_Code") = CInt(StockRec("Tax_Code"))
    
  'Populate other Invoice Item fields
  InvItem("Qty_Order") = 1#
  InvItem("Unit_Price") = 200#
  InvItem("Net_Amount") = 200#
  InvItem("Tax_Amount") = 0#
  InvItem("Comment_1") = ""
  InvItem("Comment_2") = ""
  InvItem("Unit_Of_Sale") = ""
  
  'Update the Invoice
  If InvPost.Update Then
    MsgBox "Invoice Created Successfully"
  Else
    MsgBox "Invoice Not Created"
  End If
  
Else
  MsgBox "Could not connect."
End If

'Disconnect and destroy the objects
WS.Disconnect
Set InvItem = Nothing
Set InvPost = Nothing
Set SalesRec = Nothing
Set StockRec = Nothing
Set WS = Nothing
Set SDO = Nothing

End
Remove Method Example (Workspaces Collection)

Remove Method Example (Workspaces Collection)

This example demonstrates how to remove an existing Workspace object from the Workspaces Collection.

Set WS = SDO.Workspaces.Remove("MyConnection")
How to delete records - Example

How to Delete Records

To use the new SDO in Visual Basic you must add it to the list of References so that Visual Basic knows what the Sage Line 50 Data Objects are when you refer to them.

Follow these steps:

In Visual Basic 4 (32-bit)

Choose the Tools menu followed by References.

Find the 'Sage Data Objects 5.0' item, check it and click OK.

In Visual Basic 5/6

Choose the Project menu followed by References.

Find the 'Sage Data Objects 5.0' item, check it and click OK.

If you cannot see the 'Sage Data Objects 5.0' item in the References list, choose Browse and locate the directory where the SDOENG50.DLL and SDOENG50.TLB files are located. Select the SDOENG50.TLB file and click OK. This will add the "Sage Data Objects" to the Reference list in Visual Basic and at the same time register the objects in the Windows registry.

Visual Basic Code Example

The following code example essentially deletes a customer record from the sales ledger. However it also contains a few more useful snippets of code.

The first is an example illustrating a search on a specified account number. The account number is passed to a string variable which is then used to perform a Find. The find will return either a true or false depending on the results.

The second shows how to link a sales record to its corresponding header transaction records. This is necessary since as a developer you should not allow a user to delete an account that has transaction records. The example returns the number of transaction records as an integer which can then be evaluated.

Const szDataPath = "c:\sfw\accdata\"
Private Sub Command1_Click()

    'Declare SDO objects
    Dim DBEngine    As SageDataObject50.SDOEngine
    Dim WS          As SageDataObject50.WorkSpace
    Dim SalRec      As SageDataObject50.SalesRecord
    Dim Header      As SageDataObject50.HeaderData

    'Declare general varaibles
    Dim bFlag       As Boolean
    Dim szAccountNo As String
    Dim iLinkedRecs As Single
    
    'Create instances of both Engine and Workspace
    Set DBEngine = New SageDataObject.SDOEngine
    Set WS = DBEngine.Workspaces.Add("My Workspace")
    
    'Connect to data source
    bFlag = WS.Connect(szDataPath, "manager", "", "sdoExample")
    If Not bFlag Then
        MsgBox "Program could not connect to Sage Line 50 Data Source", _ 
  vbCritical
        Exit Sub
    End If
    
    'Create instance of sales record
    Set SalRec = WS.CreateObject("SalesRecord")
    
    'Assign a value to szAccountNo
    szAccountNo = "0123"
    
    'Perform a search on the account number
    SalRec("Account_Ref") = szAccountNo
    bFlag = SalRec.Find(False)
    If bFlag = False Then
        MsgBox "Account " & szAccountNo & " could not be found.", _
 		vbInformation
        Exit Sub
    End If
    
    'Link sales record to header transactions
    Set Header = SalRec.Link()
    
    'Return the number of header transactions
    iLinkedRecs = Header.Count
    
    'Check to see if there is any transaction records
    If iLinkedRecs = 0 Then
        'OK to delete customer account
        SalRec.Remove
        MsgBox "Account has been removed.", vbInformation
    Else
        'Cannot delete account since there are transactions
        MsgBox "You cannont delete an account that has tranactions.", _
                vbCritical
    End If
     
   'Disconnect and destroy the objects
   WS.Disconnect
   Set Header = Nothing
   Set SalRec = Nothing
   Set WS = Nothing
   Set DBEngine = Nothing
   
End Sub
How to create a service invoice - Example

How to Create a Service Invoice

To use the new SDO in Visual Basic you must add it to the list of References so that Visual Basic knows what the Sage Line 50 Data Objects are when you refer to them.

Follow these steps:

In Visual Basic 4 (32-bit)

Choose the Tools menu followed by References.

Find the 'Sage Data Objects 5.0' item, check it and click OK.

In Visual Basic 5/6

Choose the Project menu followed by References.

Find the 'Sage Data Objects' item, check it and click OK.

If you cannot see the 'Sage Data Objects' item in the References list, choose Browse and locate the directory where the SDOENG50.DLL and SDOENG50.TLB files are located. Select the SDOENG50.TLB file and click OK. This will add the "Sage Data Objects 5.0" to the Reference list in Visual Basic and at the same time register the objects in the Windows registry.

Visual Basic Code Example

This example creates a service invoice for the first customer in the sales ledger.

The program creates a text file using the invoice number followed by the extension .srv; giving a filename of invno.srv. This filename is then written to the InvItem(Service_File) property, and the file size is written to the InvItem(Service_File_Size) property.

The program illustrates how to use GetNextNumber to return the next available invoice number. The invoice is then updated to the InvPost file. This example also introduces a SDO constant : sdoServiceInvoice

Dim SDO As New SageDataObject50.SDOEngine
Dim WS As SageDataObject50.WorkSpace
Dim InvPost As SageDataObject50.InvoicePost
Dim InvItem As SageDataObject50.InvoiceItem
Dim SalesRec As SageDataObject50.SalesRecord
Dim szConnect As String

'Declare program variables
Dim FileNum As Integer
Dim iCtr As Integer
Dim szItemList As String
Dim szItemDescription As String

'Add Workspace
Set WS = SDO.Workspaces.Add("Myconnection")

'Set connect path - note last \ is required.
szConnect = "C:\SFW\ACCDATA\"

'Attempt connection to data files
If WS.Connect(szConnect, "manager", "", "ThisIsUnique") Then

  'Create an instance of InvoicePost & Record object's
  Set SalesRec = WS.CreateObject("SalesRecord")
  Set InvPost = WS.CreateObject("InvoicePost")
  
  'Set the type of invoice so we can find the next available number
  InvPost.Type = sdoLedgerService
  
  'Use the GetNextNumber Method to generate the next available number
  InvPost.Header("Invoice_Number") = InvPost.GetNextNumber

  'Get Next File Handle and open file for output
  FileNum = FreeFile()
  Open szConnect & CStr(InvPost.Header("Invoice_Number")) & ".srv" For Output As #FileNum
  
  'Loop for Number of Items on the Invoice
  szItemList = ""
  For iCtr = 1 To 2
    Set InvItem = InvPost.Items.Add()
    szItemDescription = "This is Item Line Number " & iCtr
    szItemList = szItemList + szItemDescription + Chr(0)
    InvItem("Text") = "Posting Text"
    InvItem("Service_File") = CStr(InvPost.Header("Invoice_Number")) & ".srv"
    InvItem("Service_File_Size") = Len(szItemDescription)
    InvItem("Service_Item_Lines") = 1
    InvItem("Net_Amount") = 100#
    InvItem("Full_Net_Amount") = 100#
    InvItem("Tax_Amount") = 17.5
    InvItem("Nominal_Code") = CStr(SalesRec("Def_Nom_Code"))
    InvItem("Tax_Code") = CInt(SalesRec("Def_Tax_Code"))
  Next iCtr
  Print #FileNum, szItemList
  Close #FileNum
  
  'Populate Invoice Header Information
  InvPost.Header("Invoice_Date") = Date
  InvPost.Header("Notes_1") = ""
  InvPost.Header("Notes_2") = ""
  InvPost.Header("Notes_3") = ""
  InvPost.Header("Taken_By") = ""
  InvPost.Header("Order_Number") = ""
  InvPost.Header("Cust_Order_Number") = ""
  InvPost.Header("Payment_Ref") = ""
  InvPost.Header("Global_Nom_Code") = ""
  InvPost.Header("Global_Details") = ""
  InvPost.Header("Invoice_Type_Code") = sdoServiceInvoice
  InvPost.Header("Items_Net") = 200#
  InvPost.Header("Items_Tax") = 35#
  InvPost.Header("Total_Bytes") = Len(szItemList)
  
  'Read the first customer
  SalesRec.MoveFirst
  InvPost.Header("Account_Ref") = CStr(SalesRec("Account_Ref"))
  InvPost.Header("Name") = CStr(SalesRec("Name"))
  InvPost.Header("Address_1") = CStr(SalesRec("Address_1"))
  InvPost.Header("Address_2") = CStr(SalesRec("Address_2"))
  InvPost.Header("Address_3") = CStr(SalesRec("Address_3"))
  InvPost.Header("Address_4") = CStr(SalesRec("Address_4"))
  InvPost.Header("Address_5") = CStr(SalesRec("Address_5"))
  InvPost.Header("Del_Address_1") = CStr(SalesRec("Del_Address_1"))
  InvPost.Header("Del_Address_2") = CStr(SalesRec("Del_Address_2"))
  InvPost.Header("Del_Address_3") = CStr(SalesRec("Del_Address_3"))
  InvPost.Header("Del_Address_4") = CStr(SalesRec("Del_Address_4"))
  InvPost.Header("Del_Address_5") = CStr(SalesRec("Del_Address_5"))
  InvPost.Header("Cust_Tel_Number") = CStr(SalesRec("Telephone"))
  InvPost.Header("Contact_Name") = CStr(SalesRec("Contact_Name"))
  InvPost.Header("Global_Tax_Code") = CInt(SalesRec("Def_Tax_Code"))
  
  'Update the Invoice
  If InvPost.Update Then
    MsgBox "Invoice Created Successfully"
  Else
    MsgBox "Invoice Not Created"
  End If
  
Else
  MsgBox "Could not connect."
End If

'Disconnect and destroy the objects
WS.Disconnect
Set InvItem = Nothing
Set InvPost = Nothing
Set SalesRec = Nothing
Set    
End
Update Method Example (Workspaces Collection)

Update Method Examples

This example demonstrates how to edit an existing record.

Dim Sal as SageDataObject50.SalesRecord
set Sal = ws.CreateObject("SalesRecord)

' Editing an existing record
Sal.MoveFirst
Sal.Edit
Sal("NAME") = "Unused account"
Sal.Update

This example demonstrates how to create a new record.

Dim sal as SalesRecord
set sal = ws.CreateObject("SalesRecord)

' Creating a new record
sal.AddNew
sal("ACCOUNT_REF") = "ABC001"
sal("NAME") = "My first account"
sal.Update
Posting a transaction - Example 2

Posting a Transaction</