Receiving data via com connection from 1s. Three pillars of working with COM objects. Working over a COM connection is easier than you think. Establish an OLE connection

Print (Ctrl+P)

One of the options for exchanging data between 1C databases is exchange via a COM connection. Using a COM connection, you can connect from one 1C database to another and read or write data. This method can be used both in client-server versions of databases and in file databases. This article discusses these types of connections on platform 8.3

com connection

You can create two types of COM objects for the 1C application. This is ole connections V83.Application and com connections V83.COMConnector . In case of V83.Application An almost full-fledged copy of the 1C application is launched. In case of use V83.COMConnector A small server part is launched. The speed of operation in this case is higher, but some functions may not be available. In particular, working with forms and common modules for which the property of working with external connections is not set. Mostly you should use V83.COMConnector and only in case of lack of functionality V83.Application. The difference in operating speed can be especially noticeable on large-volume databases. For platform 8.2 used V82.Application or V82.COMConnector

Establish an OLE connection

Connection = New COMObject(“V83.Application” ) ;

Establish a COM connection

Connection = New COMObject(“V83.COMConnector” ) ;

Connection string

//For the client-server option
Connection String= “Srvr = ““ServerName” “;Ref = “ “BaseName” ;
//For file mode option:
Connection String= “File = ““PathKBase” “; Usr = UserName; Pwd = Password”;
Attempt
Connection = Connection . Connect(ConnectionString) ;
Exception
Message = New MessageToUser;
Message . Text = “Failed to connect to the database” + DescriptionErrors(); Message . To report();
EndAttempt ;

Disconnection

Connection = Undefined ;
For object V83.Application It is necessary to terminate the connection, otherwise an incomplete session will remain, which will then have to be deleted manually. In case of V83.COMConnector the connection is broken automatically when the procedure in which the connection was made is completed. And there is one more small point. For the user under whom the connection is being made, the “Request confirmation when closing the program” checkbox must be disabled in its settings.

NewObject() method

To create a new object, you can use the NewObject() method, for example:

For V83.COMConnector

RequestCOM = Connection. NewObject( "Request ") ;
TableCOM = Connection. NewObject( “Table of Values”) ;
ArrayCOM = Connection. NewObject(“Array” ) ;

ViewCOM =Connection.NewObject

For V83.Application

