Résumé détaillé de la documentation Sage 100 Objets Métiers
1. Présentation générale
Sage 100 Objets Métiers est une bibliothèque logicielle ActiveX (COM) destinée à simplifier le développement d'applications accédant aux bases de données Sage 100c (SQL Server et Express). Elle met à disposition des développeurs des classes, interfaces, méthodes et propriétés permettant l'accès en lecture et en écriture aux données.
Lors de l'ajout ou de la modification de données, des contrôles de cohérence sont automatiquement effectués. De plus, des automatismes sont gérés (initialisation de champs avec des valeurs par défaut ou héritées) lors de la création de nouveaux enregistrements (articles, tiers, documents, etc.).
La documentation présente le fonctionnement à travers des exemples développés en Visual Basic.Net ou C# sous Microsoft Visual Studio, exécutables en mode console.
2. Concepts fondamentaux (Terminologie)
Objet
Un objet est une abstraction codée d'une entité ou d'une relation du monde réel (une base de données, un enregistrement, etc.). Un objet résulte de l'instanciation d'une classe ou, dans le cadre de Sage 100 Objets Métiers, peut être créé par un autre objet de type "Factory".
Classe
Une classe permet de créer (instancier) un objet. Elle se décompose en :
L'implémentation : code et données internes (encapsulation)
L'interface : méthodes et propriétés visibles
Deux classes de type "Application" sont proposées :
Classe | Description |
|---|---|
| Accès à une base commerciale |
| Accès à une base comptable |
Interface
Deux types d'interfaces :
Interfaces "Factory" (
IBITypeObjectFactory) : créent de nouveaux objetsInterfaces Objets Métiers (
IBIPersistObject) : résultent de l'appel des interfaces Factory
Méthode / Propriété
Une méthode exécute une action ou retourne une valeur (ex : Solde(), Remove(), Write()). Une propriété correspond à l'état ou à la valeur d'un élément (ex : CT_Intitule, IsModified).
Collection
Une collection (IBICollection) regroupe plusieurs objets de même type, parcourable et accessible par index.
Processus
Un processus est une entité métier gérant des automatismes sur un ou une collection d'enregistrements. Il implémente :
CanProcess(): vérifie la cohérence avant insertionProcess(): valide et insère réellement les donnéesErrors(IFailInfoCol) : collection d'erreurs
Identifiant
Clé unique créée pour chaque objet, sous forme de stream. Les identifiants générés sur des objets persistants garantissent d'accéder au même objet après déconnexion/reconnexion. Pour les objets non persistants, l'identifiant n'est valable que pendant la connexion en cours.
Prédicats (depuis v10.05)
Permettent de retourner une collection triée et filtrée sur des critères paramétrables, avec optimisation (collections de pointeurs). La propriété ListForward remplace List avec les mêmes optimisations.
3. Pré-requis et installation
Compatibilité
Sage 100 Objets Métiers version 3.10 permet l'accès aux bases Sage 100c Essentials, Standard et Premium version 3.xx. Environnement minimum : Windows 7 SP1.
Tables accessibles en lecture/écriture
Tables paramètres, comptes généraux/analytiques/reportings
Écritures générales et analytiques, modèles de saisie/grille/règlement
Codes journaux, banques, familles et articles
Ressources et centres de charges, tiers
Documents des ventes, achats, stocks et internes
Dépôts de stockage et emplacements, lots, collaborateurs, glossaires, barèmes
Types de documents non créables
Facture Comptabilisée, Archive, Dépréciation de stock, Tickets (non accessibles en lecture)
Installation du kit de développement
Fichiers installés :
Objets100c.dll: ActiveX Sage 100 Objets MétiersCA Articles.xls: fichier d'exemple ExcelAnnuaire: projet Vb.Net (ExempleWindows.sln)
Deux types d'installation :
Standard :
Program Files\Fichiers Communs\Sage\Objets métiers\Objets100c.dllSide By Side (SxS) : cohabitation de plusieurs versions dans
%Windir%\WinSXS
Exemple de manifest de dépendance :
xml
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="com.sage.cobj.100c"
version="3.1.0.1" processorArchitecture="x86"
publicKeyToken="77d7af533b8e0189" />
</dependentAssembly>
</dependency>Déploiement
Deux setups disponibles :
kitobjets100c_100.exe: Kit Revendeurobjets100c_100.exe: Runtime Utilisateur
Génération d'un setup silencieux :
text
c:\redist\objets100c_100.exe -rInstallation silencieuse :
text
c:\redist\objets100c_100.exe -s -f1c:\test\setup.iss -f2c:\test\setup.logOptions de compilation
L'ActiveX est une librairie 32 bits. Il faut impérativement compiler en mode x86 (Target CPU : x86) pour fonctionner sur un environnement 64 bits.
4. Accès aux bases de données
L'interface IBIPersistStream
Classes de base :
BSCPTAApplication100c: base comptableBSCIALApplication100c: base commerciale
Création d'une base comptable (C#)
csharp
using Objets100cLib;
using System;
class Program
{
static void Main()
{
BSCPTAApplication100c baseCpta = new BSCPTAApplication100c();
if (CreeBaseCpta(baseCpta, @"C:\temp\test1.mae"))
Console.WriteLine("Base comptable correctement créée !");
}
static bool CreeBaseCpta(BSCPTAApplication100c baseCpta, string nomBase)
{
try
{
baseCpta.Name = nomBase;
baseCpta.Create();
return true;
}
catch (Exception ex)
{
Console.WriteLine("Erreur en création de base comptable : {0}", ex.Message);
return false;
}
}
}Ouverture / Fermeture d'une base comptable
csharp
static bool OuvreBaseCpta(BSCPTAApplication100c baseCpta, string nomBase,
string utilisateur = "<Administrateur>", string motDePasse = "")
{
try
{
baseCpta.Name = nomBase;
baseCpta.Loggable.UserName = utilisateur;
baseCpta.Loggable.UserPwd = motDePasse;
baseCpta.Open();
return true;
}
catch (Exception ex)
{
Console.WriteLine("Erreur en ouverture : {0}", ex.Message);
return false;
}
}
static bool FermeBaseCpta(BSCPTAApplication100c baseCpta)
{
try
{
baseCpta.Close();
return true;
}
catch (Exception ex)
{
Console.WriteLine("Erreur en fermeture : {0}", ex.Message);
return false;
}
}Création / Ouverture d'une base commerciale
Une base commerciale est toujours liée à une base comptable. Il faut donc instancier deux classes :
csharp
BSCPTAApplication100c baseCpta = new BSCPTAApplication100c();
BSCIALApplication100c baseCial = new BSCIALApplication100c();
baseCpta.Name = @"C:\temp\Bijou.mae";
baseCpta.Loggable.UserName = "<Administrateur>";
baseCpta.Loggable.UserPwd = "";
baseCpta.Open();
baseCial.CptaApplication = baseCpta;
baseCial.Name = @"C:\temp\Bijou.gcm";
baseCial.Loggable.UserName = "<Administrateur>";
baseCial.Loggable.UserPwd = "";
baseCial.Open();À la place de Name, on peut utiliser CompanyServer et CompanyDatabaseName pour une connexion SQL directe :
csharp
baseCial.CompanyServer = @".\SQL2017";
baseCial.CompanyDatabaseName = "BIJOU";
baseCial.Loggable.UserName = "<Administrateur>";
baseCial.Loggable.UserPwd = "";
baseCial.Open();5. Manipulation des enregistrements
Les interfaces IBIPersistObject et IBITypeObjectFactory
IBIPersistObject : représentation en mémoire des enregistrements de la base
IBITypeObjectFactory : fabrique de nouveaux objets
Propriétés et méthodes clés de IBIPersistObject :
Propriété/Méthode | Description |
|---|---|
| Au moins une propriété modifiée |
| Objet lié à un enregistrement |
| Identifiant de l'objet |
| Objet application dont dépend l'objet |
| Lecture de l'objet |
| Relit si modifié |
| Suppression |
| Initialisation de valeurs par défaut |
| Écriture dans la base |
| Écriture + sous-objets liés |
| Sérialisation de l'identifiant |
Méthodes de IBITypeObjectFactory :
Méthode | Description |
|---|---|
| Création d'un nouvel objet |
| Collection complète |
| Collection optimisée |
| Lecture par identifiant |
| Lecture depuis un stream |
| Collection filtrée par prédicat |
Création d'un nouvel objet Client (C#)
csharp
BSCPTAApplication100c baseCpta = new BSCPTAApplication100c();
IBOClient3 objetClient = null;
if (OuvreBaseCpta(baseCpta, @"C:\temp\Bijou.mae"))
{
objetClient = baseCpta.FactoryClient.Create();
Console.WriteLine("Objet Client créé !");
FermeBaseCpta(baseCpta);
}Lecture d'un enregistrement (Devise)
csharp
IBPDevise2 devise = baseCpta.FactoryDevise.ReadIntitule("Dollar US");
Console.WriteLine("Lecture de l'enregistrement Devise {0}!", "Dollar US");Enregistrement d'un objet Client
csharp
static bool EnregistreObjetClient(IBOClient3 objetClient,
string numCompteClient, string intituleCompteClient)
{
try
{
objetClient.CT_Num = numCompteClient;
objetClient.CT_Intitule = intituleCompteClient;
objetClient.Write();
return true;
}
catch (Exception ex)
{
Console.WriteLine("Erreur en enregistrement : {0}", ex.Message);
return false;
}
}Suppression d'un enregistrement
csharp
IBOTiers3 objetTiers = baseCpta.FactoryTiers.ReadNumero("ZAN");
objetTiers.Remove();Le cache en lecture
Lorsqu'un enregistrement est lu, un objet est créé en mémoire et un cache stocke les identifiants. Avantages :
Accélération de la lecture
Cohérence des propriétés entre objets pointant vers le même enregistrement
Propagation des modifications
Particularités multi-utilisateurs :
Un cache distinct par Stream (application)
L'application Sage 100c n'utilise jamais le cache
Si Sage 100c modifie/supprime un enregistrement, une notification est envoyée (état "modifié" ou "supprimé") et une exception est déclenchée lors de la prochaine modification
Exemple de traitement des notifications :
csharp
public static void MAJCacheTiers(ref IBOTiers3 objTiers)
{
try
{
if (((BSCPTAApplication100c)objTiers.Stream).FactoryTiers.ExistNumero(objTiers.CT_Num))
objTiers.Read();
else
objTiers = null;
}
catch (Exception ex)
{
Console.WriteLine("Erreur : " + ex.Message);
}
}Les collections
csharp
IBICollection colTiers = baseCpta.FactoryTiers.List;
Console.WriteLine("La base de données contient {0} tiers.", colTiers.Count);
IBOTiers3 tiers = colTiers.Item(colTiers.Count);
Console.WriteLine("Le dernier tiers se nomme {0}.", tiers.CT_Intitule);
foreach (IBOTiers3 t in colTiers)
Console.WriteLine("{0}", t.CT_Num);Les liens entre les objets
Un sous-objet ne peut être créé qu'à partir d'un objet maître persistant. Exception : le processus IPMDocument permet d'ajouter des lignes à un document non persistant.
Exemple d'ajout d'un contact à un tiers existant :
csharp
IBOTiers3 tiers = baseCpta.FactoryTiers.ReadNumero("CARAT");
IBOTiersContact3 contact = tiers.FactoryTiersContact.Create();
contact.Nom = "Vinson";
contact.Prenom = "Virginie";
contact.Fonction = "Comptable";
contact.Telecom.Telephone = "12 34 56 78 90";
contact.ServiceContact = baseCpta.FactoryServiceContact.ReadIntitule("Direction");
contact.Write();Initialisation des objets - SetDefault()
SetDefault() initialise certaines propriétés avec des valeurs par défaut si elles ne sont pas renseignées. Exemple pour IBOTiers3 :
Si
CT_Intitule = ""→CT_Intitule = CT_NumSi
TiersPayeur = Nothing→TiersPayeur = TiersSi
CompteGPrinc = Nothing→ compte collectif par défaut
WriteDefault() effectue en plus :
Héritage de propriétés (ex : tarifs famille → article)
Création d'enregistrements liés (ex : adresse de livraison principale)
Modification de propriétés liées (ex : proratisation analytique)
Verrouillage en modification
Lorsqu'une propriété est modifiée, l'enregistrement est verrouillé. Le verrou est levé par Write() ou Read(). En cas d'échec, Read() réinitialise les propriétés.
csharp
static bool ModifieAdresseTiers(IBOTiers3 objetTiers, Adresse nouvelleAdresse)
{
try
{
objetTiers.Adresse.Adresse = nouvelleAdresse.Adresse;
objetTiers.Adresse.Complement = nouvelleAdresse.Complement;
objetTiers.Adresse.CodePostal = nouvelleAdresse.CP;
objetTiers.Adresse.Ville = nouvelleAdresse.Ville;
objetTiers.Write();
return true;
}
catch (Exception ex)
{
Console.WriteLine("Erreur : {0}", ex.Message);
if (objetTiers.IsPersistant) objetTiers.Read();
return false;
}
}6. Développement .Net et encapsulation
Pour utiliser les objets COM avec des composants .Net, il est recommandé de les encapsuler.
csharp
public class ControlObjet100
{
private IBIPersistObject mPersistObject;
public ControlObjet100(IBIPersistObject obj) { mPersistObject = obj; }
public virtual IBIPersistObject GetObject() { return mPersistObject; }
public override string ToString() { return ""; }
}
public class CBOtiers : ControlObjet100
{
public CBOtiers(IBIPersistObject obj) : base(obj) { }
public override string ToString() { return GetInterface().CT_Num; }
public IBOtiers3 GetInterface() { return (IBOTiers3)GetObject(); }
}
// Utilisation dans un formulaire
foreach (IBOTiers3 tiers in baseCpta.FactoryTiers.ListOrderNumero)
comboBoxTiers.Items.Add(new CBOtiers(tiers));
// Récupération
string numero = ((CBOtiers)comboBoxTiers.SelectedItem).GetInterface().CT_Num;7. Processus métiers
7.1 Processus Encoder (IPMEncoder)
Insère une collection d'écritures comptables en une seule fois, garantissant l'équilibre de la période.
csharp
BSCPTAApplication100c baseCpta = new BSCPTAApplication100c();
baseCpta.Name = @"C:\temp\Bijou.mae";
baseCpta.Open();
IPMEncoder processus = baseCpta.CreateProcess_Encoder();
processus.Journal = baseCpta.FactoryJournal.ReadNumero("VE");
processus.Date = new DateTime(2012, 3, 1);
processus.EC_Intitule = "Facture client";
IBOTiers3 tiers = baseCpta.FactoryTiers.ReadNumero("TOPAZ");
IBOCompteG3 compteCharge = baseCpta.FactoryCompteG.ReadNumero("701019");
IBOCompteG3 compteTVA = baseCpta.FactoryCompteG.ReadNumero("4457119");
IBOCompteG3 compteTiers = tiers.CompteGPrinc;
processus.AddTiersPart(tiers, 40000, compteCharge, compteTVA, compteTiers);
if (processus.CanProcess)
processus.Process();
else
foreach (IFailInfo err in processus.Errors)
Console.WriteLine($"Erreur {err.ErrorCode} : {err.Text}");7.2 Processus Création de document (IPMDocument)
Crée un document complet (entête + lignes) en une seule fois. Pour un article nomenclaturé, les lignes composantes sont automatiquement ajoutées.
csharp
BSCIALApplication100c baseCial = new BSCIALApplication100c();
// ... ouverture ...
IPMDocument processus = baseCial.CreateProcess_Document(DocumentType.DocumentTypeVenteFacture);
IBODocumentVente3 doc = (IBODocumentVente3)processus.Document;
doc.SetDefaultClient(baseCial.CptaApplication.FactoryClient.ReadNumero("CARAT"));
doc.SetAutoRecalcUTotaux(false);
processus.AddArticleReference("ENSHF", 10);
foreach (IBODocumentVenteLigne3 lig in doc.FactoryDocumentLigne.List)
lig.SetDefaultRemise();
if (!processus.CanProcess)
{
foreach (IFailInfo err in processus.Errors)
Console.WriteLine($"Erreur {err.ErrorCode} : {err.Text}");
}
else
{
processus.Process();
}7.3 Processus de contrôle qualité (IPMControlerQualite)
csharp
IPMControllerQualite pQualite = baseCial.CreateProcess_ControllerQualite;
pQualite.Domain = DomainType.DomainTypeAchat;
pQualite.PeriodDO_Date.Start = new DateTime(2011, 1, 1);
pQualite.PeriodDO_Date.End = new DateTime(2011, 12, 31);
pQualite.TypeDocumentRetour = DocumentType.DocumentTypeAchatFacture;
foreach (IBODocumentLigneEmplacement mLigEmp in pQualite.QueryLigneEmplacement)
{
if (mLigEmp.DocumentLigne.Article.AR_Ref == "BAAR01")
{
pQualite.Valider(mLigEmp, 42);
pQualite.Retourner(mLigEmp, 8, "Erreur de commande");
}
}
if (pQualite.CanProcess)
pQualite.Process();7.4 Processus d'application des barèmes (IPMAppliquerBareme)
csharp
IBODocumentVente3 mDoc = baseCial.FactoryDocumentVente.ReadPiece(
DocumentType.DocumentTypeVenteCommande, "BC00197");
IPMAppliquerBareme pBareme = baseCial.CreateProcess_AppliquerBareme(mDoc);
if (pBareme.CanProcess)
pBareme.Process();7.5 Processus de colisage (IPMColiser)
csharp
IPMColiser pColiser = baseCial.CreateProcess_Coliser;
IBODocumentVente3 pDoc = baseCial.FactoryDocumentVente.ReadPiece(
DocumentType.DocumentTypeVentePrepaLivraison, "PL00014");
int iCpt = 1;
foreach (IBODocumentVenteLigne3 pLig in pDoc.FactoryDocumentLigne.List)
{
pColiser.LigneOrigine = pLig;
while (pColiser.QteRestantAColiser > 0)
{
((IUserColis)pColiser.UserColis.AddNew()).Set("Colis" + iCpt, 1);
iCpt++;
}
if (pColiser.CanProcess) pColiser.Process();
}7.6 Processus de prélèvement Série/Lot (IPMPreleverLot)
csharp
IPMPreleverLot pPrelever = baseCial.CreateProcess_PreleverLot;
pPrelever.LigneOrigine = pLig;
pPrelever.UserLots.RemoveAll();
IBODepot3 pDepot = pLig.Depot;
IBOArticleDepot3 pArtDepot = pLig.Article.FactoryArticleDepot.ReadDepot(pDepot);
foreach (IBOArticleDepotLot pArtDepotLot in pArtDepot.FactoryArticleDepotLot.QueryNonEpuise)
{
if (pPrelever.QteRestantARepartir == 0) break;
double dQte = pArtDepotLot.StockATerme;
if (dQte > 0)
{
IUserLot mUserLot = pPrelever.UserLots.AddNew();
if (pPrelever.QteRestantARepartir >= dQte)
mUserLot.Set(pArtDepotLot, dQte, pArtDepotLot.Complement);
else
mUserLot.Set(pArtDepotLot, pPrelever.QteRestantARepartir, pArtDepotLot.Complement);
}
}
if (pPrelever.CanProcess) pPrelever.Process();7.7 Processus de transfert d'article (IPMDocTransferer)
csharp
// Transfert dans un document existant
IBODocumentStock3 mDoc = baseCial.FactoryDocumentStock.ReadPiece(
DocumentType.DocumentTypeStockVirement, "MT00021");
IPMDocTransferer pTransfert = baseCial.CreateProcess_DocTransferer;
pTransfert.Document = mDoc;
pTransfert.SetDefaultArticle(baseCial.FactoryArticle.ReadReference("BAAR01"), 10);
if (pTransfert.CanProcess) pTransfert.Process();Pour un article géré par lot :
csharp
pTransfert.SetDefaultArticle(mArt, 2);
pTransfert.UserLotsToUse.RemoveAll();
IUserLot mUserLot = pTransfert.UserLotsToUse.AddNew();
IBOArticleDepotLot mArtDepotLot = mArt.FactoryArticleDepot.ReadDepot(mDepot)
.FactoryArticleDepotLot.ReadNoSerie("LINGOR001");
mUserLot.Lot = mArtDepotLot;
mUserLot.QteToUse = 2;
pTransfert.DepotEmplDest = mDepot.FactoryDepotEmplacement.ReadCode("A3T1N2P2");7.8 Processus de transformation de documents (IPMDocTransformer)
csharp
// Transformation d'une ligne de devis dans un nouveau bon de commande
IPMDocTransformer pTransfo = baseCial.Transformation.Vente.CreateProcess_Commander;
IBODocumentVente3 pDoc = baseCial.FactoryDocumentVente.ReadPiece(
DocumentType.DocumentTypeVenteDevis, "DE00036");
if (pDoc.FactoryDocumentLigne.List.Count > 0)
{
IBODocumentVenteLigne3 pLig = pDoc.FactoryDocumentLigne.List[1];
pTransfo.AddDocumentLigne(pLig);
if (pTransfo.CanProcess)
pTransfo.Process();
}Pour affecter manuellement les numéros de série/lot :
csharp
IPMDocTransformer pTransfo = baseCial.Transformation.Vente.CreateProcess_Livrer;
IBODocumentVente3 pDoc = baseCial.FactoryDocumentVente.ReadPiece(
DocumentType.DocumentTypeVenteDevis, "DE00002");
pTransfo.AddDocument(pDoc);
foreach (IBODocumentVenteLigne3 pLig in pTransfo.ListLignesATransformer)
{
if (pLig.Article.AR_SuiviStock == SuiviStockType.SuiviStockTypeSerie)
SetSerie(pTransfo, pLig);
else if (pLig.Article.AR_SuiviStock == SuiviStockType.SuiviStockTypeLot)
SetLot(pTransfo, pLig, hashTb);
}
if (pTransfo.CanProcess) pTransfo.Process();7.9 Processus de lettrage (IPMLettrer)
csharp
IPMLettrer pLettre = baseCpta.CreateProcess_Letter();
pLettre.AddEcriture(baseCpta.FactoryEcriture.ReadNumero(479));
pLettre.AddEcriture(baseCpta.FactoryEcriture.ReadNumero(146));
pLettre.AddEcriture(baseCpta.FactoryEcriture.ReadNumero(485));
pLettre.AddEcriture(baseCpta.FactoryEcriture.ReadNumero(1194));
pLettre.Type = LettrageType.LettrageTypeLettrageMontant;
pLettre.SetDefaultLettre();
if (pLettre.CanProcess) pLettre.Process();7.10 Processus d'insertion de ligne de sous-total (IPMDocInsererSousTotal)
csharp
IPMDocument pProc = baseCial.CreateProcess_Document(DocumentType.DocumentTypeVenteCommande);
IBODocumentVente3 mDoc = (IBODocumentVente3)pProc.Document;
mDoc.SetDefaultClient(baseCial.CptaApplication.FactoryClient.ReadNumero("CARAT"));
mDoc.WriteDefault();
IPMDocInsererSousTotal pSousTotal = baseCial.CreateProcess_SousTotal(mDoc);
IBODocumentVenteLigne3 mLig = mDoc.FactoryDocumentLigne.Create();
mLig.SetDefaultArticle(baseCial.FactoryArticle.ReadReference("GRAVURE"), 1);
mLig.WriteDefault();
pSousTotal.AddDocumentLigne(mLig);
mLig = mDoc.FactoryDocumentLigne.Create();
mLig.SetDefaultArticle(baseCial.FactoryArticle.ReadReference("BAAR01"), 1);
mLig.WriteDefault();
pSousTotal.AddDocumentLigne(mLig);
if (pSousTotal.CanProcess)
{
pSousTotal.Process();
if (pProc.CanProcess) pProc.Process();
}7.11 Processus de recalcul du prix de revient (IPMDocRecalculPrixCompose)
csharp
IBODocumentStock3 pDoc = baseCial.FactoryDocumentStock.ReadPiece(
DocumentType.DocumentTypeStockFabrication, "BF00008");
IPMDocRecalculPrixCompose pRecalc = baseCial.CreateProcess_RecalculPrixCompose(pDoc);
foreach (IBODocumentStockLigne3 pLig in pDoc.FactoryDocumentLigne.List)
{
if (pLig.ArticleCompose.Equals(baseCial.FactoryArticle.ReadReference("CHORFA")))
{
if (pLig.Article.Equals(baseCial.FactoryArticle.ReadReference("SVFORMAPP")))
{
pLig.DL_Qte = pLig.DL_Qte - 0.5;
pLig.Write();
}
pRecalc.AddDocumentLigne(pLig);
}
}
if (pRecalc.CanProcess) pRecalc.Process();7.12 Processus de sortie d'article géré par lot (IPMSortirLots)
csharp
// Exemple 1 : sortie par emplacement
IBODocumentVente3 pDoc = baseCial.FactoryDocumentVente.CreateType(
DocumentType.DocumentTypeVenteLivraison);
pDoc.SetDefaultClient(baseCial.CptaApplication.FactoryClient.ReadNumero("CARAT"));
pDoc.WriteDefault();
IBODocumentVenteLigne3 pLig = pDoc.FactoryDocumentLigne.Create();
pLig.SetDefaultArticle(baseCial.FactoryArticle.ReadReference("ARTICLE_LOT"), 10);
IPMSortirLots pProc = baseCial.CreateProcess_SortirLots();
IBODepotEmplacement pDepotEmpl = pDoc.DepotStockage
.FactoryDepotEmplacement.ReadCode("A1T1N1P1");
pProc.SetLigneDefaultLot(pLig, null, pDepotEmpl);
if (pProc.CanProcess) pProc.Process();csharp
// Exemple 2 : sortie par numéro de lot sans emplacement
IPMSortirLots pProc = baseCial.CreateProcess_SortirLots();
pProc.SetLigneDefaultLot(pLig, "LOT1", null);
if (pProc.CanProcess) pProc.Process();7.13 Processus de règlement des échéances (IPMReglerEcheances)
csharp
IBODocumentVente3 doc = baseCial.FactoryDocumentVente.ReadPiece(
DocumentType.DocumentTypeVenteFacture, "FA00028");
IBOTiersPart3 client = doc.TiersPayeur;
IBODocumentReglement iReglt = baseCial.FactoryDocumentReglement.Create();
iReglt.TiersPayeur = client;
iReglt.RG_Date = DateTime.Now;
iReglt.RG_Reference = "Reference";
iReglt.RG_Libelle = "Libelle";
iReglt.RG_Montant = doc.DO_NetAPayer - doc.DO_MontantRegle;
iReglt.Journal = baseCial.CptaApplication.FactoryJournal.ReadNumero("BRD");
iReglt.CompteG = client.CompteGPrinc;
iReglt.WriteDefault();
IPMReglerEcheances pRegler = baseCial.CreateProcess_ReglerEcheances();
pRegler.Reglement = iReglt;
foreach (IBODocumentEcheance3 iEcheance in doc.FactoryDocumentEcheance.List)
pRegler.AddDocumentEcheance(iEcheance);
pRegler.Process();7.14 Processus d'inventaire (IPMInventaire)
csharp
IPMinventaire inventaire = baseCial.CreateProcess_Inventaire();
inventaire.Depot = baseCial.FactoryDepot.ReadIntitule("Bijou SA");
inventaire.DateInventaire = new DateTime(2021, 12, 31);
IBODepotEmplacement pDepotEmpl = inventaire.Depot.FactoryDepotEmplacement.ReadCode("SECTIONBC7");
// Article CMUP
IBOArticle3 article = baseCial.FactoryArticle.ReadReference("BAAR01");
inventaire.AddArticle(article, 7, 233, pDepotEmpl);
// Article double gamme
article = baseCial.FactoryArticle.ReadReference("CHAAR/VAR");
inventaire.AddArticleDoubleGamme(article, 3, 111,
article.FactoryArticleGammeEnum1.ReadEnumere("42 cm"),
article.FactoryArticleGammeEnum2.ReadEnumere("Forçat"), null);
// Article série/lot
article = baseCial.FactoryArticle.ReadReference("LINGOR18");
IBOArticleDepot3 pArtDepot = article.FactoryArticleDepot.ReadDepot(inventaire.Depot);
IBOArticleDepotLot pArtDepotLot = (IBOArticleDepotLot)pArtDepot.FactoryArticleDepotLot
.ReadNoSerie("LOT-BDF111111");
inventaire.AddArticleSerie(article, 5, 66666, pArtDepotLot, pDepotEmpl);
inventaire.Process();
// Résultat : 2 documents (mouvement de sortie + mouvement d'entrée)
foreach (IBODocumentStock3 docStock in inventaire.ListDocuments)
Console.WriteLine(docStock.DO_Type + " " + docStock.DO_Piece);7.15 Processus de conversion d'un prospect en client (IPMConversionClient)
csharp
IBOClient3 prospect = (IBOClient3)baseCial.CptaApplication.FactoryProspect.Create();
prospect.CT_Num = "JADE";
prospect.CT_Intitule = "Prospect Jade";
prospect.CT_Classement = "Jade";
prospect.WriteDefault();
IPMConversionClient processConversion = baseCial.CreateProcess_ConversionClient(prospect);
processConversion.Intitule = "Client Jade";
processConversion.NumPayeur = prospect;
processConversion.NumPrinc = baseCial.CptaApplication.FactoryCompteG.ReadNumero("4110000");
try
{
processConversion.Process();
}
catch
{
for (int i = 1; i <= processConversion.Errors.Count; i++)
Console.WriteLine(processConversion.Errors[i].Text);
}7.16 Processus Bon à Payer (IPMBonAPayer)
csharp
IBOCollaborateur cCollabo = baseCpta.FactoryCollaborateur.ReadNomPrenom("PLATY", "Nelly");
cCollabo.Financier = true;
cCollabo.Write();
IBPBonAPayer bonAPayer = (IBPBonAPayer)baseCpta.FactoryBonAPayer.List[1];
bonAPayer.Responsable = cCollabo;
bonAPayer.Autorisation = eBAPAutorisationType.BAP_Financier;
bonAPayer.Facture = eBAPAValider.BAP_SelonMontant;
bonAPayer.SeuilValidation = 999;
bonAPayer.Write();
IBOEcriture3 cEcrit = baseCpta.FactoryEcriture.ReadNumero(65);
IPMBonAPayer pBonAPayer = baseCpta.CreateProcess_BAPPayer(cCollabo);
pBonAPayer.Commentaire = "Ok pour Payer";
pBonAPayer.Ecriture = cEcrit;
pBonAPayer.Process();8. Gestion des identifiants (Sérialisation / Désérialisation)
L'identifiant se présente sous la forme :
text
[Numéro de version d'interface][Interface][Identifiant Sage 100c]Exemple : 1114112|com.sage.om.cpta.CLIENT|CARAT
Classe d'implémentation de IStream (C#)
csharp
public class ImplementIStream : IStream, IDisposable
{
private Stream _mStream;
public ImplementIStream(Stream s) { _mStream = s; }
public void Clone(out IStream ppsm)
{
MemoryStream memBuffer = new MemoryStream();
byte[] memByte = new byte[_mStream.Length];
_mStream.Read(memByte, 0, memByte.Length);
memBuffer.Write(memByte, 0, memByte.Length);
ppsm = new ImplementIStream(memBuffer);
}
public void Commit(uint grfCommitFlags) { _mStream.Flush(); }
public void LockRegion(_ULARGE_INTEGER libOffset, _ULARGE_INTEGER cb, uint dwLockType) { }
public void RemoteCopyTo(IStream pstm, _ULARGE_INTEGER cb,
out _ULARGE_INTEGER pcbRead, out _ULARGE_INTEGER pcbWritten)
{
pcbRead.QuadPart = pcbWritten.QuadPart = 0;
}
public unsafe void RemoteRead(out byte pv, uint cb, out uint pcbRead)
{
fixed (byte* bBuffer = &pv)
{
byte* pByte = bBuffer;
long remainsRead = _mStream.Length - _mStream.Position;
uint remains = (uint)(remainsRead > cb ? cb : remainsRead);
for (uint i = 0; i < remains; i++)
{
*pByte = (byte)_mStream.ReadByte();
pByte++;
}
pcbRead = remains;
}
}
public unsafe void RemoteWrite(ref byte pv, uint cb, out uint pcbWritten)
{
byte[] arBuf = new byte[cb];
fixed (byte* bBuffer = &pv)
{
byte* pByte = bBuffer;
for (int i = 0; i < cb; i++)
{
arBuf[i] = *pByte;
_mStream.WriteByte(*pByte);
pByte++;
}
}
pcbWritten = cb;
}
public void RemoteSeek(_LARGE_INTEGER dlibMove, uint dwOrigin,
out _ULARGE_INTEGER plibNewPosition)
{
ulong pos = (ulong)_mStream.Seek(dlibMove.QuadPart, (SeekOrigin)dwOrigin);
plibNewPosition.QuadPart = pos;
}
public void Revert() { }
public void SetSize(_ULARGE_INTEGER libNewSize) { _mStream.SetLength((long)libNewSize.QuadPart); }
public void Stat(out tagSTATSTG pstatstg, uint grfStatFlag) { pstatstg = new tagSTATSTG(); }
public void UnlockRegion(_ULARGE_INTEGER libOffset, _ULARGE_INTEGER cb, uint dwLockType) { }
public override string ToString()
{
StreamReader reader = new StreamReader(_mStream);
_mStream.Seek(0, SeekOrigin.Begin);
return reader.ReadToEnd();
}
public void Dispose()
{
if (_mStream == null) return;
_mStream.Dispose();
_mStream = null;
}
}Sérialisation d'un tiers dans une chaîne
csharp
public string SerializeTiersToString(string ctnum)
{
string sKey = "";
try
{
IBOTiers3 pTiers = _mCpta.FactoryTiers.ReadNumero(ctnum);
MemoryStream mMemStream = new MemoryStream();
ImplementIStream mStream = new ImplementIStream(mMemStream);
pTiers.WriteTo(mStream);
sKey = mStream.ToString();
}
catch (Exception ex) { Console.WriteLine(ex.Message); }
return sKey;
}Désérialisation depuis un fichier
csharp
public string UnSerializeFileStream(string sPath)
{
try
{
FileStream mFileStream = new FileStream(sPath, FileMode.Open);
ImplementIStream mStream = new ImplementIStream(mFileStream);
IBIPersistObject mObj = _mCpta.ReadFrom(mStream);
if (mObj is IBOTiers3)
return ((IBOTiers3)mObj).CT_Num;
}
catch (Exception ex) { Console.WriteLine(ex.Message); }
return "";
}9. Gestion des prédicats
csharp
IPredicateBuilder predBuilder = (IPredicateBuilder)mCptaApplication;
// Prédicat simple : CG_Num commence par "7"
IPredicateComparison pred2 = (IPredicateComparison)predBuilder.Create(
ePredicateType.PredicateTypeComparison);
pred2.PredicateTypeComparison = ePredicateTypeComparison.PredicateTypeComparisonBegins;
pred2.Key = "CG_Num";
pred2.Values.Add("7");
IBICollection col = mCptaApplication.FactoryCompteG.QueryPredicate(pred2, "CG_Num");
col = mCptaApplication.FactoryCompteG.QueryPredicate(pred2, "- CG_Num"); // tri descendant
// Prédicat composé (OR)
IPredicateCompound pred4 = (IPredicateCompound)predBuilder.Create(
ePredicateType.PredicateTypeCompound);
pred4.PredicateTypeCompound = ePredicateTypeCompound.PredicateTypeCompoundOr;
IPredicateComparison sousPred41 = (IPredicateComparison)pred4.Predicates.AddNew(
ePredicateType.PredicateTypeComparison);
sousPred41.Key = "CG_Num";
sousPred41.Values.Add("701005");
IPredicateComparison sousPred42 = (IPredicateComparison)pred4.Predicates.AddNew(
ePredicateType.PredicateTypeComparison);
sousPred42.Key = "CG_Type";
sousPred42.Values.Add(1);
col = mCptaApplication.FactoryCompteG.QueryPredicate(pred4, "CG_Num;CG_Intitule");10. Récupération et traitement des erreurs
csharp
try
{
tiers.CT_Num = "NUMERO_DE_COMPTE_TIERS_DE_PLUS_DE_17_CARACTERES";
}
catch (Exception ex)
{
Console.WriteLine("Erreur ! {0}", ex.Message);
}Les fonctions de la documentation acceptent des paramètres et retournent un booléen indiquant si le traitement s'est correctement terminé, avec interception des erreurs via Try...Catch.
11. Exemples avancés
Gestion des coûts des articles
csharp
IBOArticle3 article = baseCial.FactoryArticle.ReadReference("BAAR01");
// Paramétrage des 3 frais
CreeFraisArticle(article, 1, null, "2U"); // Coût de stockage
CreeFraisArticle(article, 2, null, "10%+1U"); // Coût de transport
CreeFraisArticle(article, 3, "Coût de manutention", "8%+50F+10U");
article.Write();
// Calcul
double montantUnitaire = 100, qte = 10;
double frais = article.AR_Frais.Calcul(montantUnitaire, qte, 2);
void CreeFraisArticle(IBOArticle3 art, int index, string intitule, string modeCalcul)
{
art.AR_Frais.Frais[index].FR_Denomination = intitule ?? art.AR_Frais.Frais[index].FR_Denomination;
art.AR_Frais.Frais[index].Remise.FromString(modeCalcul ?? art.AR_Frais.Frais[index].Remise.ToString());
}Gammes de remise par catégorie tarifaire
csharp
IBOArticle3 article = baseCial.FactoryArticle.ReadReference("BAAR01");
IBPCategoryTarif catTarifaire = ((BSCIALApplication100c)article.Stream)
.FactoryCategoryTarif.ReadIntitule("Detaillants");
IBOArticleTarifCategory3 catTarifArticle = article.FactoryArticleTarifCategory.Create();
catTarifArticle.CategorieTarif = catTarifaire;
catTarifArticle.GammeRemise = ((BSCIALApplication100c)catTarifArticle.Stream)
.FactoryGamme.ReadIntitule("Quantite");
catTarifArticle.WriteDefault();
// Affectation des bornes de remise
int nbBorneSup = catTarifArticle.FactoryArticleTarifQte.List.Count;
for (int i = 0; i < nbBorneSup; i++)
{
IBOArticleTarifQteCategory3 tarifQte = catTarifArticle.FactoryArticleTarifQte.List.Item(i + 1);
tarifQte.Remise.FromString(remises[i]);
tarifQte.Write();
}Articles à gammes
csharp
IBOArticle3 article = baseCial.FactoryArticle.ReadReference("CHAAR/VAR");
// Ajout d'un énuméré de gamme et d'une référence
IBOArticleGammeEnum3 gammeEnum1 = article.FactoryArticleGammeEnum1.Create();
gammeEnum1.EG_Enumere = "68 cm";
gammeEnum1.Write();
IBOArticleGammeEnumRef3 gammeRef = gammeEnum1.FactoryArticleGammeEnumRef.Create();
gammeRef.AE_Ref = "CHAARVARC68";
gammeRef.AE_CodeBarre = "38141030";
gammeRef.AE_PrixAch = 180;
gammeRef.Write();Informations libres
csharp
IBOClient3 client = baseCpta.FactoryClient.ReadNumero("CARAT");
// Lecture du paramétrage
foreach (IBIField infoLibre in baseCpta.FactoryTiers.InfoLibreFields)
{
Console.WriteLine("Intitulé : " + infoLibre.Name);
Console.WriteLine("Type : " + infoLibre.Type);
if (infoLibre.Type == FieldType.FieldTypeCStr)
Console.WriteLine("Longueur : " + infoLibre.Size);
if (infoLibre.IsCalculable)
Console.WriteLine("Formule : " + infoLibre.Formule);
}
// Affectation de valeurs
client.InfoLibre.Item(1) = new DateTime(2009, 1, 1);
client.InfoLibre.Item("Actionnaire_Pal") = "Sage France";
client.InfoLibre.Item("Capital_social") = 15000;
client.Write();Informations complémentaires
csharp
IBOClient client = baseCpta.FactoryClient.ReadNumero("DIAMA");
IBOInfoComplementClientFactory pInfoClifact = client.FactoryInfoComplement;
if (pInfoClifact.ExistCode("CODE2"))
{
IBOInfoComplementClient infoCli = pInfoClifact.ReadCode("CODE2");
InfoType infoT = infoCli.CI_Type;
if (infoT == InfoType.eCDT_MONTANT || infoT == InfoType.eCDT_VALEUR)
{
double dVal = Convert.ToDouble(infoCli.CI_Valeur) * 2;
infoCli.CI_Valeur = dVal.ToString();
infoCli.Write();
}
}
// Document de vente
IBODocumentVente3 docVente = baseCial.FactoryDocumentVente.ReadPiece(
DocumentType.DocumentTypeVenteFacture, "FA00005");
IBOInfoComplementEnteteFactory infoFactDoc = docVente.FactoryInfoComplement;
if (infoFactDoc.ExistCode("CODEFA00005"))
{
IBOInfoComplementEntete infoDoc = infoFactDoc.ReadCode("CODEFA00005");
if (infoDoc.DI_Type == InfoType.eCDT_DATE)
{
DateTime dDate = Convert.ToDateTime(infoDoc.DI_Valeur).AddDays(1);
infoDoc.DI_Valeur = dDate.ToString();
infoDoc.Write();
}
}Écritures comptables
csharp
// Insertion d'écritures de vente de produits soumis à TVA
double montantTTC = montantHT * (1 + compteGHT.Taxe.TA_Taux / 100);
IBOEcriture3 ligneTTC = baseCpta.FactoryEcriture.Create();
ligneTTC.Tiers = baseCpta.FactoryTiers.ReadNumero("CARAT");
ligneTTC.CompteG = baseCpta.FactoryCompteG.ReadNumero("4110000");
ligneTTC.Journal = baseCpta.FactoryJournal.ReadNumero("VE");
ligneTTC.Date = DateTime.Parse("22/08/09");
ligneTTC.EC_Piece = "AXJ48";
ligneTTC.EC_Intitule = "Facture 0508102";
ligneTTC.EC_Sens = EcritureSensType.EcritureSensTypeDebit;
ligneTTC.EC_Montant = montantTTC;
ligneTTC.Write();Modèles de saisie
csharp
IBOModeleEcriture3 modele = null;
foreach (IBOModeleEcriture3 m in baseCpta.FactoryModeleEcriture.List)
{
if (m.PI_Intitule == "Achats intracommunautaires") { modele = m; break; }
}
// Parcours des lignes
foreach (IBOModeleEcritureLigne3 ligne in modele.FactoryModeleEcritureLigne.List)
{
Console.WriteLine("Jour : " + ligne.PG_Jour);
Console.WriteLine("N° pièce : " + ligne.PG_Piece);
Console.WriteLine("N° compte général : " + ligne.CG_Num);
Console.WriteLine("Montant : " + ligne.PG_Montant);
Console.WriteLine("Sens : " + ligne.PG_Sens);
}
// Ajout d'une ligne analytique
IBOModeleEcritureLigneA3 nouvLigneA = modele.FactoryModeleEcritureLigne.List[1]
.FactoryModeleEcritureLigneA.Create();
nouvLigneA.Analytique = planAnalytique;
nouvLigneA.CA_Num = "SECTION1";
nouvLigneA.PA_Quantite = "10";
nouvLigneA.PA_Montant = "100";
nouvLigneA.Write();Documents commerciaux
csharp
IBODocumentVente3 docVente = baseCial.FactoryDocumentVente.CreateType(
DocumentType.DocumentTypeVenteDevis);
docVente.SetDefaultClient(baseCial.CptaApplication.FactoryClient.ReadNumero("CARAT"));
IBODocumentVenteLigne3 ligne = docVente.FactoryDocumentLigne.Create();
ligne.SetDefaultArticle(baseCial.FactoryArticle.ReadReference("ENSHF"), 10);
ligne.WriteDefault();Règlements en Gestion commerciale
csharp
IBODocumentVente3 doc = baseCial.FactoryDocumentVente.ReadPiece(
DocumentType.DocumentTypeVenteFacture, "FA00028");
IBOTiersPart3 client = doc.TiersPayeur;
IBODocumentReglement reglement = baseCial.FactoryDocumentReglement.Create();
reglement.TiersPayeur = client;
reglement.RG_Date = DateTime.Now;
reglement.RG_Reference = "Reference";
reglement.RG_Libelle = "Libelle";
reglement.RG_Montant = doc.DO_NetAPayer - doc.DO_MontantRegle;
reglement.Journal = baseCial.CptaApplication.FactoryJournal.ReadNumero("BRD");
reglement.CompteG = client.CompteGPrinc;
reglement.WriteDefault();12. Annexes - Interfaces principales
Interfaces communes
Interface | Description |
|---|---|
| Collection d'objets |
| Collection générique non persistante |
| Contact (nom, prénom, fonction, service, télécom) |
| Champ information libre |
| Collection de champs |
| Autorisations d'accès (UserName, UserPwd) |
| Fichier multimédia |
| Identifiant d'objet |
| Objet persistant |
| Base de données |
| Fabrique d'objets |
| Collection de valeurs (informations libres) |
| Collection d'énumérés statistiques |
| Informations d'adresse |
| Liste des bases SQL |
| Informations base de données |
| Période de date |
| Élément devise |
| Licences |
| Informations télécommunication |
Classes d'application
Classe | Description |
|---|---|
| Base comptable |
| Base commerciale |
Interfaces Factory paramètres (IBPxxxFactory)
IBPAnalyseFactory, IBPAnalytiqueFactory3, IBPCodeRisqueFactory, IBPContactFactory, IBPDeviseFactory2, IBPRappelFactory, IBPReglementFactory3, IBPServiceContactFactory, IBPStructBanqueFactory, IBPTiersStatFactory, IBPTiersFactory, IBPBonAPayer
Interfaces Factory métiers (IBOxxxFactory)
IBOBanqueFactory, IBOBanqueRibFactory, IBOClientFactory3, IBOClientLivraisonAllFactory, IBOClientProspectFactory, IBOClientTarifFactory3, IBOCompteAFactory3, IBOCompteGFactory3, IBOCompteRFactory, IBODossierContactFactory2, IBOEcritureFactory3, IBOEcritureAFactory2, IBOFournisseurFactory3, IBOJournalFactory3, IBOModeleEcritureFactory2, IBOModeleGrilleFactory, IBOModeleReglementFactory, IBOPaysFactory, IBOProspectFactory, IBOTaxeFactory3, IBOTiersCompteGFactory3, IBOTiersFactory3, etc.
Interfaces Processus
Interface | Description |
|---|---|
| Interface de base des processus |
| Saisie de pièce comptable |
| Lettrage d'écritures |
| Création de documents commerciaux |
| Application des barèmes |
| Contrôle qualité |
| Colisage |
| Transfert d'article |
| Transformation de documents |
| Prélèvement Série/Lot |
| Insertion de ligne de sous-total |
| Recalcul de prix de revient |
| Sortie d'article géré par lot |
| Conversion prospect → client |
| Règlement des échéances |
| Inventaire |
| Bon à payer |
| Erreur renvoyée par un processus |
| Collection d'erreurs |
13. Énumérateurs principaux
Énumérateur | Valeurs |
|---|---|
| Document, Fabrication, Interesse |
| FinInf, FinProche, FinSup, Inf, Proche, Sup |
| Gamme, RessourceUnitaire, RessourceMultiple, Standard |
| Interesse, Objectif, Domaine, Base, Calcul |
| Objectif, Calcul, Type |
| Client, Fournisseur |
| Auto, Bloque, CodeRisque |
| Fixe, Variable |
| Achat, Vente, VenteAchat |
| Detail, Total |
| Aucun, Detail, Solde |
| Detail, Total |
| Monsieur, Madame, Mademoiselle |
| None, SageSql, SqlServer |
| Standard, Transit, Controle |
| Aucune, A, B, C |
| Certain, Incertain |
| Devis, Commande, Livraison, Facture, Avoir, etc. |
| Achat, Interne, Stock, Ticket, Vente |
| Credit, Debit |
| Central, Detail, Total |
| CStr, Date, Double, Montant, etc. |
| Divers, Montant, PrixNet, Qtes |
| Achat, General, Situation, Tresorerie, Vente |
| LettrageDevise, LettrageMontant, PointageMontant, PrelettrageDevise, PrelettrageMontant |
| Aucun, Composant, Compose, Fabrication, Lies |
| Aucun, BonAchat, Carte, Cheque, Espece |
| Aucun, Cmup, Fifo, Lifo, Lot, Serie |
| Agraire, CEE, IGIC, IRPF, Surtaxe, TPHT, TPPoids, TPTTC, TVADebit, TVAEncaiss |
| Autre, Client, Fournisseur, Salarie |
14. Nouveautés des versions
v6.0 : Publication des dates de modification/création, objets et factory Règlements, processus IPMReglerEcheances, IPMSortirLots
v7.0 : Infos complémentaires (client/document/ligne), optimisations stock, chefs des ventes
v7.20 : ILicence.Version, SetEmplacementEntree, WriteCumulLot, CreateInfoLibre, IPMBonAPayer
v8.00 : Modification énumérés DocumentProvenanceType et DocumentLigneProvenanceType, compteurs dépôt/gamme
v9.00 : TypeLigneRegistre, ITransformationAchat/Vente (Facturer/Preparer), IPMInventaire
v10.00 : Facturation électronique (FluxFiscal, Assujettissement, CodeRoutage, FactCadre), ConserveDocuments
v10.05 : Publication des prédicats
v11.00 : EC_DateRappro et EC_TresoPiece en lecture/écriture, AR_InterdireCommande, AR_Exclure, DO_RefExterne
v12.00 : BanqueRib en lecture/écriture, 10 exercices comptables
v12.20 : CG_ReportAnal, DO_ClauseReserve, champs DGI facture électronique achat
Conclusion
Sage 100 Objets Métiers est une bibliothèque ActiveX complète offrant :
Un accès lecture/écriture aux bases comptables et commerciales Sage 100c
Des contrôles de cohérence automatiques
Des processus métiers couvrant l'ensemble des besoins (comptabilité, ventes, achats, stocks, règlements)
Une gestion fine des collections, du cache et des verrouillages
Des prédicats pour des requêtes optimisées
Une sérialisation des identifiants pour un stockage durable
Les développements doivent être compilés en x86 et il est recommandé d'utiliser le Side By Side pour garantir la compatibilité des versions.