RequestOLE = Connection. NewObject(“ Request ") ;
TableOLE = Connection. NewObject(“Table of Values”) ;
ArrayOLE = Connection.NewObject(“Array” ) ;
ViewCOM =Connection.NewObject(“UniqueIdentifier”, StringUID);

RequestCOM . Text ="CHOOSE
| Positions of Organizations. Code,
| Positions of Organizations.Name
|FROM | Directory.Positions of Organizations
HOW TO POSITIONS OF ORGANIZATIONS”;

Result = RequestCOM. Run();
Sample = Result. Choose () ;
Bye Selection. Next()Cycle
EndCycle ;
You can also use configuration object managers:
DirectoryCOM = Connection. Directories. DirectoryName;
DocumentCOM = Connection. Documentation. DocumentName;
RegisterCOM = Connection. Information Registers. RegisterName ;

Receiving and comparing enumeration via COM connection

To compare the values ​​of enumeration elements defined in the configuration, it is necessary to convert these elements to one of the primitive types, the comparison of which is easy. Such types can be either numeric or string type. You can convert the value of an enumeration element to a numeric type like this:

Enum Item = Connection.Directories.Directory1.FindByCode(1).Props1;

PossibleValues ​​= Enum Element.Metadata().Enum Values;

EnumerationElementNumber = PossibleValues.Index(PossibleValues.Find(Connection.XMLString(EnumerationElement)));

If EnumerationItemNumber = 0 Then Report( “Enumer value1”);

ElseIfEnumerationItemNumber = 1 Then Report("EnumerationValue2");

endIf;

Retrieving an object via COM by identifier

Through configuration object managers we get a com object, for example:
DocumentCOM = Connection. Documentation. DocumentName;

Then we get a unique identifier string:

StringUID =Connection.string ( DocumentCOM.UniqueIdentifier())

Identifier = New U uniqueIdentifier(StringUID);
WITH linkByIdentifier = Documents[DocumentName].GetLink(Identifier);

If you need to find a com object by document by identifier, then you need to write like this:

WidCOM = Connection.NewObject(“UniqueIdentifier”, StringUID);
LinkByIdentifier = Connection.Documents[DocumentName].GetLink(WidCOM);

Hello Khabrachans!

In this article I want to talk about how integration with the 1C platform is established in my organization. What prompted me to do this was the almost complete absence technical information about this theme. Reading various articles and reports on the topic of connecting 1C with any information system, you are convinced over and over again that they are all of a marketing, demonstration nature, and never technical, reflecting the problem and the essence of its solution.

I warn you that this method in no way claims to be universal. Since there are many 1C configurations themselves, and information systems, languages ​​and platforms - even more, the number of possible combinations is enormous. My goal is to demonstrate one possible solution.


I chose Python as the language that will be integrated with 1C. It is very well suited for process automation. This is facilitated by the minimalism of the syntax (the code is typed very quickly), rich standard library(less need for third-party modules), cross-platform - with a high probability, code written in Linix OS will work successfully on Windows.

To begin with, I will outline the data with which we will work. The organization is an energy sales company in the Far Eastern region - it serves approximately 400 thousand subscribers, the 1C database is based on a custom configuration. For each subscriber, his payments, charges, consumed services and calculation schemes, meters, readings and many other data are stored.

Once upon a time, an organization had a program written in Delphi and using MSSQL/Firebird as a database. In those glorious times, you could connect to the database using any language and perform many actions - select debtor subscribers, post received payments, record instrument readings. It is not surprising that the collection of scripts that automate the routine has been constantly growing. Programmers could perform any action without opening the program itself.

Alas, with the transition to 1C, the freebie ended - it was no longer possible to connect to the database directly. In general, the 1C platform itself is indivisible and does not lend itself well to integration with other systems. She, as they say, is a thing in itself. When loading data into 1C, you should remember that extracting it from there will not be so easy. But in view of the fact that the organization needed to implement payment systems and Personal Area, it was necessary to find some solution.

The main tasks facing me were the ability to quickly obtain data on a specific personal account- Full name, address, metering devices, meter readings, payments, charges. Plus the generation of documents - reconciliation report, payment receipt. So, there is no possibility of direct connection to the database - anyone who has looked at a 1C database on a SQL server has seen that it is difficult to understand the mass of tables like aaa1, aaa2. And building queries with such table and field names is simply unrealistic. In addition, many 1C tables (especially the most important ones, such as a slice of the latest, balances and revolutions) are virtual and scattered across different physical tables, collected by multiple joins. This method is not suitable.

The 1C platform provides the ability to connect to it via a COM connection. Like many Windows programs, during the installation of 1C two COM objects are registered in the system - Automation Server and COM Connector. Both objects can be worked with using a language that supports COM technology.

The Automation Server object is a 1C application, almost no different from a regular client application. The difference is that there is an additional opportunity program control application instance. When working with a COM Connector object, a lightweight version of the 1C application is launched, in which forms, as well as functions and methods related to the interface and visual effects, are not available. The application itself starts in the “External connection” mode. Initializing global variables (for example, defining current user and its settings) must be performed in the 1C external connection module. If in external connection mode the code calls a function that is not available in this mode, an exception will be thrown (which will be passed to our Python script). Calls to unsafe functions should be framed with constructs of the form

#If NOT an OuterJoin Then Warning("Hello!"); #EndIf

Since working with COM objects is an exclusively windows-only technology, it is not surprising that it is not included in the standard Python distribution. You will need to install an extension - a set of modules that provide all the necessary functionality for programming under Windows in Python. It can be downloaded as a pre-built exe installer. The extension itself provides access to the registry, services, ODBC, COM objects, etc. As an alternative, you can immediately install the ActiveState Python distribution, which comes with a Win32 extension out of the box.

For some time I experimented with a COM connection in developing web applications, in particular, a personal account. The following disadvantages were identified:

The COM connection is slow. Low performance is a well-known disadvantage of COM technology.
- The process of establishing a connection with 1C, depending on the configuration, can take from 1 to 8 seconds (in my case - 6 seconds). Needless to say, establishing a connection for each request will result in each page taking 8 seconds to load.
- Since web applications in Python work as independent servers, the previous point can be compensated by storing the connection in some global variable and restoring it in case of an error. To be honest, I haven’t thought about how to maintain a connection in PHP yet.
- The cross-platform functionality of the web application is lost.

Based on the points listed above, it was decided to change the principle of interaction, dividing it into 2 parts - the first platform-dependent (Window-based), uploading 1C data into any convenient format, and the second, platform-independent, capable of working with data without suspecting anything about 1C in principle.

The action strategy is as follows: the Python script connects to 1C, executes the necessary queries and uploads the data to the SQLite database. You can connect to this database from Python, PHP, Java. Most of our projects work in Python, and since I can’t stand writing raw SQL queries by hand, all work with the SQLite database is done through the SQLAlchemy ORM. All that was required was to describe the database data structure in a declarative style:

From sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, Numeric, DateTime, Unicode, Boolean, LargeBinary, ForeignKey Base = declarative_base() class Abonent(Base): __tablename__ = "abonents" id = Column(Integer, primary_key= True) account = Column(Unicode(32), index=True) code = Column(Unicode(32)) address = Column(Unicode(512)) fio = Column(Unicode(256)) source = Column(Unicode(16) ) psu = Column(Unicode(256)) tso = Column(Unicode(256)) np = Column(Unicode(256)) street = Column(Unicode(256)) house = Column(Integer) flat = Column(Integer) mro = Column(Unicode(256)) class Payment(Base): __tablename__ = "payments" # and so on...

Now you just need to import this module into any Python project, and you can work with the data.

I foresee your question - “why SQLite”? The main reason is that the database is read-only, so problems with writing to SQLite should not worry us. Secondly, the format of this DBMS is convenient - it is more convenient to view (there are many free utilities, including a super extension for FireFox). Thirdly, in some cases it was necessary to gain access to subscribers from machines that do not have a connection to the MySQL server. In this case, it is enough to copy the SQLite database file, and this machine will have access to all the information.

Unloading occurs once a day at night. Entering data into 1C can be automated in the same way. For example, it is required to record the readings left by subscribers on the personal account website. In this case, we again connect to 1C and programmatically create and post the document “Act of readings”. I will provide the code below.

Working with COM objects in Python is a bit unusual. Firstly, the “Pythonicity” of the code is lost - the rules for naming variables and functions in 1C, to put it mildly, do not correspond to the Zen of Python. Secondly, everyone knows that 1C objects are often named with Cyrillic characters, which will cause problems when developing in Python... but they can be solved. I suggest you look at the code:

Import pythoncom import win32com.client V82_CONN_STRING = "Srvr=v8_server;Ref=v8_db;Usr=username;Pwd=megapass;" pythoncom.CoInitialize() V82 = win32com.client.Dispatch("V82.COMConnector").Connect(V82_CONN_STRING)

As can be seen from the code, the client is initialized to work with 1C. A COM object is defined by the name “V82.COMConnector”. Please note that this name is valid for the V8.2 platform, if you have version 8.1, then the name will be “V81.COMConnector”.

We call the Connect() method on the initialized client, passing it the connection string. The string consists of the server name, database, user and password. The resulting V82 object stores the connection to the 1C application. It doesn't have a Disconnect() method or anything like that. To disconnect from the database, just delete the object from memory using the del() function or assign it to the None variable.

Having an object, you can access any fields and methods of the 1C global context, operate with universal objects such as TabularDocument, ValueTable, etc. It is important to note that when working via a COM connection, 1C works in the “External connection” mode. It does not allow any interactive functionality, such as pop-up dialogs, notifications, and, most importantly, forms. I am sure that you will more than once curse the configuration developers who enclose the most important functionality in the Button1Press() procedure in the document form module.

Let's talk about such an important thing as Cyrillic attributes. Despite the fact that 1C is a bilingual environment and for each Russian method there is an English-language analogue, sooner or later you will need to turn to the Cyrillic attribute. If this does not cause any problems in PHP or VBSCript languages,

Set Con = CreateObject("v81.COMConnector") Set v8 =Con.Connect("Connection string") Set AccountsManager = v8.Documents.Accounts.... Set AccountsRecord= AccountsManager.CreateItem() AccountsRecord.Account = .... .... AccountsRecord.Write()

Then the Python code will simply crash with a Syntax Error. What to do? Edit the configuration? No, it is enough to use the getattr and setattr methods. By passing a COM object and the Cyrillic name of the attribute to these functions, you can get and set values ​​accordingly:

#coding=cp1251 catalog = getattr(V82.Catalogs, "PersonalAccounts")

The following is important: the names of details, as well as parameters of functions and methods, must be transmitted in cp1251 encoding. Therefore, in order to avoid confusion with encodings in advance, it makes sense to declare it at the beginning of the file: #coding=cp1251. You can then pass strings without worrying about their encoding. But! All strings received from 1C (results of calling functions, queries) will be in UTF-8 encoding.

An example of code that executes a query in the 1C environment, iterates through the result and saves the database in SQLite:

#coding=cp1251 q = """ SELECT Personal Accounts. Code AS code, Personal Accounts. Building. Settlement. Name + ", " + Personal Accounts. Short Address AS address, Personal Accounts. Subscriber. Name AS fio, Personal Accounts. Division. Name AS psu, EXPRESS (Characteristics of Personal Accounts Slice of the Last. Value AS Directory. Territorial Network Organizations). Name AS tso, Personal Accounts. Building. Populated Point. Name AS np, Personal Accounts. Building. Street. Name AS street, Personal Accounts. Building. House AS house, Personal Account a.MainRoom.RoomNumber AS flat , PersonalAccounts.Division.Parent.Name AS mro FROM Directory.PersonalAccounts AS PersonalAccounts LEFT CONNECTION RegisterInformation.CharacteristicsPersonalAccounts.Slice of the Last(, TypeCharacteristics = VALUE(Directory.Types of Characteristics.Territorial Network Organization)) AS CharacteristicsL PersonalAccountsSliceLast software PersonalAccounts.Link = CharacteristicsPersonalAccountsSliceLast.Object """ query = V82.NewObject("Query", q) selection = query.Execute().Choose() CONN = db.connect() CONN.query(models.Abonent).delete() while selection.Next(): abonent = models.Abonent() abonent.account = selection.code.strip() abonent.code = selection.code abonent.fio = selection.fio abonent.address = selection.address abonent.psu = selection.psu abonent.tso = selection. tso abonent.source = u"ASRN" abonent.np = selection.np abonent.street = selection.street abonent.house = selection.house abonent.flat = selection.flat abonent.mro = selection.mro CONN.add(abonent) CONN.commit()

Here CONN is the connection session with the SQLite database. A query object is created and its text is filled in. As noted above, the request text must be in cp1251, for which the encoding is first declared. After executing the request, all subscribers are deleted in the database so as not to add duplicates, then they are added in a loop and the final commit follows.

When working with requests, I discovered the following rules.

When selecting fields, assign them names in Latin letters; it will be much more convenient to access them through a selector (dot), instead of getattr().
- Choose only primitive data types: strings, numbers, date and boolean. Never select links to an object (document, reference book)! In this context, you absolutely do not need links and are even harmful, because any call to a link prop or method will result in a request through a COM connection. If you access link attributes in a loop, it will be extremely slow.
- If you select a field of type Date, it will be returned as a PyTime object. This is a special data type for transmitting date-time in a COM connection. It is not as convenient to work with as with the usual datetime. If you pass this object to int(), it will return a timestamp, from which you can then get the datetime using the fromtimestamp() method.

Now let's look at how printed documents are formed. The fact is that the consumer must be given the opportunity to download pre-prepared documents, for example, a payment receipt or a reconciliation report. These documents are generated in 1C in accordance with established requirements; their implementation in Python will take a lot of time. Therefore, it is better to generate documents in 1C and save them in Excel format.

Thus, the reconciliation act document is generated by a special external processing. For those who are not familiar with 1C terminology: processing is a stand-alone program that has its own module, forms, templates, designed to run in the 1C environment. It is necessary to initialize processing, fill in its details and call a function that will return us a spreadsheet document intended for viewing in 1C. This document must be saved in Excel format and copied to the server or recorded in the database.

Link = getattr(V82.Catalogs, "System Reports").FindByDescription("Ellen Reconciliation Report") nav_url = V82.GetURL(link, "Report") name = V82.ExternalReports.Connect(nav_url) ExternalReport = V82.ExternalReports.Create (name) setattr(ExternalReport, "PersonalAccount", reference) table_doc = ExternalReport.GetDoc() path = V82.GetTempFileName("xls") table_doc.Write(path, V82 .SpreadsheetDocumentFileType.XLS) report = models.Report() report .account = reference.Code.strip() report.type = u"act" report.document = open(path, "rb").read() CONN.add(report)

The above fragment does the following: The processing that generates the document is connected. Processing can be built into the configuration, stored on disk or in a 1C database (in some directory). Since processing changes frequently, in order not to update the configuration each time, the most frequently changing processing is stored in the “System Reports” directory, in a “value storage” attribute named Report. Processing can be initialized by unloading it from the database to disk and loading it, or using the GetURL() method, to which you need to pass a link to the directory element and the name of the attribute. We assign the values ​​of the details to the received processing object, call the exported function GetDoc(), and receive a spreadsheet document that is saved to a temporary Excel file. The contents of this file are written to the SQlite database.

The last thing that remains to be considered is the programmatic entry of data into 1C. Let's assume that you need to enter testimonies from subscribers. To do this, it is enough to create and carry out the document “Act of Taking Testimony”:

#coding=cp1251 acts = getattr(V82.Documents, "Act of Taking Testimony") act = acts.CreateDocument() setattr(act, "Testimony", 1024.23) setattr(act, "Subscriber", "Ivanov") # Filling in other details. .. act.Write()
Data entry is now automated.

So, I outlined a method that is based on programmatic upload and download of data using a COM connection. This method has been successfully operating in my organization for almost a year. The database, formed from 1C, serves 3 payment systems, Internet acquiring (payment by cards via the Internet), as well as a personal account. In addition, they connect to the database various scripts to automate routine.

Despite the shortcomings of the method (slow COM connection speed), in general it functions stably. We have data in a platform-independent form (SQLite), which can be worked with from any language. And the main part of the code is written in Python, which means that many tools and techniques are available that you can’t even dream of in 1C.

This is one of possible ways interaction with 1C. I am sure that it is not new and has probably already been tested and optimized by someone. However, I tried to present as many details of the process as possible in order to protect you from the pitfalls that I myself stepped on.

I wish you all good luck, and remember that 1C is not as scary as it is made out to be!

One of the options for exchanging data between 1C databases is exchange via a COM connection.

Using a COM connection, you can connect from one 1C database to another and read or write data. This method can be used both in client-server versions of databases and in file databases. In this article we will look at examples of this type of connection. The examples use platform 8.2.

You can create two types of COM objects for the 1C application. This V82.Application And V82.COMConnector. In case of V82.Application An almost full-fledged copy of the 1C application is launched. in case of use V82.COMConnector A small server part is launched.
The speed of operation in this case is higher, but some functions may not be available. In particular, working with forms and common modules for which the property of working with external connections is not set. Mostly you should use V82.COMConnector and only in case of lack of functionality V82.Application. The difference in operating speed can be especially noticeable on large-volume databases.

So let's get started

  1. Let's create a COM object
    • For V82.Application Connection = New COMObject("V82.Application" ) ;
    • For V82.COMConnector Connection = New COMObject("V82.COMConnector" ) ;
  2. Let's create a connection string
    • for the server version of the database ConnectionString = "Srvr = " "ServerName" ";Ref = " "BaseName" ;
    • for the file version of the database ConnectionString = "File = " "PathKBase" "; Usr = UserName; Pwd = Password";
  3. Connecting to the database Attempt Connection = Connection. Connect(ConnectionString) ; Exception Message = New MessageToUser; Message. Text = + ErrorDescription() ; Message. To report() ; EndAttempt ;
  4. Disconnecting from the database Connection = Undefined ;

    For object V82.Application It is necessary to terminate the connection, otherwise an incomplete session will remain, which will then have to be deleted manually. In case of V82.COMConnector the connection is broken automatically when the procedure in which the connection was made is completed. And there is one more small point.

    For the user under whom the connection is being made, the “Request confirmation when closing the program” checkbox must be disabled in its settings.

Now let's put all the code together

Connection = New COMObject("V82.Application" ) ; //Connection = New COMObject("V82.COMConnector"); ConnectionString = "Srvr = " "Server1C" ";Ref = " "MyBase" "; Usr = Petya; Pwd = 123" ; //ConnectionString = "File = ""С:\MyBase""; Usr = Petya; Pwd = 123"; Attempt Connection = Connection. Connect(ConnectionString) ; Exception Message = New MessageToUser; Message. Text = "Could not connect to the database"+ DescriptionError() ; Message. To report() ; EndAttempt ; Connection = Undefined ;

For connection type V82.Application the method is used for the COM object that was created initially, and for V82.COMConnector method is applied to the connection. further work with the request proceeds standard means 1C. in code it looks like this:

Request = Connection. NewObject("Request" ) ; // For V82.COMConnector Request = Connection. NewObject("Request" ) ; // For V82.Application Request. Text = "SELECT | Positions of Organizations. Code, | Positions of Organizations.Name|FROM | Directory. Positions of Organizations AS Positions of Organizations"; Result = Request. Run(); Sample = Result. Choose() ; Bye Selection. Next() Loop EndLoop ;

For version 1C:Enterprise 8.3 everything remains unchanged except that when creating COM objects you must use "V83.COMConnector" or "V83.Application".

) That's right

At the same time, I have seen more than once when publications that did not even reach 10 points simply “took off.”
Why did this happen? Apparently because someone clearly liked them.


This is what I’m saying, that it would be nice to understand how much you need it without reading the rating article, or to evaluate it not so primitively +/-. As for what I liked, I would correct it this way: it gained so much due to the fact that the stars aligned and a lot of people gathered on the site and many liked it, you yourself understand this is a matter of chance because as soon as the article leaves home page then it can already be found only by request, and so everyone passing by votes. And, as far as I understand, constant comments = promotion of the article allow you to maintain it on the main page.
This is precisely why they put shops on public streets - after all, what is often important is not the quality and relevance of the goods, but the trafficability of the place; people walking often buy something that they will throw away the next day, just for the sake of the process. This is a disease that has long been known to everyone - shopping addiction. Or simply increasing the flow increases the likelihood of the right buyer.

And the pros and cons... - this is just a kind of “thank you” for the time and work spent


Those. Does a minus also count as a “thank you”? I wanted to know your opinion on whether it should be used in such cases, and how interesting others think? Should you put it when the article is harmful/bad or when it is simply useless/empty for you?
In my opinion, the article looks like a simple rating increase, because:
1. The problem with types I cited was completely ignored by the author, although he was not too lazy to write a bunch of comments.
2. There is an obvious inaccuracy in the article: it is said that this is the only way

V82 = New COMObject("V82.ComConnector"); Code = AccountCOM.Code;


but I can easily do it using processing like this:

Report(Base. Directories. Counterparties. Find By Name("LLC"). Code);


and everything is fine! And I choose the connection V82.ComConnector
It’s somehow strange that the author doesn’t care at all that his article contains the problems that were pointed out, but he doesn’t react in any way.
3. But there is still a problem when the error “Class does not exist” pops up
4. But there is a problem when 8.2 is installed, and then 8.1 is installed - try exchanging via OLE/COM with a standard UT-BP exchange!
5. Could you indicate the main processing on the site that allows you to universally connect via OLE/COM so that beginners do not waste time, you write for them! By the way, for some reason her picture is on your display, why? And as a result, 2 words on the merits, and 6 more behind the scenes.

In general, I don’t throw mud, but point out specific gaps, but there is zero reaction. If this is the experience you are sharing, then it is somehow erroneous and incomplete.
My point is that if the author had a desire to collect all the glitches, he could at least listen to other people’s experience, and not snap at comments. A situation immediately arises when the one who read it knows more than the author, they tell him (sometimes incorrectly), and he also fights back. As a result, all the information is not in the article, but in the comments! Funny! This often happens, but you don’t need to focus on the fact that you wanted the best - I show what’s best, and others show it! Include this in the article and it will be worthwhile; not everyone is interested in reading this skirmish.

One way to transfer data from one 1C configuration to another is software connection using COM. Many companies use several different databases, between which there must be certain connections and dependencies. If it is necessary not only to transfer data, but also to perform certain data processing, then a COM connection will be the optimal mechanism. The ability to analyze data from another 1C database is useful to any developer.

We connect via COM to the 1C database

To implement a COM connection in 1C, a special mechanism called COMConnector is used. This object is installed along with the platform and is used for communication information bases. It should be noted that for versions 8.2 and 8.3 objects with different names are used - “V82.COMConnector” and “V83.COMConnector”, respectively.

Remember that the duration of the COM connection to the database costs a license - do not get carried away with simultaneous execution of several connections. This is especially important for organizations that have a limited number of licenses. This issue can be resolved using routine tasks executing when there are no active user connections to the infobase.

To be able to connect to another database and request the necessary information, you must know the following data:

  1. What type is it - file or client-server;
  2. Where is it located;
  3. What name and password can you use to log in?
  4. What data are you interested in?

From the first three points, to implement a COM connection, you need to create a string of parameters. Depending on the type of information security, it will differ appearance. Using the received string, a connection is made, with the help of which you can collect data from another database for analysis and processing using any methods.

Connection ParametersFileIB = "File=""Path_to_database""; Usr=""User_name"";Pwd=""Password"""; Connection ParametersClientServerIB = "Srvr=""Server_Name""; Ref=""Database_Name""; Usr=""User_Name""; Pwd=""Password""";

The connection function is simple and should not raise any questions if all parameters are specified correctly. To speed up debugging and analysis possible errors it is better to enclose the connection in the “Try” construction. The function will return a value of the “COM object” type, with which you will work to obtain the necessary data.

&OnServer Function ConnectToBase() exportConnectionIB Parameters = "File=""E:\1c database\ERP""; Usr=""Administrator"";Pwd=""1"""; V83COMCon= New COMObject("V83.COMConnector"); Attempt Return V83COMCon.Connect(IB Connection Parameters); Exception Report(ErrorDescription()); Return Undefined; EndAttempt; EndFunction

Through a COM connection you can not only select data, but also add it to the database you are connecting to. Remember that we can transfer 4 primitive data types via a COM object. Other types will have to be specified using the platform's built-in search functions. Please note that global platform functions are also called via a COM connection.

We receive data from the 1C database

After you have received the desired object, you need to read data from another database. To do this, we use a request via a COM connection in 1C 8.3 using the received value of the “COM object” type from the function. It is important to first connect to the database and then execute the request. Execution occurs through the NewObject method, specifying the object type in string form as a parameter - “Request”.

&OnServer Procedure TestCOMOnServer() Connection = ConnectToBase(); If TypeValue(Connection) Type("Undefined") Then RequestBPZO = Connection.NewObject("Request"); RequestBPZO.Text = "SELECT first 15 | DirectoryUser.Name AS Name |FROM | Directory.users AS DirectoryUser"; Select = RequestBPZO.Execute().select(); While Selection.next() loop Report(Selection.Number); EndCycle; endIf; End of Procedure >

For example, to obtain information about users of a certain department, we will set a condition in the request through parameters. One parameter will be of a simple type - a string, and the division will be a link to the directory element "Enterprise Structure". The result of the query is a table with the listed fields of the type that they exist in the database to which the COM connection occurred. If you need to convert them to other types, use the standard platform functions:

  • Line();
  • Number();
  • Date of().
RequestBPZO = Connection.NewObject("Request"); RequestBPZO.Text = "SELECT first 15 | DirectoryUser.Name AS Name | FROM | Directory.Users AS DirectoryUser I WHERE | DirectoryUser.Department = &RequiredDepartment | And DirectoryUser.Name like ""%"" + &RequiredName+ ""%""" ; Request BPZO.SetParameter("Required Department", Connection. Directories. Enterprise Structure. Find By Code("00-000023")); RequestBPZO.SetParameter("RequiredName","Ekaterina"); Select = RequestBPZO.Execute().select(); While Selection.next() loop Report(Selection.Name); EndCycle;

If you need to transfer an array to the database for selection based on several parameters, for example, departments, the NewObject command is also used. Similarly, you can pass a list or table of values, filling them with elements of another database through a connection. All existing methods of objects and mechanisms of the platform are available to you for searching.

RequestBPZO = Connection.NewObject.("Request"); RequestBPZO.Text = "SELECT first 15 | DirectoryUser.Name AS Name | FROM | Directory.Users AS DirectoryUser I WHERE | DirectoryUser.Department B (&NecessaryDepartment) | And DirectoryUser.Name like ""%"" + &NecessaryName+ ""%" ""; Array of Departments = Connection.NewObject("Array"); Array of Departments.Add(Connection.Directories.Enterprise Structure.Find By Code("00-000023")); Array of Departments.Add(Connection.Directories.Enterprise Structure.Find By Code("00-000038")); Array of Departments.Add(Connection.Directories.Enterprise Structure.Find By Code("00-000046")); Request BPZO.SetParameter("Required Department", Array of Departments); RequestBPZO.SetParameter("RequiredName","Ekaterina"); Select = RequestBPZO.Execute().select(); While Selection.next() loop Report(Selection.Name); EndCycle;

When transferring documents or directory elements, the question of controlling the transfer of a specific object always arises. With the help of COM connections, such problems can be solved through a unique identifier. You need to find an object in the plug-in database by identifier from the current information security using the “GetLink” function, using the identifier as a string. If one is not found, you can create it using a COM connection.

StrIdent = String(Directories.Users.FindByCode("00-0000313").UniqueIdentifier()); If NOT ValueFilled(Connection.Directories.Users.GetLink(Connection.NewObject("UniqueIdentifier", StrIdent))) then NewUser = Connection.Directories.Users.CreateItem(); NewUser.Name = Directories.Users.FindByCode("00-0000313").Name; NewUser.Individual = Directories.Users.FindByCode("00-0000313").Individual; NewUser.Write(); endIf;

Also, a COM connection has the right to use procedures and functions from common 1C modules with the “External connection” property enabled. In addition to this condition, the called function or procedure must be export and not include interactive actions performed on the server. Otherwise, you will see an error about the operation being invalid.

Compound..; VariableFunction = Connection..; function call>general module name>procedure call>general module name>

The possibilities for external connection with another database in 1C are quite extensive and can allow you to perform many tasks. It is important to be able to correctly evaluate the tools and choose optimal solution. In most cases, this skill appears only with experience or by studying examples of the work of experienced specialists.